Added possibility to run quality modes test. Added possibility to input arguments to the test. The test will (for each frame) log the values in contentMetrics to a txt-file. The txt-file can optionally be saved in a specific place. Fixed an issue where video_coding_test crashed if there weren't any parameter submitted to an input argument.

BUG=

Review URL: https://webrtc-codereview.appspot.com/772005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3068 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
brykt@google.com
2012-11-09 16:16:41 +00:00
parent 9cb9fc17b1
commit e8ef807a2d
7 changed files with 886 additions and 749 deletions

View File

@@ -27,7 +27,7 @@
using namespace webrtc;
int NormalTest::RunTest(CmdArgs& args)
int NormalTest::RunTest(const CmdArgs& args)
{
#if defined(EVENT_DEBUG)
printf("SIMULATION TIME\n");
@@ -67,8 +67,8 @@ VCMNTEncodeCompleteCallback::~VCMNTEncodeCompleteCallback()
{
}
void
VCMNTEncodeCompleteCallback::RegisterTransportCallback(VCMPacketizationCallback* transport)
void VCMNTEncodeCompleteCallback::RegisterTransportCallback(
VCMPacketizationCallback* transport)
{
}
@@ -207,7 +207,7 @@ NormalTest::~NormalTest()
//
}
void
NormalTest::Setup(CmdArgs& args)
NormalTest::Setup(const CmdArgs& args)
{
_inname = args.inputFile;
_encodedName = test::OutputPath() + "encoded_normaltest.yuv";
@@ -242,23 +242,24 @@ NormalTest::Setup(CmdArgs& args)
_log.open((test::OutputPath() + "TestLog.txt").c_str(),
std::fstream::out | std::fstream::app);
return;
}
WebRtc_Word32
NormalTest::Perform(CmdArgs& args)
NormalTest::Perform(const CmdArgs& args)
{
Setup(args);
EventWrapper* waitEvent = EventWrapper::Create();
VideoCodec _sendCodec;//, _receiveCodec; // tmp - sendCodecd used as receive codec
VideoCodec _sendCodec;
_vcm->InitializeReceiver();
_vcm->InitializeSender();
TEST(VideoCodingModule::Codec(_videoType, &_sendCodec) == VCM_OK);
_sendCodec.startBitrate = (int)_bitRate; // should be later on changed via the API
// should be later on changed via the API
_sendCodec.startBitrate = (int)_bitRate;
_sendCodec.width = static_cast<WebRtc_UWord16>(_width);
_sendCodec.height = static_cast<WebRtc_UWord16>(_height);
_sendCodec.maxFramerate = _frameRate;
TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1400) == VCM_OK);// will also set and init the desired codec
// will also set and init the desired codec
TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1400) == VCM_OK);
// register a decoder (same codec for decoder and encoder )
TEST(_vcm->RegisterReceiveCodec(&_sendCodec, 1) == VCM_OK);
/* Callback Settings */
@@ -286,8 +287,7 @@ NormalTest::Perform(CmdArgs& args)
sendStats.SetTargetFrameRate(static_cast<WebRtc_UWord32>(_frameRate));
_vcm->RegisterSendStatisticsCallback(&sendStats);
while (feof(_sourceFile) == 0)
{
while (feof(_sourceFile) == 0) {
#if !defined(EVENT_DEBUG)
WebRtc_Word64 processStartTime = _clock->MillisecondTimestamp();
#endif
@@ -299,7 +299,8 @@ NormalTest::Perform(CmdArgs& args)
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_sendCodec.maxFramerate));
_timeStamp +=
(WebRtc_UWord32)(9e4 / static_cast<float>(_sendCodec.maxFramerate));
sourceFrame.set_timestamp(_timeStamp);
_encodeTimes[int(sourceFrame.timestamp())] =
clock()/(double)CLOCKS_PER_SEC;
@@ -326,11 +327,15 @@ NormalTest::Perform(CmdArgs& args)
{
_vcm->Process();
}
WebRtc_UWord32 framePeriod = static_cast<WebRtc_UWord32>(1000.0f/static_cast<float>(_sendCodec.maxFramerate) + 0.5f);
WebRtc_UWord32 framePeriod =
static_cast<WebRtc_UWord32>(
1000.0f / static_cast<float>(_sendCodec.maxFramerate) + 0.5f);
#if defined(EVENT_DEBUG)
static_cast<FakeTickTime*>(_clock)->IncrementDebugClock(framePeriod);
#else
WebRtc_Word64 timeSpent = _clock->MillisecondTimestamp() - processStartTime;
WebRtc_Word64 timeSpent =
_clock->MillisecondTimestamp() - processStartTime;
if (timeSpent < framePeriod)
{
waitEvent->Wait(framePeriod - timeSpent);
@@ -385,7 +390,8 @@ NormalTest::Print()
&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;
( _log) << "Actual bitrate: " << actualBitRate <<
" kbps\tTarget: " << _bitRate << " kbps" << std::endl;
printf("Average encode time: %f s\n", avgEncTime);
( _log) << "Average encode time: " << avgEncTime << " s" << std::endl;
printf("Average decode time: %f s\n", avgDecTime);

View File

@@ -18,17 +18,20 @@
class NormalTest;
//Send Side - Packetization callback - will create and send a packet to the VCMReceiver
//Send Side - Packetization callback -
// will create and send a packet to the VCMReceiver
class VCMNTEncodeCompleteCallback : public webrtc::VCMPacketizationCallback
{
public:
public:
// constructor input: file in which encoded data will be written
VCMNTEncodeCompleteCallback(FILE* encodedFile, NormalTest& test);
virtual ~VCMNTEncodeCompleteCallback();
// Register transport callback
void RegisterTransportCallback(webrtc::VCMPacketizationCallback* transport);
// process encoded data received from the encoder, pass stream to the VCMReceiver module
WebRtc_Word32 SendData(const webrtc::FrameType frameType,
// process encoded data received from the encoder,
// pass stream to the VCMReceiver module
WebRtc_Word32
SendData(const webrtc::FrameType frameType,
const WebRtc_UWord8 payloadType,
const WebRtc_UWord32 timeStamp,
int64_t capture_time_ms,
@@ -37,7 +40,8 @@ public:
const webrtc::RTPFragmentationHeader& fragmentationHeader,
const webrtc::RTPVideoHeader* videoHdr);
// Register exisitng VCM. Currently - encode and decode with the same vcm module.
// Register exisitng VCM.
// Currently - encode and decode with the same vcm module.
void RegisterReceiverVCM(webrtc::VideoCodingModule *vcm);
// Return sum of encoded data (all frames in the sequence)
WebRtc_Word32 EncodedBytes();
@@ -46,7 +50,7 @@ public:
// conversion function for payload type (needed for the callback function)
// RTPVideoVideoCodecTypes ConvertPayloadType(WebRtc_UWord8 payloadType);
private:
private:
FILE* _encodedFile;
WebRtc_UWord32 _encodedBytes;
WebRtc_UWord32 _skipCnt;
@@ -76,18 +80,16 @@ private:
int _decodedBytes;
int _currentWidth;
int _currentHeight;
}; // end of VCMDecodeCompleCallback class
class NormalTest
{
public:
NormalTest(webrtc::VideoCodingModule* vcm,
webrtc::TickTimeBase* clock);
~NormalTest();
static int RunTest(CmdArgs& args);
WebRtc_Word32 Perform(CmdArgs& args);
static int RunTest(const CmdArgs& args);
WebRtc_Word32 Perform(const CmdArgs& args);
// option:: turn into private and call from perform
int Width() const { return _width; };
int Height() const { return _height; };
@@ -96,7 +98,7 @@ public:
protected:
// test setup - open files, general initializations
void Setup(CmdArgs& args);
void Setup(const CmdArgs& args);
// close open files, delete used memory
void Teardown();
// print results to std output and to log file

View File

@@ -10,34 +10,34 @@
#include "quality_modes_test.h"
#include <time.h>
#include <iostream>
#include <string>
#include <time.h>
#include <sstream>
#include "../source/event.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/video_coding/main/source/event.h"
#include "modules/video_coding/main/source/mock/fake_tick_time.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "test_callbacks.h"
#include "test_macros.h"
#include "modules/video_coding/main/test/test_callbacks.h"
#include "modules/video_coding/main/test/test_macros.h"
#include "modules/video_coding/main/test/test_util.h"
#include "system_wrappers/interface/data_log.h"
#include "system_wrappers/interface/data_log.h"
#include "testsupport/metrics/video_metrics.h"
using namespace webrtc;
int qualityModeTest()
int qualityModeTest(const CmdArgs& args)
{
// Don't run this test with debug events.
#if defined(EVENT_DEBUG)
return -1;
#endif
TickTimeBase clock;
FakeTickTime clock(0);
VideoCodingModule* vcm = VideoCodingModule::Create(1, &clock);
QualityModesTest QMTest(vcm, &clock);
QMTest.Perform();
QMTest.Perform(args);
VideoCodingModule::Destroy(vcm);
return 0;
}
QualityModesTest::QualityModesTest(VideoCodingModule* vcm,
TickTimeBase* clock):
NormalTest(vcm, clock),
@@ -46,35 +46,37 @@ _vpm()
//
}
QualityModesTest::~QualityModesTest()
{
//
}
void
QualityModesTest::Setup()
QualityModesTest::Setup(const CmdArgs& args)
{
NormalTest::Setup(args);
_inname = args.inputFile;
_outname = args.outputFile;
fv_outfilename_ = args.fv_outputfile;
filename_testvideo_ =
_inname.substr(_inname.find_last_of("\\/") + 1,_inname.length());
_inname= test::ProjectRootPath() + "resources/crew_30f_4CIF.yuv";
_outname = test::OutputPath() + "out_qmtest.yuv";
_encodedName = test::OutputPath() + "encoded_qmtest.yuv";
//NATIVE/SOURCE VALUES
_nativeWidth = 2*352;
_nativeHeight = 2*288;
_nativeFrameRate = 30;
_nativeWidth = args.width;
_nativeHeight = args.height;
_nativeFrameRate =args.frameRate;
//TARGET/ENCODER VALUES
_width = 2*352;
_height = 2*288;
_frameRate = 30;
//
_bitRate = 400;
_width = args.width;
_height = args.height;
_frameRate = args.frameRate;
_flagSSIM = false;
_bitRate = args.bitRate;
_flagSSIM = true;
_lengthSourceFrame = 3*_nativeWidth*_nativeHeight/2;
@@ -94,12 +96,26 @@ QualityModesTest::Setup()
exit(1);
}
DataLog::CreateLog();
feature_table_name_ = fv_outfilename_;
DataLog::AddTable(feature_table_name_);
DataLog::AddColumn(feature_table_name_, "motion magnitude", 1);
DataLog::AddColumn(feature_table_name_, "spatial prediction error", 1);
DataLog::AddColumn(feature_table_name_, "spatial pred err horizontal", 1);
DataLog::AddColumn(feature_table_name_, "spatial pred err vertical", 1);
DataLog::AddColumn(feature_table_name_, "width", 1);
DataLog::AddColumn(feature_table_name_, "height", 1);
DataLog::AddColumn(feature_table_name_, "num pixels", 1);
DataLog::AddColumn(feature_table_name_, "frame rate", 1);
DataLog::AddColumn(feature_table_name_, "num frames since drop", 1);
_log.open((test::OutputPath() + "TestLog.txt").c_str(),
std::fstream::out | std::fstream::app);
return;
}
void
QualityModesTest::Print()
{
@@ -109,7 +125,7 @@ QualityModesTest::Print()
(_log) << "Output file: " << _outname << std::endl;
(_log) << "Total run time: " << _testTotalTime << std::endl;
printf("Total run time: %f s \n", _testTotalTime);
double ActualBitRate = 8.0 *( _sumEncBytes / (_frameCnt / _nativeFrameRate));
double ActualBitRate = 8.0*( _sumEncBytes / (_frameCnt / _nativeFrameRate));
double actualBitRate = ActualBitRate / 1000.0;
double avgEncTime = _totalEncodeTime / _frameCnt;
double avgDecTime = _totalDecodeTime / _frameCnt;
@@ -118,7 +134,8 @@ QualityModesTest::Print()
_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;
( _log) << "Actual bitrate: " << actualBitRate<< " kbps\tTarget: " <<
_bitRate << " kbps" << std::endl;
printf("Average encode time: %f s\n", avgEncTime);
( _log) << "Average encode time: " << avgEncTime << " s" << std::endl;
printf("Average decode time: %f s\n", avgDecTime);
@@ -135,7 +152,7 @@ QualityModesTest::Print()
}
(_log) << std::endl;
printf("\nVCM Qualit Modes Test: \n\n%i tests completed\n", vcmMacrosTests);
printf("\nVCM Quality Modes Test: \n\n%i tests completed\n", vcmMacrosTests);
if (vcmMacrosErrors > 0)
{
printf("%i FAILED\n\n", vcmMacrosErrors);
@@ -155,21 +172,20 @@ QualityModesTest::Teardown()
return;
}
WebRtc_Word32
QualityModesTest::Perform()
QualityModesTest::Perform(const CmdArgs& args)
{
Setup();
Setup(args);
// changing bit/frame rate during the test
const float bitRateUpdate[] = {1000};
const float frameRateUpdate[] = {30};
const int updateFrameNum[] = {10000}; // frame numbers at which an update will occur
// frame num at which an update will occur
const int updateFrameNum[] = {10000};
WebRtc_UWord32 numChanges = sizeof(updateFrameNum)/sizeof(*updateFrameNum);
WebRtc_UWord8 change = 0;// change counter
_vpm = VideoProcessingModule::Create(1);
EventWrapper* waitEvent = EventWrapper::Create();
VideoCodec codec;//both send and receive
_vcm->InitializeReceiver();
@@ -184,7 +200,10 @@ QualityModesTest::Perform()
codec.maxFramerate = (WebRtc_UWord8) _frameRate;
codec.width = (WebRtc_UWord16)_width;
codec.height = (WebRtc_UWord16)_height;
TEST(_vcm->RegisterSendCodec(&codec, 2, 1440) == VCM_OK);// will also set and init the desired codec
codec.codecSpecific.VP8.frameDroppingOn = false;
// Will also set and init the desired codec
TEST(_vcm->RegisterSendCodec(&codec, 2, 1440) == VCM_OK);
i = NumberOfCodecs;
}
}
@@ -192,7 +211,8 @@ QualityModesTest::Perform()
// register a decoder (same codec for decoder and encoder )
TEST(_vcm->RegisterReceiveCodec(&codec, 2) == VCM_OK);
/* Callback Settings */
VCMQMDecodeCompleCallback _decodeCallback(_decodedFile);
VCMQMDecodeCompleCallback _decodeCallback(
_decodedFile, _nativeFrameRate, feature_table_name_);
_vcm->RegisterReceiveCallback(&_decodeCallback);
VCMNTEncodeCompleteCallback _encodeCompleteCallback(_encodedFile, *this);
_vcm->RegisterTransportCallback(&_encodeCompleteCallback);
@@ -203,7 +223,7 @@ QualityModesTest::Perform()
QMTestVideoSettingsCallback QMCallback;
QMCallback.RegisterVCM(_vcm);
QMCallback.RegisterVPM(_vpm);
_vcm->RegisterVideoQMCallback(&QMCallback);
//_vcm->RegisterVideoQMCallback(&QMCallback);
///////////////////////
/// Start Test
@@ -229,18 +249,18 @@ QualityModesTest::Perform()
// setting user frame rate
_vpm->SetMaxFrameRate((WebRtc_UWord32)(_nativeFrameRate+ 0.5f));
// for starters: keeping native values:
_vpm->SetTargetResolution(_width, _height, (WebRtc_UWord32)(_frameRate+ 0.5f));
_vpm->SetTargetResolution(_width, _height,
(WebRtc_UWord32)(_frameRate+ 0.5f));
_decodeCallback.SetOriginalFrameDimensions(_nativeWidth, _nativeHeight);
//tmp - disabling VPM frame dropping
_vpm->EnableTemporalDecimation(false);
WebRtc_Word32 ret = 0;
_numFramesDroppedVPM = 0;
while (feof(_sourceFile)== 0)
{
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
do {
if (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0) {
_frameCnt++;
int size_y = _nativeWidth * _nativeHeight;
int size_uv = ((_nativeWidth + 1) / 2) * ((_nativeHeight + 1) / 2);
@@ -251,7 +271,8 @@ QualityModesTest::Perform()
_nativeWidth, (_nativeWidth + 1) / 2,
(_nativeWidth + 1) / 2);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(codec.maxFramerate));
_timeStamp +=
(WebRtc_UWord32)(9e4 / static_cast<float>(codec.maxFramerate));
sourceFrame.set_timestamp(_timeStamp);
ret = _vpm->PreprocessFrame(sourceFrame, &decimatedFrame);
@@ -266,6 +287,11 @@ QualityModesTest::Perform()
printf("Error in PreprocessFrame: %d\n", ret);
//exit(1);
}
// Frame was not re-sampled => use original.
if (decimatedFrame == NULL)
{
decimatedFrame = &sourceFrame;
}
contentMetrics = _vpm->ContentMetrics();
if (contentMetrics == NULL)
{
@@ -286,11 +312,15 @@ QualityModesTest::Perform()
printf("Error in AddFrame: %d\n", ret);
//exit(1);
}
_decodeTimes[int(sourceFrame.timestamp())] = clock() /
(double)CLOCKS_PER_SEC - _decodeTimes[int(sourceFrame.timestamp())];
// Same timestamp value for encode and decode
_decodeTimes[int(sourceFrame.timestamp())] =
clock()/(double)CLOCKS_PER_SEC;
ret = _vcm->Decode();
_totalDecodeTime += clock()/(double)CLOCKS_PER_SEC -
_decodeTimes[int(sourceFrame.timestamp())];
if (ret < 0)
{
printf("Error in Decode: %d\n", ret);
@@ -305,9 +335,8 @@ QualityModesTest::Perform()
if (_frameCnt%((int)_frameRate) == 0)
{
_vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 1);
waitEvent->Wait(33);
}
waitEvent->Wait(33);
// check for bit rate update
if (change < numChanges && _frameCnt == updateFrameNum[change])
{
@@ -315,11 +344,37 @@ QualityModesTest::Perform()
_frameRate = frameRateUpdate[change];
codec.startBitrate = (int)_bitRate;
codec.maxFramerate = (WebRtc_UWord8) _frameRate;
// Will also set and init the desired codec
TEST(_vcm->RegisterSendCodec(&codec, 2, 1440) == VCM_OK);
change++;
}
DataLog::InsertCell(feature_table_name_, "motion magnitude",
contentMetrics->motion_magnitude);
DataLog::InsertCell(feature_table_name_, "spatial prediction error",
contentMetrics->spatial_pred_err);
DataLog::InsertCell(feature_table_name_, "spatial pred err horizontal",
contentMetrics->spatial_pred_err_h);
DataLog::InsertCell(feature_table_name_, "spatial pred err vertical",
contentMetrics->spatial_pred_err_v);
DataLog::InsertCell(feature_table_name_, "width", _nativeHeight);
DataLog::InsertCell(feature_table_name_, "height", _nativeWidth);
DataLog::InsertCell(feature_table_name_, "num pixels",
_nativeHeight * _nativeWidth);
DataLog::InsertCell(feature_table_name_, "frame rate", _nativeFrameRate);
DataLog::NextRow(feature_table_name_);
static_cast<FakeTickTime*>(
_clock)->IncrementDebugClock(1000 / _nativeFrameRate);
}
} while (feof(_sourceFile) == 0);
_decodeCallback.WriteEnd(_frameCnt);
double endTime = clock()/(double)CLOCKS_PER_SEC;
_testTotalTime = endTime - startTime;
_sumEncBytes = _encodeCompleteCallback.EncodedBytes();
@@ -333,6 +388,8 @@ QualityModesTest::Perform()
return 0;
}
// implementing callback to be called from
// VCM to update VPM of frame rate and size
QMTestVideoSettingsCallback::QMTestVideoSettingsCallback():
_vpm(NULL),
_vcm(NULL)
@@ -389,9 +446,9 @@ QMTestVideoSettingsCallback::SetVideoQMSettings(const WebRtc_UWord32 frameRate,
return retVal;
}
// Decoded Frame Callback Implmentation
VCMQMDecodeCompleCallback::VCMQMDecodeCompleCallback(FILE* decodedFile):
// Decoded Frame Callback Implementation
VCMQMDecodeCompleCallback::VCMQMDecodeCompleCallback(
FILE* decodedFile, int frame_rate, std::string feature_table_name):
_decodedFile(decodedFile),
_decodedBytes(0),
//_test(test),
@@ -401,7 +458,10 @@ _decWidth(0),
_decHeight(0),
//_interpolator(NULL),
_decBuffer(NULL),
_frameCnt(0)
_frameCnt(0),
frame_rate_(frame_rate),
frames_cnt_since_drop_(0),
feature_table_name_(feature_table_name)
{
//
}
@@ -419,11 +479,36 @@ VCMQMDecodeCompleCallback::~VCMQMDecodeCompleCallback()
_decBuffer = NULL;
}
}
WebRtc_Word32
VCMQMDecodeCompleCallback::FrameToRender(I420VideoFrame& videoFrame)
{
if ((_origWidth == videoFrame.width()) &&
(_origHeight == videoFrame.height()))
++frames_cnt_since_drop_;
// When receiving the first coded frame the last_frame variable is not set
if (last_frame_.IsZeroSize()) {
last_frame_.CopyFrame(videoFrame);
}
// Check if there were frames skipped.
int num_frames_skipped = static_cast<int>( 0.5f +
(videoFrame.timestamp() - (last_frame_.timestamp() + (9e4 / frame_rate_))) /
(9e4 / frame_rate_));
// If so...put the last frames into the encoded stream to make up for the
// skipped frame(s)
while (num_frames_skipped > 0) {
PrintI420VideoFrame(last_frame_, _decodedFile);
_frameCnt++;
--num_frames_skipped;
frames_cnt_since_drop_ = 1; // Reset counter
}
DataLog::InsertCell(
feature_table_name_,"num frames since drop",frames_cnt_since_drop_);
if (_origWidth == videoFrame.width() && _origHeight == videoFrame.height())
{
if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
return -1;
@@ -446,25 +531,23 @@ VCMQMDecodeCompleCallback::FrameToRender(I420VideoFrame& videoFrame)
_decodedBytes += CalcBufferSize(kI420, videoFrame.width(),
videoFrame.height());
videoFrame.SwapFrame(&last_frame_);
return VCM_OK;
}
WebRtc_Word32
VCMQMDecodeCompleCallback::DecodedBytes()
WebRtc_Word32 VCMQMDecodeCompleCallback::DecodedBytes()
{
return _decodedBytes;
}
void
VCMQMDecodeCompleCallback::SetOriginalFrameDimensions(WebRtc_Word32 width,
void VCMQMDecodeCompleCallback::SetOriginalFrameDimensions(WebRtc_Word32 width,
WebRtc_Word32 height)
{
_origWidth = width;
_origHeight = height;
}
WebRtc_Word32
VCMQMDecodeCompleCallback::buildInterpolator()
WebRtc_Word32 VCMQMDecodeCompleCallback::buildInterpolator()
{
WebRtc_UWord32 decFrameLength = _origWidth*_origHeight*3 >> 1;
if (_decBuffer != NULL)
@@ -476,6 +559,20 @@ VCMQMDecodeCompleCallback::buildInterpolator()
{
return -1;
}
return 0;
}
// This function checks if the total number of frames processed in the encoding
// process is the same as the number of frames rendered. If not, the last
// frame (or several consecutive frames from the end) must have been dropped. If
// this is the case, the last frame is repeated so that there are as many
// frames rendered as there are number of frames encoded.
void VCMQMDecodeCompleCallback::WriteEnd(int input_frame_count)
{
int num_missing_frames = input_frame_count - _frameCnt;
for (int n = num_missing_frames; n > 0; --n) {
PrintI420VideoFrame(last_frame_, _decodedFile);
_frameCnt++;
}
}

View File

@@ -13,9 +13,10 @@
#include "video_processing.h"
#include "normal_test.h"
#include "system_wrappers/interface/data_log.h"
#include "video_coding_defines.h"
int qualityModeTest();
int qualityModeTest(const CmdArgs& args);
class QualityModesTest : public NormalTest
{
@@ -23,11 +24,11 @@ public:
QualityModesTest(webrtc::VideoCodingModule* vcm,
webrtc::TickTimeBase* clock);
virtual ~QualityModesTest();
WebRtc_Word32 Perform();
WebRtc_Word32 Perform(const CmdArgs& args);
private:
void Setup();
void Setup(const CmdArgs& args);
void Print();
void Teardown();
void SsimComp();
@@ -43,14 +44,20 @@ private:
WebRtc_UWord32 _numFramesDroppedVPM;
bool _flagSSIM;
std::string filename_testvideo_;
std::string fv_outfilename_;
std::string feature_table_name_;
}; // end of QualityModesTest class
class VCMQMDecodeCompleCallback: public webrtc::VCMReceiveCallback
{
public:
VCMQMDecodeCompleCallback(FILE* decodedFile);
VCMQMDecodeCompleCallback(
FILE* decodedFile,
int frame_rate,
std::string feature_table_name);
virtual ~VCMQMDecodeCompleCallback();
void SetUserReceiveCallback(webrtc::VCMReceiveCallback* receiveCallback);
// will write decoded frame into file
@@ -58,6 +65,9 @@ public:
WebRtc_Word32 DecodedBytes();
void SetOriginalFrameDimensions(WebRtc_Word32 width, WebRtc_Word32 height);
WebRtc_Word32 buildInterpolator();
// Check if last frame is dropped, if so, repeat the last rendered frame.
void WriteEnd(int input_tot_frame_count);
private:
FILE* _decodedFile;
WebRtc_UWord32 _decodedBytes;
@@ -69,6 +79,12 @@ private:
// VideoInterpolator* _interpolator;
WebRtc_UWord8* _decBuffer;
WebRtc_UWord32 _frameCnt; // debug
webrtc::I420VideoFrame last_frame_;
int frame_rate_;
int frames_cnt_since_drop_;
std::string feature_table_name_;
}; // end of VCMQMDecodeCompleCallback class

View File

@@ -41,7 +41,8 @@ class CmdArgs
"/resources/foreman_cif.yuv"),
outputFile(webrtc::test::OutputPath() +
"video_coding_test_output_352x288.yuv"),
testNum(11) {}
fv_outputfile(webrtc::test::OutputPath() + "features.txt"),
testNum(0) {}
std::string codecName;
webrtc::VideoCodecType codecType;
int width;
@@ -54,6 +55,7 @@ class CmdArgs
int camaEnable;
std::string inputFile;
std::string outputFile;
std::string fv_outputfile;
int testNum;
};

