FFmpeg
framesync.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Nicolas George
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/opt.h"
23 #include "avfilter.h"
24 #include "filters.h"
25 #include "framesync.h"
26 #include "internal.h"
27 
28 #define OFFSET(member) offsetof(FFFrameSync, member)
29 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
30 
31 static const char *framesync_name(void *ptr)
32 {
33  return "framesync";
34 }
35 
36 static const AVOption framesync_options[] = {
37  { "eof_action", "Action to take when encountering EOF from secondary input ",
38  OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
39  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
40  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
41  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
42  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
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  { NULL }
46 };
47 static const AVClass framesync_class = {
49  .class_name = "framesync",
50  .item_name = framesync_name,
51  .category = AV_CLASS_CATEGORY_FILTER,
52  .option = framesync_options,
53  .parent_log_context_offset = OFFSET(parent),
54 };
55 
56 enum {
60 };
61 
62 static int consume_from_fifos(FFFrameSync *fs);
63 
65 {
66  return &framesync_class;
67 }
68 
70 {
71  if (fs->class)
72  return;
73  fs->class = &framesync_class;
75 }
76 
77 int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
78 {
79  /* For filters with several outputs, we will not be able to assume which
80  output is relevant for ff_outlink_frame_wanted() and
81  ff_outlink_set_status(). To be designed when needed. */
82  av_assert0(parent->nb_outputs == 1);
83 
85  fs->parent = parent;
86  fs->nb_in = nb_in;
87 
88  fs->in = av_calloc(nb_in, sizeof(*fs->in));
89  if (!fs->in)
90  return AVERROR(ENOMEM);
91  return 0;
92 }
93 
95 {
96  fs->eof = 1;
97  fs->frame_ready = 0;
98  ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE);
99 }
100 
102 {
103  unsigned i, level = 0;
104 
105  for (i = 0; i < fs->nb_in; i++)
106  if (fs->in[i].state != STATE_EOF)
107  level = FFMAX(level, fs->in[i].sync);
108  av_assert0(level <= fs->sync_level);
109  if (level < fs->sync_level)
110  av_log(fs, AV_LOG_VERBOSE, "Sync level %u\n", level);
111  if (level)
112  fs->sync_level = level;
113  else
114  framesync_eof(fs);
115 }
116 
118 {
119  unsigned i;
120  int64_t gcd, lcm;
121 
122  if (!fs->opt_repeatlast || fs->opt_eof_action == EOF_ACTION_PASS) {
123  fs->opt_repeatlast = 0;
124  fs->opt_eof_action = EOF_ACTION_PASS;
125  }
126  if (fs->opt_shortest || fs->opt_eof_action == EOF_ACTION_ENDALL) {
127  fs->opt_shortest = 1;
128  fs->opt_eof_action = EOF_ACTION_ENDALL;
129  }
130  if (!fs->opt_repeatlast) {
131  for (i = 1; i < fs->nb_in; i++) {
132  fs->in[i].after = EXT_NULL;
133  fs->in[i].sync = 0;
134  }
135  }
136  if (fs->opt_shortest) {
137  for (i = 0; i < fs->nb_in; i++)
138  fs->in[i].after = EXT_STOP;
139  }
140 
141  if (!fs->time_base.num) {
142  for (i = 0; i < fs->nb_in; i++) {
143  if (fs->in[i].sync) {
144  if (fs->time_base.num) {
145  gcd = av_gcd(fs->time_base.den, fs->in[i].time_base.den);
146  lcm = (fs->time_base.den / gcd) * fs->in[i].time_base.den;
147  if (lcm < AV_TIME_BASE / 2) {
148  fs->time_base.den = lcm;
149  fs->time_base.num = av_gcd(fs->time_base.num,
150  fs->in[i].time_base.num);
151  } else {
152  fs->time_base.num = 1;
153  fs->time_base.den = AV_TIME_BASE;
154  break;
155  }
156  } else {
157  fs->time_base = fs->in[i].time_base;
158  }
159  }
160  }
161  if (!fs->time_base.num) {
162  av_log(fs, AV_LOG_ERROR, "Impossible to set time base\n");
163  return AVERROR(EINVAL);
164  }
165  av_log(fs, AV_LOG_VERBOSE, "Selected %d/%d time base\n",
166  fs->time_base.num, fs->time_base.den);
167  }
168 
169  for (i = 0; i < fs->nb_in; i++)
170  fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE;
171  fs->sync_level = UINT_MAX;
173 
174  return 0;
175 }
176 
178 {
179  unsigned i;
180  int64_t pts;
181  int ret;
182 
183  while (!(fs->frame_ready || fs->eof)) {
185  if (ret <= 0)
186  return ret;
187 
188  pts = INT64_MAX;
189  for (i = 0; i < fs->nb_in; i++)
190  if (fs->in[i].have_next && fs->in[i].pts_next < pts)
191  pts = fs->in[i].pts_next;
192  if (pts == INT64_MAX) {
193  framesync_eof(fs);
194  break;
195  }
196  for (i = 0; i < fs->nb_in; i++) {
197  if (fs->in[i].pts_next == pts ||
198  (fs->in[i].before == EXT_INFINITY &&
199  fs->in[i].state == STATE_BOF)) {
200  av_frame_free(&fs->in[i].frame);
201  fs->in[i].frame = fs->in[i].frame_next;
202  fs->in[i].pts = fs->in[i].pts_next;
203  fs->in[i].frame_next = NULL;
204  fs->in[i].pts_next = AV_NOPTS_VALUE;
205  fs->in[i].have_next = 0;
206  fs->in[i].state = fs->in[i].frame ? STATE_RUN : STATE_EOF;
207  if (fs->in[i].sync == fs->sync_level && fs->in[i].frame)
208  fs->frame_ready = 1;
209  if (fs->in[i].state == STATE_EOF &&
210  fs->in[i].after == EXT_STOP)
211  framesync_eof(fs);
212  }
213  }
214  if (fs->frame_ready)
215  for (i = 0; i < fs->nb_in; i++)
216  if ((fs->in[i].state == STATE_BOF &&
217  fs->in[i].before == EXT_STOP))
218  fs->frame_ready = 0;
219  fs->pts = pts;
220  }
221  return 0;
222 }
223 
224 static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in,
225  int64_t pts)
226 {
227  /* Possible enhancement: use the link's frame rate */
228  return pts + 1;
229 }
230 
232 {
233  int64_t pts;
234 
235  av_assert0(!fs->in[in].have_next);
236  av_assert0(frame);
237  pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base);
238  frame->pts = pts;
239  fs->in[in].frame_next = frame;
240  fs->in[in].pts_next = pts;
241  fs->in[in].have_next = 1;
242 }
243 
244 static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
245 {
246  av_assert0(!fs->in[in].have_next);
247  pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY
248  ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts);
249  fs->in[in].sync = 0;
251  fs->in[in].frame_next = NULL;
252  fs->in[in].pts_next = pts;
253  fs->in[in].have_next = 1;
254 }
255 
256 int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
257  unsigned get)
258 {
259  AVFrame *frame;
260  unsigned need_copy = 0, i;
261  int64_t pts_next;
262  int ret;
263 
264  if (!fs->in[in].frame) {
265  *rframe = NULL;
266  return 0;
267  }
268  frame = fs->in[in].frame;
269  if (get) {
270  /* Find out if we need to copy the frame: is there another sync
271  stream, and do we know if its current frame will outlast this one? */
272  pts_next = fs->in[in].have_next ? fs->in[in].pts_next : INT64_MAX;
273  for (i = 0; i < fs->nb_in && !need_copy; i++)
274  if (i != in && fs->in[i].sync &&
275  (!fs->in[i].have_next || fs->in[i].pts_next < pts_next))
276  need_copy = 1;
277  if (need_copy) {
278  if (!(frame = av_frame_clone(frame)))
279  return AVERROR(ENOMEM);
280  if ((ret = av_frame_make_writable(frame)) < 0) {
282  return ret;
283  }
284  } else {
285  fs->in[in].frame = NULL;
286  }
287  fs->frame_ready = 0;
288  }
289  *rframe = frame;
290  return 0;
291 }
292 
294 {
295  unsigned i;
296 
297  for (i = 0; i < fs->nb_in; i++) {
298  av_frame_free(&fs->in[i].frame);
299  av_frame_free(&fs->in[i].frame_next);
300  }
301 
302  av_freep(&fs->in);
303 }
304 
306 {
307  AVFilterContext *ctx = fs->parent;
308  AVFrame *frame = NULL;
309  int64_t pts;
310  unsigned i, nb_active, nb_miss;
311  int ret, status;
312 
313  nb_active = nb_miss = 0;
314  for (i = 0; i < fs->nb_in; i++) {
315  if (fs->in[i].have_next || fs->in[i].state == STATE_EOF)
316  continue;
317  nb_active++;
318  ret = ff_inlink_consume_frame(ctx->inputs[i], &frame);
319  if (ret < 0)
320  return ret;
321  if (ret) {
322  av_assert0(frame);
324  } else {
326  if (ret > 0) {
328  } else if (!ret) {
329  nb_miss++;
330  }
331  }
332  }
333  if (nb_miss) {
334  if (nb_miss == nb_active && !ff_outlink_frame_wanted(ctx->outputs[0]))
335  return FFERROR_NOT_READY;
336  for (i = 0; i < fs->nb_in; i++)
337  if (!fs->in[i].have_next && fs->in[i].state != STATE_EOF)
338  ff_inlink_request_frame(ctx->inputs[i]);
339  return 0;
340  }
341  return 1;
342 }
343 
345 {
346  int ret;
347 
349  if (ret < 0)
350  return ret;
351  if (fs->eof || !fs->frame_ready)
352  return 0;
353  ret = fs->on_event(fs);
354  if (ret < 0)
355  return ret;
356  fs->frame_ready = 0;
357 
358  return 0;
359 }
360 
362 {
363  int ret;
364 
365  ret = ff_framesync_init(fs, parent, 2);
366  if (ret < 0)
367  return ret;
368  fs->in[0].time_base = parent->inputs[0]->time_base;
369  fs->in[1].time_base = parent->inputs[1]->time_base;
370  fs->in[0].sync = 2;
371  fs->in[0].before = EXT_STOP;
372  fs->in[0].after = EXT_INFINITY;
373  fs->in[1].sync = 1;
374  fs->in[1].before = EXT_NULL;
375  fs->in[1].after = EXT_INFINITY;
376  return 0;
377 }
378 
380 {
381  AVFilterContext *ctx = fs->parent;
382  AVFrame *mainpic = NULL, *secondpic = NULL;
383  int ret;
384 
385  if ((ret = ff_framesync_get_frame(fs, 0, &mainpic, 1)) < 0 ||
386  (ret = ff_framesync_get_frame(fs, 1, &secondpic, 0)) < 0) {
387  av_frame_free(&mainpic);
388  return ret;
389  }
390  av_assert0(mainpic);
391  mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base);
392  if (ctx->is_disabled)
393  secondpic = NULL;
394  *f0 = mainpic;
395  *f1 = secondpic;
396  return 0;
397 }
398 
400 {
401  int ret;
402 
403  ret = ff_framesync_dualinput_get(fs, f0, f1);
404  if (ret < 0)
405  return ret;
406  ret = ff_inlink_make_frame_writable(fs->parent->inputs[0], f0);
407  if (ret < 0) {
408  av_frame_free(f0);
409  *f1 = NULL;
410  return ret;
411  }
412  return 0;
413 }
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:117
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
level
uint8_t level
Definition: svq3.c:207
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1305
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:293
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
consume_from_fifos
static int consume_from_fifos(FFFrameSync *fs)
Definition: framesync.c:305
ff_framesync_get_frame
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:256
AVClass::version
int version
LIBAVUTIL_VERSION with which this structure was created.
Definition: log.h:93
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
av_frame_make_writable
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition: frame.c:611
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
ff_framesync_get_class
const AVClass * ff_framesync_get_class(void)
Get the class for the framesync object.
Definition: framesync.c:64
AVOption
AVOption.
Definition: opt.h:246
EOF_ACTION_ENDALL
@ EOF_ACTION_ENDALL
Definition: framesync.h:28
AVFilterContext::nb_outputs
unsigned nb_outputs
number of output pads
Definition: avfilter.h:351
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
FFFrameSync
Frame sync structure.
Definition: framesync.h:146
EXT_INFINITY
@ EXT_INFINITY
Extend the frame to infinity.
Definition: framesync.h:75
av_gcd
int64_t av_gcd(int64_t a, int64_t b)
Compute the greatest common divisor of two integer operands.
Definition: mathematics.c:37
framesync_advance
static int framesync_advance(FFFrameSync *fs)
Definition: framesync.c:177
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1481
EXT_STOP
@ EXT_STOP
Completely stop all streams with this one.
Definition: framesync.h:65
framesync_inject_frame
static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame)
Definition: framesync.c:231
EXT_NULL
@ EXT_NULL
Ignore this stream and continue processing the other ones.
Definition: framesync.h:70
framesync_pts_extrapolate
static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, int64_t pts)
Definition: framesync.c:224
pts
static int64_t pts
Definition: transcode_aac.c:647
OFFSET
#define OFFSET(member)
Definition: framesync.c:28
STATE_RUN
@ STATE_RUN
Definition: framesync.c:58
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
FLAGS
#define FLAGS
Definition: framesync.c:29
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1607
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
get
static void get(uint8_t *pixels, int stride, int16_t *block)
Definition: proresenc_anatoliy.c:304
filters.h
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
EOF_ACTION_PASS
@ EOF_ACTION_PASS
Definition: framesync.h:29
ff_inlink_make_frame_writable
int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
Make sure a frame is writable.
Definition: avfilter.c:1525
if
if(ret)
Definition: filter_design.txt:179
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:259
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
framesync_inject_status
static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
Definition: framesync.c:244
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1436
AV_CLASS_CATEGORY_FILTER
@ AV_CLASS_CATEGORY_FILTER
Definition: log.h:37
framesync_sync_level_update
static void framesync_sync_level_update(FFFrameSync *fs)
Definition: framesync.c:101
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:361
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
framesync_options
static const AVOption framesync_options[]
Definition: framesync.c:36
internal.h
in
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
Definition: audio_convert.c:326
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
framesync_eof
static void framesync_eof(FFFrameSync *fs)
Definition: framesync.c:94
framesync_class
static const AVClass framesync_class
Definition: framesync.c:47
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
ff_framesync_init
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
Definition: framesync.c:77
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
framesync.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
framesync_name
static const char * framesync_name(void *ptr)
Definition: framesync.c:31
STATE_BOF
@ STATE_BOF
Definition: framesync.c:57
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
STATE_EOF
@ STATE_EOF
Definition: framesync.c:59
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:344
ff_framesync_dualinput_get
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Definition: framesync.c:379
ff_framesync_dualinput_get_writable
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.
Definition: framesync.c:399
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
ff_framesync_preinit
void ff_framesync_preinit(FFFrameSync *fs)
Pre-initialize a frame sync structure.
Definition: framesync.c:69