Message ID | 20180311224156.23986-2-sw@jkqxz.net |
---|---|
State | Superseded |
Headers | show |
On 11 March 2018 at 22:41, Mark Thompson <sw@jkqxz.net> wrote: > The old vaAcquireBufferHandle() API works in fewer cases and provides > less information than the current vaExportSurfaceHandle(), but it exists > on older versions and is already used by the OpenCL code. This probably > doesn't have much use directly, but it will be used to replace the ad-hoc > OpenCL code in a following patch. > --- > libavutil/hwcontext_vaapi.c | 191 ++++++++++++++++++++++++++++++ > +++++++++++--- > 1 file changed, 179 insertions(+), 12 deletions(-) > > diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c > index 99f76b9169..15f1c4d1c0 100644 > --- a/libavutil/hwcontext_vaapi.c > +++ b/libavutil/hwcontext_vaapi.c > @@ -1073,8 +1073,9 @@ static int vaapi_map_from_drm(AVHWFramesContext > *src_fc, AVFrame *dst, > return 0; > } > > -static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, > - HWMapDescriptor *hwmap) > +#if VA_CHECK_VERSION(1, 1, 0) > +static void vaapi_unmap_to_drm_esh(AVHWFramesContext *hwfc, > + HWMapDescriptor *hwmap) > { > AVDRMFrameDescriptor *drm_desc = hwmap->priv; > int i; > @@ -1085,10 +1086,9 @@ static void vaapi_unmap_to_drm(AVHWFramesContext > *dst_fc, > av_freep(&drm_desc); > } > > -static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, > - const AVFrame *src, int flags) > +static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst, > + const AVFrame *src, int flags) > { > -#if VA_CHECK_VERSION(1, 1, 0) > AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; > VASurfaceID surface_id; > VAStatus vas; > @@ -1140,7 +1140,7 @@ static int vaapi_map_to_drm(AVHWFramesContext > *hwfc, AVFrame *dst, > } > > err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, > - &vaapi_unmap_to_drm, drm_desc); > + &vaapi_unmap_to_drm_esh, drm_desc); > if (err < 0) > goto fail; > > @@ -1155,15 +1155,182 @@ fail: > close(va_desc.objects[i].fd); > av_freep(&drm_desc); > return err; > -#else > - // Older versions without vaExportSurfaceHandle() are not supported - > - // in theory this is possible with a combination of vaDeriveImage() > - // and vaAcquireBufferHandle(), but it doesn't carry enough metadata > - // to actually use the result in a generic way. > - return AVERROR(ENOSYS); > +} > #endif > + > +typedef struct VAAPIDRMImageBufferMapping { > + VAImage image; > + VABufferInfo buffer_info; > + > + AVDRMFrameDescriptor drm_desc; > +} VAAPIDRMImageBufferMapping; > + > +static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc, > + HWMapDescriptor *hwmap) > +{ > + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; > + VAAPIDRMImageBufferMapping *mapping = hwmap->priv; > + VASurfaceID surface_id; > + VAStatus vas; > + > + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; > + av_log(hwfc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from DRM.\n", > + surface_id); > + > + // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(), > + // so we shouldn't close them separately. > + > + vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer " > + "handle of image %#x (derived from surface %#x): " > + "%d (%s).\n", mapping->image.buf, surface_id, > + vas, vaErrorStr(vas)); > + } > + > + vas = vaDestroyImage(hwctx->display, mapping->image.image_id); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image " > + "derived from surface %#x: %d (%s).\n", > + surface_id, vas, vaErrorStr(vas)); > + } > + > + av_free(mapping); > } > + > +static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst, > + const AVFrame *src, int flags) > +{ > + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; > + VAAPIDRMImageBufferMapping *mapping = NULL; > + VASurfaceID surface_id; > + VAStatus vas; > + int err, i, p; > + > + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; > + av_log(hwfc, AV_LOG_DEBUG, "Map VAAPI surface %#x to DRM.\n", > + surface_id); > + > + mapping = av_mallocz(sizeof(*mapping)); > + if (!mapping) > + return AVERROR(ENOMEM); > + > + vas = vaDeriveImage(hwctx->display, surface_id, > + &mapping->image); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " > + "surface %#x: %d (%s).\n", > + surface_id, vas, vaErrorStr(vas)); > + err = AVERROR(EIO); > + goto fail; > + } > + > + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { > + if (vaapi_drm_format_map[i].va_fourcc == > + mapping->image.format.fourcc) > + break; > + } > + if (i >= FF_ARRAY_ELEMS(vaapi_drm_format_map)) { > + av_log(hwfc, AV_LOG_ERROR, "No matching DRM format for " > + "VAAPI format %#x.\n", mapping->image.format.fourcc); > + err = AVERROR(EINVAL); > + goto fail_derived; > + } > + > + mapping->buffer_info.mem_type = > + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; > + > + mapping->drm_desc.nb_layers = > + vaapi_drm_format_map[i].nb_layer_formats; > + if (mapping->drm_desc.nb_layers > 1) { > + if (mapping->drm_desc.nb_layers != mapping->image.num_planes) { > + av_log(hwfc, AV_LOG_ERROR, "Image properties do not match " > + "expected format: got %d planes, but expected %d.\n", > + mapping->image.num_planes, > mapping->drm_desc.nb_layers); > + err = AVERROR(EINVAL); > + goto fail_derived; > + } > + > + for(p = 0; p < mapping->drm_desc.nb_layers; p++) { > + mapping->drm_desc.layers[p] = (AVDRMLayerDescriptor) { > + .format = vaapi_drm_format_map[i].layer_formats[p], > + .nb_planes = 1, > + .planes[0] = { > + .object_index = 0, > + .offset = mapping->image.offsets[p], > + .pitch = mapping->image.pitches[p], > + }, > + }; > + } > + } else { > + mapping->drm_desc.layers[0].format = > + vaapi_drm_format_map[i].layer_formats[0]; > + mapping->drm_desc.layers[0].nb_planes = > mapping->image.num_planes; > + for (p = 0; p < mapping->image.num_planes; p++) { > + mapping->drm_desc.layers[0].planes[p] = > (AVDRMPlaneDescriptor) { > + .object_index = 0, > + .offset = mapping->image.offsets[p], > + .pitch = mapping->image.pitches[p], > + }; > + } > + } > + > + vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf, > + &mapping->buffer_info); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer " > + "handle from image %#x (derived from surface %#x): " > + "%d (%s).\n", mapping->image.buf, surface_id, > + vas, vaErrorStr(vas)); > + err = AVERROR(EIO); > + goto fail_derived; > + } > + > + av_log(hwfc, AV_LOG_DEBUG, "DRM PRIME fd is %ld.\n", > + mapping->buffer_info.handle); > + > + mapping->drm_desc.nb_objects = 1; > + mapping->drm_desc.objects[0] = (AVDRMObjectDescriptor) { > + .fd = mapping->buffer_info.handle, > + .size = mapping->image.data_size, > + // There is no way to get the format modifier with this API. > + .format_modifier = DRM_FORMAT_MOD_NONE, > + }; > + > + err = ff_hwframe_map_create(src->hw_frames_ctx, > + dst, src, &vaapi_unmap_to_drm_abh, > + mapping); > + if (err < 0) > + goto fail_mapped; > + > + dst->data[0] = (uint8_t*)&mapping->drm_desc; > + dst->width = src->width; > + dst->height = src->height; > + > + return 0; > + > +fail_mapped: > + vaReleaseBufferHandle(hwctx->display, mapping->image.buf); > +fail_derived: > + vaDestroyImage(hwctx->display, mapping->image.image_id); > +fail: > + av_freep(&mapping); > + return err; > +} > + > +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, > + const AVFrame *src, int flags) > +{ > +#if VA_CHECK_VERSION(1, 1, 0) > + int err; > + err = vaapi_map_to_drm_esh(hwfc, dst, src, flags); > + if (err != AVERROR(ENOSYS)) > + return err; > #endif > + return vaapi_map_to_drm_abh(hwfc, dst, src, flags); > +} > + > +#endif /* CONFIG_LIBDRM */ > > static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, > const AVFrame *src, int flags) > -- > 2.16.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > Why? libva 1.1.0 is 6 years old now. It doesn't make sense to have 2 pieces of code to do the same thing.
On 12/03/18 00:01, Rostislav Pehlivanov wrote: > On 11 March 2018 at 22:41, Mark Thompson <sw@jkqxz.net> wrote: > >> The old vaAcquireBufferHandle() API works in fewer cases and provides >> less information than the current vaExportSurfaceHandle(), but it exists >> on older versions and is already used by the OpenCL code. This probably >> doesn't have much use directly, but it will be used to replace the ad-hoc >> OpenCL code in a following patch. >> --- >> libavutil/hwcontext_vaapi.c | 191 ++++++++++++++++++++++++++++++ >> +++++++++++--- >> 1 file changed, 179 insertions(+), 12 deletions(-) >> >> ... > > Why? libva 1.1.0 is 6 years old now. It doesn't make sense to have 2 pieces > of code to do the same thing. VAAPI 1.1.0 != libva 1.1.0. VAAPI 1.1.0 is in libva 2.1.0, released last month. (This is not confusing at all.) - Mark
On 12 March 2018 at 00:23, Mark Thompson <sw@jkqxz.net> wrote: > On 12/03/18 00:01, Rostislav Pehlivanov wrote: > > On 11 March 2018 at 22:41, Mark Thompson <sw@jkqxz.net> wrote: > > > >> The old vaAcquireBufferHandle() API works in fewer cases and provides > >> less information than the current vaExportSurfaceHandle(), but it exists > >> on older versions and is already used by the OpenCL code. This probably > >> doesn't have much use directly, but it will be used to replace the > ad-hoc > >> OpenCL code in a following patch. > >> --- > >> libavutil/hwcontext_vaapi.c | 191 ++++++++++++++++++++++++++++++ > >> +++++++++++--- > >> 1 file changed, 179 insertions(+), 12 deletions(-) > >> > >> ... > > > > Why? libva 1.1.0 is 6 years old now. It doesn't make sense to have 2 > pieces > > of code to do the same thing. > > VAAPI 1.1.0 != libva 1.1.0. VAAPI 1.1.0 is in libva 2.1.0, released last > month. > > (This is not confusing at all.) > > - Mark > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ABH seems pretty much worse than ESH, and considering you can't get the format modifiers makes it useless for Vulkan. I don't see why we need to support it in addition to ESH.
On 12/03/18 17:40, Rostislav Pehlivanov wrote: > On 12 March 2018 at 00:23, Mark Thompson <sw@jkqxz.net> wrote: > >> On 12/03/18 00:01, Rostislav Pehlivanov wrote: >>> On 11 March 2018 at 22:41, Mark Thompson <sw@jkqxz.net> wrote: >>> >>>> The old vaAcquireBufferHandle() API works in fewer cases and provides >>>> less information than the current vaExportSurfaceHandle(), but it exists >>>> on older versions and is already used by the OpenCL code. This probably >>>> doesn't have much use directly, but it will be used to replace the >> ad-hoc >>>> OpenCL code in a following patch. >>>> --- >>>> libavutil/hwcontext_vaapi.c | 191 ++++++++++++++++++++++++++++++ >>>> +++++++++++--- >>>> 1 file changed, 179 insertions(+), 12 deletions(-) >>>> >>>> ... >>> >>> Why? libva 1.1.0 is 6 years old now. It doesn't make sense to have 2 >> pieces >>> of code to do the same thing. >> >> VAAPI 1.1.0 != libva 1.1.0. VAAPI 1.1.0 is in libva 2.1.0, released last >> month. >> >> (This is not confusing at all.) >> > > ABH seems pretty much worse than ESH, and considering you can't get the > format modifiers makes it useless for Vulkan. I don't see why we need to > support it in addition to ESH. It's what it currently used by the Beignet/OpenCL interop (since it was the only thing which existed when that was written, and the format modifier isn't needed), and I don't want to break that. Since it was only released a few weeks ago it will probably be a while before it lands in all distributions, and it isn't implemented at all by the Intel ex-blob driver yet. - Mark
On 12 March 2018 at 22:46, Mark Thompson <sw@jkqxz.net> wrote: > On 12/03/18 17:40, Rostislav Pehlivanov wrote: > > On 12 March 2018 at 00:23, Mark Thompson <sw@jkqxz.net> wrote: > > > >> On 12/03/18 00:01, Rostislav Pehlivanov wrote: > >>> On 11 March 2018 at 22:41, Mark Thompson <sw@jkqxz.net> wrote: > >>> > >>>> The old vaAcquireBufferHandle() API works in fewer cases and provides > >>>> less information than the current vaExportSurfaceHandle(), but it > exists > >>>> on older versions and is already used by the OpenCL code. This > probably > >>>> doesn't have much use directly, but it will be used to replace the > >> ad-hoc > >>>> OpenCL code in a following patch. > >>>> --- > >>>> libavutil/hwcontext_vaapi.c | 191 ++++++++++++++++++++++++++++++ > >>>> +++++++++++--- > >>>> 1 file changed, 179 insertions(+), 12 deletions(-) > >>>> > >>>> ... > >>> > >>> Why? libva 1.1.0 is 6 years old now. It doesn't make sense to have 2 > >> pieces > >>> of code to do the same thing. > >> > >> VAAPI 1.1.0 != libva 1.1.0. VAAPI 1.1.0 is in libva 2.1.0, released > last > >> month. > >> > >> (This is not confusing at all.) > >> > > > > ABH seems pretty much worse than ESH, and considering you can't get the > > format modifiers makes it useless for Vulkan. I don't see why we need to > > support it in addition to ESH. > > It's what it currently used by the Beignet/OpenCL interop (since it was > the only thing which existed when that was written, and the format modifier > isn't needed), and I don't want to break that. > > Since it was only released a few weeks ago it will probably be a while > before it lands in all distributions, and it isn't implemented at all by > the Intel ex-blob driver yet. > > - Mark > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > In this case wouldn't it be better if the ABH mapping function is moved to hwcontext_opencl? Then hwcontext_vaapi can be trusted to always produce completely mapped to DRM frames.
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 99f76b9169..15f1c4d1c0 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1073,8 +1073,9 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, return 0; } -static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, - HWMapDescriptor *hwmap) +#if VA_CHECK_VERSION(1, 1, 0) +static void vaapi_unmap_to_drm_esh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) { AVDRMFrameDescriptor *drm_desc = hwmap->priv; int i; @@ -1085,10 +1086,9 @@ static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, av_freep(&drm_desc); } -static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src, int flags) +static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) { -#if VA_CHECK_VERSION(1, 1, 0) AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; VASurfaceID surface_id; VAStatus vas; @@ -1140,7 +1140,7 @@ static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, } err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, - &vaapi_unmap_to_drm, drm_desc); + &vaapi_unmap_to_drm_esh, drm_desc); if (err < 0) goto fail; @@ -1155,15 +1155,182 @@ fail: close(va_desc.objects[i].fd); av_freep(&drm_desc); return err; -#else - // Older versions without vaExportSurfaceHandle() are not supported - - // in theory this is possible with a combination of vaDeriveImage() - // and vaAcquireBufferHandle(), but it doesn't carry enough metadata - // to actually use the result in a generic way. - return AVERROR(ENOSYS); +} #endif + +typedef struct VAAPIDRMImageBufferMapping { + VAImage image; + VABufferInfo buffer_info; + + AVDRMFrameDescriptor drm_desc; +} VAAPIDRMImageBufferMapping; + +static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from DRM.\n", + surface_id); + + // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(), + // so we shouldn't close them separately. + + vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer " + "handle of image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + } + + vas = vaDestroyImage(hwctx->display, mapping->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image " + "derived from surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + } + + av_free(mapping); } + +static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = NULL; + VASurfaceID surface_id; + VAStatus vas; + int err, i, p; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map VAAPI surface %#x to DRM.\n", + surface_id); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + vas = vaDeriveImage(hwctx->display, surface_id, + &mapping->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (vaapi_drm_format_map[i].va_fourcc == + mapping->image.format.fourcc) + break; + } + if (i >= FF_ARRAY_ELEMS(vaapi_drm_format_map)) { + av_log(hwfc, AV_LOG_ERROR, "No matching DRM format for " + "VAAPI format %#x.\n", mapping->image.format.fourcc); + err = AVERROR(EINVAL); + goto fail_derived; + } + + mapping->buffer_info.mem_type = + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + + mapping->drm_desc.nb_layers = + vaapi_drm_format_map[i].nb_layer_formats; + if (mapping->drm_desc.nb_layers > 1) { + if (mapping->drm_desc.nb_layers != mapping->image.num_planes) { + av_log(hwfc, AV_LOG_ERROR, "Image properties do not match " + "expected format: got %d planes, but expected %d.\n", + mapping->image.num_planes, mapping->drm_desc.nb_layers); + err = AVERROR(EINVAL); + goto fail_derived; + } + + for(p = 0; p < mapping->drm_desc.nb_layers; p++) { + mapping->drm_desc.layers[p] = (AVDRMLayerDescriptor) { + .format = vaapi_drm_format_map[i].layer_formats[p], + .nb_planes = 1, + .planes[0] = { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }, + }; + } + } else { + mapping->drm_desc.layers[0].format = + vaapi_drm_format_map[i].layer_formats[0]; + mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes; + for (p = 0; p < mapping->image.num_planes; p++) { + mapping->drm_desc.layers[0].planes[p] = (AVDRMPlaneDescriptor) { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }; + } + } + + vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf, + &mapping->buffer_info); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer " + "handle from image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_derived; + } + + av_log(hwfc, AV_LOG_DEBUG, "DRM PRIME fd is %ld.\n", + mapping->buffer_info.handle); + + mapping->drm_desc.nb_objects = 1; + mapping->drm_desc.objects[0] = (AVDRMObjectDescriptor) { + .fd = mapping->buffer_info.handle, + .size = mapping->image.data_size, + // There is no way to get the format modifier with this API. + .format_modifier = DRM_FORMAT_MOD_NONE, + }; + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_to_drm_abh, + mapping); + if (err < 0) + goto fail_mapped; + + dst->data[0] = (uint8_t*)&mapping->drm_desc; + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail_mapped: + vaReleaseBufferHandle(hwctx->display, mapping->image.buf); +fail_derived: + vaDestroyImage(hwctx->display, mapping->image.image_id); +fail: + av_freep(&mapping); + return err; +} + +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if VA_CHECK_VERSION(1, 1, 0) + int err; + err = vaapi_map_to_drm_esh(hwfc, dst, src, flags); + if (err != AVERROR(ENOSYS)) + return err; #endif + return vaapi_map_to_drm_abh(hwfc, dst, src, flags); +} + +#endif /* CONFIG_LIBDRM */ static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)