Make struct SynchronizationDelays more general.
Bug: none Change-Id: Iab263789cc8b51917acb3db2803fa71a927bc62a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161640 Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Commit-Queue: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30060}
This commit is contained in:
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include "video/stream_synchronization.h"
|
#include "video/stream_synchronization.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -36,7 +35,6 @@ bool StreamSynchronization::ComputeRelativeDelay(
|
|||||||
const Measurements& audio_measurement,
|
const Measurements& audio_measurement,
|
||||||
const Measurements& video_measurement,
|
const Measurements& video_measurement,
|
||||||
int* relative_delay_ms) {
|
int* relative_delay_ms) {
|
||||||
assert(relative_delay_ms);
|
|
||||||
int64_t audio_last_capture_time_ms;
|
int64_t audio_last_capture_time_ms;
|
||||||
if (!audio_measurement.rtp_to_ntp.Estimate(audio_measurement.latest_timestamp,
|
if (!audio_measurement.rtp_to_ntp.Estimate(audio_measurement.latest_timestamp,
|
||||||
&audio_last_capture_time_ms)) {
|
&audio_last_capture_time_ms)) {
|
||||||
@ -66,14 +64,14 @@ bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
|
|||||||
int current_audio_delay_ms,
|
int current_audio_delay_ms,
|
||||||
int* total_audio_delay_target_ms,
|
int* total_audio_delay_target_ms,
|
||||||
int* total_video_delay_target_ms) {
|
int* total_video_delay_target_ms) {
|
||||||
assert(total_audio_delay_target_ms && total_video_delay_target_ms);
|
|
||||||
|
|
||||||
int current_video_delay_ms = *total_video_delay_target_ms;
|
int current_video_delay_ms = *total_video_delay_target_ms;
|
||||||
|
|
||||||
RTC_LOG(LS_VERBOSE) << "Audio delay: " << current_audio_delay_ms
|
RTC_LOG(LS_VERBOSE) << "Audio delay: " << current_audio_delay_ms
|
||||||
<< " current diff: " << relative_delay_ms
|
<< " current diff: " << relative_delay_ms
|
||||||
<< " for stream " << audio_stream_id_;
|
<< " for stream " << audio_stream_id_;
|
||||||
// Calculate the difference between the lowest possible video delay and
|
|
||||||
// the current audio delay.
|
// Calculate the difference between the lowest possible video delay and the
|
||||||
|
// current audio delay.
|
||||||
int current_diff_ms =
|
int current_diff_ms =
|
||||||
current_video_delay_ms - current_audio_delay_ms + relative_delay_ms;
|
current_video_delay_ms - current_audio_delay_ms + relative_delay_ms;
|
||||||
|
|
||||||
@ -95,82 +93,77 @@ bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
|
|||||||
if (diff_ms > 0) {
|
if (diff_ms > 0) {
|
||||||
// The minimum video delay is longer than the current audio delay.
|
// The minimum video delay is longer than the current audio delay.
|
||||||
// We need to decrease extra video delay, or add extra audio delay.
|
// We need to decrease extra video delay, or add extra audio delay.
|
||||||
if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
|
if (video_delay_.extra_ms > base_target_delay_ms_) {
|
||||||
// We have extra delay added to ViE. Reduce this delay before adding
|
// We have extra delay added to ViE. Reduce this delay before adding
|
||||||
// extra delay to VoE.
|
// extra delay to VoE.
|
||||||
channel_delay_.extra_video_delay_ms -= diff_ms;
|
video_delay_.extra_ms -= diff_ms;
|
||||||
channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
|
audio_delay_.extra_ms = base_target_delay_ms_;
|
||||||
} else { // channel_delay_.extra_video_delay_ms > 0
|
} else { // video_delay_.extra_ms > 0
|
||||||
// We have no extra video delay to remove, increase the audio delay.
|
// We have no extra video delay to remove, increase the audio delay.
|
||||||
channel_delay_.extra_audio_delay_ms += diff_ms;
|
audio_delay_.extra_ms += diff_ms;
|
||||||
channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
|
video_delay_.extra_ms = base_target_delay_ms_;
|
||||||
}
|
}
|
||||||
} else { // if (diff_ms > 0)
|
} else { // if (diff_ms > 0)
|
||||||
// The video delay is lower than the current audio delay.
|
// The video delay is lower than the current audio delay.
|
||||||
// We need to decrease extra audio delay, or add extra video delay.
|
// We need to decrease extra audio delay, or add extra video delay.
|
||||||
if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
|
if (audio_delay_.extra_ms > base_target_delay_ms_) {
|
||||||
// We have extra delay in VoiceEngine.
|
// We have extra delay in VoiceEngine.
|
||||||
// Start with decreasing the voice delay.
|
// Start with decreasing the voice delay.
|
||||||
// Note: diff_ms is negative; add the negative difference.
|
// Note: diff_ms is negative; add the negative difference.
|
||||||
channel_delay_.extra_audio_delay_ms += diff_ms;
|
audio_delay_.extra_ms += diff_ms;
|
||||||
channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
|
video_delay_.extra_ms = base_target_delay_ms_;
|
||||||
} else { // channel_delay_.extra_audio_delay_ms > base_target_delay_ms_
|
} else { // audio_delay_.extra_ms > base_target_delay_ms_
|
||||||
// We have no extra delay in VoiceEngine, increase the video delay.
|
// We have no extra delay in VoiceEngine, increase the video delay.
|
||||||
// Note: diff_ms is negative; subtract the negative difference.
|
// Note: diff_ms is negative; subtract the negative difference.
|
||||||
channel_delay_.extra_video_delay_ms -= diff_ms; // X - (-Y) = X + Y.
|
video_delay_.extra_ms -= diff_ms; // X - (-Y) = X + Y.
|
||||||
channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
|
audio_delay_.extra_ms = base_target_delay_ms_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that video is never below our target.
|
// Make sure that video is never below our target.
|
||||||
channel_delay_.extra_video_delay_ms =
|
video_delay_.extra_ms =
|
||||||
std::max(channel_delay_.extra_video_delay_ms, base_target_delay_ms_);
|
std::max(video_delay_.extra_ms, base_target_delay_ms_);
|
||||||
|
|
||||||
int new_video_delay_ms;
|
int new_video_delay_ms;
|
||||||
if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
|
if (video_delay_.extra_ms > base_target_delay_ms_) {
|
||||||
new_video_delay_ms = channel_delay_.extra_video_delay_ms;
|
new_video_delay_ms = video_delay_.extra_ms;
|
||||||
} else {
|
} else {
|
||||||
// No change to the extra video delay. We are changing audio and we only
|
// No change to the extra video delay. We are changing audio and we only
|
||||||
// allow to change one at the time.
|
// allow to change one at the time.
|
||||||
new_video_delay_ms = channel_delay_.last_video_delay_ms;
|
new_video_delay_ms = video_delay_.last_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that we don't go below the extra video delay.
|
// Make sure that we don't go below the extra video delay.
|
||||||
new_video_delay_ms =
|
new_video_delay_ms = std::max(new_video_delay_ms, video_delay_.extra_ms);
|
||||||
std::max(new_video_delay_ms, channel_delay_.extra_video_delay_ms);
|
|
||||||
|
|
||||||
// Verify we don't go above the maximum allowed video delay.
|
// Verify we don't go above the maximum allowed video delay.
|
||||||
new_video_delay_ms =
|
new_video_delay_ms =
|
||||||
std::min(new_video_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
|
std::min(new_video_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
|
||||||
|
|
||||||
int new_audio_delay_ms;
|
int new_audio_delay_ms;
|
||||||
if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
|
if (audio_delay_.extra_ms > base_target_delay_ms_) {
|
||||||
new_audio_delay_ms = channel_delay_.extra_audio_delay_ms;
|
new_audio_delay_ms = audio_delay_.extra_ms;
|
||||||
} else {
|
} else {
|
||||||
// No change to the audio delay. We are changing video and we only
|
// No change to the audio delay. We are changing video and we only allow to
|
||||||
// allow to change one at the time.
|
// change one at the time.
|
||||||
new_audio_delay_ms = channel_delay_.last_audio_delay_ms;
|
new_audio_delay_ms = audio_delay_.last_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that we don't go below the extra audio delay.
|
// Make sure that we don't go below the extra audio delay.
|
||||||
new_audio_delay_ms =
|
new_audio_delay_ms = std::max(new_audio_delay_ms, audio_delay_.extra_ms);
|
||||||
std::max(new_audio_delay_ms, channel_delay_.extra_audio_delay_ms);
|
|
||||||
|
|
||||||
// Verify we don't go above the maximum allowed audio delay.
|
// Verify we don't go above the maximum allowed audio delay.
|
||||||
new_audio_delay_ms =
|
new_audio_delay_ms =
|
||||||
std::min(new_audio_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
|
std::min(new_audio_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
|
||||||
|
|
||||||
// Remember our last audio and video delays.
|
video_delay_.last_ms = new_video_delay_ms;
|
||||||
channel_delay_.last_video_delay_ms = new_video_delay_ms;
|
audio_delay_.last_ms = new_audio_delay_ms;
|
||||||
channel_delay_.last_audio_delay_ms = new_audio_delay_ms;
|
|
||||||
|
|
||||||
RTC_LOG(LS_VERBOSE) << "Sync video delay " << new_video_delay_ms
|
RTC_LOG(LS_VERBOSE) << "Sync video delay " << new_video_delay_ms
|
||||||
<< " for video stream " << video_stream_id_
|
<< " for video stream " << video_stream_id_
|
||||||
<< " and audio delay "
|
<< " and audio delay " << audio_delay_.extra_ms
|
||||||
<< channel_delay_.extra_audio_delay_ms
|
|
||||||
<< " for audio stream " << audio_stream_id_;
|
<< " for audio stream " << audio_stream_id_;
|
||||||
|
|
||||||
// Return values.
|
|
||||||
*total_video_delay_target_ms = new_video_delay_ms;
|
*total_video_delay_target_ms = new_video_delay_ms;
|
||||||
*total_audio_delay_target_ms = new_audio_delay_ms;
|
*total_audio_delay_target_ms = new_audio_delay_ms;
|
||||||
return true;
|
return true;
|
||||||
@ -178,16 +171,14 @@ bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
|
|||||||
|
|
||||||
void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) {
|
void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) {
|
||||||
// Initial extra delay for audio (accounting for existing extra delay).
|
// Initial extra delay for audio (accounting for existing extra delay).
|
||||||
channel_delay_.extra_audio_delay_ms +=
|
audio_delay_.extra_ms += target_delay_ms - base_target_delay_ms_;
|
||||||
target_delay_ms - base_target_delay_ms_;
|
audio_delay_.last_ms += target_delay_ms - base_target_delay_ms_;
|
||||||
channel_delay_.last_audio_delay_ms += target_delay_ms - base_target_delay_ms_;
|
|
||||||
|
|
||||||
// The video delay is compared to the last value (and how much we can update
|
// The video delay is compared to the last value (and how much we can update
|
||||||
// is limited by that as well).
|
// is limited by that as well).
|
||||||
channel_delay_.last_video_delay_ms += target_delay_ms - base_target_delay_ms_;
|
video_delay_.last_ms += target_delay_ms - base_target_delay_ms_;
|
||||||
|
|
||||||
channel_delay_.extra_video_delay_ms +=
|
video_delay_.extra_ms += target_delay_ms - base_target_delay_ms_;
|
||||||
target_delay_ms - base_target_delay_ms_;
|
|
||||||
|
|
||||||
// Video is already delayed by the desired amount.
|
// Video is already delayed by the desired amount.
|
||||||
base_target_delay_ms_ = target_delay_ms;
|
base_target_delay_ms_ = target_delay_ms;
|
||||||
|
@ -30,28 +30,28 @@ class StreamSynchronization {
|
|||||||
|
|
||||||
bool ComputeDelays(int relative_delay_ms,
|
bool ComputeDelays(int relative_delay_ms,
|
||||||
int current_audio_delay_ms,
|
int current_audio_delay_ms,
|
||||||
int* extra_audio_delay_ms,
|
int* total_audio_delay_target_ms,
|
||||||
int* total_video_delay_target_ms);
|
int* total_video_delay_target_ms);
|
||||||
|
|
||||||
// On success |relative_delay| contains the number of milliseconds later video
|
// On success |relative_delay_ms| contains the number of milliseconds later
|
||||||
// is rendered relative audio. If audio is played back later than video a
|
// video is rendered relative audio. If audio is played back later than video
|
||||||
// |relative_delay| will be negative.
|
// |relative_delay_ms| will be negative.
|
||||||
static bool ComputeRelativeDelay(const Measurements& audio_measurement,
|
static bool ComputeRelativeDelay(const Measurements& audio_measurement,
|
||||||
const Measurements& video_measurement,
|
const Measurements& video_measurement,
|
||||||
int* relative_delay_ms);
|
int* relative_delay_ms);
|
||||||
// Set target buffering delay - All audio and video will be delayed by at
|
|
||||||
// least target_delay_ms.
|
// Set target buffering delay. Audio and video will be delayed by at least
|
||||||
|
// |target_delay_ms|.
|
||||||
void SetTargetBufferingDelay(int target_delay_ms);
|
void SetTargetBufferingDelay(int target_delay_ms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SynchronizationDelays {
|
struct SynchronizationDelays {
|
||||||
int extra_video_delay_ms = 0;
|
int extra_ms = 0;
|
||||||
int last_video_delay_ms = 0;
|
int last_ms = 0;
|
||||||
int extra_audio_delay_ms = 0;
|
|
||||||
int last_audio_delay_ms = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SynchronizationDelays channel_delay_;
|
SynchronizationDelays audio_delay_;
|
||||||
|
SynchronizationDelays video_delay_;
|
||||||
const int video_stream_id_;
|
const int video_stream_id_;
|
||||||
const int audio_stream_id_;
|
const int audio_stream_id_;
|
||||||
int base_target_delay_ms_;
|
int base_target_delay_ms_;
|
||||||
|
Reference in New Issue
Block a user