/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "generic_codec_test.h"
#include <cmath>
#include <stdio.h>
#include "../source/event.h"
#include "rtp_rtcp.h"
#include "module_common_types.h"
#include "test_macros.h"
#include "modules/video_coding/main/source/mock/fake_tick_time.h"

using namespace webrtc;

enum { kMaxWaitEncTimeMs = 100 };

int GenericCodecTest::RunTest(CmdArgs& args)
{
#if !defined(EVENT_DEBUG)
    printf("\n\nEnable debug events to run this test!\n\n");
    return -1;
#endif
    FakeTickTime clock(0);
    VideoCodingModule* vcm = VideoCodingModule::Create(1, &clock);
    GenericCodecTest* get = new GenericCodecTest(vcm, &clock);
    Trace::CreateTrace();
    Trace::SetTraceFile(
        (test::OutputPath() + "genericCodecTestTrace.txt").c_str());
    Trace::SetLevelFilter(webrtc::kTraceAll);
    get->Perform(args);
    Trace::ReturnTrace();
    delete get;
    VideoCodingModule::Destroy(vcm);
    return 0;
}

GenericCodecTest::GenericCodecTest(VideoCodingModule* vcm, FakeTickTime* clock):
_clock(clock),
_vcm(vcm),
_width(0),
_height(0),
_frameRate(0),
_lengthSourceFrame(0),
_timeStamp(0)
{
}

GenericCodecTest::~GenericCodecTest()
{
}

