[FFmpeg-devel] [PATCH 1/2] lavfi/framesync2: add dualinput helper functions.
Nicolas George
george at nsup.org
Sun Jul 30 16:32:40 EEST 2017
Signed-off-by: Nicolas George <george at nsup.org>
---
libavfilter/framesync2.c | 78 +++++++++++++++++++++++++++++++++++++-----------
libavfilter/framesync2.h | 20 +++++++++++++
2 files changed, 80 insertions(+), 18 deletions(-)
Ok, this one actually works.
There was a bug in framesync2 triggered by certain time bases, fixed.
When pushing, I will add another commit to reorder the functions and get rid
of the forward declaration.
Next steps: update blend, libvmaf, lut3d, paletteuse, psnr, ssim;
make shortest ans cie. options of the framesync context and make it a child
context of the filters, so that all options are always available.
diff --git a/libavfilter/framesync2.c b/libavfilter/framesync2.c
index 0e9f6f210c..02c41e7203 100644
--- a/libavfilter/framesync2.c
+++ b/libavfilter/framesync2.c
@@ -46,6 +46,8 @@ enum {
STATE_EOF,
};
+static int consume_from_fifos(FFFrameSync *fs);
+
int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
{
/* For filters with several outputs, we will not be able to assume which
@@ -127,26 +129,16 @@ int ff_framesync2_configure(FFFrameSync *fs)
return 0;
}
-static void framesync_advance(FFFrameSync *fs)
+static int framesync_advance(FFFrameSync *fs)
{
- int latest;
unsigned i;
int64_t pts;
+ int ret;
- if (fs->eof)
- return;
- while (!fs->frame_ready) {
- latest = -1;
- for (i = 0; i < fs->nb_in; i++) {
- if (!fs->in[i].have_next) {
- if (latest < 0 || fs->in[i].pts < fs->in[latest].pts)
- latest = i;
- }
- }
- if (latest >= 0) {
- fs->in_request = latest;
- break;
- }
+ while (!(fs->frame_ready || fs->eof)) {
+ ret = consume_from_fifos(fs);
+ if (ret <= 0)
+ return ret;
pts = fs->in[0].pts_next;
for (i = 1; i < fs->nb_in; i++)
@@ -181,6 +173,7 @@ static void framesync_advance(FFFrameSync *fs)
fs->frame_ready = 0;
fs->pts = pts;
}
+ return 0;
}
static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in,
@@ -264,7 +257,7 @@ void ff_framesync2_uninit(FFFrameSync *fs)
av_freep(&fs->in);
}
-int ff_framesync2_activate(FFFrameSync *fs)
+static int consume_from_fifos(FFFrameSync *fs)
{
AVFilterContext *ctx = fs->parent;
AVFrame *frame = NULL;
@@ -300,8 +293,16 @@ int ff_framesync2_activate(FFFrameSync *fs)
ff_inlink_request_frame(ctx->inputs[i]);
return 0;
}
+ return 1;
+}
- framesync_advance(fs);
+int ff_framesync2_activate(FFFrameSync *fs)
+{
+ int ret;
+
+ ret = framesync_advance(fs);
+ if (ret < 0)
+ return ret;
if (fs->eof || !fs->frame_ready)
return 0;
ret = fs->on_event(fs);
@@ -311,3 +312,44 @@ int ff_framesync2_activate(FFFrameSync *fs)
return 0;
}
+
+int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
+{
+ int ret;
+
+ ret = ff_framesync2_init(fs, parent, 2);
+ if (ret < 0)
+ return ret;
+ fs->in[0].time_base = parent->inputs[0]->time_base;
+ fs->in[1].time_base = parent->inputs[1]->time_base;
+ fs->in[0].sync = 2;
+ fs->in[0].before = EXT_STOP;
+ fs->in[0].after = EXT_INFINITY;
+ fs->in[1].sync = 1;
+ fs->in[1].before = EXT_NULL;
+ fs->in[1].after = EXT_INFINITY;
+ return 0;
+}
+
+int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
+{
+ AVFilterContext *ctx = fs->parent;
+ AVFrame *mainpic = NULL, *secondpic = NULL;
+ int ret = 0;
+
+ if ((ret = ff_framesync2_get_frame(fs, 0, &mainpic, 1)) < 0 ||
+ (ret = ff_framesync2_get_frame(fs, 1, &secondpic, 0)) < 0) {
+ av_frame_free(&mainpic);
+ return ret;
+ }
+ ret = ff_inlink_make_frame_writable(ctx->inputs[0], &mainpic);
+ if (ret < 0)
+ return ret;
+ av_assert0(mainpic);
+ mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base);
+ if (ctx->is_disabled)
+ secondpic = NULL;
+ *f0 = mainpic;
+ *f1 = secondpic;
+ return 0;
+}
diff --git a/libavfilter/framesync2.h b/libavfilter/framesync2.h
index 2b37636ebb..d24bd7abe8 100644
--- a/libavfilter/framesync2.h
+++ b/libavfilter/framesync2.h
@@ -245,4 +245,24 @@ int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
*/
int ff_framesync2_activate(FFFrameSync *fs);
+/**
+ * Initialize a frame sync structure for dualinput.
+ *
+ * Compared to generic framesync, dualinput assumes the first input is the
+ * main one and the filtering is performed on it. The first input will be
+ * the only one with sync set and generic timeline support will just pass it
+ * unchanged when disabled.
+ *
+ * Equivalent to ff_framesync2_init(fs, parent, 2) then setting the time
+ * base, sync and ext modes on the inputs.
+ */
+int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent);
+
+/**
+ * @param f0 used to return the main frame
+ * @param f1 used to return the second frame, or NULL if disabled
+ * @return >=0 for success or AVERROR code
+ */
+int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
+
#endif /* AVFILTER_FRAMESYNC2_H */
--
2.13.2
More information about the ffmpeg-devel
mailing list