1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 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
11cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
12cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include <algorithm>
16cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org
17cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"
18cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
20cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
21cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool SenderThreadFunction(void *obj)
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (obj == NULL)
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    TestLoadGenerator *_genObj = static_cast<TestLoadGenerator *>(obj);
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _genObj->GeneratorLoop();
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgTestLoadGenerator::TestLoadGenerator(TestSenderReceiver *sender, int32_t rtpSampleRate)
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_critSect(CriticalSectionWrapper::CreateCriticalSection()),
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_eventPtr(NULL),
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_genThread(NULL),
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_bitrateKbps(0),
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_sender(sender),
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_running(false),
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_rtpSampleRate(rtpSampleRate)
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTestLoadGenerator::~TestLoadGenerator ()
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_running)
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        Stop();
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _critSect;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
58b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t TestLoadGenerator::SetBitrate (int32_t newBitrateKbps)
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (newBitrateKbps < 0)
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _bitrateKbps = newBitrateKbps;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("New bitrate = %i kbps\n", _bitrateKbps);
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _bitrateKbps;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
75b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t TestLoadGenerator::Start (const char *threadName)
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _eventPtr = EventWrapper::Create();
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _genThread = ThreadWrapper::CreateThread(SenderThreadFunction, this, kRealtimePriority, threadName);
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_genThread == NULL)
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        throw "Unable to start generator thread";
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _running = true;
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int tid;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _genThread->Start(tid);
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
97b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t TestLoadGenerator::Stop ()
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect.Enter();
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_genThread)
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _genThread->SetNotAlive();
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _running = false;
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _eventPtr->Set();
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while (!_genThread->Stop())
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _critSect.Leave();
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _critSect.Enter();
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete _genThread;
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _genThread = NULL;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete _eventPtr;
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _eventPtr = NULL;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _genThread = NULL;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect.Leave();
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (0);
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint TestLoadGenerator::generatePayload ()
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
128b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    return(generatePayload( static_cast<uint32_t>( TickTime::MillisecondTimestamp() * _rtpSampleRate / 1000 )));
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
132b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint TestLoadGenerator::sendPayload (const uint32_t timeStamp,
133b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                    const uint8_t* payloadData,
134b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                    const uint32_t payloadSize,
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    const webrtc::FrameType frameType /*= webrtc::kVideoFrameDelta*/)
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (_sender->SendOutgoingData(timeStamp, payloadData, payloadSize, frameType));
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
142b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgCBRGenerator::CBRGenerator (TestSenderReceiver *sender, int32_t payloadSizeBytes, int32_t bitrateKbps, int32_t rtpSampleRate)
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//_eventPtr(NULL),
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_payloadSizeBytes(payloadSizeBytes),
146b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org_payload(new uint8_t[payloadSizeBytes]),
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTestLoadGenerator(sender, rtpSampleRate)
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SetBitrate (bitrateKbps);
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRGenerator::~CBRGenerator ()
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_running)
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        Stop();
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_payload)
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete [] _payload;
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool CBRGenerator::GeneratorLoop ()
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double periodMs;
169b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    int64_t nextSendTime = TickTime::MillisecondTimestamp();
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // no critSect
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (_running)
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // send data (critSect inside)
176b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        generatePayload( static_cast<uint32_t>(nextSendTime * _rtpSampleRate / 1000) );
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // calculate wait time
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        periodMs = 8.0 * _payloadSizeBytes / ( _bitrateKbps );
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        nextSendTime = static_cast<int64_t>(nextSendTime + periodMs);
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
183b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        int32_t waitTime = static_cast<int32_t>(nextSendTime - TickTime::MillisecondTimestamp());
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (waitTime < 0)
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            waitTime = 0;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // wait
189b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        _eventPtr->Wait(static_cast<int32_t>(waitTime));
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
195b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint CBRGenerator::generatePayload ( uint32_t timestamp )
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
199b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    //uint8_t *payload = new uint8_t[_payloadSizeBytes];
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int ret = sendPayload(timestamp, _payload, _payloadSizeBytes);
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //delete [] payload;
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ret;
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/////////////////////
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
212b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgCBRFixFRGenerator::CBRFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps,
213b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                      int32_t rtpSampleRate, int32_t frameRateFps /*= 30*/,
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      double spread /*= 0.0*/)
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//_eventPtr(NULL),
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_payloadSizeBytes(0),
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_payload(NULL),
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_payloadAllocLen(0),
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frameRateFps(frameRateFps),
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_spreadFactor(spread),
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTestLoadGenerator(sender, rtpSampleRate)
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SetBitrate (bitrateKbps);
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRFixFRGenerator::~CBRFixFRGenerator ()
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_running)
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        Stop();
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_payload)
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete [] _payload;
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _payloadAllocLen = 0;
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool CBRFixFRGenerator::GeneratorLoop ()
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double periodMs;
245b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    int64_t nextSendTime = TickTime::MillisecondTimestamp();
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect.Enter();
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_frameRateFps <= 0)
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect.Leave();
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // no critSect
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (_running)
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect.Enter();
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // calculate payload size
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _payloadSizeBytes = nextPayloadSize();
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_payloadSizeBytes > 0)
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (_payloadAllocLen < _payloadSizeBytes * (1 + _spreadFactor))
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // re-allocate _payload
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (_payload)
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    delete [] _payload;
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _payload = NULL;
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
276b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                _payloadAllocLen = static_cast<int32_t>((_payloadSizeBytes * (1 + _spreadFactor) * 3) / 2 + .5); // 50% extra to avoid frequent re-alloc
277b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                _payload = new uint8_t[_payloadAllocLen];
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // send data (critSect inside)
282b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org            generatePayload( static_cast<uint32_t>(nextSendTime * _rtpSampleRate / 1000) );
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect.Leave();
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // calculate wait time
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        periodMs = 1000.0 / _frameRateFps;
289b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        nextSendTime = static_cast<int64_t>(nextSendTime + periodMs + 0.5);
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
291b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        int32_t waitTime = static_cast<int32_t>(nextSendTime - TickTime::MillisecondTimestamp());
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (waitTime < 0)
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            waitTime = 0;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // wait
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _eventPtr->Wait(waitTime);
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
303b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t CBRFixFRGenerator::nextPayloadSize()
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const double periodMs = 1000.0 / _frameRateFps;
306b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    return static_cast<int32_t>(_bitrateKbps * periodMs / 8 + 0.5);
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
309b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint CBRFixFRGenerator::generatePayload ( uint32_t timestamp )
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double factor = ((double) rand() - RAND_MAX/2) / RAND_MAX; // [-0.5; 0.5]
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    factor = 1 + 2 * _spreadFactor * factor; // [1 - _spreadFactor ; 1 + _spreadFactor]
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
316b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    int32_t thisPayloadBytes = static_cast<int32_t>(_payloadSizeBytes * factor);
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // sanity
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (thisPayloadBytes > _payloadAllocLen)
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        thisPayloadBytes = _payloadAllocLen;
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int ret = sendPayload(timestamp, _payload, thisPayloadBytes);
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ret;
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/////////////////////
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
330b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgPeriodicKeyFixFRGenerator::PeriodicKeyFixFRGenerator (TestSenderReceiver *sender, int32_t bitrateKbps,
331b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                                      int32_t rtpSampleRate, int32_t frameRateFps /*= 30*/,
332b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                                      double spread /*= 0.0*/, double keyFactor /*= 4.0*/, uint32_t keyPeriod /*= 300*/)
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_keyFactor(keyFactor),
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_keyPeriod(keyPeriod),
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frameCount(0),
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, frameRateFps, spread)
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
341b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t PeriodicKeyFixFRGenerator::nextPayloadSize()
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // calculate payload size for a delta frame
344b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    int32_t payloadSizeBytes = static_cast<int32_t>(1000 * _bitrateKbps / (8.0 * _frameRateFps * (1.0 + (_keyFactor - 1.0) / _keyPeriod)) + 0.5);
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_frameCount % _keyPeriod == 0)
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // this is a key frame, scale the payload size
349b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        payloadSizeBytes = static_cast<int32_t>(_keyFactor * _payloadSizeBytes + 0.5);
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameCount++;
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return payloadSizeBytes;
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org////////////////////
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
358b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgCBRVarFRGenerator::CBRVarFRGenerator(TestSenderReceiver *sender, int32_t bitrateKbps, const uint8_t* frameRates,
359b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                     uint16_t numFrameRates, int32_t rtpSampleRate, double avgFrPeriodMs,
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     double frSpreadFactor, double spreadFactor)
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_avgFrPeriodMs(avgFrPeriodMs),
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frSpreadFactor(frSpreadFactor),
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frameRates(NULL),
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_numFrameRates(numFrameRates),
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_frChangeTimeMs(TickTime::MillisecondTimestamp() + _avgFrPeriodMs),
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, frameRates[0], spreadFactor)
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
369b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    _frameRates = new uint8_t[_numFrameRates];
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memcpy(_frameRates, frameRates, _numFrameRates);
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRVarFRGenerator::~CBRVarFRGenerator()
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete [] _frameRates;
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid CBRVarFRGenerator::ChangeFrameRate()
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
380b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    const int64_t nowMs = TickTime::MillisecondTimestamp();
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (nowMs < _frChangeTimeMs)
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Time to change frame rate
386b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    uint16_t frIndex = static_cast<uint16_t>(static_cast<double>(rand()) / RAND_MAX
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                            * (_numFrameRates - 1) + 0.5) ;
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(frIndex < _numFrameRates);
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _frameRateFps = _frameRates[frIndex];
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Update the next frame rate change time
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double factor = ((double) rand() - RAND_MAX/2) / RAND_MAX; // [-0.5; 0.5]
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    factor = 1 + 2 * _frSpreadFactor * factor; // [1 - _frSpreadFactor ; 1 + _frSpreadFactor]
393b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    _frChangeTimeMs = nowMs + static_cast<int64_t>(1000.0 * factor *
394b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                                   _avgFrPeriodMs + 0.5);
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printf("New frame rate: %d\n", _frameRateFps);
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
399b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t CBRVarFRGenerator::nextPayloadSize()
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ChangeFrameRate();
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return CBRFixFRGenerator::nextPayloadSize();
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org////////////////////
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
407b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgCBRFrameDropGenerator::CBRFrameDropGenerator(TestSenderReceiver *sender, int32_t bitrateKbps,
408b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                                         int32_t rtpSampleRate, double spreadFactor)
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_accBits(0),
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRFixFRGenerator(sender, bitrateKbps, rtpSampleRate, 30, spreadFactor)
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgCBRFrameDropGenerator::~CBRFrameDropGenerator()
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
419b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t CBRFrameDropGenerator::nextPayloadSize()
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _accBits -= 1000 * _bitrateKbps / _frameRateFps;
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_accBits < 0)
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _accBits = 0;
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_accBits > 0.3 * _bitrateKbps * 1000)
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //printf("drop\n");
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //printf("keep\n");
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        const double periodMs = 1000.0 / _frameRateFps;
435b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        int32_t frameSize = static_cast<int32_t>(_bitrateKbps * periodMs / 8 + 0.5);
436b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        frameSize = std::max(frameSize, static_cast<int32_t>(300 * periodMs / 8 + 0.5));
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _accBits += frameSize * 8;
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return frameSize;
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
441