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