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

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

Issue 2071473002: Reland of Split IncomingVideoStream into two implementations, with smoothing and without. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: add explicit Created 4 years, 6 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/video_receive_stream.h ('k') | webrtc/video/video_stream_decoder.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) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 codec.width = 320; 137 codec.width = 320;
138 codec.height = 180; 138 codec.height = 180;
139 codec.startBitrate = codec.minBitrate = codec.maxBitrate = 139 codec.startBitrate = codec.minBitrate = codec.maxBitrate =
140 Call::Config::kDefaultStartBitrateBps / 1000; 140 Call::Config::kDefaultStartBitrateBps / 1000;
141 141
142 return codec; 142 return codec;
143 } 143 }
144 } // namespace 144 } // namespace
145 145
146 namespace internal { 146 namespace internal {
147
148 // Since an IncomingVideoStream instance will create a thread/queue, we don't
149 // instantiate one unless we know we're going to be delivering the frames
150 // to a renderer.
151 //
152 // TODO(tommi): Consider making the functionality provided by the
153 // IncomingVideoStream classes, tied to the Config class instead or even higher
154 // level. That will make it an optional feature that will be up to the
155 // application to use or not use. Right now, we have two classes available,
156 // they both have threads involved which uses WebRTC's threading classes and
157 // that might not suit what the application wants to do. If one of them or
158 // neither, suits, the app can get some code size back as well as more control.
159 std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>
160 MaybeCreateIncomingVideoStream(const VideoReceiveStream::Config& config,
161 rtc::VideoSinkInterface<VideoFrame>* callback) {
162 std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> ret;
163 if (config.renderer) {
164 if (config.disable_prerenderer_smoothing) {
165 ret.reset(new IncomingVideoStreamNoSmoothing(callback));
166 } else {
167 ret.reset(new IncomingVideoStream(config.render_delay_ms, callback));
168 }
169 }
170 return ret;
171 }
172
147 VideoReceiveStream::VideoReceiveStream( 173 VideoReceiveStream::VideoReceiveStream(
148 int num_cpu_cores, 174 int num_cpu_cores,
149 CongestionController* congestion_controller, 175 CongestionController* congestion_controller,
150 VideoReceiveStream::Config config, 176 VideoReceiveStream::Config config,
151 webrtc::VoiceEngine* voice_engine, 177 webrtc::VoiceEngine* voice_engine,
152 ProcessThread* process_thread, 178 ProcessThread* process_thread,
153 CallStats* call_stats, 179 CallStats* call_stats,
154 VieRemb* remb) 180 VieRemb* remb)
155 : transport_adapter_(config.rtcp_send_transport), 181 : transport_adapter_(config.rtcp_send_transport),
156 config_(std::move(config)), 182 config_(std::move(config)),
157 process_thread_(process_thread), 183 process_thread_(process_thread),
158 clock_(Clock::GetRealTimeClock()), 184 clock_(Clock::GetRealTimeClock()),
159 decode_thread_(DecodeThreadFunction, this, "DecodingThread"), 185 decode_thread_(DecodeThreadFunction, this, "DecodingThread"),
160 congestion_controller_(congestion_controller), 186 congestion_controller_(congestion_controller),
161 call_stats_(call_stats), 187 call_stats_(call_stats),
162 video_receiver_(clock_, nullptr, this, this, this), 188 video_receiver_(clock_, nullptr, this, this, this),
163 incoming_video_stream_(config_.disable_prerenderer_smoothing),
164 stats_proxy_(&config_, clock_), 189 stats_proxy_(&config_, clock_),
165 rtp_stream_receiver_(&video_receiver_, 190 rtp_stream_receiver_(&video_receiver_,
166 congestion_controller_->GetRemoteBitrateEstimator( 191 congestion_controller_->GetRemoteBitrateEstimator(
167 UseSendSideBwe(config_)), 192 UseSendSideBwe(config_)),
168 &transport_adapter_, 193 &transport_adapter_,
169 call_stats_->rtcp_rtt_stats(), 194 call_stats_->rtcp_rtt_stats(),
170 congestion_controller_->pacer(), 195 congestion_controller_->pacer(),
171 congestion_controller_->packet_router(), 196 congestion_controller_->packet_router(),
172 remb, 197 remb,
173 &config_, 198 &config_,
174 &stats_proxy_, 199 &stats_proxy_,
175 process_thread_), 200 process_thread_),
176 video_stream_decoder_(&video_receiver_,
177 &rtp_stream_receiver_,
178 &rtp_stream_receiver_,
179 rtp_stream_receiver_.IsRetransmissionsEnabled(),
180 rtp_stream_receiver_.IsFecEnabled(),
181 &stats_proxy_,
182 &incoming_video_stream_,
183 config.pre_render_callback),
184 vie_sync_(&video_receiver_) { 201 vie_sync_(&video_receiver_) {
185 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString(); 202 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
186 203
187 RTC_DCHECK(process_thread_); 204 RTC_DCHECK(process_thread_);
188 RTC_DCHECK(congestion_controller_); 205 RTC_DCHECK(congestion_controller_);
189 RTC_DCHECK(call_stats_); 206 RTC_DCHECK(call_stats_);
190 207
191 // Register the channel to receive stats updates.
192 call_stats_->RegisterStatsObserver(&video_stream_decoder_);
193
194 RTC_DCHECK(!config_.decoders.empty()); 208 RTC_DCHECK(!config_.decoders.empty());
195 std::set<int> decoder_payload_types; 209 std::set<int> decoder_payload_types;
196 for (const Decoder& decoder : config_.decoders) { 210 for (const Decoder& decoder : config_.decoders) {
197 RTC_CHECK(decoder.decoder); 211 RTC_CHECK(decoder.decoder);
198 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) == 212 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) ==
199 decoder_payload_types.end()) 213 decoder_payload_types.end())
200 << "Duplicate payload type (" << decoder.payload_type 214 << "Duplicate payload type (" << decoder.payload_type
201 << ") for different decoders."; 215 << ") for different decoders.";
202 decoder_payload_types.insert(decoder.payload_type); 216 decoder_payload_types.insert(decoder.payload_type);
203 video_receiver_.RegisterExternalDecoder(decoder.decoder, 217 video_receiver_.RegisterExternalDecoder(decoder.decoder,
204 decoder.payload_type); 218 decoder.payload_type);
205 219
206 VideoCodec codec = CreateDecoderVideoCodec(decoder); 220 VideoCodec codec = CreateDecoderVideoCodec(decoder);
207 RTC_CHECK(rtp_stream_receiver_.SetReceiveCodec(codec)); 221 RTC_CHECK(rtp_stream_receiver_.SetReceiveCodec(codec));
208 RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec( 222 RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec(
209 &codec, num_cpu_cores, false)); 223 &codec, num_cpu_cores, false));
210 } 224 }
211 225
212 video_receiver_.SetRenderDelay(config.render_delay_ms); 226 video_receiver_.SetRenderDelay(config.render_delay_ms);
213 incoming_video_stream_.SetExpectedRenderDelay(config.render_delay_ms);
214 incoming_video_stream_.SetExternalCallback(this);
215 227
216 process_thread_->RegisterModule(&video_receiver_); 228 process_thread_->RegisterModule(&video_receiver_);
217 process_thread_->RegisterModule(&vie_sync_); 229 process_thread_->RegisterModule(&vie_sync_);
218 } 230 }
219 231
220 VideoReceiveStream::~VideoReceiveStream() { 232 VideoReceiveStream::~VideoReceiveStream() {
221 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString(); 233 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString();
222 Stop(); 234 Stop();
223 235
224 process_thread_->DeRegisterModule(&vie_sync_); 236 process_thread_->DeRegisterModule(&vie_sync_);
225 process_thread_->DeRegisterModule(&video_receiver_); 237 process_thread_->DeRegisterModule(&video_receiver_);
226 238
227 // Deregister external decoders so they are no longer running during 239 // Deregister external decoders so they are no longer running during
228 // destruction. This effectively stops the VCM since the decoder thread is 240 // destruction. This effectively stops the VCM since the decoder thread is
229 // stopped, the VCM is deregistered and no asynchronous decoder threads are 241 // stopped, the VCM is deregistered and no asynchronous decoder threads are
230 // running. 242 // running.
231 for (const Decoder& decoder : config_.decoders) 243 for (const Decoder& decoder : config_.decoders)
232 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type); 244 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type);
233 245
234 call_stats_->DeregisterStatsObserver(&video_stream_decoder_);
235
236 congestion_controller_->GetRemoteBitrateEstimator(UseSendSideBwe(config_)) 246 congestion_controller_->GetRemoteBitrateEstimator(UseSendSideBwe(config_))
237 ->RemoveStream(rtp_stream_receiver_.GetRemoteSsrc()); 247 ->RemoveStream(rtp_stream_receiver_.GetRemoteSsrc());
238 } 248 }
239 249
240 void VideoReceiveStream::SignalNetworkState(NetworkState state) { 250 void VideoReceiveStream::SignalNetworkState(NetworkState state) {
241 rtp_stream_receiver_.SignalNetworkState(state); 251 rtp_stream_receiver_.SignalNetworkState(state);
242 } 252 }
243 253
244 254
245 bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { 255 bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
246 return rtp_stream_receiver_.DeliverRtcp(packet, length); 256 return rtp_stream_receiver_.DeliverRtcp(packet, length);
247 } 257 }
248 258
249 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet, 259 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet,
250 size_t length, 260 size_t length,
251 const PacketTime& packet_time) { 261 const PacketTime& packet_time) {
252 return rtp_stream_receiver_.DeliverRtp(packet, length, packet_time); 262 return rtp_stream_receiver_.DeliverRtp(packet, length, packet_time);
253 } 263 }
254 264
255 void VideoReceiveStream::Start() { 265 void VideoReceiveStream::Start() {
256 if (decode_thread_.IsRunning()) 266 if (decode_thread_.IsRunning())
257 return; 267 return;
258 transport_adapter_.Enable(); 268 transport_adapter_.Enable();
259 incoming_video_stream_.Start(); 269 incoming_video_stream_ = MaybeCreateIncomingVideoStream(config_, this);
270 video_stream_decoder_.reset(new VideoStreamDecoder(
271 &video_receiver_, &rtp_stream_receiver_, &rtp_stream_receiver_,
272 rtp_stream_receiver_.IsRetransmissionsEnabled(),
273 rtp_stream_receiver_.IsFecEnabled(), &stats_proxy_,
274 incoming_video_stream_.get(), config_.pre_render_callback));
275 // Register the channel to receive stats updates.
276 call_stats_->RegisterStatsObserver(video_stream_decoder_.get());
260 // Start the decode thread 277 // Start the decode thread
261 decode_thread_.Start(); 278 decode_thread_.Start();
262 decode_thread_.SetPriority(rtc::kHighestPriority); 279 decode_thread_.SetPriority(rtc::kHighestPriority);
263 rtp_stream_receiver_.StartReceive(); 280 rtp_stream_receiver_.StartReceive();
264 } 281 }
265 282
266 void VideoReceiveStream::Stop() { 283 void VideoReceiveStream::Stop() {
267 incoming_video_stream_.Stop();
268 rtp_stream_receiver_.StopReceive(); 284 rtp_stream_receiver_.StopReceive();
269 video_receiver_.TriggerDecoderShutdown(); 285 video_receiver_.TriggerDecoderShutdown();
270 decode_thread_.Stop(); 286 decode_thread_.Stop();
287 call_stats_->DeregisterStatsObserver(video_stream_decoder_.get());
288 video_stream_decoder_.reset();
289 incoming_video_stream_.reset();
271 transport_adapter_.Disable(); 290 transport_adapter_.Disable();
272 } 291 }
273 292
274 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine, 293 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine,
275 int audio_channel_id) { 294 int audio_channel_id) {
276 if (voice_engine && audio_channel_id != -1) { 295 if (voice_engine && audio_channel_id != -1) {
277 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine); 296 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine);
278 vie_sync_.ConfigureSync(audio_channel_id, voe_sync_interface, 297 vie_sync_.ConfigureSync(audio_channel_id, voe_sync_interface,
279 rtp_stream_receiver_.rtp_rtcp(), 298 rtp_stream_receiver_.rtp_rtcp(),
280 rtp_stream_receiver_.GetRtpReceiver()); 299 rtp_stream_receiver_.GetRtpReceiver());
281 voe_sync_interface->Release(); 300 voe_sync_interface->Release();
282 } else { 301 } else {
283 vie_sync_.ConfigureSync(-1, nullptr, rtp_stream_receiver_.rtp_rtcp(), 302 vie_sync_.ConfigureSync(-1, nullptr, rtp_stream_receiver_.rtp_rtcp(),
284 rtp_stream_receiver_.GetRtpReceiver()); 303 rtp_stream_receiver_.GetRtpReceiver());
285 } 304 }
286 } 305 }
287 306
288 VideoReceiveStream::Stats VideoReceiveStream::GetStats() const { 307 VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
289 return stats_proxy_.GetStats(); 308 return stats_proxy_.GetStats();
290 } 309 }
291 310
311 // TODO(tommi): This method grabs a lock 6 times.
292 void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) { 312 void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) {
313 // TODO(tommi): OnDecodedFrame grabs a lock, incidentally the same lock
314 // that OnSyncOffsetUpdated() and OnRenderedFrame() below grab.
293 stats_proxy_.OnDecodedFrame(); 315 stats_proxy_.OnDecodedFrame();
294 316
295 int64_t sync_offset_ms; 317 int64_t sync_offset_ms;
296 if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) 318 // TODO(tommi): GetStreamSyncOffsetInMs grabs three locks. One inside the
319 // function itself, another in GetChannel() and a third in
320 // GetPlayoutTimestamp. Seems excessive. Anyhow, I'm assuming the function
321 // succeeds most of the time, which leads to grabbing a fourth lock.
322 if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) {
323 // TODO(tommi): OnSyncOffsetUpdated grabs a lock.
297 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms); 324 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms);
325 }
298 326
299 if (config_.renderer) 327 // config_.renderer must never be null if we're getting this callback.
300 config_.renderer->OnFrame(video_frame); 328 config_.renderer->OnFrame(video_frame);
301 329
330 // TODO(tommi): OnRenderFrame grabs a lock too.
302 stats_proxy_.OnRenderedFrame(video_frame.width(), video_frame.height()); 331 stats_proxy_.OnRenderedFrame(video_frame.width(), video_frame.height());
303 } 332 }
304 333
305 // TODO(asapersson): Consider moving callback from video_encoder.h or 334 // TODO(asapersson): Consider moving callback from video_encoder.h or
306 // creating a different callback. 335 // creating a different callback.
307 int32_t VideoReceiveStream::Encoded( 336 int32_t VideoReceiveStream::Encoded(
308 const EncodedImage& encoded_image, 337 const EncodedImage& encoded_image,
309 const CodecSpecificInfo* codec_specific_info, 338 const CodecSpecificInfo* codec_specific_info,
310 const RTPFragmentationHeader* fragmentation) { 339 const RTPFragmentationHeader* fragmentation) {
311 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info); 340 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 const std::vector<uint16_t>& sequence_numbers) { 374 const std::vector<uint16_t>& sequence_numbers) {
346 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers); 375 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers);
347 } 376 }
348 377
349 void VideoReceiveStream::RequestKeyFrame() { 378 void VideoReceiveStream::RequestKeyFrame() {
350 rtp_stream_receiver_.RequestKeyFrame(); 379 rtp_stream_receiver_.RequestKeyFrame();
351 } 380 }
352 381
353 } // namespace internal 382 } // namespace internal
354 } // namespace webrtc 383 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/video_receive_stream.h ('k') | webrtc/video/video_stream_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698