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_engine/vie_channel.h"
12
13 #include <algorithm>
14 #include <vector>
15
16 #include "webrtc/common.h"
17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
18 #include "webrtc/experiments.h"
19 #include "webrtc/modules/pacing/include/paced_sender.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
21 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
22 #include "webrtc/modules/utility/interface/process_thread.h"
23 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
24 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
25 #include "webrtc/modules/video_render/include/video_render_defines.h"
26 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
27 #include "webrtc/system_wrappers/interface/logging.h"
28 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
29 #include "webrtc/video_engine/call_stats.h"
30 #include "webrtc/video_engine/include/vie_codec.h"
31 #include "webrtc/video_engine/include/vie_errors.h"
32 #include "webrtc/video_engine/include/vie_image_process.h"
33 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
34 #include "webrtc/frame_callback.h"
35 #include "webrtc/video_engine/vie_defines.h"
36
37 namespace webrtc {
38
39 const int kMaxDecodeWaitTimeMs = 50;
40 const int kInvalidRtpExtensionId = 0;
41 static const int kMaxTargetDelayMs = 10000;
42 static const float kMaxIncompleteTimeMultiplier = 3.5f;
43
44 namespace {
45
AggregateReportBlocks(const std::vector<RTCPReportBlock> & report_blocks,std::map<uint32_t,RTCPReportBlock> * prev_report_blocks)46 RTCPReportBlock AggregateReportBlocks(
47 const std::vector<RTCPReportBlock>& report_blocks,
48 std::map<uint32_t, RTCPReportBlock>* prev_report_blocks) {
49 int fraction_lost_sum = 0;
50 int fl_seq_num_sum = 0;
51 int jitter_sum = 0;
52 int number_of_report_blocks = 0;
53 RTCPReportBlock aggregate;
54 std::vector<RTCPReportBlock>::const_iterator report_block =
55 report_blocks.begin();
56 for (; report_block != report_blocks.end(); ++report_block) {
57 aggregate.cumulativeLost += report_block->cumulativeLost;
58 std::map<uint32_t, RTCPReportBlock>::iterator prev_report_block =
59 prev_report_blocks->find(report_block->sourceSSRC);
60 if (prev_report_block != prev_report_blocks->end()) {
61 // Skip the first report block since we won't be able to get a correct
62 // weight for it.
63 int seq_num_diff = report_block->extendedHighSeqNum -
64 prev_report_block->second.extendedHighSeqNum;
65 if (seq_num_diff > 0) {
66 fraction_lost_sum += report_block->fractionLost * seq_num_diff;
67 fl_seq_num_sum += seq_num_diff;
68 }
69 }
70 jitter_sum += report_block->jitter;
71 ++number_of_report_blocks;
72 (*prev_report_blocks)[report_block->sourceSSRC] = *report_block;
73 }
74 if (fl_seq_num_sum > 0) {
75 aggregate.fractionLost =
76 (fraction_lost_sum + fl_seq_num_sum / 2) / fl_seq_num_sum;
77 }
78 if (number_of_report_blocks > 0) {
79 aggregate.jitter =
80 (jitter_sum + number_of_report_blocks / 2) / number_of_report_blocks;
81 }
82 // Not well defined for aggregated report blocks.
83 aggregate.extendedHighSeqNum = 0;
84 return aggregate;
85 }
86 } // namespace
87
88 // Helper class receiving statistics callbacks.
89 class ChannelStatsObserver : public CallStatsObserver {
90 public:
ChannelStatsObserver(ViEChannel * owner)91 explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
~ChannelStatsObserver()92 virtual ~ChannelStatsObserver() {}
93
94 // Implements StatsObserver.
OnRttUpdate(uint32_t rtt)95 virtual void OnRttUpdate(uint32_t rtt) {
96 owner_->OnRttUpdate(rtt);
97 }
98
99 private:
100 ViEChannel* owner_;
101 };
102
ViEChannel(int32_t channel_id,int32_t engine_id,uint32_t number_of_cores,const Config & config,ProcessThread & module_process_thread,RtcpIntraFrameObserver * intra_frame_observer,RtcpBandwidthObserver * bandwidth_observer,RemoteBitrateEstimator * remote_bitrate_estimator,RtcpRttStats * rtt_stats,PacedSender * paced_sender,RtpRtcp * default_rtp_rtcp,bool sender)103 ViEChannel::ViEChannel(int32_t channel_id,
104 int32_t engine_id,
105 uint32_t number_of_cores,
106 const Config& config,
107 ProcessThread& module_process_thread,
108 RtcpIntraFrameObserver* intra_frame_observer,
109 RtcpBandwidthObserver* bandwidth_observer,
110 RemoteBitrateEstimator* remote_bitrate_estimator,
111 RtcpRttStats* rtt_stats,
112 PacedSender* paced_sender,
113 RtpRtcp* default_rtp_rtcp,
114 bool sender)
115 : ViEFrameProviderBase(channel_id, engine_id),
116 channel_id_(channel_id),
117 engine_id_(engine_id),
118 number_of_cores_(number_of_cores),
119 num_socket_threads_(kViESocketThreads),
120 callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
121 rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
122 default_rtp_rtcp_(default_rtp_rtcp),
123 vcm_(VideoCodingModule::Create()),
124 vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
125 vie_sender_(channel_id),
126 vie_sync_(vcm_, this),
127 stats_observer_(new ChannelStatsObserver(this)),
128 module_process_thread_(module_process_thread),
129 codec_observer_(NULL),
130 do_key_frame_callbackRequest_(false),
131 rtp_observer_(NULL),
132 rtcp_observer_(NULL),
133 intra_frame_observer_(intra_frame_observer),
134 rtt_stats_(rtt_stats),
135 paced_sender_(paced_sender),
136 pad_with_redundant_payloads_(false),
137 bandwidth_observer_(bandwidth_observer),
138 send_timestamp_extension_id_(kInvalidRtpExtensionId),
139 absolute_send_time_extension_id_(kInvalidRtpExtensionId),
140 external_transport_(NULL),
141 decoder_reset_(true),
142 wait_for_key_frame_(false),
143 decode_thread_(NULL),
144 effect_filter_(NULL),
145 color_enhancement_(false),
146 mtu_(0),
147 sender_(sender),
148 nack_history_size_sender_(kSendSidePacketHistorySize),
149 max_nack_reordering_threshold_(kMaxPacketAgeToNack),
150 pre_render_callback_(NULL) {
151 RtpRtcp::Configuration configuration;
152 configuration.id = ViEModuleId(engine_id, channel_id);
153 configuration.audio = false;
154 configuration.default_module = default_rtp_rtcp;
155 configuration.outgoing_transport = &vie_sender_;
156 configuration.rtcp_feedback = this;
157 configuration.intra_frame_callback = intra_frame_observer;
158 configuration.bandwidth_callback = bandwidth_observer;
159 configuration.rtt_stats = rtt_stats;
160 configuration.remote_bitrate_estimator = remote_bitrate_estimator;
161 configuration.paced_sender = paced_sender;
162 configuration.receive_statistics = vie_receiver_.GetReceiveStatistics();
163 configuration.send_bitrate_observer = &send_bitrate_observer_;
164 configuration.send_frame_count_observer = &send_frame_count_observer_;
165 configuration.send_side_delay_observer = &send_side_delay_observer_;
166
167 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
168 vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
169 vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
170 }
171
Init()172 int32_t ViEChannel::Init() {
173 if (module_process_thread_.RegisterModule(
174 vie_receiver_.GetReceiveStatistics()) != 0) {
175 return -1;
176 }
177 // RTP/RTCP initialization.
178 if (rtp_rtcp_->SetSendingMediaStatus(false) != 0) {
179 return -1;
180 }
181 if (module_process_thread_.RegisterModule(rtp_rtcp_.get()) != 0) {
182 return -1;
183 }
184 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqFirRtp);
185 rtp_rtcp_->SetRTCPStatus(kRtcpCompound);
186 if (paced_sender_) {
187 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
188 }
189 if (vcm_->InitializeReceiver() != 0) {
190 return -1;
191 }
192 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true)) {
193 return -1;
194 }
195 if (vcm_->RegisterReceiveCallback(this) != 0) {
196 return -1;
197 }
198 vcm_->RegisterFrameTypeCallback(this);
199 vcm_->RegisterReceiveStatisticsCallback(this);
200 vcm_->RegisterDecoderTimingCallback(this);
201 vcm_->SetRenderDelay(kViEDefaultRenderDelayMs);
202 if (module_process_thread_.RegisterModule(vcm_) != 0) {
203 return -1;
204 }
205 #ifdef VIDEOCODEC_VP8
206 VideoCodec video_codec;
207 if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
208 rtp_rtcp_->RegisterSendPayload(video_codec);
209 // TODO(holmer): Can we call SetReceiveCodec() here instead?
210 if (!vie_receiver_.RegisterPayload(video_codec)) {
211 return -1;
212 }
213 vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_);
214 vcm_->RegisterSendCodec(&video_codec, number_of_cores_,
215 rtp_rtcp_->MaxDataPayloadLength());
216 } else {
217 assert(false);
218 }
219 #endif
220
221 return 0;
222 }
223
~ViEChannel()224 ViEChannel::~ViEChannel() {
225 // Make sure we don't get more callbacks from the RTP module.
226 module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
227 module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
228 module_process_thread_.DeRegisterModule(vcm_);
229 module_process_thread_.DeRegisterModule(&vie_sync_);
230 while (simulcast_rtp_rtcp_.size() > 0) {
231 std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
232 RtpRtcp* rtp_rtcp = *it;
233 module_process_thread_.DeRegisterModule(rtp_rtcp);
234 delete rtp_rtcp;
235 simulcast_rtp_rtcp_.erase(it);
236 }
237 while (removed_rtp_rtcp_.size() > 0) {
238 std::list<RtpRtcp*>::iterator it = removed_rtp_rtcp_.begin();
239 delete *it;
240 removed_rtp_rtcp_.erase(it);
241 }
242 if (decode_thread_) {
243 StopDecodeThread();
244 }
245 // Release modules.
246 VideoCodingModule::Destroy(vcm_);
247 }
248
SetSendCodec(const VideoCodec & video_codec,bool new_stream)249 int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
250 bool new_stream) {
251 if (!sender_) {
252 return 0;
253 }
254 if (video_codec.codecType == kVideoCodecRED ||
255 video_codec.codecType == kVideoCodecULPFEC) {
256 LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType;
257 return -1;
258 }
259 if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) {
260 LOG_F(LS_ERROR) << "Incorrect config "
261 << video_codec.numberOfSimulcastStreams;
262 return -1;
263 }
264 // Update the RTP module with the settings.
265 // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been
266 // set explicitly.
267 bool restart_rtp = false;
268 if (rtp_rtcp_->Sending() && new_stream) {
269 restart_rtp = true;
270 rtp_rtcp_->SetSendingStatus(false);
271 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
272 it != simulcast_rtp_rtcp_.end(); ++it) {
273 (*it)->SetSendingStatus(false);
274 (*it)->SetSendingMediaStatus(false);
275 }
276 }
277
278 bool fec_enabled = false;
279 uint8_t payload_type_red;
280 uint8_t payload_type_fec;
281 rtp_rtcp_->GenericFECStatus(fec_enabled, payload_type_red, payload_type_fec);
282
283 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
284
285 if (video_codec.numberOfSimulcastStreams > 0) {
286 // Set correct bitrate to base layer.
287 // Create our simulcast RTP modules.
288 int num_modules_to_add = video_codec.numberOfSimulcastStreams -
289 simulcast_rtp_rtcp_.size() - 1;
290 if (num_modules_to_add < 0) {
291 num_modules_to_add = 0;
292 }
293
294 // Add back removed rtp modules. Order is important (allocate from front of
295 // removed modules) to preserve RTP settings such as SSRCs for simulcast
296 // streams.
297 std::list<RtpRtcp*> new_rtp_modules;
298 for (; removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0;
299 --num_modules_to_add) {
300 new_rtp_modules.push_back(removed_rtp_rtcp_.front());
301 removed_rtp_rtcp_.pop_front();
302 }
303
304 for (int i = 0; i < num_modules_to_add; ++i)
305 new_rtp_modules.push_back(CreateRtpRtcpModule());
306
307 // Initialize newly added modules.
308 for (std::list<RtpRtcp*>::iterator it = new_rtp_modules.begin();
309 it != new_rtp_modules.end();
310 ++it) {
311 RtpRtcp* rtp_rtcp = *it;
312
313 rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP());
314
315 if (rtp_rtcp_->StorePackets()) {
316 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
317 } else if (paced_sender_) {
318 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
319 }
320
321 if (fec_enabled) {
322 rtp_rtcp->SetGenericFECStatus(
323 fec_enabled, payload_type_red, payload_type_fec);
324 }
325 rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
326 rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
327
328 int mode;
329 uint32_t ssrc;
330 int payload_type;
331 rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
332 rtp_rtcp->SetRTXSendStatus(mode);
333 simulcast_rtp_rtcp_.push_back(rtp_rtcp);
334
335 // Silently ignore error.
336 module_process_thread_.RegisterModule(rtp_rtcp);
337 }
338
339 // Remove last in list if we have too many.
340 for (int j = simulcast_rtp_rtcp_.size();
341 j > (video_codec.numberOfSimulcastStreams - 1);
342 j--) {
343 RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
344 module_process_thread_.DeRegisterModule(rtp_rtcp);
345 rtp_rtcp->SetSendingStatus(false);
346 rtp_rtcp->SetSendingMediaStatus(false);
347 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
348 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
349 simulcast_rtp_rtcp_.pop_back();
350 removed_rtp_rtcp_.push_front(rtp_rtcp);
351 }
352 uint8_t idx = 0;
353 // Configure all simulcast modules.
354 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
355 it != simulcast_rtp_rtcp_.end();
356 it++) {
357 idx++;
358 RtpRtcp* rtp_rtcp = *it;
359 rtp_rtcp->DeRegisterSendPayload(video_codec.plType);
360 if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) {
361 return -1;
362 }
363 if (mtu_ != 0) {
364 rtp_rtcp->SetMaxTransferUnit(mtu_);
365 }
366 if (restart_rtp) {
367 rtp_rtcp->SetSendingStatus(true);
368 rtp_rtcp->SetSendingMediaStatus(true);
369 }
370 if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) {
371 // Deregister in case the extension was previously enabled.
372 rtp_rtcp->DeregisterSendRtpHeaderExtension(
373 kRtpExtensionTransmissionTimeOffset);
374 if (rtp_rtcp->RegisterSendRtpHeaderExtension(
375 kRtpExtensionTransmissionTimeOffset,
376 send_timestamp_extension_id_) != 0) {
377 }
378 } else {
379 rtp_rtcp->DeregisterSendRtpHeaderExtension(
380 kRtpExtensionTransmissionTimeOffset);
381 }
382 if (absolute_send_time_extension_id_ != kInvalidRtpExtensionId) {
383 // Deregister in case the extension was previously enabled.
384 rtp_rtcp->DeregisterSendRtpHeaderExtension(
385 kRtpExtensionAbsoluteSendTime);
386 if (rtp_rtcp->RegisterSendRtpHeaderExtension(
387 kRtpExtensionAbsoluteSendTime,
388 absolute_send_time_extension_id_) != 0) {
389 }
390 } else {
391 rtp_rtcp->DeregisterSendRtpHeaderExtension(
392 kRtpExtensionAbsoluteSendTime);
393 }
394 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(
395 rtp_rtcp_->GetSendChannelRtcpStatisticsCallback());
396 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
397 rtp_rtcp_->GetSendChannelRtpStatisticsCallback());
398 }
399 // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old
400 // modules can be deleted after this step.
401 vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
402 } else {
403 while (!simulcast_rtp_rtcp_.empty()) {
404 RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
405 module_process_thread_.DeRegisterModule(rtp_rtcp);
406 rtp_rtcp->SetSendingStatus(false);
407 rtp_rtcp->SetSendingMediaStatus(false);
408 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
409 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
410 simulcast_rtp_rtcp_.pop_back();
411 removed_rtp_rtcp_.push_front(rtp_rtcp);
412 }
413 // Clear any previous modules.
414 vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
415 }
416
417 // Don't log this error, no way to check in advance if this pl_type is
418 // registered or not...
419 rtp_rtcp_->DeRegisterSendPayload(video_codec.plType);
420 if (rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
421 return -1;
422 }
423 if (restart_rtp) {
424 rtp_rtcp_->SetSendingStatus(true);
425 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
426 it != simulcast_rtp_rtcp_.end(); ++it) {
427 (*it)->SetSendingStatus(true);
428 (*it)->SetSendingMediaStatus(true);
429 }
430 }
431 return 0;
432 }
433
SetReceiveCodec(const VideoCodec & video_codec)434 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
435 if (!vie_receiver_.SetReceiveCodec(video_codec)) {
436 return -1;
437 }
438
439 if (video_codec.codecType != kVideoCodecRED &&
440 video_codec.codecType != kVideoCodecULPFEC) {
441 // Register codec type with VCM, but do not register RED or ULPFEC.
442 if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_,
443 wait_for_key_frame_) != VCM_OK) {
444 return -1;
445 }
446 }
447 return 0;
448 }
449
GetReceiveCodec(VideoCodec * video_codec)450 int32_t ViEChannel::GetReceiveCodec(VideoCodec* video_codec) {
451 if (vcm_->ReceiveCodec(video_codec) != 0) {
452 return -1;
453 }
454 return 0;
455 }
456
RegisterCodecObserver(ViEDecoderObserver * observer)457 int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) {
458 CriticalSectionScoped cs(callback_cs_.get());
459 if (observer) {
460 if (codec_observer_) {
461 LOG_F(LS_ERROR) << "Observer already registered.";
462 return -1;
463 }
464 codec_observer_ = observer;
465 } else {
466 codec_observer_ = NULL;
467 }
468 return 0;
469 }
470
RegisterExternalDecoder(const uint8_t pl_type,VideoDecoder * decoder,bool buffered_rendering,int32_t render_delay)471 int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
472 VideoDecoder* decoder,
473 bool buffered_rendering,
474 int32_t render_delay) {
475 int32_t result;
476 result = vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering);
477 if (result != VCM_OK) {
478 return result;
479 }
480 return vcm_->SetRenderDelay(render_delay);
481 }
482
DeRegisterExternalDecoder(const uint8_t pl_type)483 int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) {
484 VideoCodec current_receive_codec;
485 int32_t result = 0;
486 result = vcm_->ReceiveCodec(¤t_receive_codec);
487 if (vcm_->RegisterExternalDecoder(NULL, pl_type, false) != VCM_OK) {
488 return -1;
489 }
490
491 if (result == 0 && current_receive_codec.plType == pl_type) {
492 result = vcm_->RegisterReceiveCodec(
493 ¤t_receive_codec, number_of_cores_, wait_for_key_frame_);
494 }
495 return result;
496 }
497
ReceiveCodecStatistics(uint32_t * num_key_frames,uint32_t * num_delta_frames)498 int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
499 uint32_t* num_delta_frames) {
500 VCMFrameCount received_frames;
501 if (vcm_->ReceivedFrameCount(received_frames) != VCM_OK) {
502 return -1;
503 }
504 *num_key_frames = received_frames.numKeyFrames;
505 *num_delta_frames = received_frames.numDeltaFrames;
506 return 0;
507 }
508
DiscardedPackets() const509 uint32_t ViEChannel::DiscardedPackets() const {
510 return vcm_->DiscardedPackets();
511 }
512
ReceiveDelay() const513 int ViEChannel::ReceiveDelay() const {
514 return vcm_->Delay();
515 }
516
WaitForKeyFrame(bool wait)517 int32_t ViEChannel::WaitForKeyFrame(bool wait) {
518 wait_for_key_frame_ = wait;
519 return 0;
520 }
521
SetSignalPacketLossStatus(bool enable,bool only_key_frames)522 int32_t ViEChannel::SetSignalPacketLossStatus(bool enable,
523 bool only_key_frames) {
524 if (enable) {
525 if (only_key_frames) {
526 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
527 if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) {
528 return -1;
529 }
530 } else {
531 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
532 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) {
533 return -1;
534 }
535 }
536 } else {
537 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
538 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
539 }
540 return 0;
541 }
542
SetRTCPMode(const RTCPMethod rtcp_mode)543 int32_t ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) {
544 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
545 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
546 it != simulcast_rtp_rtcp_.end();
547 it++) {
548 RtpRtcp* rtp_rtcp = *it;
549 rtp_rtcp->SetRTCPStatus(rtcp_mode);
550 }
551 return rtp_rtcp_->SetRTCPStatus(rtcp_mode);
552 }
553
GetRTCPMode(RTCPMethod * rtcp_mode)554 int32_t ViEChannel::GetRTCPMode(RTCPMethod* rtcp_mode) {
555 *rtcp_mode = rtp_rtcp_->RTCP();
556 return 0;
557 }
558
SetNACKStatus(const bool enable)559 int32_t ViEChannel::SetNACKStatus(const bool enable) {
560 // Update the decoding VCM.
561 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
562 return -1;
563 }
564 if (enable) {
565 // Disable possible FEC.
566 SetFECStatus(false, 0, 0);
567 }
568 // Update the decoding VCM.
569 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
570 return -1;
571 }
572 return ProcessNACKRequest(enable);
573 }
574
ProcessNACKRequest(const bool enable)575 int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
576 if (enable) {
577 // Turn on NACK.
578 if (rtp_rtcp_->RTCP() == kRtcpOff) {
579 return -1;
580 }
581 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
582 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
583 vcm_->RegisterPacketRequestCallback(this);
584
585 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
586
587 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
588 it != simulcast_rtp_rtcp_.end();
589 it++) {
590 RtpRtcp* rtp_rtcp = *it;
591 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
592 }
593 // Don't introduce errors when NACK is enabled.
594 vcm_->SetDecodeErrorMode(kNoErrors);
595 } else {
596 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
597 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
598 it != simulcast_rtp_rtcp_.end();
599 it++) {
600 RtpRtcp* rtp_rtcp = *it;
601 if (paced_sender_ == NULL) {
602 rtp_rtcp->SetStorePacketsStatus(false, 0);
603 }
604 }
605 vcm_->RegisterPacketRequestCallback(NULL);
606 if (paced_sender_ == NULL) {
607 rtp_rtcp_->SetStorePacketsStatus(false, 0);
608 }
609 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
610 // When NACK is off, allow decoding with errors. Otherwise, the video
611 // will freeze, and will only recover with a complete key frame.
612 vcm_->SetDecodeErrorMode(kWithErrors);
613 }
614 return 0;
615 }
616
SetFECStatus(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)617 int32_t ViEChannel::SetFECStatus(const bool enable,
618 const unsigned char payload_typeRED,
619 const unsigned char payload_typeFEC) {
620 // Disable possible NACK.
621 if (enable) {
622 SetNACKStatus(false);
623 }
624
625 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
626 }
627
ProcessFECRequest(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)628 int32_t ViEChannel::ProcessFECRequest(
629 const bool enable,
630 const unsigned char payload_typeRED,
631 const unsigned char payload_typeFEC) {
632 if (rtp_rtcp_->SetGenericFECStatus(enable, payload_typeRED,
633 payload_typeFEC) != 0) {
634 return -1;
635 }
636 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
637 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
638 it != simulcast_rtp_rtcp_.end();
639 it++) {
640 RtpRtcp* rtp_rtcp = *it;
641 rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC);
642 }
643 return 0;
644 }
645
SetHybridNACKFECStatus(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)646 int32_t ViEChannel::SetHybridNACKFECStatus(
647 const bool enable,
648 const unsigned char payload_typeRED,
649 const unsigned char payload_typeFEC) {
650 if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) {
651 return -1;
652 }
653
654 int32_t ret_val = 0;
655 ret_val = ProcessNACKRequest(enable);
656 if (ret_val < 0) {
657 return ret_val;
658 }
659 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
660 }
661
SetSenderBufferingMode(int target_delay_ms)662 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) {
663 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
664 LOG(LS_ERROR) << "Invalid send buffer value.";
665 return -1;
666 }
667 if (target_delay_ms == 0) {
668 // Real-time mode.
669 nack_history_size_sender_ = kSendSidePacketHistorySize;
670 } else {
671 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms);
672 // Don't allow a number lower than the default value.
673 if (nack_history_size_sender_ < kSendSidePacketHistorySize) {
674 nack_history_size_sender_ = kSendSidePacketHistorySize;
675 }
676 }
677 if (rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_) != 0) {
678 return -1;
679 }
680 return 0;
681 }
682
SetReceiverBufferingMode(int target_delay_ms)683 int ViEChannel::SetReceiverBufferingMode(int target_delay_ms) {
684 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
685 LOG(LS_ERROR) << "Invalid receive buffer delay value.";
686 return -1;
687 }
688 int max_nack_list_size;
689 int max_incomplete_time_ms;
690 if (target_delay_ms == 0) {
691 // Real-time mode - restore default settings.
692 max_nack_reordering_threshold_ = kMaxPacketAgeToNack;
693 max_nack_list_size = kMaxNackListSize;
694 max_incomplete_time_ms = 0;
695 } else {
696 max_nack_list_size = 3 * GetRequiredNackListSize(target_delay_ms) / 4;
697 max_nack_reordering_threshold_ = max_nack_list_size;
698 // Calculate the max incomplete time and round to int.
699 max_incomplete_time_ms = static_cast<int>(kMaxIncompleteTimeMultiplier *
700 target_delay_ms + 0.5f);
701 }
702 vcm_->SetNackSettings(max_nack_list_size, max_nack_reordering_threshold_,
703 max_incomplete_time_ms);
704 vcm_->SetMinReceiverDelay(target_delay_ms);
705 if (vie_sync_.SetTargetBufferingDelay(target_delay_ms) < 0)
706 return -1;
707 return 0;
708 }
709
GetRequiredNackListSize(int target_delay_ms)710 int ViEChannel::GetRequiredNackListSize(int target_delay_ms) {
711 // The max size of the nack list should be large enough to accommodate the
712 // the number of packets (frames) resulting from the increased delay.
713 // Roughly estimating for ~40 packets per frame @ 30fps.
714 return target_delay_ms * 40 * 30 / 1000;
715 }
716
SetKeyFrameRequestMethod(const KeyFrameRequestMethod method)717 int32_t ViEChannel::SetKeyFrameRequestMethod(
718 const KeyFrameRequestMethod method) {
719 return rtp_rtcp_->SetKeyFrameRequestMethod(method);
720 }
721
EnableRemb(bool enable)722 bool ViEChannel::EnableRemb(bool enable) {
723 if (rtp_rtcp_->SetREMBStatus(enable) != 0)
724 return false;
725 return true;
726 }
727
SetSendTimestampOffsetStatus(bool enable,int id)728 int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
729 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
730 int error = 0;
731 if (enable) {
732 // Enable the extension, but disable possible old id to avoid errors.
733 send_timestamp_extension_id_ = id;
734 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
735 kRtpExtensionTransmissionTimeOffset);
736 error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
737 kRtpExtensionTransmissionTimeOffset, id);
738 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
739 it != simulcast_rtp_rtcp_.end(); it++) {
740 (*it)->DeregisterSendRtpHeaderExtension(
741 kRtpExtensionTransmissionTimeOffset);
742 error |= (*it)->RegisterSendRtpHeaderExtension(
743 kRtpExtensionTransmissionTimeOffset, id);
744 }
745 } else {
746 // Disable the extension.
747 send_timestamp_extension_id_ = kInvalidRtpExtensionId;
748 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
749 kRtpExtensionTransmissionTimeOffset);
750 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
751 it != simulcast_rtp_rtcp_.end(); it++) {
752 (*it)->DeregisterSendRtpHeaderExtension(
753 kRtpExtensionTransmissionTimeOffset);
754 }
755 }
756 return error;
757 }
758
SetReceiveTimestampOffsetStatus(bool enable,int id)759 int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
760 return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1;
761 }
762
SetSendAbsoluteSendTimeStatus(bool enable,int id)763 int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
764 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
765 int error = 0;
766 if (enable) {
767 // Enable the extension, but disable possible old id to avoid errors.
768 absolute_send_time_extension_id_ = id;
769 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
770 kRtpExtensionAbsoluteSendTime);
771 error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
772 kRtpExtensionAbsoluteSendTime, id);
773 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
774 it != simulcast_rtp_rtcp_.end(); it++) {
775 (*it)->DeregisterSendRtpHeaderExtension(
776 kRtpExtensionAbsoluteSendTime);
777 error |= (*it)->RegisterSendRtpHeaderExtension(
778 kRtpExtensionAbsoluteSendTime, id);
779 }
780 } else {
781 // Disable the extension.
782 absolute_send_time_extension_id_ = kInvalidRtpExtensionId;
783 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
784 kRtpExtensionAbsoluteSendTime);
785 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
786 it != simulcast_rtp_rtcp_.end(); it++) {
787 (*it)->DeregisterSendRtpHeaderExtension(
788 kRtpExtensionAbsoluteSendTime);
789 }
790 }
791 return error;
792 }
793
SetReceiveAbsoluteSendTimeStatus(bool enable,int id)794 int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
795 return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
796 }
797
SetRtcpXrRrtrStatus(bool enable)798 void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
799 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
800 rtp_rtcp_->SetRtcpXrRrtrStatus(enable);
801 }
802
SetTransmissionSmoothingStatus(bool enable)803 void ViEChannel::SetTransmissionSmoothingStatus(bool enable) {
804 assert(paced_sender_ && "No paced sender registered.");
805 paced_sender_->SetStatus(enable);
806 }
807
EnableTMMBR(const bool enable)808 int32_t ViEChannel::EnableTMMBR(const bool enable) {
809 return rtp_rtcp_->SetTMMBRStatus(enable);
810 }
811
EnableKeyFrameRequestCallback(const bool enable)812 int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) {
813
814 CriticalSectionScoped cs(callback_cs_.get());
815 if (enable && !codec_observer_) {
816 LOG(LS_ERROR) << "No ViECodecObserver set.";
817 return -1;
818 }
819 do_key_frame_callbackRequest_ = enable;
820 return 0;
821 }
822
SetSSRC(const uint32_t SSRC,const StreamType usage,const uint8_t simulcast_idx)823 int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
824 const StreamType usage,
825 const uint8_t simulcast_idx) {
826 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
827 ReserveRtpRtcpModules(simulcast_idx + 1);
828 RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx);
829 if (rtp_rtcp == NULL)
830 return -1;
831 if (usage == kViEStreamTypeRtx) {
832 rtp_rtcp->SetRtxSsrc(SSRC);
833 } else {
834 rtp_rtcp->SetSSRC(SSRC);
835 }
836 return 0;
837 }
838
SetRemoteSSRCType(const StreamType usage,const uint32_t SSRC)839 int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
840 const uint32_t SSRC) {
841 vie_receiver_.SetRtxSsrc(SSRC);
842 return 0;
843 }
844
GetLocalSSRC(uint8_t idx,unsigned int * ssrc)845 int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) {
846 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
847 RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx);
848 if (rtp_rtcp == NULL)
849 return -1;
850 *ssrc = rtp_rtcp->SSRC();
851 return 0;
852 }
853
GetRemoteSSRC(uint32_t * ssrc)854 int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) {
855 *ssrc = vie_receiver_.GetRemoteSsrc();
856 return 0;
857 }
858
GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize])859 int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) {
860 uint32_t arrayCSRC[kRtpCsrcSize];
861 memset(arrayCSRC, 0, sizeof(arrayCSRC));
862
863 int num_csrcs = vie_receiver_.GetCsrcs(arrayCSRC);
864 if (num_csrcs > 0) {
865 memcpy(CSRCs, arrayCSRC, num_csrcs * sizeof(uint32_t));
866 }
867 return 0;
868 }
869
SetPadWithRedundantPayloads(bool enable)870 void ViEChannel::SetPadWithRedundantPayloads(bool enable) {
871 {
872 CriticalSectionScoped cs(callback_cs_.get());
873 pad_with_redundant_payloads_ = enable;
874 }
875 int mode;
876 uint32_t ssrc;
877 int payload_type;
878 rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
879 if (mode != kRtxOff) {
880 // Since RTX was already enabled we have to reset it with payload-based
881 // padding on.
882 SetRtxSendStatus(true);
883 }
884 }
885
SetRtxSendPayloadType(int payload_type)886 int ViEChannel::SetRtxSendPayloadType(int payload_type) {
887 rtp_rtcp_->SetRtxSendPayloadType(payload_type);
888 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
889 it != simulcast_rtp_rtcp_.end(); it++) {
890 (*it)->SetRtxSendPayloadType(payload_type);
891 }
892 SetRtxSendStatus(true);
893 return 0;
894 }
895
SetRtxSendStatus(bool enable)896 void ViEChannel::SetRtxSendStatus(bool enable) {
897 int rtx_settings = kRtxOff;
898 if (enable) {
899 CriticalSectionScoped cs(callback_cs_.get());
900 rtx_settings = kRtxRetransmitted;
901 if (pad_with_redundant_payloads_)
902 rtx_settings |= kRtxRedundantPayloads;
903 }
904 rtp_rtcp_->SetRTXSendStatus(rtx_settings);
905 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
906 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
907 it != simulcast_rtp_rtcp_.end(); it++) {
908 (*it)->SetRTXSendStatus(rtx_settings);
909 }
910 }
911
SetRtxReceivePayloadType(int payload_type)912 void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
913 vie_receiver_.SetRtxPayloadType(payload_type);
914 }
915
SetStartSequenceNumber(uint16_t sequence_number)916 int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
917 if (rtp_rtcp_->Sending()) {
918 return -1;
919 }
920 return rtp_rtcp_->SetSequenceNumber(sequence_number);
921 }
922
SetRtpStateForSsrc(uint32_t ssrc,const RtpState & rtp_state)923 void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) {
924 assert(!rtp_rtcp_->Sending());
925 default_rtp_rtcp_->SetRtpStateForSsrc(ssrc, rtp_state);
926 }
927
GetRtpStateForSsrc(uint32_t ssrc)928 RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) {
929 assert(!rtp_rtcp_->Sending());
930
931 RtpState rtp_state;
932 if (!default_rtp_rtcp_->GetRtpStateForSsrc(ssrc, &rtp_state)) {
933 LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
934 }
935 return rtp_state;
936 }
937
SetRTCPCName(const char rtcp_cname[])938 int32_t ViEChannel::SetRTCPCName(const char rtcp_cname[]) {
939 if (rtp_rtcp_->Sending()) {
940 return -1;
941 }
942 return rtp_rtcp_->SetCNAME(rtcp_cname);
943 }
944
GetRemoteRTCPCName(char rtcp_cname[])945 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
946 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
947 return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
948 }
949
RegisterRtpObserver(ViERTPObserver * observer)950 int32_t ViEChannel::RegisterRtpObserver(ViERTPObserver* observer) {
951 CriticalSectionScoped cs(callback_cs_.get());
952 if (observer) {
953 if (rtp_observer_) {
954 LOG_F(LS_ERROR) << "Observer already registered.";
955 return -1;
956 }
957 rtp_observer_ = observer;
958 } else {
959 rtp_observer_ = NULL;
960 }
961 return 0;
962 }
963
RegisterRtcpObserver(ViERTCPObserver * observer)964 int32_t ViEChannel::RegisterRtcpObserver(ViERTCPObserver* observer) {
965 CriticalSectionScoped cs(callback_cs_.get());
966 if (observer) {
967 if (rtcp_observer_) {
968 LOG_F(LS_ERROR) << "Observer already registered.";
969 return -1;
970 }
971 rtcp_observer_ = observer;
972 } else {
973 rtcp_observer_ = NULL;
974 }
975 return 0;
976 }
977
SendApplicationDefinedRTCPPacket(const uint8_t sub_type,uint32_t name,const uint8_t * data,uint16_t data_length_in_bytes)978 int32_t ViEChannel::SendApplicationDefinedRTCPPacket(
979 const uint8_t sub_type,
980 uint32_t name,
981 const uint8_t* data,
982 uint16_t data_length_in_bytes) {
983 if (!rtp_rtcp_->Sending()) {
984 return -1;
985 }
986 if (!data) {
987 LOG_F(LS_ERROR) << "Invalid input.";
988 return -1;
989 }
990 if (data_length_in_bytes % 4 != 0) {
991 LOG(LS_ERROR) << "Invalid input length.";
992 return -1;
993 }
994 RTCPMethod rtcp_method = rtp_rtcp_->RTCP();
995 if (rtcp_method == kRtcpOff) {
996 LOG_F(LS_ERROR) << "RTCP not enable.";
997 return -1;
998 }
999 // Create and send packet.
1000 if (rtp_rtcp_->SetRTCPApplicationSpecificData(sub_type, name, data,
1001 data_length_in_bytes) != 0) {
1002 return -1;
1003 }
1004 return 0;
1005 }
1006
GetSendRtcpStatistics(uint16_t * fraction_lost,uint32_t * cumulative_lost,uint32_t * extended_max,uint32_t * jitter_samples,int32_t * rtt_ms)1007 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
1008 uint32_t* cumulative_lost,
1009 uint32_t* extended_max,
1010 uint32_t* jitter_samples,
1011 int32_t* rtt_ms) {
1012 // Aggregate the report blocks associated with streams sent on this channel.
1013 std::vector<RTCPReportBlock> report_blocks;
1014 rtp_rtcp_->RemoteRTCPStat(&report_blocks);
1015 {
1016 CriticalSectionScoped lock(rtp_rtcp_cs_.get());
1017 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1018 it != simulcast_rtp_rtcp_.end();
1019 ++it) {
1020 (*it)->RemoteRTCPStat(&report_blocks);
1021 }
1022 }
1023
1024 if (report_blocks.empty())
1025 return -1;
1026
1027 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1028 std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
1029 for (; it != report_blocks.end(); ++it) {
1030 if (it->remoteSSRC == remote_ssrc)
1031 break;
1032 }
1033 if (it == report_blocks.end()) {
1034 // We have not received packets with an SSRC matching the report blocks. To
1035 // have a chance of calculating an RTT we will try with the SSRC of the
1036 // first report block received.
1037 // This is very important for send-only channels where we don't know the
1038 // SSRC of the other end.
1039 remote_ssrc = report_blocks[0].remoteSSRC;
1040 }
1041
1042 RTCPReportBlock report;
1043 if (report_blocks.size() > 1)
1044 report = AggregateReportBlocks(report_blocks, &prev_report_blocks_);
1045 else
1046 report = report_blocks[0];
1047
1048 *fraction_lost = report.fractionLost;
1049 *cumulative_lost = report.cumulativeLost;
1050 *extended_max = report.extendedHighSeqNum;
1051 *jitter_samples = report.jitter;
1052
1053 uint16_t dummy;
1054 uint16_t rtt = 0;
1055 if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
1056 return -1;
1057 }
1058 *rtt_ms = rtt;
1059 return 0;
1060 }
1061
RegisterSendChannelRtcpStatisticsCallback(RtcpStatisticsCallback * callback)1062 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
1063 RtcpStatisticsCallback* callback) {
1064 rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(callback);
1065 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1066 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1067 it != simulcast_rtp_rtcp_.end();
1068 ++it) {
1069 (*it)->RegisterSendChannelRtcpStatisticsCallback(callback);
1070 }
1071 }
1072
1073 // TODO(holmer): This is a bad function name as it implies that it returns the
1074 // received RTCP, while it actually returns the statistics which will be sent
1075 // in the RTCP.
GetReceivedRtcpStatistics(uint16_t * fraction_lost,uint32_t * cumulative_lost,uint32_t * extended_max,uint32_t * jitter_samples,int32_t * rtt_ms)1076 int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
1077 uint32_t* cumulative_lost,
1078 uint32_t* extended_max,
1079 uint32_t* jitter_samples,
1080 int32_t* rtt_ms) {
1081 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1082 StreamStatistician* statistician =
1083 vie_receiver_.GetReceiveStatistics()->GetStatistician(remote_ssrc);
1084 RtcpStatistics receive_stats;
1085 if (!statistician || !statistician->GetStatistics(
1086 &receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
1087 return -1;
1088 }
1089 *fraction_lost = receive_stats.fraction_lost;
1090 *cumulative_lost = receive_stats.cumulative_lost;
1091 *extended_max = receive_stats.extended_max_sequence_number;
1092 *jitter_samples = receive_stats.jitter;
1093
1094 uint16_t dummy = 0;
1095 uint16_t rtt = 0;
1096 rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy);
1097 *rtt_ms = rtt;
1098 return 0;
1099 }
1100
RegisterReceiveChannelRtcpStatisticsCallback(RtcpStatisticsCallback * callback)1101 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
1102 RtcpStatisticsCallback* callback) {
1103 vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
1104 callback);
1105 }
1106
GetRtpStatistics(uint32_t * bytes_sent,uint32_t * packets_sent,uint32_t * bytes_received,uint32_t * packets_received) const1107 int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
1108 uint32_t* packets_sent,
1109 uint32_t* bytes_received,
1110 uint32_t* packets_received) const {
1111 StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()->
1112 GetStatistician(vie_receiver_.GetRemoteSsrc());
1113 *bytes_received = 0;
1114 *packets_received = 0;
1115 if (statistician)
1116 statistician->GetDataCounters(bytes_received, packets_received);
1117 if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
1118 return -1;
1119 }
1120 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1121 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1122 it != simulcast_rtp_rtcp_.end();
1123 it++) {
1124 uint32_t bytes_sent_temp = 0;
1125 uint32_t packets_sent_temp = 0;
1126 RtpRtcp* rtp_rtcp = *it;
1127 rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1128 *bytes_sent += bytes_sent_temp;
1129 *packets_sent += packets_sent_temp;
1130 }
1131 for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1132 it != removed_rtp_rtcp_.end(); ++it) {
1133 uint32_t bytes_sent_temp = 0;
1134 uint32_t packets_sent_temp = 0;
1135 RtpRtcp* rtp_rtcp = *it;
1136 rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1137 *bytes_sent += bytes_sent_temp;
1138 *packets_sent += packets_sent_temp;
1139 }
1140 return 0;
1141 }
1142
RegisterSendChannelRtpStatisticsCallback(StreamDataCountersCallback * callback)1143 void ViEChannel::RegisterSendChannelRtpStatisticsCallback(
1144 StreamDataCountersCallback* callback) {
1145 rtp_rtcp_->RegisterSendChannelRtpStatisticsCallback(callback);
1146 {
1147 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1148 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1149 it != simulcast_rtp_rtcp_.end();
1150 it++) {
1151 (*it)->RegisterSendChannelRtpStatisticsCallback(callback);
1152 }
1153 }
1154 }
1155
RegisterReceiveChannelRtpStatisticsCallback(StreamDataCountersCallback * callback)1156 void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback(
1157 StreamDataCountersCallback* callback) {
1158 vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
1159 }
1160
GetRtcpPacketTypeCounters(RtcpPacketTypeCounter * packets_sent,RtcpPacketTypeCounter * packets_received) const1161 void ViEChannel::GetRtcpPacketTypeCounters(
1162 RtcpPacketTypeCounter* packets_sent,
1163 RtcpPacketTypeCounter* packets_received) const {
1164 rtp_rtcp_->GetRtcpPacketTypeCounters(packets_sent, packets_received);
1165
1166 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1167 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1168 it != simulcast_rtp_rtcp_.end(); ++it) {
1169 RtcpPacketTypeCounter sent;
1170 RtcpPacketTypeCounter received;
1171 (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1172 packets_sent->Add(sent);
1173 packets_received->Add(received);
1174 }
1175 for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1176 it != removed_rtp_rtcp_.end(); ++it) {
1177 RtcpPacketTypeCounter sent;
1178 RtcpPacketTypeCounter received;
1179 (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1180 packets_sent->Add(sent);
1181 packets_received->Add(received);
1182 }
1183 }
1184
GetBandwidthUsage(uint32_t * total_bitrate_sent,uint32_t * video_bitrate_sent,uint32_t * fec_bitrate_sent,uint32_t * nackBitrateSent) const1185 void ViEChannel::GetBandwidthUsage(uint32_t* total_bitrate_sent,
1186 uint32_t* video_bitrate_sent,
1187 uint32_t* fec_bitrate_sent,
1188 uint32_t* nackBitrateSent) const {
1189 rtp_rtcp_->BitrateSent(total_bitrate_sent, video_bitrate_sent,
1190 fec_bitrate_sent, nackBitrateSent);
1191 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1192 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1193 it != simulcast_rtp_rtcp_.end(); it++) {
1194 uint32_t stream_rate = 0;
1195 uint32_t video_rate = 0;
1196 uint32_t fec_rate = 0;
1197 uint32_t nackRate = 0;
1198 RtpRtcp* rtp_rtcp = *it;
1199 rtp_rtcp->BitrateSent(&stream_rate, &video_rate, &fec_rate, &nackRate);
1200 *total_bitrate_sent += stream_rate;
1201 *video_bitrate_sent += video_rate;
1202 *fec_bitrate_sent += fec_rate;
1203 *nackBitrateSent += nackRate;
1204 }
1205 }
1206
GetSendSideDelay(int * avg_send_delay,int * max_send_delay) const1207 bool ViEChannel::GetSendSideDelay(int* avg_send_delay,
1208 int* max_send_delay) const {
1209 *avg_send_delay = 0;
1210 *max_send_delay = 0;
1211 bool valid_estimate = false;
1212 int num_send_delays = 0;
1213 if (rtp_rtcp_->GetSendSideDelay(avg_send_delay, max_send_delay)) {
1214 ++num_send_delays;
1215 valid_estimate = true;
1216 }
1217 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1218 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1219 it != simulcast_rtp_rtcp_.end(); it++) {
1220 RtpRtcp* rtp_rtcp = *it;
1221 int sub_stream_avg_delay = 0;
1222 int sub_stream_max_delay = 0;
1223 if (rtp_rtcp->GetSendSideDelay(&sub_stream_avg_delay,
1224 &sub_stream_max_delay)) {
1225 *avg_send_delay += sub_stream_avg_delay;
1226 *max_send_delay = std::max(*max_send_delay, sub_stream_max_delay);
1227 ++num_send_delays;
1228 }
1229 }
1230 if (num_send_delays > 0) {
1231 valid_estimate = true;
1232 *avg_send_delay = *avg_send_delay / num_send_delays;
1233 *avg_send_delay = (*avg_send_delay + num_send_delays / 2) / num_send_delays;
1234 }
1235 return valid_estimate;
1236 }
1237
RegisterSendSideDelayObserver(SendSideDelayObserver * observer)1238 void ViEChannel::RegisterSendSideDelayObserver(
1239 SendSideDelayObserver* observer) {
1240 send_side_delay_observer_.Set(observer);
1241 }
1242
RegisterSendBitrateObserver(BitrateStatisticsObserver * observer)1243 void ViEChannel::RegisterSendBitrateObserver(
1244 BitrateStatisticsObserver* observer) {
1245 send_bitrate_observer_.Set(observer);
1246 }
1247
GetReceiveBandwidthEstimatorStats(ReceiveBandwidthEstimatorStats * output) const1248 void ViEChannel::GetReceiveBandwidthEstimatorStats(
1249 ReceiveBandwidthEstimatorStats* output) const {
1250 vie_receiver_.GetReceiveBandwidthEstimatorStats(output);
1251 }
1252
StartRTPDump(const char file_nameUTF8[1024],RTPDirections direction)1253 int32_t ViEChannel::StartRTPDump(const char file_nameUTF8[1024],
1254 RTPDirections direction) {
1255 if (direction == kRtpIncoming) {
1256 return vie_receiver_.StartRTPDump(file_nameUTF8);
1257 } else {
1258 return vie_sender_.StartRTPDump(file_nameUTF8);
1259 }
1260 }
1261
StopRTPDump(RTPDirections direction)1262 int32_t ViEChannel::StopRTPDump(RTPDirections direction) {
1263 if (direction == kRtpIncoming) {
1264 return vie_receiver_.StopRTPDump();
1265 } else {
1266 return vie_sender_.StopRTPDump();
1267 }
1268 }
1269
StartSend()1270 int32_t ViEChannel::StartSend() {
1271 CriticalSectionScoped cs(callback_cs_.get());
1272 if (!external_transport_) {
1273 LOG(LS_ERROR) << "No transport set.";
1274 return -1;
1275 }
1276 rtp_rtcp_->SetSendingMediaStatus(true);
1277
1278 if (rtp_rtcp_->Sending()) {
1279 return kViEBaseAlreadySending;
1280 }
1281 if (rtp_rtcp_->SetSendingStatus(true) != 0) {
1282 return -1;
1283 }
1284 CriticalSectionScoped cs_rtp(rtp_rtcp_cs_.get());
1285 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1286 it != simulcast_rtp_rtcp_.end();
1287 it++) {
1288 RtpRtcp* rtp_rtcp = *it;
1289 rtp_rtcp->SetSendingMediaStatus(true);
1290 rtp_rtcp->SetSendingStatus(true);
1291 }
1292 return 0;
1293 }
1294
StopSend()1295 int32_t ViEChannel::StopSend() {
1296 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1297 rtp_rtcp_->SetSendingMediaStatus(false);
1298 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1299 it != simulcast_rtp_rtcp_.end();
1300 it++) {
1301 RtpRtcp* rtp_rtcp = *it;
1302 rtp_rtcp->SetSendingMediaStatus(false);
1303 }
1304 if (!rtp_rtcp_->Sending()) {
1305 return kViEBaseNotSending;
1306 }
1307
1308 // Reset.
1309 rtp_rtcp_->ResetSendDataCountersRTP();
1310 if (rtp_rtcp_->SetSendingStatus(false) != 0) {
1311 return -1;
1312 }
1313 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1314 it != simulcast_rtp_rtcp_.end();
1315 it++) {
1316 RtpRtcp* rtp_rtcp = *it;
1317 rtp_rtcp->ResetSendDataCountersRTP();
1318 rtp_rtcp->SetSendingStatus(false);
1319 }
1320 return 0;
1321 }
1322
Sending()1323 bool ViEChannel::Sending() {
1324 return rtp_rtcp_->Sending();
1325 }
1326
StartReceive()1327 int32_t ViEChannel::StartReceive() {
1328 CriticalSectionScoped cs(callback_cs_.get());
1329 if (StartDecodeThread() != 0) {
1330 vie_receiver_.StopReceive();
1331 return -1;
1332 }
1333 vie_receiver_.StartReceive();
1334 return 0;
1335 }
1336
StopReceive()1337 int32_t ViEChannel::StopReceive() {
1338 vie_receiver_.StopReceive();
1339 StopDecodeThread();
1340 vcm_->ResetDecoder();
1341 return 0;
1342 }
1343
RegisterSendTransport(Transport * transport)1344 int32_t ViEChannel::RegisterSendTransport(Transport* transport) {
1345 if (rtp_rtcp_->Sending()) {
1346 return -1;
1347 }
1348
1349 CriticalSectionScoped cs(callback_cs_.get());
1350 if (external_transport_) {
1351 LOG_F(LS_ERROR) << "Transport already registered.";
1352 return -1;
1353 }
1354 external_transport_ = transport;
1355 vie_sender_.RegisterSendTransport(transport);
1356 return 0;
1357 }
1358
DeregisterSendTransport()1359 int32_t ViEChannel::DeregisterSendTransport() {
1360 CriticalSectionScoped cs(callback_cs_.get());
1361 if (!external_transport_) {
1362 return 0;
1363 }
1364 if (rtp_rtcp_->Sending()) {
1365 LOG_F(LS_ERROR) << "Can't deregister transport when sending.";
1366 return -1;
1367 }
1368 external_transport_ = NULL;
1369 vie_sender_.DeregisterSendTransport();
1370 return 0;
1371 }
1372
ReceivedRTPPacket(const void * rtp_packet,const int32_t rtp_packet_length,const PacketTime & packet_time)1373 int32_t ViEChannel::ReceivedRTPPacket(
1374 const void* rtp_packet, const int32_t rtp_packet_length,
1375 const PacketTime& packet_time) {
1376 {
1377 CriticalSectionScoped cs(callback_cs_.get());
1378 if (!external_transport_) {
1379 return -1;
1380 }
1381 }
1382 return vie_receiver_.ReceivedRTPPacket(
1383 rtp_packet, rtp_packet_length, packet_time);
1384 }
1385
ReceivedRTCPPacket(const void * rtcp_packet,const int32_t rtcp_packet_length)1386 int32_t ViEChannel::ReceivedRTCPPacket(
1387 const void* rtcp_packet, const int32_t rtcp_packet_length) {
1388 {
1389 CriticalSectionScoped cs(callback_cs_.get());
1390 if (!external_transport_) {
1391 return -1;
1392 }
1393 }
1394 return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length);
1395 }
1396
SetMTU(uint16_t mtu)1397 int32_t ViEChannel::SetMTU(uint16_t mtu) {
1398 if (rtp_rtcp_->SetMaxTransferUnit(mtu) != 0) {
1399 return -1;
1400 }
1401 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1402 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1403 it != simulcast_rtp_rtcp_.end();
1404 it++) {
1405 RtpRtcp* rtp_rtcp = *it;
1406 rtp_rtcp->SetMaxTransferUnit(mtu);
1407 }
1408 mtu_ = mtu;
1409 return 0;
1410 }
1411
MaxDataPayloadLength() const1412 uint16_t ViEChannel::MaxDataPayloadLength() const {
1413 return rtp_rtcp_->MaxDataPayloadLength();
1414 }
1415
EnableColorEnhancement(bool enable)1416 int32_t ViEChannel::EnableColorEnhancement(bool enable) {
1417 CriticalSectionScoped cs(callback_cs_.get());
1418 color_enhancement_ = enable;
1419 return 0;
1420 }
1421
rtp_rtcp()1422 RtpRtcp* ViEChannel::rtp_rtcp() {
1423 return rtp_rtcp_.get();
1424 }
1425
GetStatsObserver()1426 CallStatsObserver* ViEChannel::GetStatsObserver() {
1427 return stats_observer_.get();
1428 }
1429
1430 // Do not acquire the lock of |vcm_| in this function. Decode callback won't
1431 // necessarily be called from the decoding thread. The decoding thread may have
1432 // held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring
1433 // the same lock in the path of decode callback can deadlock.
FrameToRender(I420VideoFrame & video_frame)1434 int32_t ViEChannel::FrameToRender(
1435 I420VideoFrame& video_frame) { // NOLINT
1436 CriticalSectionScoped cs(callback_cs_.get());
1437
1438 if (decoder_reset_) {
1439 // Trigger a callback to the user if the incoming codec has changed.
1440 if (codec_observer_) {
1441 // The codec set by RegisterReceiveCodec might not be the size we're
1442 // actually decoding.
1443 receive_codec_.width = static_cast<uint16_t>(video_frame.width());
1444 receive_codec_.height = static_cast<uint16_t>(video_frame.height());
1445 codec_observer_->IncomingCodecChanged(channel_id_, receive_codec_);
1446 }
1447 decoder_reset_ = false;
1448 }
1449 // Post processing is not supported if the frame is backed by a texture.
1450 if (video_frame.native_handle() == NULL) {
1451 if (pre_render_callback_ != NULL)
1452 pre_render_callback_->FrameCallback(&video_frame);
1453 if (effect_filter_) {
1454 unsigned int length = CalcBufferSize(kI420,
1455 video_frame.width(),
1456 video_frame.height());
1457 scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]);
1458 ExtractBuffer(video_frame, length, video_buffer.get());
1459 effect_filter_->Transform(length,
1460 video_buffer.get(),
1461 video_frame.ntp_time_ms(),
1462 video_frame.timestamp(),
1463 video_frame.width(),
1464 video_frame.height());
1465 }
1466 if (color_enhancement_) {
1467 VideoProcessingModule::ColorEnhancement(&video_frame);
1468 }
1469 }
1470
1471 uint32_t arr_ofCSRC[kRtpCsrcSize];
1472 int32_t no_of_csrcs = vie_receiver_.GetCsrcs(arr_ofCSRC);
1473 if (no_of_csrcs <= 0) {
1474 arr_ofCSRC[0] = vie_receiver_.GetRemoteSsrc();
1475 no_of_csrcs = 1;
1476 }
1477 DeliverFrame(&video_frame, no_of_csrcs, arr_ofCSRC);
1478 return 0;
1479 }
1480
ReceivedDecodedReferenceFrame(const uint64_t picture_id)1481 int32_t ViEChannel::ReceivedDecodedReferenceFrame(
1482 const uint64_t picture_id) {
1483 return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
1484 }
1485
IncomingCodecChanged(const VideoCodec & codec)1486 void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
1487 CriticalSectionScoped cs(callback_cs_.get());
1488 receive_codec_ = codec;
1489 }
1490
OnReceiveStatisticsUpdate(const uint32_t bit_rate,const uint32_t frame_rate)1491 int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate,
1492 const uint32_t frame_rate) {
1493 CriticalSectionScoped cs(callback_cs_.get());
1494 if (codec_observer_) {
1495 codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate);
1496 }
1497 return 0;
1498 }
1499
OnDecoderTiming(int decode_ms,int max_decode_ms,int current_delay_ms,int target_delay_ms,int jitter_buffer_ms,int min_playout_delay_ms,int render_delay_ms)1500 void ViEChannel::OnDecoderTiming(int decode_ms,
1501 int max_decode_ms,
1502 int current_delay_ms,
1503 int target_delay_ms,
1504 int jitter_buffer_ms,
1505 int min_playout_delay_ms,
1506 int render_delay_ms) {
1507 CriticalSectionScoped cs(callback_cs_.get());
1508 if (!codec_observer_)
1509 return;
1510 codec_observer_->DecoderTiming(decode_ms,
1511 max_decode_ms,
1512 current_delay_ms,
1513 target_delay_ms,
1514 jitter_buffer_ms,
1515 min_playout_delay_ms,
1516 render_delay_ms);
1517 }
1518
RequestKeyFrame()1519 int32_t ViEChannel::RequestKeyFrame() {
1520 {
1521 CriticalSectionScoped cs(callback_cs_.get());
1522 if (codec_observer_ && do_key_frame_callbackRequest_) {
1523 codec_observer_->RequestNewKeyFrame(channel_id_);
1524 }
1525 }
1526 return rtp_rtcp_->RequestKeyFrame();
1527 }
1528
SliceLossIndicationRequest(const uint64_t picture_id)1529 int32_t ViEChannel::SliceLossIndicationRequest(
1530 const uint64_t picture_id) {
1531 return rtp_rtcp_->SendRTCPSliceLossIndication((uint8_t) picture_id);
1532 }
1533
ResendPackets(const uint16_t * sequence_numbers,uint16_t length)1534 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
1535 uint16_t length) {
1536 return rtp_rtcp_->SendNACK(sequence_numbers, length);
1537 }
1538
ChannelDecodeThreadFunction(void * obj)1539 bool ViEChannel::ChannelDecodeThreadFunction(void* obj) {
1540 return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess();
1541 }
1542
ChannelDecodeProcess()1543 bool ViEChannel::ChannelDecodeProcess() {
1544 vcm_->Decode(kMaxDecodeWaitTimeMs);
1545 return true;
1546 }
1547
OnRttUpdate(uint32_t rtt)1548 void ViEChannel::OnRttUpdate(uint32_t rtt) {
1549 vcm_->SetReceiveChannelParameters(rtt);
1550 }
1551
ReserveRtpRtcpModules(size_t num_modules)1552 void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) {
1553 for (size_t total_modules =
1554 1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size();
1555 total_modules < num_modules;
1556 ++total_modules) {
1557 RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
1558 rtp_rtcp->SetSendingStatus(false);
1559 rtp_rtcp->SetSendingMediaStatus(false);
1560 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
1561 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
1562 removed_rtp_rtcp_.push_back(rtp_rtcp);
1563 }
1564 }
1565
GetRtpRtcpModule(size_t index) const1566 RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const {
1567 if (index == 0)
1568 return rtp_rtcp_.get();
1569 if (index <= simulcast_rtp_rtcp_.size()) {
1570 std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1571 for (size_t i = 1; i < index; ++i) {
1572 ++it;
1573 }
1574 return *it;
1575 }
1576
1577 // If the requested module exists it must be in the removed list. Index
1578 // translation to this list must remove the default module as well as all
1579 // active simulcast modules.
1580 size_t removed_idx = index - simulcast_rtp_rtcp_.size() - 1;
1581 if (removed_idx >= removed_rtp_rtcp_.size())
1582 return NULL;
1583
1584 std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1585 while (removed_idx-- > 0)
1586 ++it;
1587
1588 return *it;
1589 }
1590
CreateRtpRtcpModule()1591 RtpRtcp* ViEChannel::CreateRtpRtcpModule() {
1592 RtpRtcp::Configuration configuration;
1593 configuration.id = ViEModuleId(engine_id_, channel_id_);
1594 configuration.audio = false; // Video.
1595 configuration.default_module = default_rtp_rtcp_;
1596 configuration.outgoing_transport = &vie_sender_;
1597 configuration.intra_frame_callback = intra_frame_observer_;
1598 configuration.bandwidth_callback = bandwidth_observer_.get();
1599 configuration.rtt_stats = rtt_stats_;
1600 configuration.paced_sender = paced_sender_;
1601 configuration.send_side_delay_observer = &send_side_delay_observer_;
1602
1603 return RtpRtcp::CreateRtpRtcp(configuration);
1604 }
1605
StartDecodeThread()1606 int32_t ViEChannel::StartDecodeThread() {
1607 // Start the decode thread
1608 if (decode_thread_) {
1609 // Already started.
1610 return 0;
1611 }
1612 decode_thread_ = ThreadWrapper::CreateThread(ChannelDecodeThreadFunction,
1613 this, kHighestPriority,
1614 "DecodingThread");
1615 if (!decode_thread_) {
1616 return -1;
1617 }
1618
1619 unsigned int thread_id;
1620 if (decode_thread_->Start(thread_id) == false) {
1621 delete decode_thread_;
1622 decode_thread_ = NULL;
1623 LOG(LS_ERROR) << "Could not start decode thread.";
1624 return -1;
1625 }
1626 return 0;
1627 }
1628
StopDecodeThread()1629 int32_t ViEChannel::StopDecodeThread() {
1630 if (!decode_thread_) {
1631 return 0;
1632 }
1633
1634 decode_thread_->SetNotAlive();
1635 if (decode_thread_->Stop()) {
1636 delete decode_thread_;
1637 } else {
1638 assert(false && "could not stop decode thread");
1639 }
1640 decode_thread_ = NULL;
1641 return 0;
1642 }
1643
SetVoiceChannel(int32_t ve_channel_id,VoEVideoSync * ve_sync_interface)1644 int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
1645 VoEVideoSync* ve_sync_interface) {
1646 if (ve_sync_interface) {
1647 // Register lip sync
1648 module_process_thread_.RegisterModule(&vie_sync_);
1649 } else {
1650 module_process_thread_.DeRegisterModule(&vie_sync_);
1651 }
1652 return vie_sync_.ConfigureSync(ve_channel_id,
1653 ve_sync_interface,
1654 rtp_rtcp_.get(),
1655 vie_receiver_.GetRtpReceiver());
1656 }
1657
VoiceChannel()1658 int32_t ViEChannel::VoiceChannel() {
1659 return vie_sync_.VoiceChannel();
1660 }
1661
RegisterEffectFilter(ViEEffectFilter * effect_filter)1662 int32_t ViEChannel::RegisterEffectFilter(ViEEffectFilter* effect_filter) {
1663 CriticalSectionScoped cs(callback_cs_.get());
1664 if (effect_filter && effect_filter_) {
1665 LOG(LS_ERROR) << "Effect filter already registered.";
1666 return -1;
1667 }
1668 effect_filter_ = effect_filter;
1669 return 0;
1670 }
1671
RegisterPreRenderCallback(I420FrameCallback * pre_render_callback)1672 void ViEChannel::RegisterPreRenderCallback(
1673 I420FrameCallback* pre_render_callback) {
1674 CriticalSectionScoped cs(callback_cs_.get());
1675 pre_render_callback_ = pre_render_callback;
1676 }
1677
RegisterPreDecodeImageCallback(EncodedImageCallback * pre_decode_callback)1678 void ViEChannel::RegisterPreDecodeImageCallback(
1679 EncodedImageCallback* pre_decode_callback) {
1680 vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
1681 }
1682
OnApplicationDataReceived(const int32_t id,const uint8_t sub_type,const uint32_t name,const uint16_t length,const uint8_t * data)1683 void ViEChannel::OnApplicationDataReceived(const int32_t id,
1684 const uint8_t sub_type,
1685 const uint32_t name,
1686 const uint16_t length,
1687 const uint8_t* data) {
1688 if (channel_id_ != ChannelId(id)) {
1689 return;
1690 }
1691 CriticalSectionScoped cs(callback_cs_.get());
1692 {
1693 if (rtcp_observer_) {
1694 rtcp_observer_->OnApplicationDataReceived(
1695 channel_id_, sub_type, name, reinterpret_cast<const char*>(data),
1696 length);
1697 }
1698 }
1699 }
1700
OnInitializeDecoder(const int32_t id,const int8_t payload_type,const char payload_name[RTP_PAYLOAD_NAME_SIZE],const int frequency,const uint8_t channels,const uint32_t rate)1701 int32_t ViEChannel::OnInitializeDecoder(
1702 const int32_t id,
1703 const int8_t payload_type,
1704 const char payload_name[RTP_PAYLOAD_NAME_SIZE],
1705 const int frequency,
1706 const uint8_t channels,
1707 const uint32_t rate) {
1708 LOG(LS_INFO) << "OnInitializeDecoder " << payload_type << " "
1709 << payload_name;
1710 vcm_->ResetDecoder();
1711
1712 CriticalSectionScoped cs(callback_cs_.get());
1713 decoder_reset_ = true;
1714 return 0;
1715 }
1716
OnIncomingSSRCChanged(const int32_t id,const uint32_t ssrc)1717 void ViEChannel::OnIncomingSSRCChanged(const int32_t id, const uint32_t ssrc) {
1718 assert(channel_id_ == ChannelId(id));
1719 rtp_rtcp_->SetRemoteSSRC(ssrc);
1720
1721 CriticalSectionScoped cs(callback_cs_.get());
1722 {
1723 if (rtp_observer_) {
1724 rtp_observer_->IncomingSSRCChanged(channel_id_, ssrc);
1725 }
1726 }
1727 }
1728
OnIncomingCSRCChanged(const int32_t id,const uint32_t CSRC,const bool added)1729 void ViEChannel::OnIncomingCSRCChanged(const int32_t id,
1730 const uint32_t CSRC,
1731 const bool added) {
1732 assert(channel_id_ == ChannelId(id));
1733 CriticalSectionScoped cs(callback_cs_.get());
1734 {
1735 if (rtp_observer_) {
1736 rtp_observer_->IncomingCSRCChanged(channel_id_, CSRC, added);
1737 }
1738 }
1739 }
1740
ResetStatistics(uint32_t ssrc)1741 void ViEChannel::ResetStatistics(uint32_t ssrc) {
1742 StreamStatistician* statistician =
1743 vie_receiver_.GetReceiveStatistics()->GetStatistician(ssrc);
1744 if (statistician)
1745 statistician->ResetStatistics();
1746 }
1747
RegisterSendFrameCountObserver(FrameCountObserver * observer)1748 void ViEChannel::RegisterSendFrameCountObserver(
1749 FrameCountObserver* observer) {
1750 send_frame_count_observer_.Set(observer);
1751 }
1752
ReceivedBWEPacket(int64_t arrival_time_ms,int payload_size,const RTPHeader & header)1753 void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms,
1754 int payload_size, const RTPHeader& header) {
1755 vie_receiver_.ReceivedBWEPacket(arrival_time_ms, payload_size, header);
1756 }
1757 } // namespace webrtc
1758