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

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

Issue 2035173002: Split IncomingVideoStream into two implementations, with smoothing and without. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Address comments 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 encoded_frame_proxy_(config.pre_decode_callback), 182 encoded_frame_proxy_(config.pre_decode_callback),
157 config_(std::move(config)), 183 config_(std::move(config)),
158 process_thread_(process_thread), 184 process_thread_(process_thread),
159 clock_(Clock::GetRealTimeClock()), 185 clock_(Clock::GetRealTimeClock()),
160 decode_thread_(DecodeThreadFunction, this, "DecodingThread"), 186 decode_thread_(DecodeThreadFunction, this, "DecodingThread"),
161 congestion_controller_(congestion_controller), 187 congestion_controller_(congestion_controller),
162 call_stats_(call_stats), 188 call_stats_(call_stats),
163 video_receiver_(clock_, nullptr, this, this, this), 189 video_receiver_(clock_, nullptr, this, this, this),
164 incoming_video_stream_(config_.disable_prerenderer_smoothing),
165 stats_proxy_(&config_, clock_), 190 stats_proxy_(&config_, clock_),
166 rtp_stream_receiver_(&video_receiver_, 191 rtp_stream_receiver_(&video_receiver_,
167 congestion_controller_->GetRemoteBitrateEstimator( 192 congestion_controller_->GetRemoteBitrateEstimator(
168 UseSendSideBwe(config_)), 193 UseSendSideBwe(config_)),
169 &transport_adapter_, 194 &transport_adapter_,
170 call_stats_->rtcp_rtt_stats(), 195 call_stats_->rtcp_rtt_stats(),
171 congestion_controller_->pacer(), 196 congestion_controller_->pacer(),
172 congestion_controller_->packet_router(), 197 congestion_controller_->packet_router(),
173 remb, 198 remb,
174 &config_, 199 &config_,
175 &stats_proxy_, 200 &stats_proxy_,
176 process_thread_), 201 process_thread_),
177 video_stream_decoder_(&video_receiver_,
178 &rtp_stream_receiver_,
179 &rtp_stream_receiver_,
180 rtp_stream_receiver_.IsRetransmissionsEnabled(),
181 rtp_stream_receiver_.IsFecEnabled(),
182 &stats_proxy_,
183 &incoming_video_stream_,
184 config.pre_render_callback),
185 vie_sync_(&video_receiver_) { 202 vie_sync_(&video_receiver_) {
186 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString(); 203 LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
187 204
188 RTC_DCHECK(process_thread_); 205 RTC_DCHECK(process_thread_);
189 RTC_DCHECK(congestion_controller_); 206 RTC_DCHECK(congestion_controller_);
190 RTC_DCHECK(call_stats_); 207 RTC_DCHECK(call_stats_);
191 208
192 // Register the channel to receive stats updates.
193 call_stats_->RegisterStatsObserver(&video_stream_decoder_);
194
195 RTC_DCHECK(!config_.decoders.empty()); 209 RTC_DCHECK(!config_.decoders.empty());
196 std::set<int> decoder_payload_types; 210 std::set<int> decoder_payload_types;
197 for (const Decoder& decoder : config_.decoders) { 211 for (const Decoder& decoder : config_.decoders) {
198 RTC_CHECK(decoder.decoder); 212 RTC_CHECK(decoder.decoder);
199 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) == 213 RTC_CHECK(decoder_payload_types.find(decoder.payload_type) ==
200 decoder_payload_types.end()) 214 decoder_payload_types.end())
201 << "Duplicate payload type (" << decoder.payload_type 215 << "Duplicate payload type (" << decoder.payload_type
202 << ") for different decoders."; 216 << ") for different decoders.";
203 decoder_payload_types.insert(decoder.payload_type); 217 decoder_payload_types.insert(decoder.payload_type);
204 video_receiver_.RegisterExternalDecoder(decoder.decoder, 218 video_receiver_.RegisterExternalDecoder(decoder.decoder,
205 decoder.payload_type); 219 decoder.payload_type);
206 220
207 VideoCodec codec = CreateDecoderVideoCodec(decoder); 221 VideoCodec codec = CreateDecoderVideoCodec(decoder);
208 RTC_CHECK(rtp_stream_receiver_.SetReceiveCodec(codec)); 222 RTC_CHECK(rtp_stream_receiver_.SetReceiveCodec(codec));
209 RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec( 223 RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec(
210 &codec, num_cpu_cores, false)); 224 &codec, num_cpu_cores, false));
211 } 225 }
212 226
213 video_receiver_.SetRenderDelay(config.render_delay_ms); 227 video_receiver_.SetRenderDelay(config.render_delay_ms);
214 incoming_video_stream_.SetExpectedRenderDelay(config.render_delay_ms);
215 incoming_video_stream_.SetExternalCallback(this);
216 228
217 process_thread_->RegisterModule(&video_receiver_); 229 process_thread_->RegisterModule(&video_receiver_);
218 process_thread_->RegisterModule(&vie_sync_); 230 process_thread_->RegisterModule(&vie_sync_);
219 } 231 }
220 232
221 VideoReceiveStream::~VideoReceiveStream() { 233 VideoReceiveStream::~VideoReceiveStream() {
222 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString(); 234 LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString();
223 Stop(); 235 Stop();
224 236
225 process_thread_->DeRegisterModule(&vie_sync_); 237 process_thread_->DeRegisterModule(&vie_sync_);
226 process_thread_->DeRegisterModule(&video_receiver_); 238 process_thread_->DeRegisterModule(&video_receiver_);
227 239
228 // Deregister external decoders so they are no longer running during 240 // Deregister external decoders so they are no longer running during
229 // destruction. This effectively stops the VCM since the decoder thread is 241 // destruction. This effectively stops the VCM since the decoder thread is
230 // stopped, the VCM is deregistered and no asynchronous decoder threads are 242 // stopped, the VCM is deregistered and no asynchronous decoder threads are
231 // running. 243 // running.
232 for (const Decoder& decoder : config_.decoders) 244 for (const Decoder& decoder : config_.decoders)
233 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type); 245 video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type);
234 246
235 call_stats_->DeregisterStatsObserver(&video_stream_decoder_);
236
237 congestion_controller_->GetRemoteBitrateEstimator(UseSendSideBwe(config_)) 247 congestion_controller_->GetRemoteBitrateEstimator(UseSendSideBwe(config_))
238 ->RemoveStream(rtp_stream_receiver_.GetRemoteSsrc()); 248 ->RemoveStream(rtp_stream_receiver_.GetRemoteSsrc());
239 } 249 }
240 250
241 void VideoReceiveStream::SignalNetworkState(NetworkState state) { 251 void VideoReceiveStream::SignalNetworkState(NetworkState state) {
242 rtp_stream_receiver_.SignalNetworkState(state); 252 rtp_stream_receiver_.SignalNetworkState(state);
243 } 253 }
244 254
245 255
246 bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { 256 bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
247 return rtp_stream_receiver_.DeliverRtcp(packet, length); 257 return rtp_stream_receiver_.DeliverRtcp(packet, length);
248 } 258 }
249 259
250 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet, 260 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet,
251 size_t length, 261 size_t length,
252 const PacketTime& packet_time) { 262 const PacketTime& packet_time) {
253 return rtp_stream_receiver_.DeliverRtp(packet, length, packet_time); 263 return rtp_stream_receiver_.DeliverRtp(packet, length, packet_time);
254 } 264 }
255 265
256 void VideoReceiveStream::Start() { 266 void VideoReceiveStream::Start() {
257 if (decode_thread_.IsRunning()) 267 if (decode_thread_.IsRunning())
258 return; 268 return;
259 transport_adapter_.Enable(); 269 transport_adapter_.Enable();
260 incoming_video_stream_.Start(); 270 incoming_video_stream_ = MaybeCreateIncomingVideoStream(config_, this);
271 video_stream_decoder_.reset(new VideoStreamDecoder(
272 &video_receiver_, &rtp_stream_receiver_, &rtp_stream_receiver_,
273 rtp_stream_receiver_.IsRetransmissionsEnabled(),
274 rtp_stream_receiver_.IsFecEnabled(), &stats_proxy_,
275 incoming_video_stream_.get(), config_.pre_render_callback));
276 // Register the channel to receive stats updates.
277 call_stats_->RegisterStatsObserver(video_stream_decoder_.get());
261 // Start the decode thread 278 // Start the decode thread
262 decode_thread_.Start(); 279 decode_thread_.Start();
263 decode_thread_.SetPriority(rtc::kHighestPriority); 280 decode_thread_.SetPriority(rtc::kHighestPriority);
264 rtp_stream_receiver_.StartReceive(); 281 rtp_stream_receiver_.StartReceive();
265 } 282 }
266 283
267 void VideoReceiveStream::Stop() { 284 void VideoReceiveStream::Stop() {
268 incoming_video_stream_.Stop();
269 rtp_stream_receiver_.StopReceive(); 285 rtp_stream_receiver_.StopReceive();
270 video_receiver_.TriggerDecoderShutdown(); 286 video_receiver_.TriggerDecoderShutdown();
271 decode_thread_.Stop(); 287 decode_thread_.Stop();
288 call_stats_->DeregisterStatsObserver(video_stream_decoder_.get());
289 video_stream_decoder_.reset();
290 incoming_video_stream_.reset();
272 transport_adapter_.Disable(); 291 transport_adapter_.Disable();
273 } 292 }
274 293
275 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine, 294 void VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine,
276 int audio_channel_id) { 295 int audio_channel_id) {
277 if (voice_engine && audio_channel_id != -1) { 296 if (voice_engine && audio_channel_id != -1) {
278 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine); 297 VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine);
279 vie_sync_.ConfigureSync(audio_channel_id, voe_sync_interface, 298 vie_sync_.ConfigureSync(audio_channel_id, voe_sync_interface,
280 rtp_stream_receiver_.rtp_rtcp(), 299 rtp_stream_receiver_.rtp_rtcp(),
281 rtp_stream_receiver_.GetRtpReceiver()); 300 rtp_stream_receiver_.GetRtpReceiver());
282 voe_sync_interface->Release(); 301 voe_sync_interface->Release();
283 } else { 302 } else {
284 vie_sync_.ConfigureSync(-1, nullptr, rtp_stream_receiver_.rtp_rtcp(), 303 vie_sync_.ConfigureSync(-1, nullptr, rtp_stream_receiver_.rtp_rtcp(),
285 rtp_stream_receiver_.GetRtpReceiver()); 304 rtp_stream_receiver_.GetRtpReceiver());
286 } 305 }
287 } 306 }
288 307
289 VideoReceiveStream::Stats VideoReceiveStream::GetStats() const { 308 VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
290 return stats_proxy_.GetStats(); 309 return stats_proxy_.GetStats();
291 } 310 }
292 311
312 // TODO(tommi): This method grabs a lock 6 times.
293 void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) { 313 void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) {
314 // TODO(tommi): OnDecodedFrame grabs a lock, incidentally the same lock
315 // that OnSyncOffsetUpdated() and OnRenderedFrame() below grab.
294 stats_proxy_.OnDecodedFrame(); 316 stats_proxy_.OnDecodedFrame();
295 317
296 int64_t sync_offset_ms; 318 int64_t sync_offset_ms;
297 if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) 319 // TODO(tommi): GetStreamSyncOffsetInMs grabs three locks. One inside the
320 // function itself, another in GetChannel() and a third in
321 // GetPlayoutTimestamp. Seems excessive. Anyhow, I'm assuming the function
322 // succeeds most of the time, which leads to grabbing a fourth lock.
323 if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) {
324 // TODO(tommi): OnSyncOffsetUpdated grabs a lock.
298 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms); 325 stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms);
326 }
299 327
300 if (config_.renderer) 328 // config_.renderer must never be null if we're getting this callback.
301 config_.renderer->OnFrame(video_frame); 329 config_.renderer->OnFrame(video_frame);
302 330
331 // TODO(tommi): OnRenderFrame grabs a lock too.
303 stats_proxy_.OnRenderedFrame(video_frame.width(), video_frame.height()); 332 stats_proxy_.OnRenderedFrame(video_frame.width(), video_frame.height());
304 } 333 }
305 334
306 // TODO(asapersson): Consider moving callback from video_encoder.h or 335 // TODO(asapersson): Consider moving callback from video_encoder.h or
307 // creating a different callback. 336 // creating a different callback.
308 int32_t VideoReceiveStream::Encoded( 337 int32_t VideoReceiveStream::Encoded(
309 const EncodedImage& encoded_image, 338 const EncodedImage& encoded_image,
310 const CodecSpecificInfo* codec_specific_info, 339 const CodecSpecificInfo* codec_specific_info,
311 const RTPFragmentationHeader* fragmentation) { 340 const RTPFragmentationHeader* fragmentation) {
312 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info); 341 stats_proxy_.OnPreDecode(encoded_image, codec_specific_info);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 const std::vector<uint16_t>& sequence_numbers) { 375 const std::vector<uint16_t>& sequence_numbers) {
347 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers); 376 rtp_stream_receiver_.RequestPacketRetransmit(sequence_numbers);
348 } 377 }
349 378
350 void VideoReceiveStream::RequestKeyFrame() { 379 void VideoReceiveStream::RequestKeyFrame() {
351 rtp_stream_receiver_.RequestKeyFrame(); 380 rtp_stream_receiver_.RequestKeyFrame();
352 } 381 }
353 382
354 } // namespace internal 383 } // namespace internal
355 } // namespace webrtc 384 } // 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