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
112637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/generic_codec_test.h"
122637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org
133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h>
152637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org
162637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/common_video/interface/i420_video_frame.h"
172637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
182637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h"
192637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_macros.h"
201bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h"
214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc;
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgenum { kMaxWaitEncTimeMs = 100 };
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint GenericCodecTest::RunTest(CmdArgs& args)
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
291bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    SimulatedClock clock(0);
302637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org    NullEventFactory event_factory;
318edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    VideoCodingModule* vcm = VideoCodingModule::Create(&clock, &event_factory);
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GenericCodecTest* get = new GenericCodecTest(vcm, &clock);
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::CreateTrace();
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::SetTraceFile(
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        (test::OutputPath() + "genericCodecTestTrace.txt").c_str());
3606eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org    Trace::set_level_filter(webrtc::kTraceAll);
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    get->Perform(args);
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Trace::ReturnTrace();
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete get;
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoCodingModule::Destroy(vcm);
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
441bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.orgGenericCodecTest::GenericCodecTest(VideoCodingModule* vcm,
451bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org                                   SimulatedClock* clock):
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_clock(clock),
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_vcm(vcm),
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_width(0),
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_height(0),
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frameRate(0),
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lengthSourceFrame(0),
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_timeStamp(0)
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::~GenericCodecTest()
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::Setup(CmdArgs& args)
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _timeStamp = 0;
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Test Sequence parameters */
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inname= args.inputFile;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (args.outputFile.compare(""))
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _outname = test::OutputPath() + "GCTest_decoded.yuv";
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _outname = args.outputFile;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedName = test::OutputPath() + "GCTest_encoded.vp8";
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = args.width;
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = args.height;
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameRate = args.frameRate;
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lengthSourceFrame  = 3*_width*_height/2;
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* File settings */
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((_sourceFile = fopen(_inname.c_str(), "rb")) == NULL)
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Cannot read file %s.\n", _inname.c_str());
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((_encodedFile = fopen(_encodedName.c_str(), "wb")) == NULL)
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Cannot write encoded file.\n");
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((_decodedFile = fopen(_outname.c_str(),  "wb")) == NULL)
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Cannot write file %s.\n", _outname.c_str());
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
98dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::Perform(CmdArgs& args)
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
101dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    int32_t ret;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Setup(args);
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /*
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    1. sanity checks
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    2. encode/decoder individuality
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    3. API testing
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    4. Target bitrate (within a specific timespan)
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    5. Pipeline Delay
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    */
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /*******************************/
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* sanity checks on inputs    */
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /*****************************/
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoCodec sendCodec, receiveCodec;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.maxBitrate = 8000;
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->NumberOfCodecs() > 0); // This works since we now initialize the list in the constructor
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->Codec(0, &sendCodec)  == VCM_OK);
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
120dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    int32_t NumberOfCodecs = _vcm->NumberOfCodecs();
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // registration of first codec in the list
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int i = 0;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Codec(0, &_sendCodec);
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1440) == VCM_OK);
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // sanity on encoder registration
1263bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    I420VideoFrame sourceFrame;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->Codec(kVideoCodecVP8, &sendCodec) == 0);
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.maxBitrate = 8000;
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendCodec(&sendCodec, 1, 1440);
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Codec(kVideoCodecVP8, &sendCodec);
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.height = 0;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->RegisterSendCodec(&sendCodec, 1, 1440) < 0); // bad height
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Codec(kVideoCodecVP8, &sendCodec);
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Codec(kVideoCodecVP8, &sendCodec);
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
13872e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    // Setting rate when encoder uninitialized.
13972e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    TEST(_vcm->SetChannelParameters(100000, 0, 0) < 0);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // register all availbale decoders -- need to have more for this test
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (i=0; i< NumberOfCodecs; i++)
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->Codec(i, &receiveCodec);
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->RegisterReceiveCodec(&receiveCodec, 1);
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
146dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    uint8_t* tmpBuffer = new uint8_t[_lengthSourceFrame];
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
1483bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    int half_width = (_width + 1) / 2;
1493bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    int half_height = (_height + 1) / 2;
1503bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    int size_y = _width * _height;
1513bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    int size_uv = half_width * half_height;
1523bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    sourceFrame.CreateFrame(size_y, tmpBuffer,
1533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                            size_uv, tmpBuffer + size_y,
1543bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                            size_uv, tmpBuffer + size_y + size_uv,
1553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                            _width, _height,
1563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                            _width, half_width, half_width);
1573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    sourceFrame.set_timestamp(_timeStamp++);
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->AddVideoFrame(sourceFrame) < 0 ); // encoder uninitialized
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
16072e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    // Setting rtt when receiver uninitialized.
16172e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    TEST(_vcm->SetChannelParameters(100000, 0, 0) < 0);
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      /**************************************/
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org     /* encoder/decoder individuality test */
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /**************************************/
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //Register both encoder and decoder, reset decoder - encode, set up decoder, reset encoder - decode.
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rewind(_sourceFile);
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NumberOfCodecs = _vcm->NumberOfCodecs();
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Register VP8
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Codec(kVideoCodecVP8, &_sendCodec);
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->SendCodec(&sendCodec);
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.startBitrate = 2000;
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set target frame rate to half of the incoming frame rate
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // to test the frame rate control in the VCM
179dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    sendCodec.maxFramerate = (uint8_t)(_frameRate / 2);
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.width = _width;
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sendCodec.height = _height;
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(strncmp(_sendCodec.plName, "VP8", 3) == 0); // was VP8
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _decodeCallback = new VCMDecodeCompleteCallback(_decodedFile);
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback = new VCMEncodeCompleteCallback(_encodedFile);
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterReceiveCallback(_decodeCallback);
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterTransportCallback(_encodeCompleteCallback);
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->RegisterReceiverVCM(_vcm);
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendCodec(&sendCodec, 4, 1440);
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->SetCodecType(ConvertCodecType(sendCodec.plName));
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->Process();
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //encoding 1 second of video
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (i = 0; i < _frameRate; i++)
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
2003bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        sourceFrame.CreateFrame(size_y, tmpBuffer,
2013bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                size_uv, tmpBuffer + size_y,
2023bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                size_uv, tmpBuffer + size_y + size_uv,
2033bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                _width, _height,
2043bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                _width, half_width, half_width);
205dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        _timeStamp += (uint32_t)(9e4 / static_cast<float>(_frameRate));
2063bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        sourceFrame.set_timestamp(_timeStamp);
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        IncrementDebugClock(_frameRate);
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->Process();
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
211dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    sendCodec.maxFramerate = (uint8_t)_frameRate;
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK); // same codec for encode and decode
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ret = 0;
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    i = 0;
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while ((i < 25) && (ret == 0) )
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ret = _vcm->Decode();
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        TEST(ret == VCM_OK);
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (ret < 0)
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            printf("error in frame # %d \n", i);
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        IncrementDebugClock(_frameRate);
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        i++;
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //TEST((ret == 0) && (i = 50));
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ret == 0)
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Encoder/Decoder individuality test complete - View output files \n");
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // last frame - not decoded
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->Decode() < 0); // frame to be encoded exists, decoder uninitialized
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Test key frame request on packet loss mode.
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This a frame as a key frame and fooling the receiver
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // that the last packet was lost. The decoding will succeed,
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // but the VCM will see a packet loss and request a new key frame.
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VCMEncComplete_KeyReqTest keyReqTest_EncCompleteCallback(*_vcm);
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    KeyFrameReqTest frameTypeCallback;
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterTransportCallback(&keyReqTest_EncCompleteCallback);
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->RegisterReceiverVCM(_vcm);
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendCodec(&sendCodec, 4, 1440);
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->SetCodecType(ConvertCodecType(sendCodec.plName));
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->SetVideoProtection(kProtectionKeyOnKeyLoss, true) == VCM_OK);
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->RegisterFrameTypeCallback(&frameTypeCallback) == VCM_OK);
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
251dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    _timeStamp += (uint32_t)(9e4 / static_cast<float>(_frameRate));
2523bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    sourceFrame.set_timestamp(_timeStamp);
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // First packet of a subsequent frame required before the jitter buffer
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // will allow decoding an incomplete frame.
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(_vcm->Decode() == VCM_OK);
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("API tests complete \n");
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org     /*******************/
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Bit Rate Tests */
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /*****************/
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Requirements:
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    * 1. OneSecReq = 15 % above/below target over a time period of 1s (_frameRate number of frames)
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    * 3. FullReq  = 10% for total seq. (for 300 frames/seq. coincides with #1)
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    * 4. Test will go over all registered codecs
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //NOTE: time requirements are not part of the release tests
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    */
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double FullReq   =  0.1;
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //double OneSecReq = 0.15;
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("\n RATE CONTROL TEST\n");
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // initializing....
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeReceiver();
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rewind(_sourceFile);
2763bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    sourceFrame.CreateEmptyFrame(_width, _height, _width,
2773bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                 (_width + 1) / 2, (_width + 1) / 2);
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const float bitRate[] = {100, 400, 600, 1000, 2000};
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const float nBitrates = sizeof(bitRate)/sizeof(*bitRate);
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    float _bitRate = 0;
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int _frameCnt = 0;
28222c283b04855b8775d323e8788a0438ce2d7c2b5henrike@webrtc.org    float totalBytesOneSec = 0;//, totalBytesTenSec;
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    float totalBytes, actualBitrate;
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VCMFrameCount frameCount; // testing frame type counters
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // start test
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NumberOfCodecs = _vcm->NumberOfCodecs();
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // going over all available codecs
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->SetFrameDimensions(_width, _height);
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SendStatsTest sendStats;
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (int k = 0; k < NumberOfCodecs; k++)
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //for (int k = NumberOfCodecs - 1; k >=0; k--)
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {// static list starts from 0
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //just checking
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->InitializeSender();
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _sendCodec.maxBitrate = 8000;
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        TEST(_vcm->Codec(k, &_sendCodec)== VCM_OK);
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->RegisterSendCodec(&_sendCodec, 1, 1440);
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->RegisterTransportCallback(_encodeCompleteCallback);
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodeCompleteCallback->SetCodecType(ConvertCodecType(_sendCodec.plName));
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf (" \n\n Codec type = %s \n\n",_sendCodec.plName);
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (i = 0; i < nBitrates; i++)
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org             _bitRate = static_cast<float>(bitRate[i]);
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // just testing
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->InitializeSender();
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _sendCodec.startBitrate = (int)_bitRate;
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _sendCodec.maxBitrate = 8000;
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _sendCodec.maxFramerate = _frameRate;
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->RegisterSendCodec(&_sendCodec, 1, 1440);
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->RegisterTransportCallback(_encodeCompleteCallback);
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // up to here
31272e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org            _vcm->SetChannelParameters(static_cast<uint32_t>(1000 * _bitRate),
31372e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org                                       0, 20);
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _frameCnt = 0;
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            totalBytes = 0;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _encodeCompleteCallback->Initialize();
317dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org            sendStats.set_framerate(static_cast<uint32_t>(_frameRate));
31863136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org            sendStats.set_bitrate(1000 * _bitRate);
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->RegisterSendStatisticsCallback(&sendStats);
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            while (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) ==
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                _lengthSourceFrame)
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                _frameCnt++;
3243bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                sourceFrame.CreateFrame(size_y, tmpBuffer,
3253bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                        size_uv, tmpBuffer + size_y,
3263bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                        size_uv, tmpBuffer + size_y + size_uv,
3273bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                        _width, _height,
3283bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                        _width, (_width + 1) / 2,
3293bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                        (_width + 1) / 2);
330dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org                _timeStamp += (uint32_t)(9e4 / static_cast<float>(_frameRate));
3313bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                sourceFrame.set_timestamp(_timeStamp);
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                ret = _vcm->AddVideoFrame(sourceFrame);
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                IncrementDebugClock(_frameRate);
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // The following should be uncommneted for timing tests. Release tests only include
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // compliance with full sequence bit rate.
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (_frameCnt == _frameRate)// @ 1sec
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    totalBytesOneSec =  _encodeCompleteCallback->EncodedBytes();//totalBytes;
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                TEST(_vcm->TimeUntilNextProcess() >= 0);
3423b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org            }  // video seq. encode done
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            TEST(_vcm->TimeUntilNextProcess() == 0);
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->Process(); // Let the module calculate its send bit rate estimate
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // estimating rates
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // complete sequence
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // bit rate assumes input frame rate is as specified
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            totalBytes = _encodeCompleteCallback->EncodedBytes();
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            actualBitrate = (float)(8.0/1000)*(totalBytes / (_frameCnt / _frameRate));
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            printf("Complete Seq.: target bitrate: %.0f kbps, actual bitrate: %.1f kbps\n", _bitRate, actualBitrate);
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            TEST((fabs(actualBitrate - _bitRate) < FullReq * _bitRate) ||
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 (strncmp(_sendCodec.plName, "I420", 4) == 0));
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // 1 Sec.
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            actualBitrate = (float)(8.0/1000)*(totalBytesOneSec);
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //actualBitrate = (float)(8.0*totalBytesOneSec)/(oneSecTime - startTime);
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //printf("First 1Sec: target bitrate: %.0f kbps, actual bitrate: %.1f kbps\n", _bitRate, actualBitrate);
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //TEST(fabs(actualBitrate - _bitRate) < OneSecReq * _bitRate);
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rewind(_sourceFile);
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //checking key/delta frame count
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->SentFrameCount(frameCount);
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            printf("frame count: %d delta, %d key\n", frameCount.numDeltaFrames, frameCount.numKeyFrames);
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }// end per codec
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3673b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org    }  // end rate control test
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /********************************/
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Encoder Pipeline Delay Test */
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /******************************/
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NumberOfCodecs = _vcm->NumberOfCodecs();
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool encodeComplete = false;
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // going over all available codecs
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (int k = 0; k < NumberOfCodecs; k++)
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->Codec(k, &_sendCodec);
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->InitializeSender();
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _sendCodec.maxBitrate = 8000;
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->RegisterTransportCallback(_encodeCompleteCallback);
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _frameCnt = 0;
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        encodeComplete = false;
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while (encodeComplete == false)
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _frameCnt++;
3893bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org            sourceFrame.CreateFrame(size_y, tmpBuffer,
3903bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                    size_uv, tmpBuffer + size_y,
3913bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                    size_uv, tmpBuffer + size_y + size_uv,
3923bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                    _width, _height,
3933bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                    _width, half_width, half_width);
394dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org            _timeStamp += (uint32_t)(9e4 / static_cast<float>(_frameRate));
3953bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org            sourceFrame.set_timestamp(_timeStamp);
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->AddVideoFrame(sourceFrame);
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            encodeComplete = _encodeCompleteCallback->EncodeComplete();
3983b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org        }  // first frame encoded
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf ("\n Codec type = %s \n", _sendCodec.plName);
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf(" Encoder pipeline delay = %d frames\n", _frameCnt - 1);
4013b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org    }  // end for all codecs
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /********************************/
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* Encoder Packet Size Test     */
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /********************************/
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    RTPSendCallback_SizeTest sendCallback;
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    RtpRtcp::Configuration configuration;
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    configuration.id = 1;
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    configuration.audio = false;
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    configuration.outgoing_transport = &sendCallback;
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    RtpRtcp& rtpModule = *RtpRtcp::CreateRtpRtcp(configuration);
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VCMRTPEncodeCompleteCallback encCompleteCallback(&rtpModule);
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Test temporal decimation settings
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (int k = 0; k < NumberOfCodecs; k++)
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _vcm->Codec(k, &_sendCodec);
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (strncmp(_sendCodec.plName, "I420", 4) == 0)
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // Only test with I420
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TEST(strncmp(_sendCodec.plName, "I420", 4) == 0);
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->InitializeSender();
430dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    _sendCodec.maxFramerate = static_cast<uint8_t>(_frameRate / 2.0 + 0.5f);
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
43272e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    _vcm->SetChannelParameters(2000000, 0, 0);
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterTransportCallback(_encodeCompleteCallback);
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // up to here
43572e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org    _vcm->SetChannelParameters(static_cast<uint32_t>(1000 * _bitRate), 0, 20);
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeCompleteCallback->Initialize();
437dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    sendStats.set_framerate(static_cast<uint32_t>(_frameRate));
43863136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org    sendStats.set_bitrate(1000 * _bitRate);
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _vcm->RegisterSendStatisticsCallback(&sendStats);
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rewind(_sourceFile);
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) ==
4423bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        _lengthSourceFrame) {
4433bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        sourceFrame.CreateFrame(size_y, tmpBuffer,
4443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                size_uv, tmpBuffer + size_y,
4453bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                size_uv, tmpBuffer + size_y + size_uv,
4463bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                _width, _height,
4473bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                _width, half_width, half_width);
448dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        _timeStamp += (uint32_t)(9e4 / static_cast<float>(_frameRate));
4493bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        sourceFrame.set_timestamp(_timeStamp);
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ret = _vcm->AddVideoFrame(sourceFrame);
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_vcm->TimeUntilNextProcess() <= 0)
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _vcm->Process();
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        IncrementDebugClock(_frameRate);
4563b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org    }  // first frame encoded
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete &rtpModule;
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Print();
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete tmpBuffer;
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _decodeCallback;
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _encodeCompleteCallback;
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::Print()
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf(" \n\n VCM Generic Encoder Test: \n\n%i tests completed\n", vcmMacrosTests);
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (vcmMacrosErrors > 0)
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("%i FAILED\n\n", vcmMacrosErrors);
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("ALL PASSED\n\n");
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfloat
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::WaitForEncodedFrame() const
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
484dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    int64_t startTime = _clock->TimeInMilliseconds();
4851bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    while (_clock->TimeInMilliseconds() - startTime < kMaxWaitEncTimeMs*10)
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_encodeCompleteCallback->EncodeComplete())
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return _encodeCompleteCallback->EncodedBytes();
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGenericCodecTest::IncrementDebugClock(float frameRate)
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
4981bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    _clock->AdvanceTimeMilliseconds(1000/frameRate);
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCallback_SizeTest::SendPacket(int channel, const void *data, int len)
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nPackets++;
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _payloadSizeSum += len;
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Make sure no payloads (len - header size) are larger than maxPayloadSize
507dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    TEST(len > 0 && static_cast<uint32_t>(len - 12) <= _maxPayloadSize);
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
512dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgRTPSendCallback_SizeTest::SetMaxPayloadSize(uint32_t maxPayloadSize)
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _maxPayloadSize = maxPayloadSize;
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCallback_SizeTest::Reset()
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nPackets = 0;
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _payloadSizeSum = 0;
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfloat
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCallback_SizeTest::AveragePayloadSize() const
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_nPackets > 0)
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return _payloadSizeSum / static_cast<float>(_nPackets);
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
534dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncComplete_KeyReqTest::SendData(
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const FrameType frameType,
537dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t payloadType,
538dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t timeStamp,
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int64_t capture_time_ms,
540dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t* payloadData,
541dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t payloadSize,
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPFragmentationHeader& /*fragmentationHeader*/,
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const webrtc::RTPVideoHeader* /*videoHdr*/)
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcRTPHeader rtpInfo;
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.markerBit = true; // end of frame
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
5487fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    rtpInfo.type.Video.codec = kRtpVideoVp8;
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.payloadType = payloadType;
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.sequenceNumber = _seqNo;
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _seqNo += 2;
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.ssrc = 0;
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.timestamp = _timeStamp;
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _timeStamp += 3000;
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.type.Video.isFirstPacket = false;
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.frameType = kVideoFrameKey;
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _vcm.IncomingPacket(payloadData, payloadSize, rtpInfo);
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
559