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
116696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_callbacks.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
156696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
166696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
177fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
187fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
196696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/utility/interface/rtp_dump.h"
206696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/test_macros.h"
211bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/******************************
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  VCMEncodeCompleteCallback
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *****************************/
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Basic callback implementation
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// passes the encoded frame directly to the encoder
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Packetization callback implementation
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::VCMEncodeCompleteCallback(FILE* encodedFile):
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedFile(encodedFile),
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes(0),
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _VCMReceiver(NULL),
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _seqNo(0),
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeComplete(false),
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width(0),
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height(0),
397fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    _codecType(kRtpVideoNone)
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::~VCMEncodeCompleteCallback()
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::RegisterTransportCallback(
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                            VCMPacketizationCallback* transport)
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
53dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::SendData(
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const FrameType frameType,
56dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t  payloadType,
57dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t timeStamp,
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int64_t capture_time_ms,
59dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t* payloadData,
60dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t payloadSize,
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPFragmentationHeader& fragmentationHeader,
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPVideoHeader* videoHdr)
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // will call the VCMReceiver input packet
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameType = frameType;
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // writing encodedData into file
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (fwrite(payloadData, 1, payloadSize, _encodedFile) !=  payloadSize) {
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtcRTPHeader rtpInfo;
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.markerBit = true; // end of frame
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.type.Video.isFirstPacket = true;
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.type.Video.codec = _codecType;
74dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    rtpInfo.type.Video.height = (uint16_t)_height;
75dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    rtpInfo.type.Video.width = (uint16_t)_width;
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    switch (_codecType)
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
787fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    case webrtc::kRtpVideoVp8:
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        rtpInfo.type.Video.codecHeader.VP8.nonReference =
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            videoHdr->codecHeader.VP8.nonReference;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        rtpInfo.type.Video.codecHeader.VP8.pictureId =
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            videoHdr->codecHeader.VP8.pictureId;
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    default:
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        assert(false);
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.payloadType = payloadType;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.sequenceNumber = _seqNo++;
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.ssrc = 0;
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.header.timestamp = timeStamp;
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rtpInfo.frameType = frameType;
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Size should also be received from that table, since the payload type
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // defines the size.
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes += payloadSize;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // directly to receiver
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int ret = _VCMReceiver->IncomingPacket(payloadData, payloadSize, rtpInfo);
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeComplete = true;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ret;
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfloat
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::EncodedBytes()
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _encodedBytes;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::EncodeComplete()
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodeComplete)
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodeComplete = false;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::Initialize()
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeComplete = false;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes = 0;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _seqNo = 0;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMEncodeCompleteCallback::ResetByteCount()
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes = 0;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/***********************************/
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*   VCMRTPEncodeCompleteCallback  */
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/***********************************/
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Encode Complete callback implementation
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// passes the encoded frame via the RTP module to the decoder
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Packetization callback implementation
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
145dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMRTPEncodeCompleteCallback::SendData(
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const FrameType frameType,
148dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t  payloadType,
149dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t timeStamp,
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int64_t capture_time_ms,
151dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint8_t* payloadData,
152dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        const uint32_t payloadSize,
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPFragmentationHeader& fragmentationHeader,
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const RTPVideoHeader* videoHdr)
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameType = frameType;
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes+= payloadSize;
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodeComplete = true;
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _RTPModule->SendOutgoingData(frameType,
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        payloadType,
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        timeStamp,
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        capture_time_ms,
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        payloadData,
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        payloadSize,
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        &fragmentationHeader,
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        videoHdr);
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgfloat
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMRTPEncodeCompleteCallback::EncodedBytes()
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // only good for one call  - after which will reset value;
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    float tmp = _encodedBytes;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedBytes = 0;
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return tmp;
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMRTPEncodeCompleteCallback::EncodeComplete()
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodeComplete)
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodeComplete = false;
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Decoded Frame Callback Implementation
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
191dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
1923bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgVCMDecodeCompleteCallback::FrameToRender(I420VideoFrame& videoFrame)
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1943bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
1973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  _decodedBytes+= CalcBufferSize(kI420, videoFrame.width(),
1983bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                 videoFrame.height());
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return VCM_OK;
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
202dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMDecodeCompleteCallback::DecodedBytes()
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _decodedBytes;
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2081bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.orgRTPSendCompleteCallback::RTPSendCompleteCallback(Clock* clock,
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                 const char* filename):
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _clock(clock),
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sendCount(0),
2127fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    rtp_payload_registry_(NULL),
2137fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    rtp_receiver_(NULL),
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _rtp(NULL),
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lossPct(0),
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _burstLength(0),
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _networkDelayMs(0),
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _jitterVar(0),
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _prevLossState(0),
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalSentLength(0),
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _rtpPackets(),
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _rtpDump(NULL)
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (filename != NULL)
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpDump = RtpDump::CreateRtpDump();
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpDump->Start(filename);
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::~RTPSendCompleteCallback()
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_rtpDump != NULL)
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpDump->Stop();
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        RtpDump::DestroyRtpDump(_rtpDump);
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Delete remaining packets
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (!_rtpPackets.empty())
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Take first packet in list
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete _rtpPackets.front();
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpPackets.pop_front();
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sendCount++;
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalSentLength += len;
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_rtpDump != NULL)
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
255dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        if (_rtpDump->DumpPacket((const uint8_t*)data, len) != 0)
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool transmitPacket = true;
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    transmitPacket = PacketLoss();
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2641bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org    int64_t now = _clock->TimeInMilliseconds();
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Insert outgoing packet into list
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (transmitPacket)
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        RtpPacket* newPacket = new RtpPacket();
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        memcpy(newPacket->data, data, len);
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        newPacket->length = len;
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Simulate receive time = network delay + packet jitter
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // simulated as a Normal distribution random variable with
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // mean = networkDelay and variance = jitterVar
274dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        int32_t
275dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        simulatedDelay = (int32_t)NormalDist(_networkDelayMs,
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   sqrt(_jitterVar));
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        newPacket->receiveTime = now + simulatedDelay;
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpPackets.push_back(newPacket);
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Are we ready to send packets to the receiver?
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    RtpPacket* packet = NULL;
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (!_rtpPackets.empty())
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Take first packet in list
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        packet = _rtpPackets.front();
288dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org        int64_t timeToReceive = packet->receiveTime - now;
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (timeToReceive > 0)
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // No available packets to send
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _rtpPackets.pop_front();
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        assert(_rtp);  // We must have a configured RTP module for this test.
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Send to receive side
2986696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org        RTPHeader header;
2996696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org        scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
3006696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org        if (!parser->Parse(packet->data, packet->length, &header)) {
3016696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org          delete packet;
3026696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org          return -1;
3036696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org        }
3047fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org        PayloadUnion payload_specific;
3057fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org        if (!rtp_payload_registry_->GetPayloadSpecifics(
3067fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org            header.payloadType, &payload_specific)) {
3077fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org          return -1;
3087fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org        }
309db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org        if (!rtp_receiver_->IncomingRtpPacket(header, packet->data,
3107fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org                                              packet->length, payload_specific,
3117fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org                                              true))
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete packet;
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete packet;
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        packet = NULL;
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return len; // OK
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::SendRTCPPacket(int channel, const void *data, int len)
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Incorporate network conditions
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return SendPacket(channel, data, len);
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::SetLossPct(double lossPct)
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _lossPct = lossPct;
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::SetBurstLength(double burstLength)
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _burstLength = burstLength;
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::PacketLoss()
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool transmitPacket = true;
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_burstLength <= 1.0)
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Random loss: if _burstLength parameter is not set, or <=1
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (UnifomLoss(_lossPct))
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // drop
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            transmitPacket = false;
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Simulate bursty channel (Gilbert model)
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // (1st order) Markov chain model with memory of the previous/last
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // packet state (loss or received)
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // 0 = received state
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // 1 = loss state
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // probTrans10: if previous packet is lost, prob. to -> received state
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // probTrans11: if previous packet is lost, prob. to -> loss state
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // probTrans01: if previous packet is received, prob. to -> loss state
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // probTrans00: if previous packet is received, prob. to -> received
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Map the two channel parameters (average loss rate and burst length)
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // to the transition probabilities:
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double probTrans10 = 100 * (1.0 / _burstLength);
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double probTrans11 = (100.0 - probTrans10);
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double probTrans01 = (probTrans10 * ( _lossPct / (100.0 - _lossPct)));
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Note: Random loss (Bernoulli) model is a special case where:
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // burstLength = 100.0 / (100.0 - _lossPct) (i.e., p10 + p01 = 100)
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_prevLossState == 0 )
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // previous packet was received
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (UnifomLoss(probTrans01))
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // drop, update previous state to loss
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                _prevLossState = 1;
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                transmitPacket = false;
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        else if (_prevLossState == 1)
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _prevLossState = 0;
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // previous packet was lost
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (UnifomLoss(probTrans11))
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // drop, update previous state to loss
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                _prevLossState = 1;
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                transmitPacket = false;
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org             }
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return transmitPacket;
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRTPSendCompleteCallback::UnifomLoss(double lossPct)
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
409bcf0a1019f34cac346bd8349c2206f9d06adbe4epbos@webrtc.org    double randVal = (rand() + 1.0) / (RAND_MAX + 1.0);
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return randVal < lossPct/100;
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
413dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
414dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgPacketRequester::ResendPackets(const uint16_t* sequenceNumbers,
415dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org                               uint16_t length)
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _rtp.SendNACK(sequenceNumbers, length);
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
420dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
421dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgSendStatsTest::SendStatistics(const uint32_t bitRate,
422dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org                              const uint32_t frameRate)
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
42463136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org    TEST(frameRate <= _framerate);
42563136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org    TEST(bitRate > _bitrate / 2 && bitRate < 3 * _bitrate / 2);
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("VCM 1 sec: Bit rate: %u\tFrame rate: %u\n", bitRate, frameRate);
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
430dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t KeyFrameReqTest::RequestKeyFrame() {
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  printf("Key frame requested\n");
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoProtectionCallback::VideoProtectionCallback():
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgdelta_fec_params_(),
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgkey_fec_params_()
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&key_fec_params_, 0, sizeof(key_fec_params_));
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoProtectionCallback::~VideoProtectionCallback()
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
449dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.orgint32_t
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoProtectionCallback::ProtectionRequest(
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const FecProtectionParams* delta_fec_params,
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const FecProtectionParams* key_fec_params,
453dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    uint32_t* sent_video_rate_bps,
454dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    uint32_t* sent_nack_rate_bps,
455dba5f4541529da6ce75cc634834a9197e610731bpbos@webrtc.org    uint32_t* sent_fec_rate_bps)
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    key_fec_params_ = *key_fec_params;
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delta_fec_params_ = *delta_fec_params;
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Update RTP
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_rtp->SetFecParameters(&delta_fec_params_,
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               &key_fec_params_) != 0)
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Error in Setting FEC rate\n");
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgFecProtectionParams VideoProtectionCallback::DeltaFecParameters() const
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return delta_fec_params_;
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgFecProtectionParams VideoProtectionCallback::KeyFecParameters() const
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return key_fec_params_;
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
482