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