Changing all PSNR/SSIM calculations to use libyuv.

Removed old PSNR/SSIM implementations in:
* test/testsupport/metrics/video_metrics.cc
* src/modules/video_coding/codecs/test_framework/test.cc
The functions in video_metrics.cc is now using code in libyuv instead. Old code in test.cc is using the same functions.
The code for video_metrics.h had to be moved into a separate GYP file to avoid circular dependency error on Mac (see issue 160 for more details). The reason for this is that libyuv's unittest target depends on test_support_main.

BUG=
TEST=metrics_unittests in Debug+Release on Linux, Mac and Windows.

Review URL: http://webrtc-codereview.appspot.com/333025

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1325 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
kjellander@webrtc.org
2012-01-04 08:09:32 +00:00
parent ec0f54954d
commit cc33737a80
21 changed files with 453 additions and 893 deletions

View File

@@ -50,6 +50,7 @@
'webrtc_video_coding',
'webrtc_vp8',
'<(webrtc_root)/../testing/gtest.gyp:gtest',
'<(webrtc_root)/../test/metrics.gyp:metrics',
'<(webrtc_root)/../test/test.gyp:test_support_main',
],
'sources': [

View File

@@ -117,20 +117,18 @@ class VideoProcessorIntegrationTest: public testing::Test {
frame_reader_->Close();
frame_writer_->Close();
QualityMetricsResult result;
EXPECT_EQ(0, PsnrFromFiles(config_.input_filename.c_str(),
config_.output_filename.c_str(),
config_.codec_settings->width,
config_.codec_settings->height, &result));
EXPECT_GT(result.average, minimum_psnr + 2.0);
EXPECT_GT(result.min, minimum_psnr);
EXPECT_EQ(0, SsimFromFiles(config_.input_filename.c_str(),
config_.output_filename.c_str(),
config_.codec_settings->width,
config_.codec_settings->height, &result));
EXPECT_GT(result.average, minimum_ssim + 0.1);
EXPECT_GT(result.min, minimum_ssim);
webrtc::test::QualityMetricsResult psnr_result, ssim_result;
EXPECT_EQ(0, webrtc::test::I420MetricsFromFiles(
config_.input_filename.c_str(),
config_.output_filename.c_str(),
config_.codec_settings->width,
config_.codec_settings->height,
&psnr_result,
&ssim_result));
EXPECT_GT(psnr_result.average, minimum_psnr + 2.0);
EXPECT_GT(psnr_result.min, minimum_psnr);
EXPECT_GT(ssim_result.average, minimum_ssim + 0.1);
EXPECT_GT(ssim_result.min, minimum_ssim);
}
};

View File

@@ -11,7 +11,6 @@
#include "benchmark.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
@@ -19,12 +18,11 @@
#include <windows.h>
#endif
#include "event_wrapper.h"
#include "testsupport/fileutils.h"
#include "common_video/libyuv/include/libyuv.h"
#include "video_codec_interface.h"
#include "video_source.h"
#include "system_wrappers/interface/event_wrapper.h"
#include "modules/video_coding/codecs/test_framework/video_source.h"
#include "testsupport/fileutils.h"
#include "testsupport/metrics/video_metrics.h"
#define SSIM_CALC 0 // by default, don't compute SSIM
@@ -80,8 +78,8 @@ Benchmark::Perform()
const int nBitrates = sizeof(bitRate)/sizeof(*bitRate);
int testIterations = 10;
double psnr[nBitrates];
double ssim[nBitrates];
webrtc::test::QualityMetricsResult psnr[nBitrates];
webrtc::test::QualityMetricsResult ssim[nBitrates];
double fps[nBitrates];
double totalEncodeTime[nBitrates];
double totalDecodeTime[nBitrates];
@@ -153,12 +151,14 @@ Benchmark::Perform()
double actualBitRate = ActualBitRate(_framecnt) / 1000.0;
std::cout << " " << actualBitRate;
_results << "," << actualBitRate;
PSNRfromFiles(_inname.c_str(), _outname.c_str(), _inst.width,
_inst.height, &psnr[k]);
webrtc::test::QualityMetricsResult psnr_result;
I420PSNRFromFiles(_inname.c_str(), _outname.c_str(),
_inst.width, _inst.height, &psnr[k]);
if (SSIM_CALC)
{
SSIMfromFiles(_inname.c_str(), _outname.c_str(), _inst.width,
_inst.height, &ssim[k]);
webrtc::test::QualityMetricsResult ssim_result;
I420SSIMFromFiles(_inname.c_str(), _outname.c_str(),
_inst.width, _inst.height, &ssim[k]);
}
fps[k] = avgFps;
@@ -167,8 +167,8 @@ Benchmark::Perform()
_results << std::endl << "Y-PSNR [dB]";
for (int k = 0; k < nBitrates; k++)
{
std::cout << " " << psnr[k];
_results << "," << psnr[k];
std::cout << " " << psnr[k].average;
_results << "," << psnr[k].average;
}
if (SSIM_CALC)
@@ -177,8 +177,8 @@ Benchmark::Perform()
_results << std::endl << "SSIM ";
for (int k = 0; k < nBitrates; k++)
{
std::cout << " " << ssim[k];
_results << "," << ssim[k];
std::cout << " " << ssim[k].average;
_results << "," << ssim[k].average;
}
}

