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