summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpwestin@webrtc.org <pwestin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2013-04-11 20:23:35 +0000
committerpwestin@webrtc.org <pwestin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2013-04-11 20:23:35 +0000
commitf2724977323ae0d162fa0b33135046701f3eba66 (patch)
tree54e44795144c053ad82e517fed248a4701fc87b1
parent02f158e77885046f5634e8f969496066fa059bed (diff)
downloadwebrtc-f2724977323ae0d162fa0b33135046701f3eba66.tar.gz
Adding playout buffer status to the voe video sync
Review URL: https://webrtc-codereview.appspot.com/1311004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@3835 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r--video_engine/vie_sync_module.cc25
-rw-r--r--voice_engine/channel.cc310
-rw-r--r--voice_engine/channel.h23
-rw-r--r--voice_engine/include/voe_video_sync.h12
-rw-r--r--voice_engine/test/auto_test/standard/video_sync_test.cc16
-rw-r--r--voice_engine/voe_video_sync_impl.cc43
-rw-r--r--voice_engine/voe_video_sync_impl.h4
7 files changed, 200 insertions, 233 deletions
diff --git a/video_engine/vie_sync_module.cc b/video_engine/vie_sync_module.cc
index fe7a1cab..a974e256 100644
--- a/video_engine/vie_sync_module.cc
+++ b/video_engine/vie_sync_module.cc
@@ -114,24 +114,19 @@ int32_t ViESyncModule::Process() {
assert(video_rtp_rtcp_ && voe_sync_interface_);
assert(sync_.get());
- int current_audio_delay_ms = 0;
+ int audio_jitter_buffer_delay_ms = 0;
+ int playout_buffer_delay_ms = 0;
if (voe_sync_interface_->GetDelayEstimate(voe_channel_id_,
- current_audio_delay_ms) != 0) {
- // Could not get VoE delay value, probably not a valid channel Id.
+ &audio_jitter_buffer_delay_ms,
+ &playout_buffer_delay_ms) != 0) {
+ // Could not get VoE delay value, probably not a valid channel Id or
+ // the channel have not received enough packets.
WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceVideo, vie_channel_->Id(),
"%s: VE_GetDelayEstimate error for voice_channel %d",
__FUNCTION__, voe_channel_id_);
return 0;
}
- // VoiceEngine report delay estimates even when not started, ignore if the
- // reported value is lower than 40 ms.
- if (current_audio_delay_ms < 40) {
- WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, vie_channel_->Id(),
- "A/V Sync: Audio delay < 40, skipping.");
- return 0;
- }
-
RtpRtcp* voice_rtp_rtcp = NULL;
if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, voice_rtp_rtcp)) {
return 0;
@@ -153,14 +148,16 @@ int32_t ViESyncModule::Process() {
return 0;
}
- TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", total_video_delay_target_ms);
- TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay", current_audio_delay_ms);
+ TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay",
+ total_video_delay_target_ms);
+ TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay",
+ audio_jitter_buffer_delay_ms);
TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms);
int extra_audio_delay_ms = 0;
// Calculate the necessary extra audio delay and desired total video
// delay to get the streams in sync.
if (!sync_->ComputeDelays(relative_delay_ms,
- current_audio_delay_ms,
+ audio_jitter_buffer_delay_ms,
&extra_audio_delay_ms,
&total_video_delay_target_ms)) {
return 0;
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index 3480564c..7abf7d4f 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -628,7 +628,6 @@ Channel::OnReceivedPayloadData(const uint8_t* payloadData,
// Update the packet delay
UpdatePacketDelay(rtpHeader->header.timestamp,
rtpHeader->header.sequenceNumber);
-
return 0;
}
@@ -898,8 +897,8 @@ Channel::Channel(const int32_t channelId,
_decryptionRTCPBufferPtr(NULL),
_timeStamp(0), // This is just an offset, RTP module will add it's own random offset
_sendTelephoneEventPayloadType(106),
- _playoutTimeStampRTP(0),
- _playoutTimeStampRTCP(0),
+ playout_timestamp_rtp_(0),
+ playout_timestamp_rtcp_(0),
_numberOfDiscardedPackets(0),
_engineStatisticsPtr(NULL),
_outputMixerPtr(NULL),
@@ -950,8 +949,7 @@ Channel::Channel(const int32_t channelId,
_countAliveDetections(0),
_countDeadDetections(0),
_outputSpeechType(AudioFrame::kNormalSpeech),
- _averageDelayMs(0),
- _previousSequenceNumber(0),
+ _average_jitter_buffer_delay_us(0),
_previousTimestamp(0),
_recPacketDelayMs(20),
_RxVadDetection(false),
@@ -2120,10 +2118,7 @@ int32_t Channel::ReceivedRTPPacket(const int8_t* data, int32_t length) {
"Channel::ReceivedRTPPacket()");
// Store playout timestamp for the received RTP packet
- uint32_t playoutTimestamp(0);
- if (GetPlayoutTimeStamp(playoutTimestamp) == 0) {
- _playoutTimeStampRTP = playoutTimestamp;
- }
+ UpdatePlayoutTimestamp(false);
// Dump the RTP packet to a file (if RTP dump is enabled).
if (_rtpDumpIn.DumpPacket((const uint8_t*)data,
@@ -2149,10 +2144,7 @@ int32_t Channel::ReceivedRTCPPacket(const int8_t* data, int32_t length) {
WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
"Channel::ReceivedRTCPPacket()");
// Store playout timestamp for the received RTCP packet
- uint32_t playoutTimestamp(0);
- if (GetPlayoutTimeStamp(playoutTimestamp) == 0) {
- _playoutTimeStampRTCP = playoutTimestamp;
- }
+ UpdatePlayoutTimestamp(true);
// Dump the RTCP packet to a file (if RTP dump is enabled).
if (_rtpDumpIn.DumpPacket((const uint8_t*)data,
@@ -3836,12 +3828,12 @@ Channel::GetRemoteRTCPData(
// This value is updated on each incoming RTCP packet (0 when no packet
// has been received)
- playoutTimestamp = _playoutTimeStampRTCP;
+ playoutTimestamp = playout_timestamp_rtcp_;
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId),
"GetRemoteRTCPData() => playoutTimestamp=%lu",
- _playoutTimeStampRTCP);
+ playout_timestamp_rtcp_);
if (NULL != jitter || NULL != fractionLost)
{
@@ -4659,13 +4651,19 @@ Channel::GetNetworkStatistics(NetworkStatistics& stats)
return return_value;
}
-int
-Channel::GetDelayEstimate(int& delayMs) const
-{
+bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms,
+ int* playout_buffer_delay_ms) const {
+ if (_average_jitter_buffer_delay_us == 0) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::GetDelayEstimate()");
- delayMs = (_averageDelayMs + 5) / 10 + _recPacketDelayMs;
- return 0;
+ "Channel::GetDelayEstimate() no valid estimate.");
+ return false;
+ }
+ *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 +
+ _recPacketDelayMs;
+ *playout_buffer_delay_ms = playout_delay_ms_;
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::GetDelayEstimate()");
+ return true;
}
int Channel::SetInitialPlayoutDelay(int delay_ms)
@@ -4714,24 +4712,69 @@ Channel::SetMinimumPlayoutDelay(int delayMs)
return 0;
}
-int
-Channel::GetPlayoutTimestamp(unsigned int& timestamp)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::GetPlayoutTimestamp()");
- uint32_t playoutTimestamp(0);
- if (GetPlayoutTimeStamp(playoutTimestamp) != 0)
- {
- _engineStatisticsPtr->SetLastError(
- VE_CANNOT_RETRIEVE_VALUE, kTraceError,
- "GetPlayoutTimestamp() failed to retrieve timestamp");
- return -1;
+void Channel::UpdatePlayoutTimestamp(bool rtcp) {
+ uint32_t playout_timestamp = 0;
+
+ if (_audioCodingModule.PlayoutTimestamp(&playout_timestamp) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::UpdatePlayoutTimestamp() failed to read playout"
+ " timestamp from the ACM");
+ _engineStatisticsPtr->SetLastError(
+ VE_CANNOT_RETRIEVE_VALUE, kTraceError,
+ "UpdatePlayoutTimestamp() failed to retrieve timestamp");
+ return;
+ }
+
+ uint16_t delay_ms = 0;
+ if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) {
+ WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::UpdatePlayoutTimestamp() failed to read playout"
+ " delay from the ADM");
+ _engineStatisticsPtr->SetLastError(
+ VE_CANNOT_RETRIEVE_VALUE, kTraceError,
+ "UpdatePlayoutTimestamp() failed to retrieve playout delay");
+ return;
+ }
+
+ int32_t playout_frequency = _audioCodingModule.PlayoutFrequency();
+ CodecInst current_recive_codec;
+ if (_audioCodingModule.ReceiveCodec(&current_recive_codec) == 0) {
+ if (STR_CASE_CMP("G722", current_recive_codec.plname) == 0) {
+ playout_frequency = 8000;
+ } else if (STR_CASE_CMP("opus", current_recive_codec.plname) == 0) {
+ playout_frequency = 48000;
}
- timestamp = playoutTimestamp;
- WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
- VoEId(_instanceId,_channelId),
- "GetPlayoutTimestamp() => timestamp=%u", timestamp);
- return 0;
+ }
+
+ // Remove the playout delay.
+ playout_timestamp -= (delay_ms * (playout_frequency / 1000));
+
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu",
+ playout_timestamp);
+
+ if (rtcp) {
+ playout_timestamp_rtcp_ = playout_timestamp;
+ } else {
+ playout_timestamp_rtp_ = playout_timestamp;
+ }
+ playout_delay_ms_ = delay_ms;
+}
+
+int Channel::GetPlayoutTimestamp(unsigned int& timestamp) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::GetPlayoutTimestamp()");
+ if (playout_timestamp_rtp_ == 0) {
+ _engineStatisticsPtr->SetLastError(
+ VE_CANNOT_RETRIEVE_VALUE, kTraceError,
+ "GetPlayoutTimestamp() failed to retrieve timestamp");
+ return -1;
+ }
+ timestamp = playout_timestamp_rtp_;
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+ VoEId(_instanceId,_channelId),
+ "GetPlayoutTimestamp() => timestamp=%u", timestamp);
+ return 0;
}
int
@@ -4983,47 +5026,6 @@ Channel::InsertInbandDtmfTone()
return 0;
}
-int32_t
-Channel::GetPlayoutTimeStamp(uint32_t& playoutTimestamp)
-{
- uint32_t timestamp(0);
- CodecInst currRecCodec;
-
- if (_audioCodingModule.PlayoutTimestamp(&timestamp) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::GetPlayoutTimeStamp() failed to read playout"
- " timestamp from the ACM");
- return -1;
- }
-
- uint16_t delayMS(0);
- if (_audioDeviceModulePtr->PlayoutDelay(&delayMS) == -1)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::GetPlayoutTimeStamp() failed to read playout"
- " delay from the ADM");
- return -1;
- }
-
- int32_t playoutFrequency = _audioCodingModule.PlayoutFrequency();
- if (_audioCodingModule.ReceiveCodec(&currRecCodec) == 0) {
- if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) {
- playoutFrequency = 8000;
- } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) {
- playoutFrequency = 48000;
- }
- }
- timestamp -= (delayMS * (playoutFrequency/1000));
-
- playoutTimestamp = timestamp;
-
- WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::GetPlayoutTimeStamp() => playoutTimestamp = %lu",
- playoutTimestamp);
- return 0;
-}
-
void
Channel::ResetDeadOrAliveCounters()
{
@@ -5072,110 +5074,66 @@ Channel::SendPacketRaw(const void *data, int len, bool RTCP)
}
}
-int32_t
-Channel::UpdatePacketDelay(const uint32_t timestamp,
- const uint16_t sequenceNumber)
-{
- WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)",
- timestamp, sequenceNumber);
-
- int32_t rtpReceiveFrequency(0);
-
- // Get frequency of last received payload
- rtpReceiveFrequency = _audioCodingModule.ReceiveFrequency();
-
- CodecInst currRecCodec;
- if (_audioCodingModule.ReceiveCodec(&currRecCodec) == 0) {
- if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) {
- // Even though the actual sampling rate for G.722 audio is
- // 16,000 Hz, the RTP clock rate for the G722 payload format is
- // 8,000 Hz because that value was erroneously assigned in
- // RFC 1890 and must remain unchanged for backward compatibility.
- rtpReceiveFrequency = 8000;
- } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) {
- // We are resampling Opus internally to 32,000 Hz until all our
- // DSP routines can operate at 48,000 Hz, but the RTP clock
- // rate for the Opus payload format is standardized to 48,000 Hz,
- // because that is the maximum supported decoding sampling rate.
- rtpReceiveFrequency = 48000;
- }
- }
+// Called for incoming RTP packets after successful RTP header parsing.
+void Channel::UpdatePacketDelay(uint32_t rtp_timestamp,
+ uint16_t sequence_number) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)",
+ rtp_timestamp, sequence_number);
- const uint32_t timeStampDiff = timestamp - _playoutTimeStampRTP;
- uint32_t timeStampDiffMs(0);
+ // Get frequency of last received payload
+ int rtp_receive_frequency = _audioCodingModule.ReceiveFrequency();
- if (timeStampDiff > 0)
- {
- switch (rtpReceiveFrequency) {
- case 8000:
- timeStampDiffMs = static_cast<uint32_t>(timeStampDiff >> 3);
- break;
- case 16000:
- timeStampDiffMs = static_cast<uint32_t>(timeStampDiff >> 4);
- break;
- case 32000:
- timeStampDiffMs = static_cast<uint32_t>(timeStampDiff >> 5);
- break;
- case 48000:
- timeStampDiffMs = static_cast<uint32_t>(timeStampDiff / 48);
- break;
- default:
- WEBRTC_TRACE(kTraceWarning, kTraceVoice,
- VoEId(_instanceId, _channelId),
- "Channel::UpdatePacketDelay() invalid sample rate");
- timeStampDiffMs = 0;
- return -1;
- }
- if (timeStampDiffMs > (2 * kVoiceEngineMaxMinPlayoutDelayMs))
- {
- timeStampDiffMs = 0;
- }
+ CodecInst current_receive_codec;
+ if (_audioCodingModule.ReceiveCodec(&current_receive_codec) != 0) {
+ return;
+ }
- if (_averageDelayMs == 0)
- {
- _averageDelayMs = timeStampDiffMs * 10;
- }
- else
- {
- // Filter average delay value using exponential filter (alpha is
- // 7/8). We derive 10*_averageDelayMs here (reduces risk of
- // rounding error) and compensate for it in GetDelayEstimate()
- // later. Adding 4/8 results in correct rounding.
- _averageDelayMs = ((_averageDelayMs*7 + 10*timeStampDiffMs + 4)>>3);
- }
+ if (STR_CASE_CMP("G722", current_receive_codec.plname) == 0) {
+ // Even though the actual sampling rate for G.722 audio is
+ // 16,000 Hz, the RTP clock rate for the G722 payload format is
+ // 8,000 Hz because that value was erroneously assigned in
+ // RFC 1890 and must remain unchanged for backward compatibility.
+ rtp_receive_frequency = 8000;
+ } else if (STR_CASE_CMP("opus", current_receive_codec.plname) == 0) {
+ // We are resampling Opus internally to 32,000 Hz until all our
+ // DSP routines can operate at 48,000 Hz, but the RTP clock
+ // rate for the Opus payload format is standardized to 48,000 Hz,
+ // because that is the maximum supported decoding sampling rate.
+ rtp_receive_frequency = 48000;
+ }
- if (sequenceNumber - _previousSequenceNumber == 1)
- {
- uint16_t packetDelayMs = 0;
- switch (rtpReceiveFrequency) {
- case 8000:
- packetDelayMs = static_cast<uint16_t>(
- (timestamp - _previousTimestamp) >> 3);
- break;
- case 16000:
- packetDelayMs = static_cast<uint16_t>(
- (timestamp - _previousTimestamp) >> 4);
- break;
- case 32000:
- packetDelayMs = static_cast<uint16_t>(
- (timestamp - _previousTimestamp) >> 5);
- break;
- case 48000:
- packetDelayMs = static_cast<uint16_t>(
- (timestamp - _previousTimestamp) / 48);
- break;
- }
+ // playout_timestamp_rtp_ updated in UpdatePlayoutTimestamp for every incoming
+ // packet.
+ uint32_t timestamp_diff_ms = (rtp_timestamp - playout_timestamp_rtp_) /
+ (rtp_receive_frequency / 1000);
- if (packetDelayMs >= 10 && packetDelayMs <= 60)
- _recPacketDelayMs = packetDelayMs;
- }
- }
+ uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) /
+ (rtp_receive_frequency / 1000);
- _previousSequenceNumber = sequenceNumber;
- _previousTimestamp = timestamp;
+ _previousTimestamp = rtp_timestamp;
- return 0;
+ if (timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) {
+ timestamp_diff_ms = 0;
+ }
+
+ if (timestamp_diff_ms == 0) return;
+
+ if (packet_delay_ms >= 10 && packet_delay_ms <= 60) {
+ _recPacketDelayMs = packet_delay_ms;
+ }
+
+ if (_average_jitter_buffer_delay_us == 0) {
+ _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000;
+ return;
+ }
+
+ // Filter average delay value using exponential filter (alpha is
+ // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces
+ // risk of rounding error) and compensate for it in GetDelayEstimate()
+ // later.
+ _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 +
+ 1000 * timestamp_diff_ms + 500) / 8;
}
void
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index 972b5abc..582a6fbf 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -202,10 +202,12 @@ public:
int GetNetworkStatistics(NetworkStatistics& stats);
// VoEVideoSync
- int GetDelayEstimate(int& delayMs) const;
+ bool GetDelayEstimate(int* jitter_buffer_delay_ms,
+ int* playout_buffer_delay_ms) const;
int SetInitialPlayoutDelay(int delay_ms);
int SetMinimumPlayoutDelay(int delayMs);
int GetPlayoutTimestamp(unsigned int& timestamp);
+ void UpdatePlayoutTimestamp(bool rtcp);
int SetInitTimestamp(unsigned int timestamp);
int SetInitSequenceNumber(short sequenceNumber);
@@ -421,14 +423,12 @@ public:
private:
int InsertInbandDtmfTone();
- int32_t
- MixOrReplaceAudioWithFile(const int mixingFrequency);
+ int32_t MixOrReplaceAudioWithFile(const int mixingFrequency);
int32_t MixAudioWithFile(AudioFrame& audioFrame, const int mixingFrequency);
- int32_t GetPlayoutTimeStamp(uint32_t& playoutTimestamp);
void UpdateDeadOrAliveCounters(bool alive);
int32_t SendPacketRaw(const void *data, int len, bool RTCP);
- int32_t UpdatePacketDelay(const uint32_t timestamp,
- const uint16_t sequenceNumber);
+ void UpdatePacketDelay(uint32_t timestamp,
+ uint16_t sequenceNumber);
void RegisterReceiveCodecsToRTPModule();
int ApmProcessRx(AudioFrame& audioFrame);
@@ -470,10 +470,12 @@ private:
uint8_t* _decryptionRTCPBufferPtr;
uint32_t _timeStamp;
uint8_t _sendTelephoneEventPayloadType;
- uint32_t _playoutTimeStampRTP;
- uint32_t _playoutTimeStampRTCP;
+ uint32_t playout_timestamp_rtp_;
+ uint32_t playout_timestamp_rtcp_;
+ uint32_t playout_delay_ms_;
uint32_t _numberOfDiscardedPackets;
-private:
+
+ private:
// uses
Statistics* _engineStatisticsPtr;
OutputMixer* _outputMixerPtr;
@@ -532,8 +534,7 @@ private:
uint32_t _countDeadDetections;
AudioFrame::SpeechType _outputSpeechType;
// VoEVideoSync
- uint32_t _averageDelayMs;
- uint16_t _previousSequenceNumber;
+ uint32_t _average_jitter_buffer_delay_us;
uint32_t _previousTimestamp;
uint16_t _recPacketDelayMs;
// VoEAudioProcessing
diff --git a/voice_engine/include/voe_video_sync.h b/voice_engine/include/voe_video_sync.h
index 14230364..857422ee 100644
--- a/voice_engine/include/voe_video_sync.h
+++ b/voice_engine/include/voe_video_sync.h
@@ -55,18 +55,20 @@ public:
virtual int Release() = 0;
// Gets the current sound card buffer size (playout delay).
- virtual int GetPlayoutBufferSize(int& bufferMs) = 0;
+ virtual int GetPlayoutBufferSize(int& buffer_ms) = 0;
// Sets an additional delay for the playout jitter buffer.
- virtual int SetMinimumPlayoutDelay(int channel, int delayMs) = 0;
+ virtual int SetMinimumPlayoutDelay(int channel, int delay_ms) = 0;
// Sets an initial delay for the playout jitter buffer. The playout of the
// audio is delayed by |delay_ms| in millisecond.
virtual int SetInitialPlayoutDelay(int channel, int delay_ms) = 0;
- // Gets the sum of the algorithmic delay, jitter buffer delay, and the
- // playout buffer delay for a specified |channel|.
- virtual int GetDelayEstimate(int channel, int& delayMs) = 0;
+ // Gets the |jitter_buffer_delay_ms| (including the algorithmic delay), and
+ // the |playout_buffer_delay_ms| for a specified |channel|.
+ virtual int GetDelayEstimate(int channel,
+ int* jitter_buffer_delay_ms,
+ int* playout_buffer_delay_ms) = 0;
// Manual initialization of the RTP timestamp.
virtual int SetInitTimestamp(int channel, unsigned int timestamp) = 0;
diff --git a/voice_engine/test/auto_test/standard/video_sync_test.cc b/voice_engine/test/auto_test/standard/video_sync_test.cc
index b8aedcdb..31e37191 100644
--- a/voice_engine/test/auto_test/standard/video_sync_test.cc
+++ b/voice_engine/test/auto_test/standard/video_sync_test.cc
@@ -31,14 +31,17 @@ class VideoSyncTest : public AfterStreamingFixture {
std::vector<int> all_delay_estimates;
for (int second = 0; second < 15; second++) {
- int delay_estimate = 0;
- EXPECT_EQ(0, voe_vsync_->GetDelayEstimate(channel_, delay_estimate));
+ int jitter_buffer_delay_ms = 0;
+ int playout_buffer_delay_ms = 0;
+ EXPECT_EQ(0, voe_vsync_->GetDelayEstimate(channel_,
+ &jitter_buffer_delay_ms,
+ &playout_buffer_delay_ms));
- EXPECT_GT(delay_estimate, min_estimate) <<
+ EXPECT_GT(jitter_buffer_delay_ms, min_estimate) <<
"The delay estimate can not conceivably get lower than " <<
min_estimate << " ms, it's unrealistic.";
- all_delay_estimates.push_back(delay_estimate);
+ all_delay_estimates.push_back(jitter_buffer_delay_ms);
Sleep(1000);
}
@@ -67,9 +70,10 @@ class VideoSyncTest : public AfterStreamingFixture {
}
};
-TEST_F(VideoSyncTest, CanGetPlayoutTimestampWhilePlayingWithoutSettingItFirst) {
+TEST_F(VideoSyncTest,
+ CanNotGetPlayoutTimestampWhilePlayingWithoutSettingItFirst) {
unsigned int ignored;
- EXPECT_EQ(0, voe_vsync_->GetPlayoutTimestamp(channel_, ignored));
+ EXPECT_EQ(-1, voe_vsync_->GetPlayoutTimestamp(channel_, ignored));
}
TEST_F(VideoSyncTest, CannotSetInitTimestampWhilePlaying) {
diff --git a/voice_engine/voe_video_sync_impl.cc b/voice_engine/voe_video_sync_impl.cc
index 4ef1228a..3796c5e0 100644
--- a/voice_engine/voe_video_sync_impl.cc
+++ b/voice_engine/voe_video_sync_impl.cc
@@ -164,26 +164,29 @@ int VoEVideoSyncImpl::SetInitialPlayoutDelay(int channel, int delay_ms)
return channel_ptr->SetInitialPlayoutDelay(delay_ms);
}
-int VoEVideoSyncImpl::GetDelayEstimate(int channel, int& delayMs)
-{
- WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
- "GetDelayEstimate(channel=%d, delayMs=?)", channel);
- IPHONE_NOT_SUPPORTED(_shared->statistics());
-
- if (!_shared->statistics().Initialized())
- {
- _shared->SetLastError(VE_NOT_INITED, kTraceError);
- return -1;
- }
- voe::ScopedChannel sc(_shared->channel_manager(), channel);
- voe::Channel* channelPtr = sc.ChannelPtr();
- if (channelPtr == NULL)
- {
- _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
- "GetDelayEstimate() failed to locate channel");
- return -1;
- }
- return channelPtr->GetDelayEstimate(delayMs);
+int VoEVideoSyncImpl::GetDelayEstimate(int channel,
+ int* jitter_buffer_delay_ms,
+ int* playout_buffer_delay_ms) {
+ WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+ "GetDelayEstimate(channel=%d, delayMs=?)", channel);
+ IPHONE_NOT_SUPPORTED(_shared->statistics());
+
+ if (!_shared->statistics().Initialized()) {
+ _shared->SetLastError(VE_NOT_INITED, kTraceError);
+ return -1;
+ }
+ voe::ScopedChannel sc(_shared->channel_manager(), channel);
+ voe::Channel* channelPtr = sc.ChannelPtr();
+ if (channelPtr == NULL) {
+ _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+ "GetDelayEstimate() failed to locate channel");
+ return -1;
+ }
+ if (!channelPtr->GetDelayEstimate(jitter_buffer_delay_ms,
+ playout_buffer_delay_ms)) {
+ return -1;
+ }
+ return 0;
}
int VoEVideoSyncImpl::GetPlayoutBufferSize(int& bufferMs)
diff --git a/voice_engine/voe_video_sync_impl.h b/voice_engine/voe_video_sync_impl.h
index 86ce75cd..fafefd10 100644
--- a/voice_engine/voe_video_sync_impl.h
+++ b/voice_engine/voe_video_sync_impl.h
@@ -26,7 +26,9 @@ public:
virtual int SetInitialPlayoutDelay(int channel, int delay_ms);
- virtual int GetDelayEstimate(int channel, int& delayMs);
+ virtual int GetDelayEstimate(int channel,
+ int* jitter_buffer_delay_ms,
+ int* playout_buffer_delay_ms);
virtual int SetInitTimestamp(int channel, unsigned int timestamp);