Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: webrtc/video/rtp_streams_synchronizer.cc

Issue 2452163004: Stop using VoEVideoSync in Call/VideoReceiveStream. (Closed)
Patch Set: Don't expose RtpRtcp module in Syncable Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/video/rtp_streams_synchronizer.h" 11 #include "webrtc/video/rtp_streams_synchronizer.h"
12 12
13 #include "webrtc/base/checks.h" 13 #include "webrtc/base/checks.h"
14 #include "webrtc/base/logging.h" 14 #include "webrtc/base/logging.h"
15 #include "webrtc/base/timeutils.h" 15 #include "webrtc/base/timeutils.h"
16 #include "webrtc/base/trace_event.h" 16 #include "webrtc/base/trace_event.h"
17 #include "webrtc/call/syncable.h"
17 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" 18 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
18 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 19 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
19 #include "webrtc/modules/video_coding/video_coding_impl.h" 20 #include "webrtc/modules/video_coding/video_coding_impl.h"
20 #include "webrtc/system_wrappers/include/clock.h" 21 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/video/stream_synchronization.h" 22 #include "webrtc/video/stream_synchronization.h"
22 #include "webrtc/video_frame.h" 23 #include "webrtc/video_frame.h"
23 #include "webrtc/voice_engine/include/voe_video_sync.h"
24 24
25 namespace webrtc { 25 namespace webrtc {
26 namespace { 26 namespace {
27 bool UpdateMeasurements(StreamSynchronization::Measurements* stream, 27 bool UpdateVideoMeasurements(StreamSynchronization::Measurements* stream,
28 RtpRtcp* rtp_rtcp, 28 RtpRtcp* rtp_rtcp,
stefan-webrtc 2017/01/19 11:59:59 git cl format
29 RtpReceiver* receiver) { 29 RtpReceiver* receiver) {
30 if (!receiver->Timestamp(&stream->latest_timestamp)) 30 if (!receiver->Timestamp(&stream->latest_timestamp))
31 return false; 31 return false;
32 if (!receiver->LastReceivedTimeMs(&stream->latest_receive_time_ms)) 32 if (!receiver->LastReceivedTimeMs(&stream->latest_receive_time_ms))
33 return false; 33 return false;
34 34
35 uint32_t ntp_secs = 0; 35 uint32_t ntp_secs = 0;
36 uint32_t ntp_frac = 0; 36 uint32_t ntp_frac = 0;
37 uint32_t rtp_timestamp = 0; 37 uint32_t rtp_timestamp = 0;
38 if (rtp_rtcp->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr, 38 if (rtp_rtcp->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
39 &rtp_timestamp) != 0) { 39 &rtp_timestamp) != 0) {
40 return false; 40 return false;
41 } 41 }
42 42
43 bool new_rtcp_sr = false; 43 bool new_rtcp_sr = false;
44 if (!stream->rtp_to_ntp.UpdateMeasurements(ntp_secs, ntp_frac, rtp_timestamp, 44 if (!stream->rtp_to_ntp.UpdateMeasurements(ntp_secs, ntp_frac, rtp_timestamp,
45 &new_rtcp_sr)) { 45 &new_rtcp_sr)) {
46 return false; 46 return false;
47 } 47 }
48 48
49 return true; 49 return true;
50 } 50 }
51
52 bool UpdateAudioMeasurements(StreamSynchronization::Measurements* stream,
53 const Syncable::Info& info) {
54 RTC_DCHECK(stream);
55 stream->latest_timestamp = info.latest_timestamp;
56 stream->latest_receive_time_ms = info.latest_receive_time_ms;
57 bool new_rtcp_sr = false;
58 if (!stream->rtp_to_ntp.UpdateMeasurements(info.ntp_secs, info.ntp_frac,
59 info.rtp_timestamp,
60 &new_rtcp_sr)) {
61 return false;
62 }
63 return true;
64 }
51 } // namespace 65 } // namespace
52 66
53 RtpStreamsSynchronizer::RtpStreamsSynchronizer( 67 RtpStreamsSynchronizer::RtpStreamsSynchronizer(
54 vcm::VideoReceiver* video_receiver, 68 vcm::VideoReceiver* video_receiver,
55 RtpStreamReceiver* rtp_stream_receiver) 69 RtpStreamReceiver* rtp_stream_receiver)
56 : clock_(Clock::GetRealTimeClock()), 70 : clock_(Clock::GetRealTimeClock()),
57 video_receiver_(video_receiver), 71 video_receiver_(video_receiver),
58 video_rtp_receiver_(rtp_stream_receiver->GetRtpReceiver()), 72 video_rtp_receiver_(rtp_stream_receiver->GetRtpReceiver()),
59 video_rtp_rtcp_(rtp_stream_receiver->rtp_rtcp()), 73 video_rtp_rtcp_(rtp_stream_receiver->rtp_rtcp()),
60 voe_channel_id_(-1), 74 syncable_(nullptr),
61 voe_sync_interface_(nullptr),
62 audio_rtp_receiver_(nullptr),
63 audio_rtp_rtcp_(nullptr),
64 sync_(), 75 sync_(),
65 last_sync_time_(rtc::TimeNanos()) { 76 last_sync_time_(rtc::TimeNanos()) {
66 process_thread_checker_.DetachFromThread(); 77 process_thread_checker_.DetachFromThread();
67 } 78 }
68 79
69 void RtpStreamsSynchronizer::ConfigureSync(int voe_channel_id, 80 void RtpStreamsSynchronizer::ConfigureSync(Syncable* syncable) {
70 VoEVideoSync* voe_sync_interface) {
71 if (voe_channel_id != -1)
72 RTC_DCHECK(voe_sync_interface);
73
74 rtc::CritScope lock(&crit_); 81 rtc::CritScope lock(&crit_);
75 if (voe_channel_id_ == voe_channel_id && 82 if (syncable == syncable_) {
76 voe_sync_interface_ == voe_sync_interface) {
77 // This prevents expensive no-ops. 83 // This prevents expensive no-ops.
78 return; 84 return;
79 } 85 }
80 voe_channel_id_ = voe_channel_id;
81 voe_sync_interface_ = voe_sync_interface;
82 86
83 audio_rtp_rtcp_ = nullptr; 87 syncable_ = syncable;
84 audio_rtp_receiver_ = nullptr;
85 sync_.reset(nullptr); 88 sync_.reset(nullptr);
86 89 if (syncable_) {
87 if (voe_channel_id_ != -1) {
88 voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &audio_rtp_rtcp_,
89 &audio_rtp_receiver_);
90 RTC_DCHECK(audio_rtp_rtcp_);
91 RTC_DCHECK(audio_rtp_receiver_);
92 sync_.reset(new StreamSynchronization(video_rtp_rtcp_->SSRC(), 90 sync_.reset(new StreamSynchronization(video_rtp_rtcp_->SSRC(),
93 voe_channel_id_)); 91 syncable_->id()));
94 } 92 }
95 } 93 }
96 94
97 int64_t RtpStreamsSynchronizer::TimeUntilNextProcess() { 95 int64_t RtpStreamsSynchronizer::TimeUntilNextProcess() {
98 RTC_DCHECK_RUN_ON(&process_thread_checker_); 96 RTC_DCHECK_RUN_ON(&process_thread_checker_);
99 const int64_t kSyncIntervalMs = 1000; 97 const int64_t kSyncIntervalMs = 1000;
100 return kSyncIntervalMs - 98 return kSyncIntervalMs -
101 (rtc::TimeNanos() - last_sync_time_) / rtc::kNumNanosecsPerMillisec; 99 (rtc::TimeNanos() - last_sync_time_) / rtc::kNumNanosecsPerMillisec;
102 } 100 }
103 101
104 void RtpStreamsSynchronizer::Process() { 102 void RtpStreamsSynchronizer::Process() {
105 RTC_DCHECK_RUN_ON(&process_thread_checker_); 103 RTC_DCHECK_RUN_ON(&process_thread_checker_);
106 104
107 const int current_video_delay_ms = video_receiver_->Delay(); 105 const int current_video_delay_ms = video_receiver_->Delay();
108 last_sync_time_ = rtc::TimeNanos(); 106 last_sync_time_ = rtc::TimeNanos();
109 107
110 rtc::CritScope lock(&crit_); 108 rtc::CritScope lock(&crit_);
111 if (voe_channel_id_ == -1) { 109 if (!syncable_) {
112 return; 110 return;
113 } 111 }
114 RTC_DCHECK(voe_sync_interface_);
115 RTC_DCHECK(sync_.get()); 112 RTC_DCHECK(sync_.get());
116 113
117 int audio_jitter_buffer_delay_ms = 0; 114 rtc::Optional<Syncable::Info> audio_sync_info = syncable_->GetInfo();
118 int playout_buffer_delay_ms = 0; 115 if (!audio_sync_info) {
119 if (voe_sync_interface_->GetDelayEstimate(voe_channel_id_,
120 &audio_jitter_buffer_delay_ms,
121 &playout_buffer_delay_ms) != 0) {
122 return; 116 return;
123 } 117 }
124 const int current_audio_delay_ms = audio_jitter_buffer_delay_ms + 118 if (!UpdateAudioMeasurements(&audio_measurement_, *audio_sync_info)) {
125 playout_buffer_delay_ms;
126
127 int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms;
128 if (!UpdateMeasurements(&video_measurement_, video_rtp_rtcp_,
129 video_rtp_receiver_)) {
130 return; 119 return;
131 } 120 }
132 121
133 if (!UpdateMeasurements(&audio_measurement_, audio_rtp_rtcp_, 122 int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms;
134 audio_rtp_receiver_)) { 123 if (!UpdateVideoMeasurements(&video_measurement_, video_rtp_rtcp_,
124 video_rtp_receiver_)) {
135 return; 125 return;
136 } 126 }
137 127
138 if (last_video_receive_ms == video_measurement_.latest_receive_time_ms) { 128 if (last_video_receive_ms == video_measurement_.latest_receive_time_ms) {
139 // No new video packet has been received since last update. 129 // No new video packet has been received since last update.
140 return; 130 return;
141 } 131 }
142 132
143 int relative_delay_ms; 133 int relative_delay_ms;
144 // Calculate how much later or earlier the audio stream is compared to video. 134 // Calculate how much later or earlier the audio stream is compared to video.
145 if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_, 135 if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_,
146 &relative_delay_ms)) { 136 &relative_delay_ms)) {
147 return; 137 return;
148 } 138 }
149 139
150 TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", current_video_delay_ms); 140 TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", current_video_delay_ms);
151 TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay", current_audio_delay_ms); 141 TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay",
142 audio_sync_info->current_delay_ms);
152 TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms); 143 TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms);
153 int target_audio_delay_ms = 0; 144 int target_audio_delay_ms = 0;
154 int target_video_delay_ms = current_video_delay_ms; 145 int target_video_delay_ms = current_video_delay_ms;
155 // Calculate the necessary extra audio delay and desired total video 146 // Calculate the necessary extra audio delay and desired total video
156 // delay to get the streams in sync. 147 // delay to get the streams in sync.
157 if (!sync_->ComputeDelays(relative_delay_ms, 148 if (!sync_->ComputeDelays(relative_delay_ms,
158 current_audio_delay_ms, 149 audio_sync_info->current_delay_ms,
159 &target_audio_delay_ms, 150 &target_audio_delay_ms,
160 &target_video_delay_ms)) { 151 &target_video_delay_ms)) {
161 return; 152 return;
162 } 153 }
163 154
164 if (voe_sync_interface_->SetMinimumPlayoutDelay( 155 syncable_->SetMinimumPlayoutDelay(target_audio_delay_ms);
165 voe_channel_id_, target_audio_delay_ms) == -1) {
166 LOG(LS_ERROR) << "Error setting voice delay.";
167 }
168 video_receiver_->SetMinimumPlayoutDelay(target_video_delay_ms); 156 video_receiver_->SetMinimumPlayoutDelay(target_video_delay_ms);
169 } 157 }
170 158
171 bool RtpStreamsSynchronizer::GetStreamSyncOffsetInMs( 159 bool RtpStreamsSynchronizer::GetStreamSyncOffsetInMs(
172 const VideoFrame& frame, 160 const VideoFrame& frame,
173 int64_t* stream_offset_ms, 161 int64_t* stream_offset_ms,
174 double* estimated_freq_khz) const { 162 double* estimated_freq_khz) const {
175 rtc::CritScope lock(&crit_); 163 rtc::CritScope lock(&crit_);
176 if (voe_channel_id_ == -1) 164 if (!syncable_) {
177 return false;
178
179 uint32_t playout_timestamp = 0;
180 if (voe_sync_interface_->GetPlayoutTimestamp(voe_channel_id_,
181 playout_timestamp) != 0) {
182 return false; 165 return false;
183 } 166 }
184 167
168 uint32_t playout_timestamp = syncable_->GetPlayoutTimestamp();
169
185 int64_t latest_audio_ntp; 170 int64_t latest_audio_ntp;
186 if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp, 171 if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp,
187 &latest_audio_ntp)) { 172 &latest_audio_ntp)) {
188 return false; 173 return false;
189 } 174 }
190 175
191 int64_t latest_video_ntp; 176 int64_t latest_video_ntp;
192 if (!video_measurement_.rtp_to_ntp.Estimate(frame.timestamp(), 177 if (!video_measurement_.rtp_to_ntp.Estimate(frame.timestamp(),
193 &latest_video_ntp)) { 178 &latest_video_ntp)) {
194 return false; 179 return false;
195 } 180 }
196 181
197 int64_t time_to_render_ms = 182 int64_t time_to_render_ms =
198 frame.render_time_ms() - clock_->TimeInMilliseconds(); 183 frame.render_time_ms() - clock_->TimeInMilliseconds();
199 if (time_to_render_ms > 0) 184 if (time_to_render_ms > 0)
200 latest_video_ntp += time_to_render_ms; 185 latest_video_ntp += time_to_render_ms;
201 186
202 *stream_offset_ms = latest_audio_ntp - latest_video_ntp; 187 *stream_offset_ms = latest_audio_ntp - latest_video_ntp;
203 *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz; 188 *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz;
204 return true; 189 return true;
205 } 190 }
206 191
207 } // namespace webrtc 192 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698