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