aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@cloudera.com>2012-01-22 13:47:00 -0800
committerMichael Niedermayer <michaelni@gmx.at>2012-01-22 23:40:24 +0100
commit9bf9c314a093db16a009829bfe874bf03ffaecc9 (patch)
tree9460aeb9e1a0ce5eb1c1aaf5010ddef20fc7e73f
parenteaf4bf6df2cf26c31bf7f787edd69812a681ab2e (diff)
downloadffmpeg-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.c26
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,