| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
| 3 * | |
| 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 | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 #include "webrtc/video/vie_channel.h" | |
| 12 | |
| 13 #include <algorithm> | |
| 14 #include <map> | |
| 15 #include <vector> | |
| 16 | |
| 17 #include "webrtc/base/checks.h" | |
| 18 #include "webrtc/base/logging.h" | |
| 19 #include "webrtc/base/platform_thread.h" | |
| 20 #include "webrtc/common.h" | |
| 21 #include "webrtc/common_video/include/incoming_video_stream.h" | |
| 22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | |
| 23 #include "webrtc/frame_callback.h" | |
| 24 #include "webrtc/modules/pacing/paced_sender.h" | |
| 25 #include "webrtc/modules/pacing/packet_router.h" | |
| 26 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | |
| 27 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" | |
| 28 #include "webrtc/modules/utility/include/process_thread.h" | |
| 29 #include "webrtc/modules/video_coding/include/video_coding.h" | |
| 30 #include "webrtc/modules/video_processing/include/video_processing.h" | |
| 31 #include "webrtc/modules/video_render/video_render_defines.h" | |
| 32 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
| 33 #include "webrtc/system_wrappers/include/metrics.h" | |
| 34 #include "webrtc/video/call_stats.h" | |
| 35 #include "webrtc/video/payload_router.h" | |
| 36 #include "webrtc/video/receive_statistics_proxy.h" | |
| 37 #include "webrtc/video/report_block_stats.h" | |
| 38 | |
| 39 namespace webrtc { | |
| 40 | |
| 41 const int kMaxDecodeWaitTimeMs = 50; | |
| 42 static const int kMaxTargetDelayMs = 10000; | |
| 43 const int kMinSendSidePacketHistorySize = 600; | |
| 44 const int kMaxPacketAgeToNack = 450; | |
| 45 const int kMaxNackListSize = 250; | |
| 46 | |
| 47 // Helper class receiving statistics callbacks. | |
| 48 class ChannelStatsObserver : public CallStatsObserver { | |
| 49 public: | |
| 50 explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {} | |
| 51 virtual ~ChannelStatsObserver() {} | |
| 52 | |
| 53 // Implements StatsObserver. | |
| 54 virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | |
| 55 owner_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); | |
| 56 } | |
| 57 | |
| 58 private: | |
| 59 ViEChannel* const owner_; | |
| 60 }; | |
| 61 | |
| 62 class ViEChannelProtectionCallback : public VCMProtectionCallback { | |
| 63 public: | |
| 64 explicit ViEChannelProtectionCallback(ViEChannel* owner) : owner_(owner) {} | |
| 65 ~ViEChannelProtectionCallback() {} | |
| 66 | |
| 67 | |
| 68 int ProtectionRequest( | |
| 69 const FecProtectionParams* delta_fec_params, | |
| 70 const FecProtectionParams* key_fec_params, | |
| 71 uint32_t* sent_video_rate_bps, | |
| 72 uint32_t* sent_nack_rate_bps, | |
| 73 uint32_t* sent_fec_rate_bps) override { | |
| 74 return owner_->ProtectionRequest(delta_fec_params, key_fec_params, | |
| 75 sent_video_rate_bps, sent_nack_rate_bps, | |
| 76 sent_fec_rate_bps); | |
| 77 } | |
| 78 private: | |
| 79 ViEChannel* owner_; | |
| 80 }; | |
| 81 | |
| 82 ViEChannel::ViEChannel(uint32_t number_of_cores, | |
| 83 Transport* transport, | |
| 84 ProcessThread* module_process_thread, | |
| 85 RtcpIntraFrameObserver* intra_frame_observer, | |
| 86 RtcpBandwidthObserver* bandwidth_observer, | |
| 87 TransportFeedbackObserver* transport_feedback_observer, | |
| 88 RemoteBitrateEstimator* remote_bitrate_estimator, | |
| 89 RtcpRttStats* rtt_stats, | |
| 90 PacedSender* paced_sender, | |
| 91 PacketRouter* packet_router, | |
| 92 size_t max_rtp_streams, | |
| 93 bool sender) | |
| 94 : number_of_cores_(number_of_cores), | |
| 95 sender_(sender), | |
| 96 module_process_thread_(module_process_thread), | |
| 97 crit_(CriticalSectionWrapper::CreateCriticalSection()), | |
| 98 send_payload_router_(new PayloadRouter()), | |
| 99 vcm_protection_callback_(new ViEChannelProtectionCallback(this)), | |
| 100 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), | |
| 101 nullptr, | |
| 102 nullptr)), | |
| 103 vie_receiver_(vcm_, remote_bitrate_estimator, this), | |
| 104 vie_sync_(vcm_), | |
| 105 stats_observer_(new ChannelStatsObserver(this)), | |
| 106 receive_stats_callback_(nullptr), | |
| 107 incoming_video_stream_(nullptr), | |
| 108 intra_frame_observer_(intra_frame_observer), | |
| 109 rtt_stats_(rtt_stats), | |
| 110 paced_sender_(paced_sender), | |
| 111 packet_router_(packet_router), | |
| 112 bandwidth_observer_(bandwidth_observer), | |
| 113 transport_feedback_observer_(transport_feedback_observer), | |
| 114 decode_thread_(ChannelDecodeThreadFunction, this, "DecodingThread"), | |
| 115 nack_history_size_sender_(kMinSendSidePacketHistorySize), | |
| 116 max_nack_reordering_threshold_(kMaxPacketAgeToNack), | |
| 117 pre_render_callback_(NULL), | |
| 118 report_block_stats_sender_(new ReportBlockStats()), | |
| 119 time_of_first_rtt_ms_(-1), | |
| 120 rtt_sum_ms_(0), | |
| 121 last_rtt_ms_(0), | |
| 122 num_rtts_(0), | |
| 123 rtp_rtcp_modules_( | |
| 124 CreateRtpRtcpModules(!sender, | |
| 125 vie_receiver_.GetReceiveStatistics(), | |
| 126 transport, | |
| 127 intra_frame_observer_, | |
| 128 bandwidth_observer_.get(), | |
| 129 transport_feedback_observer_, | |
| 130 rtt_stats_, | |
| 131 &rtcp_packet_type_counter_observer_, | |
| 132 remote_bitrate_estimator, | |
| 133 paced_sender_, | |
| 134 packet_router_, | |
| 135 &send_bitrate_observer_, | |
| 136 &send_frame_count_observer_, | |
| 137 &send_side_delay_observer_, | |
| 138 max_rtp_streams)), | |
| 139 num_active_rtp_rtcp_modules_(1) { | |
| 140 vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]); | |
| 141 vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); | |
| 142 } | |
| 143 | |
| 144 int32_t ViEChannel::Init() { | |
| 145 static const int kDefaultRenderDelayMs = 10; | |
| 146 module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics()); | |
| 147 | |
| 148 // RTP/RTCP initialization. | |
| 149 module_process_thread_->RegisterModule(rtp_rtcp_modules_[0]); | |
| 150 | |
| 151 rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); | |
| 152 if (paced_sender_) { | |
| 153 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 154 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); | |
| 155 } | |
| 156 packet_router_->AddRtpModule(rtp_rtcp_modules_[0]); | |
| 157 if (sender_) { | |
| 158 std::list<RtpRtcp*> send_rtp_modules(1, rtp_rtcp_modules_[0]); | |
| 159 send_payload_router_->SetSendingRtpModules(send_rtp_modules); | |
| 160 RTC_DCHECK(!send_payload_router_->active()); | |
| 161 } | |
| 162 if (vcm_->RegisterReceiveCallback(this) != 0) { | |
| 163 return -1; | |
| 164 } | |
| 165 vcm_->RegisterFrameTypeCallback(this); | |
| 166 vcm_->RegisterReceiveStatisticsCallback(this); | |
| 167 vcm_->RegisterDecoderTimingCallback(this); | |
| 168 vcm_->SetRenderDelay(kDefaultRenderDelayMs); | |
| 169 | |
| 170 module_process_thread_->RegisterModule(vcm_); | |
| 171 module_process_thread_->RegisterModule(&vie_sync_); | |
| 172 | |
| 173 return 0; | |
| 174 } | |
| 175 | |
| 176 ViEChannel::~ViEChannel() { | |
| 177 UpdateHistograms(); | |
| 178 // Make sure we don't get more callbacks from the RTP module. | |
| 179 module_process_thread_->DeRegisterModule( | |
| 180 vie_receiver_.GetReceiveStatistics()); | |
| 181 module_process_thread_->DeRegisterModule(vcm_); | |
| 182 module_process_thread_->DeRegisterModule(&vie_sync_); | |
| 183 send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>()); | |
| 184 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) | |
| 185 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); | |
| 186 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 187 module_process_thread_->DeRegisterModule(rtp_rtcp); | |
| 188 delete rtp_rtcp; | |
| 189 } | |
| 190 if (!sender_) | |
| 191 StopDecodeThread(); | |
| 192 // Release modules. | |
| 193 VideoCodingModule::Destroy(vcm_); | |
| 194 } | |
| 195 | |
| 196 void ViEChannel::UpdateHistograms() { | |
| 197 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds(); | |
| 198 | |
| 199 { | |
| 200 CriticalSectionScoped cs(crit_.get()); | |
| 201 int64_t elapsed_sec = (now - time_of_first_rtt_ms_) / 1000; | |
| 202 if (time_of_first_rtt_ms_ != -1 && num_rtts_ > 0 && | |
| 203 elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
| 204 int64_t avg_rtt_ms = (rtt_sum_ms_ + num_rtts_ / 2) / num_rtts_; | |
| 205 RTC_HISTOGRAM_COUNTS_10000( | |
| 206 "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms); | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 if (sender_) { | |
| 211 RtcpPacketTypeCounter rtcp_counter; | |
| 212 GetSendRtcpPacketTypeCounter(&rtcp_counter); | |
| 213 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; | |
| 214 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
| 215 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute", | |
| 216 rtcp_counter.nack_packets * 60 / elapsed_sec); | |
| 217 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute", | |
| 218 rtcp_counter.fir_packets * 60 / elapsed_sec); | |
| 219 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute", | |
| 220 rtcp_counter.pli_packets * 60 / elapsed_sec); | |
| 221 if (rtcp_counter.nack_requests > 0) { | |
| 222 RTC_HISTOGRAM_PERCENTAGE( | |
| 223 "WebRTC.Video.UniqueNackRequestsReceivedInPercent", | |
| 224 rtcp_counter.UniqueNackRequestsInPercent()); | |
| 225 } | |
| 226 int fraction_lost = report_block_stats_sender_->FractionLostInPercent(); | |
| 227 if (fraction_lost != -1) { | |
| 228 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.SentPacketsLostInPercent", | |
| 229 fraction_lost); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 StreamDataCounters rtp; | |
| 234 StreamDataCounters rtx; | |
| 235 GetSendStreamDataCounters(&rtp, &rtx); | |
| 236 StreamDataCounters rtp_rtx = rtp; | |
| 237 rtp_rtx.Add(rtx); | |
| 238 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs( | |
| 239 Clock::GetRealTimeClock()->TimeInMilliseconds()) / | |
| 240 1000; | |
| 241 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
| 242 RTC_HISTOGRAM_COUNTS_100000( | |
| 243 "WebRTC.Video.BitrateSentInKbps", | |
| 244 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | |
| 245 1000)); | |
| 246 RTC_HISTOGRAM_COUNTS_10000( | |
| 247 "WebRTC.Video.MediaBitrateSentInKbps", | |
| 248 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); | |
| 249 RTC_HISTOGRAM_COUNTS_10000( | |
| 250 "WebRTC.Video.PaddingBitrateSentInKbps", | |
| 251 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / | |
| 252 1000)); | |
| 253 RTC_HISTOGRAM_COUNTS_10000( | |
| 254 "WebRTC.Video.RetransmittedBitrateSentInKbps", | |
| 255 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / | |
| 256 elapsed_sec / 1000)); | |
| 257 if (rtp_rtcp_modules_[0]->RtxSendStatus() != kRtxOff) { | |
| 258 RTC_HISTOGRAM_COUNTS_10000( | |
| 259 "WebRTC.Video.RtxBitrateSentInKbps", | |
| 260 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | |
| 261 1000)); | |
| 262 } | |
| 263 bool fec_enabled = false; | |
| 264 uint8_t pltype_red; | |
| 265 uint8_t pltype_fec; | |
| 266 rtp_rtcp_modules_[0]->GenericFECStatus(fec_enabled, pltype_red, | |
| 267 pltype_fec); | |
| 268 if (fec_enabled) { | |
| 269 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateSentInKbps", | |
| 270 static_cast<int>(rtp_rtx.fec.TotalBytes() * | |
| 271 8 / elapsed_sec / 1000)); | |
| 272 } | |
| 273 } | |
| 274 } else if (vie_receiver_.GetRemoteSsrc() > 0) { | |
| 275 // Get receive stats if we are receiving packets, i.e. there is a remote | |
| 276 // ssrc. | |
| 277 RtcpPacketTypeCounter rtcp_counter; | |
| 278 GetReceiveRtcpPacketTypeCounter(&rtcp_counter); | |
| 279 int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000; | |
| 280 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
| 281 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute", | |
| 282 rtcp_counter.nack_packets * 60 / elapsed_sec); | |
| 283 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute", | |
| 284 rtcp_counter.fir_packets * 60 / elapsed_sec); | |
| 285 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute", | |
| 286 rtcp_counter.pli_packets * 60 / elapsed_sec); | |
| 287 if (rtcp_counter.nack_requests > 0) { | |
| 288 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent", | |
| 289 rtcp_counter.UniqueNackRequestsInPercent()); | |
| 290 } | |
| 291 } | |
| 292 | |
| 293 StreamDataCounters rtp; | |
| 294 StreamDataCounters rtx; | |
| 295 GetReceiveStreamDataCounters(&rtp, &rtx); | |
| 296 StreamDataCounters rtp_rtx = rtp; | |
| 297 rtp_rtx.Add(rtx); | |
| 298 elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(now) / 1000; | |
| 299 if (elapsed_sec > metrics::kMinRunTimeInSeconds) { | |
| 300 RTC_HISTOGRAM_COUNTS_10000( | |
| 301 "WebRTC.Video.BitrateReceivedInKbps", | |
| 302 static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | |
| 303 1000)); | |
| 304 RTC_HISTOGRAM_COUNTS_10000( | |
| 305 "WebRTC.Video.MediaBitrateReceivedInKbps", | |
| 306 static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); | |
| 307 RTC_HISTOGRAM_COUNTS_10000( | |
| 308 "WebRTC.Video.PaddingBitrateReceivedInKbps", | |
| 309 static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / | |
| 310 1000)); | |
| 311 RTC_HISTOGRAM_COUNTS_10000( | |
| 312 "WebRTC.Video.RetransmittedBitrateReceivedInKbps", | |
| 313 static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / | |
| 314 elapsed_sec / 1000)); | |
| 315 uint32_t ssrc = 0; | |
| 316 if (vie_receiver_.GetRtxSsrc(&ssrc)) { | |
| 317 RTC_HISTOGRAM_COUNTS_10000( | |
| 318 "WebRTC.Video.RtxBitrateReceivedInKbps", | |
| 319 static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec / | |
| 320 1000)); | |
| 321 } | |
| 322 if (vie_receiver_.IsFecEnabled()) { | |
| 323 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateReceivedInKbps", | |
| 324 static_cast<int>(rtp_rtx.fec.TotalBytes() * | |
| 325 8 / elapsed_sec / 1000)); | |
| 326 } | |
| 327 } | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, | |
| 332 bool new_stream) { | |
| 333 RTC_DCHECK(sender_); | |
| 334 if (video_codec.codecType == kVideoCodecRED || | |
| 335 video_codec.codecType == kVideoCodecULPFEC) { | |
| 336 LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType; | |
| 337 return -1; | |
| 338 } | |
| 339 if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) { | |
| 340 LOG_F(LS_ERROR) << "Incorrect config " | |
| 341 << video_codec.numberOfSimulcastStreams; | |
| 342 return -1; | |
| 343 } | |
| 344 // Update the RTP module with the settings. | |
| 345 // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been | |
| 346 // set explicitly. | |
| 347 // The first layer is always active, so the first module can be checked for | |
| 348 // sending status. | |
| 349 bool is_sending = rtp_rtcp_modules_[0]->Sending(); | |
| 350 bool router_was_active = send_payload_router_->active(); | |
| 351 send_payload_router_->set_active(false); | |
| 352 send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>()); | |
| 353 | |
| 354 std::vector<RtpRtcp*> registered_modules; | |
| 355 std::vector<RtpRtcp*> deregistered_modules; | |
| 356 size_t num_active_modules = video_codec.numberOfSimulcastStreams > 0 | |
| 357 ? video_codec.numberOfSimulcastStreams | |
| 358 : 1; | |
| 359 size_t num_prev_active_modules; | |
| 360 { | |
| 361 // Cache which modules are active so StartSend can know which ones to start. | |
| 362 CriticalSectionScoped cs(crit_.get()); | |
| 363 num_prev_active_modules = num_active_rtp_rtcp_modules_; | |
| 364 num_active_rtp_rtcp_modules_ = num_active_modules; | |
| 365 } | |
| 366 for (size_t i = 0; i < num_active_modules; ++i) | |
| 367 registered_modules.push_back(rtp_rtcp_modules_[i]); | |
| 368 | |
| 369 for (size_t i = num_active_modules; i < rtp_rtcp_modules_.size(); ++i) | |
| 370 deregistered_modules.push_back(rtp_rtcp_modules_[i]); | |
| 371 | |
| 372 // Disable inactive modules. | |
| 373 for (RtpRtcp* rtp_rtcp : deregistered_modules) { | |
| 374 rtp_rtcp->SetSendingStatus(false); | |
| 375 rtp_rtcp->SetSendingMediaStatus(false); | |
| 376 } | |
| 377 | |
| 378 // Configure active modules. | |
| 379 for (RtpRtcp* rtp_rtcp : registered_modules) { | |
| 380 rtp_rtcp->DeRegisterSendPayload(video_codec.plType); | |
| 381 if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) { | |
| 382 return -1; | |
| 383 } | |
| 384 rtp_rtcp->SetSendingStatus(is_sending); | |
| 385 rtp_rtcp->SetSendingMediaStatus(is_sending); | |
| 386 } | |
| 387 | |
| 388 // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old | |
| 389 // modules can be deleted after this step. | |
| 390 vie_receiver_.RegisterRtpRtcpModules(registered_modules); | |
| 391 | |
| 392 // Update the packet and payload routers with the sending RtpRtcp modules. | |
| 393 if (sender_) { | |
| 394 std::list<RtpRtcp*> active_send_modules; | |
| 395 for (RtpRtcp* rtp_rtcp : registered_modules) | |
| 396 active_send_modules.push_back(rtp_rtcp); | |
| 397 send_payload_router_->SetSendingRtpModules(active_send_modules); | |
| 398 } | |
| 399 | |
| 400 if (router_was_active) | |
| 401 send_payload_router_->set_active(true); | |
| 402 | |
| 403 // Deregister previously registered modules. | |
| 404 for (size_t i = num_active_modules; i < num_prev_active_modules; ++i) { | |
| 405 module_process_thread_->DeRegisterModule(rtp_rtcp_modules_[i]); | |
| 406 packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]); | |
| 407 } | |
| 408 // Register new active modules. | |
| 409 for (size_t i = num_prev_active_modules; i < num_active_modules; ++i) { | |
| 410 module_process_thread_->RegisterModule(rtp_rtcp_modules_[i]); | |
| 411 packet_router_->AddRtpModule(rtp_rtcp_modules_[i]); | |
| 412 } | |
| 413 return 0; | |
| 414 } | |
| 415 | |
| 416 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { | |
| 417 RTC_DCHECK(!sender_); | |
| 418 if (!vie_receiver_.SetReceiveCodec(video_codec)) { | |
| 419 return -1; | |
| 420 } | |
| 421 | |
| 422 if (video_codec.codecType != kVideoCodecRED && | |
| 423 video_codec.codecType != kVideoCodecULPFEC) { | |
| 424 // Register codec type with VCM, but do not register RED or ULPFEC. | |
| 425 if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_, false) != | |
| 426 VCM_OK) { | |
| 427 return -1; | |
| 428 } | |
| 429 } | |
| 430 return 0; | |
| 431 } | |
| 432 | |
| 433 | |
| 434 int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type, | |
| 435 VideoDecoder* decoder, | |
| 436 bool buffered_rendering, | |
| 437 int32_t render_delay) { | |
| 438 RTC_DCHECK(!sender_); | |
| 439 vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering); | |
| 440 return vcm_->SetRenderDelay(render_delay); | |
| 441 } | |
| 442 | |
| 443 int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames, | |
| 444 uint32_t* num_delta_frames) { | |
| 445 CriticalSectionScoped cs(crit_.get()); | |
| 446 *num_key_frames = receive_frame_counts_.key_frames; | |
| 447 *num_delta_frames = receive_frame_counts_.delta_frames; | |
| 448 return 0; | |
| 449 } | |
| 450 | |
| 451 uint32_t ViEChannel::DiscardedPackets() const { | |
| 452 return vcm_->DiscardedPackets(); | |
| 453 } | |
| 454 | |
| 455 int ViEChannel::ReceiveDelay() const { | |
| 456 return vcm_->Delay(); | |
| 457 } | |
| 458 | |
| 459 void ViEChannel::SetRTCPMode(const RtcpMode rtcp_mode) { | |
| 460 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 461 rtp_rtcp->SetRTCPStatus(rtcp_mode); | |
| 462 } | |
| 463 | |
| 464 void ViEChannel::SetProtectionMode(bool enable_nack, | |
| 465 bool enable_fec, | |
| 466 int payload_type_red, | |
| 467 int payload_type_fec) { | |
| 468 // Validate payload types. | |
| 469 if (enable_fec) { | |
| 470 RTC_DCHECK_GE(payload_type_red, 0); | |
| 471 RTC_DCHECK_GE(payload_type_fec, 0); | |
| 472 RTC_DCHECK_LE(payload_type_red, 127); | |
| 473 RTC_DCHECK_LE(payload_type_fec, 127); | |
| 474 } else { | |
| 475 RTC_DCHECK_EQ(payload_type_red, -1); | |
| 476 RTC_DCHECK_EQ(payload_type_fec, -1); | |
| 477 // Set to valid uint8_ts to be castable later without signed overflows. | |
| 478 payload_type_red = 0; | |
| 479 payload_type_fec = 0; | |
| 480 } | |
| 481 | |
| 482 VCMVideoProtection protection_method; | |
| 483 if (enable_nack) { | |
| 484 protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack; | |
| 485 } else { | |
| 486 protection_method = kProtectionNone; | |
| 487 } | |
| 488 | |
| 489 vcm_->SetVideoProtection(protection_method, true); | |
| 490 | |
| 491 // Set NACK. | |
| 492 ProcessNACKRequest(enable_nack); | |
| 493 | |
| 494 // Set FEC. | |
| 495 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 496 rtp_rtcp->SetGenericFECStatus(enable_fec, | |
| 497 static_cast<uint8_t>(payload_type_red), | |
| 498 static_cast<uint8_t>(payload_type_fec)); | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 void ViEChannel::ProcessNACKRequest(const bool enable) { | |
| 503 if (enable) { | |
| 504 // Turn on NACK. | |
| 505 if (rtp_rtcp_modules_[0]->RTCP() == RtcpMode::kOff) | |
| 506 return; | |
| 507 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); | |
| 508 | |
| 509 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 510 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); | |
| 511 | |
| 512 vcm_->RegisterPacketRequestCallback(this); | |
| 513 // Don't introduce errors when NACK is enabled. | |
| 514 vcm_->SetDecodeErrorMode(kNoErrors); | |
| 515 } else { | |
| 516 vcm_->RegisterPacketRequestCallback(NULL); | |
| 517 if (paced_sender_ == nullptr) { | |
| 518 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 519 rtp_rtcp->SetStorePacketsStatus(false, 0); | |
| 520 } | |
| 521 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); | |
| 522 // When NACK is off, allow decoding with errors. Otherwise, the video | |
| 523 // will freeze, and will only recover with a complete key frame. | |
| 524 vcm_->SetDecodeErrorMode(kWithErrors); | |
| 525 } | |
| 526 } | |
| 527 | |
| 528 bool ViEChannel::IsSendingFecEnabled() { | |
| 529 bool fec_enabled = false; | |
| 530 uint8_t pltype_red = 0; | |
| 531 uint8_t pltype_fec = 0; | |
| 532 | |
| 533 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 534 rtp_rtcp->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); | |
| 535 if (fec_enabled) | |
| 536 return true; | |
| 537 } | |
| 538 return false; | |
| 539 } | |
| 540 | |
| 541 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { | |
| 542 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { | |
| 543 LOG(LS_ERROR) << "Invalid send buffer value."; | |
| 544 return -1; | |
| 545 } | |
| 546 if (target_delay_ms == 0) { | |
| 547 // Real-time mode. | |
| 548 nack_history_size_sender_ = kMinSendSidePacketHistorySize; | |
| 549 } else { | |
| 550 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms); | |
| 551 // Don't allow a number lower than the default value. | |
| 552 if (nack_history_size_sender_ < kMinSendSidePacketHistorySize) { | |
| 553 nack_history_size_sender_ = kMinSendSidePacketHistorySize; | |
| 554 } | |
| 555 } | |
| 556 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 557 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); | |
| 558 return 0; | |
| 559 } | |
| 560 | |
| 561 int ViEChannel::GetRequiredNackListSize(int target_delay_ms) { | |
| 562 // The max size of the nack list should be large enough to accommodate the | |
| 563 // the number of packets (frames) resulting from the increased delay. | |
| 564 // Roughly estimating for ~40 packets per frame @ 30fps. | |
| 565 return target_delay_ms * 40 * 30 / 1000; | |
| 566 } | |
| 567 | |
| 568 int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) { | |
| 569 // Disable any previous registrations of this extension to avoid errors. | |
| 570 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 571 rtp_rtcp->DeregisterSendRtpHeaderExtension( | |
| 572 kRtpExtensionTransmissionTimeOffset); | |
| 573 } | |
| 574 if (!enable) | |
| 575 return 0; | |
| 576 // Enable the extension. | |
| 577 int error = 0; | |
| 578 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 579 error |= rtp_rtcp->RegisterSendRtpHeaderExtension( | |
| 580 kRtpExtensionTransmissionTimeOffset, id); | |
| 581 } | |
| 582 return error; | |
| 583 } | |
| 584 | |
| 585 int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) { | |
| 586 return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1; | |
| 587 } | |
| 588 | |
| 589 int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { | |
| 590 // Disable any previous registrations of this extension to avoid errors. | |
| 591 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 592 rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionAbsoluteSendTime); | |
| 593 if (!enable) | |
| 594 return 0; | |
| 595 // Enable the extension. | |
| 596 int error = 0; | |
| 597 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 598 error |= rtp_rtcp->RegisterSendRtpHeaderExtension( | |
| 599 kRtpExtensionAbsoluteSendTime, id); | |
| 600 } | |
| 601 return error; | |
| 602 } | |
| 603 | |
| 604 int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { | |
| 605 return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1; | |
| 606 } | |
| 607 | |
| 608 int ViEChannel::SetSendVideoRotationStatus(bool enable, int id) { | |
| 609 // Disable any previous registrations of this extension to avoid errors. | |
| 610 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 611 rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation); | |
| 612 if (!enable) | |
| 613 return 0; | |
| 614 // Enable the extension. | |
| 615 int error = 0; | |
| 616 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 617 error |= rtp_rtcp->RegisterSendRtpHeaderExtension( | |
| 618 kRtpExtensionVideoRotation, id); | |
| 619 } | |
| 620 return error; | |
| 621 } | |
| 622 | |
| 623 int ViEChannel::SetReceiveVideoRotationStatus(bool enable, int id) { | |
| 624 return vie_receiver_.SetReceiveVideoRotationStatus(enable, id) ? 0 : -1; | |
| 625 } | |
| 626 | |
| 627 int ViEChannel::SetSendTransportSequenceNumber(bool enable, int id) { | |
| 628 // Disable any previous registrations of this extension to avoid errors. | |
| 629 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 630 rtp_rtcp->DeregisterSendRtpHeaderExtension( | |
| 631 kRtpExtensionTransportSequenceNumber); | |
| 632 } | |
| 633 if (!enable) | |
| 634 return 0; | |
| 635 // Enable the extension. | |
| 636 int error = 0; | |
| 637 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 638 error |= rtp_rtcp->RegisterSendRtpHeaderExtension( | |
| 639 kRtpExtensionTransportSequenceNumber, id); | |
| 640 } | |
| 641 return error; | |
| 642 } | |
| 643 | |
| 644 int ViEChannel::SetReceiveTransportSequenceNumber(bool enable, int id) { | |
| 645 return vie_receiver_.SetReceiveTransportSequenceNumber(enable, id) ? 0 : -1; | |
| 646 } | |
| 647 | |
| 648 void ViEChannel::SetRtcpXrRrtrStatus(bool enable) { | |
| 649 rtp_rtcp_modules_[0]->SetRtcpXrRrtrStatus(enable); | |
| 650 } | |
| 651 | |
| 652 void ViEChannel::EnableTMMBR(bool enable) { | |
| 653 rtp_rtcp_modules_[0]->SetTMMBRStatus(enable); | |
| 654 } | |
| 655 | |
| 656 int32_t ViEChannel::SetSSRC(const uint32_t SSRC, | |
| 657 const StreamType usage, | |
| 658 const uint8_t simulcast_idx) { | |
| 659 RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[simulcast_idx]; | |
| 660 if (usage == kViEStreamTypeRtx) { | |
| 661 rtp_rtcp->SetRtxSsrc(SSRC); | |
| 662 } else { | |
| 663 rtp_rtcp->SetSSRC(SSRC); | |
| 664 } | |
| 665 return 0; | |
| 666 } | |
| 667 | |
| 668 int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage, | |
| 669 const uint32_t SSRC) { | |
| 670 vie_receiver_.SetRtxSsrc(SSRC); | |
| 671 return 0; | |
| 672 } | |
| 673 | |
| 674 int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) { | |
| 675 RTC_DCHECK_LE(idx, rtp_rtcp_modules_.size()); | |
| 676 *ssrc = rtp_rtcp_modules_[idx]->SSRC(); | |
| 677 return 0; | |
| 678 } | |
| 679 | |
| 680 uint32_t ViEChannel::GetRemoteSSRC() { | |
| 681 return vie_receiver_.GetRemoteSsrc(); | |
| 682 } | |
| 683 | |
| 684 int ViEChannel::SetRtxSendPayloadType(int payload_type, | |
| 685 int associated_payload_type) { | |
| 686 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 687 rtp_rtcp->SetRtxSendPayloadType(payload_type, associated_payload_type); | |
| 688 SetRtxSendStatus(true); | |
| 689 return 0; | |
| 690 } | |
| 691 | |
| 692 void ViEChannel::SetRtxSendStatus(bool enable) { | |
| 693 int rtx_settings = | |
| 694 enable ? kRtxRetransmitted | kRtxRedundantPayloads : kRtxOff; | |
| 695 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 696 rtp_rtcp->SetRtxSendStatus(rtx_settings); | |
| 697 } | |
| 698 | |
| 699 void ViEChannel::SetRtxReceivePayloadType(int payload_type, | |
| 700 int associated_payload_type) { | |
| 701 vie_receiver_.SetRtxPayloadType(payload_type, associated_payload_type); | |
| 702 } | |
| 703 | |
| 704 void ViEChannel::SetUseRtxPayloadMappingOnRestore(bool val) { | |
| 705 vie_receiver_.SetUseRtxPayloadMappingOnRestore(val); | |
| 706 } | |
| 707 | |
| 708 void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) { | |
| 709 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); | |
| 710 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 711 if (rtp_rtcp->SetRtpStateForSsrc(ssrc, rtp_state)) | |
| 712 return; | |
| 713 } | |
| 714 } | |
| 715 | |
| 716 RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) { | |
| 717 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); | |
| 718 RtpState rtp_state; | |
| 719 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 720 if (rtp_rtcp->GetRtpStateForSsrc(ssrc, &rtp_state)) | |
| 721 return rtp_state; | |
| 722 } | |
| 723 LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc; | |
| 724 return rtp_state; | |
| 725 } | |
| 726 | |
| 727 // TODO(pbos): Set CNAME on all modules. | |
| 728 int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) { | |
| 729 RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending()); | |
| 730 return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname); | |
| 731 } | |
| 732 | |
| 733 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) { | |
| 734 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc(); | |
| 735 return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname); | |
| 736 } | |
| 737 | |
| 738 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost, | |
| 739 uint32_t* cumulative_lost, | |
| 740 uint32_t* extended_max, | |
| 741 uint32_t* jitter_samples, | |
| 742 int64_t* rtt_ms) { | |
| 743 // Aggregate the report blocks associated with streams sent on this channel. | |
| 744 std::vector<RTCPReportBlock> report_blocks; | |
| 745 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 746 rtp_rtcp->RemoteRTCPStat(&report_blocks); | |
| 747 | |
| 748 if (report_blocks.empty()) | |
| 749 return -1; | |
| 750 | |
| 751 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc(); | |
| 752 std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin(); | |
| 753 for (; it != report_blocks.end(); ++it) { | |
| 754 if (it->remoteSSRC == remote_ssrc) | |
| 755 break; | |
| 756 } | |
| 757 if (it == report_blocks.end()) { | |
| 758 // We have not received packets with an SSRC matching the report blocks. To | |
| 759 // have a chance of calculating an RTT we will try with the SSRC of the | |
| 760 // first report block received. | |
| 761 // This is very important for send-only channels where we don't know the | |
| 762 // SSRC of the other end. | |
| 763 remote_ssrc = report_blocks[0].remoteSSRC; | |
| 764 } | |
| 765 | |
| 766 // TODO(asapersson): Change report_block_stats to not rely on | |
| 767 // GetSendRtcpStatistics to be called. | |
| 768 RTCPReportBlock report = | |
| 769 report_block_stats_sender_->AggregateAndStore(report_blocks); | |
| 770 *fraction_lost = report.fractionLost; | |
| 771 *cumulative_lost = report.cumulativeLost; | |
| 772 *extended_max = report.extendedHighSeqNum; | |
| 773 *jitter_samples = report.jitter; | |
| 774 | |
| 775 int64_t dummy; | |
| 776 int64_t rtt = 0; | |
| 777 if (rtp_rtcp_modules_[0]->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != | |
| 778 0) { | |
| 779 return -1; | |
| 780 } | |
| 781 *rtt_ms = rtt; | |
| 782 return 0; | |
| 783 } | |
| 784 | |
| 785 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback( | |
| 786 RtcpStatisticsCallback* callback) { | |
| 787 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 788 rtp_rtcp->RegisterRtcpStatisticsCallback(callback); | |
| 789 } | |
| 790 | |
| 791 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback( | |
| 792 RtcpStatisticsCallback* callback) { | |
| 793 vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback( | |
| 794 callback); | |
| 795 rtp_rtcp_modules_[0]->RegisterRtcpStatisticsCallback(callback); | |
| 796 } | |
| 797 | |
| 798 void ViEChannel::RegisterRtcpPacketTypeCounterObserver( | |
| 799 RtcpPacketTypeCounterObserver* observer) { | |
| 800 rtcp_packet_type_counter_observer_.Set(observer); | |
| 801 } | |
| 802 | |
| 803 void ViEChannel::GetSendStreamDataCounters( | |
| 804 StreamDataCounters* rtp_counters, | |
| 805 StreamDataCounters* rtx_counters) const { | |
| 806 *rtp_counters = StreamDataCounters(); | |
| 807 *rtx_counters = StreamDataCounters(); | |
| 808 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 809 StreamDataCounters rtp_data; | |
| 810 StreamDataCounters rtx_data; | |
| 811 rtp_rtcp->GetSendStreamDataCounters(&rtp_data, &rtx_data); | |
| 812 rtp_counters->Add(rtp_data); | |
| 813 rtx_counters->Add(rtx_data); | |
| 814 } | |
| 815 } | |
| 816 | |
| 817 void ViEChannel::GetReceiveStreamDataCounters( | |
| 818 StreamDataCounters* rtp_counters, | |
| 819 StreamDataCounters* rtx_counters) const { | |
| 820 StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()-> | |
| 821 GetStatistician(vie_receiver_.GetRemoteSsrc()); | |
| 822 if (statistician) { | |
| 823 statistician->GetReceiveStreamDataCounters(rtp_counters); | |
| 824 } | |
| 825 uint32_t rtx_ssrc = 0; | |
| 826 if (vie_receiver_.GetRtxSsrc(&rtx_ssrc)) { | |
| 827 StreamStatistician* statistician = | |
| 828 vie_receiver_.GetReceiveStatistics()->GetStatistician(rtx_ssrc); | |
| 829 if (statistician) { | |
| 830 statistician->GetReceiveStreamDataCounters(rtx_counters); | |
| 831 } | |
| 832 } | |
| 833 } | |
| 834 | |
| 835 void ViEChannel::RegisterSendChannelRtpStatisticsCallback( | |
| 836 StreamDataCountersCallback* callback) { | |
| 837 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 838 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(callback); | |
| 839 } | |
| 840 | |
| 841 void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback( | |
| 842 StreamDataCountersCallback* callback) { | |
| 843 vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback); | |
| 844 } | |
| 845 | |
| 846 void ViEChannel::GetSendRtcpPacketTypeCounter( | |
| 847 RtcpPacketTypeCounter* packet_counter) const { | |
| 848 std::map<uint32_t, RtcpPacketTypeCounter> counter_map = | |
| 849 rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap(); | |
| 850 | |
| 851 RtcpPacketTypeCounter counter; | |
| 852 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 853 counter.Add(counter_map[rtp_rtcp->SSRC()]); | |
| 854 *packet_counter = counter; | |
| 855 } | |
| 856 | |
| 857 void ViEChannel::GetReceiveRtcpPacketTypeCounter( | |
| 858 RtcpPacketTypeCounter* packet_counter) const { | |
| 859 std::map<uint32_t, RtcpPacketTypeCounter> counter_map = | |
| 860 rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap(); | |
| 861 | |
| 862 RtcpPacketTypeCounter counter; | |
| 863 counter.Add(counter_map[vie_receiver_.GetRemoteSsrc()]); | |
| 864 | |
| 865 *packet_counter = counter; | |
| 866 } | |
| 867 | |
| 868 void ViEChannel::RegisterSendSideDelayObserver( | |
| 869 SendSideDelayObserver* observer) { | |
| 870 send_side_delay_observer_.Set(observer); | |
| 871 } | |
| 872 | |
| 873 void ViEChannel::RegisterSendBitrateObserver( | |
| 874 BitrateStatisticsObserver* observer) { | |
| 875 send_bitrate_observer_.Set(observer); | |
| 876 } | |
| 877 | |
| 878 int32_t ViEChannel::StartSend() { | |
| 879 CriticalSectionScoped cs(crit_.get()); | |
| 880 | |
| 881 if (rtp_rtcp_modules_[0]->Sending()) | |
| 882 return -1; | |
| 883 | |
| 884 for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) { | |
| 885 RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i]; | |
| 886 rtp_rtcp->SetSendingMediaStatus(true); | |
| 887 rtp_rtcp->SetSendingStatus(true); | |
| 888 } | |
| 889 send_payload_router_->set_active(true); | |
| 890 return 0; | |
| 891 } | |
| 892 | |
| 893 int32_t ViEChannel::StopSend() { | |
| 894 send_payload_router_->set_active(false); | |
| 895 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 896 rtp_rtcp->SetSendingMediaStatus(false); | |
| 897 | |
| 898 if (!rtp_rtcp_modules_[0]->Sending()) { | |
| 899 return -1; | |
| 900 } | |
| 901 | |
| 902 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 903 rtp_rtcp->SetSendingStatus(false); | |
| 904 } | |
| 905 return 0; | |
| 906 } | |
| 907 | |
| 908 bool ViEChannel::Sending() { | |
| 909 return rtp_rtcp_modules_[0]->Sending(); | |
| 910 } | |
| 911 | |
| 912 void ViEChannel::StartReceive() { | |
| 913 if (!sender_) | |
| 914 StartDecodeThread(); | |
| 915 vie_receiver_.StartReceive(); | |
| 916 } | |
| 917 | |
| 918 void ViEChannel::StopReceive() { | |
| 919 vie_receiver_.StopReceive(); | |
| 920 if (!sender_) { | |
| 921 StopDecodeThread(); | |
| 922 vcm_->ResetDecoder(); | |
| 923 } | |
| 924 } | |
| 925 | |
| 926 int32_t ViEChannel::ReceivedRTPPacket(const void* rtp_packet, | |
| 927 size_t rtp_packet_length, | |
| 928 const PacketTime& packet_time) { | |
| 929 return vie_receiver_.ReceivedRTPPacket( | |
| 930 rtp_packet, rtp_packet_length, packet_time); | |
| 931 } | |
| 932 | |
| 933 int32_t ViEChannel::ReceivedRTCPPacket(const void* rtcp_packet, | |
| 934 size_t rtcp_packet_length) { | |
| 935 return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length); | |
| 936 } | |
| 937 | |
| 938 int32_t ViEChannel::SetMTU(uint16_t mtu) { | |
| 939 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 940 rtp_rtcp->SetMaxTransferUnit(mtu); | |
| 941 return 0; | |
| 942 } | |
| 943 | |
| 944 RtpRtcp* ViEChannel::rtp_rtcp() { | |
| 945 return rtp_rtcp_modules_[0]; | |
| 946 } | |
| 947 | |
| 948 rtc::scoped_refptr<PayloadRouter> ViEChannel::send_payload_router() { | |
| 949 return send_payload_router_; | |
| 950 } | |
| 951 | |
| 952 VCMProtectionCallback* ViEChannel::vcm_protection_callback() { | |
| 953 return vcm_protection_callback_.get(); | |
| 954 } | |
| 955 | |
| 956 CallStatsObserver* ViEChannel::GetStatsObserver() { | |
| 957 return stats_observer_.get(); | |
| 958 } | |
| 959 | |
| 960 // Do not acquire the lock of |vcm_| in this function. Decode callback won't | |
| 961 // necessarily be called from the decoding thread. The decoding thread may have | |
| 962 // held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring | |
| 963 // the same lock in the path of decode callback can deadlock. | |
| 964 int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT | |
| 965 CriticalSectionScoped cs(crit_.get()); | |
| 966 | |
| 967 if (pre_render_callback_ != NULL) | |
| 968 pre_render_callback_->FrameCallback(&video_frame); | |
| 969 | |
| 970 // TODO(pbos): Remove stream id argument. | |
| 971 incoming_video_stream_->RenderFrame(0xFFFFFFFF, video_frame); | |
| 972 return 0; | |
| 973 } | |
| 974 | |
| 975 int32_t ViEChannel::ReceivedDecodedReferenceFrame( | |
| 976 const uint64_t picture_id) { | |
| 977 return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id); | |
| 978 } | |
| 979 | |
| 980 void ViEChannel::OnIncomingPayloadType(int payload_type) { | |
| 981 CriticalSectionScoped cs(crit_.get()); | |
| 982 if (receive_stats_callback_) | |
| 983 receive_stats_callback_->OnIncomingPayloadType(payload_type); | |
| 984 } | |
| 985 | |
| 986 void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) { | |
| 987 CriticalSectionScoped cs(crit_.get()); | |
| 988 if (receive_stats_callback_) | |
| 989 receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate); | |
| 990 } | |
| 991 | |
| 992 void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) { | |
| 993 CriticalSectionScoped cs(crit_.get()); | |
| 994 if (receive_stats_callback_) | |
| 995 receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets); | |
| 996 } | |
| 997 | |
| 998 void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) { | |
| 999 CriticalSectionScoped cs(crit_.get()); | |
| 1000 receive_frame_counts_ = frame_counts; | |
| 1001 if (receive_stats_callback_) | |
| 1002 receive_stats_callback_->OnFrameCountsUpdated(frame_counts); | |
| 1003 } | |
| 1004 | |
| 1005 void ViEChannel::OnDecoderTiming(int decode_ms, | |
| 1006 int max_decode_ms, | |
| 1007 int current_delay_ms, | |
| 1008 int target_delay_ms, | |
| 1009 int jitter_buffer_ms, | |
| 1010 int min_playout_delay_ms, | |
| 1011 int render_delay_ms) { | |
| 1012 CriticalSectionScoped cs(crit_.get()); | |
| 1013 if (!receive_stats_callback_) | |
| 1014 return; | |
| 1015 receive_stats_callback_->OnDecoderTiming( | |
| 1016 decode_ms, max_decode_ms, current_delay_ms, target_delay_ms, | |
| 1017 jitter_buffer_ms, min_playout_delay_ms, render_delay_ms, last_rtt_ms_); | |
| 1018 } | |
| 1019 | |
| 1020 int32_t ViEChannel::RequestKeyFrame() { | |
| 1021 return rtp_rtcp_modules_[0]->RequestKeyFrame(); | |
| 1022 } | |
| 1023 | |
| 1024 int32_t ViEChannel::SliceLossIndicationRequest( | |
| 1025 const uint64_t picture_id) { | |
| 1026 return rtp_rtcp_modules_[0]->SendRTCPSliceLossIndication( | |
| 1027 static_cast<uint8_t>(picture_id)); | |
| 1028 } | |
| 1029 | |
| 1030 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers, | |
| 1031 uint16_t length) { | |
| 1032 return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length); | |
| 1033 } | |
| 1034 | |
| 1035 bool ViEChannel::ChannelDecodeThreadFunction(void* obj) { | |
| 1036 return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess(); | |
| 1037 } | |
| 1038 | |
| 1039 bool ViEChannel::ChannelDecodeProcess() { | |
| 1040 vcm_->Decode(kMaxDecodeWaitTimeMs); | |
| 1041 return true; | |
| 1042 } | |
| 1043 | |
| 1044 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | |
| 1045 vcm_->SetReceiveChannelParameters(max_rtt_ms); | |
| 1046 | |
| 1047 CriticalSectionScoped cs(crit_.get()); | |
| 1048 if (time_of_first_rtt_ms_ == -1) | |
| 1049 time_of_first_rtt_ms_ = Clock::GetRealTimeClock()->TimeInMilliseconds(); | |
| 1050 rtt_sum_ms_ += avg_rtt_ms; | |
| 1051 last_rtt_ms_ = avg_rtt_ms; | |
| 1052 ++num_rtts_; | |
| 1053 } | |
| 1054 | |
| 1055 int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params, | |
| 1056 const FecProtectionParams* key_fec_params, | |
| 1057 uint32_t* video_rate_bps, | |
| 1058 uint32_t* nack_rate_bps, | |
| 1059 uint32_t* fec_rate_bps) { | |
| 1060 *video_rate_bps = 0; | |
| 1061 *nack_rate_bps = 0; | |
| 1062 *fec_rate_bps = 0; | |
| 1063 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | |
| 1064 uint32_t not_used = 0; | |
| 1065 uint32_t module_video_rate = 0; | |
| 1066 uint32_t module_fec_rate = 0; | |
| 1067 uint32_t module_nack_rate = 0; | |
| 1068 rtp_rtcp->SetFecParameters(delta_fec_params, key_fec_params); | |
| 1069 rtp_rtcp->BitrateSent(¬_used, &module_video_rate, &module_fec_rate, | |
| 1070 &module_nack_rate); | |
| 1071 *video_rate_bps += module_video_rate; | |
| 1072 *nack_rate_bps += module_nack_rate; | |
| 1073 *fec_rate_bps += module_fec_rate; | |
| 1074 } | |
| 1075 return 0; | |
| 1076 } | |
| 1077 | |
| 1078 std::vector<RtpRtcp*> ViEChannel::CreateRtpRtcpModules( | |
| 1079 bool receiver_only, | |
| 1080 ReceiveStatistics* receive_statistics, | |
| 1081 Transport* outgoing_transport, | |
| 1082 RtcpIntraFrameObserver* intra_frame_callback, | |
| 1083 RtcpBandwidthObserver* bandwidth_callback, | |
| 1084 TransportFeedbackObserver* transport_feedback_callback, | |
| 1085 RtcpRttStats* rtt_stats, | |
| 1086 RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, | |
| 1087 RemoteBitrateEstimator* remote_bitrate_estimator, | |
| 1088 RtpPacketSender* paced_sender, | |
| 1089 TransportSequenceNumberAllocator* transport_sequence_number_allocator, | |
| 1090 BitrateStatisticsObserver* send_bitrate_observer, | |
| 1091 FrameCountObserver* send_frame_count_observer, | |
| 1092 SendSideDelayObserver* send_side_delay_observer, | |
| 1093 size_t num_modules) { | |
| 1094 RTC_DCHECK_GT(num_modules, 0u); | |
| 1095 RtpRtcp::Configuration configuration; | |
| 1096 ReceiveStatistics* null_receive_statistics = configuration.receive_statistics; | |
| 1097 configuration.audio = false; | |
| 1098 configuration.receiver_only = receiver_only; | |
| 1099 configuration.receive_statistics = receive_statistics; | |
| 1100 configuration.outgoing_transport = outgoing_transport; | |
| 1101 configuration.intra_frame_callback = intra_frame_callback; | |
| 1102 configuration.rtt_stats = rtt_stats; | |
| 1103 configuration.rtcp_packet_type_counter_observer = | |
| 1104 rtcp_packet_type_counter_observer; | |
| 1105 configuration.paced_sender = paced_sender; | |
| 1106 configuration.transport_sequence_number_allocator = | |
| 1107 transport_sequence_number_allocator; | |
| 1108 configuration.send_bitrate_observer = send_bitrate_observer; | |
| 1109 configuration.send_frame_count_observer = send_frame_count_observer; | |
| 1110 configuration.send_side_delay_observer = send_side_delay_observer; | |
| 1111 configuration.bandwidth_callback = bandwidth_callback; | |
| 1112 configuration.transport_feedback_callback = transport_feedback_callback; | |
| 1113 | |
| 1114 std::vector<RtpRtcp*> modules; | |
| 1115 for (size_t i = 0; i < num_modules; ++i) { | |
| 1116 RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration); | |
| 1117 rtp_rtcp->SetSendingStatus(false); | |
| 1118 rtp_rtcp->SetSendingMediaStatus(false); | |
| 1119 rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound); | |
| 1120 modules.push_back(rtp_rtcp); | |
| 1121 // Receive statistics and remote bitrate estimator should only be set for | |
| 1122 // the primary (first) module. | |
| 1123 configuration.receive_statistics = null_receive_statistics; | |
| 1124 configuration.remote_bitrate_estimator = nullptr; | |
| 1125 } | |
| 1126 return modules; | |
| 1127 } | |
| 1128 | |
| 1129 void ViEChannel::StartDecodeThread() { | |
| 1130 RTC_DCHECK(!sender_); | |
| 1131 if (decode_thread_.IsRunning()) | |
| 1132 return; | |
| 1133 // Start the decode thread | |
| 1134 decode_thread_.Start(); | |
| 1135 decode_thread_.SetPriority(rtc::kHighestPriority); | |
| 1136 } | |
| 1137 | |
| 1138 void ViEChannel::StopDecodeThread() { | |
| 1139 vcm_->TriggerDecoderShutdown(); | |
| 1140 | |
| 1141 decode_thread_.Stop(); | |
| 1142 } | |
| 1143 | |
| 1144 int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id, | |
| 1145 VoEVideoSync* ve_sync_interface) { | |
| 1146 return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface, | |
| 1147 rtp_rtcp_modules_[0], | |
| 1148 vie_receiver_.GetRtpReceiver()); | |
| 1149 } | |
| 1150 | |
| 1151 int32_t ViEChannel::VoiceChannel() { | |
| 1152 return vie_sync_.VoiceChannel(); | |
| 1153 } | |
| 1154 | |
| 1155 void ViEChannel::RegisterPreRenderCallback( | |
| 1156 I420FrameCallback* pre_render_callback) { | |
| 1157 CriticalSectionScoped cs(crit_.get()); | |
| 1158 pre_render_callback_ = pre_render_callback; | |
| 1159 } | |
| 1160 | |
| 1161 void ViEChannel::RegisterPreDecodeImageCallback( | |
| 1162 EncodedImageCallback* pre_decode_callback) { | |
| 1163 vcm_->RegisterPreDecodeImageCallback(pre_decode_callback); | |
| 1164 } | |
| 1165 | |
| 1166 // TODO(pbos): Remove OnInitializeDecoder which is called from the RTP module, | |
| 1167 // any decoder resetting should be handled internally within the VCM. | |
| 1168 int32_t ViEChannel::OnInitializeDecoder( | |
| 1169 const int8_t payload_type, | |
| 1170 const char payload_name[RTP_PAYLOAD_NAME_SIZE], | |
| 1171 const int frequency, | |
| 1172 const uint8_t channels, | |
| 1173 const uint32_t rate) { | |
| 1174 LOG(LS_INFO) << "OnInitializeDecoder " << static_cast<int>(payload_type) | |
| 1175 << " " << payload_name; | |
| 1176 vcm_->ResetDecoder(); | |
| 1177 | |
| 1178 return 0; | |
| 1179 } | |
| 1180 | |
| 1181 void ViEChannel::OnIncomingSSRCChanged(const uint32_t ssrc) { | |
| 1182 rtp_rtcp_modules_[0]->SetRemoteSSRC(ssrc); | |
| 1183 } | |
| 1184 | |
| 1185 void ViEChannel::OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) {} | |
| 1186 | |
| 1187 void ViEChannel::RegisterSendFrameCountObserver( | |
| 1188 FrameCountObserver* observer) { | |
| 1189 send_frame_count_observer_.Set(observer); | |
| 1190 } | |
| 1191 | |
| 1192 void ViEChannel::RegisterReceiveStatisticsProxy( | |
| 1193 ReceiveStatisticsProxy* receive_statistics_proxy) { | |
| 1194 CriticalSectionScoped cs(crit_.get()); | |
| 1195 receive_stats_callback_ = receive_statistics_proxy; | |
| 1196 } | |
| 1197 | |
| 1198 void ViEChannel::SetIncomingVideoStream( | |
| 1199 IncomingVideoStream* incoming_video_stream) { | |
| 1200 CriticalSectionScoped cs(crit_.get()); | |
| 1201 incoming_video_stream_ = incoming_video_stream; | |
| 1202 } | |
| 1203 } // namespace webrtc | |
| OLD | NEW |