Re: [libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering
On Thu, 29 Jun 2017 10:25:09 +0100 Mark Thompson wrote: > This does actually work already by magic :) > > Both NV12 and P010 surfaces become UNORM R and RG planes, just with a > different size of sample underneath. Use in OpenCL then sees them > identically as planes of single-precision floating point values. > (Technically it isn't quite right for P010 because the low bits don't > necessarily do the right thing, but it's close enough for practical purposes.) You can assume the padding is 0 (or if it's not, that the source actually has higher precision). But scaling to full fixed point range instead of shifting is incorrect. I'd love to see libplacebo to be used for this - but for now it doesn't exist yet, and is OpenGL only. ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering
On 29/06/17 02:16, Jun Zhao wrote: > On 2017/6/28 5:50, Mark Thompson wrote: >> --- >> libavfilter/Makefile | 6 + >> libavfilter/opencl.c | 285 >> +++ >> libavfilter/opencl.h | 74 +++ >> libavfilter/opencl/rgbyuv.cl | 117 ++ >> libavfilter/opencl_source.h | 24 >> tools/cl2c | 20 +++ >> 6 files changed, 526 insertions(+) > > I guess we can give a general Colour Space Conversions solution based on > OpenCL, now > I can think some case can't support in this patch. :) e,g: > > - 10bits <-> 8bits This does actually work already by magic :) Both NV12 and P010 surfaces become UNORM R and RG planes, just with a different size of sample underneath. Use in OpenCL then sees them identically as planes of single-precision floating point values. (Technically it isn't quite right for P010 because the low bits don't necessarily do the right thing, but it's close enough for practical purposes.) > - YUV422 <-> 420P Trickier because the layouts are genuinely different: 4:2:2 planar formats will be fine as-is (though requiring different OpenCL code), but there is no straightforward representation for single-plane interleaved YUYV so it's unclear what to do there. (There are quite a lot of other holes in this as well - e.g. chroma siting and range aren't considered at all.) ___ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel
Re: [libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering
On 2017/6/28 5:50, Mark Thompson wrote: > --- > libavfilter/Makefile | 6 + > libavfilter/opencl.c | 285 > +++ > libavfilter/opencl.h | 74 +++ > libavfilter/opencl/rgbyuv.cl | 117 ++ > libavfilter/opencl_source.h | 24 > tools/cl2c | 20 +++ > 6 files changed, 526 insertions(+) I guess we can give a general Colour Space Conversions solution based on OpenCL, now I can think some case can't support in this patch. :) e,g: - YUV422 <-> 420P - 10bits <-> 8bits ... > create mode 100644 libavfilter/opencl.c > create mode 100644 libavfilter/opencl.h > create mode 100644 libavfilter/opencl/rgbyuv.cl > create mode 100644 libavfilter/opencl_source.h > create mode 100755 tools/cl2c > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 348ad9211..1370ef04b 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -106,3 +106,9 @@ OBJS-$(CONFIG_TESTSRC_FILTER)+= > vsrc_testsrc.o > > TOOLS = graph2dot > TESTPROGS = filtfmts > + > +OPENCL = $(subst $(SRC_PATH)/,,$(wildcard > $(SRC_PATH)/libavfilter/opencl/*.cl)) > +.SECONDARY: $(OPENCL:.cl=.c) > +libavfilter/opencl/%.c: TAG = OPENCL > +libavfilter/opencl/%.c: $(SRC_PATH)/libavfilter/opencl/%.cl > + $(M)$(SRC_PATH)/tools/cl2c $< $@ > diff --git a/libavfilter/opencl.c b/libavfilter/opencl.c > new file mode 100644 > index 0..f7b3f1818 > --- /dev/null > +++ b/libavfilter/opencl.c > @@ -0,0 +1,285 @@ > +/* > + * This file is part of Libav. > + * > + * Libav is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * Libav is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with Libav; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include > +#include > + > +#include "libavutil/hwcontext.h" > +#include "libavutil/hwcontext_opencl.h" > +#include "libavutil/mem.h" > + > +#include "avfilter.h" > +#include "formats.h" > +#include "opencl.h" > + > +int ff_opencl_filter_query_formats(AVFilterContext *avctx) > +{ > +const static enum AVPixelFormat formats[] = { > +AV_PIX_FMT_OPENCL, > +AV_PIX_FMT_NONE, > +}; > +int i; > + > +for (i = 0; i < avctx->nb_inputs; i++) { > +ff_formats_ref(ff_make_format_list(formats), > + &avctx->inputs[i]->out_formats); > +} > + > +for (i = 0; i < avctx->nb_outputs; i++) { > +ff_formats_ref(ff_make_format_list(formats), > + &avctx->outputs[i]->in_formats); > +} > + > +return 0; > +} > + > +int ff_opencl_filter_config_input(AVFilterLink *inlink) > +{ > +AVFilterContext *avctx = inlink->dst; > +OpenCLFilterContext *ctx = avctx->priv; > +AVHWFramesContext *input_frames; > + > +if (!inlink->hw_frames_ctx) { > +av_log(avctx, AV_LOG_ERROR, "OpenCL filtering requires a " > + "hardware frames context on the input.\n"); > +return AVERROR(EINVAL); > +} > + > +// Extract the device and default output format from the first input. > +if (avctx->inputs[0] != inlink) > +return 0; > + > +input_frames = (AVHWFramesContext*)inlink->hw_frames_ctx->data; > + > +if (input_frames->format != AV_PIX_FMT_OPENCL) > +return AVERROR(EINVAL); > + > +ctx->device_ref = av_buffer_ref(input_frames->device_ref); > +if (!ctx->device_ref) > +return AVERROR(ENOMEM); > +ctx->device = input_frames->device_ctx; > +ctx->hwctx = ctx->device->hwctx; > + > +// Default output parameters match input parameters. > +if (ctx->output_format == AV_PIX_FMT_NONE) > +ctx->output_format = input_frames->sw_format; > +if (!ctx->output_width) > +ctx->output_width = inlink->w; > +if (!ctx->output_height) > +ctx->output_height = inlink->h; > + > +return 0; > +} > + > +int ff_opencl_filter_config_output(AVFilterLink *outlink) > +{ > +AVFilterContext *avctx = outlink->src; > +OpenCLFilterContext *ctx = avctx->priv; > +AVBufferRef *output_frames_ref = NULL; > +AVHWFramesContext *output_frames; > +int err; > + > +av_buffer_unref(&outlink->hw_frames_ctx); > + > +output_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); > +if (!output_frames_ref) { > +err = AVERROR(ENOMEM); > +goto fail; > +} > +output_frames = (AVHWFramesContex
Re: [libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering
On Tue, 27 Jun 2017 22:50:49 +0100 Mark Thompson wrote: > --- > libavfilter/Makefile | 6 + > libavfilter/opencl.c | 285 > +++ > libavfilter/opencl.h | 74 +++ > libavfilter/opencl/rgbyuv.cl | 117 ++ > libavfilter/opencl_source.h | 24 > tools/cl2c | 20 +++ > 6 files changed, 526 insertions(+) > create mode 100644 libavfilter/opencl.c > create mode 100644 libavfilter/opencl.h > create mode 100644 libavfilter/opencl/rgbyuv.cl > create mode 100644 libavfilter/opencl_source.h > create mode 100755 tools/cl2c > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 348ad9211..1370ef04b 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -106,3 +106,9 @@ OBJS-$(CONFIG_TESTSRC_FILTER)+= > vsrc_testsrc.o > > TOOLS = graph2dot > TESTPROGS = filtfmts > + > +OPENCL = $(subst $(SRC_PATH)/,,$(wildcard > $(SRC_PATH)/libavfilter/opencl/*.cl)) > +.SECONDARY: $(OPENCL:.cl=.c) > +libavfilter/opencl/%.c: TAG = OPENCL > +libavfilter/opencl/%.c: $(SRC_PATH)/libavfilter/opencl/%.cl > + $(M)$(SRC_PATH)/tools/cl2c $< $@ > diff --git a/libavfilter/opencl.c b/libavfilter/opencl.c > new file mode 100644 > index 0..f7b3f1818 > --- /dev/null > +++ b/libavfilter/opencl.c > @@ -0,0 +1,285 @@ > +/* > + * This file is part of Libav. > + * > + * Libav is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * Libav is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with Libav; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include > +#include > + > +#include "libavutil/hwcontext.h" > +#include "libavutil/hwcontext_opencl.h" > +#include "libavutil/mem.h" > + > +#include "avfilter.h" > +#include "formats.h" > +#include "opencl.h" > + > +int ff_opencl_filter_query_formats(AVFilterContext *avctx) > +{ > +const static enum AVPixelFormat formats[] = { > +AV_PIX_FMT_OPENCL, > +AV_PIX_FMT_NONE, > +}; > +int i; > + > +for (i = 0; i < avctx->nb_inputs; i++) { > +ff_formats_ref(ff_make_format_list(formats), > + &avctx->inputs[i]->out_formats); > +} > + > +for (i = 0; i < avctx->nb_outputs; i++) { > +ff_formats_ref(ff_make_format_list(formats), > + &avctx->outputs[i]->in_formats); > +} > + > +return 0; > +} > + > +int ff_opencl_filter_config_input(AVFilterLink *inlink) > +{ > +AVFilterContext *avctx = inlink->dst; > +OpenCLFilterContext *ctx = avctx->priv; > +AVHWFramesContext *input_frames; > + > +if (!inlink->hw_frames_ctx) { > +av_log(avctx, AV_LOG_ERROR, "OpenCL filtering requires a " > + "hardware frames context on the input.\n"); > +return AVERROR(EINVAL); > +} > + > +// Extract the device and default output format from the first input. > +if (avctx->inputs[0] != inlink) > +return 0; > + > +input_frames = (AVHWFramesContext*)inlink->hw_frames_ctx->data; > + > +if (input_frames->format != AV_PIX_FMT_OPENCL) > +return AVERROR(EINVAL); > + > +ctx->device_ref = av_buffer_ref(input_frames->device_ref); > +if (!ctx->device_ref) > +return AVERROR(ENOMEM); > +ctx->device = input_frames->device_ctx; > +ctx->hwctx = ctx->device->hwctx; > + > +// Default output parameters match input parameters. > +if (ctx->output_format == AV_PIX_FMT_NONE) > +ctx->output_format = input_frames->sw_format; > +if (!ctx->output_width) > +ctx->output_width = inlink->w; > +if (!ctx->output_height) > +ctx->output_height = inlink->h; > + > +return 0; > +} > + > +int ff_opencl_filter_config_output(AVFilterLink *outlink) > +{ > +AVFilterContext *avctx = outlink->src; > +OpenCLFilterContext *ctx = avctx->priv; > +AVBufferRef *output_frames_ref = NULL; > +AVHWFramesContext *output_frames; > +int err; > + > +av_buffer_unref(&outlink->hw_frames_ctx); > + > +output_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); > +if (!output_frames_ref) { > +err = AVERROR(ENOMEM); > +goto fail; > +} > +output_frames = (AVHWFramesContext*)output_frames_ref->data; > + > +output_frames->format= AV_PIX_FMT_OPENCL; > +output_frames->sw_format = ctx->output_format; > +output_frames->width =
[libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering
--- libavfilter/Makefile | 6 + libavfilter/opencl.c | 285 +++ libavfilter/opencl.h | 74 +++ libavfilter/opencl/rgbyuv.cl | 117 ++ libavfilter/opencl_source.h | 24 tools/cl2c | 20 +++ 6 files changed, 526 insertions(+) create mode 100644 libavfilter/opencl.c create mode 100644 libavfilter/opencl.h create mode 100644 libavfilter/opencl/rgbyuv.cl create mode 100644 libavfilter/opencl_source.h create mode 100755 tools/cl2c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 348ad9211..1370ef04b 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -106,3 +106,9 @@ OBJS-$(CONFIG_TESTSRC_FILTER)+= vsrc_testsrc.o TOOLS = graph2dot TESTPROGS = filtfmts + +OPENCL = $(subst $(SRC_PATH)/,,$(wildcard $(SRC_PATH)/libavfilter/opencl/*.cl)) +.SECONDARY: $(OPENCL:.cl=.c) +libavfilter/opencl/%.c: TAG = OPENCL +libavfilter/opencl/%.c: $(SRC_PATH)/libavfilter/opencl/%.cl + $(M)$(SRC_PATH)/tools/cl2c $< $@ diff --git a/libavfilter/opencl.c b/libavfilter/opencl.c new file mode 100644 index 0..f7b3f1818 --- /dev/null +++ b/libavfilter/opencl.c @@ -0,0 +1,285 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_opencl.h" +#include "libavutil/mem.h" + +#include "avfilter.h" +#include "formats.h" +#include "opencl.h" + +int ff_opencl_filter_query_formats(AVFilterContext *avctx) +{ +const static enum AVPixelFormat formats[] = { +AV_PIX_FMT_OPENCL, +AV_PIX_FMT_NONE, +}; +int i; + +for (i = 0; i < avctx->nb_inputs; i++) { +ff_formats_ref(ff_make_format_list(formats), + &avctx->inputs[i]->out_formats); +} + +for (i = 0; i < avctx->nb_outputs; i++) { +ff_formats_ref(ff_make_format_list(formats), + &avctx->outputs[i]->in_formats); +} + +return 0; +} + +int ff_opencl_filter_config_input(AVFilterLink *inlink) +{ +AVFilterContext *avctx = inlink->dst; +OpenCLFilterContext *ctx = avctx->priv; +AVHWFramesContext *input_frames; + +if (!inlink->hw_frames_ctx) { +av_log(avctx, AV_LOG_ERROR, "OpenCL filtering requires a " + "hardware frames context on the input.\n"); +return AVERROR(EINVAL); +} + +// Extract the device and default output format from the first input. +if (avctx->inputs[0] != inlink) +return 0; + +input_frames = (AVHWFramesContext*)inlink->hw_frames_ctx->data; + +if (input_frames->format != AV_PIX_FMT_OPENCL) +return AVERROR(EINVAL); + +ctx->device_ref = av_buffer_ref(input_frames->device_ref); +if (!ctx->device_ref) +return AVERROR(ENOMEM); +ctx->device = input_frames->device_ctx; +ctx->hwctx = ctx->device->hwctx; + +// Default output parameters match input parameters. +if (ctx->output_format == AV_PIX_FMT_NONE) +ctx->output_format = input_frames->sw_format; +if (!ctx->output_width) +ctx->output_width = inlink->w; +if (!ctx->output_height) +ctx->output_height = inlink->h; + +return 0; +} + +int ff_opencl_filter_config_output(AVFilterLink *outlink) +{ +AVFilterContext *avctx = outlink->src; +OpenCLFilterContext *ctx = avctx->priv; +AVBufferRef *output_frames_ref = NULL; +AVHWFramesContext *output_frames; +int err; + +av_buffer_unref(&outlink->hw_frames_ctx); + +output_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref); +if (!output_frames_ref) { +err = AVERROR(ENOMEM); +goto fail; +} +output_frames = (AVHWFramesContext*)output_frames_ref->data; + +output_frames->format= AV_PIX_FMT_OPENCL; +output_frames->sw_format = ctx->output_format; +output_frames->width = ctx->output_width; +output_frames->height= ctx->output_height; + +err = av_hwframe_ctx_init(output_frames_ref); +if (err < 0) { +av_log(avctx, AV_LOG_ERROR, "Failed to initialise output " + "frames: %d.\n", err); +goto fail; +} + +outlink->hw_frames_ctx = output_frames_ref; +outlink->w = ctx-