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,
|
WebRtc_Word32 DecodePartitions(const EncodedImage& input_image,
|
||||||
const RTPFragmentationHeader* fragmentation);
|
const RTPFragmentationHeader* fragmentation);
|
||||||
|
|
||||||
|
WebRtc_Word32 ReturnFrame(const vpx_image_t* img, WebRtc_UWord32 timeStamp);
|
||||||
|
|
||||||
RawImage _decodedImage;
|
RawImage _decodedImage;
|
||||||
DecodedImageCallback* _decodeCompleteCallback;
|
DecodedImageCallback* _decodeCompleteCallback;
|
||||||
bool _inited;
|
bool _inited;
|
||||||
|
@ -822,8 +822,9 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vpx_dec_iter_t _iter = NULL;
|
vpx_dec_iter_t iter = NULL;
|
||||||
vpx_image_t* img;
|
vpx_image_t* img;
|
||||||
|
WebRtc_Word32 ret;
|
||||||
|
|
||||||
// check for missing frames
|
// check for missing frames
|
||||||
if (missingFrames)
|
if (missingFrames)
|
||||||
@ -833,6 +834,11 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
|
|||||||
{
|
{
|
||||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
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
|
#ifdef INDEPENDENT_PARTITIONS
|
||||||
@ -892,56 +898,10 @@ VP8Decoder::Decode(const EncodedImage& inputImage,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
img = vpx_codec_get_frame(_decoder, &_iter);
|
img = vpx_codec_get_frame(_decoder, &iter);
|
||||||
|
ret = ReturnFrame(img, inputImage._timeStamp);
|
||||||
if (img == NULL)
|
if (ret != 0)
|
||||||
{
|
return ret;
|
||||||
// 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;
|
|
||||||
|
|
||||||
// we need to communicate that we should send a RPSI with a specific picture ID
|
// 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;
|
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
|
WebRtc_Word32
|
||||||
VP8Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
|
VP8Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
|
||||||
{
|
{
|
||||||
|
@ -1115,7 +1115,6 @@ VCMJitterBuffer::GetFrameForDecoding()
|
|||||||
_waitingForCompletion.latestPacketTime =
|
_waitingForCompletion.latestPacketTime =
|
||||||
oldestFrame->LatestPacketTimeMs();
|
oldestFrame->LatestPacketTimeMs();
|
||||||
_waitingForCompletion.timestamp = oldestFrame->TimeStamp();
|
_waitingForCompletion.timestamp = oldestFrame->TimeStamp();
|
||||||
oldestFrame->SetState(kStateDecoding);
|
|
||||||
}
|
}
|
||||||
_frameBuffersTSOrder.Erase(oldestFrameListItem);
|
_frameBuffersTSOrder.Erase(oldestFrameListItem);
|
||||||
oldestFrameListItem = NULL;
|
oldestFrameListItem = NULL;
|
||||||
@ -1123,7 +1122,10 @@ VCMJitterBuffer::GetFrameForDecoding()
|
|||||||
CleanUpOldFrames();
|
CleanUpOldFrames();
|
||||||
CleanUpSizeZeroFrames();
|
CleanUpSizeZeroFrames();
|
||||||
|
|
||||||
|
// Look for previous frame loss
|
||||||
VerifyAndSetPreviousFrameLost(*oldestFrame);
|
VerifyAndSetPreviousFrameLost(*oldestFrame);
|
||||||
|
// Set as decoding. Propagates the missingFrame bit.
|
||||||
|
oldestFrame->SetState(kStateDecoding);
|
||||||
|
|
||||||
// Store current seqnum & time
|
// Store current seqnum & time
|
||||||
_lastDecodedSeqNum = oldestFrame->GetHighSeqNum();
|
_lastDecodedSeqNum = oldestFrame->GetHighSeqNum();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user