---
 libavutil/hwcontext_qsv.c | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index a2506103a..40837a33d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -583,7 +583,8 @@ static int qsv_map_from(AVHWFramesContext *ctx,
     QSVFramesContext *s = ctx->internal->priv;
     mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3];
     AVHWFramesContext *child_frames_ctx;
-
+    const AVPixFmtDescriptor *desc;
+    uint8_t *child_data;
     AVFrame *dummy;
     int ret = 0;
 
@@ -591,6 +592,40 @@ static int qsv_map_from(AVHWFramesContext *ctx,
         return AVERROR(ENOSYS);
     child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data;
 
+    switch (child_frames_ctx->device_ctx->type) {
+#if CONFIG_VAAPI
+    case AV_HWDEVICE_TYPE_VAAPI:
+        child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId;
+        break;
+#endif
+#if CONFIG_DXVA2
+    case AV_HWDEVICE_TYPE_DXVA2:
+        child_data = surf->Data.MemId;
+        break;
+#endif
+    default:
+        return AVERROR(ENOSYS);
+    }
+
+    if (dst->format == child_frames_ctx->format) {
+        ret = ff_hwframe_map_create(s->child_frames_ref,
+                                    dst, src, NULL, NULL);
+        if (ret < 0)
+            return ret;
+
+        dst->width   = src->width;
+        dst->height  = src->height;
+        dst->data[3] = child_data;
+
+        return 0;
+    }
+
+    desc = av_pix_fmt_desc_get(dst->format);
+    if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
+        // This only supports mapping to software.
+        return AVERROR(ENOSYS);
+    }
+
     dummy = av_frame_alloc();
     if (!dummy)
         return AVERROR(ENOMEM);
@@ -603,7 +638,7 @@ static int qsv_map_from(AVHWFramesContext *ctx,
     dummy->format        = child_frames_ctx->format;
     dummy->width         = src->width;
     dummy->height        = src->height;
-    dummy->data[3]       = surf->Data.MemId;
+    dummy->data[3]       = child_data;
 
     ret = av_hwframe_map(dst, dummy, flags);
 
-- 
2.11.0

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

Reply via email to