Coverage Report

Created: 2026-09-14 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/bsf/packetsync.h
Line
Count
Source
1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public License
6
 * as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#ifndef AVCODEC_BSF_PACKETSYNC_H
20
#define AVCODEC_BSF_PACKETSYNC_H
21
22
#include <stdint.h>
23
24
#include "libavutil/log.h"
25
26
#include "libavcodec/bsf.h"
27
#include "libavcodec/packet.h"
28
29
enum EOFAction {
30
    EOF_ACTION_ENDALL,
31
    EOF_ACTION_PASS
32
};
33
34
/**
35
 * This API is intended as a helper for filters that have several video
36
 * input and need to combine them somehow. If the inputs have different or
37
 * variable frame rate, getting the input packets to match requires a rather
38
 * complex logic and a few user-tunable options.
39
 *
40
 * In this API, when a set of synchronized input packets is ready to be
41
 * processed is called a packet event. packet event can be generated in
42
 * response to input packets on any or all inputs and the handling of
43
 * situations where some stream extend beyond the beginning or the end of
44
 * others can be configured.
45
 *
46
 * The basic working of this API is the following: set the on_event
47
 * callback, then call ff_packetsync_activate() from the filter's activate
48
 * callback.
49
 */
50
51
/**
52
 * Stream extrapolation mode
53
 *
54
 * Describe how the packets of a stream are extrapolated before the first one
55
 * and after EOF to keep sync with possibly longer other streams.
56
 */
57
enum FFPacketSyncExtMode {
58
59
    /**
60
     * Completely stop all streams with this one.
61
     */
62
    EXT_STOP,
63
64
    /**
65
     * Ignore this stream and continue processing the other ones.
66
     */
67
    EXT_NULL,
68
};
69
70
/**
71
 * Timestamp synchronization mode
72
 *
73
 * Describe how the packets of a stream are synchronized based on timestamp
74
 * distance.
75
 */
76
enum FFPacketTSSyncMode {
77
78
    /**
79
     * Sync to packets from secondary input with the nearest, lower or equal
80
     * timestamp to the packet event one.
81
     */
82
    TS_DEFAULT,
83
84
    /**
85
     * Sync to packets from secondary input with the absolute nearest timestamp
86
     * to the packet event one.
87
     */
88
    TS_NEAREST,
89
};
90
91
/**
92
 * Input stream structure
93
 */
94
typedef struct FFPacketSyncIn {
95
96
    /**
97
     * Extrapolation mode for timestamps before the first packet
98
     */
99
    enum FFPacketSyncExtMode before;
100
101
    /**
102
     * Extrapolation mode for timestamps after the last packet
103
     */
104
    enum FFPacketSyncExtMode after;
105
106
    /**
107
     * Time base for the incoming packets
108
     */
109
    AVRational time_base;
110
111
    /**
112
     * Current packet, may be NULL before the first one or after EOF
113
     */
114
    AVPacket *pkt;
115
116
    /**
117
     * Next packet, for internal use
118
     */
119
    AVPacket *pkt_next;
120
121
    /**
122
     * PTS of the current packet
123
     */
124
    int64_t pts;
125
126
    /**
127
     * PTS of the next packet, for internal use
128
     */
129
    int64_t pts_next;
130
131
    /**
132
     * Boolean flagging the next packet, for internal use
133
     */
134
    uint8_t have_next;
135
136
    /**
137
     * State: before first, in stream or after EOF, for internal use
138
     */
139
    uint8_t state;
140
141
    /**
142
     * Synchronization level: packets on input at the highest sync level will
143
     * generate output packet events.
144
     *
145
     * For example, if inputs #0 and #1 have sync level 2 and input #2 has
146
     * sync level 1, then a packet on either input #0 or #1 will generate a
147
     * packet event, but not a packet on input #2 until both inputs #0 and #1
148
     * have reached EOF.
149
     *
150
     * If sync is 0, no packet event will be generated.
151
     */
152
    unsigned sync;
153
154
    enum FFPacketTSSyncMode ts_mode;
155
} FFPacketSyncIn;
156
157
/**
158
 * Packet sync structure.
159
 */
160
typedef struct FFPacketSync {
161
    const AVClass *class;
162
163
    /**
164
     * Parent filter context.
165
     */
166
    AVBitStreamFilterContext *parent;
167
168
    /**
169
     * Number of input streams
170
     */
171
    unsigned nb_in;
172
173
    /**
174
     * Time base for the output events
175
     */
176
    AVRational time_base;
177
178
    /**
179
     * Timestamp of the current event
180
     */
181
    int64_t pts;
182
183
    /**
184
     * Callback called when a packet event is ready
185
     */
186
    int (*on_event)(struct FFPacketSync *fs);
187
188
    /**
189
     * Opaque pointer, not used by the API
190
     */
191
    void *opaque;
192
193
    /**
194
     * Index of the input that requires a request
195
     */
196
    unsigned in_request;
197
198
    /**
199
     * Synchronization level: only inputs with the same sync level are sync
200
     * sources.
201
     */
202
    unsigned sync_level;
203
204
    /**
205
     * Flag indicating that a packet event is ready
206
     */
207
    uint8_t pkt_ready;
208
209
    /**
210
     * Flag indicating that output has reached EOF.
211
     */
212
    uint8_t eof;
213
214
    /**
215
     * Pointer to array of inputs.
216
     */
217
    FFPacketSyncIn *in;
218
219
    int opt_eof_action;
220
    int opt_ts_sync_mode;
221
222
} FFPacketSync;
223
224
/**
225
 * Pre-initialize a packet sync structure.
226
 *
227
 * It sets the class pointer and inits the options to their default values.
228
 * The entire structure is expected to be already set to 0.
229
 * This step is optional, but necessary to use the options.
230
 */
