1 /*
2 * Copyright (c) 2013 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/common_types.h"
12 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
13 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
14 #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
15 #include "webrtc/modules/video_coding/main/source/jitter_buffer.h"
16 #include "webrtc/modules/video_coding/main/source/packet.h"
17 #include "webrtc/modules/video_coding/main/source/video_coding_impl.h"
18 #include "webrtc/system_wrappers/interface/clock.h"
19 #include "webrtc/system_wrappers/interface/logging.h"
20 #include "webrtc/system_wrappers/interface/trace_event.h"
21
22 // #define DEBUG_DECODER_BIT_STREAM
23
24 namespace webrtc {
25 namespace vcm {
26
VideoReceiver(Clock * clock,EventFactory * event_factory)27 VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory)
28 : clock_(clock),
29 process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
30 _receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()),
31 _receiverInited(false),
32 _timing(clock_),
33 _dualTiming(clock_, &_timing),
34 _receiver(&_timing, clock_, event_factory, true),
35 _dualReceiver(&_dualTiming, clock_, event_factory, false),
36 _decodedFrameCallback(_timing, clock_),
37 _dualDecodedFrameCallback(_dualTiming, clock_),
38 _frameTypeCallback(NULL),
39 _receiveStatsCallback(NULL),
40 _decoderTimingCallback(NULL),
41 _packetRequestCallback(NULL),
42 render_buffer_callback_(NULL),
43 _decoder(NULL),
44 _dualDecoder(NULL),
45 #ifdef DEBUG_DECODER_BIT_STREAM
46 _bitStreamBeforeDecoder(NULL),
47 #endif
48 _frameFromFile(),
49 _keyRequestMode(kKeyOnError),
50 _scheduleKeyRequest(false),
51 max_nack_list_size_(0),
52 pre_decode_image_callback_(NULL),
53 _codecDataBase(),
54 _receiveStatsTimer(1000, clock_),
55 _retransmissionTimer(10, clock_),
56 _keyRequestTimer(500, clock_) {
57 assert(clock_);
58 #ifdef DEBUG_DECODER_BIT_STREAM
59 _bitStreamBeforeDecoder = fopen("decoderBitStream.bit", "wb");
60 #endif
61 }
62
~VideoReceiver()63 VideoReceiver::~VideoReceiver() {
64 if (_dualDecoder != NULL) {
65 _codecDataBase.ReleaseDecoder(_dualDecoder);
66 }
67 delete _receiveCritSect;
68 #ifdef DEBUG_DECODER_BIT_STREAM
69 fclose(_bitStreamBeforeDecoder);
70 #endif
71 }
72
Process()73 int32_t VideoReceiver::Process() {
74 int32_t returnValue = VCM_OK;
75
76 // Receive-side statistics
77 if (_receiveStatsTimer.TimeUntilProcess() == 0) {
78 _receiveStatsTimer.Processed();
79 CriticalSectionScoped cs(process_crit_sect_.get());
80 if (_receiveStatsCallback != NULL) {
81 uint32_t bitRate;
82 uint32_t frameRate;
83 _receiver.ReceiveStatistics(&bitRate, &frameRate);
84 _receiveStatsCallback->OnReceiveStatisticsUpdate(bitRate, frameRate);
85 }
86
87 if (_decoderTimingCallback != NULL) {
88 int decode_ms;
89 int max_decode_ms;
90 int current_delay_ms;
91 int target_delay_ms;
92 int jitter_buffer_ms;
93 int min_playout_delay_ms;
94 int render_delay_ms;
95 _timing.GetTimings(&decode_ms,
96 &max_decode_ms,
97 ¤t_delay_ms,
98 &target_delay_ms,
99 &jitter_buffer_ms,
100 &min_playout_delay_ms,
101 &render_delay_ms);
102 _decoderTimingCallback->OnDecoderTiming(decode_ms,
103 max_decode_ms,
104 current_delay_ms,
105 target_delay_ms,
106 jitter_buffer_ms,
107 min_playout_delay_ms,
108 render_delay_ms);
109 }
110
111 // Size of render buffer.
112 if (render_buffer_callback_) {
113 int buffer_size_ms = _receiver.RenderBufferSizeMs();
114 render_buffer_callback_->RenderBufferSizeMs(buffer_size_ms);
115 }
116 }
117
118 // Key frame requests
119 if (_keyRequestTimer.TimeUntilProcess() == 0) {
120 _keyRequestTimer.Processed();
121 bool request_key_frame = false;
122 {
123 CriticalSectionScoped cs(process_crit_sect_.get());
124 request_key_frame = _scheduleKeyRequest && _frameTypeCallback != NULL;
125 }
126 if (request_key_frame) {
127 const int32_t ret = RequestKeyFrame();
128 if (ret != VCM_OK && returnValue == VCM_OK) {
129 returnValue = ret;
130 }
131 }
132 }
133
134 // Packet retransmission requests
135 // TODO(holmer): Add API for changing Process interval and make sure it's
136 // disabled when NACK is off.
137 if (_retransmissionTimer.TimeUntilProcess() == 0) {
138 _retransmissionTimer.Processed();
139 bool callback_registered = false;
140 uint16_t length;
141 {
142 CriticalSectionScoped cs(process_crit_sect_.get());
143 length = max_nack_list_size_;
144 callback_registered = _packetRequestCallback != NULL;
145 }
146 if (callback_registered && length > 0) {
147 std::vector<uint16_t> nackList(length);
148 const int32_t ret = NackList(&nackList[0], &length);
149 if (ret != VCM_OK && returnValue == VCM_OK) {
150 returnValue = ret;
151 }
152 if (ret == VCM_OK && length > 0) {
153 CriticalSectionScoped cs(process_crit_sect_.get());
154 if (_packetRequestCallback != NULL) {
155 _packetRequestCallback->ResendPackets(&nackList[0], length);
156 }
157 }
158 }
159 }
160
161 return returnValue;
162 }
163
TimeUntilNextProcess()164 int32_t VideoReceiver::TimeUntilNextProcess() {
165 uint32_t timeUntilNextProcess = _receiveStatsTimer.TimeUntilProcess();
166 if ((_receiver.NackMode() != kNoNack) ||
167 (_dualReceiver.State() != kPassive)) {
168 // We need a Process call more often if we are relying on
169 // retransmissions
170 timeUntilNextProcess =
171 VCM_MIN(timeUntilNextProcess, _retransmissionTimer.TimeUntilProcess());
172 }
173 timeUntilNextProcess =
174 VCM_MIN(timeUntilNextProcess, _keyRequestTimer.TimeUntilProcess());
175
176 return timeUntilNextProcess;
177 }
178
SetReceiveChannelParameters(uint32_t rtt)179 int32_t VideoReceiver::SetReceiveChannelParameters(uint32_t rtt) {
180 CriticalSectionScoped receiveCs(_receiveCritSect);
181 _receiver.UpdateRtt(rtt);
182 return 0;
183 }
184
185 // Enable or disable a video protection method.
186 // Note: This API should be deprecated, as it does not offer a distinction
187 // between the protection method and decoding with or without errors. If such a
188 // behavior is desired, use the following API: SetReceiverRobustnessMode.
SetVideoProtection(VCMVideoProtection videoProtection,bool enable)189 int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
190 bool enable) {
191 // By default, do not decode with errors.
192 _receiver.SetDecodeErrorMode(kNoErrors);
193 // The dual decoder should always be error free.
194 _dualReceiver.SetDecodeErrorMode(kNoErrors);
195 switch (videoProtection) {
196 case kProtectionNack:
197 case kProtectionNackReceiver: {
198 CriticalSectionScoped cs(_receiveCritSect);
199 if (enable) {
200 // Enable NACK and always wait for retransmits.
201 _receiver.SetNackMode(kNack, -1, -1);
202 } else {
203 _receiver.SetNackMode(kNoNack, -1, -1);
204 }
205 break;
206 }
207
208 case kProtectionDualDecoder: {
209 CriticalSectionScoped cs(_receiveCritSect);
210 if (enable) {
211 // Enable NACK but don't wait for retransmissions and don't
212 // add any extra delay.
213 _receiver.SetNackMode(kNack, 0, 0);
214 // Enable NACK and always wait for retransmissions and
215 // compensate with extra delay.
216 _dualReceiver.SetNackMode(kNack, -1, -1);
217 _receiver.SetDecodeErrorMode(kWithErrors);
218 } else {
219 _dualReceiver.SetNackMode(kNoNack, -1, -1);
220 }
221 break;
222 }
223
224 case kProtectionKeyOnLoss: {
225 CriticalSectionScoped cs(_receiveCritSect);
226 if (enable) {
227 _keyRequestMode = kKeyOnLoss;
228 _receiver.SetDecodeErrorMode(kWithErrors);
229 } else if (_keyRequestMode == kKeyOnLoss) {
230 _keyRequestMode = kKeyOnError; // default mode
231 } else {
232 return VCM_PARAMETER_ERROR;
233 }
234 break;
235 }
236
237 case kProtectionKeyOnKeyLoss: {
238 CriticalSectionScoped cs(_receiveCritSect);
239 if (enable) {
240 _keyRequestMode = kKeyOnKeyLoss;
241 } else if (_keyRequestMode == kKeyOnKeyLoss) {
242 _keyRequestMode = kKeyOnError; // default mode
243 } else {
244 return VCM_PARAMETER_ERROR;
245 }
246 break;
247 }
248
249 case kProtectionNackFEC: {
250 CriticalSectionScoped cs(_receiveCritSect);
251 if (enable) {
252 // Enable hybrid NACK/FEC. Always wait for retransmissions
253 // and don't add extra delay when RTT is above
254 // kLowRttNackMs.
255 _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
256 _receiver.SetDecodeErrorMode(kNoErrors);
257 _receiver.SetDecodeErrorMode(kNoErrors);
258 } else {
259 _receiver.SetNackMode(kNoNack, -1, -1);
260 }
261 break;
262 }
263 case kProtectionNackSender:
264 case kProtectionFEC:
265 case kProtectionPeriodicKeyFrames:
266 // Ignore encoder modes.
267 return VCM_OK;
268 }
269 return VCM_OK;
270 }
271
272 // Initialize receiver, resets codec database etc
InitializeReceiver()273 int32_t VideoReceiver::InitializeReceiver() {
274 CriticalSectionScoped receive_cs(_receiveCritSect);
275 CriticalSectionScoped process_cs(process_crit_sect_.get());
276 int32_t ret = _receiver.Initialize();
277 if (ret < 0) {
278 return ret;
279 }
280
281 ret = _dualReceiver.Initialize();
282 if (ret < 0) {
283 return ret;
284 }
285 _codecDataBase.ResetReceiver();
286 _timing.Reset();
287
288 _decoder = NULL;
289 _decodedFrameCallback.SetUserReceiveCallback(NULL);
290 _receiverInited = true;
291 _frameTypeCallback = NULL;
292 _receiveStatsCallback = NULL;
293 _decoderTimingCallback = NULL;
294 _packetRequestCallback = NULL;
295 _keyRequestMode = kKeyOnError;
296 _scheduleKeyRequest = false;
297
298 return VCM_OK;
299 }
300
301 // Register a receive callback. Will be called whenever there is a new frame
302 // ready for rendering.
RegisterReceiveCallback(VCMReceiveCallback * receiveCallback)303 int32_t VideoReceiver::RegisterReceiveCallback(
304 VCMReceiveCallback* receiveCallback) {
305 CriticalSectionScoped cs(_receiveCritSect);
306 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback);
307 return VCM_OK;
308 }
309
RegisterReceiveStatisticsCallback(VCMReceiveStatisticsCallback * receiveStats)310 int32_t VideoReceiver::RegisterReceiveStatisticsCallback(
311 VCMReceiveStatisticsCallback* receiveStats) {
312 CriticalSectionScoped cs(process_crit_sect_.get());
313 _receiveStatsCallback = receiveStats;
314 return VCM_OK;
315 }
316
RegisterDecoderTimingCallback(VCMDecoderTimingCallback * decoderTiming)317 int32_t VideoReceiver::RegisterDecoderTimingCallback(
318 VCMDecoderTimingCallback* decoderTiming) {
319 CriticalSectionScoped cs(process_crit_sect_.get());
320 _decoderTimingCallback = decoderTiming;
321 return VCM_OK;
322 }
323
324 // Register an externally defined decoder/render object.
325 // Can be a decoder only or a decoder coupled with a renderer.
RegisterExternalDecoder(VideoDecoder * externalDecoder,uint8_t payloadType,bool internalRenderTiming)326 int32_t VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder,
327 uint8_t payloadType,
328 bool internalRenderTiming) {
329 CriticalSectionScoped cs(_receiveCritSect);
330 if (externalDecoder == NULL) {
331 // Make sure the VCM updates the decoder next time it decodes.
332 _decoder = NULL;
333 return _codecDataBase.DeregisterExternalDecoder(payloadType) ? 0 : -1;
334 }
335 return _codecDataBase.RegisterExternalDecoder(
336 externalDecoder, payloadType, internalRenderTiming)
337 ? 0
338 : -1;
339 }
340
341 // Register a frame type request callback.
RegisterFrameTypeCallback(VCMFrameTypeCallback * frameTypeCallback)342 int32_t VideoReceiver::RegisterFrameTypeCallback(
343 VCMFrameTypeCallback* frameTypeCallback) {
344 CriticalSectionScoped cs(process_crit_sect_.get());
345 _frameTypeCallback = frameTypeCallback;
346 return VCM_OK;
347 }
348
RegisterPacketRequestCallback(VCMPacketRequestCallback * callback)349 int32_t VideoReceiver::RegisterPacketRequestCallback(
350 VCMPacketRequestCallback* callback) {
351 CriticalSectionScoped cs(process_crit_sect_.get());
352 _packetRequestCallback = callback;
353 return VCM_OK;
354 }
355
RegisterRenderBufferSizeCallback(VCMRenderBufferSizeCallback * callback)356 int VideoReceiver::RegisterRenderBufferSizeCallback(
357 VCMRenderBufferSizeCallback* callback) {
358 CriticalSectionScoped cs(process_crit_sect_.get());
359 render_buffer_callback_ = callback;
360 return VCM_OK;
361 }
362
363 // Decode next frame, blocking.
364 // Should be called as often as possible to get the most out of the decoder.
Decode(uint16_t maxWaitTimeMs)365 int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
366 int64_t nextRenderTimeMs;
367 {
368 CriticalSectionScoped cs(_receiveCritSect);
369 if (!_receiverInited) {
370 return VCM_UNINITIALIZED;
371 }
372 if (!_codecDataBase.DecoderRegistered()) {
373 return VCM_NO_CODEC_REGISTERED;
374 }
375 }
376
377 const bool dualReceiverEnabledNotReceiving = (
378 _dualReceiver.State() != kReceiving && _dualReceiver.NackMode() == kNack);
379
380 VCMEncodedFrame* frame =
381 _receiver.FrameForDecoding(maxWaitTimeMs,
382 nextRenderTimeMs,
383 _codecDataBase.SupportsRenderScheduling(),
384 &_dualReceiver);
385
386 if (dualReceiverEnabledNotReceiving && _dualReceiver.State() == kReceiving) {
387 // Dual receiver is enabled (kNACK enabled), but was not receiving
388 // before the call to FrameForDecoding(). After the call the state
389 // changed to receiving, and therefore we must copy the primary decoder
390 // state to the dual decoder to make it possible for the dual decoder to
391 // start decoding retransmitted frames and recover.
392 CriticalSectionScoped cs(_receiveCritSect);
393 if (_dualDecoder != NULL) {
394 _codecDataBase.ReleaseDecoder(_dualDecoder);
395 }
396 _dualDecoder = _codecDataBase.CreateDecoderCopy();
397 if (_dualDecoder != NULL) {
398 _dualDecoder->RegisterDecodeCompleteCallback(&_dualDecodedFrameCallback);
399 } else {
400 _dualReceiver.Reset();
401 }
402 }
403
404 if (frame == NULL) {
405 return VCM_FRAME_NOT_READY;
406 } else {
407 CriticalSectionScoped cs(_receiveCritSect);
408
409 // If this frame was too late, we should adjust the delay accordingly
410 _timing.UpdateCurrentDelay(frame->RenderTimeMs(),
411 clock_->TimeInMilliseconds());
412
413 if (pre_decode_image_callback_) {
414 EncodedImage encoded_image(frame->EncodedImage());
415 pre_decode_image_callback_->Encoded(encoded_image);
416 }
417
418 #ifdef DEBUG_DECODER_BIT_STREAM
419 if (_bitStreamBeforeDecoder != NULL) {
420 // Write bit stream to file for debugging purposes
421 if (fwrite(
422 frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) !=
423 frame->Length()) {
424 return -1;
425 }
426 }
427 #endif
428 const int32_t ret = Decode(*frame);
429 _receiver.ReleaseFrame(frame);
430 frame = NULL;
431 if (ret != VCM_OK) {
432 return ret;
433 }
434 }
435 return VCM_OK;
436 }
437
RequestSliceLossIndication(const uint64_t pictureID) const438 int32_t VideoReceiver::RequestSliceLossIndication(
439 const uint64_t pictureID) const {
440 TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID);
441 CriticalSectionScoped cs(process_crit_sect_.get());
442 if (_frameTypeCallback != NULL) {
443 const int32_t ret =
444 _frameTypeCallback->SliceLossIndicationRequest(pictureID);
445 if (ret < 0) {
446 return ret;
447 }
448 } else {
449 return VCM_MISSING_CALLBACK;
450 }
451 return VCM_OK;
452 }
453
RequestKeyFrame()454 int32_t VideoReceiver::RequestKeyFrame() {
455 TRACE_EVENT0("webrtc", "RequestKeyFrame");
456 CriticalSectionScoped process_cs(process_crit_sect_.get());
457 if (_frameTypeCallback != NULL) {
458 const int32_t ret = _frameTypeCallback->RequestKeyFrame();
459 if (ret < 0) {
460 return ret;
461 }
462 _scheduleKeyRequest = false;
463 } else {
464 return VCM_MISSING_CALLBACK;
465 }
466 return VCM_OK;
467 }
468
DecodeDualFrame(uint16_t maxWaitTimeMs)469 int32_t VideoReceiver::DecodeDualFrame(uint16_t maxWaitTimeMs) {
470 CriticalSectionScoped cs(_receiveCritSect);
471 if (_dualReceiver.State() != kReceiving ||
472 _dualReceiver.NackMode() != kNack) {
473 // The dual receiver is currently not receiving or
474 // dual decoder mode is disabled.
475 return VCM_OK;
476 }
477 int64_t dummyRenderTime;
478 int32_t decodeCount = 0;
479 // The dual decoder's state is copied from the main decoder, which may
480 // decode with errors. Make sure that the dual decoder does not introduce
481 // error.
482 _dualReceiver.SetDecodeErrorMode(kNoErrors);
483 VCMEncodedFrame* dualFrame =
484 _dualReceiver.FrameForDecoding(maxWaitTimeMs, dummyRenderTime);
485 if (dualFrame != NULL && _dualDecoder != NULL) {
486 // Decode dualFrame and try to catch up
487 int32_t ret =
488 _dualDecoder->Decode(*dualFrame, clock_->TimeInMilliseconds());
489 if (ret != WEBRTC_VIDEO_CODEC_OK) {
490 LOG(LS_ERROR) << "Failed to decode frame with dual decoder. Error code: "
491 << ret;
492 _dualReceiver.ReleaseFrame(dualFrame);
493 return VCM_CODEC_ERROR;
494 }
495 if (_receiver.DualDecoderCaughtUp(dualFrame, _dualReceiver)) {
496 // Copy the complete decoder state of the dual decoder
497 // to the primary decoder.
498 _codecDataBase.CopyDecoder(*_dualDecoder);
499 _codecDataBase.ReleaseDecoder(_dualDecoder);
500 _dualDecoder = NULL;
501 }
502 decodeCount++;
503 }
504 _dualReceiver.ReleaseFrame(dualFrame);
505 return decodeCount;
506 }
507
508 // Must be called from inside the receive side critical section.
Decode(const VCMEncodedFrame & frame)509 int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
510 TRACE_EVENT_ASYNC_STEP1("webrtc",
511 "Video",
512 frame.TimeStamp(),
513 "Decode",
514 "type",
515 frame.FrameType());
516 // Change decoder if payload type has changed
517 const bool renderTimingBefore = _codecDataBase.SupportsRenderScheduling();
518 _decoder =
519 _codecDataBase.GetDecoder(frame.PayloadType(), &_decodedFrameCallback);
520 if (renderTimingBefore != _codecDataBase.SupportsRenderScheduling()) {
521 // Make sure we reset the decode time estimate since it will
522 // be zero for codecs without render timing.
523 _timing.ResetDecodeTime();
524 }
525 if (_decoder == NULL) {
526 return VCM_NO_CODEC_REGISTERED;
527 }
528 // Decode a frame
529 int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds());
530
531 // Check for failed decoding, run frame type request callback if needed.
532 bool request_key_frame = false;
533 if (ret < 0) {
534 if (ret == VCM_ERROR_REQUEST_SLI) {
535 return RequestSliceLossIndication(
536 _decodedFrameCallback.LastReceivedPictureID() + 1);
537 } else {
538 request_key_frame = true;
539 }
540 } else if (ret == VCM_REQUEST_SLI) {
541 ret = RequestSliceLossIndication(
542 _decodedFrameCallback.LastReceivedPictureID() + 1);
543 }
544 if (!frame.Complete() || frame.MissingFrame()) {
545 switch (_keyRequestMode) {
546 case kKeyOnKeyLoss: {
547 if (frame.FrameType() == kVideoFrameKey) {
548 request_key_frame = true;
549 ret = VCM_OK;
550 }
551 break;
552 }
553 case kKeyOnLoss: {
554 request_key_frame = true;
555 ret = VCM_OK;
556 }
557 default:
558 break;
559 }
560 }
561 if (request_key_frame) {
562 CriticalSectionScoped cs(process_crit_sect_.get());
563 _scheduleKeyRequest = true;
564 }
565 TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp());
566 return ret;
567 }
568
569 // Reset the decoder state
ResetDecoder()570 int32_t VideoReceiver::ResetDecoder() {
571 bool reset_key_request = false;
572 {
573 CriticalSectionScoped cs(_receiveCritSect);
574 if (_decoder != NULL) {
575 _receiver.Initialize();
576 _timing.Reset();
577 reset_key_request = true;
578 _decoder->Reset();
579 }
580 if (_dualReceiver.State() != kPassive) {
581 _dualReceiver.Initialize();
582 }
583 if (_dualDecoder != NULL) {
584 _codecDataBase.ReleaseDecoder(_dualDecoder);
585 _dualDecoder = NULL;
586 }
587 }
588 if (reset_key_request) {
589 CriticalSectionScoped cs(process_crit_sect_.get());
590 _scheduleKeyRequest = false;
591 }
592 return VCM_OK;
593 }
594
595 // Register possible receive codecs, can be called multiple times
RegisterReceiveCodec(const VideoCodec * receiveCodec,int32_t numberOfCores,bool requireKeyFrame)596 int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
597 int32_t numberOfCores,
598 bool requireKeyFrame) {
599 CriticalSectionScoped cs(_receiveCritSect);
600 if (receiveCodec == NULL) {
601 return VCM_PARAMETER_ERROR;
602 }
603 if (!_codecDataBase.RegisterReceiveCodec(
604 receiveCodec, numberOfCores, requireKeyFrame)) {
605 return -1;
606 }
607 return 0;
608 }
609
610 // Get current received codec
ReceiveCodec(VideoCodec * currentReceiveCodec) const611 int32_t VideoReceiver::ReceiveCodec(VideoCodec* currentReceiveCodec) const {
612 CriticalSectionScoped cs(_receiveCritSect);
613 if (currentReceiveCodec == NULL) {
614 return VCM_PARAMETER_ERROR;
615 }
616 return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1;
617 }
618
619 // Get current received codec
ReceiveCodec() const620 VideoCodecType VideoReceiver::ReceiveCodec() const {
621 CriticalSectionScoped cs(_receiveCritSect);
622 return _codecDataBase.ReceiveCodec();
623 }
624
625 // Incoming packet from network parsed and ready for decode, non blocking.
IncomingPacket(const uint8_t * incomingPayload,uint32_t payloadLength,const WebRtcRTPHeader & rtpInfo)626 int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
627 uint32_t payloadLength,
628 const WebRtcRTPHeader& rtpInfo) {
629 if (rtpInfo.frameType == kVideoFrameKey) {
630 TRACE_EVENT1("webrtc",
631 "VCM::PacketKeyFrame",
632 "seqnum",
633 rtpInfo.header.sequenceNumber);
634 }
635 if (incomingPayload == NULL) {
636 // The jitter buffer doesn't handle non-zero payload lengths for packets
637 // without payload.
638 // TODO(holmer): We should fix this in the jitter buffer.
639 payloadLength = 0;
640 }
641 const VCMPacket packet(incomingPayload, payloadLength, rtpInfo);
642 int32_t ret;
643 if (_dualReceiver.State() != kPassive) {
644 ret = _dualReceiver.InsertPacket(
645 packet, rtpInfo.type.Video.width, rtpInfo.type.Video.height);
646 if (ret == VCM_FLUSH_INDICATOR) {
647 RequestKeyFrame();
648 ResetDecoder();
649 } else if (ret < 0) {
650 return ret;
651 }
652 }
653 ret = _receiver.InsertPacket(
654 packet, rtpInfo.type.Video.width, rtpInfo.type.Video.height);
655 // TODO(holmer): Investigate if this somehow should use the key frame
656 // request scheduling to throttle the requests.
657 if (ret == VCM_FLUSH_INDICATOR) {
658 RequestKeyFrame();
659 ResetDecoder();
660 } else if (ret < 0) {
661 return ret;
662 }
663 return VCM_OK;
664 }
665
666 // Minimum playout delay (used for lip-sync). This is the minimum delay required
667 // to sync with audio. Not included in VideoCodingModule::Delay()
668 // Defaults to 0 ms.
SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs)669 int32_t VideoReceiver::SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) {
670 _timing.set_min_playout_delay(minPlayoutDelayMs);
671 return VCM_OK;
672 }
673
674 // The estimated delay caused by rendering, defaults to
675 // kDefaultRenderDelayMs = 10 ms
SetRenderDelay(uint32_t timeMS)676 int32_t VideoReceiver::SetRenderDelay(uint32_t timeMS) {
677 _timing.set_render_delay(timeMS);
678 return VCM_OK;
679 }
680
681 // Current video delay
Delay() const682 int32_t VideoReceiver::Delay() const { return _timing.TargetVideoDelay(); }
683
684 // Nack list
NackList(uint16_t * nackList,uint16_t * size)685 int32_t VideoReceiver::NackList(uint16_t* nackList, uint16_t* size) {
686 VCMNackStatus nackStatus = kNackOk;
687 uint16_t nack_list_length = 0;
688 // Collect sequence numbers from the default receiver
689 // if in normal nack mode. Otherwise collect them from
690 // the dual receiver if the dual receiver is receiving.
691 if (_receiver.NackMode() != kNoNack) {
692 nackStatus = _receiver.NackList(nackList, *size, &nack_list_length);
693 }
694 if (nack_list_length == 0 && _dualReceiver.State() != kPassive) {
695 nackStatus = _dualReceiver.NackList(nackList, *size, &nack_list_length);
696 }
697 *size = nack_list_length;
698 if (nackStatus == kNackKeyFrameRequest) {
699 return RequestKeyFrame();
700 }
701 return VCM_OK;
702 }
703
ReceivedFrameCount(VCMFrameCount * frameCount) const704 int32_t VideoReceiver::ReceivedFrameCount(VCMFrameCount* frameCount) const {
705 _receiver.ReceivedFrameCount(frameCount);
706 return VCM_OK;
707 }
708
DiscardedPackets() const709 uint32_t VideoReceiver::DiscardedPackets() const {
710 return _receiver.DiscardedPackets();
711 }
712
SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,VCMDecodeErrorMode decode_error_mode)713 int VideoReceiver::SetReceiverRobustnessMode(
714 ReceiverRobustness robustnessMode,
715 VCMDecodeErrorMode decode_error_mode) {
716 CriticalSectionScoped cs(_receiveCritSect);
717 switch (robustnessMode) {
718 case VideoCodingModule::kNone:
719 _receiver.SetNackMode(kNoNack, -1, -1);
720 _dualReceiver.SetNackMode(kNoNack, -1, -1);
721 if (decode_error_mode == kNoErrors) {
722 _keyRequestMode = kKeyOnLoss;
723 } else {
724 _keyRequestMode = kKeyOnError;
725 }
726 break;
727 case VideoCodingModule::kHardNack:
728 // Always wait for retransmissions (except when decoding with errors).
729 _receiver.SetNackMode(kNack, -1, -1);
730 _dualReceiver.SetNackMode(kNoNack, -1, -1);
731 _keyRequestMode = kKeyOnError; // TODO(hlundin): On long NACK list?
732 break;
733 case VideoCodingModule::kSoftNack:
734 #if 1
735 assert(false); // TODO(hlundin): Not completed.
736 return VCM_NOT_IMPLEMENTED;
737 #else
738 // Enable hybrid NACK/FEC. Always wait for retransmissions and don't add
739 // extra delay when RTT is above kLowRttNackMs.
740 _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
741 _dualReceiver.SetNackMode(kNoNack, -1, -1);
742 _keyRequestMode = kKeyOnError;
743 break;
744 #endif
745 case VideoCodingModule::kDualDecoder:
746 if (decode_error_mode == kNoErrors) {
747 return VCM_PARAMETER_ERROR;
748 }
749 // Enable NACK but don't wait for retransmissions and don't add any extra
750 // delay.
751 _receiver.SetNackMode(kNack, 0, 0);
752 // Enable NACK, compensate with extra delay and wait for retransmissions.
753 _dualReceiver.SetNackMode(kNack, -1, -1);
754 _keyRequestMode = kKeyOnError;
755 break;
756 case VideoCodingModule::kReferenceSelection:
757 #if 1
758 assert(false); // TODO(hlundin): Not completed.
759 return VCM_NOT_IMPLEMENTED;
760 #else
761 if (decode_error_mode == kNoErrors) {
762 return VCM_PARAMETER_ERROR;
763 }
764 _receiver.SetNackMode(kNoNack, -1, -1);
765 _dualReceiver.SetNackMode(kNoNack, -1, -1);
766 break;
767 #endif
768 }
769 _receiver.SetDecodeErrorMode(decode_error_mode);
770 // The dual decoder should never decode with errors.
771 _dualReceiver.SetDecodeErrorMode(kNoErrors);
772 return VCM_OK;
773 }
774
SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode)775 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
776 CriticalSectionScoped cs(_receiveCritSect);
777 _receiver.SetDecodeErrorMode(decode_error_mode);
778 }
779
SetNackSettings(size_t max_nack_list_size,int max_packet_age_to_nack,int max_incomplete_time_ms)780 void VideoReceiver::SetNackSettings(size_t max_nack_list_size,
781 int max_packet_age_to_nack,
782 int max_incomplete_time_ms) {
783 if (max_nack_list_size != 0) {
784 CriticalSectionScoped receive_cs(_receiveCritSect);
785 CriticalSectionScoped process_cs(process_crit_sect_.get());
786 max_nack_list_size_ = max_nack_list_size;
787 }
788 _receiver.SetNackSettings(
789 max_nack_list_size, max_packet_age_to_nack, max_incomplete_time_ms);
790 _dualReceiver.SetNackSettings(
791 max_nack_list_size, max_packet_age_to_nack, max_incomplete_time_ms);
792 }
793
SetMinReceiverDelay(int desired_delay_ms)794 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) {
795 return _receiver.SetMinReceiverDelay(desired_delay_ms);
796 }
797
RegisterPreDecodeImageCallback(EncodedImageCallback * observer)798 void VideoReceiver::RegisterPreDecodeImageCallback(
799 EncodedImageCallback* observer) {
800 CriticalSectionScoped cs(_receiveCritSect);
801 pre_decode_image_callback_ = observer;
802 }
803
804 } // namespace vcm
805 } // namespace webrtc
806