From: Nicolas George <george@nsup.org> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [WIP] [PATCH 1/2] lavfi/framesync: support filters with multiple outputs Date: Mon, 26 Jun 2023 22:09:31 +0200 Message-ID: <20230626200932.1329118-1-george@nsup.org> (raw) The filters will have to provide the logic to set the status and check for a wanted frame. Signed-off-by: Nicolas George <george@nsup.org> --- libavfilter/framesync.c | 46 ++++++++++++++++++++++++++++++----------- libavfilter/framesync.h | 28 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 12 deletions(-) Untested yet. diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index c748262ba6..0923e8c22b 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -75,6 +75,10 @@ enum { static int consume_from_fifos(FFFrameSync *fs); +static void default_on_eof(FFFrameSync *fs); + +static int default_on_miss(FFFrameSync *fs); + void ff_framesync_preinit(FFFrameSync *fs) { if (fs->class) @@ -83,28 +87,36 @@ void ff_framesync_preinit(FFFrameSync *fs) av_opt_set_defaults(fs); } -int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) +int ff_framesync_postinit(FFFrameSync *fs) { - /* For filters with several outputs, we will not be able to assume which - output is relevant for ff_outlink_frame_wanted() and - ff_outlink_set_status(). To be designed when needed. */ - av_assert0(parent->nb_outputs == 1); - - ff_framesync_preinit(fs); - fs->parent = parent; - fs->nb_in = nb_in; + if (fs->parent->nb_outputs == 1) { + if (!fs->on_eof) + fs->on_eof = default_on_eof; + if (!fs->on_miss) + fs->on_miss = default_on_miss; + } + av_assert0(fs->on_eof); + av_assert0(fs->on_miss); - fs->in = av_calloc(nb_in, sizeof(*fs->in)); + fs->in = av_calloc(fs->nb_in, sizeof(*fs->in)); if (!fs->in) return AVERROR(ENOMEM); return 0; } +int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) +{ + ff_framesync_preinit(fs); + fs->parent = parent; + fs->nb_in = nb_in; + return ff_framesync_postinit(fs); +} + static void framesync_eof(FFFrameSync *fs) { fs->eof = 1; fs->frame_ready = 0; - ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); + fs->on_eof(fs); } static void framesync_sync_level_update(FFFrameSync *fs) @@ -342,7 +354,7 @@ static int consume_from_fifos(FFFrameSync *fs) } } if (nb_miss) { - if (nb_miss == nb_active && !ff_outlink_frame_wanted(ctx->outputs[0])) + if (nb_miss == nb_active && !fs->on_miss(fs)) return FFERROR_NOT_READY; for (i = 0; i < fs->nb_in; i++) if (!fs->in[i].have_next && fs->in[i].state != STATE_EOF) @@ -422,3 +434,13 @@ int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame * } return 0; } + +static void default_on_eof(FFFrameSync *fs) +{ + ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); +} + +static int default_on_miss(FFFrameSync *fs) +{ + return ff_outlink_frame_wanted(fs->parent->outputs[0]); +} diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h index 233f50a0eb..1957396c7f 100644 --- a/libavfilter/framesync.h +++ b/libavfilter/framesync.h @@ -193,6 +193,19 @@ typedef struct FFFrameSync { */ int (*on_event)(struct FFFrameSync *fs); + /** + * Callback called when EOF is reached; can be NULL + * The default is to ff_outlink_set_status() on the single output. + */ + void (*on_eof)(struct FFFrameSync *fs); + + /** + * Callback called when no input can be produced to decide if input must + * be requested + * The default is ff_outlink_frame_wanted() on the singe output. + */ + int (*on_miss)(struct FFFrameSync *fs); + /** * Opaque pointer, not used by the API */ @@ -240,6 +253,21 @@ typedef struct FFFrameSync { */ void ff_framesync_preinit(FFFrameSync *fs); +/** + * Finish the initialization of a frame sync structure + * + * Use it in combination with ff_framesync_preinit() and set fields and + * options in between. + * + * ff_framesync_preinit(fs); + * fs->parent = parent; + * fs->nb_in = nb_in; + * fs->field = value; + * ret = ff_framesync_postinit(fs); + * if (ret < 0) ... + */ +int ff_framesync_postinit(FFFrameSync *fs); + /** * Initialize a frame sync structure. * -- 2.39.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2023-06-26 20:09 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-06-26 20:09 Nicolas George [this message] 2023-06-26 20:09 ` [FFmpeg-devel] [WIP] [PATCH 2/2] lavfi/vf_framematch: add filter to output matching synchronized frames Nicolas George
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230626200932.1329118-1-george@nsup.org \ --to=george@nsup.org \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git