Re-implement dependency injection of TickTime into VCM and tests

This change basicly re-enables the change of r1220, which was
reverted in r1235 due to Clang issues.

The difference from r1220 is that the TickTimeInterface was
renamed to TickTimeClass, and no longer inherits from TickTime.

Review URL: http://webrtc-codereview.appspot.com/335006

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1267 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org
2011-12-21 15:24:01 +00:00
parent 5490c71a1b
commit 7d8c72e2db
47 changed files with 357 additions and 317 deletions

View File

@@ -9,7 +9,6 @@
*/
#include "content_metrics_processing.h"
#include "tick_time.h"
#include "module_common_types.h"
#include "video_coding_defines.h"

View File

@@ -12,13 +12,15 @@
#include "trace.h"
#include "generic_decoder.h"
#include "internal_defines.h"
#include "tick_time.h"
#include "tick_time_base.h"
namespace webrtc {
VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming& timing)
VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming& timing,
TickTimeBase* clock)
:
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_clock(clock),
_receiveCallback(NULL),
_timing(timing),
_timestampMap(kDecoderFrameMemoryLength)
@@ -53,7 +55,7 @@ WebRtc_Word32 VCMDecodedFrameCallback::Decoded(RawImage& decodedImage)
_timing.StopDecodeTimer(
decodedImage._timeStamp,
frameInfo->decodeStartTimeMs,
VCMTickTime::MillisecondTimestamp());
_clock->MillisecondTimestamp());
if (_receiveCallback != NULL)
{
@@ -146,7 +148,8 @@ WebRtc_Word32 VCMGenericDecoder::InitDecode(const VideoCodec* settings,
return _decoder.InitDecode(settings, numberOfCores);
}
WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame)
WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame,
int64_t nowMs)
{
if (_requireKeyFrame &&
!_keyFrameDecoded &&
@@ -157,7 +160,7 @@ WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame)
// before we can decode delta frames.
return VCM_CODEC_ERROR;
}
_frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = VCMTickTime::MillisecondTimestamp();
_frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs;
_frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
_callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);

View File