View File

@@ -9,41 +9,16 @@
*/
#include "test.h"
#include "video_source.h"
#include "common_video/libyuv/include/libyuv.h"
#include "event_wrapper.h"
#include "thread_wrapper.h"
#include <cstring>
#include <iostream>
#include <fstream>
#include <cmath>
#include <ctime>
#include <string.h>
#include <cassert>
#include <vector>
#include "testsupport/metrics/video_metrics.h"
using namespace webrtc;
long filesize(const char *filename); // local function defined at end of file
struct SSIMcontext
{
SSIMcontext() :
refFileName(NULL), testFileName(NULL), width(0), height(0),
SSIMptr(NULL), startFrame(-1), endFrame(-1), evnt(NULL) {};
SSIMcontext(const char *ref, const char *test, int w, int h, double *Sptr,
int start, int end, EventWrapper* ev) :
refFileName(ref), testFileName(test), width(w), height(h),
SSIMptr(Sptr), startFrame(start), endFrame(end), evnt(ev) {};
const char *refFileName;
const char *testFileName;
int width;
int height;
double *SSIMptr;
int startFrame;
int endFrame;
EventWrapper* evnt;
};
Test::Test(std::string name, std::string description)
:
_bitRate(0),
@@ -80,14 +55,17 @@ Test::Print()
(*_log) << _description << std::endl;
(*_log) << "Input file: " << _inname << std::endl;
(*_log) << "Output file: " << _outname << std::endl;
double psnr = -1.0, ssim = -1.0;
PSNRfromFiles(_inname.c_str(), _outname.c_str(), _inst.width, _inst.height, &psnr);
ssim = SSIMfromFilesMT(4 /* number of threads*/);
webrtc::test::QualityMetricsResult psnr;
webrtc::test::QualityMetricsResult ssim;
I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _inst.width,
_inst.height, &psnr);
I420SSIMFromFiles(_inname.c_str(), _outname.c_str(), _inst.width,
_inst.height, &ssim);
(*_log) << "PSNR: " << psnr << std::endl;
std::cout << "PSNR: " << psnr << std::endl << std::endl;
(*_log) << "SSIM: " << ssim << std::endl;
std::cout << "SSIM: " << ssim << std::endl << std::endl;
(*_log) << "PSNR: " << psnr.average << std::endl;
std::cout << "PSNR: " << psnr.average << std::endl << std::endl;
(*_log) << "SSIM: " << ssim.average << std::endl;
std::cout << "SSIM: " << ssim.average << std::endl << std::endl;
(*_log) << std::endl;
}
@@ -143,354 +121,6 @@ Test::SetLog(std::fstream* log)
_log = log;
}
int
Test::PSNRfromFiles(const char *refFileName, const char *testFileName, int width, int height, double *YPSNRptr)
{
FILE *refFp = fopen(refFileName, "rb");
if( refFp == NULL ) {
// cannot open reference file
fprintf(stderr, "Cannot open file %s\n", refFileName);
return -1;
}
FILE *testFp = fopen(testFileName, "rb");
if( testFp == NULL ) {
// cannot open test file
fprintf(stderr, "Cannot open file %s\n", testFileName);
return -2;
}
double mse = 0.0;
double mseLogSum = 0.0;
int frames = 0;
int frameBytes = 3*width*height/2; // bytes in one frame I420
unsigned char *ref = new unsigned char[frameBytes]; // space for one frame I420
unsigned char *test = new unsigned char[frameBytes]; // space for one frame I420
int refBytes = (int) fread(ref, 1, frameBytes, refFp);
int testBytes = (int) fread(test, 1, frameBytes, testFp);
while( refBytes == frameBytes && testBytes == frameBytes )
{
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);
// accumulate for total average
mseLogSum += std::log10( mse );
frames++;
refBytes = (int) fread(ref, 1, frameBytes, refFp);
testBytes = (int) fread(test, 1, frameBytes, testFp);
}
// ypsnrAvg = sum( 10 log (255^2 / MSE) ) / frames
// = 20 * log(255) - 10 * mseLogSum / frames
*YPSNRptr = 20.0 * std::log10(255.0) - 10.0 * mseLogSum / frames;
delete [] ref;
delete [] test;
fclose(refFp);
fclose(testFp);
return 0;
}
int
Test::SSIMfromFiles(const char *refFileName, const char *testFileName, int width, int height, double *SSIMptr,
int startFrame /*= -1*/, int endFrame /*= -1*/)
{
FILE *refFp = fopen(refFileName, "rb");
if( refFp == NULL ) {
// cannot open reference file
fprintf(stderr, "Cannot open file %s\n", refFileName);
return -1;
}
FILE *testFp = fopen(testFileName, "rb");
if( testFp == NULL ) {
// cannot open test file
fprintf(stderr, "Cannot open file %s\n", testFileName);
return -2;
}
int frames = 0;
int frameBytes = 3*width*height/2; // bytes in one frame I420
unsigned char *ref = new unsigned char[frameBytes]; // space for one frame I420
unsigned char *test = new unsigned char[frameBytes]; // space for one frame I420
if (startFrame >= 0)
{
if (fseek(refFp, frameBytes * startFrame, SEEK_SET) != 0){
fprintf(stderr, "Cannot go to frame %i in %s\n", startFrame, refFileName);
return -1;
}
if (fseek(testFp, frameBytes * startFrame, SEEK_SET) != 0){
fprintf(stderr, "Cannot go to frame %i in %s\n", startFrame, testFileName);
return -1;
}
}
int refBytes = (int) fread(ref, 1, frameBytes, refFp);
int testBytes = (int) fread(test, 1, frameBytes, testFp);
//
// SSIM: variable definition, window function, initialization
int window = 10;
int flag_window = 0; //0 for uniform window filter, 1 for gaussian symmetric window
float variance_window = 2.0; //variance for window function
float ssimFilter[121]; //2d window filter: typically 11x11 = (window+1)*(window+1)
//statistics per column of window (#columns = window+1), 0 element for avg over all columns
float avgTest[12];
float avgRef[12];
float contrastTest[12];
float contrastRef[12];
float crossCorr[12];
//
//offsets for stability
float offset1 = 0.1f;
float offset2 = 0.1f;
float offset3 = offset2/2;
//
//define window for SSIM: take uniform filter for now
float sumfil = 0.0;
int nn=-1;
for(int j=-window/2;j<=window/2;j++)
for(int i=-window/2;i<=window/2;i++)
{
nn+=1;
if (flag_window == 0)
ssimFilter[nn] = 1.0;
else
{
float dist = (float)(i*i) + (float)(j*j);
float tmp = 0.5f*dist/variance_window;
ssimFilter[nn] = exp(-tmp);
}
sumfil +=ssimFilter[nn];
}
//normalize window
nn=-1;
for(int j=-window/2;j<=window/2;j++)
for(int i=-window/2;i<=window/2;i++)
{
nn+=1;
ssimFilter[nn] = ssimFilter[nn]/((float)sumfil);
}
//
float ssimScene = 0.0; //avgerage SSIM for sequence
//
//SSIM: done with variables and defintion
//
while( refBytes == frameBytes && testBytes == frameBytes &&
!(endFrame >= 0 && frames > endFrame - startFrame))
{
float ssimFrame = 0.0;
int sh = window/2+1;
int numPixels = 0;
for(int i=sh;i<height-sh;i++)
for(int j=sh;j<width-sh;j++)
{
avgTest[0] = 0.0;
avgRef[0] = 0.0;
contrastTest[0] = 0.0;
contrastRef[0] = 0.0;
crossCorr[0] = 0.0;
numPixels +=1;
//for uniform window, only need to loop over whole window for first column pixel in image, and then shift
if (j == sh || flag_window == 1)
{
//initialize statistics
for(int k=1;k<window+2;k++)
{
avgTest[k] = 0.0;
avgRef[k] = 0.0;
contrastTest[k] = 0.0;
contrastRef[k] = 0.0;
crossCorr[k] = 0.0;
}
int nn=-1;
//compute contrast and correlation
for(int jj=-window/2;jj<=window/2;jj++)
for(int ii=-window/2;ii<=window/2;ii++)
{
nn+=1;
int i2 = i+ii;
int j2 = j+jj;
float tmp1 = (float)test[i2*width+j2];
float tmp2 = (float)ref[i2*width+j2];
//local average of each signal
avgTest[jj+window/2+1] += ssimFilter[nn]*tmp1;
avgRef[jj+window/2+1] += ssimFilter[nn]*tmp2;
//local correlation/contrast of each signal
contrastTest[jj+window/2+1] += ssimFilter[nn]*tmp1*tmp1;
contrastRef[jj+window/2+1] += ssimFilter[nn]*tmp2*tmp2;
//local cross correlation
crossCorr[jj+window/2+1] += ssimFilter[nn]*tmp1*tmp2;
}
}
//for uniform window case, can shift window horiz, then compute statistics for last column in window
else
{
//shift statistics horiz.
for(int k=1;k<window+1;k++)
{
avgTest[k]=avgTest[k+1];
avgRef[k]=avgRef[k+1];
contrastTest[k] = contrastTest[k+1];
contrastRef[k] = contrastRef[k+1];
crossCorr[k] = crossCorr[k+1];
}
//compute statistics for last column
avgTest[window+1] = 0.0;
avgRef[window+1] = 0.0;
contrastTest[window+1] = 0.0;
contrastRef[window+1] = 0.0;
crossCorr[window+1] = 0.0;
int nn = (window+1)*window - 1;
int jj = window/2;
int j2 = j + jj;
for(int ii=-window/2;ii<=window/2;ii++)
{
nn+=1;
int i2 = i+ii;
float tmp1 = (float)test[i2*width+j2];
float tmp2 = (float)ref[i2*width+j2];
//local average of each signal
avgTest[jj+window/2+1] += ssimFilter[nn]*tmp1;
avgRef[jj+window/2+1] += ssimFilter[nn]*tmp2;
//local correlation/contrast of each signal
contrastTest[jj+window/2+1] += ssimFilter[nn]*tmp1*tmp1;
contrastRef[jj+window/2+1] += ssimFilter[nn]*tmp2*tmp2;
//local cross correlation
crossCorr[jj+window/2+1] += ssimFilter[nn]*tmp1*tmp2;
}
}
//sum over all columns
for(int k=1;k<window+2;k++)
{
avgTest[0] += avgTest[k];
avgRef[0] += avgRef[k];
contrastTest[0] += contrastTest[k];
contrastRef[0] += contrastRef[k];
crossCorr[0] += crossCorr[k];
}
float tmp1 = (contrastTest[0] - avgTest[0]*avgTest[0]);
if (tmp1 < 0.0) tmp1 = 0.0;
contrastTest[0] = sqrt(tmp1);
float tmp2 = (contrastRef[0] - avgRef[0]*avgRef[0]);
if (tmp2 < 0.0) tmp2 = 0.0;
contrastRef[0] = sqrt(tmp2);
crossCorr[0] = crossCorr[0] - avgTest[0]*avgRef[0];
float ssimCorrCoeff = (crossCorr[0]+offset3)/(contrastTest[0]*contrastRef[0] + offset3);
float ssimLuminance = (2*avgTest[0]*avgRef[0]+offset1)/(avgTest[0]*avgTest[0] + avgRef[0]*avgRef[0] + offset1);
float ssimContrast = (2*contrastTest[0]*contrastRef[0]+offset2)/(contrastTest[0]*contrastTest[0] + contrastRef[0]*contrastRef[0] + offset2);
float ssimPixel = ssimCorrCoeff * ssimLuminance * ssimContrast;
ssimFrame += ssimPixel;
}
ssimFrame = ssimFrame / (numPixels);
//printf("***SSIM for frame ***%f \n",ssimFrame);
ssimScene += ssimFrame;
//
//SSIM: done with SSIM computation
//
frames++;
refBytes = (int) fread(ref, 1, frameBytes, refFp);
testBytes = (int) fread(test, 1, frameBytes, testFp);
}
//SSIM: normalize/average for sequence
ssimScene = ssimScene / frames;
*SSIMptr = ssimScene;
delete [] ref;
delete [] test;
fclose(refFp);
fclose(testFp);
return 0;
}
bool
Test::SSIMthread(void *vctx)
{
SSIMcontext *ctx = (SSIMcontext *) vctx;
SSIMfromFiles(ctx->refFileName, ctx->testFileName, ctx->width, ctx->height, ctx->SSIMptr, ctx->startFrame, ctx->endFrame);
ctx->evnt->Set();
return false;
}
double Test::SSIMfromFilesMT(const int numThreads)
{
int numFrames = filesize(_inname.c_str()) / _lengthSourceFrame;
std::vector<int> nFramesVec(numThreads);
std::vector<double> ssimVec(numThreads);
int framesPerCore = (numFrames + numThreads - 1) / numThreads; // rounding up
int i = 0;
int nFrames;
for (nFrames = numFrames; nFrames >= framesPerCore; nFrames -= framesPerCore)
{
nFramesVec[i++] = framesPerCore;
}
if (nFrames > 0)
{
assert(i == numThreads - 1);
nFramesVec[i] = nFrames; // remainder
}
int frameIx = 0;
std::vector<EventWrapper*> eventVec(numThreads);
std::vector<ThreadWrapper*> threadVec(numThreads);
std::vector<SSIMcontext> ctxVec(numThreads);
for (i = 0; i < numThreads; i++)
{
eventVec[i] = EventWrapper::Create();
ctxVec[i] = SSIMcontext(_inname.c_str(), _outname.c_str(), _inst.width, _inst.height, &ssimVec[i], frameIx, frameIx + nFramesVec[i] - 1, eventVec[i]);
threadVec[i] = ThreadWrapper::CreateThread(SSIMthread, &(ctxVec[i]), kLowPriority);
unsigned int id;
threadVec[i]->Start(id);
frameIx += nFramesVec[i];
}
// wait for all events
for (i = 0; i < numThreads; i++) {
eventVec[i]->Wait(100000 /* ms*/);
threadVec[i]->Stop();
delete threadVec[i];
delete eventVec[i];
}
double avgSsim = 0;
for (i = 0; i < numThreads; i++)
{
avgSsim += (ssimVec[i] * nFramesVec[i]);
}
avgSsim /= numFrames;
return avgSsim;
}
double Test::ActualBitRate(int nFrames)
{
return 8.0 * _sumEncBytes / (nFrames / _inst.maxFramerate);
@@ -526,11 +156,10 @@ Test::VideoEncodedBufferToEncodedImage(TestVideoEncodedBuffer& videoBuffer, Enco
long filesize(const char *filename)
{
FILE *f = fopen(filename,"rb"); /* open the file in read only */
long size = 0;
if (fseek(f,0,SEEK_END)==0) /* seek was successful */
size = ftell(f);
fclose(f);
return size;
FILE *f = fopen(filename,"rb"); /* open the file in read only */
long size = 0;
if (fseek(f,0,SEEK_END)==0) /* seek was successful */
size = ftell(f);
fclose(f);
return size;
}

View File

@@ -36,20 +36,6 @@ protected:
WebRtc_UWord32 frameRate=30,
WebRtc_UWord32 bitRate=0);
virtual void Teardown();
static int PSNRfromFiles(const char *refFileName,
const char *testFileName,
int width,
int height,
double *YPSNRptr);
static int SSIMfromFiles(const char *refFileName,
const char *testFileName,
int width,
int height,
double *SSIMptr,
int startByte = -1, int endByte = -1);
double SSIMfromFilesMT(int numThreads);
static bool SSIMthread(void *ctx);
double ActualBitRate(int nFrames);
virtual bool PacketLoss(double lossRate, int /*thrown*/);
static double RandUniform() { return (std::rand() + 1.0)/(RAND_MAX + 1.0); }

View File

@@ -16,6 +16,7 @@
'type': '<(library)',
'dependencies': [
'<(webrtc_root)/../test/metrics.gyp:metrics',
'<(webrtc_root)/../test/test.gyp:test_support',
'<(webrtc_root)/../testing/gtest.gyp:gtest',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',

View File

@@ -18,6 +18,7 @@
'video_codecs_test_framework',
'webrtc_video_coding',
'webrtc_vp8',
'<(webrtc_root)/../test/metrics.gyp:metrics',
'<(webrtc_root)/../third_party/google-gflags/google-gflags.gyp:google-gflags',
],
'sources': [

View File

@@ -265,29 +265,27 @@ int HandleCommandLineFlags(webrtc::test::TestConfig* config) {
}
void CalculateSsimVideoMetrics(webrtc::test::TestConfig* config,
QualityMetricsResult* ssimResult) {
webrtc::test::QualityMetricsResult* result) {
Log("Calculating SSIM...\n");
SsimFromFiles(config->input_filename.c_str(), config->output_filename.c_str(),
config->codec_settings->width,
config->codec_settings->height, ssimResult);
Log(" Average: %3.2f\n", ssimResult->average);
Log(" Min : %3.2f (frame %d)\n", ssimResult->min,
ssimResult->min_frame_number);
Log(" Max : %3.2f (frame %d)\n", ssimResult->max,
ssimResult->max_frame_number);
I420SSIMFromFiles(config->input_filename.c_str(),
config->output_filename.c_str(),
config->codec_settings->width,
config->codec_settings->height, result);
Log(" Average: %3.2f\n", result->average);
Log(" Min : %3.2f (frame %d)\n", result->min, result->min_frame_number);
Log(" Max : %3.2f (frame %d)\n", result->max, result->max_frame_number);
}
void CalculatePsnrVideoMetrics(webrtc::test::TestConfig* config,
QualityMetricsResult* psnrResult) {
webrtc::test::QualityMetricsResult* result) {
Log("Calculating PSNR...\n");
PsnrFromFiles(config->input_filename.c_str(), config->output_filename.c_str(),
I420PSNRFromFiles(config->input_filename.c_str(),
config->output_filename.c_str(),
config->codec_settings->width,
config->codec_settings->height, psnrResult);
Log(" Average: %3.2f\n", psnrResult->average);
Log(" Min : %3.2f (frame %d)\n", psnrResult->min,
psnrResult->min_frame_number);
Log(" Max : %3.2f (frame %d)\n", psnrResult->max,
psnrResult->max_frame_number);
config->codec_settings->height, result);
Log(" Average: %3.2f\n", result->average);
Log(" Min : %3.2f (frame %d)\n", result->min, result->min_frame_number);
Log(" Max : %3.2f (frame %d)\n", result->max, result->max_frame_number);
}
void PrintConfigurationSummary(const webrtc::test::TestConfig& config) {
@@ -312,8 +310,8 @@ void PrintConfigurationSummary(const webrtc::test::TestConfig& config) {
}
void PrintCsvOutput(const webrtc::test::Stats& stats,
const QualityMetricsResult& ssimResult,
const QualityMetricsResult& psnrResult) {
const webrtc::test::QualityMetricsResult& ssim_result,
const webrtc::test::QualityMetricsResult& psnr_result) {
Log("\nCSV output (recommended to run with --noverbose to skip the "
"above output)\n");
printf("frame_number encoding_successful decoding_successful "
@@ -325,8 +323,8 @@ void PrintCsvOutput(const webrtc::test::Stats& stats,
for (unsigned int i = 0; i < stats.stats_.size(); ++i) {
const webrtc::test::FrameStatistic& f = stats.stats_[i];
const FrameResult& ssim = ssimResult.frames[i];
const FrameResult& psnr = psnrResult.frames[i];
const webrtc::test::FrameResult& ssim = ssim_result.frames[i];
const webrtc::test::FrameResult& psnr = psnr_result.frames[i];
printf("%4d, %d, %d, %2d, %2d, %6d, %6d, %5d, %7d, %d, %2d, %2d, "
"%5.3f, %5.2f\n",
f.frame_number,
@@ -348,8 +346,8 @@ void PrintCsvOutput(const webrtc::test::Stats& stats,
void PrintPythonOutput(const webrtc::test::TestConfig& config,
const webrtc::test::Stats& stats,
const QualityMetricsResult& ssimResult,
const QualityMetricsResult& psnrResult) {
const webrtc::test::QualityMetricsResult& ssim_result,
const webrtc::test::QualityMetricsResult& psnr_result) {
Log("\nPython output (recommended to run with --noverbose to skip the "
"above output)\n");
printf("test_configuration = ["
@@ -412,8 +410,8 @@ void PrintPythonOutput(const webrtc::test::TestConfig& config,
printf("frame_data = [");
for (unsigned int i = 0; i < stats.stats_.size(); ++i) {
const webrtc::test::FrameStatistic& f = stats.stats_[i];
const FrameResult& ssim = ssimResult.frames[i];
const FrameResult& psnr = psnrResult.frames[i];
const webrtc::test::FrameResult& ssim = ssim_result.frames[i];
const webrtc::test::FrameResult& psnr = psnr_result.frames[i];
printf("{'frame_number': %d, "
"'encoding_successful': %s, 'decoding_successful': %s, "
"'encode_time': %d, 'decode_time': %d, "
@@ -508,9 +506,9 @@ int main(int argc, char* argv[]) {
stats.PrintSummary();
QualityMetricsResult ssim_result;
webrtc::test::QualityMetricsResult ssim_result;
CalculateSsimVideoMetrics(&config, &ssim_result);
QualityMetricsResult psnr_result;
webrtc::test::QualityMetricsResult psnr_result;
CalculatePsnrVideoMetrics(&config, &psnr_result);
if (FLAGS_csv) {

View File

@@ -13,6 +13,7 @@
'dependencies': [
'<(webrtc_root)/../testing/gtest.gyp:gtest',
'<(webrtc_root)/../test/test.gyp:test_support',
'<(webrtc_root)/../test/metrics.gyp:metrics',
'webrtc_video_coding',
'rtp_rtcp',
'webrtc_utility',

View File

@@ -368,8 +368,9 @@ CodecDataBaseTest::Perform(CmdArgs& args)
_vcm->Decode();
// Don't measure PSNR for I420 since it will be perfect.
if (sendCodec.codecType != kVideoCodecI420) {
QualityMetricsResult psnr;
PsnrFromFiles(_inname.c_str(), _outname.c_str(), _width, _height, &psnr);
webrtc::test::QualityMetricsResult psnr;
I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _width,
_height, &psnr);
printf("\n @ %d KBPS: ", sendCodec.startBitrate);
printf("PSNR from encoder-decoder send-receive control test"
"is %f\n\n", psnr.average);

View File

@@ -480,8 +480,9 @@ MediaOptTest::Print(int mode)
{
double ActualBitRate = 8.0 *( _sumEncBytes / (_frameCnt / _frameRate));
double actualBitRate = ActualBitRate / 1000.0;
QualityMetricsResult psnr;
PsnrFromFiles(_actualSourcename.c_str(), _outname.c_str(), _width, _height, &psnr);
webrtc::test::QualityMetricsResult psnr;
I420PSNRFromFiles(_actualSourcename.c_str(), _outname.c_str(), _width,
_height, &psnr);
(_log) << "VCM: Media Optimization Test Cycle Completed!" << std::endl;
(_log) << "Input file: " << _inname << std::endl;

View File

@@ -367,9 +367,11 @@ NormalTest::Print()
double actualBitRate = ActualBitRate / 1000.0;
double avgEncTime = _totalEncodeTime / _frameCnt;
double avgDecTime = _totalDecodeTime / _frameCnt;
QualityMetricsResult psnr, ssim;
PsnrFromFiles(_inname.c_str(), _outname.c_str(), _width, _height, &psnr);
SsimFromFiles(_inname.c_str(), _outname.c_str(), _width, _height, &ssim);
webrtc::test::QualityMetricsResult psnr, ssim;
I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
&psnr);
I420SSIMFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
&ssim);
printf("Actual bitrate: %f kbps\n", actualBitRate);
printf("Target bitrate: %f kbps\n", _bitRate);
( _log) << "Actual bitrate: " << actualBitRate<< " kbps\tTarget: " << _bitRate << " kbps" << std::endl;

View File

@@ -113,8 +113,9 @@ QualityModesTest::Print()
double actualBitRate = ActualBitRate / 1000.0;
double avgEncTime = _totalEncodeTime / _frameCnt;
double avgDecTime = _totalDecodeTime / _frameCnt;
QualityMetricsResult psnr,ssim;
PsnrFromFiles(_inname.c_str(), _outname.c_str(), _nativeWidth, _nativeHeight, &psnr);
webrtc::test::QualityMetricsResult psnr,ssim;
I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _nativeWidth,
_nativeHeight, &psnr);
printf("Actual bitrate: %f kbps\n", actualBitRate);
printf("Target bitrate: %f kbps\n", _bitRate);
( _log) << "Actual bitrate: " << actualBitRate<< " kbps\tTarget: " << _bitRate << " kbps" << std::endl;
@@ -128,7 +129,8 @@ QualityModesTest::Print()
if (_flagSSIM == 1)
{
printf("***computing SSIM***\n");
SsimFromFiles(_inname.c_str(), _outname.c_str(), _nativeWidth, _nativeHeight, &ssim);
I420SSIMFromFiles(_inname.c_str(), _outname.c_str(), _nativeWidth,
_nativeHeight, &ssim);
printf("SSIM: %f \n", ssim.average);
}
(_log) << std::endl;

View File

@@ -8,15 +8,15 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "framedrop_primitives.h"
#include "gflags/gflags.h"
#include "gtest/gtest.h"
#include "testsupport/fileutils.h"
#include "testsupport/metrics/video_metrics.h"
#include "vie_autotest.h"
#include "vie_file_based_comparison_tests.h"
#include "vie_integration_test_base.h"
#include "vie_to_file_renderer.h"
#include "video_engine/test/auto_test/automated/vie_integration_test_base.h"
#include "video_engine/test/auto_test/helpers/vie_to_file_renderer.h"
#include "video_engine/test/auto_test/interface/vie_autotest.h"
#include "video_engine/test/auto_test/interface/vie_file_based_comparison_tests.h"
#include "video_engine/test/auto_test/primitives/framedrop_primitives.h"
namespace {
@@ -79,17 +79,17 @@ class ViEVideoVerificationTest : public testing::Test {
void CompareFiles(const std::string& reference_file,
const std::string& test_file,
double minimum_psnr, double minimum_ssim) {
QualityMetricsResult psnr;
int psnr_error = PsnrFromFiles(reference_file.c_str(), test_file.c_str(),
kInputWidth, kInputHeight, &psnr);
ASSERT_EQ(0, psnr_error) << "PSNR routine failed - output files missing?";
ASSERT_GT(psnr.average, minimum_psnr);
webrtc::test::QualityMetricsResult psnr;
int error = I420PSNRFromFiles(reference_file.c_str(), test_file.c_str(),
kInputWidth, kInputHeight, &psnr);
EXPECT_EQ(0, error) << "PSNR routine failed - output files missing?";
EXPECT_GT(psnr.average, minimum_psnr);
QualityMetricsResult ssim;
int ssim_error = SsimFromFiles(reference_file.c_str(), test_file.c_str(),
kInputWidth, kInputHeight, &ssim);
ASSERT_EQ(0, ssim_error) << "SSIM routine failed - output files missing?";
ASSERT_GT(ssim.average, minimum_ssim); // 1 = perfect, -1 = terrible
webrtc::test::QualityMetricsResult ssim;
error = I420SSIMFromFiles(reference_file.c_str(), test_file.c_str(),
kInputWidth, kInputHeight, &ssim);
EXPECT_EQ(0, error) << "SSIM routine failed - output files missing?";
EXPECT_GT(ssim.average, minimum_ssim); // 1 = perfect, -1 = terrible
ViETest::Log("Results: PSNR: %f (db) SSIM: %f",
psnr.average, ssim.average);

View File

@@ -18,6 +18,7 @@
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine_core',
'<(webrtc_root)/../testing/gtest.gyp:gtest',
'<(webrtc_root)/../third_party/google-gflags/google-gflags.gyp:google-gflags',
'<(webrtc_root)/../test/metrics.gyp:metrics',
'<(webrtc_root)/../test/test.gyp:test_support',
'video_engine_core',
],