Home | History | Annotate | Download | only in test_framework
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <assert.h>
     12 #include <math.h>
     13 #include <stdlib.h>
     14 #include <string.h>
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "webrtc/modules/video_coding/codecs/test_framework/unit_test.h"
     18 #include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
     19 #include "webrtc/system_wrappers/interface/tick_util.h"
     20 #include "webrtc/test/testsupport/fileutils.h"
     21 
     22 using namespace webrtc;
     23 
     24 UnitTest::UnitTest()
     25 :
     26 CodecTest("UnitTest", "Unit test"),
     27 _tests(0),
     28 _errors(0),
     29 _source(NULL),
     30 _refFrame(NULL),
     31 _refEncFrame(NULL),
     32 _refDecFrame(NULL),
     33 _refEncFrameLength(0),
     34 _sourceFile(NULL),
     35 is_key_frame_(false),
     36 _encodeCompleteCallback(NULL),
     37 _decodeCompleteCallback(NULL)
     38 {
     39 }
     40 
     41 UnitTest::UnitTest(std::string name, std::string description)
     42 :
     43 CodecTest(name, description),
     44 _tests(0),
     45 _errors(0),
     46 _source(NULL),
     47 _refFrame(NULL),
     48 _refEncFrame(NULL),
     49 _refDecFrame(NULL),
     50 _refEncFrameLength(0),
     51 _sourceFile(NULL),
     52 is_key_frame_(false),
     53 _encodeCompleteCallback(NULL),
     54 _decodeCompleteCallback(NULL)
     55 {
     56 }
     57 
     58 UnitTest::~UnitTest()
     59 {
     60     if (_encodeCompleteCallback) {
     61         delete _encodeCompleteCallback;
     62     }
     63 
     64     if (_decodeCompleteCallback) {
     65         delete _decodeCompleteCallback;
     66     }
     67 
     68     if (_source) {
     69         delete _source;
     70     }
     71 
     72     if (_refFrame) {
     73         delete [] _refFrame;
     74     }
     75 
     76     if (_refDecFrame) {
     77         delete [] _refDecFrame;
     78     }
     79 
     80     if (_sourceBuffer) {
     81         delete [] _sourceBuffer;
     82     }
     83 
     84     if (_sourceFile) {
     85         fclose(_sourceFile);
     86     }
     87 
     88     if (_refEncFrame) {
     89         delete [] _refEncFrame;
     90     }
     91 }
     92 
     93 int32_t
     94 UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
     95                                         const webrtc::CodecSpecificInfo* codecSpecificInfo,
     96                                         const webrtc::RTPFragmentationHeader*
     97                                         fragmentation)
     98 {
     99     _encodedVideoBuffer->VerifyAndAllocate(encodedImage._size);
    100     _encodedVideoBuffer->CopyFrame(encodedImage._size, encodedImage._buffer);
    101     _encodedVideoBuffer->SetLength(encodedImage._length);
    102     // TODO(mikhal): Update frame type API.
    103     // _encodedVideoBuffer->SetFrameType(encodedImage._frameType);
    104     _encodedVideoBuffer->SetWidth(
    105         (uint16_t)encodedImage._encodedWidth);
    106     _encodedVideoBuffer->SetHeight(
    107         (uint16_t)encodedImage._encodedHeight);
    108     _encodedVideoBuffer->SetTimeStamp(encodedImage._timeStamp);
    109     _encodeComplete = true;
    110     _encodedFrameType = encodedImage._frameType;
    111     return 0;
    112 }
    113 
    114 int32_t UnitTestDecodeCompleteCallback::Decoded(I420VideoFrame& image)
    115 {
    116     _decodedVideoBuffer->CopyFrame(image);
    117     _decodeComplete = true;
    118     return 0;
    119 }
    120 
    121 bool
    122 UnitTestEncodeCompleteCallback::EncodeComplete()
    123 {
    124     if (_encodeComplete)
    125     {
    126         _encodeComplete = false;
    127         return true;
    128     }
    129     return false;
    130 }
    131 
    132 VideoFrameType
    133 UnitTestEncodeCompleteCallback::EncodedFrameType() const
    134 {
    135     return _encodedFrameType;
    136 }
    137 
    138 bool
    139 UnitTestDecodeCompleteCallback::DecodeComplete()
    140 {
    141     if (_decodeComplete)
    142     {
    143         _decodeComplete = false;
    144         return true;
    145     }
    146     return false;
    147 }
    148 
    149 uint32_t
    150 UnitTest::WaitForEncodedFrame() const
    151 {
    152     int64_t startTime = TickTime::MillisecondTimestamp();
    153     while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitEncTimeMs)
    154     {
    155         if (_encodeCompleteCallback->EncodeComplete())
    156         {
    157           return _encodedVideoBuffer.Length();
    158         }
    159     }
    160     return 0;
    161 }
    162 
    163 uint32_t
    164 UnitTest::WaitForDecodedFrame() const
    165 {
    166     int64_t startTime = TickTime::MillisecondTimestamp();
    167     while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitDecTimeMs)
    168     {
    169         if (_decodeCompleteCallback->DecodeComplete())
    170         {
    171           return webrtc::CalcBufferSize(kI420, _decodedVideoBuffer.width(),
    172                                         _decodedVideoBuffer.height());
    173         }
    174     }
    175     return 0;
    176 }
    177 
    178 uint32_t
    179 UnitTest::CodecSpecific_SetBitrate(uint32_t bitRate,
    180                                    uint32_t /* frameRate */)
    181 {
    182     return _encoder->SetRates(bitRate, _inst.maxFramerate);
    183 }
    184 
    185 void
    186 UnitTest::Setup()
    187 {
    188     // Use _sourceFile as a check to prevent multiple Setup() calls.
    189     if (_sourceFile != NULL)
    190     {
    191         return;
    192     }
    193 
    194     if (_encodeCompleteCallback == NULL)
    195     {
    196         _encodeCompleteCallback =
    197             new UnitTestEncodeCompleteCallback(&_encodedVideoBuffer);
    198     }
    199     if (_decodeCompleteCallback == NULL)
    200     {
    201         _decodeCompleteCallback =
    202             new UnitTestDecodeCompleteCallback(&_decodedVideoBuffer);
    203     }
    204 
    205     _encoder->RegisterEncodeCompleteCallback(_encodeCompleteCallback);
    206     _decoder->RegisterDecodeCompleteCallback(_decodeCompleteCallback);
    207 
    208     _source = new VideoSource(webrtc::test::ProjectRootPath() +
    209                               "resources/foreman_cif.yuv", kCIF);
    210 
    211     _lengthSourceFrame = _source->GetFrameLength();
    212     _refFrame = new unsigned char[_lengthSourceFrame];
    213     _refDecFrame = new unsigned char[_lengthSourceFrame];
    214     _sourceBuffer = new unsigned char [_lengthSourceFrame];
    215     _sourceFile = fopen(_source->GetFileName().c_str(), "rb");
    216     ASSERT_TRUE(_sourceFile != NULL);
    217 
    218     _inst.maxFramerate = _source->GetFrameRate();
    219     _bitRate = 300;
    220     _inst.startBitrate = 300;
    221     _inst.maxBitrate = 4000;
    222     _inst.width = _source->GetWidth();
    223     _inst.height = _source->GetHeight();
    224     _inst.qpMax = 56;
    225     _inst.codecSpecific.VP8.denoisingOn = true;
    226 
    227     // Get input frame.
    228     ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame, _sourceFile)
    229                            == _lengthSourceFrame);
    230     int size_y = _inst.width * _inst.height;
    231     int size_uv = ((_inst.width + 1) / 2)  * ((_inst.height + 1) / 2);
    232     _inputVideoBuffer.CreateFrame(size_y, _refFrame,
    233                                   size_uv, _refFrame + size_y,
    234                                   size_uv, _refFrame + size_y + size_uv,
    235                                   _inst.width, _inst.height,
    236                                   _inst.width,
    237                                   (_inst.width + 1) / 2, (_inst.width + 1) / 2);
    238     rewind(_sourceFile);
    239 
    240     // Get a reference encoded frame.
    241     _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
    242 
    243     // Ensures our initial parameters are valid.
    244     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    245     _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    246     _refEncFrameLength = WaitForEncodedFrame();
    247     ASSERT_TRUE(_refEncFrameLength > 0);
    248     _refEncFrame = new unsigned char[_refEncFrameLength];
    249     memcpy(_refEncFrame, _encodedVideoBuffer.Buffer(), _refEncFrameLength);
    250 
    251     // Get a reference decoded frame.
    252     _decodedVideoBuffer.CreateEmptyFrame(_inst.width, _inst.height, _inst.width,
    253                                          (_inst.width + 1) / 2,
    254                                          (_inst.width + 1) / 2);
    255     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    256     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    257 
    258     unsigned int frameLength = 0;
    259     int i = 0;
    260     _inputVideoBuffer.CreateEmptyFrame(_inst.width, _inst.height, _inst.width,
    261                                        (_inst.width + 1) / 2,
    262                                        (_inst.width + 1) / 2);
    263     while (frameLength == 0)
    264     {
    265          EncodedImage encodedImage;
    266         if (i > 0)
    267         {
    268             // Insert yet another frame.
    269             ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame,
    270                 _sourceFile) == _lengthSourceFrame);
    271             EXPECT_EQ(0, ConvertToI420(kI420, _refFrame, 0, 0, _width, _height,
    272                           0, kRotateNone, &_inputVideoBuffer));
    273             _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    274             ASSERT_TRUE(WaitForEncodedFrame() > 0);
    275         } else {
    276             // The first frame is always a key frame.
    277             encodedImage._frameType = kKeyFrame;
    278         }
    279 
    280         VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    281         ASSERT_TRUE(_decoder->Decode(encodedImage, 0, NULL)
    282                                == WEBRTC_VIDEO_CODEC_OK);
    283         frameLength = WaitForDecodedFrame();
    284         _encodedVideoBuffer.SetLength(0);
    285         i++;
    286     }
    287     rewind(_sourceFile);
    288     EXPECT_TRUE(frameLength == _lengthSourceFrame);
    289     ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame, _refDecFrame);
    290 }
    291 
    292 void
    293 UnitTest::Teardown()
    294 {
    295     // Use _sourceFile as a check to prevent multiple Teardown() calls.
    296     if (_sourceFile == NULL)
    297     {
    298         return;
    299     }
    300 
    301     _encoder->Release();
    302     _decoder->Release();
    303 
    304     fclose(_sourceFile);
    305     _sourceFile = NULL;
    306     delete [] _refFrame;
    307     _refFrame = NULL;
    308     delete [] _refEncFrame;
    309     _refEncFrame = NULL;
    310     delete [] _refDecFrame;
    311     _refDecFrame = NULL;
    312     delete [] _sourceBuffer;
    313     _sourceBuffer = NULL;
    314 }
    315 
    316 void
    317 UnitTest::Print()
    318 {
    319 }
    320 
    321 int
    322 UnitTest::DecodeWithoutAssert()
    323 {
    324     EncodedImage encodedImage;
    325     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    326     int ret = _decoder->Decode(encodedImage, 0, NULL);
    327     int frameLength = WaitForDecodedFrame();
    328     _encodedVideoBuffer.SetLength(0);
    329     return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
    330 }
    331 
    332 int
    333 UnitTest::Decode()
    334 {
    335     EncodedImage encodedImage;
    336     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    337     if (encodedImage._length == 0)
    338     {
    339         return WEBRTC_VIDEO_CODEC_OK;
    340     }
    341     if (is_key_frame_) {
    342         encodedImage._frameType = kKeyFrame;
    343     }
    344 
    345     int ret = _decoder->Decode(encodedImage, 0, NULL);
    346     unsigned int frameLength = WaitForDecodedFrame();
    347     assert(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
    348         == _lengthSourceFrame));
    349     EXPECT_TRUE(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
    350         == _lengthSourceFrame));
    351     _encodedVideoBuffer.SetLength(0);
    352     return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
    353 }
    354 
    355 // Test pure virtual VideoEncoder and VideoDecoder APIs.
    356 void
    357 UnitTest::Perform()
    358 {
    359     UnitTest::Setup();
    360     int frameLength;
    361     I420VideoFrame inputImage;
    362     EncodedImage encodedImage;
    363 
    364     //----- Encoder parameter tests -----
    365 
    366     //-- Calls before InitEncode() --
    367     // We want to revert the initialization done in Setup().
    368     EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    369     EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL)
    370                == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
    371 
    372     //-- InitEncode() errors --
    373     // Null pointer.
    374     EXPECT_TRUE(_encoder->InitEncode(NULL, 1, 1440) ==
    375         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    376     // bit rate exceeds max bit rate
    377     int32_t tmpBitRate = _inst.startBitrate;
    378     int32_t tmpMaxBitRate = _inst.maxBitrate;
    379     _inst.startBitrate = 4000;
    380     _inst.maxBitrate = 3000;
    381     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440)  ==
    382         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    383     _inst.startBitrate = tmpBitRate;
    384     _inst.maxBitrate = tmpMaxBitRate; //unspecified value
    385 
    386     // Bad framerate.
    387     _inst.maxFramerate = 0;
    388     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
    389         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    390     // Seems like we should allow any framerate in range [0, 255].
    391     //_inst.frameRate = 100;
    392     //EXPECT_TRUE(_encoder->InitEncode(&_inst, 1) == -1); // FAILS
    393     _inst.maxFramerate = 30;
    394 
    395     // Bad bitrate.
    396     _inst.startBitrate = static_cast<unsigned int>(-1);
    397     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
    398         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    399     _inst.maxBitrate = _inst.startBitrate - 1;
    400     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
    401         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    402     _inst.maxBitrate = 0;
    403     _inst.startBitrate = 300;
    404 
    405     // Bad maxBitRate.
    406     _inst.maxBitrate = 200;
    407     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
    408         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    409     _inst.maxBitrate = 4000;
    410 
    411     // Bad width.
    412     _inst.width = 0;
    413     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
    414     _inst.width = _source->GetWidth();
    415 
    416     // Bad height.
    417     _inst.height = 0;
    418     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
    419     _inst.height = _source->GetHeight();
    420 
    421     // Bad number of cores.
    422     EXPECT_TRUE(_encoder->InitEncode(&_inst, -1, 1440) ==
    423         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    424 
    425     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    426 
    427     //-- Encode() errors --
    428     inputImage.ResetSize();
    429     EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
    430         WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    431     int width = _source->GetWidth();
    432     int half_width = (width + 1) / 2;
    433     int height = _source->GetHeight();
    434     int half_height = (height + 1) / 2;
    435     int size_y = width * height;
    436     int size_uv = half_width * half_height;
    437     _inputVideoBuffer.CreateFrame(size_y, _refFrame,
    438                                   size_uv, _refFrame + size_y,
    439                                   size_uv, _refFrame + size_y + size_uv,
    440                                   width, height,
    441                                   width, half_width, half_width);
    442     //----- Encoder stress tests -----
    443 
    444     // Vary frame rate and I-frame request.
    445     for (int i = 1; i <= 60; i++)
    446     {
    447         VideoFrameType frame_type = !(i % 2) ? kKeyFrame : kDeltaFrame;
    448         std::vector<VideoFrameType> frame_types(1, frame_type);
    449         EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, &frame_types) ==
    450             WEBRTC_VIDEO_CODEC_OK);
    451         EXPECT_TRUE(WaitForEncodedFrame() > 0);
    452     }
    453 
    454     // Init then encode.
    455     _encodedVideoBuffer.SetLength(0);
    456     EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
    457         WEBRTC_VIDEO_CODEC_OK);
    458     EXPECT_TRUE(WaitForEncodedFrame() > 0);
    459 
    460     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    461     _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    462     frameLength = WaitForEncodedFrame();
    463     EXPECT_TRUE(frameLength > 0);
    464     EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
    465             _encodedVideoBuffer.Buffer(), frameLength) == true);
    466 
    467     // Reset then encode.
    468     _encodedVideoBuffer.SetLength(0);
    469     EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
    470         WEBRTC_VIDEO_CODEC_OK);
    471     WaitForEncodedFrame();
    472     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    473     _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    474     frameLength = WaitForEncodedFrame();
    475     EXPECT_TRUE(frameLength > 0);
    476     EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
    477         _encodedVideoBuffer.Buffer(), frameLength) == true);
    478 
    479     // Release then encode.
    480     _encodedVideoBuffer.SetLength(0);
    481     EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
    482         WEBRTC_VIDEO_CODEC_OK);
    483     WaitForEncodedFrame();
    484     EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    485     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    486     _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    487     frameLength = WaitForEncodedFrame();
    488     EXPECT_TRUE(frameLength > 0);
    489     EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
    490         _encodedVideoBuffer.Buffer(), frameLength) == true);
    491 
    492     //----- Decoder parameter tests -----
    493 
    494     //-- Calls before InitDecode() --
    495     // We want to revert the initialization done in Setup().
    496     EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    497     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    498     EXPECT_TRUE(_decoder->Decode(encodedImage, false, NULL) ==
    499         WEBRTC_VIDEO_CODEC_UNINITIALIZED);
    500     WaitForDecodedFrame();
    501     EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
    502     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    503     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    504 
    505     //-- Decode() errors --
    506     // Unallocated encodedVideoBuffer.
    507     _encodedVideoBuffer.Free();
    508     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    509     encodedImage._length = 10;  // Buffer NULL but length > 0
    510     EXPECT_EQ(_decoder->Decode(encodedImage, false, NULL),
    511               WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
    512     _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
    513 
    514     //----- Decoder stress tests -----
    515     unsigned char* tmpBuf = new unsigned char[_lengthSourceFrame];
    516 
    517     // "Random" and zero data.
    518     // We either expect an error, or at the least, no output.
    519     // This relies on the codec's ability to detect an erroneous bitstream.
    520     EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    521     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    522     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    523     for (int i = 0; i < 100; i++)
    524     {
    525         ASSERT_TRUE(fread(tmpBuf, 1, _refEncFrameLength, _sourceFile)
    526             == _refEncFrameLength);
    527         _encodedVideoBuffer.CopyFrame(_refEncFrameLength, tmpBuf);
    528         VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    529         int ret = _decoder->Decode(encodedImage, false, NULL);
    530         EXPECT_TRUE(ret <= 0);
    531         if (ret == 0)
    532         {
    533             EXPECT_TRUE(WaitForDecodedFrame() == 0);
    534         }
    535 
    536         memset(tmpBuf, 0, _refEncFrameLength);
    537         _encodedVideoBuffer.CopyFrame(_refEncFrameLength, tmpBuf);
    538         VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    539         if (i == 0) {
    540             // First frame is a key frame.
    541             is_key_frame_ = true;
    542         }
    543         ret = _decoder->Decode(encodedImage, false, NULL);
    544         EXPECT_TRUE(ret <= 0);
    545         if (ret == 0)
    546         {
    547             EXPECT_TRUE(WaitForDecodedFrame() == 0);
    548         }
    549     }
    550     rewind(_sourceFile);
    551 
    552     _encodedVideoBuffer.SetLength(_refEncFrameLength);
    553     _encodedVideoBuffer.CopyFrame(_refEncFrameLength, _refEncFrame);
    554 
    555     // Init then decode.
    556     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    557     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    558     frameLength = 0;
    559     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    560     // first frame is a key frame.
    561     encodedImage._frameType = kKeyFrame;
    562     while (frameLength == 0)
    563     {
    564         _decoder->Decode(encodedImage, false, NULL);
    565         frameLength = WaitForDecodedFrame();
    566     }
    567     unsigned int length = CalcBufferSize(kI420, width, height);
    568     scoped_ptr<uint8_t[]> decoded_buffer(new uint8_t[length]);
    569     ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
    570                   decoded_buffer.get());
    571     EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength, _refDecFrame,
    572                                 _lengthSourceFrame) == true);
    573 
    574     // Reset then decode.
    575     EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    576     frameLength = 0;
    577     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    578     while (frameLength == 0)
    579     {
    580         _decoder->Decode(encodedImage, false, NULL);
    581         frameLength = WaitForDecodedFrame();
    582     }
    583     ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
    584                   decoded_buffer.get());
    585     EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
    586                                 _refDecFrame, _lengthSourceFrame) == true);
    587 
    588     // Decode with other size, reset, then decode with original size again
    589     // to verify that decoder is reset to a "fresh" state upon Reset().
    590     {
    591         // Assert that input frame size is a factor of two, so that we can use
    592         // quarter size below.
    593         EXPECT_TRUE((_inst.width % 2 == 0) && (_inst.height % 2 == 0));
    594 
    595         VideoCodec tempInst;
    596         memcpy(&tempInst, &_inst, sizeof(VideoCodec));
    597         tempInst.width /= 2;
    598         tempInst.height /= 2;
    599         int tmpHalfWidth = (tempInst.width + 1) / 2;
    600         int tmpHalfHeight = (tempInst.height + 1) / 2;
    601 
    602         int tmpSizeY = tempInst.width * tempInst.height;
    603         int tmpSizeUv = tmpHalfWidth * tmpHalfHeight;
    604 
    605         // Encode reduced (quarter) frame size.
    606         EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    607         EXPECT_TRUE(_encoder->InitEncode(&tempInst, 1, 1440) ==
    608             WEBRTC_VIDEO_CODEC_OK);
    609         webrtc::I420VideoFrame tempInput;
    610         tempInput.CreateFrame(tmpSizeY, _inputVideoBuffer.buffer(kYPlane),
    611                               tmpSizeUv, _inputVideoBuffer.buffer(kUPlane),
    612                               tmpSizeUv, _inputVideoBuffer.buffer(kVPlane),
    613                               tempInst.width, tempInst.height,
    614                               tempInst.width, tmpHalfWidth, tmpHalfWidth);
    615         _encoder->Encode(tempInput, NULL, NULL);
    616         frameLength = WaitForEncodedFrame();
    617         EXPECT_TRUE(frameLength > 0);
    618         // Reset then decode.
    619         EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    620         frameLength = 0;
    621         VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    622         while (frameLength == 0)
    623         {
    624             _decoder->Decode(encodedImage, false, NULL);
    625             frameLength = WaitForDecodedFrame();
    626         }
    627 
    628         // Encode original frame again
    629         EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    630         EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
    631             WEBRTC_VIDEO_CODEC_OK);
    632         _encoder->Encode(_inputVideoBuffer, NULL, NULL);
    633         frameLength = WaitForEncodedFrame();
    634         EXPECT_TRUE(frameLength > 0);
    635 
    636         // Reset then decode original frame again.
    637         EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    638         frameLength = 0;
    639         VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    640         while (frameLength == 0)
    641         {
    642             _decoder->Decode(encodedImage, false, NULL);
    643             frameLength = WaitForDecodedFrame();
    644         }
    645 
    646         // check that decoded frame matches with reference
    647         unsigned int length = CalcBufferSize(kI420, width, height);
    648         scoped_ptr<uint8_t[]> decoded_buffer(new uint8_t[length]);
    649         ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
    650         EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), length,
    651                                     _refDecFrame, _lengthSourceFrame) == true);
    652     }
    653 
    654     // Release then decode.
    655     EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
    656     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    657     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    658     frameLength = 0;
    659     VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
    660     while (frameLength == 0)
    661     {
    662         _decoder->Decode(encodedImage, false, NULL);
    663         frameLength = WaitForDecodedFrame();
    664     }
    665     ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
    666     EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
    667                                 _refDecFrame, _lengthSourceFrame) == true);
    668     _encodedVideoBuffer.SetLength(0);
    669 
    670     delete [] tmpBuf;
    671 
    672     //----- Function tests -----
    673     int frames = 0;
    674     // Do not specify maxBitRate (as in ViE).
    675     _inst.maxBitrate = 0;
    676 
    677     //-- Timestamp propagation --
    678     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    679     EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    680     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    681     ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
    682 
    683     frames = 0;
    684     int frameDelay = 0;
    685     int encTimeStamp;
    686     _decodedVideoBuffer.set_timestamp(0);
    687     while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
    688         _lengthSourceFrame)
    689     {
    690       _inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
    691                                     size_uv, _sourceBuffer + size_y,
    692                                     size_uv, _sourceBuffer + size_y + size_uv,
    693                                     width, height,
    694                                     width, half_width, half_width);
    695 
    696         _inputVideoBuffer.set_timestamp(frames);
    697         ASSERT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
    698             WEBRTC_VIDEO_CODEC_OK);
    699         frameLength = WaitForEncodedFrame();
    700         //ASSERT_TRUE(frameLength);
    701         EXPECT_TRUE(frameLength > 0);
    702         encTimeStamp = _encodedVideoBuffer.TimeStamp();
    703         EXPECT_TRUE(_inputVideoBuffer.timestamp() ==
    704                 static_cast<unsigned>(encTimeStamp));
    705         if (frames == 0) {
    706             // First frame is always a key frame.
    707             is_key_frame_ = true;
    708         }
    709 
    710         frameLength = Decode();
    711         if (frameLength == 0)
    712         {
    713             frameDelay++;
    714         }
    715 
    716         encTimeStamp -= frameDelay;
    717         if (encTimeStamp < 0)
    718         {
    719             encTimeStamp = 0;
    720         }
    721         EXPECT_TRUE(_decodedVideoBuffer.timestamp() ==
    722                 static_cast<unsigned>(encTimeStamp));
    723         frames++;
    724     }
    725     ASSERT_TRUE(feof(_sourceFile) != 0);
    726     rewind(_sourceFile);
    727 
    728     RateControlTests();
    729 
    730     Teardown();
    731 }
    732 
    733 void
    734 UnitTest::RateControlTests()
    735 {
    736     int frames = 0;
    737     VideoFrame inputImage;
    738     uint32_t frameLength;
    739 
    740     // Do not specify maxBitRate (as in ViE).
    741     _inst.maxBitrate = 0;
    742     // Verify rate control. For this test turn on codec frame dropper.
    743     // At least one other test (BasicUnitTest) assumes frame dropper off, so
    744     // for now we only set frame dropper on for this (rate control) test.
    745     _inst.codecSpecific.VP8.frameDroppingOn = true;
    746     EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
    747     EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
    748     EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
    749     // add: should also be 0, and 1
    750     const int bitRate[] = {100, 500};
    751     const int nBitrates = sizeof(bitRate)/sizeof(*bitRate);
    752 
    753     printf("\nRate control test\n");
    754     for (int i = 0; i < nBitrates; i++)
    755     {
    756         _bitRate = bitRate[i];
    757         int totalBytes = 0;
    758         _inst.startBitrate = _bitRate;
    759         _encoder->InitEncode(&_inst, 4, 1440);
    760         _decoder->Reset();
    761         _decoder->InitDecode(&_inst, 1);
    762         frames = 0;
    763 
    764         if (_bitRate > _inst.maxBitrate)
    765         {
    766             CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
    767         }
    768         else
    769         {
    770             CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
    771         }
    772         int width = _source->GetWidth();
    773         int half_width = (width + 1) / 2;
    774         int height = _source->GetHeight();
    775         int half_height = (height + 1) / 2;
    776         int size_y = width * height;
    777         int size_uv = half_width * half_height;
    778         while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
    779             _lengthSourceFrame)
    780         {
    781             _inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
    782                                            size_uv, _sourceBuffer + size_y,
    783                                            size_uv, _sourceBuffer + size_y +
    784                                            size_uv,
    785                                            width, height,
    786                                            width, half_width, half_width);
    787             _inputVideoBuffer.set_timestamp(static_cast<uint32_t>(9e4 /
    788                     static_cast<float>(_inst.maxFramerate)));
    789             ASSERT_EQ(_encoder->Encode(_inputVideoBuffer, NULL, NULL),
    790                       WEBRTC_VIDEO_CODEC_OK);
    791             frameLength = WaitForEncodedFrame();
    792             ASSERT_GE(frameLength, 0u);
    793             totalBytes += frameLength;
    794             frames++;
    795 
    796             _encodedVideoBuffer.SetLength(0);
    797         }
    798         uint32_t actualBitrate =
    799             (totalBytes  / frames * _inst.maxFramerate * 8)/1000;
    800         printf("Target bitrate: %d kbps, actual bitrate: %d kbps\n", _bitRate,
    801             actualBitrate);
    802         // Test for close match over reasonable range.
    803           EXPECT_TRUE(abs(int32_t(actualBitrate - _bitRate)) <
    804                       0.12 * _bitRate);
    805         ASSERT_TRUE(feof(_sourceFile) != 0);
    806         rewind(_sourceFile);
    807     }
    808 }
    809 
    810 bool
    811 UnitTest::CheckIfBitExact(const void* ptrA, unsigned int aLengthBytes,
    812                           const void* ptrB, unsigned int bLengthBytes)
    813 {
    814     if (aLengthBytes != bLengthBytes)
    815     {
    816         return false;
    817     }
    818 
    819     return memcmp(ptrA, ptrB, aLengthBytes) == 0;
    820 }
    821