On 20/02/17 06:27, wm4 wrote:
> 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?

Yeah, oops.  (This has a bit of hard-coding for specific cases.  I'm going to 
clean it up when I make the DXVA2 work.  P010 should be here too, for example.)

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

Probably because I still haven't tested on Windows.  I want to add a cleaner 
way to deal with the Data.MemId things when doing that, but I'm not yet sure 
exactly what it looks like (the different indirection levels are a pain).

>> +    }
>> +    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.

map_frames_to:  Map a the platform frames context to a QSV frames context; 
really this is just filling the hwctx member so that the context is usable.

map_to: Map a single platform frame to QSV, inside a context-pair which was 
previous mapped with map_frames_to.

map_from:  Map a QSV frame either directly to a platform frame (which can be 
used without any specific frames context data for VAAPI at least, hence no 
map_frames_from), or to normal memory via the platform frame.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to