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 |