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