webrtc/common_video/vplib/main/test/convert_test.cc

369 lines
12 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Test application for color space conversion functions
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cmath>
#include <time.h>
#include "test_util.h"
#include "vplib.h"
using namespace webrtc;
// Optimization testing
//#define SCALEOPT //For Windows currently, June 2010
WebRtc_Word32
ImagePSNRfromBuffer(WebRtc_UWord8 *refBufName, WebRtc_UWord8 *testBufName,
WebRtc_Word32 width, WebRtc_Word32 height,
VideoType vType, double *YPSNRptr);
void TestRetVal(int testVal, int refVal );
int convert_test(CmdArgs& args)
{
// reading YUV frame - testing on the first frame of the foreman sequence
//SET UP
int j = 0;
int retVal;
std::string outname = args.outputFile;
if (outname == "")
{
outname = "conversionTest_out.yuv";
}
std::string inname;
inname = args.inputFile;
FILE* sourceFile;
FILE* outputFile;
FILE* logFile;
WebRtc_UWord32 width = args.width;
WebRtc_UWord32 height = args.height;
WebRtc_UWord32 lengthSourceFrame = width*height*3/2;
double psnr = 0;
if ((sourceFile = fopen(inname.c_str(), "rb")) == NULL)
{
printf("Cannot read file %s.\n", inname.c_str());
exit(1);
}
if ((outputFile = fopen(outname.c_str(), "wb")) == NULL)
{
printf("Cannot write file %s.\n", outname.c_str());
exit(1);
}
if ((logFile = fopen("../log.txt", "a")) == NULL)
{
printf("Cannot write file ../log.txt.\n");
exit(1);
}
// reading first frame of Foreman sequence
WebRtc_UWord8* origBuffer = new WebRtc_UWord8[width * height*3/2];
fread(origBuffer, 1, lengthSourceFrame, sourceFile);
// START TEST
printf("\nTEST #%d I420 <-> RGB24\n", j);
WebRtc_UWord8* resRGBBuffer2 = new WebRtc_UWord8[width*height*3];
WebRtc_UWord8* resI420Buffer = new WebRtc_UWord8[width*height*3/2];
retVal = ConvertFromI420(kRGB24, origBuffer, width, height,resRGBBuffer2);
TestRetVal(retVal, width*height*3);
clock_t tticks = clock();
for (int tt = 0; tt < 1000; tt++)
{
retVal = ConvertToI420(kRGB24, resRGBBuffer2, width, height,
resI420Buffer);
}
tticks = clock() - tticks;
printf("RGB24->I420 Time(1000): %d\n", tticks);
TestRetVal(retVal, width*height*3/2);
fwrite(resI420Buffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height, kI420, &psnr);
printf("Conversion between type #%d and type #%d, PSNR = %f\n", kI420,
kRGB24, psnr);
j++;
delete [] resRGBBuffer2;
printf("\nTEST #%d I420 <-> UYVY\n", j);
WebRtc_UWord8* outUYVYBuffer = new WebRtc_UWord8[width*height*2];
clock_t ticks = clock();
for (int t = 0; t < 100; t++)
{
retVal = ConvertFromI420(kUYVY, origBuffer, width,
height, outUYVYBuffer);
}
ticks = clock() - ticks;
#ifndef SCALEOPT
fprintf(logFile, "\nConvertI420ToUYVY, before opt: %d\n", ticks);
#else
fprintf(logFile, "\nConvertI420ToUYVY, after opt: %d\n", ticks);
#endif
TestRetVal(retVal, width*height*2);
retVal = ConvertToI420(kUYVY, outUYVYBuffer, width, height, resI420Buffer);
TestRetVal(retVal, width*height*3/2);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height, kI420, &psnr);
printf("Conversion between type #%d and type #%d, PSNR = %f\n",
kI420, kUYVY, psnr);
j++;
delete [] outUYVYBuffer;
printf("\nTEST #%d I420 <-> I420 \n", j);
WebRtc_UWord8* outI420Buffer = new WebRtc_UWord8[width*height*2];
retVal = ConvertToI420(kI420, origBuffer, width, height, outI420Buffer);
TestRetVal(retVal, width*height*3/2);
retVal = ConvertToI420(kI420 ,outI420Buffer, width, height, resI420Buffer);
TestRetVal(retVal, width*height*3/2);
fwrite(resI420Buffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height,
kI420, &psnr);
printf("Conversion between type #%d and type #%d, PSNR = %f\n",
kI420, kUYVY, psnr);
j++;
delete [] outI420Buffer;
printf("\nTEST #%d I420 <-> YV12\n", j);
outI420Buffer = new WebRtc_UWord8[width*height*3/2]; // assuming DIFF = 0
ticks = clock();
for (int t = 0; t < 1000; t++)
{
retVal = ConvertFromI420(kYV12, origBuffer, width, height, outI420Buffer);
}
ticks = clock() - ticks;
#ifndef SCALEOPT
fprintf(logFile, "\nConvertI420ToYV12, before opt: %d\n", ticks);
#else
fprintf(logFile, "\nConvertI420ToYV12, after opt: %d\n", ticks);
#endif
TestRetVal(retVal, width*height*3/2);
retVal = webrtc::ConvertYV12ToI420(outI420Buffer, width, height,
resI420Buffer);
TestRetVal(retVal, width*height*3/2);
fwrite(resI420Buffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height, kI420, &psnr);
printf("Conversion between type #%d and type #%d, PSNR = %f\n", kI420,
kYV12, psnr);
j++;
delete [] outI420Buffer;
delete [] resI420Buffer;
printf("\nTEST #%d I420<-> RGB565\n", j);
WebRtc_UWord8* res2ByteBuffer = new WebRtc_UWord8[width*height*2];
resI420Buffer = new WebRtc_UWord8[width * height * 3 / 2];
retVal = ConvertFromI420(kRGB565, origBuffer, width, height, res2ByteBuffer);
TestRetVal(retVal, width*height*2);
retVal = ConvertRGB565ToI420(res2ByteBuffer, width, height, resI420Buffer);
TestRetVal(retVal, width*height*3/2);
fwrite(resI420Buffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height, kI420, &psnr);
printf("Note: Frame was compressed!\n");
printf("Conversion between type #%d and type #%d, PSNR = %f\n", kI420,
kRGB565, psnr);
delete [] res2ByteBuffer;
j++;
printf("\nTEST #%d I420 <-> YUY2\n", j);
WebRtc_UWord8* outYUY2Buffer = new WebRtc_UWord8[width*height*2];
ticks = clock();
for (int t = 0; t < 1000; t++)
{
retVal = ConvertI420ToYUY2(origBuffer, outYUY2Buffer, width, height,0);
}
ticks = clock() - ticks;
#ifndef SCALEOPT
fprintf(logFile, "\nConvertI420ToYUY2, before opt: %d\n", ticks);
#else
fprintf(logFile, "\nConvertI420ToYUY2, after opt: %d\n", ticks);
#endif
TestRetVal(retVal, width*height*2);
ticks = clock();
for (int t = 0; t < 1000; t++)
{
retVal = ConvertToI420(kYUY2, outYUY2Buffer, width, height,
resI420Buffer);
}
ticks = clock() - ticks;
#ifndef SCALEOPT
fprintf(logFile, "\nConvertYUY2ToI420, before opt: %d\n", ticks);
#else
fprintf(logFile, "\nConvertYUY2ToI420, after opt: %d\n", ticks);
#endif
TestRetVal(retVal, width*height*3/2);
fwrite(resI420Buffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resI420Buffer, width, height, kI420, &psnr);
printf("Conversion between type #%d and type #%d,PSNR = %f\n", kI420,
kYUY2, psnr);
delete [] outYUY2Buffer;
j++;
printf("\nTEST #%d I420 <-> UYVY\n", j);
outUYVYBuffer = new WebRtc_UWord8[width*height*2]; // assuming DIFF = 0
WebRtc_UWord8* resYUVBuffer = new WebRtc_UWord8[width*height*2];
retVal = ConvertFromI420(kUYVY, origBuffer, width, height, outUYVYBuffer);
TestRetVal(retVal, width*height*2);
retVal = ConvertToI420(kUYVY, outUYVYBuffer, width, height, resYUVBuffer);
TestRetVal(retVal, width*height*3/2);
fwrite(resYUVBuffer, lengthSourceFrame, 1, outputFile);
ImagePSNRfromBuffer(origBuffer, resYUVBuffer, width, height, kI420, &psnr);
printf("Conversion between type #%d and type #%d,PSNR = %f\n", kI420,
kUYVY, psnr);
delete [] outUYVYBuffer;
delete [] resYUVBuffer;
j++;
/*******************************************************************
* THE FOLLOWING FUNCTIONS HAVE NO INVERSE, BUT ARE PART OF THE TEST
* IN ORDER TO VERIFY THAT THEY DO NOT CRASH
*******************************************************************/
printf("\n\n Running functions with no inverse...\n");
//printf("TEST #%d I420 -> ARGB4444 \n", j);
res2ByteBuffer = new WebRtc_UWord8[width*height*2];
ConvertI420ToARGB4444(origBuffer, res2ByteBuffer, width, height, 0);
delete [] res2ByteBuffer;
// YUY2 conversions
//printf("TEST #%d I420 -> YUY2 \n", j);
WebRtc_UWord8* sourceYUY2 = new WebRtc_UWord8[width*height*2];
ConvertI420ToYUY2(origBuffer, sourceYUY2, width, height, 0);
delete [] sourceYUY2;
//UYVY conversions
WebRtc_UWord8* sourceUYVY = new WebRtc_UWord8[width*height*2];
ConvertI420ToUYVY(origBuffer, sourceUYVY, width, height, 0);
//printf("TEST I420-> ARGB444\n");
res2ByteBuffer = new WebRtc_UWord8[(width+10)*height*2];
retVal = webrtc::ConvertI420ToARGB4444(origBuffer, res2ByteBuffer,
width, height, width + 10);
TestRetVal(retVal, (width+10)*height*2);
delete [] res2ByteBuffer;
//printf("TEST I420-> ARGB1555\n");
res2ByteBuffer = new WebRtc_UWord8[(width+10)*height*2];
retVal = ConvertI420ToARGB1555(origBuffer, res2ByteBuffer, width,
height, width + 10);
TestRetVal(retVal, (width+10)*height*2);
delete [] res2ByteBuffer;
//printf("TEST NV12 - > I420\n");
// using original I420 sequence - > just to verify it doesn't crash
ConvertNV12ToI420(origBuffer,resI420Buffer, width, height);
//printf("TEST NV12 - > I420 and Rotate 180\n");
ConvertNV12ToI420AndRotate180(origBuffer, resI420Buffer, width, height);
//printf("TEST NV12 - > I420 and Rotate anti Clockwise\n");
ConvertNV12ToI420AndRotateAntiClockwise(origBuffer, resI420Buffer,
width, height);
//printf("TEST NV12 - > I420 and Rotate Clockwise\n");
ConvertNV12ToI420AndRotateClockwise(origBuffer, resI420Buffer,
width, height);
//printf("TEST NV12 -> RGB565 \n");
res2ByteBuffer = new WebRtc_UWord8[(width+10)*height*2];
ConvertNV12ToRGB565(origBuffer, res2ByteBuffer, width, height);
delete [] res2ByteBuffer;
//printf("TEST I420 - > RGBAIPhone");
WebRtc_UWord8* resBuffer = new WebRtc_UWord8[(width + 10) * height * 4];
ConvertI420ToRGBAIPhone(origBuffer, resBuffer, width, height, width + 10);
delete [] resBuffer;
//printf("TEST #%d I420 <-> ARGB_Mac", j);
WebRtc_UWord8* outARGBBuffer = new WebRtc_UWord8[width * height * 4];
retVal = ConvertI420ToARGBMac(origBuffer,outARGBBuffer, width, height, 0);
TestRetVal(retVal, width * height * 4);
delete [] outARGBBuffer;
//closing
fclose(sourceFile);
fclose(outputFile);
fclose(logFile);
delete [] origBuffer;
delete [] resI420Buffer;
std::cout << "\n** View output file **\n";
std::cout << "Press enter to quit test...";
std::string str;
std::getline(std::cin, str);
return 0;
}
WebRtc_Word32
ImagePSNRfromBuffer(WebRtc_UWord8 *refBufName, WebRtc_UWord8 *testBufName,
WebRtc_Word32 width, WebRtc_Word32 height,
VideoType vType, double *YPSNRptr)
{
// currently assumes I420
if (vType != kI420)
{
return -1;
}
double mse = 0.0;
double mseLogSum = 0.0;
WebRtc_UWord8 *ref = refBufName;
WebRtc_UWord8 * test = testBufName;
// comparing only 1 frame
mse = 0.0;
// calculate Y sum-square-difference
for( int k = 0; k < width * height; k++ )
{
mse += (test[k] - ref[k]) * (test[k] - ref[k]);
}
// divide by number of pixels
mse /= (double) (width * height);
if (mse == 0)
{
*YPSNRptr = 48;
return 0;
}
// accumulate for total average
mseLogSum += std::log10( mse );
*YPSNRptr = 20.0 * std::log10(255.0) - 10.0 * mseLogSum;
return 0;
}
void TestRetVal(int testVal, int refVal )
{
if (testVal != refVal)
{
printf("return value = %d, desired value = %d\n", testVal, refVal);
}
}