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 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 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 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 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 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. 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 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. 303 int32_t VideoReceiver::RegisterReceiveCallback( 304 VCMReceiveCallback* receiveCallback) { 305 CriticalSectionScoped cs(_receiveCritSect); 306 _decodedFrameCallback.SetUserReceiveCallback(receiveCallback); 307 return VCM_OK; 308 } 309 310 int32_t VideoReceiver::RegisterReceiveStatisticsCallback( 311 VCMReceiveStatisticsCallback* receiveStats) { 312 CriticalSectionScoped cs(process_crit_sect_.get()); 313 _receiveStatsCallback = receiveStats; 314 return VCM_OK; 315 } 316 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. 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. 342 int32_t VideoReceiver::RegisterFrameTypeCallback( 343 VCMFrameTypeCallback* frameTypeCallback) { 344 CriticalSectionScoped cs(process_crit_sect_.get()); 345 _frameTypeCallback = frameTypeCallback; 346 return VCM_OK; 347 } 348 349 int32_t VideoReceiver::RegisterPacketRequestCallback( 350 VCMPacketRequestCallback* callback) { 351 CriticalSectionScoped cs(process_crit_sect_.get()); 352 _packetRequestCallback = callback; 353 return VCM_OK; 354 } 355 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. 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 438 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 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 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. 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 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 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 611 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 620 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. 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. 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 676 int32_t VideoReceiver::SetRenderDelay(uint32_t timeMS) { 677 _timing.set_render_delay(timeMS); 678 return VCM_OK; 679 } 680 681 // Current video delay 682 int32_t VideoReceiver::Delay() const { return _timing.TargetVideoDelay(); } 683 684 // Nack list 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 704 int32_t VideoReceiver::ReceivedFrameCount(VCMFrameCount* frameCount) const { 705 _receiver.ReceivedFrameCount(frameCount); 706 return VCM_OK; 707 } 708 709 uint32_t VideoReceiver::DiscardedPackets() const { 710 return _receiver.DiscardedPackets(); 711 } 712 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 775 void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) { 776 CriticalSectionScoped cs(_receiveCritSect); 777 _receiver.SetDecodeErrorMode(decode_error_mode); 778 } 779 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 794 int VideoReceiver::SetMinReceiverDelay(int desired_delay_ms) { 795 return _receiver.SetMinReceiverDelay(desired_delay_ms); 796 } 797 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