231
void ff_packetsync_preinit(FFPacketSync *fs);
232
233
/**
234
 * Initialize a packet sync structure.
235
 *
236
 * The entire structure is expected to be already set to 0 or preinited.
237
 *
238
 * @param  fs      packet sync structure to initialize
239
 * @param  parent  parent AVBitStreamFilterContext object
240
 * @param  nb_in   number of inputs
241
 * @return  >= 0 for success or a negative error code
242
 */
243
int ff_packetsync_init(FFPacketSync *fs, AVBitStreamFilterContext *parent, unsigned nb_in);
244
245
/**
246
 * Configure a packet sync structure.
247
 *
248
 * Must be called after all options are set but before all use.
249
 *
250
 * @return  >= 0 for success or a negative error code
251
 */
252
int ff_packetsync_configure(FFPacketSync *fs);
253
254
/**
255
 * Free all memory currently allocated.
256
 */
257
void ff_packetsync_uninit(FFPacketSync *fs);
258
259
/**
260
 * Get the current packet in an input.
261
 *
262
 * @param fs      packet sync structure
263
 * @param in      index of the input
264
 * @param rpacket  used to return the current packet (or NULL)
265
 * @param get     if not zero, the calling code needs to get ownership of
266
 *                the returned packet; the current packet will either be
267
 *                duplicated or removed from the packetsync structure
268
 */
269
int ff_packetsync_get_packet(FFPacketSync *fs, unsigned in, AVPacket **rpacket,
270
                             unsigned get);
271
272
/**
273
 * Examine the packets in the filter's input and try to produce output.
274
 *
275
 * This function can be the complete implementation of the activate
276
 * method of a filter using packetsync.
277
 */
278
int ff_packetsync_activate(FFPacketSync *fs);
279
280
/**
281
 * Initialize a packet sync structure for dualinput.
282
 *
283
 * Compared to generic packetsync, dualinput assumes the first input is the
284
 * main one and the filtering is performed on it. The first input will be
285
 * the only one with sync set and generic timeline support will just pass it
286
 * unchanged when disabled.
287
 *
288
 * Equivalent to ff_packetsync_init(fs, parent, 2) then setting the time
289
 * base, sync and ext modes on the inputs.
290
 */
291
int ff_packetsync_init_dualinput(FFPacketSync *fs, AVBitStreamFilterContext *parent);
292
293
/**
294
 * @param f0  used to return the main packet
295
 * @param f1  used to return the second packet, or NULL if disabled
296
 * @return  >=0 for success or AVERROR code
297
 * @note  The packet returned in f0 belongs to the caller (get = 1 in
298
 * ff_packetsync_get_packet()) while the packet returned in f1 is still owned
299
 * by the packetsync structure.
300
 */
301
int ff_packetsync_dualinput_get(FFPacketSync *fs, AVPacket **f0, AVPacket **f1);
302
303
/**
304
 * Same as ff_packetsync_dualinput_get(), but make sure that f0 is writable.
305
 */
306
int ff_packetsync_dualinput_get_writable(FFPacketSync *fs, AVPacket **f0, AVPacket **f1);
307
308
const AVClass *ff_packetsync_child_class_iterate(void **iter);
309
extern const AVClass ff_packetsync_class;
310
311
#define PACKETSYNC_DEFINE_PURE_CLASS(name, desc, func_prefix, options)      \
312
static const AVClass name##_class = {                                       \
313
    .class_name          = desc,                                            \
314
    .item_name           = av_default_item_name,                            \
315
    .option              = options,                                         \
316
    .version             = LIBAVUTIL_VERSION_INT,                           \
317
    .category            = AV_CLASS_CATEGORY_BITSTREAM_FILTER,              \
318
    .child_class_iterate = ff_packetsync_child_class_iterate,               \
319
    .child_next          = func_prefix##_child_next,                        \
320
}
321
322
/* A filter that uses the *_child_next-function from this macro
323
 * is required to initialize the FFPacketSync structure in AVBitStreamFilter.preinit
324
 * via the *_packetsync_preinit function defined alongside it. */
325
#define PACKETSYNC_AUXILIARY_FUNCS(func_prefix, context, field)             \
326
0
static int func_prefix##_packetsync_preinit(AVBitStreamFilterContext *ctx)  \
327
0
{                                                                           \
328
0
    context *s = ctx->priv_data; \
329
0
    ff_packetsync_preinit(&s->field); \
330
0
    return 0; \
331
0
} \
332
0
static void *func_prefix##_child_next(void *obj, void *prev)                \
333
0
{                                                                           \
334
0
    context *s = obj; \
335
0
    return prev ? NULL : &s->field; \
336
0
}
337
338
#define PACKETSYNC_DEFINE_CLASS_EXT(name, context, field, options)          \
339
PACKETSYNC_AUXILIARY_FUNCS(name, context, field)                            \
340
PACKETSYNC_DEFINE_PURE_CLASS(name, #name, name, options)
341
342
#define PACKETSYNC_DEFINE_CLASS(name, context, field)                       \
343
PACKETSYNC_DEFINE_CLASS_EXT(name, context, field, name##_options)
344
345
#endif /* AVCODEC_BSF_PACKETSYNC_H */