void
GenericCodecTest::Setup(CmdArgs& args)
{
    _timeStamp = 0;

    /* Test Sequence parameters */

    _inname= args.inputFile;
    if (args.outputFile.compare(""))
        _outname = test::OutputPath() + "GCTest_decoded.yuv";
    else
        _outname = args.outputFile;
    _encodedName = test::OutputPath() + "GCTest_encoded.vp8";
    _width = args.width;
    _height = args.height;
    _frameRate = args.frameRate;
    _lengthSourceFrame  = 3*_width*_height/2;

    /* File settings */

    if ((_sourceFile = fopen(_inname.c_str(), "rb")) == NULL)
    {
        printf("Cannot read file %s.\n", _inname.c_str());
        exit(1);
    }
    if ((_encodedFile = fopen(_encodedName.c_str(), "wb")) == NULL)
    {
        printf("Cannot write encoded file.\n");
        exit(1);
    }
    if ((_decodedFile = fopen(_outname.c_str(),  "wb")) == NULL)
    {
        printf("Cannot write file %s.\n", _outname.c_str());
        exit(1);
    }

    return;
}
WebRtc_Word32
GenericCodecTest::Perform(CmdArgs& args)
{
    WebRtc_Word32 ret;
    Setup(args);
    /*
    1. sanity checks
    2. encode/decoder individuality
    3. API testing
    4. Target bitrate (within a specific timespan)
    5. Pipeline Delay
    */

    /*******************************/
    /* sanity checks on inputs    */
    /*****************************/
    VideoCodec sendCodec, receiveCodec;
    sendCodec.maxBitrate = 8000;
    TEST(_vcm->NumberOfCodecs() > 0); // This works since we now initialize the list in the constructor
    TEST(_vcm->Codec(0, &sendCodec)  == VCM_OK);
    _vcm->InitializeSender();
    _vcm->InitializeReceiver();
    WebRtc_Word32 NumberOfCodecs = _vcm->NumberOfCodecs();
    // registration of first codec in the list
    int i = 0;
    _vcm->Codec(0, &_sendCodec);
    TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1440) == VCM_OK);
    // sanity on encoder registration
    VideoFrame sourceFrame;
    sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
    _vcm->InitializeSender();
    TEST(_vcm->Codec(kVideoCodecVP8, &sendCodec) == 0);
    TEST(_vcm->RegisterSendCodec(&sendCodec, -1, 1440) < 0); // bad number of cores
    sendCodec.maxBitrate = 8000;
    _vcm->RegisterSendCodec(&sendCodec, 1, 1440);
    _vcm->InitializeSender();
    _vcm->Codec(kVideoCodecVP8, &sendCodec);
    sendCodec.height = 0;
    TEST(_vcm->RegisterSendCodec(&sendCodec, 1, 1440) < 0); // bad height
    _vcm->Codec(kVideoCodecVP8, &sendCodec);
    sendCodec.startBitrate = -2;
    TEST(_vcm->RegisterSendCodec(&sendCodec, 1, 1440) < 0); // bad bit rate
    _vcm->Codec(kVideoCodecVP8, &sendCodec);
    _vcm->InitializeSender();
    TEST(_vcm->SetChannelParameters(100, 0, 0) < 0);// setting rate when encoder uninitialized
    // register all availbale decoders -- need to have more for this test
    for (i=0; i< NumberOfCodecs; i++)
    {
        _vcm->Codec(i, &receiveCodec);
        _vcm->RegisterReceiveCodec(&receiveCodec, 1);
    }
    WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
    TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
    // building source frame
    sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
    sourceFrame.SetHeight(_height);
    sourceFrame.SetWidth(_width);
    sourceFrame.SetTimeStamp(_timeStamp++);
    // encode/decode
    TEST(_vcm->AddVideoFrame(sourceFrame) < 0 ); // encoder uninitialized
    _vcm->InitializeReceiver();
    TEST(_vcm->SetChannelParameters(100, 0, 0) < 0);// setting rtt when receiver uninitialized

      /**************************************/
     /* encoder/decoder individuality test */
    /**************************************/
    //Register both encoder and decoder, reset decoder - encode, set up decoder, reset encoder - decode.
    rewind(_sourceFile);
    sourceFrame.Free();
    _vcm->InitializeReceiver();
    _vcm->InitializeSender();
    NumberOfCodecs = _vcm->NumberOfCodecs();
    // Register VP8
    _vcm->Codec(kVideoCodecVP8, &_sendCodec);
    _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
    _vcm->SendCodec(&sendCodec);
    sendCodec.startBitrate = 2000;

    // Set target frame rate to half of the incoming frame rate
    // to test the frame rate control in the VCM
    sendCodec.maxFramerate = (WebRtc_UWord8)(_frameRate / 2);
    sendCodec.width = _width;
    sendCodec.height = _height;
    TEST(strncmp(_sendCodec.plName, "VP8", 3) == 0); // was VP8

    _decodeCallback = new VCMDecodeCompleteCallback(_decodedFile);
    _encodeCompleteCallback = new VCMEncodeCompleteCallback(_encodedFile);
    _vcm->RegisterReceiveCallback(_decodeCallback);
    _vcm->RegisterTransportCallback(_encodeCompleteCallback);
    _encodeCompleteCallback->RegisterReceiverVCM(_vcm);

    _vcm->RegisterSendCodec(&sendCodec, 4, 1440);
    _encodeCompleteCallback->SetCodecType(ConvertCodecType(sendCodec.plName));

    _vcm->InitializeReceiver();
    _vcm->Process();

    //encoding 1 second of video
    for (i = 0; i < _frameRate; i++)
    {
        TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
        sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
        sourceFrame.SetHeight(_height);
        sourceFrame.SetWidth(_width);
        _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
        sourceFrame.SetTimeStamp(_timeStamp);
        TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
        IncrementDebugClock(_frameRate);
        _vcm->Process();
    }
    sendCodec.maxFramerate = (WebRtc_UWord8)_frameRate;
    _vcm->InitializeSender();
    TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK); // same codec for encode and decode
    ret = 0;
    i = 0;
    while ((i < 25) && (ret == 0) )
    {
        ret = _vcm->Decode();
        TEST(ret == VCM_OK);
        if (ret < 0)
        {
            printf("error in frame # %d \n", i);
        }
        IncrementDebugClock(_frameRate);
        i++;
    }
    //TEST((ret == 0) && (i = 50));
    if (ret == 0)
    {
        printf("Encoder/Decoder individuality test complete - View output files \n");
    }
    // last frame - not decoded
    _vcm->InitializeReceiver();
    TEST(_vcm->Decode() < 0); // frame to be encoded exists, decoder uninitialized


    // Test key frame request on packet loss mode.
    // This a frame as a key frame and fooling the receiver
    // that the last packet was lost. The decoding will succeed,
    // but the VCM will see a packet loss and request a new key frame.
    VCMEncComplete_KeyReqTest keyReqTest_EncCompleteCallback(*_vcm);
    KeyFrameReqTest frameTypeCallback;
    _vcm->RegisterTransportCallback(&keyReqTest_EncCompleteCallback);
    _encodeCompleteCallback->RegisterReceiverVCM(_vcm);
    _vcm->RegisterSendCodec(&sendCodec, 4, 1440);
    _encodeCompleteCallback->SetCodecType(ConvertCodecType(sendCodec.plName));
    TEST(_vcm->SetVideoProtection(kProtectionKeyOnKeyLoss, true) == VCM_OK);
    TEST(_vcm->RegisterFrameTypeCallback(&frameTypeCallback) == VCM_OK);
    TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
    TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
    _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
    sourceFrame.SetTimeStamp(_timeStamp);
    // First packet of a subsequent frame required before the jitter buffer
    // will allow decoding an incomplete frame.
    TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
    TEST(_vcm->Decode() == VCM_OK);

    printf("API tests complete \n");

     /*******************/
    /* Bit Rate Tests */
    /*****************/
    /* Requirements:
    * 1. OneSecReq = 15 % above/below target over a time period of 1s (_frameRate number of frames)
    * 3. FullReq  = 10% for total seq. (for 300 frames/seq. coincides with #1)
    * 4. Test will go over all registered codecs
    //NOTE: time requirements are not part of the release tests
    */
    double FullReq   =  0.1;
    //double OneSecReq = 0.15;
    printf("\n RATE CONTROL TEST\n");
    // initializing....
    _vcm->InitializeSender();
    _vcm->InitializeReceiver();
    rewind(_sourceFile);
    sourceFrame.Free();
    sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
    const float bitRate[] = {100, 400, 600, 1000, 2000};
    const float nBitrates = sizeof(bitRate)/sizeof(*bitRate);
    float _bitRate = 0;
    int _frameCnt = 0;
    float totalBytesOneSec;//, totalBytesTenSec;
    float totalBytes, actualBitrate;
    VCMFrameCount frameCount; // testing frame type counters
    // start test
    NumberOfCodecs = _vcm->NumberOfCodecs();
    // going over all available codecs
    _encodeCompleteCallback->SetFrameDimensions(_width, _height);
    SendStatsTest sendStats;
    for (int k = 0; k < NumberOfCodecs; k++)
    //for (int k = NumberOfCodecs - 1; k >=0; k--)
    {// static list starts from 0
        //just checking
        _vcm->InitializeSender();
        _sendCodec.maxBitrate = 8000;
        TEST(_vcm->Codec(k, &_sendCodec)== VCM_OK);
        _vcm->RegisterSendCodec(&_sendCodec, 1, 1440);
        _vcm->RegisterTransportCallback(_encodeCompleteCallback);
        _encodeCompleteCallback->SetCodecType(ConvertCodecType(_sendCodec.plName));
        printf (" \n\n Codec type = %s \n\n",_sendCodec.plName);
        for (i = 0; i < nBitrates; i++)
        {
             _bitRate = static_cast<float>(bitRate[i]);
            // just testing
            _vcm->InitializeSender();
            _sendCodec.startBitrate = (int)_bitRate;
            _sendCodec.maxBitrate = 8000;
            _sendCodec.maxFramerate = _frameRate;
            _vcm->RegisterSendCodec(&_sendCodec, 1, 1440);
            _vcm->RegisterTransportCallback(_encodeCompleteCallback);
            // up to here
            _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 20);
            _frameCnt = 0;
            totalBytes = 0;
            _encodeCompleteCallback->Initialize();
            sendStats.SetTargetFrameRate(static_cast<WebRtc_UWord32>(_frameRate));
            _vcm->RegisterSendStatisticsCallback(&sendStats);
            while (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) ==
                _lengthSourceFrame)
            {
                _frameCnt++;
                sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
                sourceFrame.SetHeight(_height);
                sourceFrame.SetWidth(_width);
                _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
                sourceFrame.SetTimeStamp(_timeStamp);

                ret = _vcm->AddVideoFrame(sourceFrame);
                IncrementDebugClock(_frameRate);
                // The following should be uncommneted for timing tests. Release tests only include
                // compliance with full sequence bit rate.


                //totalBytes = WaitForEncodedFrame();
                //currentTime = VCMTickTime::MillisecondTimestamp();//clock()/(double)CLOCKS_PER_SEC;
                if (_frameCnt == _frameRate)// @ 1sec
                {
                    totalBytesOneSec =  _encodeCompleteCallback->EncodedBytes();//totalBytes;
                }
                TEST(_vcm->TimeUntilNextProcess() >= 0);
            } // video seq. encode done
            TEST(_vcm->TimeUntilNextProcess() == 0);
            _vcm->Process(); // Let the module calculate its send bit rate estimate
            // estimating rates
            // complete sequence
            // bit rate assumes input frame rate is as specified
            totalBytes = _encodeCompleteCallback->EncodedBytes();
            actualBitrate = (float)(8.0/1000)*(totalBytes / (_frameCnt / _frameRate));

            printf("Complete Seq.: target bitrate: %.0f kbps, actual bitrate: %.1f kbps\n", _bitRate, actualBitrate);
            TEST((fabs(actualBitrate - _bitRate) < FullReq * _bitRate) ||
                 (strncmp(_sendCodec.plName, "I420", 4) == 0));

            // 1 Sec.
            actualBitrate = (float)(8.0/1000)*(totalBytesOneSec);
            //actualBitrate = (float)(8.0*totalBytesOneSec)/(oneSecTime - startTime);
            //printf("First 1Sec: target bitrate: %.0f kbps, actual bitrate: %.1f kbps\n", _bitRate, actualBitrate);
            //TEST(fabs(actualBitrate - _bitRate) < OneSecReq * _bitRate);
            rewind(_sourceFile);

            //checking key/delta frame count
            _vcm->SentFrameCount(frameCount);
            printf("frame count: %d delta, %d key\n", frameCount.numDeltaFrames, frameCount.numKeyFrames);
        }// end per codec

    } // end rate control test
    /********************************/
    /* Encoder Pipeline Delay Test */
    /******************************/
    _vcm->InitializeSender();
    sourceFrame.Free();
    sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
    NumberOfCodecs = _vcm->NumberOfCodecs();
    bool encodeComplete = false;
    // going over all available codecs
    for (int k = 0; k < NumberOfCodecs; k++)
    {
        _vcm->Codec(k, &_sendCodec);
        _vcm->InitializeSender();
        _sendCodec.maxBitrate = 8000;
        _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
        _vcm->RegisterTransportCallback(_encodeCompleteCallback);

        _frameCnt = 0;
        encodeComplete = false;
        while (encodeComplete == false)
        {
            TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
            _frameCnt++;
            sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
            sourceFrame.SetHeight(_height);
            sourceFrame.SetWidth(_width);
            _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
            sourceFrame.SetTimeStamp(_timeStamp);
            _vcm->AddVideoFrame(sourceFrame);
            encodeComplete = _encodeCompleteCallback->EncodeComplete();
        } // first frame encoded
        printf ("\n Codec type = %s \n", _sendCodec.plName);
        printf(" Encoder pipeline delay = %d frames\n", _frameCnt - 1);
    } // end for all codecs

    /********************************/
    /* Encoder Packet Size Test     */
    /********************************/
    RtpRtcp& rtpModule = *RtpRtcp::CreateRtpRtcp(1, false);
    TEST(rtpModule.InitSender() == 0);
    RTPSendCallback_SizeTest sendCallback;
    rtpModule.RegisterSendTransport(&sendCallback);

    VCMRTPEncodeCompleteCallback encCompleteCallback(&rtpModule);
    _vcm->InitializeSender();

    // TEST DISABLED FOR NOW SINCE VP8 DOESN'T HAVE THIS FEATURE

