Re: [FFmpeg-devel] [PATCH 1/2] lavfi/vf_stack_vaapi: factor out the common code for stack setting
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
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