FFmpeg
Loading...
Searching...
No Matches
f_interleave.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Stefano Sabatini
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
8 * License 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * audio and video interleaver
24 */
25
26#include "config_components.h"
27
28#include "libavutil/avassert.h"
29#include "libavutil/avstring.h"
30#include "libavutil/opt.h"
31
32#include "avfilter.h"
33#include "filters.h"
34#include "audio.h"
35#include "video.h"
36
43
44#define DURATION_LONGEST 0
45#define DURATION_SHORTEST 1
46#define DURATION_FIRST 2
47
48#define OFFSET(x) offsetof(InterleaveContext, x)
49
50#define DEFINE_OPTIONS(filt_name, flags_) \
51static const AVOption filt_name##_options[] = { \
52 { "nb_inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, .flags = flags_ }, \
53 { "n", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, .flags = flags_ }, \
54 { "duration", "how to determine the end-of-stream", \
55 OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0, 2, flags_, .unit = "duration" }, \
56 { "longest", "Duration of longest input", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST }, 0, 0, flags_, .unit = "duration" }, \
57 { "shortest", "Duration of shortest input", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, 0, 0, flags_, .unit = "duration" }, \
58 { "first", "Duration of first input", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST }, 0, 0, flags_, .unit = "duration" }, \
59 { NULL } \
60}
61
63{
64 AVFilterLink *outlink = ctx->outputs[0];
65 InterleaveContext *s = ctx->priv;
66 int64_t q_pts, pts = INT64_MAX;
67 int i, nb_eofs = 0, input_idx = -1;
68 int first_eof = 0;
69 int64_t rpts;
70 int status;
71 int nb_inputs_with_frames = 0;
72
74
75 for (i = 0; i < ctx->nb_inputs; i++) {
76 int is_eof = !!ff_inlink_acknowledge_status(ctx->inputs[i], &status, &rpts);
77
78 nb_eofs += is_eof;
79 if (i == 0)
80 first_eof = is_eof;
81 }
82
83 if ((nb_eofs > 0 && s->duration_mode == DURATION_SHORTEST) ||
84 (nb_eofs == ctx->nb_inputs && s->duration_mode == DURATION_LONGEST) ||
85 (first_eof && s->duration_mode == DURATION_FIRST)) {
86 ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
87 return 0;
88 }
89
90 for (i = 0; i < ctx->nb_inputs; i++) {
91 if (!ff_inlink_queued_frames(ctx->inputs[i]))
92 continue;
93 nb_inputs_with_frames++;
94 }
95
96 if (nb_inputs_with_frames >= ctx->nb_inputs - nb_eofs) {
97 for (i = 0; i < ctx->nb_inputs; i++) {
99
100 if (ff_inlink_queued_frames(ctx->inputs[i]) == 0)
101 continue;
102
103 frame = ff_inlink_peek_frame(ctx->inputs[i], 0);
104 if (frame->pts == AV_NOPTS_VALUE) {
105 int ret;
106
108 "NOPTS value for input frame cannot be accepted, frame discarded\n");
109 ret = ff_inlink_consume_frame(ctx->inputs[i], &frame);
110 if (ret < 0)
111 return ret;
113 return AVERROR_INVALIDDATA;
114 }
115
116 q_pts = av_rescale_q(frame->pts, ctx->inputs[i]->time_base, AV_TIME_BASE_Q);
117 if (q_pts < pts) {
118 pts = q_pts;
119 input_idx = i;
120 }
121 }
122
123 if (input_idx >= 0) {
124 AVFrame *frame;
125 int ret;
126
127 ret = ff_inlink_consume_frame(ctx->inputs[input_idx], &frame);
128 if (ret < 0)
129 return ret;
130
131 frame->pts = s->pts = pts;
132 return ff_filter_frame(outlink, frame);
133 }
134 }
135
136 for (i = 0; i < ctx->nb_inputs; i++) {
137 if (ff_inlink_queued_frames(ctx->inputs[i]))
138 continue;
139 if (ff_outlink_frame_wanted(outlink) &&
140 !ff_outlink_get_status(ctx->inputs[i])) {
141 ff_inlink_request_frame(ctx->inputs[i]);
142 return 0;
143 }
144 }
145
146 if (i == ctx->nb_inputs - nb_eofs && ff_outlink_frame_wanted(outlink)) {
148 return 0;
149 }
150
151 return FFERROR_NOT_READY;
152}
153
155{
156 InterleaveContext *s = ctx->priv;
157 const AVFilterPad *outpad = &ctx->filter->outputs[0];
158 int i, ret;
159
160 for (i = 0; i < s->nb_inputs; i++) {
161 AVFilterPad inpad = { 0 };
162
163 inpad.name = av_asprintf("input%d", i);
164 if (!inpad.name)
165 return AVERROR(ENOMEM);
166 inpad.type = outpad->type;
167
168 switch (outpad->type) {
173 default:
174 av_assert0(0);
175 }
176 if ((ret = ff_append_inpad_free_name(ctx, &inpad)) < 0)
177 return ret;
178 }
179
180 return 0;
181}
182
183static int config_output(AVFilterLink *outlink)
184{
185 FilterLink *l = ff_filter_link(outlink);
186 AVFilterContext *ctx = outlink->src;
187 AVFilterLink *inlink0 = ctx->inputs[0];
188 int i;
189
190 if (outlink->type == AVMEDIA_TYPE_VIDEO) {
191 outlink->time_base = AV_TIME_BASE_Q;
192 outlink->w = inlink0->w;
193 outlink->h = inlink0->h;
194 outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
195 outlink->format = inlink0->format;
196 l->frame_rate = (AVRational) {1, 0};
197 for (i = 1; i < ctx->nb_inputs; i++) {
198 AVFilterLink *inlink = ctx->inputs[i];
199
200 if (outlink->w != inlink->w ||
201 outlink->h != inlink->h ||
202 outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num ||
203 outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) {
204 av_log(ctx, AV_LOG_ERROR, "Parameters for input link %s "
205 "(size %dx%d, SAR %d:%d) do not match the corresponding "
206 "output link parameters (%dx%d, SAR %d:%d)\n",
207 ctx->input_pads[i].name, inlink->w, inlink->h,
208 inlink->sample_aspect_ratio.num,
209 inlink->sample_aspect_ratio.den,
210 outlink->w, outlink->h,
211 outlink->sample_aspect_ratio.num,
212 outlink->sample_aspect_ratio.den);
213 return AVERROR(EINVAL);
214 }
215 }
216 }
217 return 0;
218}
219
220#if CONFIG_INTERLEAVE_FILTER
221
224
225static const AVFilterPad interleave_outputs[] = {
226 {
227 .name = "default",
228 .type = AVMEDIA_TYPE_VIDEO,
229 .config_props = config_output,
230 },
231};
232
234 .p.name = "interleave",
235 .p.description = NULL_IF_CONFIG_SMALL("Temporally interleave video inputs."),
236 .p.priv_class = &interleave_class,
238 .priv_size = sizeof(InterleaveContext),
239 .init = init,
241 FILTER_OUTPUTS(interleave_outputs),
242};
243
244#endif
245
246#if CONFIG_AINTERLEAVE_FILTER
247
249AVFILTER_DEFINE_CLASS(ainterleave);
250
251static const AVFilterPad ainterleave_outputs[] = {
252 {
253 .name = "default",
254 .type = AVMEDIA_TYPE_AUDIO,
255 .config_props = config_output,
256 },
257};
258
260 .p.name = "ainterleave",
261 .p.description = NULL_IF_CONFIG_SMALL("Temporally interleave audio inputs."),
262 .p.priv_class = &ainterleave_class,
264 .priv_size = sizeof(InterleaveContext),
265 .init = init,
267 FILTER_OUTPUTS(ainterleave_outputs),
268};
269
270#endif
#define DURATION_SHORTEST
Definition af_amix.c:52
#define DURATION_FIRST
Definition af_amix.c:53
#define DURATION_LONGEST
Definition af_amix.c:51
const FFFilter ff_vf_interleave
const FFFilter ff_af_ainterleave
AVFrame * ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
get_audio_buffer() handler for filters which simply pass audio along
Definition audio.c:41
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition avfilter.c:132
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
Definition avfilter.c:1648
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:1467
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
Definition avfilter.c:1690
size_t ff_inlink_queued_frames(AVFilterLink *link)
Get the number of frames available on the link.
Definition avfilter.c:1483
AVFrame * ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
Access a frame in the link fifo without consuming it.
Definition avfilter.c:1561
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition avfilter.c:229
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:1520
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition avfilter.c:1623
Main libavfilter public API header.
char * av_asprintf(const char *fmt,...)
Definition avstring.c:115
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
long long int64_t
Definition coverity.c:34
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define DEFINE_OPTIONS(filt_name, flags_)
static int activate(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
#define AV_OPT_FLAG_FILTERING_PARAM
A generic parameter which can be set by the user for filtering.
Definition opt.h:380
#define AV_OPT_FLAG_AUDIO_PARAM
Definition opt.h:356
#define AV_OPT_FLAG_VIDEO_PARAM
Definition opt.h:357
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition avfilter.h:155
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_OUTPUTS(array)
Definition filters.h:265
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:629
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
Definition filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition filters.h:652
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
AVOptions.
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
AVFrame *(* audio)(AVFilterLink *link, int nb_samples)
Definition filters.h:82
enum AVMediaType type
AVFilterPad type.
Definition filters.h:51
AVFrame *(* video)(AVFilterLink *link, int w, int h)
Definition filters.h:81
union AVFilterPad::@363170257351226013155122005037023043242205350137 get_buffer
Callback functions to get a video/audio buffers.
const char * name
Pad name.
Definition filters.h:46
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
static int64_t pts
static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dst_linesize, int src_linesize, enum FilterMode mode, int swap)
Definition vf_il.c:113
AVFrame * ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
Definition video.c:44