From 107eeefd5df46621baa93d0ddc05477acfcb987c Mon Sep 17 00:00:00 2001
From: Ivan Uskov <ivan.uskov@nablet.com>
Date: Wed, 22 Jul 2015 14:45:56 -0400
Subject: [PATCH] libavcodec/qsvdec_h264.c bug fixed: decoder fails after
 restart on non-annex-b content.

---
 libavcodec/qsvdec_h264.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/libavcodec/qsvdec_h264.c b/libavcodec/qsvdec_h264.c
index 78356e3..3d6b3eb 100644
--- a/libavcodec/qsvdec_h264.c
+++ b/libavcodec/qsvdec_h264.c
@@ -42,6 +42,8 @@ typedef struct QSVH264Context {
     // the filter for converting to Annex B
     AVBitStreamFilterContext *bsf;
 
+    uint8_t *orig_extradata;
+    uint32_t orig_extradata_size;
 } QSVH264Context;
 
 static av_cold int qsv_decode_close(AVCodecContext *avctx)
@@ -52,6 +54,19 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx)
 
     av_bitstream_filter_close(s->bsf);
 
+    /*
+     * Restore original extradata, so that if the decoder is
+     * reinitialised, the filtering  will work as expected.
+     */
+
+    if (s->orig_extradata) {
+        av_free(avctx->extradata);
+        avctx->extradata      = s->orig_extradata;
+        avctx->extradata_size = s->orig_extradata_size;
+        s->orig_extradata     = NULL;
+        s->orig_extradata_size= 0;
+    }
+
     return 0;
 }
 
@@ -60,6 +75,15 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
     QSVH264Context *s = avctx->priv_data;
     int ret;
 
+    /* Back up the extradata so it can be restored at close time. */
+    s->orig_extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!s->orig_extradata) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to allocate copy of extradata\n");
+        return AVERROR(ENOMEM);
+    }
+    s->orig_extradata_size = avctx->extradata_size;
+    memcpy(s->orig_extradata, avctx->extradata, avctx->extradata_size);
+
     s->bsf = av_bitstream_filter_init("h264_mp4toannexb");
     if (!s->bsf) {
         ret = AVERROR(ENOMEM);
-- 
1.8.3.1

