diff options
Diffstat (limited to 'chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc')
-rw-r--r-- | chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc | 156 |
1 files changed, 65 insertions, 91 deletions
diff --git a/chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc b/chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc index 68668eae7de..5bc1c90f52c 100644 --- a/chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc +++ b/chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc @@ -16,7 +16,7 @@ #include "webrtc/modules/video_coding/main/source/packet.h" #include "webrtc/modules/video_coding/main/source/video_coding_impl.h" #include "webrtc/system_wrappers/interface/clock.h" -#include "webrtc/system_wrappers/interface/trace.h" +#include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/system_wrappers/interface/trace_event.h" // #define DEBUG_DECODER_BIT_STREAM @@ -24,18 +24,15 @@ namespace webrtc { namespace vcm { -VideoReceiver::VideoReceiver(const int32_t id, - Clock* clock, - EventFactory* event_factory) - : _id(id), - clock_(clock), +VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory) + : clock_(clock), process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), _receiveCritSect(CriticalSectionWrapper::CreateCriticalSection()), _receiverInited(false), - _timing(clock_, id, 1), - _dualTiming(clock_, id, 2, &_timing), - _receiver(&_timing, clock_, event_factory, id, 1, true), - _dualReceiver(&_dualTiming, clock_, event_factory, id, 2, false), + _timing(clock_), + _dualTiming(clock_, &_timing), + _receiver(&_timing, clock_, event_factory, true), + _dualReceiver(&_dualTiming, clock_, event_factory, false), _decodedFrameCallback(_timing, clock_), _dualDecodedFrameCallback(_dualTiming, clock_), _frameTypeCallback(NULL), @@ -53,7 +50,7 @@ VideoReceiver::VideoReceiver(const int32_t id, _scheduleKeyRequest(false), max_nack_list_size_(0), pre_decode_image_callback_(NULL), - _codecDataBase(id), + _codecDataBase(), _receiveStatsTimer(1000, clock_), _retransmissionTimer(10, clock_), _keyRequestTimer(500, clock_) { @@ -121,8 +118,12 @@ int32_t VideoReceiver::Process() { // Key frame requests if (_keyRequestTimer.TimeUntilProcess() == 0) { _keyRequestTimer.Processed(); - CriticalSectionScoped cs(process_crit_sect_.get()); - if (_scheduleKeyRequest && _frameTypeCallback != NULL) { + bool request_key_frame = false; + { + CriticalSectionScoped cs(process_crit_sect_.get()); + request_key_frame = _scheduleKeyRequest && _frameTypeCallback != NULL; + } + if (request_key_frame) { const int32_t ret = RequestKeyFrame(); if (ret != VCM_OK && returnValue == VCM_OK) { returnValue = ret; @@ -135,16 +136,24 @@ int32_t VideoReceiver::Process() { // disabled when NACK is off. if (_retransmissionTimer.TimeUntilProcess() == 0) { _retransmissionTimer.Processed(); - CriticalSectionScoped cs(process_crit_sect_.get()); - if (_packetRequestCallback != NULL) { - uint16_t length = max_nack_list_size_; + bool callback_registered = false; + uint16_t length; + { + CriticalSectionScoped cs(process_crit_sect_.get()); + length = max_nack_list_size_; + callback_registered = _packetRequestCallback != NULL; + } + if (callback_registered && length > 0) { std::vector<uint16_t> nackList(length); const int32_t ret = NackList(&nackList[0], &length); if (ret != VCM_OK && returnValue == VCM_OK) { returnValue = ret; } - if (length > 0) { - _packetRequestCallback->ResendPackets(&nackList[0], length); + if (ret == VCM_OK && length > 0) { + CriticalSectionScoped cs(process_crit_sect_.get()); + if (_packetRequestCallback != NULL) { + _packetRequestCallback->ResendPackets(&nackList[0], length); + } } } } @@ -434,17 +443,9 @@ int32_t VideoReceiver::RequestSliceLossIndication( const int32_t ret = _frameTypeCallback->SliceLossIndicationRequest(pictureID); if (ret < 0) { - WEBRTC_TRACE(webrtc::kTraceError, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Failed to request key frame"); return ret; } } else { - WEBRTC_TRACE(webrtc::kTraceWarning, - webrtc::kTraceVideoCoding, - VCMId(_id), - "No frame type request callback registered"); return VCM_MISSING_CALLBACK; } return VCM_OK; @@ -452,22 +453,14 @@ int32_t VideoReceiver::RequestSliceLossIndication( int32_t VideoReceiver::RequestKeyFrame() { TRACE_EVENT0("webrtc", "RequestKeyFrame"); - CriticalSectionScoped cs(process_crit_sect_.get()); + CriticalSectionScoped process_cs(process_crit_sect_.get()); if (_frameTypeCallback != NULL) { const int32_t ret = _frameTypeCallback->RequestKeyFrame(); if (ret < 0) { - WEBRTC_TRACE(webrtc::kTraceError, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Failed to request key frame"); return ret; } _scheduleKeyRequest = false; } else { - WEBRTC_TRACE(webrtc::kTraceWarning, - webrtc::kTraceVideoCoding, - VCMId(_id), - "No frame type request callback registered"); return VCM_MISSING_CALLBACK; } return VCM_OK; @@ -490,29 +483,18 @@ int32_t VideoReceiver::DecodeDualFrame(uint16_t maxWaitTimeMs) { VCMEncodedFrame* dualFrame = _dualReceiver.FrameForDecoding(maxWaitTimeMs, dummyRenderTime); if (dualFrame != NULL && _dualDecoder != NULL) { - WEBRTC_TRACE(webrtc::kTraceStream, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Decoding frame %u with dual decoder", - dualFrame->TimeStamp()); // Decode dualFrame and try to catch up int32_t ret = _dualDecoder->Decode(*dualFrame, clock_->TimeInMilliseconds()); if (ret != WEBRTC_VIDEO_CODEC_OK) { - WEBRTC_TRACE(webrtc::kTraceWarning, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Failed to decode frame with dual decoder"); + LOG(LS_ERROR) << "Failed to decode frame with dual decoder. Error code: " + << ret; _dualReceiver.ReleaseFrame(dualFrame); return VCM_CODEC_ERROR; } if (_receiver.DualDecoderCaughtUp(dualFrame, _dualReceiver)) { // Copy the complete decoder state of the dual decoder // to the primary decoder. - WEBRTC_TRACE(webrtc::kTraceStream, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Dual decoder caught up"); _codecDataBase.CopyDecoder(*_dualDecoder); _codecDataBase.ReleaseDecoder(_dualDecoder); _dualDecoder = NULL; @@ -547,62 +529,65 @@ int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); // Check for failed decoding, run frame type request callback if needed. + bool request_key_frame = false; if (ret < 0) { if (ret == VCM_ERROR_REQUEST_SLI) { return RequestSliceLossIndication( _decodedFrameCallback.LastReceivedPictureID() + 1); } else { - WEBRTC_TRACE(webrtc::kTraceError, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Failed to decode frame %u, requesting key frame", - frame.TimeStamp()); - ret = RequestKeyFrame(); + request_key_frame = true; } } else if (ret == VCM_REQUEST_SLI) { ret = RequestSliceLossIndication( _decodedFrameCallback.LastReceivedPictureID() + 1); } if (!frame.Complete() || frame.MissingFrame()) { - CriticalSectionScoped cs(process_crit_sect_.get()); switch (_keyRequestMode) { case kKeyOnKeyLoss: { if (frame.FrameType() == kVideoFrameKey) { - _scheduleKeyRequest = true; - return VCM_OK; + request_key_frame = true; + ret = VCM_OK; } break; } case kKeyOnLoss: { - _scheduleKeyRequest = true; - return VCM_OK; + request_key_frame = true; + ret = VCM_OK; } default: break; } } + if (request_key_frame) { + CriticalSectionScoped cs(process_crit_sect_.get()); + _scheduleKeyRequest = true; + } TRACE_EVENT_ASYNC_END0("webrtc", "Video", frame.TimeStamp()); return ret; } // Reset the decoder state int32_t VideoReceiver::ResetDecoder() { - CriticalSectionScoped cs(_receiveCritSect); - if (_decoder != NULL) { - _receiver.Initialize(); - _timing.Reset(); - { - CriticalSectionScoped cs(process_crit_sect_.get()); - _scheduleKeyRequest = false; + bool reset_key_request = false; + { + CriticalSectionScoped cs(_receiveCritSect); + if (_decoder != NULL) { + _receiver.Initialize(); + _timing.Reset(); + reset_key_request = true; + _decoder->Reset(); + } + if (_dualReceiver.State() != kPassive) { + _dualReceiver.Initialize(); + } + if (_dualDecoder != NULL) { + _codecDataBase.ReleaseDecoder(_dualDecoder); + _dualDecoder = NULL; } - _decoder->Reset(); - } - if (_dualReceiver.State() != kPassive) { - _dualReceiver.Initialize(); } - if (_dualDecoder != NULL) { - _codecDataBase.ReleaseDecoder(_dualDecoder); - _dualDecoder = NULL; + if (reset_key_request) { + CriticalSectionScoped cs(process_crit_sect_.get()); + _scheduleKeyRequest = false; } return VCM_OK; } @@ -710,25 +695,8 @@ int32_t VideoReceiver::NackList(uint16_t* nackList, uint16_t* size) { nackStatus = _dualReceiver.NackList(nackList, *size, &nack_list_length); } *size = nack_list_length; - - switch (nackStatus) { - case kNackNeedMoreMemory: { - WEBRTC_TRACE(webrtc::kTraceError, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Out of memory"); - return VCM_MEMORY; - } - case kNackKeyFrameRequest: { - CriticalSectionScoped cs(_receiveCritSect); - WEBRTC_TRACE(webrtc::kTraceWarning, - webrtc::kTraceVideoCoding, - VCMId(_id), - "Failed to get NACK list, requesting key frame"); + if (nackStatus == kNackKeyFrameRequest) { return RequestKeyFrame(); - } - default: - break; } return VCM_OK; } @@ -763,14 +731,17 @@ int VideoReceiver::SetReceiverRobustnessMode( _keyRequestMode = kKeyOnError; // TODO(hlundin): On long NACK list? break; case VideoCodingModule::kSoftNack: +#if 1 assert(false); // TODO(hlundin): Not completed. return VCM_NOT_IMPLEMENTED; +#else // Enable hybrid NACK/FEC. Always wait for retransmissions and don't add // extra delay when RTT is above kLowRttNackMs. _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1); _dualReceiver.SetNackMode(kNoNack, -1, -1); _keyRequestMode = kKeyOnError; break; +#endif case VideoCodingModule::kDualDecoder: if (decode_error_mode == kNoErrors) { return VCM_PARAMETER_ERROR; @@ -783,14 +754,17 @@ int VideoReceiver::SetReceiverRobustnessMode( _keyRequestMode = kKeyOnError; break; case VideoCodingModule::kReferenceSelection: +#if 1 assert(false); // TODO(hlundin): Not completed. return VCM_NOT_IMPLEMENTED; +#else if (decode_error_mode == kNoErrors) { return VCM_PARAMETER_ERROR; } _receiver.SetNackMode(kNoNack, -1, -1); _dualReceiver.SetNackMode(kNoNack, -1, -1); break; +#endif } _receiver.SetDecodeErrorMode(decode_error_mode); // The dual decoder should never decode with errors. |