@@ -34,7 +34,7 @@ struct VCMFrameInformation
class VCMDecodedFrameCallback : public DecodedImageCallback
{
public:
VCMDecodedFrameCallback(VCMTiming& timing);
VCMDecodedFrameCallback(VCMTiming& timing, TickTimeBase* clock);
virtual ~VCMDecodedFrameCallback();
void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
@@ -49,6 +49,7 @@ public:
private:
CriticalSectionWrapper* _critSect;
TickTimeBase* _clock;
VideoFrame _frame;
VCMReceiveCallback* _receiveCallback;
VCMTiming& _timing;
@@ -76,7 +77,7 @@ public:
*
* inputVideoBuffer reference to encoded video frame
*/
WebRtc_Word32 Decode(const VCMEncodedFrame& inputFrame);
WebRtc_Word32 Decode(const VCMEncodedFrame& inputFrame, int64_t nowMs);
/**
* Free the decoder memory

View File

@@ -9,20 +9,19 @@
*/
#include "inter_frame_delay.h"
#include "tick_time.h"
namespace webrtc {
VCMInterFrameDelay::VCMInterFrameDelay()
VCMInterFrameDelay::VCMInterFrameDelay(int64_t currentWallClock)
{
Reset();
Reset(currentWallClock);
}
// Resets the delay estimate
void
VCMInterFrameDelay::Reset()
VCMInterFrameDelay::Reset(int64_t currentWallClock)
{
_zeroWallClock = VCMTickTime::MillisecondTimestamp();
_zeroWallClock = currentWallClock;
_wrapArounds = 0;
_prevWallClock = 0;
_prevTimestamp = 0;
@@ -34,13 +33,8 @@ VCMInterFrameDelay::Reset()
bool
VCMInterFrameDelay::CalculateDelay(WebRtc_UWord32 timestamp,
WebRtc_Word64 *delay,
WebRtc_Word64 currentWallClock /* = -1 */)
int64_t currentWallClock)
{
if (currentWallClock <= -1)
{
currentWallClock = VCMTickTime::MillisecondTimestamp();
}
if (_prevWallClock == 0)
{
// First set of data, initialization, wait for next frame

View File

@@ -19,10 +19,10 @@ namespace webrtc
class VCMInterFrameDelay
{
public:
VCMInterFrameDelay();
VCMInterFrameDelay(int64_t currentWallClock);
// Resets the estimate. Zeros are given as parameters.
void Reset();
void Reset(int64_t currentWallClock);
// Calculates the delay of a frame with the given timestamp.
// This method is called when the frame is complete.
@@ -35,7 +35,7 @@ public:
// Return value : true if OK, false when reordered timestamps
bool CalculateDelay(WebRtc_UWord32 timestamp,
WebRtc_Word64 *delay,
WebRtc_Word64 currentWallClock = -1);
int64_t currentWallClock);
// Returns the current difference between incoming timestamps
//

View File

@@ -20,7 +20,7 @@
#include "event.h"
#include "trace.h"
#include "tick_time.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "list_wrapper.h"
#include <cassert>
@@ -57,10 +57,13 @@ VCMJitterBuffer::CompleteDecodableKeyFrameCriteria(VCMFrameBuffer* frame,
}
// Constructor
VCMJitterBuffer::VCMJitterBuffer(WebRtc_Word32 vcmId, WebRtc_Word32 receiverId,
VCMJitterBuffer::VCMJitterBuffer(TickTimeBase* clock,
WebRtc_Word32 vcmId,
WebRtc_Word32 receiverId,
bool master) :
_vcmId(vcmId),
_receiverId(receiverId),
_clock(clock),
_running(false),
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_master(master),
@@ -81,6 +84,7 @@ VCMJitterBuffer::VCMJitterBuffer(WebRtc_Word32 vcmId, WebRtc_Word32 receiverId,
_numConsecutiveOldPackets(0),
_discardedPackets(0),
_jitterEstimate(vcmId, receiverId),
_delayEstimate(_clock->MillisecondTimestamp()),
_rttMs(0),
_nackMode(kNoNack),
_lowRttNackThresholdMs(-1),
@@ -180,7 +184,7 @@ VCMJitterBuffer::Start()
_incomingFrameCount = 0;
_incomingFrameRate = 0;
_incomingBitCount = 0;
_timeLastIncomingFrameCount = VCMTickTime::MillisecondTimestamp();
_timeLastIncomingFrameCount = _clock->MillisecondTimestamp();
memset(_receiveStatistics, 0, sizeof(_receiveStatistics));
_numConsecutiveOldFrames = 0;
@@ -262,7 +266,7 @@ VCMJitterBuffer::FlushInternal()
// Also reset the jitter and delay estimates
_jitterEstimate.Reset();
_delayEstimate.Reset();
_delayEstimate.Reset(_clock->MillisecondTimestamp());
_waitingForCompletion.frameSize = 0;
_waitingForCompletion.timestamp = 0;
@@ -607,7 +611,7 @@ WebRtc_Word32
VCMJitterBuffer::GetUpdate(WebRtc_UWord32& frameRate, WebRtc_UWord32& bitRate)
{
CriticalSectionScoped cs(_critSect);
const WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
const WebRtc_Word64 now = _clock->MillisecondTimestamp();
WebRtc_Word64 diff = now - _timeLastIncomingFrameCount;
if (diff < 1000 && _incomingFrameRate > 0 && _incomingBitRate > 0)
{
@@ -662,7 +666,7 @@ VCMJitterBuffer::GetUpdate(WebRtc_UWord32& frameRate, WebRtc_UWord32& bitRate)
else
{
// No frames since last call
_timeLastIncomingFrameCount = VCMTickTime::MillisecondTimestamp();
_timeLastIncomingFrameCount = _clock->MillisecondTimestamp();
frameRate = 0;
bitRate = 0;
_incomingBitRate = 0;
@@ -703,7 +707,7 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
_critSect->Leave();
return NULL;
}
const WebRtc_Word64 endWaitTimeMs = VCMTickTime::MillisecondTimestamp()
const WebRtc_Word64 endWaitTimeMs = _clock->MillisecondTimestamp()
+ maxWaitTimeMS;
WebRtc_Word64 waitTimeMs = maxWaitTimeMS;
while (waitTimeMs > 0)
@@ -732,7 +736,7 @@ VCMJitterBuffer::GetCompleteFrameForDecoding(WebRtc_UWord32 maxWaitTimeMS)
if (oldestFrame == NULL)
{
waitTimeMs = endWaitTimeMs -
VCMTickTime::MillisecondTimestamp();
_clock->MillisecondTimestamp();
}
else
{
@@ -1519,7 +1523,7 @@ VCMFrameBufferEnum
VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
{
CriticalSectionScoped cs(_critSect);
WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
WebRtc_Word64 nowMs = _clock->MillisecondTimestamp();
VCMFrameBufferEnum bufferReturn = kSizeError;
VCMFrameBufferEnum ret = kSizeError;
VCMFrameBuffer* frame = static_cast<VCMFrameBuffer*>(buffer);
@@ -1530,7 +1534,7 @@ VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
{
// Now it's time to start estimating jitter
// reset the delay estimate.
_delayEstimate.Reset();
_delayEstimate.Reset(_clock->MillisecondTimestamp());
_firstPacket = false;
}

View File

@@ -33,6 +33,7 @@ enum VCMNackMode
};
// forward declarations
class TickTimeBase;
class VCMFrameBuffer;
class VCMPacket;
class VCMEncodedFrame;
@@ -49,7 +50,8 @@ public:
class VCMJitterBuffer
{
public:
VCMJitterBuffer(WebRtc_Word32 vcmId = -1,
VCMJitterBuffer(TickTimeBase* clock,
WebRtc_Word32 vcmId = -1,
WebRtc_Word32 receiverId = -1,
bool master = true);
virtual ~VCMJitterBuffer();
@@ -191,6 +193,7 @@ private:
WebRtc_Word32 _vcmId;
WebRtc_Word32 _receiverId;
TickTimeBase* _clock;
// If we are running (have started) or not
bool _running;
CriticalSectionWrapper* _critSect;

View File

@@ -12,8 +12,8 @@
#include "internal_defines.h"
#include "jitter_estimator.h"
#include "rtt_filter.h"
#include "tick_time.h"
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -577,7 +577,7 @@ VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
return true;
}
VCMLossProtectionLogic::VCMLossProtectionLogic():
VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs):
_selectedMethod(NULL),
_currentParameters(),
_rtt(0),
@@ -599,7 +599,7 @@ _codecWidth(0),
_codecHeight(0),
_numLayers(1)
{
Reset();
Reset(nowMs);
}
VCMLossProtectionLogic::~VCMLossProtectionLogic()
@@ -688,13 +688,13 @@ VCMLossProtectionLogic::UpdateResidualPacketLoss(float residualPacketLoss)
}
void
VCMLossProtectionLogic::UpdateLossPr(WebRtc_UWord8 lossPr255)
VCMLossProtectionLogic::UpdateLossPr(WebRtc_UWord8 lossPr255,
int64_t nowMs)
{
const WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
UpdateMaxLossHistory(lossPr255, now);
_lossPr255.Apply(static_cast<float> (now - _lastPrUpdateT),
UpdateMaxLossHistory(lossPr255, nowMs);
_lossPr255.Apply(static_cast<float> (nowMs - _lastPrUpdateT),
static_cast<float> (lossPr255));
_lastPrUpdateT = now;
_lastPrUpdateT = nowMs;
_lossPr = _lossPr255.Value() / 255.0f;
}
@@ -768,14 +768,14 @@ VCMLossProtectionLogic::MaxFilteredLossPr(WebRtc_Word64 nowMs) const
}
WebRtc_UWord8
VCMLossProtectionLogic::FilteredLoss() const
VCMLossProtectionLogic::FilteredLoss(int64_t nowMs) const
{
if (_selectedMethod != NULL &&
(_selectedMethod->Type() == kFec ||
_selectedMethod->Type() == kNackFec))
{
// Take the windowed max of the received loss.
return MaxFilteredLossPr(VCMTickTime::MillisecondTimestamp());
return MaxFilteredLossPr(nowMs);
}
else
{
@@ -797,21 +797,19 @@ VCMLossProtectionLogic::UpdateBitRate(float bitRate)
}
void
VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets)
VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets, int64_t nowMs)
{
const WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
_packetsPerFrame.Apply(static_cast<float>(now - _lastPacketPerFrameUpdateT),
_packetsPerFrame.Apply(static_cast<float>(nowMs - _lastPacketPerFrameUpdateT),
nPackets);
_lastPacketPerFrameUpdateT = now;
_lastPacketPerFrameUpdateT = nowMs;
}
void
VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets)
VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs)
{
const WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
_packetsPerFrameKey.Apply(static_cast<float>(now -
_packetsPerFrameKey.Apply(static_cast<float>(nowMs -
_lastPacketPerFrameUpdateTKey), nPackets);
_lastPacketPerFrameUpdateTKey = now;
_lastPacketPerFrameUpdateTKey = nowMs;
}
void
@@ -868,12 +866,11 @@ VCMLossProtectionLogic::SelectedType() const
}
void
VCMLossProtectionLogic::Reset()
VCMLossProtectionLogic::Reset(int64_t nowMs)
{
const WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
_lastPrUpdateT = now;
_lastPacketPerFrameUpdateT = now;
_lastPacketPerFrameUpdateTKey = now;
_lastPrUpdateT = nowMs;
_lastPacketPerFrameUpdateT = nowMs;
_lastPacketPerFrameUpdateTKey = nowMs;
_lossPr255.Reset(0.9999f);
_packetsPerFrame.Reset(0.9999f);
_fecRateDelta = _fecRateKey = 0;

View File

@@ -15,7 +15,6 @@
#include "trace.h"
#include "exp_filter.h"
#include "internal_defines.h"
#include "tick_time.h"
#include "qm_select.h"
#include <cmath>
@@ -216,7 +215,7 @@ private:
class VCMLossProtectionLogic
{
public:
VCMLossProtectionLogic();
VCMLossProtectionLogic(int64_t nowMs);
~VCMLossProtectionLogic();
// Set the protection method to be used
@@ -255,7 +254,7 @@ public:
// Input:
// - lossPr255 : The packet loss probability [0, 255],
// reported by RTCP.
void UpdateLossPr(WebRtc_UWord8 lossPr255);
void UpdateLossPr(WebRtc_UWord8 lossPr255, int64_t nowMs);
// Update the filtered packet loss.
//
@@ -274,13 +273,13 @@ public:
//
// Input:
// - nPackets : Number of packets in the latest sent frame.
void UpdatePacketsPerFrame(float nPackets);
void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
// Update the number of packets per frame estimate, for key frames
//
// Input:
// - nPackets : umber of packets in the latest sent frame.
void UpdatePacketsPerFrameKey(float nPackets);
void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
// Update the keyFrameSize estimate
//
@@ -334,9 +333,9 @@ public:
// Returns the filtered loss probability in the interval [0, 255].
//
// Return value : The filtered loss probability
WebRtc_UWord8 FilteredLoss() const;
WebRtc_UWord8 FilteredLoss(int64_t nowMs) const;
void Reset();
void Reset(int64_t nowMs);
void Release();

View File

@@ -12,11 +12,14 @@
#include "content_metrics_processing.h"
#include "frame_dropper.h"
#include "qm_select.h"
#include "modules/video_coding/main/source/tick_time_base.h"
namespace webrtc {
VCMMediaOptimization::VCMMediaOptimization(WebRtc_Word32 id):
VCMMediaOptimization::VCMMediaOptimization(WebRtc_Word32 id,
TickTimeBase* clock):
_id(id),
_clock(clock),
_maxBitRate(0),
_sendCodecType(kVideoCodecUnknown),
_codecWidth(0),
@@ -43,7 +46,7 @@ _numLayers(0)
memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes));
_frameDropper = new VCMFrameDropper(_id);
_lossProtLogic = new VCMLossProtectionLogic();
_lossProtLogic = new VCMLossProtectionLogic(_clock->MillisecondTimestamp());
_content = new VCMContentMetricsProcessing();
_qmResolution = new VCMQmResolution();
}
@@ -63,12 +66,12 @@ VCMMediaOptimization::Reset()
memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes));
InputFrameRate(); // Resets _incomingFrameRate
_frameDropper->Reset();
_lossProtLogic->Reset();
_lossProtLogic->Reset(_clock->MillisecondTimestamp());
_frameDropper->SetRates(0, 0);
_content->Reset();
_qmResolution->Reset();
_lossProtLogic->UpdateFrameRate(_incomingFrameRate);
_lossProtLogic->Reset();
_lossProtLogic->Reset(_clock->MillisecondTimestamp());
_sendStatisticsZeroEncode = 0;
_targetBitRate = 0;
_codecWidth = 0;
@@ -95,7 +98,7 @@ VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate,
{
VCMProtectionMethod *selectedMethod = _lossProtLogic->SelectedMethod();
_lossProtLogic->UpdateBitRate(static_cast<float>(bitRate));
_lossProtLogic->UpdateLossPr(fractionLost);
_lossProtLogic->UpdateLossPr(fractionLost, _clock->MillisecondTimestamp());
_lossProtLogic->UpdateRtt(roundTripTimeMs);
_lossProtLogic->UpdateResidualPacketLoss(static_cast<float>(fractionLost));
@@ -118,7 +121,8 @@ VCMMediaOptimization::SetTargetRates(WebRtc_UWord32 bitRate,
// average or max filter may be used.
// We should think about which filter is appropriate for low/high bit rates,
// low/high loss rates, etc.
WebRtc_UWord8 packetLossEnc = _lossProtLogic->FilteredLoss();
WebRtc_UWord8 packetLossEnc = _lossProtLogic->FilteredLoss(
_clock->MillisecondTimestamp());
// For now use the filtered loss for computing the robustness settings
_lossProtLogic->UpdateFilteredLossPr(packetLossEnc);
@@ -261,7 +265,7 @@ VCMMediaOptimization::SetEncodingData(VideoCodecType sendCodecType,
// has changed. If native dimension values have changed, then either user
// initiated change, or QM initiated change. Will be able to determine only
// after the processing of the first frame.
_lastChangeTime = VCMTickTime::MillisecondTimestamp();
_lastChangeTime = _clock->MillisecondTimestamp();
_content->Reset();
_content->UpdateFrameRate(frameRate);
@@ -346,7 +350,7 @@ VCMMediaOptimization::SentFrameRate()
float
VCMMediaOptimization::SentBitRate()
{
UpdateBitRateEstimate(-1, VCMTickTime::MillisecondTimestamp());
UpdateBitRateEstimate(-1, _clock->MillisecondTimestamp());
return _avgSentBitRateBps / 1000.0f;
}
@@ -361,7 +365,7 @@ VCMMediaOptimization::UpdateWithEncodedData(WebRtc_Word32 encodedLength,
FrameType encodedFrameType)
{
// look into the ViE version - debug mode - needs also number of layers.
UpdateBitRateEstimate(encodedLength, VCMTickTime::MillisecondTimestamp());
UpdateBitRateEstimate(encodedLength, _clock->MillisecondTimestamp());
if(encodedLength > 0)
{
const bool deltaFrame = (encodedFrameType != kVideoFrameKey &&
@@ -374,11 +378,13 @@ VCMMediaOptimization::UpdateWithEncodedData(WebRtc_Word32 encodedLength,
static_cast<float>(_maxPayloadSize);
if (deltaFrame)
{
_lossProtLogic->UpdatePacketsPerFrame(minPacketsPerFrame);
_lossProtLogic->UpdatePacketsPerFrame(
minPacketsPerFrame, _clock->MillisecondTimestamp());
}
else
{
_lossProtLogic->UpdatePacketsPerFrameKey(minPacketsPerFrame);
_lossProtLogic->UpdatePacketsPerFrameKey(
minPacketsPerFrame, _clock->MillisecondTimestamp());
}
if (_enableQm)
@@ -529,7 +535,7 @@ VCMMediaOptimization::SelectQuality()
_qmResolution->ResetRates();
// Reset counters
_lastQMUpdateTime = VCMTickTime::MillisecondTimestamp();
_lastQMUpdateTime = _clock->MillisecondTimestamp();
// Reset content metrics
_content->Reset();
@@ -552,7 +558,7 @@ VCMMediaOptimization::checkStatusForQMchange()
// (to sample the metrics) from the event lastChangeTime
// lastChangeTime is the time where user changed the size/rate/frame rate
// (via SetEncodingData)
WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
WebRtc_Word64 now = _clock->MillisecondTimestamp();
if ((now - _lastQMUpdateTime) < kQmMinIntervalMs ||
(now - _lastChangeTime) < kQmMinIntervalMs)
{
@@ -622,7 +628,7 @@ VCMMediaOptimization::QMUpdate(VCMResolutionScale* qm)
void
VCMMediaOptimization::UpdateIncomingFrameRate()
{
WebRtc_Word64 now = VCMTickTime::MillisecondTimestamp();
WebRtc_Word64 now = _clock->MillisecondTimestamp();
if (_incomingFrameTimes[0] == 0)
{
// first no shift
@@ -674,7 +680,7 @@ VCMMediaOptimization::ProcessIncomingFrameRate(WebRtc_Word64 now)
WebRtc_UWord32
VCMMediaOptimization::InputFrameRate()
{
ProcessIncomingFrameRate(VCMTickTime::MillisecondTimestamp());
ProcessIncomingFrameRate(_clock->MillisecondTimestamp());
return WebRtc_UWord32 (_incomingFrameRate + 0.5f);
}

View File

@@ -24,6 +24,7 @@ namespace webrtc
enum { kBitrateMaxFrameSamples = 60 };
enum { kBitrateAverageWinMs = 1000 };
class TickTimeBase;
class VCMContentMetricsProcessing;
class VCMFrameDropper;
@@ -38,7 +39,7 @@ struct VCMEncodedFrameSample
class VCMMediaOptimization
{
public:
VCMMediaOptimization(WebRtc_Word32 id);
VCMMediaOptimization(WebRtc_Word32 id, TickTimeBase* clock);
~VCMMediaOptimization(void);
/*
* Reset the Media Optimization module
@@ -163,7 +164,7 @@ private:
enum { kFrameHistoryWinMs = 2000};
WebRtc_Word32 _id;
TickTimeBase* _clock;
WebRtc_Word32 _maxBitRate;
VideoCodecType _sendCodecType;
WebRtc_UWord16 _codecWidth;

View File

@@ -8,33 +8,40 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_WRAPPER_H_
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_WRAPPER_H_
#ifndef WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_H_
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_H_
#include "modules/video_coding/main/source/tick_time_interface.h"
#include <assert.h>
#include <limits>
#include "modules/video_coding/main/source/tick_time_base.h"
namespace webrtc {
class FakeTickTime : public TickTimeInterface {
// Provides a fake implementation of TickTimeBase, intended for offline
// testing. This implementation does not query the system clock, but returns a
// time value set by the user when creating the object, and incremented with
// the method IncrementDebugClock.
class FakeTickTime : public TickTimeBase {
public:
explicit FakeTickTime(int64_t start_time_ms) : fake_now_(TickTime::Now()) {
fake_now_ += (MillisecondsToTicks(start_time_ms) - fake_now_.Ticks());
}
virtual TickTime Now() const { return fake_now_; }
explicit FakeTickTime(int64_t start_time_ms) : fake_now_ms_(start_time_ms) {}
virtual ~FakeTickTime() {}
virtual int64_t MillisecondTimestamp() const {
return TicksToMilliseconds(Now().Ticks());
return fake_now_ms_;
}
virtual int64_t MicrosecondTimestamp() const {
return 1000 * TicksToMilliseconds(Now().Ticks());
return 1000 * fake_now_ms_;
}
virtual void IncrementDebugClock(int64_t increase_ms) {
fake_now_ += MillisecondsToTicks(increase_ms);
assert(increase_ms <= std::numeric_limits<int64_t>::max() - fake_now_ms_);
fake_now_ms_ += increase_ms;
}
private:
TickTime fake_now_;
int64_t fake_now_ms_;
};
} // namespace
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_WRAPPER_H_
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_MOCK_FAKE_TICK_TIME_H_

View File

@@ -13,7 +13,7 @@
#include "encoded_frame.h"
#include "internal_defines.h"
#include "media_opt_util.h"
#include "tick_time.h"
#include "tick_time_base.h"
#include "trace.h"
#include "video_coding.h"
@@ -22,15 +22,17 @@
namespace webrtc {
VCMReceiver::VCMReceiver(VCMTiming& timing,
TickTimeBase* clock,
WebRtc_Word32 vcmId,
WebRtc_Word32 receiverId,
bool master)
:
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_vcmId(vcmId),
_clock(clock),
_receiverId(receiverId),
_master(master),
_jitterBuffer(vcmId, receiverId, master),
_jitterBuffer(_clock, vcmId, receiverId, master),
_timing(timing),
_renderWaitEvent(*new VCMEvent()),
_state(kPassive)
@@ -118,10 +120,10 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
VCMId(_vcmId, _receiverId),
"Packet seqNo %u of frame %u at %u",
packet.seqNum, packet.timestamp,
MaskWord64ToUWord32(VCMTickTime::MillisecondTimestamp()));
MaskWord64ToUWord32(_clock->MillisecondTimestamp()));
}
const WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
const WebRtc_Word64 nowMs = _clock->MillisecondTimestamp();
WebRtc_Word64 renderTimeMs = _timing.RenderTimeMs(packet.timestamp, nowMs);
@@ -130,7 +132,7 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
// Render time error. Assume that this is due to some change in
// the incoming video stream and reset the JB and the timing.
_jitterBuffer.Flush();
_timing.Reset();
_timing.Reset(_clock->MillisecondTimestamp());
return VCM_FLUSH_INDICATOR;
}
else if (renderTimeMs < nowMs - kMaxVideoDelayMs)
@@ -139,7 +141,7 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
"This frame should have been rendered more than %u ms ago."
"Flushing jitter buffer and resetting timing.", kMaxVideoDelayMs);
_jitterBuffer.Flush();
_timing.Reset();
_timing.Reset(_clock->MillisecondTimestamp());
return VCM_FLUSH_INDICATOR;
}
else if (_timing.TargetVideoDelay() > kMaxVideoDelayMs)
@@ -148,14 +150,14 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
"More than %u ms target delay. Flushing jitter buffer and resetting timing.",
kMaxVideoDelayMs);
_jitterBuffer.Flush();
_timing.Reset();
_timing.Reset(_clock->MillisecondTimestamp());
return VCM_FLUSH_INDICATOR;
}
// First packet received belonging to this frame.
if (buffer->Length() == 0)
{
const WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
const WebRtc_Word64 nowMs = _clock->MillisecondTimestamp();
if (_master)
{
// Only trace the primary receiver to make it possible to parse and plot the trace file.
@@ -199,7 +201,7 @@ VCMReceiver::FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs, WebRtc_Word64& nextR
// is thread-safe.
FrameType incomingFrameType = kVideoFrameDelta;
nextRenderTimeMs = -1;
const WebRtc_Word64 startTimeMs = VCMTickTime::MillisecondTimestamp();
const WebRtc_Word64 startTimeMs = _clock->MillisecondTimestamp();
WebRtc_Word64 ret = _jitterBuffer.GetNextTimeStamp(maxWaitTimeMs,
incomingFrameType,
nextRenderTimeMs);
@@ -215,7 +217,7 @@ VCMReceiver::FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs, WebRtc_Word64& nextR
_timing.UpdateCurrentDelay(timeStamp);
const WebRtc_Word32 tempWaitTime = maxWaitTimeMs -
static_cast<WebRtc_Word32>(VCMTickTime::MillisecondTimestamp() - startTimeMs);
static_cast<WebRtc_Word32>(_clock->MillisecondTimestamp() - startTimeMs);
WebRtc_UWord16 newMaxWaitTime = static_cast<WebRtc_UWord16>(VCM_MAX(tempWaitTime, 0));
VCMEncodedFrame* frame = NULL;
@@ -256,7 +258,7 @@ VCMReceiver::FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs,
{
// How long can we wait until we must decode the next frame
WebRtc_UWord32 waitTimeMs = _timing.MaxWaitingTime(nextRenderTimeMs,
VCMTickTime::MillisecondTimestamp());
_clock->MillisecondTimestamp());
// Try to get a complete frame from the jitter buffer
VCMEncodedFrame* frame = _jitterBuffer.GetCompleteFrameForDecoding(0);
@@ -296,7 +298,7 @@ VCMReceiver::FrameForDecoding(WebRtc_UWord16 maxWaitTimeMs,
{
// Get an incomplete frame
if (_timing.MaxWaitingTime(nextRenderTimeMs,
VCMTickTime::MillisecondTimestamp()) > 0)
_clock->MillisecondTimestamp()) > 0)
{
// Still time to wait for a complete frame
return NULL;
@@ -328,7 +330,7 @@ VCMReceiver::FrameForRendering(WebRtc_UWord16 maxWaitTimeMs,
// as possible before giving the frame to the decoder, which will render the frame as soon
// as it has been decoded.
WebRtc_UWord32 waitTimeMs = _timing.MaxWaitingTime(nextRenderTimeMs,
VCMTickTime::MillisecondTimestamp());
_clock->MillisecondTimestamp());
if (maxWaitTimeMs < waitTimeMs)
{
// If we're not allowed to wait until the frame is supposed to be rendered

View File

@@ -13,6 +13,7 @@
#include "critical_section_wrapper.h"
#include "jitter_buffer.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "timing.h"
#include "packet.h"
@@ -40,6 +41,7 @@ class VCMReceiver
{
public:
VCMReceiver(VCMTiming& timing,
TickTimeBase* clock,
WebRtc_Word32 vcmId = -1,
WebRtc_Word32 receiverId = -1,
bool master = true);
@@ -83,6 +85,7 @@ private:
CriticalSectionWrapper* _critSect;
WebRtc_Word32 _vcmId;
TickTimeBase* _clock;
WebRtc_Word32 _receiverId;
bool _master;
VCMJitterBuffer _jitterBuffer;

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_TICK_TIME_H_
#define WEBRTC_MODULES_VIDEO_CODING_TICK_TIME_H_
#include "tick_util.h"
#include <assert.h>
namespace webrtc
{
//#define TICK_TIME_DEBUG
class VCMTickTime : public TickTime
{
#ifdef TICK_TIME_DEBUG
public:
/*
* Get current time
*/
static TickTime Now() { assert(false); };
/*
* Get time in milli seconds
*/
static WebRtc_Word64 MillisecondTimestamp() { return _timeNowDebug; };
/*
* Get time in micro seconds
*/
static WebRtc_Word64 MicrosecondTimestamp() { return _timeNowDebug * 1000LL; };
static void IncrementDebugClock() { _timeNowDebug++; };
private:
static WebRtc_Word64 _timeNowDebug;
#else
public:
static void IncrementDebugClock() { assert(false); };
#endif
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_TICK_TIME_H_

View File

@@ -8,24 +8,24 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_WRAPPER_H_
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_WRAPPER_H_
#ifndef WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_BASE_H_
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_BASE_H_
#include "system_wrappers/interface/tick_util.h"
namespace webrtc {
class TickTimeInterface : public TickTime {
// This class provides a mockable wrapper to TickTime.
class TickTimeBase {
public:
// Current time in the tick domain.
virtual TickTime Now() const { return TickTime::Now(); }
virtual ~TickTimeBase() {}
// Now in the time domain in ms.
// "Now" in milliseconds.
virtual int64_t MillisecondTimestamp() const {
return TickTime::MillisecondTimestamp();
}
// Now in the time domain in us.
// "Now" in microseconds.
virtual int64_t MicrosecondTimestamp() const {
return TickTime::MicrosecondTimestamp();
}
@@ -33,4 +33,4 @@ class TickTimeInterface : public TickTime {
} // namespace
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_WRAPPER_H_
#endif // WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_TICK_TIME_BASE_H_

View File

@@ -9,17 +9,20 @@
*/
#include "internal_defines.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "timestamp_extrapolator.h"
#include "tick_time.h"
#include "trace.h"
namespace webrtc {
VCMTimestampExtrapolator::VCMTimestampExtrapolator(WebRtc_Word32 vcmId, WebRtc_Word32 id)
VCMTimestampExtrapolator::VCMTimestampExtrapolator(TickTimeBase* clock,
WebRtc_Word32 vcmId,
WebRtc_Word32 id)
:
_rwLock(RWLockWrapper::CreateRWLock()),
_vcmId(vcmId),
_id(id),
_clock(clock),
_startMs(0),
_firstTimestamp(0),
_wrapArounds(0),
@@ -35,7 +38,7 @@ _accDrift(6600), // in timestamp ticks, i.e. 15 ms
_accMaxError(7000),
_P11(1e10)
{
Reset(VCMTickTime::MillisecondTimestamp());
Reset(_clock->MillisecondTimestamp());
}
VCMTimestampExtrapolator::~VCMTimestampExtrapolator()
@@ -53,7 +56,7 @@ VCMTimestampExtrapolator::Reset(const WebRtc_Word64 nowMs /* = -1 */)
}
else
{
_startMs = VCMTickTime::MillisecondTimestamp();
_startMs = _clock->MillisecondTimestamp();
}
_prevMs = _startMs;
_firstTimestamp = 0;

View File

@@ -17,10 +17,14 @@
namespace webrtc
{
class TickTimeBase;
class VCMTimestampExtrapolator
{
public:
VCMTimestampExtrapolator(WebRtc_Word32 vcmId = 0, WebRtc_Word32 receiverId = 0);
VCMTimestampExtrapolator(TickTimeBase* clock,
WebRtc_Word32 vcmId = 0,
WebRtc_Word32 receiverId = 0);
~VCMTimestampExtrapolator();
void Update(WebRtc_Word64 tMs, WebRtc_UWord32 ts90khz, bool trace = true);
WebRtc_UWord32 ExtrapolateTimestamp(WebRtc_Word64 tMs) const;
@@ -33,6 +37,7 @@ private:
RWLockWrapper* _rwLock;
WebRtc_Word32 _vcmId;
WebRtc_Word32 _id;
TickTimeBase* _clock;
bool _trace;
double _w[2];
double _P[2][2];

View File

@@ -16,10 +16,14 @@
namespace webrtc {
VCMTiming::VCMTiming(WebRtc_Word32 vcmId, WebRtc_Word32 timingId, VCMTiming* masterTiming)
VCMTiming::VCMTiming(TickTimeBase* clock,
WebRtc_Word32 vcmId,
WebRtc_Word32 timingId,
VCMTiming* masterTiming)
:
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_vcmId(vcmId),
_clock(clock),
_timingId(timingId),
_master(false),
_tsExtrapolator(),
@@ -33,7 +37,7 @@ _prevFrameTimestamp(0)
if (masterTiming == NULL)
{
_master = true;
_tsExtrapolator = new VCMTimestampExtrapolator(vcmId, timingId);
_tsExtrapolator = new VCMTimestampExtrapolator(_clock, vcmId, timingId);
}
else
{

View File

@@ -18,6 +18,7 @@
namespace webrtc
{
class TickTimeBase;
class VCMTimestampExtrapolator;
class VCMTiming
@@ -25,7 +26,8 @@ class VCMTiming
public:
// The primary timing component should be passed
// if this is the dual timing component.
VCMTiming(WebRtc_Word32 vcmId = 0,
VCMTiming(TickTimeBase* clock,
WebRtc_Word32 vcmId = 0,
WebRtc_Word32 timingId = 0,
VCMTiming* masterTiming = NULL);
~VCMTiming();
@@ -92,6 +94,7 @@ protected:
private:
CriticalSectionWrapper* _critSect;
WebRtc_Word32 _vcmId;
TickTimeBase* _clock;
WebRtc_Word32 _timingId;
bool _master;
VCMTimestampExtrapolator* _tsExtrapolator;

View File

@@ -63,8 +63,7 @@
'receiver.h',
'rtt_filter.h',
'session_info.h',
'tick_time.h',
'tick_time_interface.h',
'tick_time_base.h',
'timestamp_extrapolator.h',
'timestamp_map.h',
'timing.h',

View File

@@ -15,6 +15,7 @@
#include "packet.h"
#include "trace.h"
#include "video_codec_interface.h"
#include "modules/video_coding/main/source/tick_time_base.h"
namespace webrtc
{
@@ -33,26 +34,30 @@ VCMProcessTimer::TimeUntilProcess() const
{
return static_cast<WebRtc_UWord32>(
VCM_MAX(static_cast<WebRtc_Word64>(_periodMs) -
(VCMTickTime::MillisecondTimestamp() - _latestMs), 0));
(_clock->MillisecondTimestamp() - _latestMs), 0));
}
void
VCMProcessTimer::Processed()
{
_latestMs = VCMTickTime::MillisecondTimestamp();
_latestMs = _clock->MillisecondTimestamp();
}
VideoCodingModuleImpl::VideoCodingModuleImpl(const WebRtc_Word32 id)
VideoCodingModuleImpl::VideoCodingModuleImpl(const WebRtc_Word32 id,
TickTimeBase* clock,
bool delete_clock_on_destroy)
:
_id(id),
clock_(clock),
delete_clock_on_destroy_(delete_clock_on_destroy),
_receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()),
_receiverInited(false),
_timing(id, 1),
_dualTiming(id, 2, &_timing),
_receiver(_timing, id, 1),
_dualReceiver(_dualTiming, id, 2, false),
_decodedFrameCallback(_timing),
_dualDecodedFrameCallback(_dualTiming),
_timing(clock_, id, 1),
_dualTiming(clock_, id, 2, &_timing),
_receiver(_timing, clock_, id, 1),
_dualReceiver(_dualTiming, clock_, id, 2, false),
_decodedFrameCallback(_timing, clock_),
_dualDecodedFrameCallback(_dualTiming, clock_),
_frameTypeCallback(NULL),
_frameStorageCallback(NULL),
_receiveStatsCallback(NULL),
@@ -67,17 +72,18 @@ _scheduleKeyRequest(false),
_sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
_encoder(),
_encodedFrameCallback(),
_mediaOpt(id),
_mediaOpt(id, clock_),
_sendCodecType(kVideoCodecUnknown),
_sendStatsCallback(NULL),
_encoderInputFile(NULL),
_codecDataBase(id),
_receiveStatsTimer(1000),
_sendStatsTimer(1000),
_retransmissionTimer(10),
_keyRequestTimer(500)
_receiveStatsTimer(1000, clock_),
_sendStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_),
_keyRequestTimer(500, clock_)
{
assert(clock_);
for (int i = 0; i < kMaxSimulcastStreams; i++)
{
_nextFrameType[i] = kVideoFrameDelta;
@@ -98,6 +104,7 @@ VideoCodingModuleImpl::~VideoCodingModuleImpl()
}
delete _receiveCritSect;
delete _sendCritSect;
if (delete_clock_on_destroy_) delete clock_;
#ifdef DEBUG_DECODER_BIT_STREAM
fclose(_bitStreamBeforeDecoder);
#endif
@@ -113,7 +120,18 @@ VideoCodingModule::Create(const WebRtc_Word32 id)
webrtc::kTraceVideoCoding,
VCMId(id),
"VideoCodingModule::Create()");
return new VideoCodingModuleImpl(id);
return new VideoCodingModuleImpl(id, new TickTimeBase(), true);
}
VideoCodingModule*
VideoCodingModule::Create(const WebRtc_Word32 id, TickTimeBase* clock)
{
WEBRTC_TRACE(webrtc::kTraceModuleCall,
webrtc::kTraceVideoCoding,
VCMId(id),
"VideoCodingModule::Create()");
assert(clock);
return new VideoCodingModuleImpl(id, clock, false);
}
void
@@ -1089,7 +1107,7 @@ VideoCodingModuleImpl::Decode(WebRtc_UWord16 maxWaitTimeMs)
// If this frame was too late, we should adjust the delay accordingly
_timing.UpdateCurrentDelay(frame->RenderTimeMs(),
VCMTickTime::MillisecondTimestamp());
clock_->MillisecondTimestamp());
#ifdef DEBUG_DECODER_BIT_STREAM
if (_bitStreamBeforeDecoder != NULL)
@@ -1206,7 +1224,8 @@ VideoCodingModuleImpl::DecodeDualFrame(WebRtc_UWord16 maxWaitTimeMs)
"Decoding frame %u with dual decoder",
dualFrame->TimeStamp());
// Decode dualFrame and try to catch up
WebRtc_Word32 ret = _dualDecoder->Decode(*dualFrame);
WebRtc_Word32 ret = _dualDecoder->Decode(*dualFrame,
clock_->MillisecondTimestamp());
if (ret != WEBRTC_VIDEO_CODEC_OK)
{
WEBRTC_TRACE(webrtc::kTraceWarning,
@@ -1254,7 +1273,7 @@ VideoCodingModuleImpl::Decode(const VCMEncodedFrame& frame)
return VCM_NO_CODEC_REGISTERED;
}
// Decode a frame
WebRtc_Word32 ret = _decoder->Decode(frame);
WebRtc_Word32 ret = _decoder->Decode(frame, clock_->MillisecondTimestamp());
// Check for failed decoding, run frame type request callback if needed.
if (ret < 0)

View File

@@ -21,6 +21,7 @@
#include "generic_decoder.h"
#include "generic_encoder.h"
#include "media_optimization.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include <stdio.h>
@@ -30,13 +31,16 @@ namespace webrtc
class VCMProcessTimer
{
public:
VCMProcessTimer(WebRtc_UWord32 periodMs) :
_periodMs(periodMs), _latestMs(VCMTickTime::MillisecondTimestamp()) {}
VCMProcessTimer(WebRtc_UWord32 periodMs, TickTimeBase* clock)
: _clock(clock),
_periodMs(periodMs),
_latestMs(_clock->MillisecondTimestamp()) {}
WebRtc_UWord32 Period() const;
WebRtc_UWord32 TimeUntilProcess() const;
void Processed();
private:
TickTimeBase* _clock;
WebRtc_UWord32 _periodMs;
WebRtc_Word64 _latestMs;
};
@@ -53,7 +57,9 @@ enum VCMKeyRequestMode
class VideoCodingModuleImpl : public VideoCodingModule
{
public:
VideoCodingModuleImpl(const WebRtc_Word32 id);
VideoCodingModuleImpl(const WebRtc_Word32 id,
TickTimeBase* clock,
bool delete_clock_on_destroy);
virtual ~VideoCodingModuleImpl();
@@ -259,6 +265,8 @@ protected:
private:
WebRtc_Word32 _id;
TickTimeBase* clock_;
bool delete_clock_on_destroy_;
CriticalSectionWrapper* _receiveCritSect;
bool _receiverInited;
VCMTiming _timing;