2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 /* Include only the enabled headers since some compilers (namely, Sun
28 Studio) will not omit unused inline functions and create undefined
29 references to libraries that are not being built. */
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libpostproc/postprocess.h"
37 #include "libavutil/avstring.h"
38 #include "libavutil/parseutils.h"
39 #include "libavutil/pixdesc.h"
40 #include "libavutil/eval.h"
41 #include "libavcodec/opt.h"
45 #include "libavformat/network.h"
47 #if HAVE_SYS_RESOURCE_H
48 #include <sys/resource.h>
51 const char **opt_names;
52 const char **opt_values;
53 static int opt_name_count;
54 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
55 AVFormatContext *avformat_opts;
56 struct SwsContext *sws_opts;
58 static const int this_year = 2011;
63 for (i = 0; i < AVMEDIA_TYPE_NB; i++)
64 avcodec_opts[i] = avcodec_alloc_context2(i);
65 avformat_opts = avformat_alloc_context();
67 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
71 void uninit_opts(void)
74 for (i = 0; i < AVMEDIA_TYPE_NB; i++)
75 av_freep(&avcodec_opts[i]);
76 av_freep(&avformat_opts->key);
77 av_freep(&avformat_opts);
81 for (i = 0; i < opt_name_count; i++) {
82 //opt_values are only stored for codec-specific options in which case
83 //both the name and value are dup'd
85 av_freep(&opt_names[i]);
86 av_freep(&opt_values[i]);
90 av_freep(&opt_values);
93 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
95 vfprintf(stdout, fmt, vl);
98 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
102 double d = av_strtod(numstr, &tail);
104 error= "Expected number for %s but found: %s\n";
105 else if (d < min || d > max)
106 error= "The value for %s was %s which is not within %f - %f\n";
107 else if(type == OPT_INT64 && (int64_t)d != d)
108 error= "Expected int64 for %s but found %s\n";
111 fprintf(stderr, error, context, numstr, min, max);
115 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
118 if (av_parse_time(&us, timestr, is_duration) < 0) {
119 fprintf(stderr, "Invalid %s specification for %s: %s\n",
120 is_duration ? "duration" : "date", context, timestr);
126 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
132 for(po = options; po->name != NULL; po++) {
134 if ((po->flags & mask) == value) {
139 av_strlcpy(buf, po->name, sizeof(buf));
140 if (po->flags & HAS_ARG) {
141 av_strlcat(buf, " ", sizeof(buf));
142 av_strlcat(buf, po->argname, sizeof(buf));
144 printf("-%-17s %s\n", buf, po->help);
149 static const OptionDef* find_option(const OptionDef *po, const char *name){
150 while (po->name != NULL) {
151 if (!strcmp(name, po->name))
158 void parse_options(int argc, char **argv, const OptionDef *options,
159 void (* parse_arg_function)(const char*))
161 const char *opt, *arg;
162 int optindex, handleoptions=1;
167 while (optindex < argc) {
168 opt = argv[optindex++];
170 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
172 if (opt[1] == '-' && opt[2] == '\0') {
177 po= find_option(options, opt);
178 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
179 /* handle 'no' bool option */
180 po = find_option(options, opt + 2);
181 if (!(po->name && (po->flags & OPT_BOOL)))
186 po= find_option(options, "default");
189 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
193 if (po->flags & HAS_ARG) {
194 arg = argv[optindex++];
196 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
200 if (po->flags & OPT_STRING) {
202 str = av_strdup(arg);
203 *po->u.str_arg = str;
204 } else if (po->flags & OPT_BOOL) {
205 *po->u.int_arg = bool_val;
206 } else if (po->flags & OPT_INT) {
207 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
208 } else if (po->flags & OPT_INT64) {
209 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
210 } else if (po->flags & OPT_FLOAT) {
211 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
212 } else if (po->flags & OPT_FUNC2) {
213 if (po->u.func2_arg(opt, arg) < 0) {
214 fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
217 } else if (po->flags & OPT_DUMMY) {
218 /* Do nothing for this option */
222 if(po->flags & OPT_EXIT)
225 if (parse_arg_function)
226 parse_arg_function(opt);
231 int opt_default(const char *opt, const char *arg){
234 const AVOption *o= NULL;
235 int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
237 for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
238 const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
240 ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
242 if(!o && avformat_opts)
243 ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
245 ret = av_set_string3(sws_opts, opt, arg, 1, &o);
247 if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
248 ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
249 else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
250 ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
251 else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
252 ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
255 fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
260 AVOutputFormat *oformat = NULL;
261 while ((p=av_codec_next(p))){
262 AVClass *c= p->priv_class;
263 if(c && av_find_opt(&c, opt, NULL, 0, 0))
267 while ((oformat = av_oformat_next(oformat))) {
268 const AVClass *c = oformat->priv_class;
269 if (c && av_find_opt(&c, opt, NULL, 0, 0))
274 fprintf(stderr, "Unrecognized option '%s'\n", opt);
279 // av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
281 //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
282 opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
283 opt_values[opt_name_count]= o ? NULL : av_strdup(arg);
284 opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
285 opt_names[opt_name_count++]= o ? o->name : av_strdup(opt);
287 if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
288 av_log_set_level(AV_LOG_DEBUG);
292 int opt_loglevel(const char *opt, const char *arg)
294 const struct { const char *name; int level; } log_levels[] = {
295 { "quiet" , AV_LOG_QUIET },
296 { "panic" , AV_LOG_PANIC },
297 { "fatal" , AV_LOG_FATAL },
298 { "error" , AV_LOG_ERROR },
299 { "warning", AV_LOG_WARNING },
300 { "info" , AV_LOG_INFO },
301 { "verbose", AV_LOG_VERBOSE },
302 { "debug" , AV_LOG_DEBUG },
308 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
309 if (!strcmp(log_levels[i].name, arg)) {
310 av_log_set_level(log_levels[i].level);
315 level = strtol(arg, &tail, 10);
317 fprintf(stderr, "Invalid loglevel \"%s\". "
318 "Possible levels are numbers or:\n", arg);
319 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
320 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
323 av_log_set_level(level);
327 int opt_timelimit(const char *opt, const char *arg)
330 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
331 struct rlimit rl = { lim, lim + 1 };
332 if (setrlimit(RLIMIT_CPU, &rl))
335 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
340 void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
344 if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
345 AVCodecContext *avctx= ctx;
346 if(codec && codec->priv_class && avctx->priv_data){
347 priv_ctx= avctx->priv_data;
349 } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
350 AVFormatContext *avctx = ctx;
351 if (avctx->oformat && avctx->oformat->priv_class) {
352 priv_ctx = avctx->priv_data;
356 for(i=0; i<opt_name_count; i++){
359 const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
360 /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
361 if(str && ((opt->flags & flags) == flags))
362 av_set_string3(ctx, opt_names[i], str, 1, NULL);
363 /* We need to use a differnt system to pass options to the private context because
364 it is not known which codec and thus context kind that will be when parsing options
365 we thus use opt_values directly instead of opts_ctx */
366 if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){
367 av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL);
372 void print_error(const char *filename, int err)
375 const char *errbuf_ptr = errbuf;
377 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
378 errbuf_ptr = strerror(AVUNERROR(err));
379 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
382 static int warned_cfg = 0;
385 #define SHOW_VERSION 2
386 #define SHOW_CONFIG 4
388 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
389 if (CONFIG_##LIBNAME) { \
390 const char *indent = flags & INDENT? " " : ""; \
391 if (flags & SHOW_VERSION) { \
392 unsigned int version = libname##_version(); \
393 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
395 LIB##LIBNAME##_VERSION_MAJOR, \
396 LIB##LIBNAME##_VERSION_MINOR, \
397 LIB##LIBNAME##_VERSION_MICRO, \
398 version >> 16, version >> 8 & 0xff, version & 0xff); \
400 if (flags & SHOW_CONFIG) { \
401 const char *cfg = libname##_configuration(); \
402 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
405 "%sWARNING: library configuration mismatch\n", \
409 fprintf(stderr, "%s%-11s configuration: %s\n", \
410 indent, #libname, cfg); \
415 static void print_all_libs_info(FILE* outstream, int flags)
417 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
418 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
419 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
420 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
421 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
422 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
423 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
426 void show_banner(void)
428 fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
429 program_name, program_birth_year, this_year);
430 fprintf(stderr, " built on %s %s with %s %s\n",
431 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
432 fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n");
433 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
434 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
437 void show_version(void) {
438 printf("%s " FFMPEG_VERSION "\n", program_name);
439 print_all_libs_info(stdout, SHOW_VERSION);
442 void show_license(void)
446 "This version of %s has nonfree parts compiled in.\n"
447 "Therefore it is not legally redistributable.\n",
450 "%s is free software; you can redistribute it and/or modify\n"
451 "it under the terms of the GNU General Public License as published by\n"
452 "the Free Software Foundation; either version 3 of the License, or\n"
453 "(at your option) any later version.\n"
455 "%s is distributed in the hope that it will be useful,\n"
456 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
457 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
458 "GNU General Public License for more details.\n"
460 "You should have received a copy of the GNU General Public License\n"
461 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
462 program_name, program_name, program_name
464 "%s is free software; you can redistribute it and/or modify\n"
465 "it under the terms of the GNU General Public License as published by\n"
466 "the Free Software Foundation; either version 2 of the License, or\n"
467 "(at your option) any later version.\n"
469 "%s is distributed in the hope that it will be useful,\n"
470 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
471 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
472 "GNU General Public License for more details.\n"
474 "You should have received a copy of the GNU General Public License\n"
475 "along with %s; if not, write to the Free Software\n"
476 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
477 program_name, program_name, program_name
479 "%s is free software; you can redistribute it and/or modify\n"
480 "it under the terms of the GNU Lesser General Public License as published by\n"
481 "the Free Software Foundation; either version 3 of the License, or\n"
482 "(at your option) any later version.\n"
484 "%s is distributed in the hope that it will be useful,\n"
485 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
486 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
487 "GNU Lesser General Public License for more details.\n"
489 "You should have received a copy of the GNU Lesser General Public License\n"
490 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
491 program_name, program_name, program_name
493 "%s is free software; you can redistribute it and/or\n"
494 "modify it under the terms of the GNU Lesser General Public\n"
495 "License as published by the Free Software Foundation; either\n"
496 "version 2.1 of the License, or (at your option) any later version.\n"
498 "%s is distributed in the hope that it will be useful,\n"
499 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
500 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
501 "Lesser General Public License for more details.\n"
503 "You should have received a copy of the GNU Lesser General Public\n"
504 "License along with %s; if not, write to the Free Software\n"
505 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
506 program_name, program_name, program_name
511 void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
515 for (i=-1; i < nb_fmts; i++) {
516 get_fmt_string (fmt_str, sizeof(fmt_str), i);
517 fprintf(stdout, "%s\n", fmt_str);
521 void show_formats(void)
523 AVInputFormat *ifmt=NULL;
524 AVOutputFormat *ofmt=NULL;
525 const char *last_name;
529 " D. = Demuxing supported\n"
530 " .E = Muxing supported\n"
536 const char *name=NULL;
537 const char *long_name=NULL;
539 while((ofmt= av_oformat_next(ofmt))) {
540 if((name == NULL || strcmp(ofmt->name, name)<0) &&
541 strcmp(ofmt->name, last_name)>0){
543 long_name= ofmt->long_name;
547 while((ifmt= av_iformat_next(ifmt))) {
548 if((name == NULL || strcmp(ifmt->name, name)<0) &&
549 strcmp(ifmt->name, last_name)>0){
551 long_name= ifmt->long_name;
554 if(name && strcmp(ifmt->name, name)==0)
566 long_name ? long_name:" ");
570 void show_codecs(void)
572 AVCodec *p=NULL, *p2;
573 const char *last_name;
576 " D..... = Decoding supported\n"
577 " .E.... = Encoding supported\n"
578 " ..V... = Video codec\n"
579 " ..A... = Audio codec\n"
580 " ..S... = Subtitle codec\n"
581 " ...S.. = Supports draw_horiz_band\n"
582 " ....D. = Supports direct rendering method 1\n"
583 " .....T = Supports weird frame truncation\n"
590 const char *type_str;
593 while((p= av_codec_next(p))) {
594 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
595 strcmp(p->name, last_name)>0){
597 decode= encode= cap=0;
599 if(p2 && strcmp(p->name, p2->name)==0){
600 if(p->decode) decode=1;
601 if(p->encode) encode=1;
602 cap |= p->capabilities;
610 case AVMEDIA_TYPE_VIDEO:
613 case AVMEDIA_TYPE_AUDIO:
616 case AVMEDIA_TYPE_SUBTITLE:
624 " %s%s%s%s%s%s %-15s %s",
625 decode ? "D": (/*p2->decoder ? "d":*/" "),
628 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
629 cap & CODEC_CAP_DR1 ? "D":" ",
630 cap & CODEC_CAP_TRUNCATED ? "T":" ",
632 p2->long_name ? p2->long_name : "");
633 /* if(p2->decoder && decode==0)
634 printf(" use %s for decoding", p2->decoder->name);*/
639 "Note, the names of encoders and decoders do not always match, so there are\n"
640 "several cases where the above table shows encoder only or decoder only entries\n"
641 "even though both encoding and decoding are supported. For example, the h263\n"
642 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
648 AVBitStreamFilter *bsf=NULL;
650 printf("Bitstream filters:\n");
651 while((bsf = av_bitstream_filter_next(bsf)))
652 printf("%s\n", bsf->name);
656 void show_protocols(void)
658 URLProtocol *up=NULL;
660 printf("Supported file protocols:\n"
661 "I.. = Input supported\n"
662 ".O. = Output supported\n"
663 "..S = Seek supported\n"
666 while((up = av_protocol_next(up)))
667 printf("%c%c%c %s\n",
668 up->url_read ? 'I' : '.',
669 up->url_write ? 'O' : '.',
670 up->url_seek ? 'S' : '.',
674 void show_filters(void)
676 AVFilter av_unused(**filter) = NULL;
678 printf("Filters:\n");
680 while ((filter = av_filter_next(filter)) && *filter)
681 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
685 void show_pix_fmts(void)
687 enum PixelFormat pix_fmt;
691 "I.... = Supported Input format for conversion\n"
692 ".O... = Supported Output format for conversion\n"
693 "..H.. = Hardware accelerated format\n"
694 "...P. = Paletted format\n"
695 "....B = Bitstream format\n"
696 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
700 # define sws_isSupportedInput(x) 0
701 # define sws_isSupportedOutput(x) 0
704 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
705 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
706 printf("%c%c%c%c%c %-16s %d %2d\n",
707 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
708 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
709 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
710 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
711 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
713 pix_desc->nb_components,
714 av_get_bits_per_pixel(pix_desc));
721 int yesno = (toupper(c) == 'Y');
723 while (c != '\n' && c != EOF)
729 int read_file(const char *filename, char **bufptr, size_t *size)
731 FILE *f = fopen(filename, "rb");
734 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
735 return AVERROR(errno);
737 fseek(f, 0, SEEK_END);
739 fseek(f, 0, SEEK_SET);
740 *bufptr = av_malloc(*size + 1);
742 fprintf(stderr, "Could not allocate file buffer\n");
744 return AVERROR(ENOMEM);
746 fread(*bufptr, 1, *size, f);
747 (*bufptr)[*size++] = '\0';
753 FILE *get_preset_file(char *filename, size_t filename_size,
754 const char *preset_name, int is_path, const char *codec_name)
758 const char *base[3]= { getenv("FFMPEG_DATADIR"),
764 av_strlcpy(filename, preset_name, filename_size);
765 f = fopen(filename, "r");
767 for (i = 0; i < 3 && !f; i++) {
770 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
771 f = fopen(filename, "r");
772 if (!f && codec_name) {
773 snprintf(filename, filename_size,
774 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
775 f = fopen(filename, "r");
785 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
787 FFSinkContext *priv = ctx->priv;
790 return AVERROR(EINVAL);
791 *priv = *(FFSinkContext *)opaque;
796 static void null_end_frame(AVFilterLink *inlink) { }
798 static int ffsink_query_formats(AVFilterContext *ctx)
800 FFSinkContext *priv = ctx->priv;
801 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
803 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
809 .priv_size = sizeof(FFSinkContext),
812 .query_formats = ffsink_query_formats,
814 .inputs = (AVFilterPad[]) {{ .name = "default",
815 .type = AVMEDIA_TYPE_VIDEO,
816 .end_frame = null_end_frame,
817 .min_perms = AV_PERM_READ, },
819 .outputs = (AVFilterPad[]) {{ .name = NULL }},
822 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
823 AVFilterBufferRef **picref_ptr, AVRational *tb)
826 AVFilterBufferRef *picref;
828 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
830 if (!(picref = ctx->inputs[0]->cur_buf))
831 return AVERROR(ENOENT);
832 *picref_ptr = picref;
833 ctx->inputs[0]->cur_buf = NULL;
834 *tb = ctx->inputs[0]->time_base;
836 memcpy(frame->data, picref->data, sizeof(frame->data));
837 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
838 frame->interlaced_frame = picref->video->interlaced;
839 frame->top_field_first = picref->video->top_field_first;
844 #endif /* CONFIG_AVFILTER */