diff options
author | Philip Langdale <philipl@cloudera.com> | 2012-01-22 13:47:00 -0800 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-22 23:40:24 +0100 |
commit | 9bf9c314a093db16a009829bfe874bf03ffaecc9 (patch) | |
tree | 9460aeb9e1a0ce5eb1c1aaf5010ddef20fc7e73f | |
parent | eaf4bf6df2cf26c31bf7f787edd69812a681ab2e (diff) | |
download | ffmpeg-9bf9c314a093db16a009829bfe874bf03ffaecc9.tar.gz |
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 <michaelni@gmx.at>
-rw-r--r-- | libavcodec/crystalhd.c | 26 |
1 files changed, 26 insertions, 0 deletions
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, |