//    sourceFrame.Free();
//    sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
//    NumberOfCodecs = _vcm->NumberOfCodecs();
//    WebRtc_UWord32 targetPayloadSize = 500;
//    rtpModule.SetMaxTransferUnit(targetPayloadSize);
//    // going over all available codecs
//    for (int k = 0; k < NumberOfCodecs; k++)
//    {
//        _vcm->Codec(k, &_sendCodec);
//        if (strncmp(_sendCodec.plName, "VP8", 3) == 0)
//        {
//            // Only test with VP8
//            continue;
//        }
//        rtpModule.RegisterSendPayload(_sendCodec.plName, _sendCodec.plType);
//        // Make sure we only get one NAL unit per packet
//        _vcm->InitializeSender();
//        _vcm->RegisterSendCodec(&_sendCodec, 4, targetPayloadSize);
//        sendCallback.SetMaxPayloadSize(targetPayloadSize);
//        _vcm->RegisterTransportCallback(&encCompleteCallback);
//        sendCallback.Reset();
//        _frameCnt = 0;
//        rewind(_sourceFile);
//        while (!feof(_sourceFile))
//        {
//            fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile);
//            _frameCnt++;
//            sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
//            sourceFrame.SetHeight(_height);
//            sourceFrame.SetWidth(_width);
//            _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
//            sourceFrame.SetTimeStamp(_timeStamp);
//            ret = _vcm->AddVideoFrame(sourceFrame);
//        } // first frame encoded
//        printf ("\n Codec type = %s \n",_sendCodec.plName);
//        printf(" Average payload size = %f bytes, target = %u bytes\n", sendCallback.AveragePayloadSize(), targetPayloadSize);
//    } // end for all codecs


    // Test temporal decimation settings
    for (int k = 0; k < NumberOfCodecs; k++)
    {
        _vcm->Codec(k, &_sendCodec);
        if (strncmp(_sendCodec.plName, "I420", 4) == 0)
        {
            // Only test with I420
            break;
        }
    }
    TEST(strncmp(_sendCodec.plName, "I420", 4) == 0);
    _vcm->InitializeSender();
    _sendCodec.maxFramerate = static_cast<WebRtc_UWord8>(_frameRate / 2.0 + 0.5f);
    _vcm->RegisterSendCodec(&_sendCodec, 4, 1440);
    _vcm->SetChannelParameters(2000, 0, 0);
    _vcm->RegisterTransportCallback(_encodeCompleteCallback);
    // up to here
    _vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 20);
    _encodeCompleteCallback->Initialize();
    sendStats.SetTargetFrameRate(static_cast<WebRtc_UWord32>(_frameRate));
    _vcm->RegisterSendStatisticsCallback(&sendStats);
    rewind(_sourceFile);
    while (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) ==
        _lengthSourceFrame)
    {
        sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
        sourceFrame.SetHeight(_height);
        sourceFrame.SetWidth(_width);
        _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
        sourceFrame.SetTimeStamp(_timeStamp);
        ret = _vcm->AddVideoFrame(sourceFrame);
        if (_vcm->TimeUntilNextProcess() <= 0)
        {
            _vcm->Process();
        }
        IncrementDebugClock(_frameRate);
    } // first frame encoded

    RtpRtcp::DestroyRtpRtcp(&rtpModule);
    Print();
    delete tmpBuffer;
    delete _decodeCallback;
    delete _encodeCompleteCallback;
    return 0;
}


