summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/modules/video_coding/main/source/video_receiver.cc
diff options
context:
space:
mode:
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.cc156
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.