Relanding 4597 - Don't force key frame when decoding with errors.

Makes sure that incomplete key frame or delta frames will be released from the JB when decoding with errors.
The decoder in turn will trigger a PLI until a complete key frame is received in order to start a session.

TBR=stefan@webrtc.org

BUG=

Review URL: https://webrtc-codereview.appspot.com/2097004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4607 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org
2013-08-23 21:54:50 +00:00
parent 442709ea96
commit b2c28c3699
11 changed files with 123 additions and 83 deletions

View File

@ -597,8 +597,7 @@ VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder(
}
if (ptr_decoder->InitDecode(decoder_item->settings.get(),
decoder_item->number_of_cores,
decoder_item->require_key_frame) < 0) {
decoder_item->number_of_cores) < 0) {
ReleaseDecoder(ptr_decoder);
return NULL;
}

View File

@ -133,9 +133,7 @@ _frameInfos(),
_nextFrameInfoIdx(0),
_decoder(decoder),
_codecType(kVideoCodecUnknown),
_isExternal(isExternal),
_requireKeyFrame(false),
_keyFrameDecoded(false)
_isExternal(isExternal)
{
}
@ -144,11 +142,8 @@ VCMGenericDecoder::~VCMGenericDecoder()
}
int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
int32_t numberOfCores,
bool requireKeyFrame)
int32_t numberOfCores)
{
_requireKeyFrame = requireKeyFrame;
_keyFrameDecoded = false;
_codecType = settings->codecType;
return _decoder.InitDecode(settings, numberOfCores);
@ -157,15 +152,6 @@ int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame,
int64_t nowMs)
{
if (_requireKeyFrame &&
!_keyFrameDecoded &&
frame.FrameType() != kVideoFrameKey &&
frame.FrameType() != kVideoFrameGolden)
{
// Require key frame is enabled, meaning that one key frame must be decoded
// before we can decode delta frames.
return VCM_CODEC_ERROR;
}
_frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs;
_frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
_callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);
@ -194,22 +180,17 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame,
// 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 = (_keyFrameDecoded ||
frame.FrameType() == kVideoFrameKey);
return ret;
}
int32_t
VCMGenericDecoder::Release()
{
_keyFrameDecoded = false;
return _decoder.Release();
}
int32_t VCMGenericDecoder::Reset()
{
_keyFrameDecoded = false;
return _decoder.Reset();
}

View File

@ -70,8 +70,7 @@ public:
* Initialize the decoder with the information from the VideoCodec
*/
int32_t InitDecode(const VideoCodec* settings,
int32_t numberOfCores,
bool requireKeyFrame);
int32_t numberOfCores);
/**
* Decode to a raw I420 frame,
@ -115,7 +114,6 @@ protected:
VideoDecoder& _decoder;
VideoCodecType _codecType;
bool _isExternal;
bool _requireKeyFrame;
bool _keyFrameDecoded;
};

View File

@ -508,19 +508,13 @@ bool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) {
return false;
}
VCMFrameBuffer* oldest_frame = decodable_frames_.Front();
// If we have exactly one frame in the buffer, release it only if it is
// complete. We know decodable_frames_ is not empty due to the prevoius
// complete. We know decodable_frames_ is not empty due to the previous
// check.
if (decodable_frames_.size() == 1 && incomplete_frames_.empty()
&& oldest_frame->GetState() != kStateComplete) {
return false;
}
// Always start with a complete key frame.
if (last_decoded_state_.in_initial_state() &&
oldest_frame->FrameType() != kVideoFrameKey) {
return false;
}
*timestamp = oldest_frame->TimeStamp();
return true;