View File

@@ -37,8 +37,15 @@ int vcmMacrosErrors = 0;
int ParseArguments(int argc, char **argv, CmdArgs& args)
{
int i = 1;
while (i < argc)
{
if (argv[i+1] == '\0')
{
printf( "You did not supply a parameter value\n." );
return -1;
}
if (argv[i][0] != '-')
{
return -1;
@@ -131,6 +138,11 @@ int ParseArguments(int argc, char **argv, CmdArgs& args)
args.camaEnable = atoi(argv[i+1]);
break;
}
case 'v':
{
args.fv_outputfile = argv[i+1];
break;
}
default:
return -1;
}
@@ -153,8 +165,13 @@ int main(int argc, char **argv)
}
int ret = 0;
switch (args.testNum)
{
switch (args.testNum) {
case 0:
ret = NormalTest::RunTest(args);
ret |= CodecDataBaseTest::RunTest(args);
ret |= ReceiverTimingTests(args);
ret |= JitterBufferTest(args);
break;
case 1:
ret = NormalTest::RunTest(args);
break;
@@ -187,10 +204,7 @@ int main(int argc, char **argv)
ret = DecodeFromStorageTest(args);
break;
case 11:
ret = NormalTest::RunTest(args);
ret |= CodecDataBaseTest::RunTest(args);
ret |= ReceiverTimingTests(args);
ret |= JitterBufferTest(args);
qualityModeTest(args);
break;
default:
ret = -1;

View File

@@ -23,7 +23,7 @@ using ::webrtc::DataLog;
struct ExpectedValues {
public:
ExpectedValues()
: values(NULL),
: values(),
multi_value_length(1) {
}