FFmpeg
Loading...
Searching...
No Matches
ffmpeg_filter.c
Go to the documentation of this file.
1/*
2 * ffmpeg filter configuration
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#include <stdint.h>
22
23#include "ffmpeg.h"
24#include "graph/graphprint.h"
25
29
31#include "libavutil/avassert.h"
32#include "libavutil/avstring.h"
33#include "libavutil/bprint.h"
36#include "libavutil/mem.h"
37#include "libavutil/opt.h"
38#include "libavutil/pixdesc.h"
39#include "libavutil/pixfmt.h"
40#include "libavutil/samplefmt.h"
41#include "libavutil/time.h"
42#include "libavutil/timestamp.h"
43
44typedef struct FilterGraphPriv {
46
47 // name used for logging
48 char log_name[32];
49
51 // true when the filtergraph contains only meta filters
52 // that do not modify the frame data
55
57
59
60 // frame for temporarily holding output from the filtergraph
62 // frame for sending output to the encoder
64
66 unsigned sch_idx;
68
70{
71 return (FilterGraphPriv*)fg;
72}
73
75{
76 return (const FilterGraphPriv*)fg;
77}
78
79// data that is local to the filter thread and not visible outside of it
80typedef struct FilterGraphThread {
82
84
85 // Temporary buffer for output frames, since on filtergraph reset
86 // we cannot send them to encoders immediately.
87 // The output index is stored in frame opaque.
89
90 // index of the next input to request from the scheduler
91 unsigned next_in;
92 // set to 1 after at least one frame passed through this output
94
95 // EOF status of each input/output, as received by the thread
96 uint8_t *eof_in;
97 uint8_t *eof_out;
99
100typedef struct InputFilterPriv {
102
104
105 // used to hold submitted input
107
108 // For inputs bound to a filtergraph output
110
111 // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video,
112 // same as type otherwise
114
115 int eof;
116 int bound;
118 uint64_t nb_dropped;
119
120 // parameters configured for this input
122
128
131
133
136
138
140
144
147
151
152 struct {
153 AVFrame *frame;
154
157
158 /// marks if sub2video_update should force an initialization
159 unsigned int initialize;
162
164{
165 return (InputFilterPriv*)ifilter;
166}
167
168typedef struct FPSConvContext {
170 /* number of frames emitted by the video-encoding sync code */
172 /* history of nb_frames_prev, i.e. the number of times the
173 * previous frame was duplicated by vsync code in recent
174 * do_video_out() calls */
176
177 uint64_t dup_warning;
178
181
183
189
194
195typedef struct OutputFilterPriv {
197
199 char log_name[32];
200
202
203 /* desired output stream properties */
211
212 unsigned crop_top;
213 unsigned crop_bottom;
214 unsigned crop_left;
215 unsigned crop_right;
216
219
220 // time base in which the output is sent to our downstream
221 // does not need to match the filtersink's timebase
223 // at least one frame with the above timebase was sent
224 // to our downstream, so it cannot change anymore
226
228
231
232 // those are only set if no format is specified and the encoder gives us multiple options
233 // They point directly to the relevant lists of the encoder.
234 union {
237 };
239 const int *sample_rates;
243
245
249 // offset for output timestamps, in AV_TIME_BASE_Q
253
256
257 unsigned flags;
259
261{
262 return (OutputFilterPriv*)ofilter;
263}
264
265typedef struct FilterCommand {
266 char *target;
267 char *command;
268 char *arg;
269
270 double time;
273
274static void filter_command_free(void *opaque, uint8_t *data)
275{
277
278 av_freep(&fc->target);
279 av_freep(&fc->command);
280 av_freep(&fc->arg);
281
282 av_free(data);
283}
284
286{
288 int ret;
289
291
292 frame->width = ifp->width;
293 frame->height = ifp->height;
294 frame->format = ifp->format;
295 frame->colorspace = ifp->color_space;
296 frame->color_range = ifp->color_range;
297 frame->alpha_mode = ifp->alpha_mode;
298
299 ret = av_frame_get_buffer(frame, 0);
300 if (ret < 0)
301 return ret;
302
303 memset(frame->data[0], 0, frame->height * frame->linesize[0]);
304
305 return 0;
306}
307
308static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
310{
311 uint32_t *pal, *dst2;
312 uint8_t *src, *src2;
313 int x, y;
314
315 if (r->type != SUBTITLE_BITMAP) {
316 av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n");
317 return;
318 }
319 if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
320 av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n",
321 r->x, r->y, r->w, r->h, w, h
322 );
323 return;
324 }
325
326 dst += r->y * dst_linesize + r->x * 4;
327 src = r->data[0];
328 pal = (uint32_t *)r->data[1];
329 for (y = 0; y < r->h; y++) {
330 dst2 = (uint32_t *)dst;
331 src2 = src;
332 for (x = 0; x < r->w; x++)
333 *(dst2++) = pal[*(src2++)];
334 dst += dst_linesize;
335 src += r->linesize[0];
336 }
337}
338
340{
342 int ret;
343
344 av_assert1(frame->data[0]);
345 ifp->sub2video.last_pts = frame->pts = pts;
349 if (ret != AVERROR_EOF && ret < 0)
351 "Error while add the frame to buffer source(%s).\n",
352 av_err2str(ret));
353}
354
355static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts,
356 const AVSubtitle *sub)
357{
359 int8_t *dst;
360 int dst_linesize;
361 int num_rects;
362 int64_t pts, end_pts;
363
364 if (sub) {
365 pts = av_rescale_q(sub->pts + sub->start_display_time * 1000LL,
367 end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000LL,
369 num_rects = sub->num_rects;
370 } else {
371 /* If we are initializing the system, utilize current heartbeat
372 PTS as the start time, and show until the following subpicture
373 is received. Otherwise, utilize the previous subpicture's end time
374 as the fall-back value. */
375 pts = ifp->sub2video.initialize ?
376 heartbeat_pts : ifp->sub2video.end_pts;
377 end_pts = INT64_MAX;
378 num_rects = 0;
379 }
380 if (sub2video_get_blank_frame(ifp) < 0) {
382 "Impossible to get a blank canvas.\n");
383 return;
384 }
385 dst = frame->data [0];
386 dst_linesize = frame->linesize[0];
387 for (int i = 0; i < num_rects; i++)
388 sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
390 ifp->sub2video.end_pts = end_pts;
391 ifp->sub2video.initialize = 0;
392}
393
394/* Define a function for appending a list of allowed formats
395 * to an AVBPrint. If nonempty, the list will have a header. */
396#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
397static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint) \
398{ \
399 if (ofp->var == none && !ofp->supported_list) \
400 return; \
401 av_bprintf(bprint, #name "="); \
402 if (ofp->var != none) { \
403 av_bprintf(bprint, printf_format, get_name(ofp->var)); \
404 } else { \
405 const type *p; \
406 \
407 for (p = ofp->supported_list; *p != none; p++) { \
408 av_bprintf(bprint, printf_format "|", get_name(*p)); \
409 } \
410 if (bprint->len > 0) \
411 bprint->str[--bprint->len] = '\0'; \
412 } \
413 av_bprint_chars(bprint, ':', 1); \
414}
415
418
421
423 "%d", )
424
425DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
427
428DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
430
431DEF_CHOOSE_FORMAT(alpha_modes, enum AVAlphaMode, alpha_mode, alpha_modes,
433
434static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
435{
436 if (av_channel_layout_check(&ofp->ch_layout)) {
437 av_bprintf(bprint, "channel_layouts=");
438 av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
439 } else if (ofp->ch_layouts) {
440 const AVChannelLayout *p;
441
442 av_bprintf(bprint, "channel_layouts=");
443 for (p = ofp->ch_layouts; p->nb_channels; p++) {
444 av_channel_layout_describe_bprint(p, bprint);
445 av_bprintf(bprint, "|");
446 }
447 if (bprint->len > 0)
448 bprint->str[--bprint->len] = '\0';
449 } else
450 return;
451 av_bprint_chars(bprint, ':', 1);
452}
453
454static int read_binary(void *logctx, const char *path,
455 uint8_t **data, int *len)
456{
457 AVIOContext *io = NULL;
459 int ret;
460
461 *data = NULL;
462 *len = 0;
463
464 ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL);
465 if (ret < 0) {
466 av_log(logctx, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
467 path, av_err2str(ret));
468 return ret;
469 }
470
471 fsize = avio_size(io);
472 if (fsize < 0 || fsize > INT_MAX) {
473 av_log(logctx, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
474 ret = AVERROR(EIO);
475 goto fail;
476 }
477
478 *data = av_malloc(fsize);
479 if (!*data) {
480 ret = AVERROR(ENOMEM);
481 goto fail;
482 }
483
484 ret = avio_read(io, *data, fsize);
485 if (ret != fsize) {
486 av_log(logctx, AV_LOG_ERROR, "Error reading file %s\n", path);
487 ret = ret < 0 ? ret : AVERROR(EIO);
488 goto fail;
489 }
490
491 *len = fsize;
492
493 ret = 0;
494fail:
495 avio_close(io);
496 if (ret < 0) {
497 av_freep(data);
498 *len = 0;
499 }
500 return ret;
501}
502
503static int filter_opt_apply(void *logctx, AVFilterContext *f,
504 const char *key, const char *val)
505{
506 const AVOption *o = NULL;
507 int ret;
508
510 if (ret >= 0)
511 return 0;
512
513 if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
515 if (!o)
516 goto err_apply;
517
518 // key is a valid option name prefixed with '/'
519 // interpret value as a path from which to load the actual option value
520 key++;
521
522 if (o->type == AV_OPT_TYPE_BINARY) {
523 uint8_t *data;
524 int len;
525
526 ret = read_binary(logctx, val, &data, &len);
527 if (ret < 0)
528 goto err_load;
529
531 av_freep(&data);
532 } else {
534 if (!data) {
535 ret = AVERROR(EIO);
536 goto err_load;
537 }
538
540 av_freep(&data);
541 }
542 if (ret < 0)
543 goto err_apply;
544
545 return 0;
546
547err_apply:
548 av_log(logctx, AV_LOG_ERROR,
549 "Error applying option '%s' to filter '%s': %s\n",
550 key, f->filter->name, av_err2str(ret));
551 return ret;
552err_load:
553 av_log(logctx, AV_LOG_ERROR,
554 "Error loading value for option '%s' from file '%s'\n",
555 key, val);
556 return ret;
557}
558
559static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
560{
561 for (size_t i = 0; i < seg->nb_chains; i++) {
562 AVFilterChain *ch = seg->chains[i];
563
564 for (size_t j = 0; j < ch->nb_filters; j++) {
565 AVFilterParams *p = ch->filters[j];
566 const AVDictionaryEntry *e = NULL;
567
568 av_assert0(p->filter);
569
570 while ((e = av_dict_iterate(p->opts, e))) {
571 int ret = filter_opt_apply(logctx, p->filter, e->key, e->value);
572 if (ret < 0)
573 return ret;
574 }
575
576 av_dict_free(&p->opts);
577 }
578 }
579
580 return 0;
581}
582
583static int graph_parse(void *logctx,
584 AVFilterGraph *graph, const char *desc,
586 AVBufferRef *hw_device)
587{
589 int ret;
590
591 *inputs = NULL;
592 *outputs = NULL;
593
594 ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
595 if (ret < 0)
596 return ret;
597
599 if (ret < 0)
600 goto fail;
601
602 if (hw_device) {
603 for (int i = 0; i < graph->nb_filters; i++) {
604 AVFilterContext *f = graph->filters[i];
605
606 if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE))
607 continue;
608 f->hw_device_ctx = av_buffer_ref(hw_device);
609 if (!f->hw_device_ctx) {
610 ret = AVERROR(ENOMEM);
611 goto fail;
612 }
613 }
614 }
615
616 ret = graph_opts_apply(logctx, seg);
617 if (ret < 0)
618 goto fail;
619
621
622fail:
624 return ret;
625}
626
627// Filters can be configured only if the formats of all inputs are known.
629{
630 for (int i = 0; i < fg->nb_inputs; i++) {
632 if (ifp->format < 0)
633 return 0;
634 }
635 return 1;
636}
637
638static int filter_thread(void *arg);
639
640static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
641{
643 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
644 int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
645
646 if (nb_pads > 1)
647 return av_strdup(ctx->filter->name);
648 return av_asprintf("%s:%s", ctx->filter->name,
649 avfilter_pad_get_name(pads, inout->pad_idx));
650}
651
652static const char *ofilter_item_name(void *obj)
653{
654 OutputFilterPriv *ofp = obj;
655 return ofp->log_name;
656}
657
658static const AVOption ofilter_options[] = {
659 {"video_size", "set video size", offsetof(OutputFilterPriv, width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, INT_MAX },
660 {"pixel_format", "set pixel format", offsetof(OutputFilterPriv, format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX },
661 {"colorspace", "color space", offsetof(OutputFilterPriv, color_space), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX },
662 {"color_range", "color range", offsetof(OutputFilterPriv, color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX },
663 {"alpha_mode", "color range", offsetof(OutputFilterPriv, alpha_mode), AV_OPT_TYPE_INT, {.i64 = AVALPHA_MODE_UNSPECIFIED }, 0, INT_MAX },
664 {"ar", "set audio sampling rate (in Hz)", offsetof(OutputFilterPriv, sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX },
665 {"ch_layout", NULL, offsetof(OutputFilterPriv, ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0 },
666 { NULL },
667};
668
669static const AVClass ofilter_class = {
670 .class_name = "OutputFilter",
671 .version = LIBAVUTIL_VERSION_INT,
672 .item_name = ofilter_item_name,
673 .option = ofilter_options,
674 .parent_log_context_offset = offsetof(OutputFilterPriv, log_parent),
675 .category = AV_CLASS_CATEGORY_FILTER,
676};
677
679{
680 OutputFilterPriv *ofp;
681 OutputFilter *ofilter;
682
683 ofp = allocate_array_elem(&fg->outputs, sizeof(*ofp), &fg->nb_outputs);
684 if (!ofp)
685 return NULL;
686
687 ofilter = &ofp->ofilter;
688 ofilter->class = &ofilter_class;
689 ofp->log_parent = fg;
690 ofilter->graph = fg;
691 ofilter->type = type;
693 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
694 ofilter->index = fg->nb_outputs - 1;
695
696 snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
697 av_get_media_type_string(type)[0], ofilter->index);
698
699 return ofilter;
700}
701
702static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist,
703 const ViewSpecifier *vs)
704{
705 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
706 FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph);
708 int ret;
709
710 av_assert0(!ifp->bound);
711 ifp->bound = 1;
712
713 if (ifilter->type != ist->par->codec_type &&
714 !(ifilter->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
715 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s stream to %s filtergraph input\n",
717 return AVERROR(EINVAL);
718 }
719
720 ifp->type_src = ist->st->codecpar->codec_type;
721
723 if (!ifp->opts.fallback)
724 return AVERROR(ENOMEM);
725
726 ret = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph),
727 vs, &ifp->opts, &src);
728 if (ret < 0)
729 return ret;
730
731 ifilter->input_name = av_strdup(ifp->opts.name);
732 if (!ifilter->input_name)
733 return AVERROR(EINVAL);
734
735 ret = sch_connect(fgp->sch,
736 src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index));
737 if (ret < 0)
738 return ret;
739
740 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
742 if (!ifp->sub2video.frame)
743 return AVERROR(ENOMEM);
744
745 ifp->width = ifp->opts.sub2video_width;
746 ifp->height = ifp->opts.sub2video_height;
747
748 /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
749 palettes for all rectangles are identical or compatible */
751
753
754 av_log(fgp, AV_LOG_VERBOSE, "sub2video: using %dx%d canvas\n",
755 ifp->width, ifp->height);
756 }
757
758 return 0;
759}
760
762 const ViewSpecifier *vs)
763{
766 int ret;
767
768 av_assert0(!ifp->bound);
769 ifp->bound = 1;
770
771 if (ifp->ifilter.type != dec->type) {
772 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s decoder to %s filtergraph input\n",
774 return AVERROR(EINVAL);
775 }
776
777 ifp->type_src = ifp->ifilter.type;
778
779 ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src);
780 if (ret < 0)
781 return ret;
782
783 ifp->ifilter.input_name = av_strdup(ifp->opts.name);
784 if (!ifp->ifilter.input_name)
785 return AVERROR(EINVAL);
786
787 ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
788 if (ret < 0)
789 return ret;
790
791 return 0;
792}
793
794static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed,
795 const AVChannelLayout *layout_requested)
796{
797 int i, err;
798
799 if (layout_requested->order != AV_CHANNEL_ORDER_UNSPEC) {
800 /* Pass the layout through for all orders but UNSPEC */
801 err = av_channel_layout_copy(&f->ch_layout, layout_requested);
802 if (err < 0)
803 return err;
804 return 0;
805 }
806
807 /* Requested layout is of order UNSPEC */
808 if (!layouts_allowed) {
809 /* Use the default native layout for the requested amount of channels when the
810 encoder doesn't have a list of supported layouts */
811 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
812 return 0;
813 }
814 /* Encoder has a list of supported layouts. Pick the first layout in it with the
815 same amount of channels as the requested layout */
816 for (i = 0; layouts_allowed[i].nb_channels; i++) {
817 if (layouts_allowed[i].nb_channels == layout_requested->nb_channels)
818 break;
819 }
820 if (layouts_allowed[i].nb_channels) {
821 /* Use it if one is found */
822 err = av_channel_layout_copy(&f->ch_layout, &layouts_allowed[i]);
823 if (err < 0)
824 return err;
825 return 0;
826 }
827 /* If no layout for the amount of channels requested was found, use the default
828 native layout for it. */
829 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
830
831 return 0;
832}
833
834static int parse_reinit_opts(AVFifo **pout, const char *opts, void *logctx)
835{
836 AVFifo *out;
837 int ret = AVERROR_BUG;
838 char *ptr, *str, *substr = NULL;
839 const char *token;
840
841 str = av_strdup(opts);
842 if (!str)
843 return AVERROR(ENOMEM);
844
846 if (!out) {
847 ret = AVERROR(ENOMEM);
848 goto end;
849 }
850
851 token = av_strtok(str, ",", &ptr);
852 while (token) {
853 ReinitOpts o = { 0 };
854 const char *subtoken;
855 char *subptr, *endptr;
856
857 substr = av_strdup(token);
858 if (!substr) {
859 ret = AVERROR(ENOMEM);
860 goto end;
861 }
862 subtoken = av_strtok(substr, "|", &subptr);
863 if (subtoken && subptr) {
864 if (!av_strstart(subtoken, "pts=", &subtoken)) {
865 av_log(logctx, AV_LOG_ERROR, "Invalid reinit identifier\n");
866 ret = AVERROR(ENOMEM);
867 goto end;
868 }
869 o.pts = strtoll(subtoken, &endptr, 0);
870 if (*endptr || o.pts < 0) {
871 ret = AVERROR(EINVAL);
872 goto end;
873 }
874 ret = av_dict_parse_string(&o.dict, subptr, "=", ":", 0);
875 if (ret < 0) {
876 av_log(logctx, AV_LOG_ERROR, "Error parsing encoder options\n");
877 goto end;
878 }
879 ret = av_fifo_write(out, &o, 1);
880 if (ret < 0) {
881 av_dict_free(&o.dict);
882 goto end;
883 }
884 } else {
885 ret = AVERROR(EINVAL);
886 goto end;
887 }
888 av_freep(&substr);
889 if (ptr)
890 ptr += strspn(ptr, " \n\t\r");
891 token = av_strtok(NULL, ",", &ptr);
892 }
893
894 ret = 0;
895end:
896 *pout = out;
897 av_free(substr);
898 av_free(str);
899
900 return ret;
901}
902
903int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
905{
906 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
907 FilterGraph *fg = ofilter->graph;
908 FilterGraphPriv *fgp = fgp_from_fg(fg);
909 int ret;
910
911 av_assert0(!ofilter->bound);
912 av_assert0(!opts->enc ||
913 ofilter->type == opts->enc->type);
914
915 ofp->needed = ofilter->bound = 1;
916 av_freep(&ofilter->linklabel);
917
918 ofp->flags |= opts->flags;
919 ofp->ts_offset = opts->ts_offset;
920 ofp->enc_timebase = opts->output_tb;
921
922 ofp->trim_start_us = opts->trim_start_us;
923 ofp->trim_duration_us = opts->trim_duration_us;
924
925 ofilter->output_name = av_strdup(opts->name);
926 if (!ofilter->output_name)
927 return AVERROR(EINVAL);
928
929 if (opts->reinit_opts) {
930 ret = parse_reinit_opts(&ofp->reinit_opts_fifo, opts->reinit_opts, ofilter);
931 if (ret < 0)
932 return ret;
933 }
934
935 ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
936 if (ret < 0)
937 return ret;
938
939 ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
940 if (ret < 0)
941 return ret;
942
943 if (opts->flags & OFILTER_FLAG_AUDIO_24BIT)
944 av_dict_set(&ofp->swr_opts, "output_sample_bits", "24", 0);
945
946 if (fgp->is_simple) {
947 // for simple filtergraph there is just one output,
948 // so use only graph-level information for logging
949 ofp->log_parent = NULL;
950 av_strlcpy(ofp->log_name, fgp->log_name, sizeof(ofp->log_name));
951 } else
952 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
953
954 switch (ofilter->type) {
956 ofp->width = opts->width;
957 ofp->height = opts->height;
958 if (opts->format != AV_PIX_FMT_NONE) {
959 ofp->format = opts->format;
960 } else
961 ofp->pix_fmts = opts->pix_fmts;
962
963 if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
964 ofp->color_space = opts->color_space;
965 else
966 ofp->color_spaces = opts->color_spaces;
967
968 if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
969 ofp->color_range = opts->color_range;
970 else
971 ofp->color_ranges = opts->color_ranges;
972
973 if (opts->alpha_mode != AVALPHA_MODE_UNSPECIFIED)
974 ofp->alpha_mode = opts->alpha_mode;
975 else
976 ofp->alpha_modes = opts->alpha_modes;
977
979
981 if (!ofp->fps.last_frame)
982 return AVERROR(ENOMEM);
983
984 ofp->fps.vsync_method = opts->vsync_method;
985 ofp->fps.framerate = opts->frame_rate;
986 ofp->fps.framerate_max = opts->max_frame_rate;
987 ofp->fps.framerate_supported = opts->frame_rates;
988
989 // reduce frame rate for mpeg4 to be within the spec limits
990 if (opts->enc && opts->enc->id == AV_CODEC_ID_MPEG4)
991 ofp->fps.framerate_clip = 65535;
992
993 ofp->fps.dup_warning = 1000;
994
995 break;
997 if (opts->format != AV_SAMPLE_FMT_NONE) {
998 ofp->format = opts->format;
999 } else {
1000 ofp->sample_fmts = opts->sample_fmts;
1001 }
1002 if (opts->sample_rate) {
1003 ofp->sample_rate = opts->sample_rate;
1004 } else
1005 ofp->sample_rates = opts->sample_rates;
1006 if (opts->ch_layout.nb_channels) {
1007 int ret = set_channel_layout(ofp, opts->ch_layouts, &opts->ch_layout);
1008 if (ret < 0)
1009 return ret;
1010 } else {
1011 ofp->ch_layouts = opts->ch_layouts;
1012 }
1013 break;
1014 }
1015
1016 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index),
1017 SCH_ENC(sched_idx_enc));
1018 if (ret < 0)
1019 return ret;
1020
1021 return 0;
1022}
1023
1026{
1027 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1028
1029 av_assert0(!ofilter->bound);
1030 av_assert0(ofilter->type == ifp->ifilter.type);
1031
1032 ofp->needed = ofilter->bound = 1;
1033 av_freep(&ofilter->linklabel);
1034
1035 ofilter->output_name = av_strdup(opts->name);
1036 if (!ofilter->output_name)
1037 return AVERROR(EINVAL);
1038
1039 ifp->ofilter_src = ofilter;
1040
1041 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
1042
1043 return 0;
1044}
1045
1046static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
1047{
1049 OutputFilter *ofilter_src = fg_src->outputs[out_idx];
1051 char name[32];
1052 int ret;
1053
1054 av_assert0(!ifp->bound);
1055 ifp->bound = 1;
1056
1057 if (ifp->ifilter.type != ofilter_src->type) {
1058 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s output to %s input\n",
1059 av_get_media_type_string(ofilter_src->type),
1061 return AVERROR(EINVAL);
1062 }
1063
1064 ifp->type_src = ifp->ifilter.type;
1065
1066 memset(&opts, 0, sizeof(opts));
1067
1068 snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->ifilter.index);
1069 opts.name = name;
1070
1071 ret = ofilter_bind_ifilter(ofilter_src, ifp, &opts);
1072 if (ret < 0)
1073 return ret;
1074
1075 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fg_src->index, out_idx),
1076 SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
1077 if (ret < 0)
1078 return ret;
1079
1080 return 0;
1081}
1082
1084{
1085 InputFilterPriv *ifp;
1086 InputFilter *ifilter;
1087
1088 ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs);
1089 if (!ifp)
1090 return NULL;
1091
1092 ifilter = &ifp->ifilter;
1093 ifilter->graph = fg;
1094
1095 ifp->frame = av_frame_alloc();
1096 if (!ifp->frame)
1097 return NULL;
1098
1099 ifilter->index = fg->nb_inputs - 1;
1100 ifp->format = -1;
1104
1106 if (!ifp->frame_queue)
1107 return NULL;
1108
1109 return ifilter;
1110}
1111
1113{
1114 FilterGraph *fg = *pfg;
1115 FilterGraphPriv *fgp;
1116
1117 if (!fg)
1118 return;
1119 fgp = fgp_from_fg(fg);
1120
1121 for (int j = 0; j < fg->nb_inputs; j++) {
1122 InputFilter *ifilter = fg->inputs[j];
1123 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1124
1125 if (ifp->frame_queue) {
1126 AVFrame *frame;
1127 while (av_fifo_read(ifp->frame_queue, &frame, 1) >= 0)
1130 }
1132
1133 av_frame_free(&ifp->frame);
1135
1138 av_freep(&ifilter->linklabel);
1139 av_freep(&ifp->opts.name);
1142 av_freep(&ifilter->name);
1143 av_freep(&ifilter->input_name);
1144 av_freep(&fg->inputs[j]);
1145 }
1146 av_freep(&fg->inputs);
1147 for (int j = 0; j < fg->nb_outputs; j++) {
1148 OutputFilter *ofilter = fg->outputs[j];
1149 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1150
1152 av_dict_free(&ofp->sws_opts);
1153 av_dict_free(&ofp->swr_opts);
1154
1155 av_freep(&ofilter->linklabel);
1156 av_freep(&ofilter->name);
1157 av_freep(&ofilter->output_name);
1158 av_freep(&ofilter->apad);
1160 if (ofp->reinit_opts_fifo) {
1161 while (av_fifo_read(ofp->reinit_opts_fifo, &ofp->reinit_opts, 1) >= 0)
1164 }
1167 av_freep(&fg->outputs[j]);
1168 }
1169 av_freep(&fg->outputs);
1170 av_freep(&fg->graph_desc);
1171
1172 av_frame_free(&fgp->frame);
1173 av_frame_free(&fgp->frame_enc);
1174
1175 av_freep(pfg);
1176}
1177
1178static const char *fg_item_name(void *obj)
1179{
1180 const FilterGraphPriv *fgp = obj;
1181
1182 return fgp->log_name;
1183}
1184
1185static const AVClass fg_class = {
1186 .class_name = "FilterGraph",
1187 .version = LIBAVUTIL_VERSION_INT,
1188 .item_name = fg_item_name,
1189 .category = AV_CLASS_CATEGORY_FILTER,
1190};
1191
1192int fg_create(FilterGraph **pfg, char **graph_desc, Scheduler *sch,
1194{
1195 FilterGraphPriv *fgp;
1196 FilterGraph *fg;
1197
1199 AVFilterGraph *graph;
1200 int ret = 0;
1201
1202 fgp = av_mallocz(sizeof(*fgp));
1203 if (!fgp) {
1204 av_freep(graph_desc);
1205 return AVERROR(ENOMEM);
1206 }
1207 fg = &fgp->fg;
1208
1209 if (pfg) {
1210 *pfg = fg;
1211 fg->index = -1;
1212 } else {
1214 if (ret < 0) {
1215 av_freep(graph_desc);
1216 av_freep(&fgp);
1217 return ret;
1218 }
1219
1220 fg->index = nb_filtergraphs - 1;
1221 }
1222
1223 fg->class = &fg_class;
1224 fg->graph_desc = *graph_desc;
1226 fgp->nb_threads = -1;
1227 fgp->sch = sch;
1228
1229 *graph_desc = NULL;
1230
1231 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
1232
1233 fgp->frame = av_frame_alloc();
1234 fgp->frame_enc = av_frame_alloc();
1235 if (!fgp->frame || !fgp->frame_enc)
1236 return AVERROR(ENOMEM);
1237
1238 /* this graph is only used for determining the kinds of inputs
1239 * and outputs we have, and is discarded on exit from this function */
1240 graph = avfilter_graph_alloc();
1241 if (!graph)
1242 return AVERROR(ENOMEM);;
1243 graph->nb_threads = 1;
1244
1245 ret = graph_parse(fg, graph, fg->graph_desc, &inputs, &outputs,
1247 if (ret < 0)
1248 goto fail;
1249
1250 for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
1251 InputFilter *const ifilter = ifilter_alloc(fg);
1252
1253 if (!ifilter) {
1254 ret = AVERROR(ENOMEM);
1255 goto fail;
1256 }
1257
1258 ifilter->linklabel = cur->name;
1259 cur->name = NULL;
1260
1261 ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads,
1262 cur->pad_idx);
1263
1264 if (ifilter->type != AVMEDIA_TYPE_VIDEO && ifilter->type != AVMEDIA_TYPE_AUDIO) {
1265 av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported "
1266 "currently.\n");
1267 ret = AVERROR(ENOSYS);
1268 goto fail;
1269 }
1270
1271 ifilter->name = describe_filter_link(fg, cur, 1);
1272 if (!ifilter->name) {
1273 ret = AVERROR(ENOMEM);
1274 goto fail;
1275 }
1276 }
1277
1278 for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
1279 const enum AVMediaType type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
1280 cur->pad_idx);
1281 OutputFilter *const ofilter = ofilter_alloc(fg, type);
1282 OutputFilterPriv *ofp;
1283
1284 if (!ofilter) {
1285 ret = AVERROR(ENOMEM);
1286 goto fail;
1287 }
1288 ofp = ofp_from_ofilter(ofilter);
1289
1290 ofilter->linklabel = cur->name;
1291 cur->name = NULL;
1292
1293 ofilter->name = describe_filter_link(fg, cur, 0);
1294 if (!ofilter->name) {
1295 ret = AVERROR(ENOMEM);
1296 goto fail;
1297 }
1298
1299 // opts should only be needed in this function to fill fields from filtergraphs
1300 // whose output is meant to be treated as if it was stream, e.g. merged HEIF
1301 // tile groups.
1302 if (opts) {
1303 ofp->flags = opts->flags;
1304 ofp->side_data = opts->side_data;
1305 ofp->nb_side_data = opts->nb_side_data;
1306
1307 ofp->crop_top = opts->crop_top;
1308 ofp->crop_bottom = opts->crop_bottom;
1309 ofp->crop_left = opts->crop_left;
1310 ofp->crop_right = opts->crop_right;
1311
1314 if (sd)
1315 memcpy(ofp->displaymatrix, sd->data, sizeof(ofp->displaymatrix));
1316 }
1317 }
1318
1319 if (!fg->nb_outputs) {
1320 av_log(fg, AV_LOG_FATAL, "A filtergraph has zero outputs, this is not supported\n");
1321 ret = AVERROR(ENOSYS);
1322 goto fail;
1323 }
1324
1325 ret = sch_add_filtergraph(sch, fg->nb_inputs, fg->nb_outputs,
1326 filter_thread, fgp);
1327 if (ret < 0)
1328 goto fail;
1329 fgp->sch_idx = ret;
1330
1331fail:
1334 avfilter_graph_free(&graph);
1335
1336 if (ret < 0)
1337 return ret;
1338
1339 return 0;
1340}
1341
1343 InputStream *ist,
1344 char **graph_desc,
1345 Scheduler *sch, unsigned sched_idx_enc,
1347{
1348 const enum AVMediaType type = ist->par->codec_type;
1349 FilterGraph *fg;
1350 FilterGraphPriv *fgp;
1351 int ret;
1352
1353 ret = fg_create(pfg, graph_desc, sch, NULL);
1354 if (ret < 0)
1355 return ret;
1356 fg = *pfg;
1357 fgp = fgp_from_fg(fg);
1358
1359 fgp->is_simple = 1;
1360
1361 snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf%s",
1363
1364 if (fg->nb_inputs != 1 || fg->nb_outputs != 1) {
1365 av_log(fg, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
1366 "to have exactly 1 input and 1 output. "
1367 "However, it had %d input(s) and %d output(s). Please adjust, "
1368 "or use a complex filtergraph (-filter_complex) instead.\n",
1369 *graph_desc, fg->nb_inputs, fg->nb_outputs);
1370 return AVERROR(EINVAL);
1371 }
1372 if (fg->outputs[0]->type != type) {
1373 av_log(fg, AV_LOG_ERROR, "Filtergraph has a %s output, cannot connect "
1374 "it to %s output stream\n",
1377 return AVERROR(EINVAL);
1378 }
1379
1380 ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs);
1381 if (ret < 0)
1382 return ret;
1383
1384 ret = ofilter_bind_enc(fg->outputs[0], sched_idx_enc, opts);
1385 if (ret < 0)
1386 return ret;
1387
1388 if (opts->nb_threads >= 0)
1389 fgp->nb_threads = opts->nb_threads;
1390
1391 return 0;
1392}
1393
1394static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int commit)
1395{
1396 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1397 InputStream *ist = NULL;
1398 enum AVMediaType type = ifilter->type;
1399 ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE };
1400 const char *spec;
1401 char *p;
1402 int i, ret;
1403
1404 if (ifilter->linklabel && !strncmp(ifilter->linklabel, "dec:", 4)) {
1405 // bind to a standalone decoder
1406 int dec_idx;
1407
1408 dec_idx = strtol(ifilter->linklabel + 4, &p, 0);
1409 if (dec_idx < 0 || dec_idx >= nb_decoders) {
1410 av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n",
1411 dec_idx, fg->graph_desc);
1412 return AVERROR(EINVAL);
1413 }
1414
1415 if (type == AVMEDIA_TYPE_VIDEO) {
1416 spec = *p == ':' ? p + 1 : p;
1417 ret = view_specifier_parse(&spec, &vs);
1418 if (ret < 0)
1419 return ret;
1420 }
1421
1422 ret = ifilter_bind_dec(ifp, decoders[dec_idx], &vs);
1423 if (ret < 0)
1424 av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n",
1425 ifilter->name);
1426 return ret;
1427 } else if (ifilter->linklabel) {
1430 AVStream *st = NULL;
1431 int file_idx;
1432
1433 // try finding an unbound filtergraph output with this label
1434 for (int i = 0; i < nb_filtergraphs; i++) {
1435 FilterGraph *fg_src = filtergraphs[i];
1436
1437 if (fg == fg_src)
1438 continue;
1439
1440 for (int j = 0; j < fg_src->nb_outputs; j++) {
1441 OutputFilter *ofilter = fg_src->outputs[j];
1442
1443 if (!ofilter->bound && ofilter->linklabel &&
1444 !strcmp(ofilter->linklabel, ifilter->linklabel)) {
1445 if (commit) {
1447 "Binding input with label '%s' to filtergraph output %d:%d\n",
1448 ifilter->linklabel, i, j);
1449
1450 ret = ifilter_bind_fg(ifp, fg_src, j);
1451 if (ret < 0) {
1452 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %s\n",
1453 ifilter->linklabel);
1454 return ret;
1455 }
1456 } else
1457 ofp_from_ofilter(ofilter)->needed = 1;
1458 return 0;
1459 }
1460 }
1461 }
1462
1463 // bind to an explicitly specified demuxer stream
1464 file_idx = strtol(ifilter->linklabel, &p, 0);
1465 if (file_idx < 0 || file_idx >= nb_input_files) {
1466 av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
1467 file_idx, fg->graph_desc);
1468 return AVERROR(EINVAL);
1469 }
1470 s = input_files[file_idx]->ctx;
1471
1472 ret = stream_specifier_parse(&ss, *p == ':' ? p + 1 : p, 1, fg);
1473 if (ret < 0) {
1474 av_log(fg, AV_LOG_ERROR, "Invalid stream specifier: %s\n", p);
1475 return ret;
1476 }
1477
1478 if (type == AVMEDIA_TYPE_VIDEO) {
1479 spec = ss.remainder ? ss.remainder : "";
1480 ret = view_specifier_parse(&spec, &vs);
1481 if (ret < 0) {
1483 return ret;
1484 }
1485 }
1486
1487 for (i = 0; i < s->nb_streams; i++) {
1488 enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
1489 if (stream_type != type &&
1490 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
1491 type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
1492 continue;
1493 if (stream_specifier_match(&ss, s, s->streams[i], fg)) {
1494 st = s->streams[i];
1495 break;
1496 }
1497 }
1499 if (!st) {
1500 av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
1501 "matches no streams.\n", p, fg->graph_desc);
1502 return AVERROR(EINVAL);
1503 }
1504 ist = input_files[file_idx]->streams[st->index];
1505
1506 if (commit)
1508 "Binding input with label '%s' to input stream %d:%d\n",
1509 ifilter->linklabel, ist->file->index, ist->index);
1510 } else {
1511 // try finding an unbound filtergraph output
1512 for (int i = 0; i < nb_filtergraphs; i++) {
1513 FilterGraph *fg_src = filtergraphs[i];
1514
1515 if (fg == fg_src)
1516 continue;
1517
1518 for (int j = 0; j < fg_src->nb_outputs; j++) {
1519 OutputFilter *ofilter = fg_src->outputs[j];
1520
1521 if (!ofilter->bound) {
1522 if (commit) {
1524 "Binding unlabeled filtergraph input to filtergraph output %d:%d\n", i, j);
1525
1526 ret = ifilter_bind_fg(ifp, fg_src, j);
1527 if (ret < 0) {
1528 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %d:%d\n", i, j);
1529 return ret;
1530 }
1531 } else
1532 ofp_from_ofilter(ofilter)->needed = 1;
1533 return 0;
1534 }
1535 }
1536 }
1537
1538 ist = ist_find_unused(type);
1539 if (!ist) {
1540 av_log(fg, AV_LOG_FATAL,
1541 "Cannot find an unused %s input stream to feed the "
1542 "unlabeled input pad %s.\n",
1544 return AVERROR(EINVAL);
1545 }
1546
1547 if (commit)
1549 "Binding unlabeled input %d to input stream %d:%d\n",
1550 ifilter->index, ist->file->index, ist->index);
1551 }
1552 av_assert0(ist);
1553
1554 if (commit) {
1555 ret = ifilter_bind_ist(ifilter, ist, &vs);
1556 if (ret < 0) {
1557 av_log(fg, AV_LOG_ERROR,
1558 "Error binding an input stream to complex filtergraph input %s.\n",
1559 ifilter->name);
1560 return ret;
1561 }
1562 }
1563
1564 return 0;
1565}
1566
1567static int bind_inputs(FilterGraph *fg, int commit)
1568{
1569 // bind filtergraph inputs to input streams or other filtergraphs
1570 for (int i = 0; i < fg->nb_inputs; i++) {
1572 int ret;
1573
1574 if (ifp->bound)
1575 continue;
1576
1577 ret = fg_complex_bind_input(fg, &ifp->ifilter, commit);
1578 if (ret < 0)
1579 return ret;
1580 }
1581
1582 return 0;
1583}
1584
1586{
1587 int ret;
1588
1589 for (int i = 0; i < nb_filtergraphs; i++) {
1590 ret = bind_inputs(filtergraphs[i], 0);
1591 if (ret < 0)
1592 return ret;
1593 }
1594
1595 // check that all outputs were bound
1596 for (int i = nb_filtergraphs - 1; i >= 0; i--) {
1597 FilterGraph *fg = filtergraphs[i];
1599
1600 for (int j = 0; j < fg->nb_outputs; j++) {
1601 OutputFilter *output = fg->outputs[j];
1602 if (!ofp_from_ofilter(output)->needed) {
1603 if (!fg->is_internal) {
1604 av_log(fg, AV_LOG_FATAL,
1605 "Filter '%s' has output %d (%s) unconnected\n",
1606 output->name, j,
1607 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1608 return AVERROR(EINVAL);
1609 }
1610
1611 av_log(fg, AV_LOG_DEBUG,
1612 "Internal filter '%s' has output %d (%s) unconnected. Removing graph\n",
1613 output->name, j,
1614 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1618 if (nb_filtergraphs > 0)
1619 memmove(&filtergraphs[i],
1620 &filtergraphs[i + 1],
1621 (nb_filtergraphs - i) * sizeof(*filtergraphs));
1622 break;
1623 }
1624 }
1625 }
1626
1627 for (int i = 0; i < nb_filtergraphs; i++) {
1628 ret = bind_inputs(filtergraphs[i], 1);
1629 if (ret < 0)
1630 return ret;
1631 }
1632
1633 return 0;
1634}
1635
1637 AVFilterContext **last_filter, int *pad_idx,
1638 const char *filter_name)
1639{
1640 AVFilterGraph *graph = (*last_filter)->graph;
1642 const AVFilter *trim;
1643 enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
1644 const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
1645 int ret = 0;
1646
1647 if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
1648 return 0;
1649
1650 trim = avfilter_get_by_name(name);
1651 if (!trim) {
1652 av_log(logctx, AV_LOG_ERROR, "%s filter not present, cannot limit "
1653 "recording time.\n", name);
1655 }
1656
1657 ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
1658 if (!ctx)
1659 return AVERROR(ENOMEM);
1660
1661 if (duration != INT64_MAX) {
1662 ret = av_opt_set_int(ctx, "durationi", duration,
1664 }
1665 if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
1666 ret = av_opt_set_int(ctx, "starti", start_time,
1668 }
1669 if (ret < 0) {
1670 av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
1671 return ret;
1672 }
1673
1674 ret = avfilter_init_str(ctx, NULL);
1675 if (ret < 0)
1676 return ret;
1677
1678 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1679 if (ret < 0)
1680 return ret;
1681
1682 *last_filter = ctx;
1683 *pad_idx = 0;
1684 return 0;
1685}
1686
1687static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
1688 const char *filter_name, const char *args)
1689{
1690 AVFilterGraph *graph = (*last_filter)->graph;
1691 const AVFilter *filter = avfilter_get_by_name(filter_name);
1693 int ret;
1694
1695 if (!filter)
1696 return AVERROR_BUG;
1697
1699 filter,
1700 filter_name, args, NULL, graph);
1701 if (ret < 0)
1702 return ret;
1703
1704 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1705 if (ret < 0)
1706 return ret;
1707
1708 *last_filter = ctx;
1709 *pad_idx = 0;
1710 return 0;
1711}
1712
1714 OutputFilter *ofilter, AVFilterInOut *out)
1715{
1716 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1717 AVFilterContext *last_filter = out->filter_ctx;
1718 AVBPrint bprint;
1719 int pad_idx = out->pad_idx;
1720 int ret;
1721 char name[255];
1722
1723 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1724 ret = avfilter_graph_create_filter(&ofilter->filter,
1725 avfilter_get_by_name("buffersink"),
1726 name, NULL, NULL, graph);
1727
1728 if (ret < 0)
1729 return ret;
1730
1731 if (ofp->flags & OFILTER_FLAG_CROP) {
1732 char crop_buf[64];
1733 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
1734 ofp->crop_left, ofp->crop_right,
1735 ofp->crop_top, ofp->crop_bottom,
1736 ofp->crop_left, ofp->crop_top);
1737 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
1738 if (ret < 0)
1739 return ret;
1740 }
1741
1742 if (ofp->flags & OFILTER_FLAG_AUTOROTATE) {
1743 int32_t *displaymatrix = ofp->displaymatrix;
1744 double theta;
1745
1746 theta = get_rotation(displaymatrix);
1747
1748 if (fabs(theta - 90) < 1.0) {
1749 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1750 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
1751 } else if (fabs(theta - 180) < 1.0) {
1752 if (displaymatrix[0] < 0) {
1753 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
1754 if (ret < 0)
1755 return ret;
1756 }
1757 if (displaymatrix[4] < 0) {
1758 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1759 }
1760 } else if (fabs(theta - 270) < 1.0) {
1761 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1762 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
1763 } else if (fabs(theta) > 1.0) {
1764 char rotate_buf[64];
1765 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1766 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
1767 } else if (fabs(theta) < 1.0) {
1768 if (displaymatrix && displaymatrix[4] < 0) {
1769 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1770 }
1771 }
1772 if (ret < 0)
1773 return ret;
1774
1776 }
1777
1778 if ((ofp->width || ofp->height) && (ofp->flags & OFILTER_FLAG_AUTOSCALE) &&
1779 // skip add scale for hardware format
1780 !(ofp->format != AV_PIX_FMT_NONE &&
1782 char args[255];
1784 const AVDictionaryEntry *e = NULL;
1785
1786 snprintf(args, sizeof(args), "%d:%d",
1787 ofp->width, ofp->height);
1788
1789 while ((e = av_dict_iterate(ofp->sws_opts, e))) {
1790 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
1791 }
1792
1793 snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name);
1795 name, args, NULL, graph)) < 0)
1796 return ret;
1797 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1798 return ret;
1799
1800 last_filter = filter;
1801 pad_idx = 0;
1802 }
1803
1805 ofp->format != AV_PIX_FMT_NONE || !ofp->pix_fmts);
1807 choose_pix_fmts(ofp, &bprint);
1808 choose_color_spaces(ofp, &bprint);
1809 choose_color_ranges(ofp, &bprint);
1810 choose_alpha_modes(ofp, &bprint);
1811 if (!av_bprint_is_complete(&bprint))
1812 return AVERROR(ENOMEM);
1813
1814 if (bprint.len) {
1816
1818 avfilter_get_by_name("format"),
1819 "format", bprint.str, NULL, graph);
1820 av_bprint_finalize(&bprint, NULL);
1821 if (ret < 0)
1822 return ret;
1823 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1824 return ret;
1825
1826 last_filter = filter;
1827 pad_idx = 0;
1828 }
1829
1830 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1831 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1832 &last_filter, &pad_idx, name);
1833 if (ret < 0)
1834 return ret;
1835
1836
1837 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1838 return ret;
1839
1840 return 0;
1841}
1842
1844 OutputFilter *ofilter, AVFilterInOut *out)
1845{
1846 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1847 AVFilterContext *last_filter = out->filter_ctx;
1848 int pad_idx = out->pad_idx;
1849 AVBPrint args;
1850 char name[255];
1851 int ret;
1852
1853 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1854 ret = avfilter_graph_create_filter(&ofilter->filter,
1855 avfilter_get_by_name("abuffersink"),
1856 name, NULL, NULL, graph);
1857 if (ret < 0)
1858 return ret;
1859
1860#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
1861 AVFilterContext *filt_ctx; \
1862 \
1863 av_log(ofilter, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
1864 "similarly to -af " filter_name "=%s.\n", arg); \
1865 \
1866 ret = avfilter_graph_create_filter(&filt_ctx, \
1867 avfilter_get_by_name(filter_name), \
1868 filter_name, arg, NULL, graph); \
1869 if (ret < 0) \
1870 goto fail; \
1871 \
1872 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
1873 if (ret < 0) \
1874 goto fail; \
1875 \
1876 last_filter = filt_ctx; \
1877 pad_idx = 0; \
1878} while (0)
1880
1881 choose_sample_fmts(ofp, &args);
1882 choose_sample_rates(ofp, &args);
1883 choose_channel_layouts(ofp, &args);
1884 if (!av_bprint_is_complete(&args)) {
1885 ret = AVERROR(ENOMEM);
1886 goto fail;
1887 }
1888 if (args.len) {
1890
1891 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1893 avfilter_get_by_name("aformat"),
1894 name, args.str, NULL, graph);
1895 if (ret < 0)
1896 goto fail;
1897
1898 ret = avfilter_link(last_filter, pad_idx, format, 0);
1899 if (ret < 0)
1900 goto fail;
1901
1902 last_filter = format;
1903 pad_idx = 0;
1904 }
1905
1906 if (ofilter->apad)
1907 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1908
1909 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1910 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1911 &last_filter, &pad_idx, name);
1912 if (ret < 0)
1913 goto fail;
1914
1915 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1916 goto fail;
1917fail:
1918 av_bprint_finalize(&args, NULL);
1919
1920 return ret;
1921}
1922
1924 OutputFilter *ofilter, AVFilterInOut *out)
1925{
1926 switch (ofilter->type) {
1927 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1928 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fgp, graph, ofilter, out);
1929 default: av_assert0(0); return 0;
1930 }
1931}
1932
1934{
1935 ifp->sub2video.last_pts = INT64_MIN;
1936 ifp->sub2video.end_pts = INT64_MIN;
1937
1938 /* sub2video structure has been (re-)initialized.
1939 Mark it as such so that the system will be
1940 initialized with the first received heartbeat. */
1941 ifp->sub2video.initialize = 1;
1942}
1943
1945 InputFilter *ifilter, AVFilterInOut *in)
1946{
1947 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1948
1949 AVFilterContext *last_filter;
1950 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1951 const AVPixFmtDescriptor *desc;
1952 char name[255];
1953 int ret, pad_idx = 0;
1955 if (!par)
1956 return AVERROR(ENOMEM);
1957
1958 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1959 sub2video_prepare(ifp);
1960
1961 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1962 ifp->opts.name);
1963
1964 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1965 if (!ifilter->filter) {
1966 ret = AVERROR(ENOMEM);
1967 goto fail;
1968 }
1969
1970 par->format = ifp->format;
1971 par->time_base = ifp->time_base;
1972 par->frame_rate = ifp->opts.framerate;
1973 par->width = ifp->width;
1974 par->height = ifp->height;
1976 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
1977 par->color_space = ifp->color_space;
1978 par->color_range = ifp->color_range;
1979 par->alpha_mode = ifp->alpha_mode;
1980 par->hw_frames_ctx = ifp->hw_frames_ctx;
1981 par->side_data = ifp->side_data;
1982 par->nb_side_data = ifp->nb_side_data;
1983
1984 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1985 if (ret < 0)
1986 goto fail;
1987 av_freep(&par);
1988
1989 ret = avfilter_init_dict(ifilter->filter, NULL);
1990 if (ret < 0)
1991 goto fail;
1992
1993 last_filter = ifilter->filter;
1994
1997
1998 if ((ifp->opts.flags & IFILTER_FLAG_CROP)) {
1999 char crop_buf[64];
2000 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
2001 ifp->opts.crop_left, ifp->opts.crop_right,
2002 ifp->opts.crop_top, ifp->opts.crop_bottom,
2003 ifp->opts.crop_left, ifp->opts.crop_top);
2004 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
2005 if (ret < 0)
2006 return ret;
2007 }
2008
2009 // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
2010 ifp->displaymatrix_applied = 0;
2011 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
2012 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
2013 int32_t *displaymatrix = ifp->displaymatrix;
2014 double theta;
2015
2016 theta = get_rotation(displaymatrix);
2017
2018 if (fabs(theta - 90) < 1.0) {
2019 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2020 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
2021 } else if (fabs(theta - 180) < 1.0) {
2022 if (displaymatrix[0] < 0) {
2023 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
2024 if (ret < 0)
2025 return ret;
2026 }
2027 if (displaymatrix[4] < 0) {
2028 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2029 }
2030 } else if (fabs(theta - 270) < 1.0) {
2031 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2032 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
2033 } else if (fabs(theta) > 1.0) {
2034 char rotate_buf[64];
2035 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
2036 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
2037 } else if (fabs(theta) < 1.0) {
2038 if (displaymatrix && displaymatrix[4] < 0) {
2039 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2040 }
2041 }
2042 if (ret < 0)
2043 return ret;
2044
2045 ifp->displaymatrix_applied = 1;
2046 }
2047
2048 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
2049 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
2050 &last_filter, &pad_idx, name);
2051 if (ret < 0)
2052 return ret;
2053
2054 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2055 return ret;
2056 return 0;
2057fail:
2058 av_freep(&par);
2059
2060 return ret;
2061}
2062
2064 InputFilter *ifilter, AVFilterInOut *in)
2065{
2066 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2067 AVFilterContext *last_filter;
2069 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
2070 AVBPrint args;
2071 char name[255];
2072 int ret, pad_idx = 0;
2073
2075 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
2076 ifp->time_base.num, ifp->time_base.den,
2077 ifp->sample_rate,
2081 av_bprintf(&args, ":channel_layout=");
2083 } else
2084 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
2085 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
2086
2087 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
2088 name, args.str, NULL,
2089 graph)) < 0)
2090 return ret;
2092 if (!par)
2093 return AVERROR(ENOMEM);
2094 par->side_data = ifp->side_data;
2095 par->nb_side_data = ifp->nb_side_data;
2096 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2097 av_free(par);
2098 if (ret < 0)
2099 return ret;
2100 last_filter = ifilter->filter;
2101
2102 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
2103 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
2104 &last_filter, &pad_idx, name);
2105 if (ret < 0)
2106 return ret;
2107
2108 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2109 return ret;
2110
2111 return 0;
2112}
2113
2115 InputFilter *ifilter, AVFilterInOut *in)
2116{
2117 switch (ifilter->type) {
2118 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
2119 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
2120 default: av_assert0(0); return 0;
2121 }
2122}
2123
2125{
2126 for (int i = 0; i < fg->nb_outputs; i++)
2127 fg->outputs[i]->filter = NULL;
2128 for (int i = 0; i < fg->nb_inputs; i++)
2129 fg->inputs[i]->filter = NULL;
2131}
2132
2134{
2135 return f->nb_inputs == 0 &&
2136 (!strcmp(f->filter->name, "buffer") ||
2137 !strcmp(f->filter->name, "abuffer"));
2138}
2139
2141{
2142 for (unsigned i = 0; i < graph->nb_filters; i++) {
2143 const AVFilterContext *f = graph->filters[i];
2144
2145 /* in addition to filters flagged as meta, also
2146 * disregard sinks and buffersources (but not other sources,
2147 * since they introduce data we are not aware of)
2148 */
2149 if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
2150 f->nb_outputs == 0 ||
2152 return 0;
2153 }
2154 return 1;
2155}
2156
2157static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
2158
2160{
2161 FilterGraphPriv *fgp = fgp_from_fg(fg);
2162 AVBufferRef *hw_device;
2163 AVFilterInOut *inputs, *outputs, *cur;
2164 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
2165 int have_input_eof = 0;
2166 const char *graph_desc = fg->graph_desc;
2167
2168 cleanup_filtergraph(fg, fgt);
2169 fgt->graph = avfilter_graph_alloc();
2170 if (!fgt->graph)
2171 return AVERROR(ENOMEM);
2172
2173 if (simple) {
2175
2176 if (filter_nbthreads) {
2177 ret = av_opt_set(fgt->graph, "threads", filter_nbthreads, 0);
2178 if (ret < 0)
2179 goto fail;
2180 } else if (fgp->nb_threads >= 0) {
2181 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
2182 if (ret < 0)
2183 return ret;
2184 }
2185
2186 if (av_dict_count(ofp->sws_opts)) {
2187 ret = av_dict_get_string(ofp->sws_opts,
2188 &fgt->graph->scale_sws_opts,
2189 '=', ':');
2190 if (ret < 0)
2191 goto fail;
2192 }
2193
2194 if (av_dict_count(ofp->swr_opts)) {
2195 char *args;
2196 ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
2197 if (ret < 0)
2198 goto fail;
2199 av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
2200 av_free(args);
2201 }
2202 } else {
2204 }
2205
2207 ret = av_opt_set_int(fgt->graph, "max_buffered_frames", filter_buffered_frames, 0);
2208 if (ret < 0)
2209 return ret;
2210 }
2211
2212 hw_device = hw_device_for_filter();
2213
2214 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
2215 if (ret < 0)
2216 goto fail;
2217
2218 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
2219 if ((ret = configure_input_filter(fg, fgt->graph, fg->inputs[i], cur)) < 0) {
2222 goto fail;
2223 }
2225
2226 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
2227 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
2228 if (ret < 0) {
2230 goto fail;
2231 }
2232 }
2234
2235 if (fgp->disable_conversions)
2237 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
2238 goto fail;
2239
2240 fgp->is_meta = graph_is_meta(fgt->graph);
2241
2242 /* limit the lists of allowed formats to the ones selected, to
2243 * make sure they stay the same if the filtergraph is reconfigured later */
2244 for (int i = 0; i < fg->nb_outputs; i++) {
2245 const AVFrameSideData *const *sd;
2246 int nb_sd;
2247 OutputFilter *ofilter = fg->outputs[i];
2248 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2249 AVFilterContext *sink = ofilter->filter;
2250
2251 ofp->format = av_buffersink_get_format(sink);
2252
2253 ofp->width = av_buffersink_get_w(sink);
2254 ofp->height = av_buffersink_get_h(sink);
2258
2259 // If the timing parameters are not locked yet, get the tentative values
2260 // here but don't lock them. They will only be used if no output frames
2261 // are ever produced.
2262 if (!ofp->tb_out_locked) {
2264 if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
2265 fr.num > 0 && fr.den > 0)
2266 ofp->fps.framerate = fr;
2268 }
2270
2273 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
2274 if (ret < 0)
2275 goto fail;
2276 sd = av_buffersink_get_side_data(sink, &nb_sd);
2277 if (nb_sd)
2278 for (int j = 0; j < nb_sd; j++) {
2281 if (ret < 0) {
2283 goto fail;
2284 }
2285 }
2286 }
2287
2288 for (int i = 0; i < fg->nb_inputs; i++) {
2289 InputFilter *ifilter = fg->inputs[i];
2291 AVFrame *tmp;
2292 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2293 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2294 sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2295 } else {
2296 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2297 if (ifp->displaymatrix_applied)
2299 }
2300 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2301 }
2303 if (ret < 0)
2304 goto fail;
2305 }
2306 }
2307
2308 /* send the EOFs for the finished inputs */
2309 for (int i = 0; i < fg->nb_inputs; i++) {
2310 InputFilter *ifilter = fg->inputs[i];
2311 if (fgt->eof_in[i]) {
2312 ret = av_buffersrc_add_frame(ifilter->filter, NULL);
2313 if (ret < 0)
2314 goto fail;
2315 have_input_eof = 1;
2316 }
2317 }
2318
2319 if (have_input_eof) {
2320 // make sure the EOF propagates to the end of the graph
2322 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
2323 goto fail;
2324 }
2325
2326 return 0;
2327fail:
2328 cleanup_filtergraph(fg, fgt);
2329 return ret;
2330}
2331
2333{
2334 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2335 AVFrameSideData *sd;
2336 int ret;
2337
2338 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2339 if (ret < 0)
2340 return ret;
2341
2342 ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } :
2344 frame->time_base;
2345
2346 ifp->format = frame->format;
2347
2348 ifp->width = frame->width;
2349 ifp->height = frame->height;
2350 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2351 ifp->color_space = frame->colorspace;
2352 ifp->color_range = frame->color_range;
2353 ifp->alpha_mode = frame->alpha_mode;
2354
2355 ifp->sample_rate = frame->sample_rate;
2356 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2357 if (ret < 0)
2358 return ret;
2359
2361 for (int i = 0; i < frame->nb_side_data; i++) {
2362 const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
2363
2364 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
2365 continue;
2366
2368 &ifp->nb_side_data,
2369 frame->side_data[i], 0);
2370 if (ret < 0)
2371 return ret;
2372 }
2373
2375 if (sd) {
2376 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2379 }
2380 ifp->displaymatrix_present = !!sd;
2381
2382 /* Copy downmix related side data to InputFilterPriv so it may be propagated
2383 * to the filter chain even though it's not "global", as filters like aresample
2384 * require this information during init and not when remixing a frame */
2386 if (sd) {
2388 &ifp->nb_side_data, sd, 0);
2389 if (ret < 0)
2390 return ret;
2391 memcpy(&ifp->downmixinfo, sd->data, sizeof(ifp->downmixinfo));
2392 }
2393 ifp->downmixinfo_present = !!sd;
2395 if (sd) {
2397 &ifp->nb_side_data, sd, 0);
2398 if (ret < 0)
2399 return ret;
2400 ret = av_buffer_replace(&ifp->downmixmatrix, sd->buf);
2401 if (ret < 0)
2402 return ret;
2403 ifp->downmixmatrix_size = sd->size;
2404 }
2405 ifp->downmixmatrix_present = !!sd;
2406
2407 return 0;
2408}
2409
2411{
2412 const OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2413 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2414
2415 if (!ifp->opts.framerate.num) {
2416 ifp->opts.framerate = ofp->fps.framerate;
2417 if (ifp->opts.framerate.num > 0 && ifp->opts.framerate.den > 0)
2418 ifp->opts.flags |= IFILTER_FLAG_CFR;
2419 }
2420
2421 for (int i = 0; i < ofp->nb_side_data; i++) {
2422 int ret = av_frame_side_data_clone(&ifp->side_data, &ifp->nb_side_data,
2424 if (ret < 0)
2425 return ret;
2426 }
2427
2428 return 0;
2429}
2430
2432{
2433 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2434 return fgp->is_simple;
2435}
2436
2438 double time, const char *target,
2439 const char *command, const char *arg, int all_filters)
2440{
2441 int ret;
2442
2443 if (!graph)
2444 return;
2445
2446 if (time < 0) {
2447 char response[4096];
2448 ret = avfilter_graph_send_command(graph, target, command, arg,
2449 response, sizeof(response),
2450 all_filters ? 0 : AVFILTER_CMD_FLAG_ONE);
2451 fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s",
2452 fg->index, ret, response);
2453 } else if (!all_filters) {
2454 fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
2455 } else {
2456 ret = avfilter_graph_queue_command(graph, target, command, arg, 0, time);
2457 if (ret < 0)
2458 fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
2459 }
2460}
2461
2462static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2463{
2464 int nb_requests, nb_requests_max = -1;
2465 int best_input = -1;
2466
2467 for (int i = 0; i < fg->nb_inputs; i++) {
2468 InputFilter *ifilter = fg->inputs[i];
2469
2470 if (fgt->eof_in[i])
2471 continue;
2472
2473 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2474 if (nb_requests > nb_requests_max) {
2475 nb_requests_max = nb_requests;
2476 best_input = i;
2477 }
2478 }
2479
2480 av_assert0(best_input >= 0);
2481
2482 return best_input;
2483}
2484
2486{
2487 OutputFilter *ofilter = &ofp->ofilter;
2488 FPSConvContext *fps = &ofp->fps;
2489 AVRational tb = (AVRational){ 0, 0 };
2490 AVRational fr;
2491 const FrameData *fd;
2492
2493 fd = frame_data_c(frame);
2494
2495 // apply -enc_time_base
2496 if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
2497 (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
2498 av_log(ofp, AV_LOG_ERROR,
2499 "Demuxing timebase not available - cannot use it for encoding\n");
2500 return AVERROR(EINVAL);
2501 }
2502
2503 switch (ofp->enc_timebase.num) {
2504 case 0: break;
2505 case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
2506 case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
2507 default: tb = ofp->enc_timebase; break;
2508 }
2509
2510 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2511 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2512 goto finish;
2513 }
2514
2515 fr = fps->framerate;
2516 if (!fr.num) {
2518 if (fr_sink.num > 0 && fr_sink.den > 0)
2519 fr = fr_sink;
2520 }
2521
2522 if (fps->vsync_method == VSYNC_CFR || fps->vsync_method == VSYNC_VSCFR) {
2523 if (!fr.num && !fps->framerate_max.num) {
2524 fr = (AVRational){25, 1};
2526 "No information "
2527 "about the input framerate is available. Falling "
2528 "back to a default value of 25fps. Use the -r option "
2529 "if you want a different framerate.\n");
2530 }
2531
2532 if (fps->framerate_max.num &&
2533 (av_q2d(fr) > av_q2d(fps->framerate_max) ||
2534 !fr.den))
2535 fr = fps->framerate_max;
2536 }
2537
2538 if (fr.num > 0) {
2539 if (fps->framerate_supported) {
2540 int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
2541 fr = fps->framerate_supported[idx];
2542 }
2543 if (fps->framerate_clip) {
2544 av_reduce(&fr.num, &fr.den,
2545 fr.num, fr.den, fps->framerate_clip);
2546 }
2547 }
2548
2549 if (!(tb.num > 0 && tb.den > 0))
2550 tb = av_inv_q(fr);
2551 if (!(tb.num > 0 && tb.den > 0))
2552 tb = frame->time_base;
2553
2554 fps->framerate = fr;
2555finish:
2556 ofp->tb_out = tb;
2557 ofp->tb_out_locked = 1;
2558
2559 return 0;
2560}
2561
2562static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2564{
2565 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2566
2567 AVRational tb = tb_dst;
2568 AVRational filter_tb = frame->time_base;
2569 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2570
2571 if (frame->pts == AV_NOPTS_VALUE)
2572 goto early_exit;
2573
2574 tb.den <<= extra_bits;
2575 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2577 float_pts /= 1 << extra_bits;
2578 // when float_pts is not exactly an integer,
2579 // avoid exact midpoints to reduce the chance of rounding differences, this
2580 // can be removed in case the fps code is changed to work with integers
2581 if (float_pts != llrint(float_pts))
2582 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2583
2584 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2586 frame->time_base = tb_dst;
2587
2588early_exit:
2589
2590 if (debug_ts) {
2591 av_log(logctx, AV_LOG_INFO,
2592 "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
2593 frame ? av_ts2str(frame->pts) : "NULL",
2594 av_ts2timestr(frame->pts, &tb_dst),
2595 float_pts, tb_dst.num, tb_dst.den);
2596 }
2597
2598 return float_pts;
2599}
2600
2602{
2603 int64_t max2, min2, m;
2604
2605 if (a >= b) {
2606 max2 = a;
2607 min2 = b;
2608 } else {
2609 max2 = b;
2610 min2 = a;
2611 }
2612 m = (c >= max2) ? max2 : c;
2613
2614 return (m >= min2) ? m : min2;
2615}
2616
2617
2618/* Convert frame timestamps to the encoder timebase and decide how many times
2619 * should this (and possibly previous) frame be repeated in order to conform to
2620 * desired target framerate (if any).
2621 */
2623 int64_t *nb_frames, int64_t *nb_frames_prev)
2624{
2625 OutputFilter *ofilter = &ofp->ofilter;
2626 FPSConvContext *fps = &ofp->fps;
2627 double delta0, delta, sync_ipts, duration;
2628
2629 if (!frame) {
2630 *nb_frames_prev = *nb_frames = median3(fps->frames_prev_hist[0],
2631 fps->frames_prev_hist[1],
2632 fps->frames_prev_hist[2]);
2633
2634 if (!*nb_frames && fps->last_dropped) {
2635 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2636 fps->last_dropped++;
2637 }
2638
2639 goto finish;
2640 }
2641
2642 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2643
2644 sync_ipts = adjust_frame_pts_to_encoder_tb(ofilter->graph, frame,
2645 ofp->tb_out, ofp->ts_offset);
2646 /* delta0 is the "drift" between the input frame and
2647 * where it would fall in the output. */
2648 delta0 = sync_ipts - ofp->next_pts;
2649 delta = delta0 + duration;
2650
2651 // tracks the number of times the PREVIOUS frame should be duplicated,
2652 // mostly for variable framerate (VFR)
2653 *nb_frames_prev = 0;
2654 /* by default, we output a single frame */
2655 *nb_frames = 1;
2656
2657 if (delta0 < 0 &&
2658 delta > 0 &&
2660 if (delta0 < -0.6) {
2661 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2662 } else
2663 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2664 sync_ipts = ofp->next_pts;
2665 duration += delta0;
2666 delta0 = 0;
2667 }
2668
2669 switch (fps->vsync_method) {
2670 case VSYNC_VSCFR:
2671 if (fps->frame_number == 0 && delta0 >= 0.5) {
2672 av_log(ofp, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
2673 delta = duration;
2674 delta0 = 0;
2675 ofp->next_pts = llrint(sync_ipts);
2676 }
2678 case VSYNC_CFR:
2679 // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
2681 *nb_frames = 0;
2682 } else if (delta < -1.1)
2683 *nb_frames = 0;
2684 else if (delta > 1.1) {
2685 *nb_frames = llrintf(delta);
2686 if (delta0 > 1.1)
2687 *nb_frames_prev = llrintf(delta0 - 0.6);
2688 }
2689 frame->duration = 1;
2690 break;
2691 case VSYNC_VFR:
2692 if (delta <= -0.6)
2693 *nb_frames = 0;
2694 else if (delta > 0.6)
2695 ofp->next_pts = llrint(sync_ipts);
2696 frame->duration = llrint(duration);
2697 break;
2698 case VSYNC_PASSTHROUGH:
2699 ofp->next_pts = llrint(sync_ipts);
2700 frame->duration = llrint(duration);
2701 break;
2702 default:
2703 av_assert0(0);
2704 }
2705
2706finish:
2707 memmove(fps->frames_prev_hist + 1,
2708 fps->frames_prev_hist,
2709 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2710 fps->frames_prev_hist[0] = *nb_frames_prev;
2711
2712 if (*nb_frames_prev == 0 && fps->last_dropped) {
2713 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2715 "*** dropping frame %"PRId64" at ts %"PRId64"\n",
2716 fps->frame_number, fps->last_frame->pts);
2717 }
2718 if (*nb_frames > (*nb_frames_prev && fps->last_dropped) + (*nb_frames > *nb_frames_prev)) {
2719 uint64_t nb_frames_dup;
2720 if (*nb_frames > dts_error_threshold * 30) {
2721 av_log(ofp, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
2722 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2723 *nb_frames = 0;
2724 return;
2725 }
2726 nb_frames_dup = atomic_fetch_add(&ofilter->nb_frames_dup,
2727 *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev));
2728 av_log(ofp, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
2729 if (nb_frames_dup > fps->dup_warning) {
2730 av_log(ofp, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
2731 fps->dup_warning *= 10;
2732 }
2733 }
2734
2735 fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
2736 fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
2737}
2738
2740{
2742
2743 if (!ifp->eof) {
2745 ifp->eof = 1;
2746 }
2747}
2748
2750{
2752 int ret;
2753
2754 // we are finished and no frames were ever seen at this output,
2755 // at least initialize the encoder with a dummy frame
2756 if (!fgt->got_frame) {
2757 AVFrame *frame = fgt->frame;
2758 FrameData *fd;
2759
2760 frame->time_base = ofp->tb_out;
2761 frame->format = ofp->format;
2762
2763 frame->width = ofp->width;
2764 frame->height = ofp->height;
2765 frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
2766
2767 frame->sample_rate = ofp->sample_rate;
2768 if (ofp->ch_layout.nb_channels) {
2769 ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
2770 if (ret < 0)
2771 return ret;
2772 }
2773
2774 fd = frame_data(frame);
2775 if (!fd)
2776 return AVERROR(ENOMEM);
2777
2779 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2780 ofp->side_data, ofp->nb_side_data, 0);
2781 if (ret < 0)
2782 return ret;
2783
2784 fd->frame_rate_filter = ofp->fps.framerate;
2785
2786 av_assert0(!frame->buf[0]);
2787
2789 "No filtered frames for output stream, trying to "
2790 "initialize anyway.\n");
2791
2792 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame);
2793 if (ret < 0) {
2795 return ret;
2796 }
2797 }
2798
2799 fgt->eof_out[ofp->ofilter.index] = 1;
2800
2801 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2802 return (ret == AVERROR_EOF) ? 0 : ret;
2803}
2804
2806 AVFrame *frame)
2807{
2809 AVFrame *frame_prev = ofp->fps.last_frame;
2810 enum AVMediaType type = ofp->ofilter.type;
2811
2812 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2813
2814 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2815 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2816
2817 for (int64_t i = 0; i < nb_frames; i++) {
2818 AVFrame *frame_out;
2819 int ret;
2820
2821 if (type == AVMEDIA_TYPE_VIDEO) {
2822 AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
2823 frame_prev : frame;
2824 if (!frame_in)
2825 break;
2826
2827 frame_out = fgp->frame_enc;
2828 ret = av_frame_ref(frame_out, frame_in);
2829 if (ret < 0)
2830 return ret;
2831
2832 frame_out->pts = ofp->next_pts;
2833
2834 if (ofp->fps.dropped_keyframe) {
2835 frame_out->flags |= AV_FRAME_FLAG_KEY;
2836 ofp->fps.dropped_keyframe = 0;
2837 }
2838 } else {
2839 frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
2840 av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
2842
2843 frame->time_base = ofp->tb_out;
2844 frame->duration = av_rescale_q(frame->nb_samples,
2845 (AVRational){ 1, frame->sample_rate },
2846 ofp->tb_out);
2847
2848 ofp->next_pts = frame->pts + frame->duration;
2849
2850 frame_out = frame;
2851 }
2852
2853 // send the frame to consumers
2854 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2855 if (ret < 0) {
2856 av_frame_unref(frame_out);
2857
2858 if (!fgt->eof_out[ofp->ofilter.index]) {
2859 fgt->eof_out[ofp->ofilter.index] = 1;
2860 fgp->nb_outputs_done++;
2861 }
2862
2863 return ret == AVERROR_EOF ? 0 : ret;
2864 }
2865
2866 if (type == AVMEDIA_TYPE_VIDEO) {
2867 ofp->fps.frame_number++;
2868 ofp->next_pts++;
2869
2870 if (i == nb_frames_prev && frame)
2871 frame->flags &= ~AV_FRAME_FLAG_KEY;
2872 }
2873
2874 fgt->got_frame = 1;
2875 }
2876
2877 if (frame && frame_prev) {
2878 av_frame_unref(frame_prev);
2879 av_frame_move_ref(frame_prev, frame);
2880 }
2881
2882 if (!frame)
2883 return close_output(ofp, fgt);
2884
2885 return 0;
2886}
2887
2889 AVFrame *frame)
2890{
2893 FrameData *fd;
2894 int ret;
2895
2898 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2899 ret = fg_output_frame(ofp, fgt, NULL);
2900 return (ret < 0) ? ret : 1;
2901 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2902 return 1;
2903 } else if (ret < 0) {
2905 "Error in retrieving a frame from the filtergraph: %s\n",
2906 av_err2str(ret));
2907 return ret;
2908 }
2909
2910 if (fgt->eof_out[ofp->ofilter.index]) {
2912 return 0;
2913 }
2914
2916
2917 if (debug_ts)
2918 av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
2919 av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
2920 frame->time_base.num, frame->time_base.den);
2921
2922 // Choose the output timebase the first time we get a frame.
2923 if (!ofp->tb_out_locked) {
2924 ret = choose_out_timebase(ofp, frame);
2925 if (ret < 0) {
2926 av_log(ofp, AV_LOG_ERROR, "Could not choose an output time base\n");
2928 return ret;
2929 }
2930 }
2931
2932 fd = frame_data(frame);
2933 if (!fd) {
2935 return AVERROR(ENOMEM);
2936 }
2937
2939 if (!fgt->got_frame) {
2940 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2941 ofp->side_data, ofp->nb_side_data, 0);
2942 if (ret < 0) {
2944 return ret;
2945 }
2946 }
2947
2949
2950 // only use bits_per_raw_sample passed through from the decoder
2951 // if the filtergraph did not touch the frame data
2952 if (!fgp->is_meta)
2953 fd->bits_per_raw_sample = 0;
2954
2955 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
2956 if (!frame->duration) {
2958 if (fr.num > 0 && fr.den > 0)
2959 frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
2960 }
2961
2962 fd->frame_rate_filter = ofp->fps.framerate;
2963 }
2964
2965 ret = fg_output_frame(ofp, fgt, frame);
2967 if (ret < 0)
2968 return ret;
2969
2970 return 0;
2971}
2972
2973/* retrieve all frames available at filtergraph outputs
2974 * and send them to consumers */
2976 AVFrame *frame)
2977{
2978 FilterGraphPriv *fgp = fgp_from_fg(fg);
2979
2980 // graph not configured, just select the input to request
2981 if (!fgt->graph) {
2982 for (int i = 0; i < fg->nb_inputs; i++) {
2984 if (ifp->format < 0 && !fgt->eof_in[i]) {
2985 fgt->next_in = i;
2986 return 0;
2987 }
2988 }
2989
2990 // This state - graph is not configured, but all inputs are either
2991 // initialized or EOF - should be unreachable because sending EOF to a
2992 // filter without even a fallback format should fail
2993 av_assert0(0);
2994 return AVERROR_BUG;
2995 }
2996
2997 if (fgp->nb_outputs_done < fg->nb_outputs) {
2998 int ret;
2999
3000 /* Reap all buffers present in the buffer sinks */
3001 for (int i = 0; i < fg->nb_outputs; i++) {
3003
3004 ret = 0;
3005 while (!ret) {
3006 ret = fg_output_step(ofp, fgt, frame);
3007 if (ret < 0)
3008 return ret;
3009 }
3010 }
3011
3012
3014 if (ret == AVERROR(EAGAIN)) {
3015 fgt->next_in = choose_input(fg, fgt);
3016 return 0;
3017 } else if (ret < 0) {
3018 if (ret == AVERROR_EOF)
3019 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
3020 else
3021 av_log(fg, AV_LOG_ERROR,
3022 "Error requesting a frame from the filtergraph: %s\n",
3023 av_err2str(ret));
3024 return ret;
3025 }
3026 fgt->next_in = fg->nb_inputs;
3027
3028 // return so that scheduler can rate-control us
3029 return 0;
3030 }
3031
3032 return AVERROR_EOF;
3033}
3034
3036{
3037 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3038 int64_t pts2;
3039
3040 /* subtitles seem to be usually muxed ahead of other streams;
3041 if not, subtracting a larger time here is necessary */
3042 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
3043
3044 /* do not send the heartbeat frame if the subtitle is already ahead */
3045 if (pts2 <= ifp->sub2video.last_pts)
3046 return;
3047
3048 if (pts2 >= ifp->sub2video.end_pts || ifp->sub2video.initialize)
3049 /* if we have hit the end of the current displayed subpicture,
3050 or if we need to initialize the system, update the
3051 overlaid subpicture and its start/end times */
3052 sub2video_update(ifp, pts2 + 1, NULL);
3053 else
3054 sub2video_push_ref(ifp, pts2);
3055}
3056
3058{
3059 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3060 int ret;
3061
3062 if (buffer) {
3063 AVFrame *tmp;
3064
3065 if (!frame)
3066 return 0;
3067
3068 tmp = av_frame_alloc();
3069 if (!tmp)
3070 return AVERROR(ENOMEM);
3071
3073
3074 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3075 if (ret < 0) {
3077 return ret;
3078 }
3079
3080 return 0;
3081 }
3082
3083 // heartbeat frame
3084 if (frame && !frame->buf[0]) {
3085 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
3086 return 0;
3087 }
3088
3089 if (!frame) {
3090 if (ifp->sub2video.end_pts < INT64_MAX)
3091 sub2video_update(ifp, INT64_MAX, NULL);
3092
3093 return av_buffersrc_add_frame(ifilter->filter, NULL);
3094 }
3095
3096 ifp->width = frame->width ? frame->width : ifp->width;
3097 ifp->height = frame->height ? frame->height : ifp->height;
3098
3099 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
3100
3101 return 0;
3102}
3103
3104static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
3106{
3107 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3108 int ret;
3109
3110 if (fgt->eof_in[ifilter->index])
3111 return 0;
3112
3113 fgt->eof_in[ifilter->index] = 1;
3114
3115 if (ifilter->filter) {
3116 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
3118
3120 if (ret < 0)
3121 return ret;
3122 } else {
3123 if (ifp->format < 0) {
3124 // the filtergraph was never configured, use the fallback parameters
3125 ifp->format = ifp->opts.fallback->format;
3126 ifp->sample_rate = ifp->opts.fallback->sample_rate;
3127 ifp->width = ifp->opts.fallback->width;
3128 ifp->height = ifp->opts.fallback->height;
3130 ifp->color_space = ifp->opts.fallback->colorspace;
3131 ifp->color_range = ifp->opts.fallback->color_range;
3132 ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
3133 ifp->time_base = ifp->opts.fallback->time_base;
3134
3136 &ifp->opts.fallback->ch_layout);
3137 if (ret < 0)
3138 return ret;
3139
3141 ret = clone_side_data(&ifp->side_data, &ifp->nb_side_data,
3142 ifp->opts.fallback->side_data,
3143 ifp->opts.fallback->nb_side_data, 0);
3144 if (ret < 0)
3145 return ret;
3146
3147 if (ifilter_has_all_input_formats(ifilter->graph)) {
3148 ret = configure_filtergraph(ifilter->graph, fgt);
3149 if (ret < 0) {
3150 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
3151 return ret;
3152 }
3153 }
3154 }
3155
3156 if (ifp->format < 0) {
3157 av_log(ifilter->graph, AV_LOG_ERROR,
3158 "Cannot determine format of input %s after EOF\n",
3159 ifp->opts.name);
3160 return AVERROR_INVALIDDATA;
3161 }
3162 }
3163
3164 return 0;
3165}
3166
3168 VIDEO_CHANGED = (1 << 0),
3169 AUDIO_CHANGED = (1 << 1),
3170 MATRIX_CHANGED = (1 << 2),
3173};
3174
3175static const char *unknown_if_null(const char *str)
3176{
3177 return str ? str : "unknown";
3178}
3179
3181 InputFilter *ifilter, AVFrame *frame, int force_reinit)
3182{
3183 FilterGraphPriv *fgp = fgp_from_fg(fg);
3184 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3185 FrameData *fd;
3186 AVFrameSideData *sd;
3187 int need_reinit = 0, ret;
3188
3189 /* determine if the parameters for this input changed */
3190 switch (ifilter->type) {
3191 case AVMEDIA_TYPE_AUDIO:
3192 if (ifp->format != frame->format ||
3193 ifp->sample_rate != frame->sample_rate ||
3194 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
3195 need_reinit |= AUDIO_CHANGED;
3196 break;
3197 case AVMEDIA_TYPE_VIDEO:
3198 if (ifp->format != frame->format ||
3199 ifp->width != frame->width ||
3200 ifp->height != frame->height ||
3201 ifp->color_space != frame->colorspace ||
3202 ifp->color_range != frame->color_range ||
3203 ifp->alpha_mode != frame->alpha_mode)
3204 need_reinit |= VIDEO_CHANGED;
3205 break;
3206 }
3207
3209 if (!ifp->displaymatrix_present ||
3210 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
3211 need_reinit |= MATRIX_CHANGED;
3212 } else if (ifp->displaymatrix_present)
3213 need_reinit |= MATRIX_CHANGED;
3214
3216 if (!ifp->downmixinfo_present ||
3217 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
3218 need_reinit |= DOWNMIX_CHANGED;
3219 } else if (ifp->downmixinfo_present)
3220 need_reinit |= DOWNMIX_CHANGED;
3221
3223 if (!ifp->downmixmatrix_present ||
3224 sd->size != ifp->downmixmatrix_size || memcmp(sd->data, ifp->downmixmatrix->data, sd->size))
3225 need_reinit |= DOWNMIX_CHANGED;
3226 } else if (ifp->downmixmatrix_present)
3227 need_reinit |= DOWNMIX_CHANGED;
3228
3229 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
3230 ifp->nb_dropped++;
3231 av_log_once(fg, AV_LOG_WARNING, AV_LOG_DEBUG, &ifp->drop_warned, "Avoiding reinit; dropping frame pts: %s bound for %s\n", av_ts2str(frame->pts), ifilter->name);
3233 return 0;
3234 }
3235
3236 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
3237 need_reinit = 0;
3238
3239 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
3240 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
3241 need_reinit |= HWACCEL_CHANGED;
3242
3243 if (need_reinit) {
3244 ret = ifilter_parameters_from_frame(ifilter, frame);
3245 if (ret < 0)
3246 return ret;
3247
3248 /* Inputs bound to a filtergraph output will have some fields unset.
3249 * Handle them here */
3250 if (ifp->ofilter_src) {
3251 ret = ifilter_parameters_from_ofilter(ifilter, ifp->ofilter_src);
3252 if (ret < 0)
3253 return ret;
3254 }
3255 }
3256
3257 /* (re)init the graph if possible, otherwise buffer the frame and return */
3258 if (need_reinit || force_reinit || !fgt->graph) {
3260
3261 if (!tmp)
3262 return AVERROR(ENOMEM);
3263
3266
3267 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3268 if (ret < 0)
3270
3271 return ret;
3272 }
3273
3274 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
3276 if (ret < 0)
3277 return ret;
3278
3279 if (fgt->graph) {
3280 AVBPrint reason;
3282 if (need_reinit & AUDIO_CHANGED) {
3283 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
3284 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
3285 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
3286 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
3287 }
3288 if (need_reinit & VIDEO_CHANGED) {
3289 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
3290 const char *color_space_name = av_color_space_name(frame->colorspace);
3291 const char *color_range_name = av_color_range_name(frame->color_range);
3292 const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
3293 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha, ",
3294 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
3295 unknown_if_null(color_space_name), frame->width, frame->height,
3296 unknown_if_null(alpha_mode));
3297 }
3298 if (need_reinit & MATRIX_CHANGED)
3299 av_bprintf(&reason, "display matrix changed, ");
3300 if (need_reinit & DOWNMIX_CHANGED)
3301 av_bprintf(&reason, "downmix medatata changed, ");
3302 if (need_reinit & HWACCEL_CHANGED)
3303 av_bprintf(&reason, "hwaccel changed, ");
3304 if (force_reinit)
3305 av_bprintf(&reason, "reinitialization arguments were provided, ");
3306 if (reason.len > 1)
3307 reason.str[reason.len - 2] = '\0'; // remove last comma
3308 av_log(fg, AV_LOG_INFO, "Reconfiguring filter graph%s%s\n", reason.len ? " because " : "", reason.str);
3309 } else {
3310 /* Choke all input to avoid buffering excessive frames while the
3311 * initial filter graph is being configured, and before we have a
3312 * preferred input */
3314 }
3315
3316 ret = configure_filtergraph(fg, fgt);
3317 if (ret < 0) {
3318 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
3319 return ret;
3320 }
3321 }
3322
3323 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
3324 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
3325 frame->time_base = ifp->time_base;
3326
3327 if (ifp->displaymatrix_applied)
3329
3330 fd = frame_data(frame);
3331 if (!fd)
3332 return AVERROR(ENOMEM);
3334
3337 if (ret < 0) {
3339 if (ret != AVERROR_EOF)
3340 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
3341 return ret;
3342 }
3343
3344 return 0;
3345}
3346
3347static void fg_thread_set_name(const FilterGraph *fg)
3348{
3349 char name[16];
3350 if (filtergraph_is_simple(fg)) {
3352 snprintf(name, sizeof(name), "%cf%s",
3354 ofp->ofilter.output_name);
3355 } else {
3356 snprintf(name, sizeof(name), "fc%d", fg->index);
3357 }
3358
3360}
3361
3363{
3364 if (fgt->frame_queue_out) {
3365 AVFrame *frame;
3366 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3369 }
3370
3371 av_frame_free(&fgt->frame);
3372 av_freep(&fgt->eof_in);
3373 av_freep(&fgt->eof_out);
3374
3376
3377 memset(fgt, 0, sizeof(*fgt));
3378}
3379
3381{
3382 memset(fgt, 0, sizeof(*fgt));
3383
3384 fgt->frame = av_frame_alloc();
3385 if (!fgt->frame)
3386 goto fail;
3387
3388 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3389 if (!fgt->eof_in)
3390 goto fail;
3391
3392 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3393 if (!fgt->eof_out)
3394 goto fail;
3395
3397 if (!fgt->frame_queue_out)
3398 goto fail;
3399
3400 return 0;
3401
3402fail:
3403 fg_thread_uninit(fgt);
3404 return AVERROR(ENOMEM);
3405}
3406
3408{
3409 int ret, reinit = 0;
3410
3411 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3413
3414 if (ofp->reinit_opts.pts == AV_NOPTS_VALUE && ofp->reinit_opts_fifo &&
3417 }
3418 if (ofp->reinit_opts.pts != AV_NOPTS_VALUE &&
3420 FrameData *fd = frame_data(fgt->frame);
3421 if (!fd)
3422 return AVERROR(ENOMEM);
3423
3425 ret = av_dict_copy(&fd->reinit_opts, ofp->reinit_opts.dict, 0);
3426 if (ret < 0)
3427 return ret;
3428
3429 av_opt_set_dict(ofp, &ofp->reinit_opts.dict);
3431
3434 else
3435 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
3436 reinit = 1;
3437 }
3438 }
3439
3440 return reinit;
3441}
3442
3443static int filter_thread(void *arg)
3444{
3445 FilterGraphPriv *fgp = arg;
3446 FilterGraph *fg = &fgp->fg;
3447
3449 int ret = 0, input_status = 0;
3450
3451 ret = fg_thread_init(&fgt, fg);
3452 if (ret < 0)
3453 goto finish;
3454
3456
3457 // if we have all input parameters the graph can now be configured
3459 ret = configure_filtergraph(fg, &fgt);
3460 if (ret < 0) {
3461 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3462 av_err2str(ret));
3463 goto finish;
3464 }
3465 }
3466
3467 while (1) {
3468 InputFilter *ifilter;
3469 InputFilterPriv *ifp = NULL;
3470 enum FrameOpaque o;
3471 unsigned input_idx = fgt.next_in;
3472
3473 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3474 &input_idx, fgt.frame);
3475 if (input_status == AVERROR_EOF) {
3476 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3477 break;
3478 } else if (input_status == AVERROR(EAGAIN)) {
3479 // should only happen when we didn't request any input
3480 av_assert0(input_idx == fg->nb_inputs);
3481 goto read_frames;
3482 }
3483 av_assert0(input_status >= 0);
3484
3485 o = (intptr_t)fgt.frame->opaque;
3486
3487 // message on the control stream
3488 if (input_idx == fg->nb_inputs) {
3490
3492
3493 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3494 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3495 fc->all_filters);
3496 av_frame_unref(fgt.frame);
3497 continue;
3498 }
3499
3500 // we received an input frame or EOF
3501 ifilter = fg->inputs[input_idx];
3502 ifp = ifp_from_ifilter(ifilter);
3503
3504 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3505 int hb_frame = input_status >= 0 && o == FRAME_OPAQUE_SUB_HEARTBEAT;
3506 ret = sub2video_frame(ifilter, (fgt.frame->buf[0] || hb_frame) ? fgt.frame : NULL,
3507 !fgt.graph);
3508 } else if (fgt.frame->buf[0]) {
3509 ret = check_reinit(fg, &fgt);
3510 if (ret >= 0)
3511 ret = send_frame(fg, &fgt, ifilter, fgt.frame, ret);
3512 } else {
3514 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3515 }
3516 av_frame_unref(fgt.frame);
3517 if (ret == AVERROR_EOF) {
3518 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3519 input_idx);
3520 close_input(ifp);
3521 continue;
3522 }
3523 if (ret < 0)
3524 goto finish;
3525
3527 // retrieve all newly available frames
3528 ret = read_frames(fg, &fgt, fgt.frame);
3529 if (ret == AVERROR_EOF) {
3530 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3531 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3532 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3533 break;
3534 } else if (ret < 0) {
3535 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3536 av_err2str(ret));
3537 goto finish;
3538 }
3539
3540 // ensure all inputs no longer accepting data are closed
3541 for (int i = 0; fgt.graph && i < fg->nb_inputs; i++) {
3544 close_input(ifp);
3545 }
3546 }
3547
3548 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3550
3551 if (fgt.eof_out[i] || !fgt.graph)
3552 continue;
3553
3554 ret = fg_output_frame(ofp, &fgt, NULL);
3555 if (ret < 0)
3556 goto finish;
3557 }
3558
3559finish:
3560
3562 print_filtergraph(fg, fgt.graph);
3563
3564 // EOF is normal termination
3565 if (ret == AVERROR_EOF)
3566 ret = 0;
3567
3568 fg_thread_uninit(&fgt);
3569
3570 return ret;
3571}
3572
3573void fg_send_command(FilterGraph *fg, double time, const char *target,
3574 const char *command, const char *arg, int all_filters)
3575{
3576 FilterGraphPriv *fgp = fgp_from_fg(fg);
3577 AVBufferRef *buf;
3579
3580 fc = av_mallocz(sizeof(*fc));
3581 if (!fc)
3582 return;
3583
3584 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3585 if (!buf) {
3586 av_freep(&fc);
3587 return;
3588 }
3589
3590 fc->target = av_strdup(target);
3591 fc->command = av_strdup(command);
3592 fc->arg = av_strdup(arg);
3593 if (!fc->target || !fc->command || !fc->arg) {
3594 av_buffer_unref(&buf);
3595 return;
3596 }
3597
3598 fc->time = time;
3599 fc->all_filters = all_filters;
3600
3601 fgp->frame->buf[0] = buf;
3602 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3603
3604 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3605}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static enum AVSampleFormat sample_fmts[]
Definition adpcmenc.c:933
static double val(void *priv, double ch)
Definition aeval.c:77
static const AVFilterPad inputs[]
Definition af_aap.c:299
static const AVFilterPad outputs[]
Definition af_aap.c:310
static const char *const format[]
Definition af_aiir.c:444
int32_t
static int64_t fsize(FILE *f)
Definition audiomatch.c:29
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Main libavfilter public API header.
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition avio.c:684
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition avio.c:559
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
char * av_asprintf(const char *fmt,...)
Definition avstring.c:115
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_AUTOMATIC
memory buffer sink API for audio and video
Memory buffer source API.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define ss(width, name, subs,...)
Definition cbs_vp9.c:202
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
int stream_specifier_parse(StreamSpecifier *ss, const char *spec, int allow_remainder, void *logctx)
Parse a stream specifier string into a form suitable for matching.
Definition cmdutils.c:1011
void * allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
Atomically add a new element to an array of pointers, i.e.
Definition cmdutils.c:1540
char * read_file_to_string(const char *filename)
Definition cmdutils.c:1571
unsigned stream_specifier_match(const StreamSpecifier *ss, const AVFormatContext *s, const AVStream *st, void *logctx)
Definition cmdutils.c:1226
double get_rotation(const int32_t *displaymatrix)
Definition cmdutils.c:1553
void stream_specifier_uninit(StreamSpecifier *ss)
Definition cmdutils.c:1002
#define av_clip
Definition common.h:100
#define FFSIGN(a)
Definition common.h:75
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static __device__ float fabs(float a)
static const int sample_rates[]
Definition dcaenc.h:34
static const uint16_t fc[]
Definition dcaenc.h:43
static AVFrame * frame
audio downmix medatata
const FrameData * frame_data_c(AVFrame *frame)
Definition ffmpeg.c:497
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition ffmpeg.c:491
int nb_filtergraphs
Definition ffmpeg.c:115
InputFile ** input_files
Definition ffmpeg.c:108
const AVIOInterruptCB int_cb
Definition ffmpeg.c:322
int nb_input_files
Definition ffmpeg.c:109
FilterGraph ** filtergraphs
Definition ffmpeg.c:114
Decoder ** decoders
Definition ffmpeg.c:117
int nb_decoders
Definition ffmpeg.c:118
char * filter_nbthreads
Definition ffmpeg_opt.c:73
int debug_ts
Definition ffmpeg_opt.c:67
@ IFILTER_FLAG_CFR
Definition ffmpeg.h:253
@ IFILTER_FLAG_DROPCHANGED
Definition ffmpeg.h:255
@ IFILTER_FLAG_REINIT
Definition ffmpeg.h:252
@ IFILTER_FLAG_CROP
Definition ffmpeg.h:254
@ IFILTER_FLAG_AUTOROTATE
Definition ffmpeg.h:251
int view_specifier_parse(const char **pspec, ViewSpecifier *vs)
Definition ffmpeg_opt.c:306
int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple, const ViewSpecifier *vs, InputFilterOptions *opts, SchedulerNode *src)
AVBufferRef * hw_device_for_filter(void)
Get a hardware device to be used with this filtergraph.
Definition ffmpeg_hw.c:298
@ LATENCY_PROBE_FILTER_POST
Definition ffmpeg.h:91
@ LATENCY_PROBE_FILTER_PRE
Definition ffmpeg.h:90
float dts_error_threshold
Definition ffmpeg_opt.c:57
@ VIEW_SPECIFIER_TYPE_NONE
Definition ffmpeg.h:105
int filter_complex_nbthreads
Definition ffmpeg_opt.c:74
float frame_drop_threshold
Definition ffmpeg_opt.c:59
FrameOpaque
Definition ffmpeg.h:75
@ FRAME_OPAQUE_SEND_COMMAND
Definition ffmpeg.h:78
@ FRAME_OPAQUE_SUB_HEARTBEAT
Definition ffmpeg.h:76
@ FRAME_OPAQUE_EOF
Definition ffmpeg.h:77
int print_graphs
Definition ffmpeg_opt.c:77
int auto_conversion_filters
Definition ffmpeg_opt.c:80
InputStream * ist_find_unused(enum AVMediaType type)
Find an unused input stream of given type.
@ OFILTER_FLAG_AUTOROTATE
Definition ffmpeg.h:290
@ OFILTER_FLAG_CROP
Definition ffmpeg.h:291
@ OFILTER_FLAG_AUDIO_24BIT
Definition ffmpeg.h:288
@ OFILTER_FLAG_AUTOSCALE
Definition ffmpeg.h:289
@ OFILTER_FLAG_DISABLE_CONVERT
Definition ffmpeg.h:286
VideoSyncMethod
Definition ffmpeg.h:56
@ VSYNC_VFR
Definition ffmpeg.h:60
@ VSYNC_PASSTHROUGH
Definition ffmpeg.h:58
@ VSYNC_CFR
Definition ffmpeg.h:59
@ VSYNC_VSCFR
Definition ffmpeg.h:61
char * print_graphs_file
Definition ffmpeg_opt.c:78
@ ENC_TIME_BASE_DEMUX
Definition ffmpeg.h:65
@ ENC_TIME_BASE_FILTER
Definition ffmpeg.h:66
int filter_buffered_frames
Definition ffmpeg_opt.c:75
int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts, const ViewSpecifier *vs, SchedulerNode *src)
ReinitReason
@ HWACCEL_CHANGED
@ DOWNMIX_CHANGED
@ AUDIO_CHANGED
@ VIDEO_CHANGED
@ MATRIX_CHANGED
static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int commit)
static int read_binary(void *logctx, const char *path, uint8_t **data, int *len)
static int ifilter_parameters_from_ofilter(InputFilter *ifilter, OutputFilter *ofilter)
static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static void fg_thread_set_name(const FilterGraph *fg)
static const FilterGraphPriv * cfgp_from_cfg(const FilterGraph *fg)
int fg_finalise_bindings(void)
static int bind_inputs(FilterGraph *fg, int commit)
static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
static int filter_thread(void *arg)
static void sub2video_prepare(InputFilterPriv *ifp)
static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec, const ViewSpecifier *vs)
static OutputFilterPriv * ofp_from_ofilter(OutputFilter *ofilter)
static FilterGraphPriv * fgp_from_fg(FilterGraph *fg)
static const AVClass fg_class
static void sub2video_push_ref(InputFilterPriv *ifp, int64_t pts)
static int configure_output_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
void fg_send_command(FilterGraph *fg, double time, const char *target, const char *command, const char *arg, int all_filters)
static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt, AVFrame *frame)
static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
static int parse_reinit_opts(AVFifo **pout, const char *opts, void *logctx)
static int filter_is_buffersrc(const AVFilterContext *f)
static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
static OutputFilter * ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
static int read_frames(FilterGraph *fg, FilterGraphThread *fgt, AVFrame *frame)
static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt, AVFrame *frame)
static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame, AVRational tb_dst, int64_t start_time)
static int fg_thread_init(FilterGraphThread *fgt, const FilterGraph *fg)
static void fg_thread_uninit(FilterGraphThread *fgt)
static InputFilter * ifilter_alloc(FilterGraph *fg)
static void close_input(InputFilterPriv *ifp)
static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp, const OutputFilterOptions *opts)
static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb)
static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
static const char * unknown_if_null(const char *str)
static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, AVSubtitleRect *r)
static int graph_parse(void *logctx, AVFilterGraph *graph, const char *desc, AVFilterInOut **inputs, AVFilterInOut **outputs, AVBufferRef *hw_device)
static int check_reinit(FilterGraph *fg, FilterGraphThread *fgt)
static char * describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
static const AVClass ofilter_class
static const char * fg_item_name(void *obj)
static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
int fg_create(FilterGraph **pfg, char **graph_desc, Scheduler *sch, const OutputFilterOptions *opts)
Create a new filtergraph in the global filtergraph list.
static int insert_trim(void *logctx, int64_t start_time, int64_t duration, AVFilterContext **last_filter, int *pad_idx, const char *filter_name)
static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer)
#define AUTO_INSERT_FILTER(opt_name, filter_name, arg)
static int send_frame(FilterGraph *fg, FilterGraphThread *fgt, InputFilter *ifilter, AVFrame *frame, int force_reinit)
static int ifilter_has_all_input_formats(FilterGraph *fg)
static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist, const ViewSpecifier *vs)
static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
int fg_create_simple(FilterGraph **pfg, InputStream *ist, char **graph_desc, Scheduler *sch, unsigned sched_idx_enc, const OutputFilterOptions *opts)
static int graph_is_meta(AVFilterGraph *graph)
int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, const OutputFilterOptions *opts)
static int sub2video_get_blank_frame(InputFilterPriv *ifp)
static void filter_command_free(void *opaque, uint8_t *data)
static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter, int64_t pts, AVRational tb)
static InputFilterPriv * ifp_from_ifilter(InputFilter *ifilter)
static int insert_filter(AVFilterContext **last_filter, int *pad_idx, const char *filter_name, const char *args)
#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name)
int filtergraph_is_simple(const FilterGraph *fg)
static int filter_opt_apply(void *logctx, AVFilterContext *f, const char *key, const char *val)
static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame, int64_t *nb_frames, int64_t *nb_frames_prev)
static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed, const AVChannelLayout *layout_requested)
static void send_command(FilterGraph *fg, AVFilterGraph *graph, double time, const char *target, const char *command, const char *arg, int all_filters)
static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts, const AVSubtitle *sub)
void fg_free(FilterGraph **pfg)
static const AVOption ofilter_options[]
static const char * ofilter_item_name(void *obj)
const char * key
int sch_filter_send(Scheduler *sch, unsigned fg_idx, unsigned out_idx, AVFrame *frame)
Called by filtergraph tasks to send a filtered frame or EOF to consumers.
int sch_add_filtergraph(Scheduler *sch, unsigned nb_inputs, unsigned nb_outputs, SchThreadFunc func, void *ctx)
Add a filtergraph to the scheduler.
void sch_filter_receive_finish(Scheduler *sch, unsigned fg_idx, unsigned in_idx)
Called by filter tasks to signal that a filter input will no longer accept input.
void sch_remove_filtergraph(Scheduler *sch, int idx)
int sch_filter_receive(Scheduler *sch, unsigned fg_idx, unsigned *in_idx, AVFrame *frame)
Called by filtergraph tasks to obtain frames for filtering.
void sch_filter_choke_inputs(Scheduler *sch, unsigned fg_idx)
Called by filtergraph tasks to choke all filter inputs, preventing them from receiving more frames un...
int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst)
int sch_filter_command(Scheduler *sch, unsigned fg_idx, AVFrame *frame)
#define SCH_FILTER_IN(filter, input)
#define SCH_ENC(encoder)
#define SCH_FILTER_OUT(filter, output)
static int clone_side_data(AVFrameSideData ***dst, int *nb_dst, AVFrameSideData *const *src, int nb_src, unsigned int flags)
Wrapper calling av_frame_side_data_clone() in a loop for all source entries.
static int64_t duration
Definition ffplay.c:330
static int64_t start_time
Definition ffplay.c:329
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph)
Definition graphprint.c:948
#define fail
Definition test.h:479
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition opt.h:302
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
Definition opt.h:306
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_CHLAYOUT
Underlying C type is AVChannelLayout.
Definition opt.h:330
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition avcodec.h:2043
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
int av_buffersink_get_sample_rate(const AVFilterContext *ctx)
int av_buffersink_get_format(const AVFilterContext *ctx)
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
Definition buffersink.c:254
const AVFrameSideData *const * av_buffersink_get_side_data(const AVFilterContext *ctx, int *nb_side_data)
Definition buffersink.c:287
enum AVAlphaMode av_buffersink_get_alpha_mode(const AVFilterContext *ctx)
int av_buffersink_get_h(const AVFilterContext *ctx)
AVRational av_buffersink_get_sample_aspect_ratio(const AVFilterContext *ctx)
enum AVColorSpace av_buffersink_get_colorspace(const AVFilterContext *ctx)
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
Definition buffersink.c:274
enum AVColorRange av_buffersink_get_color_range(const AVFilterContext *ctx)
AVRational av_buffersink_get_time_base(const AVFilterContext *ctx)
int av_buffersink_get_w(const AVFilterContext *ctx)
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Get a frame with filtered data from sink and put it in frame.
Definition buffersink.c:135
#define AV_BUFFERSINK_FLAG_NO_REQUEST
Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
Definition buffersink.h:92
int av_buffersrc_get_status(AVFilterContext *ctx)
Returns 0 or a negative AVERROR code.
Definition buffersrc.c:300
int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param)
Initialize the buffersrc or abuffersrc filter with the provided parameters.
Definition buffersrc.c:122
int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Add a frame to the buffer source.
Definition buffersrc.c:210
int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags)
Close the buffer source after EOF.
Definition buffersrc.c:291
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
Add a frame to the buffer source.
Definition buffersrc.c:191
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
Get the number of failed requests.
Definition buffersrc.c:352
AVBufferSrcParameters * av_buffersrc_parameters_alloc(void)
Allocate a new AVBufferSrcParameters instance.
Definition buffersrc.c:108
@ AV_BUFFERSRC_FLAG_KEEP_REF
Keep a reference to the frame.
Definition buffersrc.h:53
@ AV_BUFFERSRC_FLAG_PUSH
Immediately push the frame to the output.
Definition buffersrc.h:46
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:187
int avfilter_init_str(AVFilterContext *filter, const char *args)
Initialize a filter with the supplied parameters.
Definition avfilter.c:960
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
Definition allfilters.c:654
void avfilter_inout_free(AVFilterInOut **inout)
Free the supplied list of AVFilterInOut and set *inout to NULL.
Definition graphparser.c:76
enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
Get the type of an AVFilterPad.
Definition avfilter.c:993
int avfilter_graph_segment_parse(AVFilterGraph *graph, const char *graph_str, int flags, AVFilterGraphSegment **seg)
Parse a textual filtergraph description into an intermediate form.
int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts)
Queue a command for one or more filter instances.
void avfilter_graph_segment_free(AVFilterGraphSegment **seg)
Free the provided AVFilterGraphSegment and everything associated with it.
AVFilterContext * avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name)
Create a new filter instance in a filter graph.
const char * avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
Get the name of an AVFilterPad.
Definition avfilter.c:988
void avfilter_graph_free(AVFilterGraph **graph)
Free a graph, destroy its links, and set *graph to NULL.
int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
Initialize a filter with the supplied dictionary of options.
Definition avfilter.c:919
int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
Send a command to one or more filter instances.
int avfilter_graph_request_oldest(AVFilterGraph *graph)
Request a frame on the oldest sink link.
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
Definition avfilter.c:149
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)
A convenience wrapper that allocates and initializes a filter in a single step.
#define AVFILTER_CMD_FLAG_ONE
Stop once a filter understood the command (for target=all for example), fast filters are favored auto...
Definition avfilter.h:441
int avfilter_graph_segment_apply(AVFilterGraphSegment *seg, int flags, AVFilterInOut **inputs, AVFilterInOut **outputs)
Apply all filter/link descriptions from a graph segment to the associated filtergraph.
int avfilter_graph_segment_create_filters(AVFilterGraphSegment *seg, int flags)
Create filters specified in a graph segment.
void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
Enable or disable automatic format conversion inside the graph.
AVFilterGraph * avfilter_graph_alloc(void)
Allocate a filter graph.
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:182
@ AVFILTER_AUTO_CONVERT_NONE
all automatic conversions disabled
Definition avfilter.h:691
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, AVBPrint *bp)
bprint variant of av_channel_layout_describe().
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition bprint.h:218
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition bprint.c:130
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition buffer.c:233
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_get_string(const AVDictionary *m, char **buffer, const char key_val_sep, const char pairs_sep)
Get dictionary entries as a string.
Definition dict.c:260
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:37
#define AVERROR_FILTER_NOT_FOUND
Filter not found.
Definition error.h:60
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition error.h:63
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition fifo.h:63
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
Definition frame.c:725
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
Free all side data entries and their contents, then zeroes out the values which the pointers are poin...
Definition side_data.c:139
#define AV_FRAME_SIDE_DATA_FLAG_REPLACE
Don't add a new entry if another of the same type exists.
Definition frame.h:1098
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition frame.c:206
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type from an array.
Definition side_data.c:108
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
const AVSideDataDescriptor * av_frame_side_data_desc(enum AVFrameSideDataType type)
Definition side_data.c:68
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, const AVFrameSideData *src, unsigned int flags)
Add a new side data entry to an array based on existing side data, taking a reference towards the con...
Definition side_data.c:254
static const AVFrameSideData * av_frame_side_data_get(AVFrameSideData *const *sd, const int nb_sd, enum AVFrameSideDataType type)
Wrapper around av_frame_side_data_get_c() to workaround the limitation that for any type T the conver...
Definition frame.h:1196
@ AV_SIDE_DATA_PROP_GLOBAL
The side data type can be used in stream-global structures.
Definition frame.h:341
@ AV_FRAME_DATA_DOWNMIX_MATRIX
Metadata relevant to a downmix procedure in the form of a remixig matrix.
Definition frame.h:307
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition frame.h:85
@ AV_FRAME_DATA_DOWNMIX_INFO
Metadata relevant to a downmix procedure.
Definition frame.h:73
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
int av_find_nearest_q_idx(AVRational q, const AVRational *q_list)
Find the value in a list of rationals nearest a given reference rational.
Definition rational.c:144
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_ROUND_PASS_MINMAX
Flag telling rescaling functions to pass INT64_MIN/MAX through unchanged, avoiding special cases for ...
@ AV_ROUND_NEAR_INF
Round to nearest and halfway cases away from zero.
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition mem.c:313
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition samplefmt.c:51
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition avstring.c:179
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition avstring.c:85
#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
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition opt.h:604
const AVOption * av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
Look for an option in an object.
Definition opt.c:2067
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1754
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition opt.c:934
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
Definition opt.c:949
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
Definition opt.c:2062
int a
const pixel * src2
if(svq3)
cl_device_type type
#define r
Definition input.c:42
#define b
Definition input.c:43
#define av_log2
Definition intmath.h:84
#define extra_bits(eb)
Definition intrax8.c:120
static void reinit(Jpeg2000EncoderContext *s)
Definition j2kenc.c:1447
const char * arg
Definition jacosubdec.c:65
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
static int ff_thread_setname(const char *name)
Definition thread.h:216
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
#define llrint(x)
Definition libm.h:396
#define llrintf(x)
Definition libm.h:401
#define lrintf(x)
Definition libm_mips.h:72
const char * desc
Definition libsvtav1.c:83
uint8_t w
Definition llvidencdsp.c:39
void av_log_once(void *avcl, int initial_level, int subsequent_level, int *state, const char *fmt,...)
Definition log.c:450
@ AV_CLASS_CATEGORY_FILTER
Definition log.h:36
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3860
const char * av_color_range_name(enum AVColorRange range)
Definition pixdesc.c:3776
const char * av_alpha_mode_name(enum AVAlphaMode mode)
Definition pixdesc.c:3925
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition pixdesc.h:128
pixel format definitions
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
AVAlphaMode
Correlation between the alpha channel and color values.
Definition pixfmt.h:816
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:817
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
#define AV_PIX_FMT_RGB32
Definition pixfmt.h:517
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
#define median3(a, b, c)
Definition speexdec.c:617
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
This structure contains the parameters describing the frames that will be passed to this filter.
Definition buffersrc.h:73
AVRational frame_rate
Video only, the frame rate of the input video.
Definition buffersrc.h:100
AVFrameSideData ** side_data
Definition buffersrc.h:124
enum AVColorRange color_range
Definition buffersrc.h:122
int format
video: the pixel format, value corresponds to enum AVPixelFormat audio: the sample format,...
Definition buffersrc.h:78
int width
Video only, the display dimensions of the input frames.
Definition buffersrc.h:87
enum AVColorSpace color_space
Video only, the YUV colorspace and range.
Definition buffersrc.h:121
enum AVAlphaMode alpha_mode
Video only, the alpha mode.
Definition buffersrc.h:130
AVRational time_base
The timebase to be used for the timestamps on the input frames.
Definition buffersrc.h:82
AVBufferRef * hw_frames_ctx
Video with a hwaccel pixel format only.
Definition buffersrc.h:106
AVRational sample_aspect_ratio
Video only, the sample (pixel) aspect ratio.
Definition buffersrc.h:92
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
char * key
Definition dict.h:91
char * value
Definition dict.h:92
This structure describes optional metadata relevant to a downmix procedure.
Definition fifo.c:35
A filterchain is a list of filter specifications.
Definition avfilter.h:904
size_t nb_filters
Definition avfilter.h:906
AVFilterParams ** filters
Definition avfilter.h:905
An instance of a filter.
Definition avfilter.h:273
A parsed representation of a filtergraph segment.
Definition avfilter.h:918
AVFilterChain ** chains
A list of filter chain contained in this segment.
Definition avfilter.h:929
unsigned nb_filters
Definition avfilter.h:564
char * scale_sws_opts
sws options to use for the auto-inserted scale filters
Definition avfilter.h:566
AVFilterContext ** filters
Definition avfilter.h:563
int nb_threads
Maximum number of threads used by filters in this graph.
Definition avfilter.h:587
A linked-list of the inputs/outputs of the filter chain.
Definition avfilter.h:718
AVFilterContext * filter_ctx
filter context associated to this input/output
Definition avfilter.h:723
int pad_idx
index of the filt_ctx pad to use for linking
Definition avfilter.h:726
struct AVFilterInOut * next
next input/input in the list, NULL if this is the last
Definition avfilter.h:729
A filter pad used for either input or output.
Definition filters.h:40
Parameters describing a filter to be created in a filtergraph.
Definition avfilter.h:837
Filter definition.
Definition avfilter.h:215
Format I/O context.
Definition avformat.h:1333
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
AVBufferRef * buf
Definition frame.h:332
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
int width
Definition frame.h:544
AVRational time_base
Time base for the timestamps in this frame.
Definition frame.h:589
void * opaque
Frame owner's private data.
Definition frame.h:610
int height
Definition frame.h:544
AVFrameSideData ** side_data
Definition frame.h:669
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition frame.h:649
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:569
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition frame.h:723
int nb_side_data
Definition frame.h:670
enum AVColorSpace colorspace
YUV colorspace type.
Definition frame.h:734
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is to be handled.
Definition frame.h:827
int sample_rate
Sample rate of the audio data.
Definition frame.h:635
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition frame.h:815
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
Bytestream IO Context.
Definition avio.h:160
AVOption.
Definition opt.h:428
enum AVOptionType type
Definition opt.h:444
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
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
This struct describes the properties of a side data type.
Definition frame.h:375
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int index
stream index in AVFormatContext
Definition avformat.h:772
uint32_t start_display_time
Definition avcodec.h:2089
uint32_t end_display_time
Definition avcodec.h:2090
unsigned num_rects
Definition avcodec.h:2091
AVSubtitleRect ** rects
Definition avcodec.h:2092
int64_t pts
Same as packet pts, in AV_TIME_BASE.
Definition avcodec.h:2093
enum AVMediaType type
Definition ffmpeg.h:454
AVFrame * last_frame
const AVRational * framerate_supported
int64_t frames_prev_hist[3]
uint64_t dup_warning
AVRational framerate
enum VideoSyncMethod vsync_method
AVRational framerate_max
unsigned nb_outputs_done
AVFrame * frame_enc
Scheduler * sch
FilterGraph fg
AVFifo * frame_queue_out
AVFilterGraph * graph
const AVClass * class
Definition ffmpeg.h:400
int index
Definition ffmpeg.h:401
int nb_outputs
Definition ffmpeg.h:406
int is_internal
Definition ffmpeg.h:411
OutputFilter ** outputs
Definition ffmpeg.h:405
int nb_inputs
Definition ffmpeg.h:404
const char * graph_desc
Definition ffmpeg.h:413
InputFilter ** inputs
Definition ffmpeg.h:403
struct FrameData::@304126211346234154321045014345346376220164157123 dec
AVRational frame_rate_filter
Definition ffmpeg.h:717
int64_t wallclock[LATENCY_PROBE_NB]
Definition ffmpeg.h:721
int nb_side_data
Definition ffmpeg.h:726
int bits_per_raw_sample
Definition ffmpeg.h:719
AVFrameSideData ** side_data
Definition ffmpeg.h:725
AVDictionary * reinit_opts
Definition ffmpeg.h:728
AVRational tb
Definition ffmpeg.h:714
int index
Definition ffmpeg.h:511
uint8_t * name
Definition ffmpeg.h:262
AVRational framerate
Definition ffmpeg.h:269
int64_t trim_end_us
Definition ffmpeg.h:260
unsigned flags
Definition ffmpeg.h:280
int64_t trim_start_us
Definition ffmpeg.h:259
unsigned crop_bottom
Definition ffmpeg.h:272
unsigned crop_right
Definition ffmpeg.h:274
AVFrame * fallback
Definition ffmpeg.h:282
unsigned crop_left
Definition ffmpeg.h:273
unsigned crop_top
Definition ffmpeg.h:271
InputFilterOptions opts
AVChannelLayout ch_layout
AVFrameSideData ** side_data
AVDownmixInfo downmixinfo
struct InputFilterPriv::@246267011247332065017016360253132152152335164263 sub2video
AVRational sample_aspect_ratio
AVBufferRef * hw_frames_ctx
InputFilter ifilter
int32_t displaymatrix[9]
enum AVColorSpace color_space
AVRational time_base
AVBufferRef * downmixmatrix
OutputFilter * ofilter_src
enum AVAlphaMode alpha_mode
enum AVColorRange color_range
unsigned int initialize
marks if sub2video_update should force an initialization
enum AVMediaType type_src
size_t downmixmatrix_size
uint8_t * name
Definition ffmpeg.h:360
AVFilterContext * filter
Definition ffmpeg.h:366
uint8_t * linklabel
Definition ffmpeg.h:372
char * input_name
Definition ffmpeg.h:368
enum AVMediaType type
Definition ffmpeg.h:364
struct FilterGraph * graph
Definition ffmpeg.h:359
int index
Definition ffmpeg.h:361
int index
Definition ffmpeg.h:471
struct InputFile * file
Definition ffmpeg.h:469
AVCodecParameters * par
Codec parameters - to be used by the decoding/streamcopy code.
Definition ffmpeg.h:481
AVStream * st
Definition ffmpeg.h:473
enum AVColorRange * color_ranges
AVRational enc_timebase
enum AVPixelFormat * pix_fmts
ReinitOpts reinit_opts
AVFifo * reinit_opts_fifo
AVDictionary * swr_opts
AVChannelLayout ch_layout
enum AVColorSpace color_space
OutputFilter ofilter
enum AVAlphaMode alpha_mode
FPSConvContext fps
enum AVColorRange color_range
AVRational sample_aspect_ratio
enum AVSampleFormat * sample_fmts
int32_t displaymatrix[9]
const int * sample_rates
const AVChannelLayout * ch_layouts
AVDictionary * sws_opts
enum AVAlphaMode * alpha_modes
enum AVColorSpace * color_spaces
AVFrameSideData ** side_data
atomic_uint_least64_t nb_frames_drop
Definition ffmpeg.h:396
AVFilterContext * filter
Definition ffmpeg.h:382
char * output_name
Definition ffmpeg.h:384
uint8_t * name
Definition ffmpeg.h:379
uint8_t * linklabel
Definition ffmpeg.h:389
atomic_uint_least64_t nb_frames_dup
Definition ffmpeg.h:395
struct FilterGraph * graph
Definition ffmpeg.h:378
char * apad
Definition ffmpeg.h:391
const AVClass * class
Definition ffmpeg.h:376
enum AVMediaType type
Definition ffmpeg.h:393
AVDictionary * dict
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static void finish(void)
Definition movenc.c:374
static AVDictionary * opts
Definition movenc.c:51
static char buffer[20]
Definition seek.c:32
#define width
Definition dsp.h:89
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition time.c:57
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:54
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:83
static int64_t pts
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
color_range
float delta
int len
static double c[64]
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:137