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 },
49 .class_name =
"framesync",
53 .parent_log_context_offset =
OFFSET(parent),
59 *iter = (
void *)(uintptr_t)
c;
112 for (
i = 0;
i <
fs->nb_in;
i++)
116 if (level < fs->sync_level)
129 fs->opt_repeatlast = 0;
133 fs->opt_shortest = 1;
136 if (!
fs->opt_repeatlast) {
137 for (
i = 1;
i <
fs->nb_in;
i++) {
142 if (
fs->opt_shortest) {
143 for (
i = 0;
i <
fs->nb_in;
i++)
147 if (!
fs->time_base.num) {
148 for (
i = 0;
i <
fs->nb_in;
i++) {
149 if (
fs->in[
i].sync) {
150 if (
fs->time_base.num) {
154 fs->time_base =
fs->in[
i].time_base;
158 if (!
fs->time_base.num) {
163 fs->time_base.num,
fs->time_base.den);
166 for (
i = 0;
i <
fs->nb_in;
i++)
168 fs->sync_level = UINT_MAX;
180 while (!(
fs->frame_ready ||
fs->eof)) {
186 for (
i = 0;
i <
fs->nb_in;
i++)
187 if (
fs->in[
i].have_next &&
fs->in[
i].pts_next <
pts)
189 if (
pts == INT64_MAX) {
193 for (
i = 0;
i <
fs->nb_in;
i++) {
194 if (
fs->in[
i].pts_next ==
pts ||
198 fs->in[
i].frame =
fs->in[
i].frame_next;
199 fs->in[
i].pts =
fs->in[
i].pts_next;
202 fs->in[
i].have_next = 0;
204 if (
fs->in[
i].sync ==
fs->sync_level &&
fs->in[
i].frame)
212 for (
i = 0;
i <
fs->nb_in;
i++)
238 fs->in[
in].have_next = 1;
250 fs->in[
in].have_next = 1;
257 unsigned need_copy = 0,
i;
261 if (!
fs->in[
in].frame) {
269 pts_next =
fs->in[
in].have_next ?
fs->in[
in].pts_next : INT64_MAX;
270 for (
i = 0;
i <
fs->nb_in && !need_copy;
i++)
271 if (
i !=
in &&
fs->in[
i].sync &&
272 (!
fs->in[
i].have_next ||
fs->in[
i].pts_next < pts_next))
294 for (
i = 0;
i <
fs->nb_in;
i++) {
307 unsigned i, nb_active, nb_miss;
310 nb_active = nb_miss = 0;
311 for (
i = 0;
i <
fs->nb_in;
i++) {
333 for (
i = 0;
i <
fs->nb_in;
i++)
348 if (
fs->eof || !
fs->frame_ready)
350 ret =
fs->on_event(
fs);
389 if (
ctx->is_disabled)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
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_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 fs(width, name, subs,...)
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.
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
static void framesync_eof(FFFrameSync *fs)
static int framesync_advance(FFFrameSync *fs)
static const AVOption framesync_options[]
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
static const AVClass framesync_class
static const char * framesync_name(void *ptr)
static int consume_from_fifos(FFFrameSync *fs)
static void framesync_sync_level_update(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.
static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
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_get_class(void)
Get the class for the framesync object.
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.
static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, int64_t pts)
const AVClass * ff_framesync_child_class_iterate(void **iter)
@ EXT_STOP
Completely stop all streams with this one.
@ EXT_NULL
Ignore this stream and continue processing the other ones.
@ EXT_INFINITY
Extend the frame to infinity.
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
#define AVERROR_EOF
End of file.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
#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(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
#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
common internal API header
@ AV_CLASS_CATEGORY_FILTER
static void get(uint8_t *pixels, int stride, int16_t *block)
Describe the class of an AVClass context structure.
int version
LIBAVUTIL_VERSION with which this structure was created.
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).