void
GenericCodecTest::Print()
{
    printf(" \n\n VCM Generic Encoder Test: \n\n%i tests completed\n", vcmMacrosTests);
    if (vcmMacrosErrors > 0)
    {
        printf("%i FAILED\n\n", vcmMacrosErrors);
    }
    else
    {
        printf("ALL PASSED\n\n");
    }
}

float
GenericCodecTest::WaitForEncodedFrame() const
{
    WebRtc_Word64 startTime = _clock->MillisecondTimestamp();
    while (_clock->MillisecondTimestamp() - startTime < kMaxWaitEncTimeMs*10)
    {
        if (_encodeCompleteCallback->EncodeComplete())
        {
            return _encodeCompleteCallback->EncodedBytes();
        }
    }
    return 0;
}

void
GenericCodecTest::IncrementDebugClock(float frameRate)
{
    _clock->IncrementDebugClock(1000/frameRate);
}

int
RTPSendCallback_SizeTest::SendPacket(int channel, const void *data, int len)
{
    _nPackets++;
    _payloadSizeSum += len;
    // Make sure no payloads (len - header size) are larger than maxPayloadSize
    TEST(len > 0 && static_cast<WebRtc_UWord32>(len - 12) <= _maxPayloadSize);
    return 0;
}

void
RTPSendCallback_SizeTest::SetMaxPayloadSize(WebRtc_UWord32 maxPayloadSize)
{
    _maxPayloadSize = maxPayloadSize;
}

