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

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

Issue 2452163004: Stop using VoEVideoSync in Call/VideoReceiveStream. (Closed)
Patch Set: comment Created 3 years, 10 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
« no previous file with comments | « webrtc/video/rtp_streams_synchronizer.h ('k') | webrtc/video/stream_synchronization.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/modules/rtp_rtcp/include/rtp_receiver.h" 17 #include "webrtc/call/syncable.h"
18 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
19 #include "webrtc/modules/video_coding/video_coding_impl.h" 18 #include "webrtc/modules/video_coding/video_coding_impl.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/video/stream_synchronization.h"
22 #include "webrtc/video_frame.h"
23 #include "webrtc/voice_engine/include/voe_video_sync.h"
24 19
25 namespace webrtc { 20 namespace webrtc {
26 namespace { 21 namespace {
27 bool UpdateMeasurements(StreamSynchronization::Measurements* stream, 22 bool UpdateMeasurements(StreamSynchronization::Measurements* stream,
28 RtpRtcp* rtp_rtcp, 23 const Syncable::Info& info) {
29 RtpReceiver* receiver) { 24 RTC_DCHECK(stream);
30 if (!receiver->Timestamp(&stream->latest_timestamp)) 25 stream->latest_timestamp = info.latest_received_capture_timestamp;
31 return false; 26 stream->latest_receive_time_ms = info.latest_receive_time_ms;
32 if (!receiver->LastReceivedTimeMs(&stream->latest_receive_time_ms))
33 return false;
34
35 uint32_t ntp_secs = 0;
36 uint32_t ntp_frac = 0;
37 uint32_t rtp_timestamp = 0;
38 if (rtp_rtcp->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
39 &rtp_timestamp) != 0) {
40 return false;
41 }
42
43 bool new_rtcp_sr = false; 27 bool new_rtcp_sr = false;
44 if (!stream->rtp_to_ntp.UpdateMeasurements(ntp_secs, ntp_frac, rtp_timestamp, 28 if (!stream->rtp_to_ntp.UpdateMeasurements(info.capture_time_ntp_secs,
29 info.capture_time_ntp_frac,
30 info.capture_time_source_clock,
45 &new_rtcp_sr)) { 31 &new_rtcp_sr)) {
46 return false; 32 return false;
47 } 33 }
48
49 return true; 34 return true;
50 } 35 }
51 } // namespace 36 } // namespace
52 37
53 RtpStreamsSynchronizer::RtpStreamsSynchronizer( 38 RtpStreamsSynchronizer::RtpStreamsSynchronizer(Syncable* syncable_video)
54 vcm::VideoReceiver* video_receiver, 39 : syncable_video_(syncable_video),
55 RtpStreamReceiver* rtp_stream_receiver) 40 syncable_audio_(nullptr),
56 : clock_(Clock::GetRealTimeClock()),
57 video_receiver_(video_receiver),
58 video_rtp_receiver_(rtp_stream_receiver->GetRtpReceiver()),
59 video_rtp_rtcp_(rtp_stream_receiver->rtp_rtcp()),
60 voe_channel_id_(-1),
61 voe_sync_interface_(nullptr),
62 audio_rtp_receiver_(nullptr),
63 audio_rtp_rtcp_(nullptr),
64 sync_(), 41 sync_(),
65 last_sync_time_(rtc::TimeNanos()) { 42 last_sync_time_(rtc::TimeNanos()) {
43 RTC_DCHECK(syncable_video);
66 process_thread_checker_.DetachFromThread(); 44 process_thread_checker_.DetachFromThread();
67 } 45 }
68 46
69 void RtpStreamsSynchronizer::ConfigureSync(int voe_channel_id, 47 void RtpStreamsSynchronizer::ConfigureSync(Syncable* syncable_audio) {
70 VoEVideoSync* voe_sync_interface) {
71 if (voe_channel_id != -1)
72 RTC_DCHECK(voe_sync_interface);
73
74 rtc::CritScope lock(&crit_); 48 rtc::CritScope lock(&crit_);
75 if (voe_channel_id_ == voe_channel_id && 49 if (syncable_audio == syncable_audio_) {
76 voe_sync_interface_ == voe_sync_interface) {
77 // This prevents expensive no-ops. 50 // This prevents expensive no-ops.
78 return; 51 return;
79 } 52 }
80 voe_channel_id_ = voe_channel_id;
81 voe_sync_interface_ = voe_sync_interface;
82 53
83 audio_rtp_rtcp_ = nullptr; 54 syncable_audio_ = syncable_audio;
84 audio_rtp_receiver_ = nullptr;
85 sync_.reset(nullptr); 55 sync_.reset(nullptr);
86 56 if (syncable_audio_) {
87 if (voe_channel_id_ != -1) { 57 sync_.reset(new StreamSynchronization(syncable_video_->id(),
88 voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &audio_rtp_rtcp_, 58 syncable_audio_->id()));
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(),
93 voe_channel_id_));
94 } 59 }
95 } 60 }
96 61
97 int64_t RtpStreamsSynchronizer::TimeUntilNextProcess() { 62 int64_t RtpStreamsSynchronizer::TimeUntilNextProcess() {
98 RTC_DCHECK_RUN_ON(&process_thread_checker_); 63 RTC_DCHECK_RUN_ON(&process_thread_checker_);
99 const int64_t kSyncIntervalMs = 1000; 64 const int64_t kSyncIntervalMs = 1000;
100 return kSyncIntervalMs - 65 return kSyncIntervalMs -
101 (rtc::TimeNanos() - last_sync_time_) / rtc::kNumNanosecsPerMillisec; 66 (rtc::TimeNanos() - last_sync_time_) / rtc::kNumNanosecsPerMillisec;
102 } 67 }
103 68
104 void RtpStreamsSynchronizer::Process() { 69 void RtpStreamsSynchronizer::Process() {
105 RTC_DCHECK_RUN_ON(&process_thread_checker_); 70 RTC_DCHECK_RUN_ON(&process_thread_checker_);
106
107 const int current_video_delay_ms = video_receiver_->Delay();
108 last_sync_time_ = rtc::TimeNanos(); 71 last_sync_time_ = rtc::TimeNanos();
109 72
110 rtc::CritScope lock(&crit_); 73 rtc::CritScope lock(&crit_);
111 if (voe_channel_id_ == -1) { 74 if (!syncable_audio_) {
112 return; 75 return;
113 } 76 }
114 RTC_DCHECK(voe_sync_interface_);
115 RTC_DCHECK(sync_.get()); 77 RTC_DCHECK(sync_.get());
116 78
117 int audio_jitter_buffer_delay_ms = 0; 79 rtc::Optional<Syncable::Info> audio_info = syncable_audio_->GetInfo();
118 int playout_buffer_delay_ms = 0; 80 if (!audio_info || !UpdateMeasurements(&audio_measurement_, *audio_info)) {
119 if (voe_sync_interface_->GetDelayEstimate(voe_channel_id_,
120 &audio_jitter_buffer_delay_ms,
121 &playout_buffer_delay_ms) != 0) {
122 return;
123 }
124 const int current_audio_delay_ms = audio_jitter_buffer_delay_ms +
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; 81 return;
131 } 82 }
132 83
133 if (!UpdateMeasurements(&audio_measurement_, audio_rtp_rtcp_, 84 int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms;
134 audio_rtp_receiver_)) { 85 rtc::Optional<Syncable::Info> video_info = syncable_video_->GetInfo();
86 if (!video_info || !UpdateMeasurements(&video_measurement_, *video_info)) {
135 return; 87 return;
136 } 88 }
137 89
138 if (last_video_receive_ms == video_measurement_.latest_receive_time_ms) { 90 if (last_video_receive_ms == video_measurement_.latest_receive_time_ms) {
139 // No new video packet has been received since last update. 91 // No new video packet has been received since last update.
140 return; 92 return;
141 } 93 }
142 94
143 int relative_delay_ms; 95 int relative_delay_ms;
144 // Calculate how much later or earlier the audio stream is compared to video. 96 // Calculate how much later or earlier the audio stream is compared to video.
145 if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_, 97 if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_,
146 &relative_delay_ms)) { 98 &relative_delay_ms)) {
147 return; 99 return;
148 } 100 }
149 101
150 TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", current_video_delay_ms); 102 TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay",
151 TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay", current_audio_delay_ms); 103 video_info->current_delay_ms);
104 TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay",
105 audio_info->current_delay_ms);
152 TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms); 106 TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms);
153 int target_audio_delay_ms = 0; 107 int target_audio_delay_ms = 0;
154 int target_video_delay_ms = current_video_delay_ms; 108 int target_video_delay_ms = video_info->current_delay_ms;
155 // Calculate the necessary extra audio delay and desired total video 109 // Calculate the necessary extra audio delay and desired total video
156 // delay to get the streams in sync. 110 // delay to get the streams in sync.
157 if (!sync_->ComputeDelays(relative_delay_ms, 111 if (!sync_->ComputeDelays(relative_delay_ms,
158 current_audio_delay_ms, 112 audio_info->current_delay_ms,
159 &target_audio_delay_ms, 113 &target_audio_delay_ms,
160 &target_video_delay_ms)) { 114 &target_video_delay_ms)) {
161 return; 115 return;
162 } 116 }
163 117
164 if (voe_sync_interface_->SetMinimumPlayoutDelay( 118 syncable_audio_->SetMinimumPlayoutDelay(target_audio_delay_ms);
165 voe_channel_id_, target_audio_delay_ms) == -1) { 119 syncable_video_->SetMinimumPlayoutDelay(target_video_delay_ms);
166 LOG(LS_ERROR) << "Error setting voice delay.";
167 }
168 video_receiver_->SetMinimumPlayoutDelay(target_video_delay_ms);
169 } 120 }
170 121
171 bool RtpStreamsSynchronizer::GetStreamSyncOffsetInMs( 122 bool RtpStreamsSynchronizer::GetStreamSyncOffsetInMs(
172 const VideoFrame& frame, 123 uint32_t timestamp,
124 int64_t render_time_ms,
173 int64_t* stream_offset_ms, 125 int64_t* stream_offset_ms,
174 double* estimated_freq_khz) const { 126 double* estimated_freq_khz) const {
175 rtc::CritScope lock(&crit_); 127 rtc::CritScope lock(&crit_);
176 if (voe_channel_id_ == -1) 128 if (!syncable_audio_) {
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; 129 return false;
183 } 130 }
184 131
132 uint32_t playout_timestamp = syncable_audio_->GetPlayoutTimestamp();
133
185 int64_t latest_audio_ntp; 134 int64_t latest_audio_ntp;
186 if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp, 135 if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp,
187 &latest_audio_ntp)) { 136 &latest_audio_ntp)) {
188 return false; 137 return false;
189 } 138 }
190 139
191 int64_t latest_video_ntp; 140 int64_t latest_video_ntp;
192 if (!video_measurement_.rtp_to_ntp.Estimate(frame.timestamp(), 141 if (!video_measurement_.rtp_to_ntp.Estimate(timestamp, &latest_video_ntp)) {
193 &latest_video_ntp)) {
194 return false; 142 return false;
195 } 143 }
196 144
197 int64_t time_to_render_ms = 145 int64_t time_to_render_ms = render_time_ms - rtc::TimeMillis();
198 frame.render_time_ms() - clock_->TimeInMilliseconds();
199 if (time_to_render_ms > 0) 146 if (time_to_render_ms > 0)
200 latest_video_ntp += time_to_render_ms; 147 latest_video_ntp += time_to_render_ms;
201 148
202 *stream_offset_ms = latest_audio_ntp - latest_video_ntp; 149 *stream_offset_ms = latest_audio_ntp - latest_video_ntp;
203 *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz; 150 *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz;
204 return true; 151 return true;
205 } 152 }
206 153
207 } // namespace webrtc 154 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/rtp_streams_synchronizer.h ('k') | webrtc/video/stream_synchronization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698