Re: [FFmpeg-devel] [PATCH 1/2] lavfi/vf_stack_vaapi: factor out the common code for stack setting

2023-02-12 Thread Xiang, Haihao
On Di, 2023-02-07 at 11:59 +0800, Xiang, Haihao wrote:
> From: Haihao Xiang 
> 
> The common code will be used in QSV based stack filters.
> 
> Signed-off-by: Haihao Xiang 
> ---
>  libavfilter/stack_internal.c | 355 +++
>  libavfilter/stack_internal.h |  60 ++
>  libavfilter/vf_stack_vaapi.c | 395 ---
>  3 files changed, 452 insertions(+), 358 deletions(-)
>  create mode 100644 libavfilter/stack_internal.c
>  create mode 100644 libavfilter/stack_internal.h
> 
> diff --git a/libavfilter/stack_internal.c b/libavfilter/stack_internal.c
> new file mode 100644
> index 00..57661e1c97
> --- /dev/null
> +++ b/libavfilter/stack_internal.c
> @@ -0,0 +1,355 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg 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.
> + *
> + * FFmpeg 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 FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +#define OFFSET(x) offsetof(StackHWContext, x)
> +#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
> +
> +#define SET_OUTPUT_REGION(region, rx, ry, rw, rh) do {  \
> +region->x = rx; \
> +region->y = ry; \
> +region->width = rw; \
> +region->height = rh;\
> +} while (0)
> +
> +static int init_framesync(AVFilterContext *avctx)
> +{
> +StackBaseContext *sctx = avctx->priv;
> +int ret;
> +
> +ret = ff_framesync_init(>fs, avctx, avctx->nb_inputs);
> +if (ret < 0)
> +return ret;
> +
> +sctx->fs.on_event = process_frame;
> +sctx->fs.opaque = sctx;
> +
> +for (int i = 0; i < sctx->nb_inputs; i++) {
> +FFFrameSyncIn *in = >fs.in[i];
> +
> +in->before = EXT_STOP;
> +in->after = sctx->shortest ? EXT_STOP : EXT_INFINITY;
> +in->sync = 1;
> +in->time_base = avctx->inputs[i]->time_base;
> +}
> +
> +return ff_framesync_configure(>fs);
> +}
> +
> +static int config_comm_output(AVFilterLink *outlink)
> +{
> +AVFilterContext *avctx = outlink->src;
> +StackBaseContext *sctx = avctx->priv;
> +AVFilterLink *inlink0 = avctx->inputs[0];
> +int width, height, ret;
> +
> +if (sctx->mode == STACK_H) {
> +height = sctx->tile_height;
> +width = 0;
> +
> +if (!height)
> +height = inlink0->h;
> +
> +for (int i = 0; i < sctx->nb_inputs; i++) {
> +AVFilterLink *inlink = avctx->inputs[i];
> +StackItemRegion *region = >regions[i];
> +
> +SET_OUTPUT_REGION(region, width, 0, av_rescale(height, 
> inlink->w, 
> inlink->h), height);
> +width += av_rescale(height, inlink->w, inlink->h);
> +}
> +} else if (sctx->mode == STACK_V) {
> +height = 0;
> +width = sctx->tile_width;
> +
> +if (!width)
> +width = inlink0->w;
> +
> +for (int i = 0; i < sctx->nb_inputs; i++) {
> +AVFilterLink *inlink = avctx->inputs[i];
> +StackItemRegion *region = >regions[i];
> +
> +SET_OUTPUT_REGION(region, 0, height, width, av_rescale(width,
> inlink->h, inlink->w));
> +height += av_rescale(width, inlink->h, inlink->w);
> +}
> +} else if (sctx->nb_grid_rows && sctx->nb_grid_columns) {
> +int xpos = 0, ypos = 0;
> +int ow, oh, k = 0;
> +
> +ow = sctx->tile_width;
> +oh = sctx->tile_height;
> +
> +if (!ow || !oh) {
> +ow = avctx->inputs[0]->w;
> +oh = avctx->inputs[0]->h;
> +}
> +
> +for (int i = 0; i < sctx->nb_grid_columns; i++) {
> +ypos = 0;
> +
> +for (int j = 0; j < sctx->nb_grid_rows; j++) {
> +StackItemRegion *region = >regions[k++];
> +
> +SET_OUTPUT_REGION(region, xpos, ypos, ow, oh);
> +ypos += oh;
> +}
> +
> +xpos += ow;
> +}
> +
> +width = ow * sctx->nb_grid_columns;
> +height = oh * sctx->nb_grid_rows;
> +} else {
> +char *arg, *p = sctx->layout, *saveptr = NULL;
> +char *arg2, *p2, *saveptr2 = NULL;
> +char *arg3, *p3, *saveptr3 = NULL;
> +int xpos, ypos, size;
> +int ow, oh;
> +
> +width = 

[FFmpeg-devel] [PATCH 1/2] lavfi/vf_stack_vaapi: factor out the common code for stack setting

2023-02-06 Thread Xiang, Haihao
From: Haihao Xiang 

The common code will be used in QSV based stack filters.

Signed-off-by: Haihao Xiang 
---
 libavfilter/stack_internal.c | 355 +++
 libavfilter/stack_internal.h |  60 ++
 libavfilter/vf_stack_vaapi.c | 395 ---
 3 files changed, 452 insertions(+), 358 deletions(-)
 create mode 100644 libavfilter/stack_internal.c
 create mode 100644 libavfilter/stack_internal.h

diff --git a/libavfilter/stack_internal.c b/libavfilter/stack_internal.c
new file mode 100644
index 00..57661e1c97
--- /dev/null
+++ b/libavfilter/stack_internal.c
@@ -0,0 +1,355 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define OFFSET(x) offsetof(StackHWContext, x)
+#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
+
+#define SET_OUTPUT_REGION(region, rx, ry, rw, rh) do {  \
+region->x = rx; \
+region->y = ry; \
+region->width = rw; \
+region->height = rh;\
+} while (0)
+
+static int init_framesync(AVFilterContext *avctx)
+{
+StackBaseContext *sctx = avctx->priv;
+int ret;
+
+ret = ff_framesync_init(>fs, avctx, avctx->nb_inputs);
+if (ret < 0)
+return ret;
+
+sctx->fs.on_event = process_frame;
+sctx->fs.opaque = sctx;
+
+for (int i = 0; i < sctx->nb_inputs; i++) {
+FFFrameSyncIn *in = >fs.in[i];
+
+in->before = EXT_STOP;
+in->after = sctx->shortest ? EXT_STOP : EXT_INFINITY;
+in->sync = 1;
+in->time_base = avctx->inputs[i]->time_base;
+}
+
+return ff_framesync_configure(>fs);
+}
+
+static int config_comm_output(AVFilterLink *outlink)
+{
+AVFilterContext *avctx = outlink->src;
+StackBaseContext *sctx = avctx->priv;
+AVFilterLink *inlink0 = avctx->inputs[0];
+int width, height, ret;
+
+if (sctx->mode == STACK_H) {
+height = sctx->tile_height;
+width = 0;
+
+if (!height)
+height = inlink0->h;
+
+for (int i = 0; i < sctx->nb_inputs; i++) {
+AVFilterLink *inlink = avctx->inputs[i];
+StackItemRegion *region = >regions[i];
+
+SET_OUTPUT_REGION(region, width, 0, av_rescale(height, inlink->w, 
inlink->h), height);
+width += av_rescale(height, inlink->w, inlink->h);
+}
+} else if (sctx->mode == STACK_V) {
+height = 0;
+width = sctx->tile_width;
+
+if (!width)
+width = inlink0->w;
+
+for (int i = 0; i < sctx->nb_inputs; i++) {
+AVFilterLink *inlink = avctx->inputs[i];
+StackItemRegion *region = >regions[i];
+
+SET_OUTPUT_REGION(region, 0, height, width, av_rescale(width, 
inlink->h, inlink->w));
+height += av_rescale(width, inlink->h, inlink->w);
+}
+} else if (sctx->nb_grid_rows && sctx->nb_grid_columns) {
+int xpos = 0, ypos = 0;
+int ow, oh, k = 0;
+
+ow = sctx->tile_width;
+oh = sctx->tile_height;
+
+if (!ow || !oh) {
+ow = avctx->inputs[0]->w;
+oh = avctx->inputs[0]->h;
+}
+
+for (int i = 0; i < sctx->nb_grid_columns; i++) {
+ypos = 0;
+
+for (int j = 0; j < sctx->nb_grid_rows; j++) {
+StackItemRegion *region = >regions[k++];
+
+SET_OUTPUT_REGION(region, xpos, ypos, ow, oh);
+ypos += oh;
+}
+
+xpos += ow;
+}
+
+width = ow * sctx->nb_grid_columns;
+height = oh * sctx->nb_grid_rows;
+} else {
+char *arg, *p = sctx->layout, *saveptr = NULL;
+char *arg2, *p2, *saveptr2 = NULL;
+char *arg3, *p3, *saveptr3 = NULL;
+int xpos, ypos, size;
+int ow, oh;
+
+width = avctx->inputs[0]->w;
+height = avctx->inputs[0]->h;
+
+for (int i = 0; i < sctx->nb_inputs; i++) {
+AVFilterLink *inlink = avctx->inputs[i];
+StackItemRegion *region = >regions[i];
+
+ow = inlink->w;
+oh = inlink->h;
+
+if (!(arg = av_strtok(p, "|", )))
+return