---
 libavcodec/qsv.c      | 17 ++++++++++++++++-
 libavcodec/qsv.h      |  2 ++
 libavcodec/qsv_h264.c | 15 +++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 8dc68ab..2038c44 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -27,6 +27,7 @@
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
 #include "libavutil/log.h"
+#include "libavutil/time.h"
 #include "internal.h"
 #include "avcodec.h"
 #include "qsv.h"
@@ -277,6 +278,7 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
     mfxSyncPoint sync;
     mfxBitstream *bs = &q->bs;
     int size         = avpkt->size;
+    int busymsec     = 0;
     int ret, i;
 
     *got_frame = 0;
@@ -317,7 +319,20 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
         ret = MFXVideoDECODE_DecodeFrameAsync(q->session, bs,
                                               insurf, &outsurf, &sync);
-    } while (ret == MFX_ERR_MORE_SURFACE || ret == MFX_ERR_MORE_DATA);
+
+        if (ret == MFX_WRN_DEVICE_BUSY) {
+            if (busymsec > q->timeout) {
+                av_log(avctx, AV_LOG_WARNING, "Timeout, device is so busy\n");
+                return AVERROR(EIO);
+            } else {
+                av_usleep(1000);
+                busymsec++;
+            }
+        } else {
+            busymsec = 0;
+        }
+    } while (ret == MFX_ERR_MORE_SURFACE || ret == MFX_ERR_MORE_DATA ||
+             ret == MFX_WRN_DEVICE_BUSY);
 
     q->last_ret = ret;
 
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index 6629c5f..9acb7ca 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -34,6 +34,7 @@
 
 #define ASYNC_DEPTH_DEFAULT 4       // internal parallelism
 #define SYNC_TIME_DEFAULT 5 * 1000  // 5s
+#define TIMEOUT_DEFAULT 5 * 1000    // 5s
 
 
 typedef struct QSVContext {
@@ -47,6 +48,7 @@ typedef struct QSVContext {
     mfxSyncPoint sync;
     mfxBitstream bs;
     int last_ret;
+    int timeout;
     AVPacketList *pending, *pending_end;
 } QSVContext;
 
diff --git a/libavcodec/qsv_h264.c b/libavcodec/qsv_h264.c
index 08e0023..70580b9 100644
--- a/libavcodec/qsv_h264.c
+++ b/libavcodec/qsv_h264.c
@@ -121,6 +121,20 @@ static void qsv_dec_flush(AVCodecContext *avctx)
     ff_qsv_flush(&q->qsv);
 }
 
+#define OFFSET(x) offsetof(QSVH264Context, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    { "timeout", "Maximum timeout in milliseconds when the device has been 
busy", OFFSET(qsv.timeout), AV_OPT_TYPE_INT, { .i64 = TIMEOUT_DEFAULT }, 0, 
INT_MAX, VD },
+    { NULL },
+};
+
+static const AVClass class = {
+    .class_name = "h264_qsv",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_h264_qsv_decoder = {
     .name           = "h264_qsv",
     .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 
part 10 (Intel Quick Sync Video acceleration)"),
@@ -132,4 +146,5 @@ AVCodec ff_h264_qsv_decoder = {
     .flush          = qsv_dec_flush,
     .close          = qsv_dec_close,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_PKT_TS,
+    .priv_class     = &class,
 };
-- 
1.8.3.msysgit.0

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

Reply via email to