---
 libavutil/hwcontext_qsv.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 4e393e630..9fcf8fab7 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -723,6 +723,104 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
     return 0;
 }
 
+static void qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf)
+{
+    surf->Info.BitDepthLuma   = 8;
+    surf->Info.BitDepthChroma = 8;
+    surf->Info.Shift          = 0;
+    surf->Info.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+    surf->Info.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+    surf->Info.FourCC         = MFX_FOURCC_NV12;
+    surf->Info.Width          = ctx->width;
+    surf->Info.CropW          = ctx->width;
+    surf->Info.Height         = ctx->height;
+    surf->Info.CropH          = ctx->height;
+    surf->Info.FrameRateExtN  = 25;
+    surf->Info.FrameRateExtD  = 1;
+}
+
+static int qsv_map_frames_to(AVHWFramesContext *dst_ctx,
+                             AVHWFramesContext *src_ctx, int flags)
+{
+    QSVFramesContext *s = dst_ctx->internal->priv;
+    AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx;
+    int i;
+
+    switch (src_ctx->device_ctx->type) {
+#if CONFIG_VAAPI
+    case AV_HWDEVICE_TYPE_VAAPI:
+        {
+            AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx;
+            s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces,
+                                                    
sizeof(*s->surfaces_internal));
+            if (!s->surfaces_internal)
+                return AVERROR(ENOMEM);
+            for (i = 0; i < src_hwctx->nb_surfaces; i++) {
+                qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
+                s->surfaces_internal[i].Data.MemId = src_hwctx->surface_ids + 
i;
+            }
+            dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
+            dst_hwctx->frame_type  = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+        }
+        break;
+#endif
+#if CONFIG_DXVA2
+        {
+            AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx;
+            s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces,
+                                                    
sizeof(*s->surfaces_internal));
+            if (!s->surfaces_internal)
+                return AVERROR(ENOMEM);
+            for (i = 0; i < src_hwctx->nb_surfaces; i++) {
+                qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
+                s->surfaces_internal[i].Data.MemId = 
(mfxMemId)src_hwctx->surfaces[i];
+            }
+            dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
+            if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget)
+                dst_hwctx->frame_type = 
MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
+            else
+                dst_hwctx->frame_type = 
MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+        }
+        break;
+#endif
+    default:
+        return AVERROR(ENOSYS);
+    }
+
+    dst_hwctx->surfaces = s->surfaces_internal;
+
+    return 0;
+}
+
+static int qsv_map_to(AVHWFramesContext *dst_ctx,
+                      AVFrame *dst, const AVFrame *src, int flags)
+{
+    AVQSVFramesContext *hwctx = dst_ctx->hwctx;
+    int i, err;
+
+    for (i = 0; i < hwctx->nb_surfaces; i++) {
+        if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId ==
+            (VASurfaceID)(uintptr_t)src->data[3])
+            break;
+    }
+    if (i >= hwctx->nb_surfaces) {
+        av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which "
+               "is not in the mapped frames context.\n");
+        return AVERROR(EINVAL);
+    }
+
+    err = ff_hwframe_map_create(dst->hw_frames_ctx,
+                                dst, src, NULL, NULL);
+    if (err)
+        return err;
+
+    dst->width   = src->width;
+    dst->height  = src->height;
+    dst->data[3] = (uint8_t*)&hwctx->surfaces[i];
+
+    return 0;
+}
+
 static int qsv_frames_get_constraints(AVHWDeviceContext *ctx,
                                       const void *hwconfig,
                                       AVHWFramesConstraints *constraints)
@@ -937,7 +1035,9 @@ const HWContextType ff_hwcontext_type_qsv = {
     .transfer_get_formats   = qsv_transfer_get_formats,
     .transfer_data_to       = qsv_transfer_data_to,
     .transfer_data_from     = qsv_transfer_data_from,
+    .map_to                 = qsv_map_to,
     .map_from               = qsv_map_from,
+    .map_frames_to          = qsv_map_frames_to,
 
     .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE 
},
 };
-- 
2.11.0

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

Reply via email to