Fixes two bugs when decoding with packet losses.
Disable _missingFrame bit since we can't set it correctly with FEC. No longer return more than one decoded frame per Decode() call. This is a work-around for a bug where the frame info map was popped more often than items were added to the map. BUG= TEST= Review URL: http://webrtc-codereview.appspot.com/215001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@722 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
ed081a99a9
commit
06887aebae
@ -16,6 +16,7 @@
|
||||
// Define return values
|
||||
|
||||
#define WEBRTC_VIDEO_CODEC_REQUEST_SLI 2
|
||||
#define WEBRTC_VIDEO_CODEC_NO_OUTPUT 1
|
||||
#define WEBRTC_VIDEO_CODEC_OK 0
|
||||
#define WEBRTC_VIDEO_CODEC_ERROR -1
|
||||
#define WEBRTC_VIDEO_CODEC_LEVEL_EXCEEDED -2
|
||||
|
@ -835,9 +835,6 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
img = vpx_codec_get_frame(_decoder, &iter);
|
||||
ret = ReturnFrame(img, inputImage._timeStamp);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
iter = NULL;
|
||||
}
|
||||
|
||||
@ -966,7 +963,7 @@ VP8Decoder::ReturnFrame(const vpx_image_t* img, WebRtc_UWord32 timeStamp)
|
||||
if (img == NULL)
|
||||
{
|
||||
// Decoder OK and NULL image => No show frame
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
|
||||
}
|
||||
|
||||
// Allocate memory for decoded image
|
||||
|
@ -343,7 +343,10 @@ VCMFrameBuffer::RestructureFrameInformation()
|
||||
PrepareForDecode();
|
||||
_frameType = ConvertFrameType(_sessionInfo.FrameType());
|
||||
_completeFrame = _sessionInfo.IsSessionComplete();
|
||||
_missingFrame = _sessionInfo.PreviousFrameLoss();
|
||||
// TODO(holmer): This bit is disabled for now since we can't tell whether
|
||||
// we have had a full frame loss or if we've just lost an FEC/empty packet.
|
||||
// _missingFrame = _sessionInfo.PreviousFrameLoss();
|
||||
_missingFrame = false;
|
||||
}
|
||||
|
||||
WebRtc_Word32
|
||||
|
@ -30,7 +30,8 @@ VCMDecodedFrameCallback::~VCMDecodedFrameCallback()
|
||||
delete &_critSect;
|
||||
}
|
||||
|
||||
void VCMDecodedFrameCallback::SetUserReceiveCallback(VCMReceiveCallback* receiveCallback)
|
||||
void VCMDecodedFrameCallback::SetUserReceiveCallback(
|
||||
VCMReceiveCallback* receiveCallback)
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
_receiveCallback = receiveCallback;
|
||||
@ -38,18 +39,27 @@ void VCMDecodedFrameCallback::SetUserReceiveCallback(VCMReceiveCallback* receive
|
||||
|
||||
WebRtc_Word32 VCMDecodedFrameCallback::Decoded(RawImage& decodedImage)
|
||||
{
|
||||
// TODO(holmer): We should improve this so that we can handle multiple
|
||||
// callbacks from one call to Decode().
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
VCMFrameInformation* frameInfo = static_cast<VCMFrameInformation*>(_timestampMap.Pop(decodedImage._timeStamp));
|
||||
VCMFrameInformation* frameInfo = static_cast<VCMFrameInformation*>(
|
||||
_timestampMap.Pop(decodedImage._timeStamp));
|
||||
if (frameInfo == NULL)
|
||||
{
|
||||
// The map should never be empty or full if this callback is called.
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
WebRtc_Word32 ret = _timing.StopDecodeTimer(decodedImage._timeStamp, frameInfo->decodeStartTimeMs, VCMTickTime::MillisecondTimestamp());
|
||||
_timing.StopDecodeTimer(
|
||||
decodedImage._timeStamp,
|
||||
frameInfo->decodeStartTimeMs,
|
||||
VCMTickTime::MillisecondTimestamp());
|
||||
|
||||
if (_receiveCallback != NULL)
|
||||
{
|
||||
_frame.Swap(decodedImage._buffer, decodedImage._length, decodedImage._size);
|
||||
_frame.Swap(decodedImage._buffer,
|
||||
decodedImage._length,
|
||||
decodedImage._size);
|
||||
_frame.SetWidth(decodedImage._width);
|
||||
_frame.SetHeight(decodedImage._height);
|
||||
_frame.SetTimeStamp(decodedImage._timeStamp);
|
||||
@ -58,18 +68,18 @@ WebRtc_Word32 VCMDecodedFrameCallback::Decoded(RawImage& decodedImage)
|
||||
WebRtc_Word32 callbackReturn = _receiveCallback->FrameToRender(_frame);
|
||||
if (callbackReturn < 0)
|
||||
{
|
||||
return callbackReturn;
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug,
|
||||
webrtc::kTraceVideoCoding,
|
||||
-1,
|
||||
"Render callback returned error: %d", callbackReturn);
|
||||
}
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
WebRtc_Word32
|
||||
VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId)
|
||||
VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame(
|
||||
const WebRtc_UWord64 pictureId)
|
||||
{
|
||||
CriticalSectionScoped cs(_critSect);
|
||||
if (_receiveCallback != NULL)
|
||||
@ -125,7 +135,9 @@ VCMGenericDecoder::~VCMGenericDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
WebRtc_Word32 VCMGenericDecoder::InitDecode(const VideoCodec* settings, WebRtc_Word32 numberOfCores, bool requireKeyFrame)
|
||||
WebRtc_Word32 VCMGenericDecoder::InitDecode(const VideoCodec* settings,
|
||||
WebRtc_Word32 numberOfCores,
|
||||
bool requireKeyFrame)
|
||||
{
|
||||
_requireKeyFrame = requireKeyFrame;
|
||||
_keyFrameDecoded = false;
|
||||
@ -149,9 +161,10 @@ WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame)
|
||||
_frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
|
||||
_callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);
|
||||
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_id),
|
||||
"Decoding timestamp %u",
|
||||
frame.TimeStamp());
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug,
|
||||
webrtc::kTraceVideoCoding,
|
||||
VCMId(_id),
|
||||
"Decoding timestamp %u", frame.TimeStamp());
|
||||
|
||||
_nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength;
|
||||
|
||||
@ -167,6 +180,12 @@ WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame)
|
||||
_callback->Pop(frame.TimeStamp());
|
||||
return ret;
|
||||
}
|
||||
else if (ret == WEBRTC_VIDEO_CODEC_NO_OUTPUT ||
|
||||
ret == WEBRTC_VIDEO_CODEC_REQUEST_SLI)
|
||||
{
|
||||
// No output
|
||||
_callback->Pop(frame.TimeStamp());
|
||||
}
|
||||
// Update the key frame decoded variable so that we know whether or not we've decoded a key frame since reset.
|
||||
_keyFrameDecoded = (frame.FrameType() == kVideoFrameKey || frame.FrameType() == kVideoFrameGolden);
|
||||
return ret;
|
||||
|
@ -199,7 +199,7 @@ VCMTiming::StopDecodeTimer(WebRtc_UWord32 timeStamp,
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_vcmId, _timingId),
|
||||
"Codec timer error: %d", timeDiffMs);
|
||||
return timeDiffMs;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (_master)
|
||||
|
Loading…
x
Reference in New Issue
Block a user