diff options
author | Mark Thompson <sw@jkqxz.net> | 2018-03-19 22:52:30 +0000 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2018-03-22 23:12:47 +0000 |
commit | 2a1542d105dc3161516e34eef77bcd64aa72cab4 (patch) | |
tree | 2f32963bfb6d8a00b9136b8a4f169922840a905e /libavfilter/opencl.c | |
parent | b78d55b2e63e410abe744932fda9358633743a9e (diff) |
lavfi/opencl: Derive global work size from plane image sizes
Add a new function to find the global work size given the output image and
the required block alignment, then use it in the overlay, program and unsharp
filters. Fixes the overlay and unsharp filters applying the kernel to
locations outside the frame when subsampled planes are present.
Diffstat (limited to 'libavfilter/opencl.c')
-rw-r--r-- | libavfilter/opencl.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/libavfilter/opencl.c b/libavfilter/opencl.c index 37afc41f8b..ae61667380 100644 --- a/libavfilter/opencl.c +++ b/libavfilter/opencl.c @@ -22,6 +22,7 @@ #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_opencl.h" #include "libavutil/mem.h" +#include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" @@ -276,3 +277,66 @@ fail: av_freep(&src); return err; } + +int ff_opencl_filter_work_size_from_image(AVFilterContext *avctx, + size_t *work_size, + AVFrame *frame, int plane, + int block_alignment) +{ + cl_mem image; + cl_mem_object_type type; + size_t width, height; + cl_int cle; + + if (frame->format != AV_PIX_FMT_OPENCL) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame format %s, " + "opencl required.\n", av_get_pix_fmt_name(frame->format)); + return AVERROR(EINVAL); + } + + image = (cl_mem)frame->data[plane]; + if (!image) { + av_log(avctx, AV_LOG_ERROR, "Plane %d required but not set.\n", + plane); + return AVERROR(EINVAL); + } + + cle = clGetMemObjectInfo(image, CL_MEM_TYPE, sizeof(type), + &type, NULL); + if (cle != CL_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query object type of " + "plane %d: %d.\n", plane, cle); + return AVERROR_UNKNOWN; + } + if (type != CL_MEM_OBJECT_IMAGE2D) { + av_log(avctx, AV_LOG_ERROR, "Plane %d is not a 2D image.\n", + plane); + return AVERROR(EINVAL); + } + + cle = clGetImageInfo(image, CL_IMAGE_WIDTH, sizeof(size_t), + &width, NULL); + if (cle != CL_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query plane %d width: %d.\n", + plane, cle); + return AVERROR_UNKNOWN; + } + + cle = clGetImageInfo(image, CL_IMAGE_HEIGHT, sizeof(size_t), + &height, NULL); + if (cle != CL_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query plane %d height: %d.\n", + plane, cle); + return AVERROR_UNKNOWN; + } + + if (block_alignment) { + width = FFALIGN(width, block_alignment); + height = FFALIGN(height, block_alignment); + } + + work_size[0] = width; + work_size[1] = height; + + return 0; +} |