FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/bitstreamfilter.c
Date: 2026-07-21 08:37:06
Exec Total Coverage
Lines: 59 534 11.0%
Functions: 3 37 8.1%
Branches: 28 339 8.3%

Line Branch Exec 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
6 * License 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "config.h"
20
21 #include <string.h>
22
23 #include "libavutil/avassert.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26
27 #include "bsf.h"
28 #include "bsf_internal.h"
29
30 static const char *default_bsf_name(void *filter_ctx)
31 {
32 AVBitStreamFilterContext *ctx = filter_ctx;
33 return ctx->name ? ctx->name : ctx->filter->name;
34 }
35
36 static void *bsf_child_next(void *obj, void *prev)
37 {
38 AVBitStreamFilterContext *ctx = obj;
39 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv_data)
40 return ctx->priv_data;
41 return NULL;
42 }
43
44 static const AVClass bitstreamfilter_class = {
45 .class_name = "AVBitStreamFilterContext",
46 .item_name = default_bsf_name,
47 .version = LIBAVUTIL_VERSION_INT,
48 .category = AV_CLASS_CATEGORY_BITSTREAM_FILTER,
49 .child_next = bsf_child_next,
50 .child_class_iterate = ff_bsf_child_class_iterate,
51 .state_flags_offset = offsetof(FFBitStreamFilterContext, state_flags),
52 };
53
54 12 int ff_bsf_alloc(const AVBitStreamFilter *filter, const char *inst_name, AVBitStreamFilterContext **pctx)
55 {
56 FFBitStreamFilterContext *ctxi;
57 AVBitStreamFilterContext *ctx;
58 12 const FFBitStreamFilter *const fi = ff_bsf(filter);
59 12 int ret = AVERROR(ENOMEM), preinited = 0;
60
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 av_assert0(filter);
62
63 12 ctxi = av_mallocz(sizeof(*ctxi));
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!ctxi)
65 return AVERROR(ENOMEM);
66 12 *pctx = ctx = &ctxi->p;
67
68 12 ctx->av_class = &bitstreamfilter_class;
69 12 ctx->filter = filter;
70
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 ctx->name = inst_name ? av_strdup(inst_name) : NULL;
71
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (fi->priv_data_size) {
72 12 ctx->priv_data = av_mallocz(fi->priv_data_size);
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!ctx->priv_data)
74 goto err;
75 }
76
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (fi->preinit) {
77 9 ret = fi->preinit(ctx);
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ret < 0)
79 goto err;
80 9 preinited = 1;
81 }
82
83 12 av_opt_set_defaults(ctx);
84
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (filter->priv_class) {
85 12 *(const AVClass**)ctx->priv_data = filter->priv_class;
86 12 av_opt_set_defaults(ctx->priv_data);
87 }
88
89 12 ctx->nb_inputs = fi->nb_inputs;
90
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (ctx->nb_inputs ) {
91 6 ctx->input_pads = av_memdup(fi->inputs, ctx->nb_inputs * sizeof(*fi->inputs));
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctx->input_pads)
93 goto err;
94 6 ctx->inputs = av_calloc(ctx->nb_inputs, sizeof(*ctx->inputs));
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctx->inputs)
96 goto err;
97 }
98
99 12 ctx->nb_outputs = fi->nb_outputs;
100
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (ctx->nb_outputs) {
101 9 ctx->output_pads = av_memdup(fi->outputs, ctx->nb_outputs * sizeof(*fi->outputs));
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!ctx->output_pads)
103 goto err;
104 9 ctx->outputs = av_calloc(ctx->nb_outputs, sizeof(*ctx->outputs));
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!ctx->outputs)
106 goto err;
107 }
108
109 12 return 0;
110
111 err:
112 if (preinited)
113 fi->uninit(ctx);
114 av_freep(&ctx->name);
115 av_freep(&ctx->inputs);
116 av_freep(&ctx->input_pads);
117 ctx->nb_inputs = 0;
118 av_freep(&ctx->outputs);
119 av_freep(&ctx->output_pads);
120 ctx->nb_outputs = 0;
121 av_freep(&ctx->priv_data);
122 av_freep(pctx);
123 return ret;
124 }
125
126 int av_bsf_link(AVBitStreamFilterContext *src, unsigned srcpad,
127 AVBitStreamFilterContext *dst, unsigned dstpad)
128 {
129 BitStreamFilterLinkInternal *li;
130 AVBitStreamFilterLink *link;
131
132 av_assert0(src->graph);
133 av_assert0(dst->graph);
134 av_assert0(src->graph == dst->graph);
135
136 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
137 src->outputs[srcpad] || dst->inputs[dstpad])
138 return AVERROR(EINVAL);
139
140 if (!(ffbsfctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
141 !(ffbsfctx(dst)->state_flags & AV_CLASS_STATE_INITIALIZED)) {
142 av_log(src, AV_LOG_ERROR, "Filters must be initialized before linking.\n");
143 return AVERROR(EINVAL);
144 }
145
146 if (src->output_pads[srcpad].codec_ids && dst->input_pads[dstpad].codec_ids) {
147 int found = 0;
148 for (int i = 0; src->output_pads[srcpad].codec_ids[i] != AV_CODEC_ID_NONE; i++) {
149 for (int j = 0; dst->input_pads[dstpad].codec_ids[j] != AV_CODEC_ID_NONE; j++)
150 if (src->output_pads[srcpad].codec_ids[i] == dst->input_pads[dstpad].codec_ids[j]) {
151 found = 1;
152 break;
153 }
154 if (found)
155 break;
156 }
157
158 if (!found) {
159 av_log(src, AV_LOG_ERROR, "No common codec id between source and dest pads\n");
160 av_log(src, AV_LOG_ERROR, "Supported input pad codecs are: ");
161 for (int i = 0; dst->input_pads[dstpad].codec_ids[i] != AV_CODEC_ID_NONE; i++) {
162 enum AVCodecID codec_id = dst->input_pads[dstpad].codec_ids[i];
163 av_log(src, AV_LOG_ERROR, "%s (%d) ",
164 avcodec_get_name(codec_id), codec_id);
165 }
166 av_log(src, AV_LOG_ERROR, "\n");
167 av_log(src, AV_LOG_ERROR, "Supported output pad codecs are: ");
168 for (int i = 0; src->output_pads[srcpad].codec_ids[i] != AV_CODEC_ID_NONE; i++) {
169 enum AVCodecID codec_id = src->output_pads[srcpad].codec_ids[i];
170 av_log(src, AV_LOG_ERROR, "%s (%d) ",
171 avcodec_get_name(codec_id), codec_id);
172 }
173 av_log(src, AV_LOG_ERROR, "\n");
174
175 return AVERROR(EINVAL);
176 }
177 }
178
179 li = av_mallocz(sizeof(*li));
180 if (!li)
181 return AVERROR(ENOMEM);
182 link = &li->l;
183
184 src->outputs[srcpad] = dst->inputs[dstpad] = link;
185
186 link->src = src;
187 link->dst = dst;
188 link->srcpad = &src->output_pads[srcpad];
189 link->dstpad = &dst->input_pads[dstpad];
190 link->graph = src->graph;
191 li->fifo = av_container_fifo_alloc_avpacket(0);
192 if (!li->fifo)
193 return AVERROR(ENOMEM);
194
195 return 0;
196 }
197
198 static void link_free(AVBitStreamFilterLink **plink)
199 {
200 AVBitStreamFilterLink *link = *plink;
201 BitStreamFilterLinkInternal *li;
202
203 if (!link)
204 return;
205 li = ff_link_internal(link);
206
207 avcodec_parameters_free(&link->par);
208 av_container_fifo_free(&li->fifo);
209
210 av_freep(plink);
211 }
212
213 18 static void free_link(AVBitStreamFilterLink *link)
214 {
215
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (!link)
216 18 return;
217
218 if (link->src)
219 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
220 if (link->dst)
221 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
222
223 link_free(&link);
224 }
225
226 12 void ff_bsf_free(AVBitStreamFilterContext *ctx)
227 {
228 int i;
229
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!ctx)
231 return;
232
233
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (ctx->graph)
234 12 ff_bsf_graph_remove_filter(ctx->graph, ctx);
235
236
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (ff_bsf(ctx->filter)->uninit)
237 12 ff_bsf(ctx->filter)->uninit(ctx);
238
239
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
21 for (i = 0; i < ctx->nb_inputs; i++) {
240 9 free_link(ctx->inputs[i]);
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ctx->input_pads[i].flags & FF_BSF_PAD_FLAG_FREE_NAME)
242 av_freep(&ctx->input_pads[i].name);
243 }
244
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
21 for (i = 0; i < ctx->nb_outputs; i++) {
245 9 free_link(ctx->outputs[i]);
246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ctx->output_pads[i].flags & FF_BSF_PAD_FLAG_FREE_NAME)
247 av_freep(&ctx->output_pads[i].name);
248 }
249
250
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (ctx->filter->priv_class)
251 12 av_opt_free(ctx->priv_data);
252
253 12 av_freep(&ctx->name);
254 12 av_freep(&ctx->input_pads);
255 12 av_freep(&ctx->output_pads);
256 12 av_freep(&ctx->inputs);
257 12 av_freep(&ctx->outputs);
258 12 av_freep(&ctx->priv_data);
259 12 av_opt_free(ctx);
260 12 av_free(ctx);
261 }
262
263 /**
264 * Parse filter options into a dictionary.
265 *
266 * @param logctx context for logging
267 * @param priv_class a filter's private class for shorthand options or NULL
268 * @param options dictionary to store parsed options in
269 * @param args options string to parse
270 *
271 * @return a non-negative number on success, a negative error code on failure
272 */
273 static int bsf_opt_parse(void *logctx, const AVClass *priv_class,
274 AVDictionary **options, const char *args)
275 {
276 const AVOption *o = NULL;
277 int ret;
278 int offset= -1;
279
280 if (!args)
281 return 0;
282
283 while (*args) {
284 char *parsed_key, *value;
285 const char *key;
286 const char *shorthand = NULL;
287 int additional_flags = 0;
288
289 if (priv_class && (o = av_opt_next(&priv_class, o))) {
290 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
291 continue;
292 offset = o->offset;
293 shorthand = o->name;
294 }
295
296 ret = av_opt_get_key_value(&args, "=", ":",
297 shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
298 &parsed_key, &value);
299 if (ret < 0) {
300 if (ret == AVERROR(EINVAL))
301 av_log(logctx, AV_LOG_ERROR, "No option name near '%s'\n", args);
302 else
303 av_log(logctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args,
304 av_err2str(ret));
305 return ret;
306 }
307 if (*args)
308 args++;
309 if (parsed_key) {
310 key = parsed_key;
311 additional_flags = AV_DICT_DONT_STRDUP_KEY;
312 priv_class = NULL; /* reject all remaining shorthand */
313 } else {
314 key = shorthand;
315 }
316
317 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
318
319 av_dict_set(options, key, value,
320 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
321 }
322
323 return 0;
324 }
325
326 int av_bsf_init_dict(AVBitStreamFilterContext *ctx, AVDictionary **options)
327 {
328 FFBitStreamFilterContext *ctxi = ffbsfctx(ctx);
329 int ret = 0;
330
331 if (ctxi->state_flags & AV_CLASS_STATE_INITIALIZED) {
332 av_log(ctx, AV_LOG_ERROR, "Filter already initialized\n");
333 return AVERROR(EINVAL);
334 }
335
336 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
337 if (ret < 0) {
338 av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n");
339 return ret;
340 }
341
342 if (ff_bsf(ctx->filter)->init2)
343 ret = ff_bsf(ctx->filter)->init2(ctx);
344 if (ret < 0)
345 return ret;
346
347 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
348
349 return 0;
350 }
351
352 int av_bsf_init_str(AVBitStreamFilterContext *ctx, const char *args)
353 {
354 AVDictionary *options = NULL;
355 const AVDictionaryEntry *e;
356 int ret = 0;
357
358 if (args && *args) {
359 ret = bsf_opt_parse(ctx, ctx->filter->priv_class, &options, args);
360 if (ret < 0)
361 goto fail;
362 }
363
364 ret = av_bsf_init_dict(ctx, &options);
365 if (ret < 0)
366 goto fail;
367
368 if ((e = av_dict_iterate(options, NULL))) {
369 av_log(ctx, AV_LOG_ERROR, "No such option: %s.\n", e->key);
370 ret = AVERROR_OPTION_NOT_FOUND;
371 goto fail;
372 }
373
374 fail:
375 av_dict_free(&options);
376
377 return ret;
378 }
379
380 const char *av_bsf_pad_get_name(const AVBitStreamFilterPad *pads, int pad_idx)
381 {
382 return pads[pad_idx].name;
383 }
384
385 const enum AVCodecID *av_bsf_pad_get_codec_ids(const AVBitStreamFilterPad *pads, int pad_idx)
386 {
387 return pads[pad_idx].codec_ids;
388 }
389
390 static void update_link_current_pts(BitStreamFilterLinkInternal *li, int64_t pts)
391 {
392 if (pts == AV_NOPTS_VALUE)
393 return;
394 li->l.current_pts = pts;
395 li->l.current_pts_us = av_rescale_q(pts, li->l.time_base, AV_TIME_BASE_Q);
396 if (li->l.graph && li->age_index >= 0)
397 ff_bsf_graph_update_heap(li->l.graph, li);
398 }
399
400 void ff_bsf_set_ready(AVBitStreamFilterContext *filter, unsigned priority)
401 {
402 FFBitStreamFilterContext *ctxi = ffbsfctx(filter);
403 ctxi->ready = FFMAX(ctxi->ready, priority);
404 }
405
406 /**
407 * Clear packet_blocked_in on all outputs.
408 * This is necessary whenever something changes on input.
409 */
410 static void filter_unblock(AVBitStreamFilterContext *filter)
411 {
412 unsigned i;
413
414 for (i = 0; i < filter->nb_outputs; i++) {
415 BitStreamFilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
416 li->packet_blocked_in = 0;
417 }
418 }
419
420 void ff_bsf_link_set_in_status(AVBitStreamFilterLink *link, int status, int64_t pts)
421 {
422 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
423
424 if (li->status_in == status)
425 return;
426 av_assert0(!li->status_in);
427 li->status_in = status;
428 li->status_in_pts = pts;
429 li->packet_wanted_out = 0;
430 li->packet_blocked_in = 0;
431 filter_unblock(link->dst);
432 ff_bsf_set_ready(link->dst, 200);
433 }
434
435 /**
436 * Set the status field of a link from the destination filter.
437 * The pts should probably be left unset (AV_NOPTS_VALUE).
438 */
439 static void link_set_out_status(AVBitStreamFilterLink *link, int status, int64_t pts)
440 {
441 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
442
443 av_assert0(!li->packet_wanted_out);
444 av_assert0(!li->status_out);
445 li->status_out = status;
446 if (pts != AV_NOPTS_VALUE)
447 update_link_current_pts(li, pts);
448 filter_unblock(link->dst);
449 ff_bsf_set_ready(link->src, 200);
450 }
451
452 int ff_bsf_config_links(AVBitStreamFilterContext *filter)
453 {
454 int (*config_link)(AVBitStreamFilterLink *);
455 unsigned i;
456 int ret;
457
458 for (i = 0; i < filter->nb_inputs; i ++) {
459 AVBitStreamFilterLink *link = filter->inputs[i];
460 AVBitStreamFilterLink *inlink;
461 BitStreamFilterLinkInternal *li = ff_link_internal(link);
462
463 if (!link) continue;
464 if (!link->src || !link->dst) {
465 av_log(filter, AV_LOG_ERROR,
466 "Not all input and output are properly linked (%d).\n", i);
467 return AVERROR(EINVAL);
468 }
469
470 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
471 link->current_pts =
472 link->current_pts_us = AV_NOPTS_VALUE;
473
474 switch (li->init_state) {
475 case AVLINK_INIT:
476 continue;
477 case AVLINK_STARTINIT:
478 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
479 return 0;
480 case AVLINK_UNINIT:
481 li->init_state = AVLINK_STARTINIT;
482
483 if ((ret = ff_bsf_config_links(link->src)) < 0)
484 return ret;
485
486 if (!(config_link = link->srcpad->config_props)) {
487 if (link->src->nb_inputs != 1) {
488 av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
489 "with more than one input "
490 "must set config_props() "
491 "callbacks on all outputs\n");
492 return AVERROR(EINVAL);
493 }
494 }
495
496 if (inlink) {
497 av_assert0(!link->par && inlink->par);
498 link->par = avcodec_parameters_alloc();
499 if (!link->par)
500 return AVERROR(ENOMEM);
501 ret = avcodec_parameters_copy(link->par, inlink->par);
502 if (ret < 0)
503 return ret;
504 } else {
505 av_assert0(!link->par);
506 link->par = avcodec_parameters_alloc();
507 if (!link->par)
508 return AVERROR(ENOMEM);
509 }
510
511 if (config_link && (ret = config_link(link)) < 0) {
512 av_log(link->src, AV_LOG_ERROR,
513 "Failed to configure output pad on %s\n",
514 link->src->name);
515 return ret;
516 }
517
518 switch (link->par->codec_type) {
519 case AVMEDIA_TYPE_VIDEO:
520 if (!link->time_base.num && !link->time_base.den)
521 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
522 break;
523
524 case AVMEDIA_TYPE_AUDIO:
525 if (inlink) {
526 if (!link->time_base.num && !link->time_base.den)
527 link->time_base = inlink->time_base;
528 }
529
530 if (!link->time_base.num && !link->time_base.den)
531 link->time_base = (AVRational) {1, link->par->sample_rate};
532 break;
533 }
534
535 if (link->dstpad->codec_ids) {
536 int j;
537 for (j = 0; link->dstpad->codec_ids[j] != AV_CODEC_ID_NONE; j++)
538 if (link->par->codec_id == link->dstpad->codec_ids[j])
539 break;
540 if (link->dstpad->codec_ids[j] == AV_CODEC_ID_NONE) {
541 av_log(link->dst, AV_LOG_ERROR, "Unsupported input codec id %s (%d). Supported input pad codecs are: ",
542 avcodec_get_name(link->par->codec_id), link->par->codec_id);
543 for (j = 0; link->dstpad->codec_ids[j] != AV_CODEC_ID_NONE; j++) {
544 enum AVCodecID codec_id = link->dstpad->codec_ids[j];
545 av_log(link->dst, AV_LOG_ERROR, "%s (%d) ",
546 avcodec_get_name(codec_id), codec_id);
547 }
548 av_log(link->dst, AV_LOG_ERROR, "\n");
549 return AVERROR(EINVAL);
550 }
551 }
552
553 if ((config_link = link->dstpad->config_props))
554 if ((ret = config_link(link)) < 0) {
555 av_log(link->dst, AV_LOG_ERROR,
556 "Failed to configure input pad on %s\n",
557 link->dst->name);
558 return ret;
559 }
560
561 li->init_state = AVLINK_INIT;
562 }
563 }
564
565 return 0;
566 }
567
568 int ff_bsf_request_packet(AVBitStreamFilterLink *link)
569 {
570 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
571
572 av_assert1(!ff_bsf(link->dst->filter)->activate);
573 if (li->status_out)
574 return li->status_out;
575 if (li->status_in) {
576 if (av_container_fifo_can_read(li->fifo)) {
577 av_assert1(!li->packet_wanted_out);
578 av_assert1(ffbsfctx(link->dst)->ready >= 300);
579 return 0;
580 } else {
581 /* Acknowledge status change. Filters using ff_bsf_request_packet() will
582 handle the change automatically. Filters can also check the
583 status directly but none do yet. */
584 link_set_out_status(link, li->status_in, li->status_in_pts);
585 return li->status_out;
586 }
587 }
588 li->packet_wanted_out = 1;
589 ff_bsf_set_ready(link->src, 100);
590 return 0;
591 }
592
593 static int64_t guess_status_pts(AVBitStreamFilterContext *ctx, int status, AVRational link_time_base)
594 {
595 unsigned i;
596 int64_t r = INT64_MAX;
597
598 for (i = 0; i < ctx->nb_inputs; i++) {
599 AVBitStreamFilterLink * const link = ctx->inputs[i];
600 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
601 if (li->status_out == status)
602 r = FFMIN(r, av_rescale_q(link->current_pts, link->time_base, link_time_base));
603 }
604 if (r < INT64_MAX)
605 return r;
606 av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n");
607 for (i = 0; i < ctx->nb_inputs; i++) {
608 AVBitStreamFilterLink * const link = ctx->inputs[i];
609 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
610 r = FFMIN(r, av_rescale_q(li->status_in_pts, link->time_base, link_time_base));
611 }
612 if (r < INT64_MAX)
613 return r;
614 return AV_NOPTS_VALUE;
615 }
616
617 static int request_packet_to_filter(AVBitStreamFilterLink *link)
618 {
619 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
620 int ret = -1;
621
622 /* Assume the filter is blocked, let the method clear it if not */
623 li->packet_blocked_in = 1;
624 if (link->srcpad->request_packet)
625 ret = link->srcpad->request_packet(link);
626 else if (link->src->inputs[0])
627 ret = ff_bsf_request_packet(link->src->inputs[0]);
628 if (ret < 0) {
629 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
630 ff_bsf_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
631 if (ret == AVERROR_EOF)
632 ret = 0;
633 }
634 return ret;
635 }
636
637 static int default_filter_packet(AVBitStreamFilterLink *link, AVPacket *pkt)
638 {
639 return ff_bsf_filter_packet(link->dst->outputs[0], pkt);
640 }
641
642 static int filter_packet_framed(AVBitStreamFilterLink *link, AVPacket *pkt)
643 {
644 int (*filter)(AVBitStreamFilterLink *, AVPacket *);
645 AVBitStreamFilterPad *dst = link->dstpad;
646 int ret;
647
648 if (!(filter = dst->filter))
649 filter = default_filter_packet;
650
651 if (dst->flags & FF_BSF_PAD_FLAG_NEEDS_WRITABLE) {
652 ret = av_packet_make_writable(pkt);
653 if (ret < 0)
654 goto fail;
655 }
656
657 ret = filter(link, pkt);
658 link->packet_count_out++;
659 return ret;
660
661 fail:
662 av_packet_free(&pkt);
663 return ret;
664 }
665
666 int ff_bsf_filter_packet(AVBitStreamFilterLink *link, AVPacket *pkt)
667 {
668 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
669 FFBitStreamFilterGraph * const graphi = ffbsffiltergraph(link->graph);
670 int ret;
671
672 li->packet_blocked_in = li->packet_wanted_out = 0;
673 link->packet_count_in++;
674 filter_unblock(link->dst);
675 if (av_container_fifo_can_read(li->fifo) >= graphi->max_packet_queue)
676 return AVERROR(ENOMEM);
677 ret = av_container_fifo_write(li->fifo, pkt, 0);
678 av_packet_free(&pkt);
679 if (ret < 0)
680 return ret;
681 av_assert1(graphi->packets_queued < graphi->max_packet_queue);
682 graphi->packets_queued++;
683 ff_bsf_set_ready(link->dst, 300);
684 return 0;
685 }
686
687 static int filter_packet_to_filter(AVBitStreamFilterLink *link)
688 {
689 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
690 AVPacket *pkt = NULL;
691 AVBitStreamFilterContext *dst = link->dst;
692 int ret;
693
694 av_assert1(av_container_fifo_can_read(li->fifo));
695 ret = ff_bsf_inlink_consume_packet(link, &pkt);
696 av_assert1(ret);
697 if (ret < 0) {
698 av_assert1(!pkt);
699 return ret;
700 }
701
702 /* The filter will soon have received a new packet, that may allow it to
703 produce one or more: unblock its outputs. */
704 filter_unblock(dst);
705 /* AVBitStreamFilterPad.filter_packet() expect packet_count_out to have the value
706 before the packet; filter_packet_framed() will re-increment it. */
707 link->packet_count_out--;
708 ret = filter_packet_framed(link, pkt);
709 if (ret < 0 && ret != li->status_out) {
710 link_set_out_status(link, ret, AV_NOPTS_VALUE);
711 } else {
712 /* Run once again, to see if several packets were available, or if
713 the input status has also changed, or any other reason. */
714 ff_bsf_set_ready(dst, 300);
715 }
716 return ret;
717 }
718
719 static int forward_status_change(AVBitStreamFilterContext *filter, BitStreamFilterLinkInternal *li_in)
720 {
721 AVBitStreamFilterLink *in = &li_in->l;
722 unsigned out = 0, progress = 0;
723 int ret;
724
725 av_assert0(!li_in->status_out);
726 if (!filter->nb_outputs) {
727 /* not necessary with the current API and sinks */
728 return 0;
729 }
730 while (!li_in->status_out) {
731 BitStreamFilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
732
733 if (!li_out->status_in) {
734 progress++;
735 ret = request_packet_to_filter(filter->outputs[out]);
736 if (ret < 0)
737 return ret;
738 }
739 if (++out == filter->nb_outputs) {
740 if (!progress) {
741 /* Every output already closed: input no longer interesting. */
742 link_set_out_status(in, li_in->status_in, li_in->status_in_pts);
743 return 0;
744 }
745 progress = 0;
746 out = 0;
747 }
748 }
749 ff_bsf_set_ready(filter, 200);
750 return 0;
751 }
752
753 static int filter_activate_default(AVBitStreamFilterContext *ctx)
754 {
755 int i, nb_eofs = 0;
756
757 for (i = 0; i < ctx->nb_outputs; i++)
758 nb_eofs += ff_bsf_outlink_get_status(ctx->outputs[i]) == AVERROR_EOF;
759 if (ctx->nb_outputs && nb_eofs == ctx->nb_outputs) {
760 for (int j = 0; j < ctx->nb_inputs; j++)
761 ff_bsf_inlink_set_status(ctx->inputs[j], AVERROR_EOF);
762 return 0;
763 }
764
765 for (i = 0; i < ctx->nb_inputs; i++) {
766 BitStreamFilterLinkInternal *li = ff_link_internal(ctx->inputs[i]);
767 if (av_container_fifo_can_read(li->fifo)) {
768 return filter_packet_to_filter(ctx->inputs[i]);
769 }
770 }
771 for (i = 0; i < ctx->nb_inputs; i++) {
772 BitStreamFilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
773 if (li->status_in && !li->status_out) {
774 av_assert1(!av_container_fifo_can_read(li->fifo));
775 return forward_status_change(ctx, li);
776 }
777 }
778 for (i = 0; i < ctx->nb_outputs; i++) {
779 BitStreamFilterLinkInternal * const li = ff_link_internal(ctx->outputs[i]);
780 if (li->packet_wanted_out &&
781 !li->packet_blocked_in) {
782 return request_packet_to_filter(ctx->outputs[i]);
783 }
784 }
785 for (i = 0; i < ctx->nb_outputs; i++) {
786 BitStreamFilterLinkInternal * const li = ff_link_internal(ctx->outputs[i]);
787 if (li->packet_wanted_out)
788 return request_packet_to_filter(ctx->outputs[i]);
789 }
790 if (!ctx->nb_outputs) {
791 ff_bsf_inlink_request_packet(ctx->inputs[0]);
792 return 0;
793 }
794 return FFERROR_BSF_NOT_READY;
795 }
796
797 int ff_bsf_activate(AVBitStreamFilterContext *ctx)
798 {
799 FFBitStreamFilterContext *ctxi = ffbsfctx(ctx);
800 const FFBitStreamFilter *const fi = ff_bsf(ctx->filter);
801 int ret;
802
803 ctxi->ready = 0;
804 ret = fi->activate ? fi->activate(ctx) : filter_activate_default(ctx);
805 if (ret == FFERROR_BSF_NOT_READY)
806 ret = 0;
807 return ret;
808 }
809
810 int ff_bsf_inlink_acknowledge_status(AVBitStreamFilterLink *link, int *rstatus, int64_t *rpts)
811 {
812 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
813 *rpts = link->current_pts;
814 if (av_container_fifo_can_read(li->fifo))
815 return *rstatus = 0;
816 if (li->status_out)
817 return *rstatus = li->status_out;
818 if (!li->status_in)
819 return *rstatus = 0;
820 *rstatus = li->status_out = li->status_in;
821 update_link_current_pts(li, li->status_in_pts);
822 *rpts = link->current_pts;
823 return 1;
824 }
825
826 size_t ff_bsf_inlink_queued_packets(AVBitStreamFilterLink *link)
827 {
828 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
829 return av_container_fifo_can_read(li->fifo);
830 }
831
832 int ff_bsf_inlink_check_available_packet(AVBitStreamFilterLink *link)
833 {
834 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
835 return av_container_fifo_can_read(li->fifo) > 0;
836 }
837
838 static void consume_update(BitStreamFilterLinkInternal *li, const AVPacket *pkt)
839 {
840 update_link_current_pts(li, pkt->pts);
841 li->l.packet_count_out++;
842 }
843
844 int ff_bsf_inlink_consume_packet(AVBitStreamFilterLink *link, AVPacket **rpkt)
845 {
846 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
847 FFBitStreamFilterGraph * const graphi = ffbsffiltergraph(link->graph);
848 AVPacket *pkt;
849
850 *rpkt = NULL;
851 if (!av_container_fifo_can_read(li->fifo))
852 return 0;
853
854 pkt = av_packet_alloc();
855 if (!pkt)
856 return AVERROR(ENOMEM);
857
858 av_container_fifo_read(li->fifo, pkt, 0);
859 consume_update(li, pkt);
860 av_assert1(graphi->packets_queued > 0);
861 graphi->packets_queued--;
862 *rpkt = pkt;
863 return 1;
864 }
865
866 void ff_bsf_inlink_request_packet(AVBitStreamFilterLink *link)
867 {
868 BitStreamFilterLinkInternal *li = ff_link_internal(link);
869 av_assert1(!li->status_in);
870 av_assert1(!li->status_out);
871 li->packet_wanted_out = 1;
872 ff_bsf_set_ready(link->src, 100);
873 }
874
875 void ff_bsf_inlink_set_status(AVBitStreamFilterLink *link, int status)
876 {
877 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
878 FFBitStreamFilterGraph * const graphi = ffbsffiltergraph(link->graph);
879 if (li->status_out)
880 return;
881 li->packet_wanted_out = 0;
882 li->packet_blocked_in = 0;
883 link_set_out_status(link, status, AV_NOPTS_VALUE);
884 while (av_container_fifo_can_read(li->fifo)) {
885 AVPacket pkt;
886 av_container_fifo_read(li->fifo, &pkt, 0);
887 av_packet_unref(&pkt);
888 av_assert1(graphi->packets_queued > 0);
889 graphi->packets_queued--;
890 }
891 if (!li->status_in)
892 li->status_in = status;
893 }
894
895 int ff_bsf_outlink_get_status(AVBitStreamFilterLink *link)
896 {
897 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
898 return li->status_in;
899 }
900
901 int ff_bsf_outlink_packet_wanted(AVBitStreamFilterLink *link)
902 {
903 BitStreamFilterLinkInternal * const li = ff_link_internal(link);
904 return li->packet_wanted_out;
905 }
906
907 const AVBitStreamFilterPad ff_default_bsf_pad[1] = {
908 {
909 .name = "default",
910 }
911 };
912