OLD | NEW |
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 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 num_active_rtp_rtcp_modules_(1) { | 138 num_active_rtp_rtcp_modules_(1) { |
139 vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]); | 139 vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]); |
140 vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); | 140 vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); |
141 } | 141 } |
142 | 142 |
143 int32_t ViEChannel::Init() { | 143 int32_t ViEChannel::Init() { |
144 static const int kDefaultRenderDelayMs = 10; | 144 static const int kDefaultRenderDelayMs = 10; |
145 module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics()); | 145 module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics()); |
146 | 146 |
147 // RTP/RTCP initialization. | 147 // RTP/RTCP initialization. |
148 module_process_thread_->RegisterModule(rtp_rtcp_modules_[0]); | |
149 | |
150 rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); | 148 rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); |
151 if (paced_sender_) { | 149 if (paced_sender_) { |
152 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 150 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
153 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); | 151 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); |
154 } | 152 } |
155 packet_router_->AddRtpModule(rtp_rtcp_modules_[0]); | 153 packet_router_->AddRtpModule(rtp_rtcp_modules_[0]); |
156 if (sender_) { | 154 if (sender_) { |
157 std::list<RtpRtcp*> send_rtp_modules(1, rtp_rtcp_modules_[0]); | 155 send_payload_router_->SetSendingRtpModules( |
158 send_payload_router_->SetSendingRtpModules(send_rtp_modules); | 156 std::vector<RtpRtcp*>(1, rtp_rtcp_modules_[0])); |
159 RTC_DCHECK(!send_payload_router_->active()); | 157 RTC_DCHECK(!send_payload_router_->active()); |
160 } | 158 } |
161 if (vcm_->RegisterReceiveCallback(this) != 0) { | 159 if (vcm_->RegisterReceiveCallback(this) != 0) { |
162 return -1; | 160 return -1; |
163 } | 161 } |
164 vcm_->RegisterFrameTypeCallback(this); | 162 vcm_->RegisterFrameTypeCallback(this); |
165 vcm_->RegisterReceiveStatisticsCallback(this); | 163 vcm_->RegisterReceiveStatisticsCallback(this); |
166 vcm_->RegisterDecoderTimingCallback(this); | 164 vcm_->RegisterDecoderTimingCallback(this); |
167 vcm_->SetRenderDelay(kDefaultRenderDelayMs); | 165 vcm_->SetRenderDelay(kDefaultRenderDelayMs); |
168 | 166 |
169 module_process_thread_->RegisterModule(vcm_); | 167 module_process_thread_->RegisterModule(vcm_); |
170 module_process_thread_->RegisterModule(&vie_sync_); | 168 module_process_thread_->RegisterModule(&vie_sync_); |
| 169 module_process_thread_->RegisterModule(this); |
171 | 170 |
172 return 0; | 171 return 0; |
173 } | 172 } |
174 | 173 |
| 174 // TODO(pbos): Consider atomics, this might block. |
| 175 int64_t ViEChannel::TimeUntilNextProcess() { |
| 176 size_t active_modules; |
| 177 { |
| 178 CriticalSectionScoped cs(crit_.get()); |
| 179 active_modules = num_active_rtp_rtcp_modules_; |
| 180 } |
| 181 |
| 182 int64_t min_time = rtp_rtcp_modules_[0]->TimeUntilNextProcess(); |
| 183 for (size_t i = 1; i < active_modules; ++i) { |
| 184 int64_t time = rtp_rtcp_modules_[i]->TimeUntilNextProcess(); |
| 185 if (time < min_time) |
| 186 min_time = time; |
| 187 } |
| 188 return min_time; |
| 189 } |
| 190 |
| 191 // TODO(pbos): Consider atomics, this might block. |
| 192 int32_t ViEChannel::Process() { |
| 193 size_t active_modules; |
| 194 { |
| 195 CriticalSectionScoped cs(crit_.get()); |
| 196 active_modules = num_active_rtp_rtcp_modules_; |
| 197 } |
| 198 |
| 199 for (size_t i = 0; i < active_modules; ++i) { |
| 200 rtp_rtcp_modules_[i]->Process(); |
| 201 } |
| 202 return 0; |
| 203 } |
| 204 |
175 ViEChannel::~ViEChannel() { | 205 ViEChannel::~ViEChannel() { |
176 UpdateHistograms(); | 206 UpdateHistograms(); |
177 // Make sure we don't get more callbacks from the RTP module. | 207 // Make sure we don't get more callbacks from the RTP module. |
| 208 module_process_thread_->DeRegisterModule(this); |
178 module_process_thread_->DeRegisterModule( | 209 module_process_thread_->DeRegisterModule( |
179 vie_receiver_.GetReceiveStatistics()); | 210 vie_receiver_.GetReceiveStatistics()); |
180 module_process_thread_->DeRegisterModule(vcm_); | 211 module_process_thread_->DeRegisterModule(vcm_); |
181 module_process_thread_->DeRegisterModule(&vie_sync_); | 212 module_process_thread_->DeRegisterModule(&vie_sync_); |
182 send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>()); | 213 send_payload_router_->SetSendingRtpModules(std::vector<RtpRtcp*>()); |
183 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) | 214 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) |
184 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); | 215 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); |
185 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 216 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
186 module_process_thread_->DeRegisterModule(rtp_rtcp); | 217 module_process_thread_->DeRegisterModule(rtp_rtcp); |
187 delete rtp_rtcp; | 218 delete rtp_rtcp; |
188 } | 219 } |
189 if (!sender_) | 220 if (!sender_) |
190 StopDecodeThread(); | 221 StopDecodeThread(); |
191 // Release modules. | 222 // Release modules. |
192 VideoCodingModule::Destroy(vcm_); | 223 VideoCodingModule::Destroy(vcm_); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 if (vie_receiver_.IsFecEnabled()) { | 360 if (vie_receiver_.IsFecEnabled()) { |
330 RTC_HISTOGRAM_COUNTS_SPARSE_10000( | 361 RTC_HISTOGRAM_COUNTS_SPARSE_10000( |
331 "WebRTC.Video.FecBitrateReceivedInKbps", | 362 "WebRTC.Video.FecBitrateReceivedInKbps", |
332 static_cast<int>(rtp_rtx.fec.TotalBytes() * 8 / elapsed_sec / | 363 static_cast<int>(rtp_rtx.fec.TotalBytes() * 8 / elapsed_sec / |
333 1000)); | 364 1000)); |
334 } | 365 } |
335 } | 366 } |
336 } | 367 } |
337 } | 368 } |
338 | 369 |
339 int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, | 370 void ViEChannel::SetSendCodec(const VideoCodec& video_codec) { |
340 bool new_stream) { | 371 // Here crit_ is used to synchronize between this method, StartSend and |
| 372 // StopSend and not end up in an inconsistent sending state. |
| 373 CriticalSectionScoped cs(crit_.get()); |
341 RTC_DCHECK(sender_); | 374 RTC_DCHECK(sender_); |
342 if (video_codec.codecType == kVideoCodecRED || | 375 RTC_DCHECK(video_codec.codecType != kVideoCodecRED); |
343 video_codec.codecType == kVideoCodecULPFEC) { | 376 RTC_DCHECK(video_codec.codecType != kVideoCodecULPFEC); |
344 LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType; | 377 RTC_DCHECK_LE(video_codec.numberOfSimulcastStreams, kMaxSimulcastStreams); |
345 return -1; | |
346 } | |
347 if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) { | |
348 LOG_F(LS_ERROR) << "Incorrect config " | |
349 << video_codec.numberOfSimulcastStreams; | |
350 return -1; | |
351 } | |
352 // Update the RTP module with the settings. | 378 // Update the RTP module with the settings. |
353 // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been | 379 // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been |
354 // set explicitly. | 380 // set explicitly. |
355 // The first layer is always active, so the first module can be checked for | 381 // The first layer is always active, so the first module can be checked for |
356 // sending status. | 382 // sending status. |
357 bool is_sending = rtp_rtcp_modules_[0]->Sending(); | |
358 bool router_was_active = send_payload_router_->active(); | 383 bool router_was_active = send_payload_router_->active(); |
359 send_payload_router_->set_active(false); | 384 send_payload_router_->set_active(false); |
360 send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>()); | 385 send_payload_router_->SetSendingRtpModules(std::vector<RtpRtcp*>()); |
361 | 386 |
| 387 size_t num_prev_active_modules = num_active_rtp_rtcp_modules_; |
| 388 num_active_rtp_rtcp_modules_ = video_codec.numberOfSimulcastStreams > 0 |
| 389 ? video_codec.numberOfSimulcastStreams |
| 390 : 1; |
362 std::vector<RtpRtcp*> registered_modules; | 391 std::vector<RtpRtcp*> registered_modules; |
363 std::vector<RtpRtcp*> deregistered_modules; | 392 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) |
364 size_t num_active_modules = video_codec.numberOfSimulcastStreams > 0 | |
365 ? video_codec.numberOfSimulcastStreams | |
366 : 1; | |
367 size_t num_prev_active_modules; | |
368 { | |
369 // Cache which modules are active so StartSend can know which ones to start. | |
370 CriticalSectionScoped cs(crit_.get()); | |
371 num_prev_active_modules = num_active_rtp_rtcp_modules_; | |
372 num_active_rtp_rtcp_modules_ = num_active_modules; | |
373 } | |
374 for (size_t i = 0; i < num_active_modules; ++i) | |
375 registered_modules.push_back(rtp_rtcp_modules_[i]); | 393 registered_modules.push_back(rtp_rtcp_modules_[i]); |
376 | 394 |
377 for (size_t i = num_active_modules; i < rtp_rtcp_modules_.size(); ++i) | |
378 deregistered_modules.push_back(rtp_rtcp_modules_[i]); | |
379 | |
380 // Disable inactive modules. | 395 // Disable inactive modules. |
381 for (RtpRtcp* rtp_rtcp : deregistered_modules) { | 396 for (size_t i = num_active_rtp_rtcp_modules_; i < rtp_rtcp_modules_.size(); |
| 397 ++i) { |
| 398 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; |
382 rtp_rtcp->SetSendingStatus(false); | 399 rtp_rtcp->SetSendingStatus(false); |
383 rtp_rtcp->SetSendingMediaStatus(false); | 400 rtp_rtcp->SetSendingMediaStatus(false); |
384 } | 401 } |
385 | 402 |
386 // Configure active modules. | 403 // Configure active modules. |
| 404 bool is_sending = rtp_rtcp_modules_[0]->Sending(); |
387 for (RtpRtcp* rtp_rtcp : registered_modules) { | 405 for (RtpRtcp* rtp_rtcp : registered_modules) { |
388 rtp_rtcp->DeRegisterSendPayload(video_codec.plType); | 406 rtp_rtcp->DeRegisterSendPayload(video_codec.plType); |
389 if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) { | 407 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendPayload(video_codec)); |
390 return -1; | |
391 } | |
392 rtp_rtcp->SetSendingStatus(is_sending); | 408 rtp_rtcp->SetSendingStatus(is_sending); |
393 rtp_rtcp->SetSendingMediaStatus(is_sending); | 409 rtp_rtcp->SetSendingMediaStatus(is_sending); |
394 } | 410 } |
395 | 411 |
396 // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old | |
397 // modules can be deleted after this step. | |
398 vie_receiver_.RegisterRtpRtcpModules(registered_modules); | 412 vie_receiver_.RegisterRtpRtcpModules(registered_modules); |
399 | 413 |
400 // Update the packet and payload routers with the sending RtpRtcp modules. | |
401 if (sender_) { | |
402 std::list<RtpRtcp*> active_send_modules; | |
403 for (RtpRtcp* rtp_rtcp : registered_modules) | |
404 active_send_modules.push_back(rtp_rtcp); | |
405 send_payload_router_->SetSendingRtpModules(active_send_modules); | |
406 } | |
407 | |
408 if (router_was_active) | |
409 send_payload_router_->set_active(true); | |
410 | 414 |
411 // Deregister previously registered modules. | 415 // Deregister previously registered modules. |
412 for (size_t i = num_active_modules; i < num_prev_active_modules; ++i) { | 416 for (size_t i = num_active_rtp_rtcp_modules_; i < num_prev_active_modules; |
413 module_process_thread_->DeRegisterModule(rtp_rtcp_modules_[i]); | 417 ++i) { |
414 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); | 418 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); |
415 } | 419 } |
416 // Register new active modules. | 420 // Register new active modules. |
417 for (size_t i = num_prev_active_modules; i < num_active_modules; ++i) { | 421 for (size_t i = num_prev_active_modules; i < num_active_rtp_rtcp_modules_; |
418 module_process_thread_->RegisterModule(rtp_rtcp_modules_[i]); | 422 ++i) { |
419 packet_router_->AddRtpModule(rtp_rtcp_modules_[i]); | 423 packet_router_->AddRtpModule(rtp_rtcp_modules_[i]); |
420 } | 424 } |
421 return 0; | 425 |
| 426 // Update the packet and payload routers with the sending RtpRtcp modules. |
| 427 send_payload_router_->SetSendingRtpModules(registered_modules); |
| 428 if (router_was_active) |
| 429 send_payload_router_->set_active(true); |
422 } | 430 } |
423 | 431 |
424 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { | 432 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { |
425 RTC_DCHECK(!sender_); | 433 RTC_DCHECK(!sender_); |
426 if (!vie_receiver_.SetReceiveCodec(video_codec)) { | 434 if (!vie_receiver_.SetReceiveCodec(video_codec)) { |
427 return -1; | 435 return -1; |
428 } | 436 } |
429 | 437 |
430 if (video_codec.codecType != kVideoCodecRED && | 438 if (video_codec.codecType != kVideoCodecRED && |
431 video_codec.codecType != kVideoCodecULPFEC) { | 439 video_codec.codecType != kVideoCodecULPFEC) { |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) { | 900 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) { |
893 RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i]; | 901 RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i]; |
894 rtp_rtcp->SetSendingMediaStatus(true); | 902 rtp_rtcp->SetSendingMediaStatus(true); |
895 rtp_rtcp->SetSendingStatus(true); | 903 rtp_rtcp->SetSendingStatus(true); |
896 } | 904 } |
897 send_payload_router_->set_active(true); | 905 send_payload_router_->set_active(true); |
898 return 0; | 906 return 0; |
899 } | 907 } |
900 | 908 |
901 int32_t ViEChannel::StopSend() { | 909 int32_t ViEChannel::StopSend() { |
| 910 // Acquire crit_ to synchronize sending status with StartSend and |
| 911 // SetSendCodec. |
| 912 CriticalSectionScoped cs(crit_.get()); |
902 send_payload_router_->set_active(false); | 913 send_payload_router_->set_active(false); |
903 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 914 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
904 rtp_rtcp->SetSendingMediaStatus(false); | 915 rtp_rtcp->SetSendingMediaStatus(false); |
905 | 916 |
906 if (!rtp_rtcp_modules_[0]->Sending()) { | 917 if (!rtp_rtcp_modules_[0]->Sending()) { |
907 return -1; | 918 return -1; |
908 } | 919 } |
909 | 920 |
910 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 921 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
911 rtp_rtcp->SetSendingStatus(false); | 922 rtp_rtcp->SetSendingStatus(false); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 CriticalSectionScoped cs(crit_.get()); | 1219 CriticalSectionScoped cs(crit_.get()); |
1209 receive_stats_callback_ = receive_statistics_proxy; | 1220 receive_stats_callback_ = receive_statistics_proxy; |
1210 } | 1221 } |
1211 | 1222 |
1212 void ViEChannel::SetIncomingVideoStream( | 1223 void ViEChannel::SetIncomingVideoStream( |
1213 IncomingVideoStream* incoming_video_stream) { | 1224 IncomingVideoStream* incoming_video_stream) { |
1214 CriticalSectionScoped cs(crit_.get()); | 1225 CriticalSectionScoped cs(crit_.get()); |
1215 incoming_video_stream_ = incoming_video_stream; | 1226 incoming_video_stream_ = incoming_video_stream; |
1216 } | 1227 } |
1217 } // namespace webrtc | 1228 } // namespace webrtc |
OLD | NEW |