Index: webrtc/video/video_receive_stream.cc |
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc |
index 92f84a0cb8e0d82eede9df651d927a383ccc0a70..9909e29c433b394da8ed2b9ca18b51442e4ddb5e 100644 |
--- a/webrtc/video/video_receive_stream.cc |
+++ b/webrtc/video/video_receive_stream.cc |
@@ -144,32 +144,6 @@ |
} // namespace |
namespace internal { |
- |
-// Since an IncomingVideoStream instance will create a thread/queue, we don't |
-// instantiate one unless we know we're going to be delivering the frames |
-// to a renderer. |
-// |
-// TODO(tommi): Consider making the functionality provided by the |
-// IncomingVideoStream classes, tied to the Config class instead or even higher |
-// level. That will make it an optional feature that will be up to the |
-// application to use or not use. Right now, we have two classes available, |
-// they both have threads involved which uses WebRTC's threading classes and |
-// that might not suit what the application wants to do. If one of them or |
-// neither, suits, the app can get some code size back as well as more control. |
-std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> |
-MaybeCreateIncomingVideoStream(const VideoReceiveStream::Config& config, |
- rtc::VideoSinkInterface<VideoFrame>* callback) { |
- std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> ret; |
- if (config.renderer) { |
- if (config.disable_prerenderer_smoothing) { |
- ret.reset(new IncomingVideoStreamNoSmoothing(callback)); |
- } else { |
- ret.reset(new IncomingVideoStream(config.render_delay_ms, callback)); |
- } |
- } |
- return ret; |
-} |
- |
VideoReceiveStream::VideoReceiveStream( |
int num_cpu_cores, |
CongestionController* congestion_controller, |
@@ -186,6 +160,7 @@ |
congestion_controller_(congestion_controller), |
call_stats_(call_stats), |
video_receiver_(clock_, nullptr, this, this, this), |
+ incoming_video_stream_(config_.disable_prerenderer_smoothing), |
stats_proxy_(&config_, clock_), |
rtp_stream_receiver_(&video_receiver_, |
congestion_controller_->GetRemoteBitrateEstimator( |
@@ -198,12 +173,23 @@ |
&config_, |
&stats_proxy_, |
process_thread_), |
+ video_stream_decoder_(&video_receiver_, |
+ &rtp_stream_receiver_, |
+ &rtp_stream_receiver_, |
+ rtp_stream_receiver_.IsRetransmissionsEnabled(), |
+ rtp_stream_receiver_.IsFecEnabled(), |
+ &stats_proxy_, |
+ &incoming_video_stream_, |
+ config.pre_render_callback), |
vie_sync_(&video_receiver_) { |
LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString(); |
RTC_DCHECK(process_thread_); |
RTC_DCHECK(congestion_controller_); |
RTC_DCHECK(call_stats_); |
+ |
+ // Register the channel to receive stats updates. |
+ call_stats_->RegisterStatsObserver(&video_stream_decoder_); |
RTC_DCHECK(!config_.decoders.empty()); |
std::set<int> decoder_payload_types; |
@@ -224,6 +210,8 @@ |
} |
video_receiver_.SetRenderDelay(config.render_delay_ms); |
+ incoming_video_stream_.SetExpectedRenderDelay(config.render_delay_ms); |
+ incoming_video_stream_.SetExternalCallback(this); |
process_thread_->RegisterModule(&video_receiver_); |
process_thread_->RegisterModule(&vie_sync_); |
@@ -243,6 +231,8 @@ |
for (const Decoder& decoder : config_.decoders) |
video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type); |
+ call_stats_->DeregisterStatsObserver(&video_stream_decoder_); |
+ |
congestion_controller_->GetRemoteBitrateEstimator(UseSendSideBwe(config_)) |
->RemoveStream(rtp_stream_receiver_.GetRemoteSsrc()); |
} |
@@ -266,14 +256,7 @@ |
if (decode_thread_.IsRunning()) |
return; |
transport_adapter_.Enable(); |
- incoming_video_stream_ = MaybeCreateIncomingVideoStream(config_, this); |
- video_stream_decoder_.reset(new VideoStreamDecoder( |
- &video_receiver_, &rtp_stream_receiver_, &rtp_stream_receiver_, |
- rtp_stream_receiver_.IsRetransmissionsEnabled(), |
- rtp_stream_receiver_.IsFecEnabled(), &stats_proxy_, |
- incoming_video_stream_.get(), config_.pre_render_callback)); |
- // Register the channel to receive stats updates. |
- call_stats_->RegisterStatsObserver(video_stream_decoder_.get()); |
+ incoming_video_stream_.Start(); |
// Start the decode thread |
decode_thread_.Start(); |
decode_thread_.SetPriority(rtc::kHighestPriority); |
@@ -281,12 +264,10 @@ |
} |
void VideoReceiveStream::Stop() { |
+ incoming_video_stream_.Stop(); |
rtp_stream_receiver_.StopReceive(); |
video_receiver_.TriggerDecoderShutdown(); |
decode_thread_.Stop(); |
- call_stats_->DeregisterStatsObserver(video_stream_decoder_.get()); |
- video_stream_decoder_.reset(); |
- incoming_video_stream_.reset(); |
transport_adapter_.Disable(); |
} |
@@ -308,26 +289,16 @@ |
return stats_proxy_.GetStats(); |
} |
-// TODO(tommi): This method grabs a lock 6 times. |
void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) { |
- // TODO(tommi): OnDecodedFrame grabs a lock, incidentally the same lock |
- // that OnSyncOffsetUpdated() and OnRenderedFrame() below grab. |
stats_proxy_.OnDecodedFrame(); |
int64_t sync_offset_ms; |
- // TODO(tommi): GetStreamSyncOffsetInMs grabs three locks. One inside the |
- // function itself, another in GetChannel() and a third in |
- // GetPlayoutTimestamp. Seems excessive. Anyhow, I'm assuming the function |
- // succeeds most of the time, which leads to grabbing a fourth lock. |
- if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) { |
- // TODO(tommi): OnSyncOffsetUpdated grabs a lock. |
+ if (vie_sync_.GetStreamSyncOffsetInMs(video_frame, &sync_offset_ms)) |
stats_proxy_.OnSyncOffsetUpdated(sync_offset_ms); |
- } |
- |
- // config_.renderer must never be null if we're getting this callback. |
- config_.renderer->OnFrame(video_frame); |
- |
- // TODO(tommi): OnRenderFrame grabs a lock too. |
+ |
+ if (config_.renderer) |
+ config_.renderer->OnFrame(video_frame); |
+ |
stats_proxy_.OnRenderedFrame(video_frame.width(), video_frame.height()); |
} |