From 9bf9c314a093db16a009829bfe874bf03ffaecc9 Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Sun, 22 Jan 2012 13:47:00 -0800 Subject: CrystalHD: Back up extradata to allow decoder reinit to work. This was a regression that came in when I switched to using the h.264 annex b filter all the time. As the filter modifies extradata, its use violates the statelessness assumption that exists in the 'ffmpeg' command line tool, and maybe elsewhere. It assumes that a docoder can be reinitalised and pointed to an existing stream and get the same results. For now, the only way to meet this requirement is to backup the extradata. Signed-off-by: Michael Niedermayer --- libavcodec/crystalhd.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'libavcodec') diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c index f184c06d9e..2d10aa9ee7 100644 --- a/libavcodec/crystalhd.c +++ b/libavcodec/crystalhd.c @@ -124,6 +124,9 @@ typedef struct { AVFrame pic; HANDLE dev; + uint8_t *orig_extradata; + uint32_t orig_extradata_size; + AVBitStreamFilterContext *bsfc; AVCodecParserContext *parser; @@ -338,6 +341,19 @@ static av_cold int uninit(AVCodecContext *avctx) DtsCloseDecoder(device); DtsDeviceClose(device); + /* + * Restore original extradata, so that if the decoder is + * reinitialised, the bitstream detection and filtering + * will work as expected. + */ + if (priv->orig_extradata) { + av_free(avctx->extradata); + avctx->extradata = priv->orig_extradata; + avctx->extradata_size = priv->orig_extradata_size; + priv->orig_extradata = NULL; + priv->orig_extradata_size = 0; + } + av_parser_close(priv->parser); if (priv->bsfc) { av_bitstream_filter_close(priv->bsfc); @@ -402,6 +418,16 @@ static av_cold int init(AVCodecContext *avctx) uint8_t *dummy_p; int dummy_int; + /* Back up the extradata so it can be restored at close time. */ + priv->orig_extradata = av_malloc(avctx->extradata_size); + if (!priv->orig_extradata) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate copy of extradata\n"); + return AVERROR(ENOMEM); + } + priv->orig_extradata_size = avctx->extradata_size; + memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size); + priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb"); if (!priv->bsfc) { av_log(avctx, AV_LOG_ERROR, -- cgit v1.2.3