From: Yukinori Yamazoe <[email protected]>

Signed-off-by: Luca Barbato <[email protected]>
---

Looks fine, last_decode_status is quite long I have a local version using
last_ret instead.

On put_dts failure we should unref the packet.

 libavcodec/qsv.c | 38 ++++++++++++++++++++++----------------
 libavcodec/qsv.h |  2 +-
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 1563031..180302e 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -164,7 +164,8 @@ int ff_qsv_init(AVCodecContext *c, QSVContext *q)
     if (ret < 0)
         return ff_qsv_error(ret);

-    q->nb_surfaces = req.NumFrameSuggested + q->param.AsyncDepth;
+    q->nb_surfaces        = req.NumFrameSuggested + q->param.AsyncDepth;
+    q->last_decode_status = MFX_ERR_MORE_DATA;

     return qsv_surface_alloc(q, &req);
 }
@@ -282,34 +283,39 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,

     ff_packet_list_put(&q->pending, &q->pending_end, avpkt);

-    if (!q->wait) {
-        ff_packet_list_get(&q->pending, &q->pending_end, &pkt);
+    ret = q->last_decode_status;
+    do {
+        if (ret == MFX_ERR_MORE_DATA) {
+            if (q->pending) {
+                ff_packet_list_get(&q->pending, &q->pending_end, &pkt);

-        if ((ret = put_dts(q, pkt.pts, pkt.dts)) < 0)
-            return ret;
+                if ((ret = put_dts(q, pkt.pts, pkt.dts)) < 0)
+                    return ret;

-        q->bs.TimeStamp = pkt.pts;
+                q->bs.TimeStamp = pkt.pts;

-        ret = bitstream_enqueue(&q->bs, pkt.data, pkt.size);
+                ret = bitstream_enqueue(&q->bs, pkt.data, pkt.size);

-        av_packet_unref(&pkt);
+                av_packet_unref(&pkt);

-        if (ret < 0)
-            return ret;
-    }
+                if (ret < 0)
+                    return ret;
+            } else {
+                break;
+            }
+        }

-    ret = MFX_ERR_MORE_SURFACE;
+        if (!(insurf = get_surface(q)))
+            break;

-    while ((insurf = get_surface(q)) && ret == MFX_ERR_MORE_SURFACE) {
         ret = MFXVideoDECODE_DecodeFrameAsync(q->session, &q->bs,
                                               insurf, &outsurf, &sync);
-    }
+    } while (ret == MFX_ERR_MORE_SURFACE || ret == MFX_ERR_MORE_DATA);

-    q->wait = 1;
+    q->last_decode_status = ret;

     switch (ret) {
     case MFX_ERR_MORE_DATA:
-        q->wait = 0;
         ret = 0;
         break;
     case MFX_WRN_VIDEO_PARAM_CHANGED:
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index d558fbb..f1d1b96 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -46,7 +46,7 @@ typedef struct QSVContext {
     int nb_surfaces;
     mfxSyncPoint sync;
     mfxBitstream bs;
-    int wait;
+    int last_decode_status;
     AVPacketList *pending, *pending_end;
 } QSVContext;

--
1.8.3.2

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to