Vp8 tests: Removing legacy unused tests and reorganization of existing ones.
Review URL: https://webrtc-codereview.appspot.com/972013 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3276 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -24,6 +24,7 @@ public:
|
|||||||
CodecTest(std::string name, std::string description,
|
CodecTest(std::string name, std::string description,
|
||||||
WebRtc_UWord32 bitRate);
|
WebRtc_UWord32 bitRate);
|
||||||
virtual ~CodecTest() {};
|
virtual ~CodecTest() {};
|
||||||
|
virtual void Setup();
|
||||||
virtual void Perform()=0;
|
virtual void Perform()=0;
|
||||||
virtual void Print();
|
virtual void Print();
|
||||||
void SetEncoder(webrtc::VideoEncoder *encoder);
|
void SetEncoder(webrtc::VideoEncoder *encoder);
|
||||||
@@ -31,7 +32,6 @@ public:
|
|||||||
void SetLog(std::fstream* log);
|
void SetLog(std::fstream* log);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Setup();
|
|
||||||
virtual void CodecSettings(int width,
|
virtual void CodecSettings(int width,
|
||||||
int height,
|
int height,
|
||||||
WebRtc_UWord32 frameRate=30,
|
WebRtc_UWord32 frameRate=30,
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class UnitTest : public CodecTest
|
|||||||
public:
|
public:
|
||||||
UnitTest();
|
UnitTest();
|
||||||
virtual ~UnitTest();
|
virtual ~UnitTest();
|
||||||
|
virtual void Setup();
|
||||||
virtual void Perform();
|
virtual void Perform();
|
||||||
virtual void Print();
|
virtual void Print();
|
||||||
|
|
||||||
@@ -41,7 +42,6 @@ protected:
|
|||||||
virtual WebRtc_UWord32 CodecSpecific_SetBitrate(
|
virtual WebRtc_UWord32 CodecSpecific_SetBitrate(
|
||||||
WebRtc_UWord32 bitRate,
|
WebRtc_UWord32 bitRate,
|
||||||
WebRtc_UWord32 /* frameRate */);
|
WebRtc_UWord32 /* frameRate */);
|
||||||
virtual void Setup();
|
|
||||||
virtual void Teardown();
|
virtual void Teardown();
|
||||||
virtual void RateControlTests();
|
virtual void RateControlTests();
|
||||||
virtual int Decode();
|
virtual int Decode();
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "benchmark.h"
|
|
||||||
#include "testsupport/fileutils.h"
|
|
||||||
#include "vp8.h"
|
|
||||||
|
|
||||||
using namespace webrtc;
|
|
||||||
|
|
||||||
VP8Benchmark::VP8Benchmark()
|
|
||||||
: Benchmark("VP8Benchmark", "VP8 benchmark over a range of test cases",
|
|
||||||
webrtc::test::OutputPath() + "VP8Benchmark.txt", "VP8") {
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8Benchmark::VP8Benchmark(std::string name, std::string description)
|
|
||||||
: Benchmark(name, description,
|
|
||||||
webrtc::test::OutputPath() + "VP8Benchmark.txt",
|
|
||||||
"VP8") {
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8Benchmark::VP8Benchmark(std::string name, std::string description,
|
|
||||||
std::string resultsFileName)
|
|
||||||
: Benchmark(name, description, resultsFileName, "VP8") {
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoEncoder* VP8Benchmark::GetNewEncoder() {
|
|
||||||
return VP8Encoder::Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoDecoder* VP8Benchmark::GetNewDecoder() {
|
|
||||||
return VP8Decoder::Create();
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_BENCHMARK_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_BENCHMARK_H_
|
|
||||||
|
|
||||||
#include "modules/video_coding/codecs/test_framework/benchmark.h"
|
|
||||||
|
|
||||||
class VP8Benchmark : public Benchmark
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VP8Benchmark();
|
|
||||||
VP8Benchmark(std::string name, std::string description);
|
|
||||||
VP8Benchmark(std::string name, std::string description, std::string resultsFileName);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual webrtc::VideoEncoder* GetNewEncoder();
|
|
||||||
virtual webrtc::VideoDecoder* GetNewDecoder();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_BENCHMARK_H_
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dual_decoder_test.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h> // memcmp
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "testsupport/fileutils.h"
|
|
||||||
|
|
||||||
VP8DualDecoderTest::VP8DualDecoderTest(float bitRate)
|
|
||||||
:
|
|
||||||
VP8NormalAsyncTest(bitRate)
|
|
||||||
{
|
|
||||||
_decoder2 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8DualDecoderTest::VP8DualDecoderTest()
|
|
||||||
:
|
|
||||||
VP8NormalAsyncTest("VP8 Dual Decoder Test", "Tests VP8 dual decoder", 1),
|
|
||||||
_decoder2(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
VP8DualDecoderTest::~VP8DualDecoderTest()
|
|
||||||
{
|
|
||||||
if(_decoder2)
|
|
||||||
{
|
|
||||||
_decoder2->Release();
|
|
||||||
delete _decoder2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VP8DualDecoderTest::Perform()
|
|
||||||
{
|
|
||||||
_inname = webrtc::test::ProjectRootPath() + "resources/foreman_cif.yuv";
|
|
||||||
CodecSettings(352, 288, 30, _bitRate);
|
|
||||||
Setup();
|
|
||||||
if(_encoder->InitEncode(&_inst, 4, 1460) < 0)
|
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_decoder->InitDecode(&_inst,1);
|
|
||||||
|
|
||||||
FrameQueue frameQueue;
|
|
||||||
VideoEncodeCompleteCallback encCallback(_encodedFile, &frameQueue, *this);
|
|
||||||
DualDecoderCompleteCallback decCallback(&_decodedVideoBuffer);
|
|
||||||
DualDecoderCompleteCallback decCallback2(&_decodedVideoBuffer2);
|
|
||||||
_encoder->RegisterEncodeCompleteCallback(&encCallback);
|
|
||||||
_decoder->RegisterDecodeCompleteCallback(&decCallback);
|
|
||||||
if (SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK)
|
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
_totalEncodeTime = _totalDecodeTime = 0;
|
|
||||||
_totalEncodePipeTime = _totalDecodePipeTime = 0;
|
|
||||||
bool complete = false;
|
|
||||||
_framecnt = 0;
|
|
||||||
_encFrameCnt = 0;
|
|
||||||
_decFrameCnt = 0;
|
|
||||||
_sumEncBytes = 0;
|
|
||||||
_lengthEncFrame = 0;
|
|
||||||
double starttime = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
while (!complete)
|
|
||||||
{
|
|
||||||
if (_encFrameCnt == 10)
|
|
||||||
{
|
|
||||||
// initialize second decoder and copy state
|
|
||||||
_decoder2 = static_cast<webrtc::VP8Decoder *>(_decoder->Copy());
|
|
||||||
assert(_decoder2 != NULL);
|
|
||||||
_decoder2->RegisterDecodeCompleteCallback(&decCallback2);
|
|
||||||
}
|
|
||||||
CodecSpecific_InitBitrate();
|
|
||||||
complete = Encode();
|
|
||||||
if (!frameQueue.Empty() || complete)
|
|
||||||
{
|
|
||||||
while (!frameQueue.Empty())
|
|
||||||
{
|
|
||||||
_frameToDecode =
|
|
||||||
static_cast<FrameQueueTuple *>(frameQueue.PopFrame());
|
|
||||||
int lost = DoPacketLoss();
|
|
||||||
if (lost == 2)
|
|
||||||
{
|
|
||||||
// Lost the whole frame, continue
|
|
||||||
_missingFrames = true;
|
|
||||||
delete _frameToDecode;
|
|
||||||
_frameToDecode = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int ret = Decode(lost);
|
|
||||||
delete _frameToDecode;
|
|
||||||
_frameToDecode = NULL;
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"\n\nError in decoder: %d\n\n", ret);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
else if (ret == 0)
|
|
||||||
{
|
|
||||||
_framecnt++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n\nPositive return value from decode!\n\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double endtime = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
double totalExecutionTime = endtime - starttime;
|
|
||||||
printf("Total execution time: %.1f s\n", totalExecutionTime);
|
|
||||||
_sumEncBytes = encCallback.EncodedBytes();
|
|
||||||
double actualBitRate = ActualBitRate(_encFrameCnt) / 1000.0;
|
|
||||||
double avgEncTime = _totalEncodeTime / _encFrameCnt;
|
|
||||||
double avgDecTime = _totalDecodeTime / _decFrameCnt;
|
|
||||||
printf("Actual bitrate: %f kbps\n", actualBitRate);
|
|
||||||
printf("Average encode time: %.1f ms\n", 1000 * avgEncTime);
|
|
||||||
printf("Average decode time: %.1f ms\n", 1000 * avgDecTime);
|
|
||||||
printf("Average encode pipeline time: %.1f ms\n",
|
|
||||||
1000 * _totalEncodePipeTime / _encFrameCnt);
|
|
||||||
printf("Average decode pipeline time: %.1f ms\n",
|
|
||||||
1000 * _totalDecodePipeTime / _decFrameCnt);
|
|
||||||
printf("Number of encoded frames: %u\n", _encFrameCnt);
|
|
||||||
printf("Number of decoded frames: %u\n", _decFrameCnt);
|
|
||||||
(*_log) << "Actual bitrate: " << actualBitRate << " kbps\tTarget: " <<
|
|
||||||
_bitRate << " kbps" << std::endl;
|
|
||||||
(*_log) << "Average encode time: " << avgEncTime << " s" << std::endl;
|
|
||||||
(*_log) << "Average decode time: " << avgDecTime << " s" << std::endl;
|
|
||||||
_encoder->Release();
|
|
||||||
_decoder->Release();
|
|
||||||
Teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
VP8DualDecoderTest::Decode(int lossValue)
|
|
||||||
{
|
|
||||||
_sumEncBytes += _frameToDecode->_frame->Length();
|
|
||||||
webrtc::EncodedImage encodedImage;
|
|
||||||
VideoEncodedBufferToEncodedImage(*(_frameToDecode->_frame), encodedImage);
|
|
||||||
encodedImage._completeFrame = !lossValue;
|
|
||||||
_decodeCompleteTime = 0;
|
|
||||||
_decodeTimes[encodedImage._timeStamp] = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
int ret = _decoder->Decode(encodedImage, _missingFrames, NULL,
|
|
||||||
_frameToDecode->_codecSpecificInfo);
|
|
||||||
// second decoder
|
|
||||||
if (_decoder2)
|
|
||||||
{
|
|
||||||
int ret2 = _decoder2->Decode(encodedImage, _missingFrames, NULL,
|
|
||||||
_frameToDecode->_codecSpecificInfo,
|
|
||||||
0 /* dummy */);
|
|
||||||
|
|
||||||
// check return values
|
|
||||||
if (ret < 0 || ret2 < 0 || ret2 != ret)
|
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare decoded images
|
|
||||||
if (!CheckIfBitExactFrames(_decodedVideoBuffer, _decodedVideoBuffer2))
|
|
||||||
{
|
|
||||||
fprintf(stderr,"\n\nClone output different from master.\n\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_missingFrames = false;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 DualDecoderCompleteCallback::Decoded(webrtc::I420VideoFrame&
|
|
||||||
image)
|
|
||||||
{
|
|
||||||
_decodedVideoBuffer->CopyFrame(image);
|
|
||||||
_decodeComplete = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DualDecoderCompleteCallback::DecodeComplete()
|
|
||||||
{
|
|
||||||
if (_decodeComplete)
|
|
||||||
{
|
|
||||||
_decodeComplete = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
VP8DualDecoderTest::CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
|
|
||||||
const webrtc::I420VideoFrame& frame2) {
|
|
||||||
for (int plane = 0; plane < webrtc::kNumOfPlanes; plane ++) {
|
|
||||||
webrtc::PlaneType plane_type = static_cast<webrtc::PlaneType>(plane);
|
|
||||||
int allocated_size1 = frame1.allocated_size(plane_type);
|
|
||||||
int allocated_size2 = frame2.allocated_size(plane_type);
|
|
||||||
if (allocated_size1 != allocated_size2)
|
|
||||||
return false;
|
|
||||||
const uint8_t* plane_buffer1 = frame1.buffer(plane_type);
|
|
||||||
const uint8_t* plane_buffer2 = frame2.buffer(plane_type);
|
|
||||||
if (memcmp(plane_buffer1, plane_buffer2, allocated_size1) != 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DUAL_DECODER_TEST_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DUAL_DECODER_TEST_H_
|
|
||||||
|
|
||||||
#include "vp8.h"
|
|
||||||
#include "normal_async_test.h"
|
|
||||||
|
|
||||||
class DualDecoderCompleteCallback;
|
|
||||||
|
|
||||||
class VP8DualDecoderTest : public VP8NormalAsyncTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VP8DualDecoderTest(float bitRate);
|
|
||||||
VP8DualDecoderTest();
|
|
||||||
virtual ~VP8DualDecoderTest();
|
|
||||||
virtual void Perform();
|
|
||||||
protected:
|
|
||||||
VP8DualDecoderTest(std::string name, std::string description,
|
|
||||||
unsigned int testNo)
|
|
||||||
: VP8NormalAsyncTest(name, description, testNo) {}
|
|
||||||
virtual int Decode(int lossValue = 0);
|
|
||||||
|
|
||||||
webrtc::VP8Decoder* _decoder2;
|
|
||||||
webrtc::I420VideoFrame _decodedVideoBuffer2;
|
|
||||||
static bool CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
|
|
||||||
const webrtc::I420VideoFrame& frame2);
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
class DualDecoderCompleteCallback : public webrtc::DecodedImageCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DualDecoderCompleteCallback(webrtc::I420VideoFrame* buffer)
|
|
||||||
: _decodedVideoBuffer(buffer), _decodeComplete(false) {}
|
|
||||||
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& decodedImage);
|
|
||||||
bool DecodeComplete();
|
|
||||||
private:
|
|
||||||
webrtc::I420VideoFrame* _decodedVideoBuffer;
|
|
||||||
bool _decodeComplete;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "normal_async_test.h"
|
|
||||||
|
|
||||||
using namespace webrtc;
|
|
||||||
|
|
||||||
VP8NormalAsyncTest::VP8NormalAsyncTest(WebRtc_UWord32 bitRate) :
|
|
||||||
NormalAsyncTest("VP8 Normal Test 1", "Tests VP8 normal execution", bitRate, 1),
|
|
||||||
_hasReceivedRPSI(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8NormalAsyncTest::VP8NormalAsyncTest(WebRtc_UWord32 bitRate, unsigned int testNo):
|
|
||||||
NormalAsyncTest("VP8 Normal Test 1", "Tests VP8 normal execution", bitRate, testNo),
|
|
||||||
_hasReceivedRPSI(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VP8NormalAsyncTest::CodecSettings(int width, int height, WebRtc_UWord32 frameRate /*=30*/, WebRtc_UWord32 bitRate /*=0*/)
|
|
||||||
{
|
|
||||||
if (bitRate > 0)
|
|
||||||
{
|
|
||||||
_bitRate = bitRate;
|
|
||||||
|
|
||||||
}else if (_bitRate == 0)
|
|
||||||
{
|
|
||||||
_bitRate = 600;
|
|
||||||
}
|
|
||||||
_inst.codecType = kVideoCodecVP8;
|
|
||||||
_inst.codecSpecific.VP8.feedbackModeOn = true;
|
|
||||||
_inst.codecSpecific.VP8.pictureLossIndicationOn = true;
|
|
||||||
_inst.codecSpecific.VP8.complexity = kComplexityNormal;
|
|
||||||
_inst.maxFramerate = (unsigned char)frameRate;
|
|
||||||
_inst.startBitrate = _bitRate;
|
|
||||||
_inst.maxBitrate = 8000;
|
|
||||||
_inst.width = width;
|
|
||||||
_inst.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VP8NormalAsyncTest::CodecSpecific_InitBitrate()
|
|
||||||
{
|
|
||||||
if (_bitRate == 0)
|
|
||||||
{
|
|
||||||
_encoder->SetRates(600, _inst.maxFramerate);
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
_encoder->SetRates(_bitRate, _inst.maxFramerate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32
|
|
||||||
VP8NormalAsyncTest::ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId)
|
|
||||||
{
|
|
||||||
_pictureIdRPSI = pictureId;
|
|
||||||
_hasReceivedRPSI = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodecSpecificInfo*
|
|
||||||
VP8NormalAsyncTest::CreateEncoderSpecificInfo() const
|
|
||||||
{
|
|
||||||
CodecSpecificInfo* vp8CodecSpecificInfo = new CodecSpecificInfo();
|
|
||||||
vp8CodecSpecificInfo->codecType = kVideoCodecVP8;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.hasReceivedRPSI = _hasReceivedRPSI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.pictureIdRPSI = _pictureIdRPSI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.hasReceivedSLI = _hasReceivedSLI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.pictureIdSLI = _pictureIdSLI;
|
|
||||||
|
|
||||||
_hasReceivedSLI = false;
|
|
||||||
_hasReceivedRPSI = false;
|
|
||||||
|
|
||||||
return vp8CodecSpecificInfo;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_NORMAL_ASYNC_TEST_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_NORMAL_ASYNC_TEST_H_
|
|
||||||
|
|
||||||
#include "modules/video_coding/codecs/test_framework/normal_async_test.h"
|
|
||||||
|
|
||||||
class VP8NormalAsyncTest : public NormalAsyncTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VP8NormalAsyncTest(WebRtc_UWord32 bitRate);
|
|
||||||
VP8NormalAsyncTest(WebRtc_UWord32 bitRate, unsigned int testNo);
|
|
||||||
VP8NormalAsyncTest() : NormalAsyncTest("VP8 Normal Test 1", "Tests VP8 normal execution", 1) {}
|
|
||||||
protected:
|
|
||||||
VP8NormalAsyncTest(std::string name, std::string description, unsigned int testNo) : NormalAsyncTest(name, description, testNo) {}
|
|
||||||
virtual void CodecSpecific_InitBitrate();
|
|
||||||
virtual void CodecSettings(int width, int height, WebRtc_UWord32 frameRate=30, WebRtc_UWord32 bitRate=0);
|
|
||||||
virtual webrtc::CodecSpecificInfo* CreateEncoderSpecificInfo() const;
|
|
||||||
virtual WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId);
|
|
||||||
private:
|
|
||||||
mutable bool _hasReceivedRPSI;
|
|
||||||
WebRtc_UWord64 _pictureIdRPSI;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "packet_loss_test.h"
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
VP8PacketLossTest::VP8PacketLossTest()
|
|
||||||
:
|
|
||||||
PacketLossTest("VP8PacketLossTest", "Encode, remove lost packets, decode")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8PacketLossTest::VP8PacketLossTest(std::string name, std::string description)
|
|
||||||
:
|
|
||||||
PacketLossTest(name, description)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8PacketLossTest::VP8PacketLossTest(double lossRate,
|
|
||||||
bool useNack,
|
|
||||||
int rttFrames)
|
|
||||||
:
|
|
||||||
PacketLossTest("VP8PacketLossTest", "Encode, remove lost packets, decode",
|
|
||||||
lossRate, useNack, rttFrames)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int VP8PacketLossTest::ByteLoss(int size, unsigned char* /* pkg */, int bytesToLose)
|
|
||||||
{
|
|
||||||
int retLength = size - bytesToLose;
|
|
||||||
if (retLength < 4)
|
|
||||||
{
|
|
||||||
retLength = 4;
|
|
||||||
}
|
|
||||||
return retLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32
|
|
||||||
VP8PacketLossTest::ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId)
|
|
||||||
{
|
|
||||||
_pictureIdRPSI = pictureId;
|
|
||||||
_hasReceivedRPSI = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
webrtc::CodecSpecificInfo*
|
|
||||||
VP8PacketLossTest::CreateEncoderSpecificInfo() const
|
|
||||||
{
|
|
||||||
webrtc::CodecSpecificInfo* vp8CodecSpecificInfo =
|
|
||||||
new webrtc::CodecSpecificInfo();
|
|
||||||
vp8CodecSpecificInfo->codecType = webrtc::kVideoCodecVP8;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.hasReceivedRPSI = _hasReceivedRPSI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.pictureIdRPSI = _pictureIdRPSI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.hasReceivedSLI = _hasReceivedSLI;
|
|
||||||
vp8CodecSpecificInfo->codecSpecific.VP8.pictureIdSLI = _pictureIdSLI;
|
|
||||||
|
|
||||||
_hasReceivedSLI = false;
|
|
||||||
_hasReceivedRPSI = false;
|
|
||||||
|
|
||||||
return vp8CodecSpecificInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VP8PacketLossTest::PacketLoss(double lossRate, int numLosses) {
|
|
||||||
if (numLosses)
|
|
||||||
return true;
|
|
||||||
return RandUniform() < lossRate;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_PACKET_LOSS_TEST_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_PACKET_LOSS_TEST_H_
|
|
||||||
|
|
||||||
#include "modules/video_coding/codecs/test_framework/packet_loss_test.h"
|
|
||||||
|
|
||||||
class VP8PacketLossTest : public PacketLossTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VP8PacketLossTest();
|
|
||||||
VP8PacketLossTest(double lossRate, bool useNack, int rttFrames);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
VP8PacketLossTest(std::string name, std::string description);
|
|
||||||
virtual int ByteLoss(int size, unsigned char *pkg, int bytesToLose);
|
|
||||||
WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId);
|
|
||||||
// |lossRate| is the probability of packet loss between 0 and 1.
|
|
||||||
// |numLosses| is the number of packets already lost in the current frame.
|
|
||||||
virtual bool PacketLoss(double lossRate, int numLosses);
|
|
||||||
|
|
||||||
webrtc::CodecSpecificInfo* CreateEncoderSpecificInfo() const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_PACKET_LOSS_TEST_H_
|
|
||||||
@@ -1,309 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "rps_test.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h> // memcmp
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "vp8.h"
|
|
||||||
|
|
||||||
VP8RpsTest::VP8RpsTest(float bitRate)
|
|
||||||
: VP8NormalAsyncTest(bitRate),
|
|
||||||
decoder2_(webrtc::VP8Decoder::Create()),
|
|
||||||
sli_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8RpsTest::VP8RpsTest()
|
|
||||||
: VP8NormalAsyncTest("VP8 Reference Picture Selection Test",
|
|
||||||
"VP8 Reference Picture Selection Test", 1),
|
|
||||||
decoder2_(webrtc::VP8Decoder::Create()),
|
|
||||||
sli_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8RpsTest::~VP8RpsTest() {
|
|
||||||
if (decoder2_) {
|
|
||||||
decoder2_->Release();
|
|
||||||
delete decoder2_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VP8RpsTest::Perform() {
|
|
||||||
_inname = "test/testFiles/foreman_cif.yuv";
|
|
||||||
CodecSettings(352, 288, 30, _bitRate);
|
|
||||||
Setup();
|
|
||||||
|
|
||||||
// Enable RPS functionality
|
|
||||||
_inst.codecSpecific.VP8.pictureLossIndicationOn = true;
|
|
||||||
_inst.codecSpecific.VP8.feedbackModeOn = true;
|
|
||||||
|
|
||||||
if(_encoder->InitEncode(&_inst, 4, 1460) < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
_decoder->InitDecode(&_inst,1);
|
|
||||||
decoder2_->InitDecode(&_inst,1);
|
|
||||||
|
|
||||||
FrameQueue frameQueue;
|
|
||||||
VideoEncodeCompleteCallback encCallback(_encodedFile, &frameQueue, *this);
|
|
||||||
RpsDecodeCompleteCallback decCallback(&_decodedVideoBuffer);
|
|
||||||
RpsDecodeCompleteCallback decCallback2(&decoded_frame2_);
|
|
||||||
_encoder->RegisterEncodeCompleteCallback(&encCallback);
|
|
||||||
_decoder->RegisterDecodeCompleteCallback(&decCallback);
|
|
||||||
decoder2_->RegisterDecodeCompleteCallback(&decCallback2);
|
|
||||||
|
|
||||||
if (SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
_totalEncodeTime = _totalDecodeTime = 0;
|
|
||||||
_totalEncodePipeTime = _totalDecodePipeTime = 0;
|
|
||||||
bool complete = false;
|
|
||||||
_framecnt = 0;
|
|
||||||
_encFrameCnt = 0;
|
|
||||||
_decFrameCnt = 0;
|
|
||||||
_sumEncBytes = 0;
|
|
||||||
_lengthEncFrame = 0;
|
|
||||||
double starttime = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
while (!complete) {
|
|
||||||
CodecSpecific_InitBitrate();
|
|
||||||
complete = EncodeRps(&decCallback2);
|
|
||||||
if (!frameQueue.Empty() || complete) {
|
|
||||||
while (!frameQueue.Empty()) {
|
|
||||||
_frameToDecode =
|
|
||||||
static_cast<FrameQueueTuple *>(frameQueue.PopFrame());
|
|
||||||
int lost = DoPacketLoss();
|
|
||||||
if (lost == 2) {
|
|
||||||
// Lost the whole frame, continue
|
|
||||||
_missingFrames = true;
|
|
||||||
delete _frameToDecode;
|
|
||||||
_frameToDecode = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int ret = Decode(lost);
|
|
||||||
delete _frameToDecode;
|
|
||||||
_frameToDecode = NULL;
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr,"\n\nError in decoder: %d\n\n", ret);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
else if (ret == 0) {
|
|
||||||
_framecnt++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n\nPositive return value from decode!\n\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double endtime = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
double totalExecutionTime = endtime - starttime;
|
|
||||||
printf("Total execution time: %.1f s\n", totalExecutionTime);
|
|
||||||
_sumEncBytes = encCallback.EncodedBytes();
|
|
||||||
double actualBitRate = ActualBitRate(_encFrameCnt) / 1000.0;
|
|
||||||
double avgEncTime = _totalEncodeTime / _encFrameCnt;
|
|
||||||
double avgDecTime = _totalDecodeTime / _decFrameCnt;
|
|
||||||
printf("Actual bitrate: %f kbps\n", actualBitRate);
|
|
||||||
printf("Average encode time: %.1f ms\n", 1000 * avgEncTime);
|
|
||||||
printf("Average decode time: %.1f ms\n", 1000 * avgDecTime);
|
|
||||||
printf("Average encode pipeline time: %.1f ms\n",
|
|
||||||
1000 * _totalEncodePipeTime / _encFrameCnt);
|
|
||||||
printf("Average decode pipeline time: %.1f ms\n",
|
|
||||||
1000 * _totalDecodePipeTime / _decFrameCnt);
|
|
||||||
printf("Number of encoded frames: %u\n", _encFrameCnt);
|
|
||||||
printf("Number of decoded frames: %u\n", _decFrameCnt);
|
|
||||||
(*_log) << "Actual bitrate: " << actualBitRate << " kbps\tTarget: " <<
|
|
||||||
_bitRate << " kbps" << std::endl;
|
|
||||||
(*_log) << "Average encode time: " << avgEncTime << " s" << std::endl;
|
|
||||||
(*_log) << "Average decode time: " << avgDecTime << " s" << std::endl;
|
|
||||||
_encoder->Release();
|
|
||||||
_decoder->Release();
|
|
||||||
Teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
|
|
||||||
_lengthEncFrame = 0;
|
|
||||||
size_t bytes_read = fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile);
|
|
||||||
if (bytes_read < _lengthSourceFrame)
|
|
||||||
return true;
|
|
||||||
int half_width = (_inst.width + 1) / 2;
|
|
||||||
int half_height = (_inst.height + 1) / 2;
|
|
||||||
int size_y = _inst.width * _inst.height;
|
|
||||||
int size_uv = half_width * half_height;
|
|
||||||
_inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
|
|
||||||
size_uv, _sourceBuffer + size_y,
|
|
||||||
size_uv, _sourceBuffer + size_y + size_uv,
|
|
||||||
_inst.width, _inst.height,
|
|
||||||
_inst.width, half_width, half_width);
|
|
||||||
_inputVideoBuffer.set_timestamp((unsigned int)
|
|
||||||
(_encFrameCnt * 9e4 / _inst.maxFramerate));
|
|
||||||
if (feof(_sourceFile) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_encodeCompleteTime = 0;
|
|
||||||
_encodeTimes[_inputVideoBuffer.timestamp()] = tGetTime();
|
|
||||||
|
|
||||||
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
|
|
||||||
codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI =
|
|
||||||
decodeCallback->LastDecodedRefPictureId(
|
|
||||||
&codecSpecificInfo->codecSpecific.VP8.hasReceivedRPSI);
|
|
||||||
if (sli_) {
|
|
||||||
codecSpecificInfo->codecSpecific.VP8.pictureIdSLI =
|
|
||||||
decodeCallback->LastDecodedPictureId();
|
|
||||||
codecSpecificInfo->codecSpecific.VP8.hasReceivedSLI = true;
|
|
||||||
sli_ = false;
|
|
||||||
}
|
|
||||||
printf("Encoding: %u\n", _framecnt);
|
|
||||||
int ret = _encoder->Encode(_inputVideoBuffer, codecSpecificInfo, NULL);
|
|
||||||
if (ret < 0)
|
|
||||||
printf("Failed to encode: %u\n", _framecnt);
|
|
||||||
|
|
||||||
if (codecSpecificInfo != NULL) {
|
|
||||||
delete codecSpecificInfo;
|
|
||||||
codecSpecificInfo = NULL;
|
|
||||||
}
|
|
||||||
if (_encodeCompleteTime > 0) {
|
|
||||||
_totalEncodeTime += _encodeCompleteTime -
|
|
||||||
_encodeTimes[_inputVideoBuffer.timestamp()];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_totalEncodeTime += tGetTime() -
|
|
||||||
_encodeTimes[_inputVideoBuffer.timestamp()];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#define FRAME_LOSS 1
|
|
||||||
|
|
||||||
int VP8RpsTest::Decode(int lossValue) {
|
|
||||||
_sumEncBytes += _frameToDecode->_frame->Length();
|
|
||||||
webrtc::EncodedImage encodedImage;
|
|
||||||
VideoEncodedBufferToEncodedImage(*(_frameToDecode->_frame), encodedImage);
|
|
||||||
encodedImage._completeFrame = !lossValue;
|
|
||||||
_decodeCompleteTime = 0;
|
|
||||||
_decodeTimes[encodedImage._timeStamp] = clock()/(double)CLOCKS_PER_SEC;
|
|
||||||
int ret = _decoder->Decode(encodedImage, _missingFrames, NULL,
|
|
||||||
_frameToDecode->_codecSpecificInfo);
|
|
||||||
// Drop every 10th frame for the second decoder
|
|
||||||
#if FRAME_LOSS
|
|
||||||
if (_framecnt == 0 || _framecnt % 10 != 0) {
|
|
||||||
printf("Decoding: %u\n", _framecnt);
|
|
||||||
if (_framecnt > 1 && (_framecnt - 1) % 10 == 0)
|
|
||||||
_missingFrames = true;
|
|
||||||
#else
|
|
||||||
if (true) {
|
|
||||||
if (_framecnt > 0 && _framecnt % 10 == 0) {
|
|
||||||
encodedImage._length = std::rand() % encodedImage._length;
|
|
||||||
printf("Decoding with loss: %u\n", _framecnt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("Decoding: %u\n", _framecnt);
|
|
||||||
#endif
|
|
||||||
int ret2 = decoder2_->Decode(encodedImage, _missingFrames, NULL,
|
|
||||||
_frameToDecode->_codecSpecificInfo,
|
|
||||||
0 /* dummy */);
|
|
||||||
|
|
||||||
// check return values
|
|
||||||
if (ret < 0 || ret2 < 0) {
|
|
||||||
return -1;
|
|
||||||
} else if (ret2 == WEBRTC_VIDEO_CODEC_ERR_REQUEST_SLI ||
|
|
||||||
ret2 == WEBRTC_VIDEO_CODEC_REQUEST_SLI) {
|
|
||||||
sli_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare decoded images
|
|
||||||
#if FRAME_LOSS
|
|
||||||
if (!_missingFrames) {
|
|
||||||
if (!CheckIfBitExactFrames(_decodedVideoBuffer,
|
|
||||||
decoded_frame2_)) {
|
|
||||||
fprintf(stderr,"\n\nRPS decoder different from master: %u\n\n",
|
|
||||||
_framecnt);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (_framecnt > 0 && _framecnt % 10 != 0) {
|
|
||||||
if (!CheckIfBitExactFrames(_decodedVideoBuffer, decoded_frame2_)) {
|
|
||||||
fprintf(stderr,"\n\nRPS decoder different from master: %u\n\n",
|
|
||||||
_framecnt);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if FRAME_LOSS
|
|
||||||
else
|
|
||||||
printf("Dropping %u\n", _framecnt);
|
|
||||||
#endif
|
|
||||||
_missingFrames = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
VP8RpsTest::CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
|
|
||||||
const webrtc::I420VideoFrame& frame2) {
|
|
||||||
for (int plane = 0; plane < webrtc::kNumOfPlanes; plane ++) {
|
|
||||||
webrtc::PlaneType plane_type = static_cast<webrtc::PlaneType>(plane);
|
|
||||||
int allocated_size1 = frame1.allocated_size(plane_type);
|
|
||||||
int allocated_size2 = frame2.allocated_size(plane_type);
|
|
||||||
if (allocated_size1 != allocated_size2)
|
|
||||||
return false;
|
|
||||||
const uint8_t* plane_buffer1 = frame1.buffer(plane_type);
|
|
||||||
const uint8_t* plane_buffer2 = frame2.buffer(plane_type);
|
|
||||||
if (memcmp(plane_buffer1, plane_buffer2, allocated_size1) != 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RpsDecodeCompleteCallback::RpsDecodeCompleteCallback(webrtc::I420VideoFrame*
|
|
||||||
buffer)
|
|
||||||
: decoded_frame_(buffer),
|
|
||||||
decode_complete_(false) {}
|
|
||||||
|
|
||||||
WebRtc_Word32 RpsDecodeCompleteCallback::Decoded(webrtc::I420VideoFrame&
|
|
||||||
image) {
|
|
||||||
return decoded_frame_->CopyFrame(image);
|
|
||||||
decode_complete_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RpsDecodeCompleteCallback::DecodeComplete() {
|
|
||||||
if (decode_complete_)
|
|
||||||
{
|
|
||||||
decode_complete_ = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 RpsDecodeCompleteCallback::ReceivedDecodedReferenceFrame(
|
|
||||||
const WebRtc_UWord64 picture_id) {
|
|
||||||
last_decoded_ref_picture_id_ = picture_id & 0x7FFF;
|
|
||||||
updated_ref_picture_id_ = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 RpsDecodeCompleteCallback::ReceivedDecodedFrame(
|
|
||||||
const WebRtc_UWord64 picture_id) {
|
|
||||||
last_decoded_picture_id_ = picture_id & 0x3F;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_UWord64 RpsDecodeCompleteCallback::LastDecodedPictureId() const {
|
|
||||||
return last_decoded_picture_id_;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_UWord64 RpsDecodeCompleteCallback::LastDecodedRefPictureId(
|
|
||||||
bool *updated) {
|
|
||||||
if (updated)
|
|
||||||
*updated = updated_ref_picture_id_;
|
|
||||||
updated_ref_picture_id_ = false;
|
|
||||||
return last_decoded_ref_picture_id_;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_RPS_TEST_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_RPS_TEST_H_
|
|
||||||
|
|
||||||
#include "common_video/interface/i420_video_frame.h"
|
|
||||||
#include "vp8.h"
|
|
||||||
#include "normal_async_test.h"
|
|
||||||
|
|
||||||
class RpsDecodeCompleteCallback;
|
|
||||||
|
|
||||||
class VP8RpsTest : public VP8NormalAsyncTest {
|
|
||||||
public:
|
|
||||||
VP8RpsTest(float bitRate);
|
|
||||||
VP8RpsTest();
|
|
||||||
virtual ~VP8RpsTest();
|
|
||||||
virtual void Perform();
|
|
||||||
private:
|
|
||||||
VP8RpsTest(std::string name, std::string description, unsigned int testNo)
|
|
||||||
: VP8NormalAsyncTest(name, description, testNo) {}
|
|
||||||
virtual bool EncodeRps(RpsDecodeCompleteCallback* decodeCallback);
|
|
||||||
virtual int Decode(int lossValue = 0);
|
|
||||||
|
|
||||||
static bool CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
|
|
||||||
const webrtc::I420VideoFrame& frame2);
|
|
||||||
|
|
||||||
webrtc::VP8Decoder* decoder2_;
|
|
||||||
webrtc::I420VideoFrame decoded_frame2_;
|
|
||||||
bool sli_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RpsDecodeCompleteCallback : public webrtc::DecodedImageCallback {
|
|
||||||
public:
|
|
||||||
RpsDecodeCompleteCallback(webrtc::I420VideoFrame* buffer);
|
|
||||||
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& decodedImage);
|
|
||||||
bool DecodeComplete();
|
|
||||||
WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 picture_id);
|
|
||||||
WebRtc_Word32 ReceivedDecodedFrame(const WebRtc_UWord64 picture_id);
|
|
||||||
WebRtc_UWord64 LastDecodedPictureId() const;
|
|
||||||
WebRtc_UWord64 LastDecodedRefPictureId(bool *updated);
|
|
||||||
|
|
||||||
private:
|
|
||||||
webrtc::I420VideoFrame* decoded_frame_;
|
|
||||||
bool decode_complete_;
|
|
||||||
WebRtc_UWord64 last_decoded_picture_id_;
|
|
||||||
WebRtc_UWord64 last_decoded_ref_picture_id_;
|
|
||||||
bool updated_ref_picture_id_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_RPS_TEST_H_
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "benchmark.h"
|
|
||||||
#include "dual_decoder_test.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "normal_async_test.h"
|
|
||||||
#include "packet_loss_test.h"
|
|
||||||
#include "vp8_unittest.h"
|
|
||||||
#include "rps_test.h"
|
|
||||||
#include "testsupport/fileutils.h"
|
|
||||||
#include "vp8.h"
|
|
||||||
|
|
||||||
using namespace webrtc;
|
|
||||||
|
|
||||||
void PopulateTests(std::vector<CodecTest*>* tests)
|
|
||||||
{
|
|
||||||
// tests->push_back(new VP8RpsTest());
|
|
||||||
tests->push_back(new VP8UnitTest());
|
|
||||||
// tests->push_back(new VP8DualDecoderTest());
|
|
||||||
// tests->push_back(new VP8Benchmark());
|
|
||||||
// tests->push_back(new VP8PacketLossTest(0.05, false, 5));
|
|
||||||
// tests->push_back(new VP8NormalAsyncTest());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Vp8WrapperTest, RunAllTests)
|
|
||||||
{
|
|
||||||
VP8Encoder* enc;
|
|
||||||
VP8Decoder* dec;
|
|
||||||
std::vector<CodecTest*> tests;
|
|
||||||
PopulateTests(&tests);
|
|
||||||
std::fstream log;
|
|
||||||
std::string log_file = webrtc::test::OutputPath() + "VP8_test_log.txt";
|
|
||||||
log.open(log_file.c_str(), std::fstream::out | std::fstream::app);
|
|
||||||
std::vector<CodecTest*>::iterator it;
|
|
||||||
for (it = tests.begin() ; it < tests.end(); it++)
|
|
||||||
{
|
|
||||||
enc = VP8Encoder::Create();
|
|
||||||
dec = VP8Decoder::Create();
|
|
||||||
(*it)->SetEncoder(enc);
|
|
||||||
(*it)->SetDecoder(dec);
|
|
||||||
(*it)->SetLog(&log);
|
|
||||||
(*it)->Perform();
|
|
||||||
(*it)->Print();
|
|
||||||
delete enc;
|
|
||||||
delete dec;
|
|
||||||
delete *it;
|
|
||||||
}
|
|
||||||
log.close();
|
|
||||||
tests.pop_back();
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
|
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
|
||||||
#include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
|
#include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
|
||||||
|
#include "webrtc/modules/video_coding/codecs/test_framework/unit_test.h"
|
||||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||||
#include "webrtc/system_wrappers/interface/tick_util.h"
|
#include "webrtc/system_wrappers/interface/tick_util.h"
|
||||||
#include "webrtc/test/testsupport/fileutils.h"
|
#include "webrtc/test/testsupport/fileutils.h"
|
||||||
@@ -149,6 +150,43 @@ class TestVp8Impl : public ::testing::Test {
|
|||||||
VideoCodec codec_inst_;
|
VideoCodec codec_inst_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_F(TestVp8Impl, BaseUnitTest) {
|
||||||
|
// TODO(mikhal): Remove dependency. Move all test code here.
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
|
||||||
|
UnitTest unittest;
|
||||||
|
unittest.SetEncoder(encoder_.get());
|
||||||
|
unittest.SetDecoder(decoder_.get());
|
||||||
|
unittest.Setup();
|
||||||
|
unittest.Perform();
|
||||||
|
unittest.Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestVp8Impl, EncoderParameterTest) {
|
||||||
|
strncpy(codec_inst_.plName, "VP8", 31);
|
||||||
|
codec_inst_.plType = 126;
|
||||||
|
codec_inst_.maxBitrate = 0;
|
||||||
|
codec_inst_.minBitrate = 0;
|
||||||
|
codec_inst_.width = 1440;
|
||||||
|
codec_inst_.height = 1080;
|
||||||
|
codec_inst_.maxFramerate = 30;
|
||||||
|
codec_inst_.startBitrate = 300;
|
||||||
|
codec_inst_.codecSpecific.VP8.complexity = kComplexityNormal;
|
||||||
|
codec_inst_.codecSpecific.VP8.numberOfTemporalLayers = 1;
|
||||||
|
// Calls before InitEncode().
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
|
||||||
|
int bit_rate = 300;
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
|
||||||
|
encoder_->SetRates(bit_rate, codec_inst_.maxFramerate));
|
||||||
|
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
|
encoder_->InitEncode(&codec_inst_, 1, 1440));
|
||||||
|
|
||||||
|
// Decoder parameter tests.
|
||||||
|
// Calls before InitDecode().
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
|
||||||
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TestVp8Impl, AlignedStrideEncodeDecode) {
|
TEST_F(TestVp8Impl, AlignedStrideEncodeDecode) {
|
||||||
// Using a QCIF image (aligned stride (u,v planse) > width).
|
// Using a QCIF image (aligned stride (u,v planse) > width).
|
||||||
// Processing only one frame.
|
// Processing only one frame.
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vp8_unittest.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "modules/video_coding/codecs/test_framework/video_source.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include "testsupport/fileutils.h"
|
|
||||||
#include "vp8.h"
|
|
||||||
|
|
||||||
using namespace webrtc;
|
|
||||||
|
|
||||||
VP8UnitTest::VP8UnitTest()
|
|
||||||
:
|
|
||||||
UnitTest("VP8UnitTest", "Unit test")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8UnitTest::VP8UnitTest(std::string name, std::string description)
|
|
||||||
:
|
|
||||||
UnitTest(name, description)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_UWord32
|
|
||||||
VP8UnitTest::CodecSpecific_SetBitrate(WebRtc_UWord32 bitRate,
|
|
||||||
WebRtc_UWord32 /*frameRate*/)
|
|
||||||
{
|
|
||||||
int rate = _encoder->SetRates(bitRate, _inst.maxFramerate);
|
|
||||||
EXPECT_TRUE(rate >= 0);
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VP8UnitTest::Perform()
|
|
||||||
{
|
|
||||||
Setup();
|
|
||||||
VP8Encoder* enc = (VP8Encoder*)_encoder;
|
|
||||||
VP8Decoder* dec = (VP8Decoder*)_decoder;
|
|
||||||
|
|
||||||
//----- Encoder parameter tests -----
|
|
||||||
//-- Calls before InitEncode() --
|
|
||||||
EXPECT_EQ(enc->Release(), WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
EXPECT_EQ(enc->SetRates(_bitRate, _inst.maxFramerate),
|
|
||||||
WEBRTC_VIDEO_CODEC_UNINITIALIZED);
|
|
||||||
|
|
||||||
EXPECT_EQ(enc->SetRates(_bitRate, _inst.maxFramerate),
|
|
||||||
WEBRTC_VIDEO_CODEC_UNINITIALIZED);
|
|
||||||
|
|
||||||
VideoCodec codecInst;
|
|
||||||
memset(&codecInst, 0, sizeof(codecInst));
|
|
||||||
strncpy(codecInst.plName, "VP8", 31);
|
|
||||||
codecInst.plType = 126;
|
|
||||||
codecInst.maxBitrate = 0;
|
|
||||||
codecInst.minBitrate = 0;
|
|
||||||
codecInst.width = 1440;
|
|
||||||
codecInst.height = 1080;
|
|
||||||
codecInst.maxFramerate = 30;
|
|
||||||
codecInst.startBitrate = 300;
|
|
||||||
codecInst.codecSpecific.VP8.complexity = kComplexityNormal;
|
|
||||||
codecInst.codecSpecific.VP8.numberOfTemporalLayers = 1;
|
|
||||||
EXPECT_EQ(enc->InitEncode(&codecInst, 1, 1440), WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
|
|
||||||
|
|
||||||
//-- Test two problematic level settings --
|
|
||||||
strncpy(codecInst.plName, "VP8", 31);
|
|
||||||
codecInst.plType = 126;
|
|
||||||
codecInst.maxBitrate = 0;
|
|
||||||
codecInst.minBitrate = 0;
|
|
||||||
codecInst.width = 352;
|
|
||||||
codecInst.height = 288;
|
|
||||||
codecInst.maxFramerate = 30;
|
|
||||||
codecInst.codecSpecific.VP8.complexity = kComplexityNormal;
|
|
||||||
codecInst.startBitrate = 300;
|
|
||||||
EXPECT_EQ(enc->InitEncode(&codecInst, 1, 1440), WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
|
|
||||||
// Settings not correct for this profile
|
|
||||||
strncpy(codecInst.plName, "VP8", 31);
|
|
||||||
codecInst.plType = 126;
|
|
||||||
codecInst.maxBitrate = 0;
|
|
||||||
codecInst.minBitrate = 0;
|
|
||||||
codecInst.width = 176;
|
|
||||||
codecInst.height = 144;
|
|
||||||
codecInst.maxFramerate = 15;
|
|
||||||
codecInst.codecSpecific.VP8.complexity = kComplexityNormal;
|
|
||||||
codecInst.startBitrate = 300;
|
|
||||||
ASSERT_EQ(enc->InitEncode(&_inst, 1, 1440), WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
|
|
||||||
|
|
||||||
//-- ProcessNewBitrate() errors --
|
|
||||||
// Bad bitrate.
|
|
||||||
EXPECT_EQ(enc->SetRates(_inst.maxBitrate + 1, _inst.maxFramerate),
|
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
|
|
||||||
//----- Decoder parameter tests -----
|
|
||||||
//-- Calls before InitDecode() --
|
|
||||||
EXPECT_TRUE(dec->Release() == 0);
|
|
||||||
ASSERT_TRUE(dec->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
|
|
||||||
|
|
||||||
//-- SetCodecConfigParameters() errors --
|
|
||||||
unsigned char tmpBuf[128];
|
|
||||||
EXPECT_TRUE(dec->SetCodecConfigParameters(NULL, sizeof(tmpBuf)) == -1);
|
|
||||||
EXPECT_TRUE(dec->SetCodecConfigParameters(tmpBuf, 1) == -1);
|
|
||||||
// Garbage data.
|
|
||||||
EXPECT_TRUE(dec->SetCodecConfigParameters(tmpBuf, sizeof(tmpBuf)) == -1);
|
|
||||||
|
|
||||||
UnitTest::Perform();
|
|
||||||
Teardown();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_VP8_UNITTEST_H_
|
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_VP8_UNITTEST_H_
|
|
||||||
|
|
||||||
#include "modules/video_coding/codecs/test_framework/unit_test.h"
|
|
||||||
|
|
||||||
class VP8UnitTest : public UnitTest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VP8UnitTest();
|
|
||||||
VP8UnitTest(std::string name, std::string description);
|
|
||||||
virtual void Perform();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual WebRtc_UWord32 CodecSpecific_SetBitrate(
|
|
||||||
WebRtc_UWord32 bitRate,
|
|
||||||
WebRtc_UWord32 /*frameRate*/);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_VP8_UNITTEST_H_
|
|
||||||
@@ -91,22 +91,7 @@
|
|||||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
# header files
|
|
||||||
'test/benchmark.h',
|
|
||||||
'test/dual_decoder_test.h',
|
|
||||||
'test/normal_async_test.h',
|
|
||||||
'test/packet_loss_test.h',
|
|
||||||
'test/rps_test.h',
|
|
||||||
'test/vp8_unittest.h',
|
|
||||||
|
|
||||||
# source files
|
# source files
|
||||||
'test/benchmark.cc',
|
|
||||||
'test/dual_decoder_test.cc',
|
|
||||||
'test/normal_async_test.cc',
|
|
||||||
'test/packet_loss_test.cc',
|
|
||||||
'test/rps_test.cc',
|
|
||||||
'test/tester.cc',
|
|
||||||
'test/vp8_unittest.cc',
|
|
||||||
'test/vp8_impl_unittest.cc',
|
'test/vp8_impl_unittest.cc',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user