28#define OFFSET(member) offsetof(FFFrameSync, member)
29#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
37 {
"eof_action",
"Action to take when encountering EOF from secondary input ",
43 {
"shortest",
"force termination when the shortest input terminates",
OFFSET(opt_shortest),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
FLAGS },
44 {
"repeatlast",
"extend last frame of secondary streams beyond EOF",
OFFSET(opt_repeatlast),
AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1,
FLAGS },
45 {
"ts_sync_mode",
"How strictly to sync streams based on secondary input timestamps",
48 {
"default",
"Frame from secondary input with the nearest lower or equal timestamp to the primary input frame",
50 {
"nearest",
"Frame from secondary input with the absolute nearest timestamp to the primary input frame",
56 .class_name =
"framesync",
60 .parent_log_context_offset =
OFFSET(parent),
66 *iter = (
void *)(uintptr_t)
c;
117 for (
i = 0;
i <
fs->nb_in;
i++)
124 for (
i = 0;
i <
fs->nb_in;
i++) {
126 fs->in[
i].ts_mode =
fs->opt_ts_sync_mode;
142 fs->opt_repeatlast = 0;
146 fs->opt_shortest = 1;
149 if (!
fs->opt_repeatlast) {
150 for (
i = 1;
i <
fs->nb_in;
i++) {
155 if (
fs->opt_shortest) {
156 for (
i = 0;
i <
fs->nb_in;
i++)
160 if (!
fs->time_base.num) {
161 for (
i = 0;
i <
fs->nb_in;
i++) {
162 if (
fs->in[
i].sync) {
163 if (
fs->time_base.num) {
167 fs->time_base =
fs->in[
i].time_base;
171 if (!
fs->time_base.num) {
176 fs->time_base.num,
fs->time_base.den);
179 for (
i = 0;
i <
fs->nb_in;
i++)
181 fs->sync_level = UINT_MAX;
193 while (!(
fs->frame_ready ||
fs->eof)) {
199 for (
i = 0;
i <
fs->nb_in;
i++)
200 if (
fs->in[
i].have_next &&
fs->in[
i].pts_next <
pts)
202 if (
pts == INT64_MAX) {
206 for (
i = 0;
i <
fs->nb_in;
i++) {
207 if (
fs->in[
i].pts_next ==
pts ||
209 fs->in[
i].have_next &&
215 fs->in[
i].frame =
fs->in[
i].frame_next;
216 fs->in[
i].pts =
fs->in[
i].pts_next;
219 fs->in[
i].have_next = 0;
221 if (
fs->in[
i].sync ==
fs->sync_level &&
fs->in[
i].frame)
229 for (
i = 0;
i <
fs->nb_in;
i++)
254 fs->in[in].pts_next =
pts;
255 fs->in[in].have_next = 1;
263 fs->in[in].frame_next =
NULL;
266 fs->in[in].have_next = 1;
273 unsigned need_copy = 0,
i;
276 if (!
fs->in[in].frame) {
284 pts_next =
fs->in[in].have_next ?
fs->in[in].pts_next : INT64_MAX;
285 for (
i = 0;
i <
fs->nb_in && !need_copy;
i++)
286 if (
i != in &&
fs->in[
i].sync &&
287 (!
fs->in[
i].have_next ||
fs->in[
i].pts_next < pts_next))
305 for (
i = 0;
i <
fs->nb_in;
i++) {
318 unsigned i, nb_active, nb_miss;
321 nb_active = nb_miss = 0;
322 for (
i = 0;
i <
fs->nb_in;
i++) {
344 for (
i = 0;
i <
fs->nb_in;
i++)
362 if (
fs->eof || !
fs->frame_ready)
364 ret =
fs->on_event(
fs);
403 if (
ctx->is_disabled)
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
Make sure a frame is writable.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
#define fs(width, name, subs,...)
static int framesync_advance(FFFrameSync *fs)
static const AVOption framesync_options[]
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
static int consume_from_fifos(FFFrameSync *fs)
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
const AVClass ff_framesync_class
static void framesync_sync_level_update(FFFrameSync *fs, int64_t eof_pts)
static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t eof_pts)
void ff_framesync_preinit(FFFrameSync *fs)
Pre-initialize a frame sync structure.
int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Same as ff_framesync_dualinput_get(), but make sure that f0 is writable.
static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame)
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
const AVClass * ff_framesync_child_class_iterate(void **iter)
static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, int64_t pts)
static const char * framesync_name(void *ptr)
static void framesync_eof(FFFrameSync *fs, int64_t pts)
@ EXT_INFINITY
Extend the frame to infinity.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AVERROR_EOF
End of file.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_ROUND_PASS_MINMAX
Flag telling rescaling functions to pass INT64_MIN/MAX through unchanged, avoiding special cases for ...
@ AV_ROUND_NEAR_INF
Round to nearest and halfway cases away from zero.
#define AV_NOPTS_VALUE
Undefined timestamp value.
#define AV_TIME_BASE
Internal time base represented as integer.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
#define LIBAVUTIL_VERSION_INT
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
@ AV_CLASS_CATEGORY_FILTER
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
@ TS_DEFAULT
Sync to packets from secondary input with the nearest, lower or equal timestamp to the packet event o...
@ TS_NEAREST
Sync to packets from secondary input with the absolute nearest timestamp to the packet event one.
@ EXT_STOP
Completely stop all streams with this one.
@ EXT_NULL
Ignore this stream and continue processing the other ones.
static void get(const uint8_t *pixels, int stride, int16_t *block)
Describe the class of an AVClass context structure.
AVFilterLink ** inputs
array of pointers to input links
unsigned nb_outputs
number of output pads
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).