1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
113f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h>
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org
143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <sstream>
153f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org
16a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/codecs/test_framework/packet_loss_test.h"
17a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc;
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::PacketLossTest()
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalAsyncTest("PacketLossTest", "Encode, remove lost packets, decode", 300,
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                5),
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lossRate(0.1),
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lossProbability(0.1),
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrame(NULL),
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrameLength(0)
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::PacketLossTest(std::string name, std::string description)
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalAsyncTest(name, description, 300, 5),
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lossRate(0.1),
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lossProbability(0.1),
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrame(NULL),
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrameLength(0)
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::PacketLossTest(std::string name, std::string description, double lossRate, bool useNack, unsigned int rttFrames /* = 0*/)
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgNormalAsyncTest(name, description, 300, 5, rttFrames),
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lossRate(lossRate),
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrame(NULL),
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_lastFrameLength(0)
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(lossRate >= 0 && lossRate <= 1);
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (useNack)
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _lossProbability = 0;
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _lossProbability = lossRate;
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::Encoded(const EncodedImage& encodedImage)
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // push timestamp to queue
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameQueue.push_back(encodedImage._timeStamp);
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NormalAsyncTest::Encoded(encodedImage);
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
693bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgPacketLossTest::Decoded(const I420VideoFrame& decodedImage)
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // check the frame queue if any frames have gone missing
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(!_frameQueue.empty()); // decoded frame is not in the queue
733bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    while(_frameQueue.front() < decodedImage.timestamp())
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // this frame is missing
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // write previous decoded frame again (frame freeze)
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_decodedFile && _lastFrame)
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          if (fwrite(_lastFrame, 1, _lastFrameLength,
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     _decodedFile) != _lastFrameLength) {
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          }
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // remove frame from queue
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _frameQueue.pop_front();
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Decoded frame is not in the queue.
893bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    assert(_frameQueue.front() == decodedImage.timestamp());
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // pop the current frame
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameQueue.pop_front();
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // save image for future freeze-frame
953bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    unsigned int length = CalcBufferSize(kI420, decodedImage.width(),
963bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                         decodedImage.height());
973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (_lastFrameLength < length)
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_lastFrame) delete [] _lastFrame;
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
10148c4b75e8d0d02294460e357ddb3a07ce295b964pbos@webrtc.org        _lastFrame = new uint8_t[length];
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1033bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    // TODO(mikhal): Can't the last frame be a I420VideoFrame?
1043bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    ExtractBuffer(decodedImage, length, _lastFrame);
1053bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _lastFrameLength = length;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NormalAsyncTest::Decoded(decodedImage);
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::Teardown()
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_totalKept + _totalThrown > 0)
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Target packet loss rate: %.4f\n", _lossProbability);
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Actual packet loss rate: %.4f\n", (_totalThrown * 1.0f) / (_totalKept + _totalThrown));
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("Channel rate: %.2f kbps\n",
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            0.001 * 8.0 * _sumChannelBytes / ((_framecnt * 1.0f) / _inst.maxFramerate));
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("No packet losses inflicted\n");
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NormalAsyncTest::Teardown();
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::Setup()
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const VideoSource source(_inname, _inst.width, _inst.height, _inst.maxFramerate);
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::stringstream ss;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::string lossRateStr;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ss << _lossRate;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ss >> lossRateStr;
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedName = source.GetName() + "-" + lossRateStr;
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _outname = "out-" + source.GetName() + "-" + lossRateStr;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_lossProbability != _lossRate)
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedName += "-nack";
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _outname += "-nack";
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedName += ".vp8";
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _outname += ".yuv";
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalKept = 0;
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalThrown = 0;
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sumChannelBytes = 0;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NormalAsyncTest::Setup();
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgPacketLossTest::CodecSpecific_InitBitrate()
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(_bitRate > 0);
15948c4b75e8d0d02294460e357ddb3a07ce295b964pbos@webrtc.org    uint32_t simulatedBitRate;
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_lossProbability != _lossRate)
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Simulating NACK
16348c4b75e8d0d02294460e357ddb3a07ce295b964pbos@webrtc.org        simulatedBitRate = uint32_t(_bitRate / (1 + _lossRate));
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        simulatedBitRate = _bitRate;
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int rtt = 0;
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_inst.maxFramerate > 0)
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      rtt = _rttFrames * (1000 / _inst.maxFramerate);
17248c4b75e8d0d02294460e357ddb3a07ce295b964pbos@webrtc.org    _encoder->SetChannelParameters((uint32_t)(_lossProbability * 255.0),
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                    rtt);
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encoder->SetRates(simulatedBitRate, _inst.maxFramerate);
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint PacketLossTest::DoPacketLoss()
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Only packet loss for delta frames
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // TODO(mikhal): Identify delta frames
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // First frame so never a delta frame.
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_frameToDecode->_frame->Length() == 0 || _sumChannelBytes == 0)
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _sumChannelBytes += _frameToDecode->_frame->Length();
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned char *packet = NULL;
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoFrame newEncBuf;
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    newEncBuf.VerifyAndAllocate(_lengthSourceFrame);
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inBufIdx = 0;
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _outBufIdx = 0;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int size = 1;
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int kept = 0;
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int thrown = 0;
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while ((size = NextPacket(1500, &packet)) > 0)
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (!PacketLoss(_lossProbability, thrown))
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            InsertPacket(&newEncBuf, packet, size);
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            kept++;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        else
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // Use the ByteLoss function if you want to lose only
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // parts of a packet, and not the whole packet.
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //int size2 = ByteLoss(size, packet, 15);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            thrown++;
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //if (size2 != size)
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //{
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //    InsertPacket(&newEncBuf, packet, size2);
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            //}
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int	lossResult  = (thrown!=0);	// 0 = no loss	1 = loss(es)
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lossResult)
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        lossResult += (kept==0);	// 2 = all lost = full frame
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameToDecode->_frame->CopyFrame(newEncBuf.Length(), newEncBuf.Buffer());
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _sumChannelBytes += newEncBuf.Length();
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalKept += kept;
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _totalThrown += thrown;
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return lossResult;
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //printf("Threw away: %d out of %d packets\n", thrown, thrown + kept);
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //printf("Encoded left: %d bytes\n", _encodedVideoBuffer.Length());
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint PacketLossTest::NextPacket(int mtu, unsigned char **pkg)
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned char *buf = _frameToDecode->_frame->Buffer();
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *pkg = buf + _inBufIdx;
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (static_cast<long>(_frameToDecode->_frame->Length()) - _inBufIdx <= mtu)
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int size = _frameToDecode->_frame->Length() - _inBufIdx;
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _inBufIdx = _frameToDecode->_frame->Length();
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return size;
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inBufIdx += mtu;
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return mtu;
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint PacketLossTest::ByteLoss(int size, unsigned char *pkg, int bytesToLose)
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return size;
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid PacketLossTest::InsertPacket(VideoFrame *buf, unsigned char *pkg, int size)
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (static_cast<long>(buf->Size()) - _outBufIdx < size)
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        printf("InsertPacket error!\n");
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memcpy(buf->Buffer() + _outBufIdx, pkg, size);
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    buf->SetLength(buf->Length() + size);
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _outBufIdx += size;
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
260