void
RTPSendCallback_SizeTest::Reset()
{
    _nPackets = 0;
    _payloadSizeSum = 0;
}

float
RTPSendCallback_SizeTest::AveragePayloadSize() const
{
    if (_nPackets > 0)
    {
        return _payloadSizeSum / static_cast<float>(_nPackets);
    }
    return 0;
}

WebRtc_Word32
VCMEncComplete_KeyReqTest::SendData(
        const FrameType frameType,
        const WebRtc_UWord8 payloadType,
        const WebRtc_UWord32 timeStamp,
        const WebRtc_UWord8* payloadData,
        const WebRtc_UWord32 payloadSize,
        const RTPFragmentationHeader& /*fragmentationHeader*/,
        const webrtc::RTPVideoHeader* /*videoHdr*/)
{
    WebRtcRTPHeader rtpInfo;
    rtpInfo.header.markerBit = true; // end of frame
    rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
    rtpInfo.type.Video.codec = kRTPVideoVP8;
    rtpInfo.header.payloadType = payloadType;
    rtpInfo.header.sequenceNumber = _seqNo;
    _seqNo += 2;
    rtpInfo.header.ssrc = 0;
    rtpInfo.header.timestamp = _timeStamp;
    _timeStamp += 3000;
    rtpInfo.type.Video.isFirstPacket = false;
    rtpInfo.frameType = kVideoFrameKey;
    return _vcm.IncomingPacket(payloadData, payloadSize, rtpInfo);
}
