Re: [libav-devel] [PATCH 07/12] lavfi: Add some common code for OpenCL filtering

2017-06-29 Thread wm4
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

2017-06-29 Thread Mark Thompson
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

2017-06-28 Thread Jun Zhao


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

2017-06-28 Thread wm4
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

2017-06-27 Thread Mark Thompson
---
 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-