On 11 March 2018 at 22:41, Mark Thompson <s...@jkqxz.net> wrote: > Also use that to support mapping VAAPI to Beignet. > --- > configure | 16 +-- > libavutil/hwcontext_opencl.c | 264 +++++++++++++++++++++--------- > ------------- > 2 files changed, 138 insertions(+), 142 deletions(-) > > diff --git a/configure b/configure > index 5e38bdab17..5051fd1abf 100755 > --- a/configure > +++ b/configure > @@ -2137,6 +2137,7 @@ HAVE_LIST=" > makeinfo_html > opencl_d3d11 > opencl_drm_arm > + opencl_drm_beignet > opencl_dxva2 > opencl_vaapi_beignet > opencl_vaapi_intel_media > @@ -6223,9 +6224,15 @@ enabled vaapi && > check_cpp_condition "va/va.h" "VA_CHECK_VERSION(1, 0, 0)" && > enable vaapi_1 > > -if enabled_all opencl vaapi ; then > +if enabled_all opencl libdrm ; then > check_type "CL/cl_intel.h" "clCreateImageFromFdINTEL_fn" && > - enable opencl_vaapi_beignet > + enable opencl_drm_beignet > + check_func_headers "CL/cl_ext.h" clImportMemoryARM && > + enable opencl_drm_arm > +fi > + > +if enabled_all opencl vaapi ; then > + enabled opencl_drm_beignet && enable opencl_vaapi_beignet > if enabled libmfx ; then > check_type "CL/cl.h CL/va_ext.h" > "clCreateFromVA_APIMediaSurfaceINTEL_fn" > && > enable opencl_vaapi_intel_media > @@ -6242,11 +6249,6 @@ if enabled_all opencl d3d11va ; then > enable opencl_d3d11 > fi > > -if enabled_all opencl libdrm ; then > - check_func_headers "CL/cl_ext.h" clImportMemoryARM && > - enable opencl_drm_arm > -fi > - > enabled vdpau && > check_cpp_condition vdpau/vdpau.h "defined > VDP_DECODER_PROFILE_MPEG4_PART2_ASP" > || > disable vdpau > diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c > index a725a491e2..334f87344e 100644 > --- a/libavutil/hwcontext_opencl.c > +++ b/libavutil/hwcontext_opencl.c > @@ -37,6 +37,12 @@ > #include "hwcontext_vaapi.h" > #endif > > +#if HAVE_OPENCL_DRM_BEIGNET > +#include <unistd.h> > +#include <CL/cl_intel.h> > +#include "hwcontext_drm.h" > +#endif > + > #if HAVE_OPENCL_VAAPI_INTEL_MEDIA > #include <mfx/mfxstructures.h> > #include <va/va.h> > @@ -74,9 +80,9 @@ typedef struct OpenCLDeviceContext { > cl_platform_id platform_id; > > // Platform/device-specific functions. > -#if HAVE_OPENCL_VAAPI_BEIGNET > - int vaapi_mapping_usable; > - clCreateImageFromFdINTEL_fn clCreateImageFromFdINTEL; > +#if HAVE_OPENCL_DRM_BEIGNET > + int beignet_drm_mapping_usable; > + clCreateImageFromFdINTEL_fn clCreateImageFromFdINTEL; > #endif > > #if HAVE_OPENCL_VAAPI_INTEL_MEDIA > @@ -685,19 +691,19 @@ static int opencl_device_init(AVHWDeviceContext > *hwdev) > } \ > } while (0) > > -#if HAVE_OPENCL_VAAPI_BEIGNET > +#if HAVE_OPENCL_DRM_BEIGNET > { > int fail = 0; > > CL_FUNC(clCreateImageFromFdINTEL, > - "Intel DRM to OpenCL image mapping"); > + "Beignet DRM to OpenCL image mapping"); > > if (fail) { > - av_log(hwdev, AV_LOG_WARNING, "VAAPI to OpenCL mapping " > - "not usable.\n"); > - priv->vaapi_mapping_usable = 0; > + av_log(hwdev, AV_LOG_WARNING, "Beignet DRM to OpenCL " > + "mapping not usable.\n"); > + priv->beignet_drm_mapping_usable = 0; > } else { > - priv->vaapi_mapping_usable = 1; > + priv->beignet_drm_mapping_usable = 1; > } > } > #endif > @@ -1187,7 +1193,8 @@ static int opencl_device_derive(AVHWDeviceContext > *hwdev, > int err; > switch (src_ctx->type) { > > -#if HAVE_OPENCL_VAAPI_BEIGNET > +#if HAVE_OPENCL_DRM_BEIGNET > + case AV_HWDEVICE_TYPE_DRM: > case AV_HWDEVICE_TYPE_VAAPI: > { > // Surface mapping works via DRM PRIME fds with no special > @@ -2028,175 +2035,151 @@ fail: > return err; > } > > -#if HAVE_OPENCL_VAAPI_BEIGNET > +#if HAVE_OPENCL_DRM_BEIGNET > > -typedef struct VAAPItoOpenCLMapping { > - VAImage va_image; > - VABufferInfo va_buffer_info; > +typedef struct DRMBeignetToOpenCLMapping { > + AVFrame *drm_frame; > + AVDRMFrameDescriptor *drm_desc; > > AVOpenCLFrameDescriptor frame; > -} VAAPItoOpenCLMapping; > +} DRMBeignetToOpenCLMapping; > > -static void opencl_unmap_from_vaapi(AVHWFramesContext *src_fc, > - HWMapDescriptor *hwmap) > +static void opencl_unmap_from_drm_beignet(AVHWFramesContext *dst_fc, > + HWMapDescriptor *hwmap) > { > - VAAPItoOpenCLMapping *mapping = hwmap->priv; > - AVVAAPIDeviceContext *src_dev = src_fc->device_ctx->hwctx; > - VASurfaceID surface_id; > - VAStatus vas; > + DRMBeignetToOpenCLMapping *mapping = hwmap->priv; > cl_int cle; > int i; > > - surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; > - av_log(src_fc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from OpenCL.\n", > - surface_id); > - > for (i = 0; i < mapping->frame.nb_planes; i++) { > cle = clReleaseMemObject(mapping->frame.planes[i]); > if (cle != CL_SUCCESS) { > - av_log(src_fc, AV_LOG_ERROR, "Failed to release CL " > - "buffer of plane %d of VA image %#x (derived " > - "from surface %#x): %d.\n", i, > - mapping->va_image.buf, surface_id, cle); > + av_log(dst_fc, AV_LOG_ERROR, "Failed to release CL image " > + "of plane %d of DRM frame: %d.\n", i, cle); > } > } > > - vas = vaReleaseBufferHandle(src_dev->display, > - mapping->va_image.buf); > - if (vas != VA_STATUS_SUCCESS) { > - av_log(src_fc, AV_LOG_ERROR, "Failed to release buffer " > - "handle of image %#x (derived from surface %#x): " > - "%d (%s).\n", mapping->va_image.buf, surface_id, > - vas, vaErrorStr(vas)); > - } > - > - vas = vaDestroyImage(src_dev->display, > - mapping->va_image.image_id); > - if (vas != VA_STATUS_SUCCESS) { > - av_log(src_fc, AV_LOG_ERROR, "Failed to destroy image " > - "derived from surface %#x: %d (%s).\n", > - surface_id, vas, vaErrorStr(vas)); > - } > - > av_free(mapping); > } > > -static int opencl_map_from_vaapi(AVHWFramesContext *dst_fc, AVFrame *dst, > - const AVFrame *src, int flags) > +static int opencl_map_from_drm_beignet(AVHWFramesContext *dst_fc, > + AVFrame *dst, const AVFrame *src, > + int flags) > { > - AVHWFramesContext *src_fc = > - (AVHWFramesContext*)src->hw_frames_ctx->data; > - AVVAAPIDeviceContext *src_dev = src_fc->device_ctx->hwctx; > - AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; > - OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; > - VAAPItoOpenCLMapping *mapping = NULL; > - VASurfaceID surface_id; > - VAStatus vas; > + AVOpenCLDeviceContext *hwctx = dst_fc->device_ctx->hwctx; > + OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; > + DRMBeignetToOpenCLMapping *mapping; > + const AVDRMFrameDescriptor *desc; > cl_int cle; > - int err, p; > + int err, i, j, p; > > - surface_id = (VASurfaceID)(uintptr_t)src->data[3]; > - av_log(src_fc, AV_LOG_DEBUG, "Map VAAPI surface %#x to OpenCL.\n", > - surface_id); > + desc = (const AVDRMFrameDescriptor*)src->data[0]; > > mapping = av_mallocz(sizeof(*mapping)); > if (!mapping) > return AVERROR(ENOMEM); > > - vas = vaDeriveImage(src_dev->display, surface_id, > - &mapping->va_image); > - if (vas != VA_STATUS_SUCCESS) { > - av_log(src_fc, AV_LOG_ERROR, "Failed to derive image from " > - "surface %#x: %d (%s).\n", > - surface_id, vas, vaErrorStr(vas)); > - err = AVERROR(EIO); > - goto fail; > - } > - > - mapping->va_buffer_info.mem_type = > - VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; > - > - vas = vaAcquireBufferHandle(src_dev->display, > - mapping->va_image.buf, > - &mapping->va_buffer_info); > - if (vas != VA_STATUS_SUCCESS) { > - av_log(src_fc, AV_LOG_ERROR, "Failed to get buffer " > - "handle from image %#x (derived from surface %#x): " > - "%d (%s).\n", mapping->va_image.buf, surface_id, > - vas, vaErrorStr(vas)); > - vaDestroyImage(src_dev->display, mapping->va_image.buf); > - err = AVERROR(EIO); > - goto fail_derived; > - } > - > - av_log(dst_fc, AV_LOG_DEBUG, "DRM PRIME fd is %ld.\n", > - mapping->va_buffer_info.handle); > + p = 0; > + for (i = 0; i < desc->nb_layers; i++) { > + const AVDRMLayerDescriptor *layer = &desc->layers[i]; > + for (j = 0; j < layer->nb_planes; j++) { > + const AVDRMPlaneDescriptor *plane = &layer->planes[j]; > + const AVDRMObjectDescriptor *object = > + &desc->objects[plane->object_index]; > + > + cl_import_image_info_intel image_info = { > + .fd = object->fd, > + .size = object->size, > + .type = CL_MEM_OBJECT_IMAGE2D, > + .offset = plane->offset, > + .row_pitch = plane->pitch, > + }; > + cl_image_desc image_desc; > > - mapping->frame.nb_planes = mapping->va_image.num_planes; > - for (p = 0; p < mapping->frame.nb_planes; p++) { > - cl_import_image_info_intel image_info = { > - .fd = mapping->va_buffer_info.handle, > - .size = mapping->va_buffer_info.mem_size, > - .type = CL_MEM_OBJECT_IMAGE2D, > - .offset = mapping->va_image.offsets[p], > - .row_pitch = mapping->va_image.pitches[p], > - }; > - cl_image_desc image_desc; > + err = opencl_get_plane_format(dst_fc->sw_format, p, > + src->width, src->height, > + &image_info.fmt, > + &image_desc); > + if (err < 0) { > + av_log(dst_fc, AV_LOG_ERROR, "DRM frame layer %d " > + "plane %d is not representable in OpenCL: %d.\n", > + i, j, err); > + goto fail; > + } > + image_info.width = image_desc.image_width; > + image_info.height = image_desc.image_height; > + > + mapping->frame.planes[p] = > + priv->clCreateImageFromFdINTEL(hwctx->context, > + &image_info, &cle); > + if (!mapping->frame.planes[p]) { > + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image " > + "from layer %d plane %d of DRM frame: %d.\n", > + i, j, cle); > + err = AVERROR(EIO); > + goto fail; > + } > > - err = opencl_get_plane_format(src_fc->sw_format, p, > - mapping->va_image.width, > - mapping->va_image.height, > - &image_info.fmt, > - &image_desc); > - if (err < 0) { > - av_log(dst_fc, AV_LOG_ERROR, "VA %#x (derived from " > - "surface %#x) has invalid parameters: %d.\n", > - mapping->va_image.buf, surface_id, err); > - goto fail_mapped; > + dst->data[p] = (uint8_t*)mapping->frame.planes[p]; > + mapping->frame.nb_planes = ++p; > } > - image_info.width = image_desc.image_width; > - image_info.height = image_desc.image_height; > - > - mapping->frame.planes[p] = > - priv->clCreateImageFromFdINTEL(dst_dev->context, > - &image_info, &cle); > - if (!mapping->frame.planes[p]) { > - av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image " > - "from plane %d of VA image %#x (derived from " > - "surface %#x): %d.\n", p, > - mapping->va_image.buf, surface_id, cle); > - err = AVERROR(EIO); > - goto fail_mapped; > - } > - > - dst->data[p] = (uint8_t*)mapping->frame.planes[p]; > } > > - err = ff_hwframe_map_create(src->hw_frames_ctx, > - dst, src, &opencl_unmap_from_vaapi, > + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, > + &opencl_unmap_from_drm_beignet, > mapping); > if (err < 0) > - goto fail_mapped; > + goto fail; > > dst->width = src->width; > dst->height = src->height; > > return 0; > > -fail_mapped: > +fail: > for (p = 0; p < mapping->frame.nb_planes; p++) { > if (mapping->frame.planes[p]) > clReleaseMemObject(mapping->frame.planes[p]); > } > - vaReleaseBufferHandle(src_dev->display, mapping->va_image.buf); > -fail_derived: > - vaDestroyImage(src_dev->display, mapping->va_image.image_id); > + return err; > +} > + > +#if HAVE_OPENCL_VAAPI_BEIGNET > + > +static int opencl_map_from_vaapi(AVHWFramesContext *dst_fc, > + AVFrame *dst, const AVFrame *src, > + int flags) > +{ > + HWMapDescriptor *hwmap; > + AVFrame *tmp; > + int err; > + > + tmp = av_frame_alloc(); > + if (!tmp) > + return AVERROR(ENOMEM); > + > + tmp->format = AV_PIX_FMT_DRM_PRIME; > + > + err = av_hwframe_map(tmp, src, flags); > + if (err < 0) > + goto fail; > + > + err = opencl_map_from_drm_beignet(dst_fc, dst, tmp, flags); > + if (err < 0) > + goto fail; > + > + // Adjust the map descriptor so that unmap works correctly. > + hwmap = (HWMapDescriptor*)dst->buf[0]->data; > + av_frame_unref(hwmap->source); > + err = av_frame_ref(hwmap->source, src); > + > fail: > - av_freep(&mapping); > + av_frame_free(&tmp); > return err; > } > > -#endif > +#endif /* HAVE_OPENCL_VAAPI_BEIGNET */ > +#endif /* HAVE_OPENCL_DRM_BEIGNET */ > > static inline cl_mem_flags opencl_mem_flags_for_mapping(int map_flags) > { > @@ -2826,9 +2809,14 @@ static int opencl_map_to(AVHWFramesContext *hwfc, > AVFrame *dst, > OpenCLDeviceContext *priv = hwfc->device_ctx->internal->priv; > av_assert0(dst->format == AV_PIX_FMT_OPENCL); > switch (src->format) { > +#if HAVE_OPENCL_DRM_BEIGNET > + case AV_PIX_FMT_DRM_PRIME: > + if (priv->beignet_drm_mapping_usable) > + return opencl_map_from_drm_beignet(hwfc, dst, src, flags); > +#endif > #if HAVE_OPENCL_VAAPI_BEIGNET > case AV_PIX_FMT_VAAPI: > - if (priv->vaapi_mapping_usable) > + if (priv->beignet_drm_mapping_usable) > return opencl_map_from_vaapi(hwfc, dst, src, flags); > #endif > #if HAVE_OPENCL_VAAPI_INTEL_MEDIA > @@ -2861,9 +2849,15 @@ static int opencl_frames_derive_to(AVHWFramesContext > *dst_fc, > { > OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; > switch (src_fc->device_ctx->type) { > +#if HAVE_OPENCL_DRM_BEIGNET > + case AV_HWDEVICE_TYPE_DRM: > + if (!priv->beignet_drm_mapping_usable) > + return AVERROR(ENOSYS); > + break; > +#endif > #if HAVE_OPENCL_VAAPI_BEIGNET > case AV_HWDEVICE_TYPE_VAAPI: > - if (!priv->vaapi_mapping_usable) > + if (!priv->beignet_drm_mapping_usable) > return AVERROR(ENOSYS); > break; > #endif > -- > 2.16.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >
Doesn't seem to work, at least on my machine: DRM frame layer 0 plane 0 is not representable in OpenCL: -22 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel