On Sun, 19 Feb 2017 18:46:36 +0000
Mark Thompson <[email protected]> wrote:

> ---
>  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;

Is that line repeated?

> +    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;

Why does it deal with VASurfaceIDs, which don't exist on Windows/DXVA?

> +    }
> +    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 },
>  };

Can't quite wrap my head around why both map_to and map_frames_to
exist, why they can't share code, and why map_from exists, but I guess
it all has its reasons.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to