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:
parent
61b4abf1f8
commit
93d216c23f
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user