Fixed bug in jitter buffer which caused the missingFrames bit to never be set.

Also updated the VP8 wrapper to return fully concealed frames (for rendering).

BUG=
TEST=

Review URL: http://webrtc-codereview.appspot.com/190003

git-svn-id: http://webrtc.googlecode.com/svn/trunk@687 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2011-10-04 06:48:11 +00:00
parent 61b4abf1f8
commit 93d216c23f
3 changed files with 68 additions and 52 deletions

View File

@ -255,6 +255,8 @@ private:
WebRtc_Word32 DecodePartitions(const EncodedImage& input_image,
const RTPFragmentationHeader* fragmentation);
WebRtc_Word32 ReturnFrame(const vpx_image_t* img, WebRtc_UWord32 timeStamp);
RawImage _decodedImage;
DecodedImageCallback* _decodeCompleteCallback;
bool _inited;

View File

@ -822,8 +822,9 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
}
#endif
vpx_dec_iter_t _iter = NULL;
vpx_dec_iter_t iter = NULL;
vpx_image_t* img;
WebRtc_Word32 ret;
// check for missing frames
if (missingFrames)
@ -833,6 +834,11 @@ 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;
}
#ifdef INDEPENDENT_PARTITIONS
@ -892,56 +898,10 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
}
#endif
img = vpx_codec_get_frame(_decoder, &_iter);
if (img == NULL)
{
// Decoder OK and NULL image => No show frame
return WEBRTC_VIDEO_CODEC_OK;
}
// Allocate memory for decoded image
WebRtc_UWord32 requiredSize = (3 * img->h * img->w) >> 1;
if (_decodedImage._buffer != NULL)
{
delete [] _decodedImage._buffer;
_decodedImage._buffer = NULL;
}
if (_decodedImage._buffer == NULL)
{
_decodedImage._size = requiredSize;
_decodedImage._buffer = new WebRtc_UWord8[_decodedImage._size];
if (_decodedImage._buffer == NULL)
{
return WEBRTC_VIDEO_CODEC_MEMORY;
}
}
WebRtc_UWord8* buf;
WebRtc_UWord32 locCnt = 0;
WebRtc_UWord32 plane, y;
for (plane = 0; plane < 3; plane++)
{
buf = img->planes[plane];
WebRtc_UWord32 shiftFactor = plane ? 1 : 0;
for(y = 0; y < img->d_h >> shiftFactor; y++)
{
memcpy(&_decodedImage._buffer[locCnt], buf, img->d_w >> shiftFactor);
locCnt += img->d_w >> shiftFactor;
buf += img->stride[plane];
}
}
// Set image parameters
_decodedImage._height = img->d_h;
_decodedImage._width = img->d_w;
_decodedImage._length = (3 * img->d_h * img->d_w) >> 1;
_decodedImage._timeStamp = inputImage._timeStamp;
_decodeCompleteCallback->Decoded(_decodedImage);
// Remember image format for later
_imageFormat = img->fmt;
img = vpx_codec_get_frame(_decoder, &iter);
ret = ReturnFrame(img, inputImage._timeStamp);
if (ret != 0)
return ret;
// we need to communicate that we should send a RPSI with a specific picture ID
@ -1000,6 +960,58 @@ VP8Decoder::DecodePartitions(const EncodedImage& input_image,
return WEBRTC_VIDEO_CODEC_OK;
}
WebRtc_Word32
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;
}
// Allocate memory for decoded image
WebRtc_UWord32 requiredSize = (3 * img->h * img->w) >> 1;
if (_decodedImage._buffer != NULL)
{
delete [] _decodedImage._buffer;
_decodedImage._buffer = NULL;
}
if (_decodedImage._buffer == NULL)
{
_decodedImage._size = requiredSize;
_decodedImage._buffer = new WebRtc_UWord8[_decodedImage._size];
}
WebRtc_UWord8* buf;
WebRtc_UWord32 locCnt = 0;
WebRtc_UWord32 plane, y;
for (plane = 0; plane < 3; plane++)
{
buf = img->planes[plane];
WebRtc_UWord32 shiftFactor = plane ? 1 : 0;
for(y = 0; y < img->d_h >> shiftFactor; y++)
{
memcpy(&_decodedImage._buffer[locCnt], buf, img->d_w >> shiftFactor);
locCnt += img->d_w >> shiftFactor;
buf += img->stride[plane];
}
}
// Set image parameters
_decodedImage._height = img->d_h;
_decodedImage._width = img->d_w;
_decodedImage._length = (3 * img->d_h * img->d_w) >> 1;
_decodedImage._timeStamp = timeStamp;
WebRtc_Word32 ret = _decodeCompleteCallback->Decoded(_decodedImage);
if (ret != 0)
return ret;
// Remember image format for later
_imageFormat = img->fmt;
return WEBRTC_VIDEO_CODEC_OK;
}
WebRtc_Word32
VP8Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
{

View File

@ -1115,7 +1115,6 @@ VCMJitterBuffer::GetFrameForDecoding()
_waitingForCompletion.latestPacketTime =
oldestFrame->LatestPacketTimeMs();
_waitingForCompletion.timestamp = oldestFrame->TimeStamp();
oldestFrame->SetState(kStateDecoding);
}
_frameBuffersTSOrder.Erase(oldestFrameListItem);
oldestFrameListItem = NULL;
@ -1123,7 +1122,10 @@ VCMJitterBuffer::GetFrameForDecoding()
CleanUpOldFrames();
CleanUpSizeZeroFrames();
// Look for previous frame loss
VerifyAndSetPreviousFrameLost(*oldestFrame);
// Set as decoding. Propagates the missingFrame bit.
oldestFrame->SetState(kStateDecoding);
// Store current seqnum & time
_lastDecodedSeqNum = oldestFrame->GetHighSeqNum();