Merge commit '76167140a91c081a0cf9d0abcaa4da18d1bacadb'
[ffmpeg.git] / libavcodec / qsvdec.c
index 7d496d9..60a53f6 100644 (file)
@@ -90,7 +90,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
     const AVPixFmtDescriptor *desc;
     mfxSession session = NULL;
     int iopattern = 0;
-    mfxVideoParam param = { { 0 } };
+    mfxVideoParam param = { 0 };
     int frame_width  = avctx->coded_width;
     int frame_height = avctx->coded_height;
     int ret;
@@ -194,17 +194,25 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
         return ret;
 
     if (frame->frame->format == AV_PIX_FMT_QSV) {
-        frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
+        frame->surface = *(mfxFrameSurface1*)frame->frame->data[3];
     } else {
-        frame->surface_internal.Info = q->frame_info;
+        frame->surface.Info = q->frame_info;
 
-        frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
-        frame->surface_internal.Data.Y        = frame->frame->data[0];
-        frame->surface_internal.Data.UV       = frame->frame->data[1];
+        frame->surface.Data.PitchLow = frame->frame->linesize[0];
+        frame->surface.Data.Y        = frame->frame->data[0];
+        frame->surface.Data.UV       = frame->frame->data[1];
+    }
+
+    if (q->frames_ctx.mids) {
+        ret = ff_qsv_find_surface_idx(&q->frames_ctx, frame);
+        if (ret < 0)
+            return ret;
 
-        frame->surface = &frame->surface_internal;
+        frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
     }
 
+    frame->used = 1;
+
     return 0;
 }
 
@@ -212,8 +220,8 @@ static void qsv_clear_unused_frames(QSVContext *q)
 {
     QSVFrame *cur = q->work_frames;
     while (cur) {
-        if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
-            cur->surface = NULL;
+        if (cur->used && !cur->surface.Data.Locked && !cur->queued) {
+            cur->used = 0;
             av_frame_unref(cur->frame);
         }
         cur = cur->next;
@@ -230,11 +238,11 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **
     frame = q->work_frames;
     last  = &q->work_frames;
     while (frame) {
-        if (!frame->surface) {
+        if (!frame->used) {
             ret = alloc_frame(avctx, q, frame);
             if (ret < 0)
                 return ret;
-            *surf = frame->surface;
+            *surf = &frame->surface;
             return 0;
         }
 
@@ -256,7 +264,7 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **
     if (ret < 0)
         return ret;
 
-    *surf = frame->surface;
+    *surf = &frame->surface;
 
     return 0;
 }
@@ -265,7 +273,7 @@ static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
 {
     QSVFrame *cur = q->work_frames;
     while (cur) {
-        if (surf == cur->surface)
+        if (surf == &cur->surface)
             return cur;
         cur = cur->next;
     }
@@ -322,8 +330,12 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
     /* make sure we do not enter an infinite loop if the SDK
      * did not consume any data and did not return anything */
     if (!*sync && !bs.DataOffset) {
-        ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
         bs.DataOffset = avpkt->size;
+        ++q->zero_consume_run;
+        if (q->zero_consume_run > 1)
+            ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
+    } else {
+        q->zero_consume_run = 0;
     }
 
     if (*sync) {
@@ -363,7 +375,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
         if (ret < 0)
             return ret;
 
-        outsurf = out_frame->surface;
+        outsurf = &out_frame->surface;
 
 #if FF_API_PKT_PTS
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -381,6 +393,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
         frame->interlaced_frame =
             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
 
+        /* update the surface properties */
+        if (avctx->pix_fmt == AV_PIX_FMT_QSV)
+            ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info;
+
         *got_frame = 1;
     }
 
@@ -421,8 +437,7 @@ int ff_qsv_decode_close(QSVContext *q)
         MFXClose(q->internal_session);
 
     av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
-    av_freep(&q->frames_ctx.mids);
-    q->frames_ctx.nb_mids = 0;
+    av_buffer_unref(&q->frames_ctx.mids_buf);
 
     return 0;
 }