1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Option handlers shared between the tools.
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "config.h"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include <stdio.h>
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#include "cmdutils.h"
26cabdff1aSopenharmony_ci#include "opt_common.h"
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include "libavutil/avassert.h"
29cabdff1aSopenharmony_ci#include "libavutil/avstring.h"
30cabdff1aSopenharmony_ci#include "libavutil/bprint.h"
31cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
32cabdff1aSopenharmony_ci#include "libavutil/cpu.h"
33cabdff1aSopenharmony_ci#include "libavutil/dict.h"
34cabdff1aSopenharmony_ci#include "libavutil/error.h"
35cabdff1aSopenharmony_ci#include "libavutil/ffversion.h"
36cabdff1aSopenharmony_ci#include "libavutil/log.h"
37cabdff1aSopenharmony_ci#include "libavutil/mem.h"
38cabdff1aSopenharmony_ci#include "libavutil/parseutils.h"
39cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h"
40cabdff1aSopenharmony_ci#include "libavutil/version.h"
41cabdff1aSopenharmony_ci
42cabdff1aSopenharmony_ci#include "libavcodec/avcodec.h"
43cabdff1aSopenharmony_ci#include "libavcodec/bsf.h"
44cabdff1aSopenharmony_ci#include "libavcodec/codec.h"
45cabdff1aSopenharmony_ci#include "libavcodec/codec_desc.h"
46cabdff1aSopenharmony_ci#include "libavcodec/version.h"
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ci#include "libavformat/avformat.h"
49cabdff1aSopenharmony_ci#include "libavformat/version.h"
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci#include "libavdevice/avdevice.h"
52cabdff1aSopenharmony_ci#include "libavdevice/version.h"
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci#include "libavfilter/avfilter.h"
55cabdff1aSopenharmony_ci#include "libavfilter/version.h"
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci#include "libswscale/swscale.h"
58cabdff1aSopenharmony_ci#include "libswscale/version.h"
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci#include "libswresample/swresample.h"
61cabdff1aSopenharmony_ci#include "libswresample/version.h"
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_ci#include "libpostproc/postprocess.h"
64cabdff1aSopenharmony_ci#include "libpostproc/version.h"
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_cienum show_muxdemuxers {
67cabdff1aSopenharmony_ci    SHOW_DEFAULT,
68cabdff1aSopenharmony_ci    SHOW_DEMUXERS,
69cabdff1aSopenharmony_ci    SHOW_MUXERS,
70cabdff1aSopenharmony_ci};
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_cistatic FILE *report_file;
73cabdff1aSopenharmony_cistatic int report_file_level = AV_LOG_DEBUG;
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_ciint show_license(void *optctx, const char *opt, const char *arg)
76cabdff1aSopenharmony_ci{
77cabdff1aSopenharmony_ci#if CONFIG_NONFREE
78cabdff1aSopenharmony_ci    printf(
79cabdff1aSopenharmony_ci    "This version of %s has nonfree parts compiled in.\n"
80cabdff1aSopenharmony_ci    "Therefore it is not legally redistributable.\n",
81cabdff1aSopenharmony_ci    program_name );
82cabdff1aSopenharmony_ci#elif CONFIG_GPLV3
83cabdff1aSopenharmony_ci    printf(
84cabdff1aSopenharmony_ci    "%s is free software; you can redistribute it and/or modify\n"
85cabdff1aSopenharmony_ci    "it under the terms of the GNU General Public License as published by\n"
86cabdff1aSopenharmony_ci    "the Free Software Foundation; either version 3 of the License, or\n"
87cabdff1aSopenharmony_ci    "(at your option) any later version.\n"
88cabdff1aSopenharmony_ci    "\n"
89cabdff1aSopenharmony_ci    "%s is distributed in the hope that it will be useful,\n"
90cabdff1aSopenharmony_ci    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
91cabdff1aSopenharmony_ci    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
92cabdff1aSopenharmony_ci    "GNU General Public License for more details.\n"
93cabdff1aSopenharmony_ci    "\n"
94cabdff1aSopenharmony_ci    "You should have received a copy of the GNU General Public License\n"
95cabdff1aSopenharmony_ci    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
96cabdff1aSopenharmony_ci    program_name, program_name, program_name );
97cabdff1aSopenharmony_ci#elif CONFIG_GPL
98cabdff1aSopenharmony_ci    printf(
99cabdff1aSopenharmony_ci    "%s is free software; you can redistribute it and/or modify\n"
100cabdff1aSopenharmony_ci    "it under the terms of the GNU General Public License as published by\n"
101cabdff1aSopenharmony_ci    "the Free Software Foundation; either version 2 of the License, or\n"
102cabdff1aSopenharmony_ci    "(at your option) any later version.\n"
103cabdff1aSopenharmony_ci    "\n"
104cabdff1aSopenharmony_ci    "%s is distributed in the hope that it will be useful,\n"
105cabdff1aSopenharmony_ci    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
106cabdff1aSopenharmony_ci    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
107cabdff1aSopenharmony_ci    "GNU General Public License for more details.\n"
108cabdff1aSopenharmony_ci    "\n"
109cabdff1aSopenharmony_ci    "You should have received a copy of the GNU General Public License\n"
110cabdff1aSopenharmony_ci    "along with %s; if not, write to the Free Software\n"
111cabdff1aSopenharmony_ci    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
112cabdff1aSopenharmony_ci    program_name, program_name, program_name );
113cabdff1aSopenharmony_ci#elif CONFIG_LGPLV3
114cabdff1aSopenharmony_ci    printf(
115cabdff1aSopenharmony_ci    "%s is free software; you can redistribute it and/or modify\n"
116cabdff1aSopenharmony_ci    "it under the terms of the GNU Lesser General Public License as published by\n"
117cabdff1aSopenharmony_ci    "the Free Software Foundation; either version 3 of the License, or\n"
118cabdff1aSopenharmony_ci    "(at your option) any later version.\n"
119cabdff1aSopenharmony_ci    "\n"
120cabdff1aSopenharmony_ci    "%s is distributed in the hope that it will be useful,\n"
121cabdff1aSopenharmony_ci    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
122cabdff1aSopenharmony_ci    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
123cabdff1aSopenharmony_ci    "GNU Lesser General Public License for more details.\n"
124cabdff1aSopenharmony_ci    "\n"
125cabdff1aSopenharmony_ci    "You should have received a copy of the GNU Lesser General Public License\n"
126cabdff1aSopenharmony_ci    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
127cabdff1aSopenharmony_ci    program_name, program_name, program_name );
128cabdff1aSopenharmony_ci#else
129cabdff1aSopenharmony_ci    printf(
130cabdff1aSopenharmony_ci    "%s is free software; you can redistribute it and/or\n"
131cabdff1aSopenharmony_ci    "modify it under the terms of the GNU Lesser General Public\n"
132cabdff1aSopenharmony_ci    "License as published by the Free Software Foundation; either\n"
133cabdff1aSopenharmony_ci    "version 2.1 of the License, or (at your option) any later version.\n"
134cabdff1aSopenharmony_ci    "\n"
135cabdff1aSopenharmony_ci    "%s is distributed in the hope that it will be useful,\n"
136cabdff1aSopenharmony_ci    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
137cabdff1aSopenharmony_ci    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
138cabdff1aSopenharmony_ci    "Lesser General Public License for more details.\n"
139cabdff1aSopenharmony_ci    "\n"
140cabdff1aSopenharmony_ci    "You should have received a copy of the GNU Lesser General Public\n"
141cabdff1aSopenharmony_ci    "License along with %s; if not, write to the Free Software\n"
142cabdff1aSopenharmony_ci    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
143cabdff1aSopenharmony_ci    program_name, program_name, program_name );
144cabdff1aSopenharmony_ci#endif
145cabdff1aSopenharmony_ci
146cabdff1aSopenharmony_ci    return 0;
147cabdff1aSopenharmony_ci}
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_cistatic int warned_cfg = 0;
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci#define INDENT        1
152cabdff1aSopenharmony_ci#define SHOW_VERSION  2
153cabdff1aSopenharmony_ci#define SHOW_CONFIG   4
154cabdff1aSopenharmony_ci#define SHOW_COPYRIGHT 8
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci#define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
157cabdff1aSopenharmony_ci    if (CONFIG_##LIBNAME) {                                             \
158cabdff1aSopenharmony_ci        const char *indent = flags & INDENT? "  " : "";                 \
159cabdff1aSopenharmony_ci        if (flags & SHOW_VERSION) {                                     \
160cabdff1aSopenharmony_ci            unsigned int version = libname##_version();                 \
161cabdff1aSopenharmony_ci            av_log(NULL, level,                                         \
162cabdff1aSopenharmony_ci                   "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",            \
163cabdff1aSopenharmony_ci                   indent, #libname,                                    \
164cabdff1aSopenharmony_ci                   LIB##LIBNAME##_VERSION_MAJOR,                        \
165cabdff1aSopenharmony_ci                   LIB##LIBNAME##_VERSION_MINOR,                        \
166cabdff1aSopenharmony_ci                   LIB##LIBNAME##_VERSION_MICRO,                        \
167cabdff1aSopenharmony_ci                   AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
168cabdff1aSopenharmony_ci                   AV_VERSION_MICRO(version));                          \
169cabdff1aSopenharmony_ci        }                                                               \
170cabdff1aSopenharmony_ci        if (flags & SHOW_CONFIG) {                                      \
171cabdff1aSopenharmony_ci            const char *cfg = libname##_configuration();                \
172cabdff1aSopenharmony_ci            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
173cabdff1aSopenharmony_ci                if (!warned_cfg) {                                      \
174cabdff1aSopenharmony_ci                    av_log(NULL, level,                                 \
175cabdff1aSopenharmony_ci                            "%sWARNING: library configuration mismatch\n", \
176cabdff1aSopenharmony_ci                            indent);                                    \
177cabdff1aSopenharmony_ci                    warned_cfg = 1;                                     \
178cabdff1aSopenharmony_ci                }                                                       \
179cabdff1aSopenharmony_ci                av_log(NULL, level, "%s%-11s configuration: %s\n",      \
180cabdff1aSopenharmony_ci                        indent, #libname, cfg);                         \
181cabdff1aSopenharmony_ci            }                                                           \
182cabdff1aSopenharmony_ci        }                                                               \
183cabdff1aSopenharmony_ci    }                                                                   \
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_cistatic void print_all_libs_info(int flags, int level)
186cabdff1aSopenharmony_ci{
187cabdff1aSopenharmony_ci    PRINT_LIB_INFO(avutil,     AVUTIL,     flags, level);
188cabdff1aSopenharmony_ci    PRINT_LIB_INFO(avcodec,    AVCODEC,    flags, level);
189cabdff1aSopenharmony_ci    PRINT_LIB_INFO(avformat,   AVFORMAT,   flags, level);
190cabdff1aSopenharmony_ci    PRINT_LIB_INFO(avdevice,   AVDEVICE,   flags, level);
191cabdff1aSopenharmony_ci    PRINT_LIB_INFO(avfilter,   AVFILTER,   flags, level);
192cabdff1aSopenharmony_ci    PRINT_LIB_INFO(swscale,    SWSCALE,    flags, level);
193cabdff1aSopenharmony_ci    PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
194cabdff1aSopenharmony_ci    PRINT_LIB_INFO(postproc,   POSTPROC,   flags, level);
195cabdff1aSopenharmony_ci}
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_cistatic void print_program_info(int flags, int level)
198cabdff1aSopenharmony_ci{
199cabdff1aSopenharmony_ci    const char *indent = flags & INDENT? "  " : "";
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
202cabdff1aSopenharmony_ci    if (flags & SHOW_COPYRIGHT)
203cabdff1aSopenharmony_ci        av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
204cabdff1aSopenharmony_ci               program_birth_year, CONFIG_THIS_YEAR);
205cabdff1aSopenharmony_ci    av_log(NULL, level, "\n");
206cabdff1aSopenharmony_ci    av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
207cabdff1aSopenharmony_ci
208cabdff1aSopenharmony_ci    av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
209cabdff1aSopenharmony_ci}
210cabdff1aSopenharmony_ci
211cabdff1aSopenharmony_cistatic void print_buildconf(int flags, int level)
212cabdff1aSopenharmony_ci{
213cabdff1aSopenharmony_ci    const char *indent = flags & INDENT ? "  " : "";
214cabdff1aSopenharmony_ci    char str[] = { FFMPEG_CONFIGURATION };
215cabdff1aSopenharmony_ci    char *conflist, *remove_tilde, *splitconf;
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_ci    // Change all the ' --' strings to '~--' so that
218cabdff1aSopenharmony_ci    // they can be identified as tokens.
219cabdff1aSopenharmony_ci    while ((conflist = strstr(str, " --")) != NULL) {
220cabdff1aSopenharmony_ci        conflist[0] = '~';
221cabdff1aSopenharmony_ci    }
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci    // Compensate for the weirdness this would cause
224cabdff1aSopenharmony_ci    // when passing 'pkg-config --static'.
225cabdff1aSopenharmony_ci    while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
226cabdff1aSopenharmony_ci        remove_tilde[sizeof("pkg-config~") - 2] = ' ';
227cabdff1aSopenharmony_ci    }
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci    splitconf = strtok(str, "~");
230cabdff1aSopenharmony_ci    av_log(NULL, level, "\n%sconfiguration:\n", indent);
231cabdff1aSopenharmony_ci    while (splitconf != NULL) {
232cabdff1aSopenharmony_ci        av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
233cabdff1aSopenharmony_ci        splitconf = strtok(NULL, "~");
234cabdff1aSopenharmony_ci    }
235cabdff1aSopenharmony_ci}
236cabdff1aSopenharmony_ci
237cabdff1aSopenharmony_civoid show_banner(int argc, char **argv, const OptionDef *options)
238cabdff1aSopenharmony_ci{
239cabdff1aSopenharmony_ci    int idx = locate_option(argc, argv, options, "version");
240cabdff1aSopenharmony_ci    if (hide_banner || idx)
241cabdff1aSopenharmony_ci        return;
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci    print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
244cabdff1aSopenharmony_ci    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
245cabdff1aSopenharmony_ci    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
246cabdff1aSopenharmony_ci}
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_ciint show_version(void *optctx, const char *opt, const char *arg)
249cabdff1aSopenharmony_ci{
250cabdff1aSopenharmony_ci    av_log_set_callback(log_callback_help);
251cabdff1aSopenharmony_ci    print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
252cabdff1aSopenharmony_ci    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
253cabdff1aSopenharmony_ci
254cabdff1aSopenharmony_ci    return 0;
255cabdff1aSopenharmony_ci}
256cabdff1aSopenharmony_ci
257cabdff1aSopenharmony_ciint show_buildconf(void *optctx, const char *opt, const char *arg)
258cabdff1aSopenharmony_ci{
259cabdff1aSopenharmony_ci    av_log_set_callback(log_callback_help);
260cabdff1aSopenharmony_ci    print_buildconf      (INDENT|0, AV_LOG_INFO);
261cabdff1aSopenharmony_ci
262cabdff1aSopenharmony_ci    return 0;
263cabdff1aSopenharmony_ci}
264cabdff1aSopenharmony_ci
265cabdff1aSopenharmony_ci#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
266cabdff1aSopenharmony_ci    if (codec->field) {                                                      \
267cabdff1aSopenharmony_ci        const type *p = codec->field;                                        \
268cabdff1aSopenharmony_ci                                                                             \
269cabdff1aSopenharmony_ci        printf("    Supported " list_name ":");                              \
270cabdff1aSopenharmony_ci        while (*p != term) {                                                 \
271cabdff1aSopenharmony_ci            get_name(*p);                                                    \
272cabdff1aSopenharmony_ci            printf(" %s", name);                                             \
273cabdff1aSopenharmony_ci            p++;                                                             \
274cabdff1aSopenharmony_ci        }                                                                    \
275cabdff1aSopenharmony_ci        printf("\n");                                                        \
276cabdff1aSopenharmony_ci    }                                                                        \
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_cistatic void print_codec(const AVCodec *c)
279cabdff1aSopenharmony_ci{
280cabdff1aSopenharmony_ci    int encoder = av_codec_is_encoder(c);
281cabdff1aSopenharmony_ci
282cabdff1aSopenharmony_ci    printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
283cabdff1aSopenharmony_ci           c->long_name ? c->long_name : "");
284cabdff1aSopenharmony_ci
285cabdff1aSopenharmony_ci    printf("    General capabilities: ");
286cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
287cabdff1aSopenharmony_ci        printf("horizband ");
288cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_DR1)
289cabdff1aSopenharmony_ci        printf("dr1 ");
290cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_DELAY)
291cabdff1aSopenharmony_ci        printf("delay ");
292cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
293cabdff1aSopenharmony_ci        printf("small ");
294cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
295cabdff1aSopenharmony_ci        printf("subframes ");
296cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
297cabdff1aSopenharmony_ci        printf("exp ");
298cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
299cabdff1aSopenharmony_ci        printf("chconf ");
300cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
301cabdff1aSopenharmony_ci        printf("paramchange ");
302cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
303cabdff1aSopenharmony_ci        printf("variable ");
304cabdff1aSopenharmony_ci    if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
305cabdff1aSopenharmony_ci                           AV_CODEC_CAP_SLICE_THREADS |
306cabdff1aSopenharmony_ci                           AV_CODEC_CAP_OTHER_THREADS))
307cabdff1aSopenharmony_ci        printf("threads ");
308cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
309cabdff1aSopenharmony_ci        printf("avoidprobe ");
310cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_HARDWARE)
311cabdff1aSopenharmony_ci        printf("hardware ");
312cabdff1aSopenharmony_ci    if (c->capabilities & AV_CODEC_CAP_HYBRID)
313cabdff1aSopenharmony_ci        printf("hybrid ");
314cabdff1aSopenharmony_ci    if (!c->capabilities)
315cabdff1aSopenharmony_ci        printf("none");
316cabdff1aSopenharmony_ci    printf("\n");
317cabdff1aSopenharmony_ci
318cabdff1aSopenharmony_ci    if (c->type == AVMEDIA_TYPE_VIDEO ||
319cabdff1aSopenharmony_ci        c->type == AVMEDIA_TYPE_AUDIO) {
320cabdff1aSopenharmony_ci        printf("    Threading capabilities: ");
321cabdff1aSopenharmony_ci        switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
322cabdff1aSopenharmony_ci                                   AV_CODEC_CAP_SLICE_THREADS |
323cabdff1aSopenharmony_ci                                   AV_CODEC_CAP_OTHER_THREADS)) {
324cabdff1aSopenharmony_ci        case AV_CODEC_CAP_FRAME_THREADS |
325cabdff1aSopenharmony_ci             AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
326cabdff1aSopenharmony_ci        case AV_CODEC_CAP_FRAME_THREADS: printf("frame");           break;
327cabdff1aSopenharmony_ci        case AV_CODEC_CAP_SLICE_THREADS: printf("slice");           break;
328cabdff1aSopenharmony_ci        case AV_CODEC_CAP_OTHER_THREADS: printf("other");           break;
329cabdff1aSopenharmony_ci        default:                         printf("none");            break;
330cabdff1aSopenharmony_ci        }
331cabdff1aSopenharmony_ci        printf("\n");
332cabdff1aSopenharmony_ci    }
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_ci    if (avcodec_get_hw_config(c, 0)) {
335cabdff1aSopenharmony_ci        printf("    Supported hardware devices: ");
336cabdff1aSopenharmony_ci        for (int i = 0;; i++) {
337cabdff1aSopenharmony_ci            const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
338cabdff1aSopenharmony_ci            if (!config)
339cabdff1aSopenharmony_ci                break;
340cabdff1aSopenharmony_ci            printf("%s ", av_hwdevice_get_type_name(config->device_type));
341cabdff1aSopenharmony_ci        }
342cabdff1aSopenharmony_ci        printf("\n");
343cabdff1aSopenharmony_ci    }
344cabdff1aSopenharmony_ci
345cabdff1aSopenharmony_ci    if (c->supported_framerates) {
346cabdff1aSopenharmony_ci        const AVRational *fps = c->supported_framerates;
347cabdff1aSopenharmony_ci
348cabdff1aSopenharmony_ci        printf("    Supported framerates:");
349cabdff1aSopenharmony_ci        while (fps->num) {
350cabdff1aSopenharmony_ci            printf(" %d/%d", fps->num, fps->den);
351cabdff1aSopenharmony_ci            fps++;
352cabdff1aSopenharmony_ci        }
353cabdff1aSopenharmony_ci        printf("\n");
354cabdff1aSopenharmony_ci    }
355cabdff1aSopenharmony_ci    PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
356cabdff1aSopenharmony_ci                          AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
357cabdff1aSopenharmony_ci    PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
358cabdff1aSopenharmony_ci                          GET_SAMPLE_RATE_NAME);
359cabdff1aSopenharmony_ci    PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
360cabdff1aSopenharmony_ci                          AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci    if (c->ch_layouts) {
363cabdff1aSopenharmony_ci        const AVChannelLayout *p = c->ch_layouts;
364cabdff1aSopenharmony_ci
365cabdff1aSopenharmony_ci        printf("    Supported channel layouts:");
366cabdff1aSopenharmony_ci        while (p->nb_channels) {
367cabdff1aSopenharmony_ci            char name[128];
368cabdff1aSopenharmony_ci            av_channel_layout_describe(p, name, sizeof(name));
369cabdff1aSopenharmony_ci            printf(" %s", name);
370cabdff1aSopenharmony_ci            p++;
371cabdff1aSopenharmony_ci        }
372cabdff1aSopenharmony_ci        printf("\n");
373cabdff1aSopenharmony_ci    }
374cabdff1aSopenharmony_ci
375cabdff1aSopenharmony_ci    if (c->priv_class) {
376cabdff1aSopenharmony_ci        show_help_children(c->priv_class,
377cabdff1aSopenharmony_ci                           AV_OPT_FLAG_ENCODING_PARAM |
378cabdff1aSopenharmony_ci                           AV_OPT_FLAG_DECODING_PARAM);
379cabdff1aSopenharmony_ci    }
380cabdff1aSopenharmony_ci}
381cabdff1aSopenharmony_ci
382cabdff1aSopenharmony_cistatic const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
383cabdff1aSopenharmony_ci                                        int encoder)
384cabdff1aSopenharmony_ci{
385cabdff1aSopenharmony_ci    const AVCodec *c;
386cabdff1aSopenharmony_ci    while ((c = av_codec_iterate(iter))) {
387cabdff1aSopenharmony_ci        if (c->id == id &&
388cabdff1aSopenharmony_ci            (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
389cabdff1aSopenharmony_ci            return c;
390cabdff1aSopenharmony_ci    }
391cabdff1aSopenharmony_ci    return NULL;
392cabdff1aSopenharmony_ci}
393cabdff1aSopenharmony_ci
394cabdff1aSopenharmony_cistatic void show_help_codec(const char *name, int encoder)
395cabdff1aSopenharmony_ci{
396cabdff1aSopenharmony_ci    const AVCodecDescriptor *desc;
397cabdff1aSopenharmony_ci    const AVCodec *codec;
398cabdff1aSopenharmony_ci
399cabdff1aSopenharmony_ci    if (!name) {
400cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
401cabdff1aSopenharmony_ci        return;
402cabdff1aSopenharmony_ci    }
403cabdff1aSopenharmony_ci
404cabdff1aSopenharmony_ci    codec = encoder ? avcodec_find_encoder_by_name(name) :
405cabdff1aSopenharmony_ci                      avcodec_find_decoder_by_name(name);
406cabdff1aSopenharmony_ci
407cabdff1aSopenharmony_ci    if (codec)
408cabdff1aSopenharmony_ci        print_codec(codec);
409cabdff1aSopenharmony_ci    else if ((desc = avcodec_descriptor_get_by_name(name))) {
410cabdff1aSopenharmony_ci        void *iter = NULL;
411cabdff1aSopenharmony_ci        int printed = 0;
412cabdff1aSopenharmony_ci
413cabdff1aSopenharmony_ci        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
414cabdff1aSopenharmony_ci            printed = 1;
415cabdff1aSopenharmony_ci            print_codec(codec);
416cabdff1aSopenharmony_ci        }
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_ci        if (!printed) {
419cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
420cabdff1aSopenharmony_ci                   "but no %s for it are available. FFmpeg might need to be "
421cabdff1aSopenharmony_ci                   "recompiled with additional external libraries.\n",
422cabdff1aSopenharmony_ci                   name, encoder ? "encoders" : "decoders");
423cabdff1aSopenharmony_ci        }
424cabdff1aSopenharmony_ci    } else {
425cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
426cabdff1aSopenharmony_ci               name);
427cabdff1aSopenharmony_ci    }
428cabdff1aSopenharmony_ci}
429cabdff1aSopenharmony_ci
430cabdff1aSopenharmony_cistatic void show_help_demuxer(const char *name)
431cabdff1aSopenharmony_ci{
432cabdff1aSopenharmony_ci    const AVInputFormat *fmt = av_find_input_format(name);
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_ci    if (!fmt) {
435cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
436cabdff1aSopenharmony_ci        return;
437cabdff1aSopenharmony_ci    }
438cabdff1aSopenharmony_ci
439cabdff1aSopenharmony_ci    printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
440cabdff1aSopenharmony_ci
441cabdff1aSopenharmony_ci    if (fmt->extensions)
442cabdff1aSopenharmony_ci        printf("    Common extensions: %s.\n", fmt->extensions);
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci    if (fmt->priv_class)
445cabdff1aSopenharmony_ci        show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
446cabdff1aSopenharmony_ci}
447cabdff1aSopenharmony_ci
448cabdff1aSopenharmony_cistatic void show_help_protocol(const char *name)
449cabdff1aSopenharmony_ci{
450cabdff1aSopenharmony_ci    const AVClass *proto_class;
451cabdff1aSopenharmony_ci
452cabdff1aSopenharmony_ci    if (!name) {
453cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
454cabdff1aSopenharmony_ci        return;
455cabdff1aSopenharmony_ci    }
456cabdff1aSopenharmony_ci
457cabdff1aSopenharmony_ci    proto_class = avio_protocol_get_class(name);
458cabdff1aSopenharmony_ci    if (!proto_class) {
459cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
460cabdff1aSopenharmony_ci        return;
461cabdff1aSopenharmony_ci    }
462cabdff1aSopenharmony_ci
463cabdff1aSopenharmony_ci    show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
464cabdff1aSopenharmony_ci}
465cabdff1aSopenharmony_ci
466cabdff1aSopenharmony_cistatic void show_help_muxer(const char *name)
467cabdff1aSopenharmony_ci{
468cabdff1aSopenharmony_ci    const AVCodecDescriptor *desc;
469cabdff1aSopenharmony_ci    const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
470cabdff1aSopenharmony_ci
471cabdff1aSopenharmony_ci    if (!fmt) {
472cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
473cabdff1aSopenharmony_ci        return;
474cabdff1aSopenharmony_ci    }
475cabdff1aSopenharmony_ci
476cabdff1aSopenharmony_ci    printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci    if (fmt->extensions)
479cabdff1aSopenharmony_ci        printf("    Common extensions: %s.\n", fmt->extensions);
480cabdff1aSopenharmony_ci    if (fmt->mime_type)
481cabdff1aSopenharmony_ci        printf("    Mime type: %s.\n", fmt->mime_type);
482cabdff1aSopenharmony_ci    if (fmt->video_codec != AV_CODEC_ID_NONE &&
483cabdff1aSopenharmony_ci        (desc = avcodec_descriptor_get(fmt->video_codec))) {
484cabdff1aSopenharmony_ci        printf("    Default video codec: %s.\n", desc->name);
485cabdff1aSopenharmony_ci    }
486cabdff1aSopenharmony_ci    if (fmt->audio_codec != AV_CODEC_ID_NONE &&
487cabdff1aSopenharmony_ci        (desc = avcodec_descriptor_get(fmt->audio_codec))) {
488cabdff1aSopenharmony_ci        printf("    Default audio codec: %s.\n", desc->name);
489cabdff1aSopenharmony_ci    }
490cabdff1aSopenharmony_ci    if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
491cabdff1aSopenharmony_ci        (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
492cabdff1aSopenharmony_ci        printf("    Default subtitle codec: %s.\n", desc->name);
493cabdff1aSopenharmony_ci    }
494cabdff1aSopenharmony_ci
495cabdff1aSopenharmony_ci    if (fmt->priv_class)
496cabdff1aSopenharmony_ci        show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
497cabdff1aSopenharmony_ci}
498cabdff1aSopenharmony_ci
499cabdff1aSopenharmony_ci#if CONFIG_AVFILTER
500cabdff1aSopenharmony_cistatic void show_help_filter(const char *name)
501cabdff1aSopenharmony_ci{
502cabdff1aSopenharmony_ci#if CONFIG_AVFILTER
503cabdff1aSopenharmony_ci    const AVFilter *f = avfilter_get_by_name(name);
504cabdff1aSopenharmony_ci    int i, count;
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci    if (!name) {
507cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
508cabdff1aSopenharmony_ci        return;
509cabdff1aSopenharmony_ci    } else if (!f) {
510cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
511cabdff1aSopenharmony_ci        return;
512cabdff1aSopenharmony_ci    }
513cabdff1aSopenharmony_ci
514cabdff1aSopenharmony_ci    printf("Filter %s\n", f->name);
515cabdff1aSopenharmony_ci    if (f->description)
516cabdff1aSopenharmony_ci        printf("  %s\n", f->description);
517cabdff1aSopenharmony_ci
518cabdff1aSopenharmony_ci    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
519cabdff1aSopenharmony_ci        printf("    slice threading supported\n");
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    printf("    Inputs:\n");
522cabdff1aSopenharmony_ci    count = avfilter_filter_pad_count(f, 0);
523cabdff1aSopenharmony_ci    for (i = 0; i < count; i++) {
524cabdff1aSopenharmony_ci        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
525cabdff1aSopenharmony_ci               av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
526cabdff1aSopenharmony_ci    }
527cabdff1aSopenharmony_ci    if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
528cabdff1aSopenharmony_ci        printf("        dynamic (depending on the options)\n");
529cabdff1aSopenharmony_ci    else if (!count)
530cabdff1aSopenharmony_ci        printf("        none (source filter)\n");
531cabdff1aSopenharmony_ci
532cabdff1aSopenharmony_ci    printf("    Outputs:\n");
533cabdff1aSopenharmony_ci    count = avfilter_filter_pad_count(f, 1);
534cabdff1aSopenharmony_ci    for (i = 0; i < count; i++) {
535cabdff1aSopenharmony_ci        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
536cabdff1aSopenharmony_ci               av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
537cabdff1aSopenharmony_ci    }
538cabdff1aSopenharmony_ci    if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
539cabdff1aSopenharmony_ci        printf("        dynamic (depending on the options)\n");
540cabdff1aSopenharmony_ci    else if (!count)
541cabdff1aSopenharmony_ci        printf("        none (sink filter)\n");
542cabdff1aSopenharmony_ci
543cabdff1aSopenharmony_ci    if (f->priv_class)
544cabdff1aSopenharmony_ci        show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
545cabdff1aSopenharmony_ci                                          AV_OPT_FLAG_AUDIO_PARAM);
546cabdff1aSopenharmony_ci    if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
547cabdff1aSopenharmony_ci        printf("This filter has support for timeline through the 'enable' option.\n");
548cabdff1aSopenharmony_ci#else
549cabdff1aSopenharmony_ci    av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
550cabdff1aSopenharmony_ci           "can not to satisfy request\n");
551cabdff1aSopenharmony_ci#endif
552cabdff1aSopenharmony_ci}
553cabdff1aSopenharmony_ci#endif
554cabdff1aSopenharmony_ci
555cabdff1aSopenharmony_cistatic void show_help_bsf(const char *name)
556cabdff1aSopenharmony_ci{
557cabdff1aSopenharmony_ci    const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
558cabdff1aSopenharmony_ci
559cabdff1aSopenharmony_ci    if (!name) {
560cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
561cabdff1aSopenharmony_ci        return;
562cabdff1aSopenharmony_ci    } else if (!bsf) {
563cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
564cabdff1aSopenharmony_ci        return;
565cabdff1aSopenharmony_ci    }
566cabdff1aSopenharmony_ci
567cabdff1aSopenharmony_ci    printf("Bit stream filter %s\n", bsf->name);
568cabdff1aSopenharmony_ci    PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
569cabdff1aSopenharmony_ci                          AV_CODEC_ID_NONE, GET_CODEC_NAME);
570cabdff1aSopenharmony_ci    if (bsf->priv_class)
571cabdff1aSopenharmony_ci        show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
572cabdff1aSopenharmony_ci}
573cabdff1aSopenharmony_ci
574cabdff1aSopenharmony_ciint show_help(void *optctx, const char *opt, const char *arg)
575cabdff1aSopenharmony_ci{
576cabdff1aSopenharmony_ci    char *topic, *par;
577cabdff1aSopenharmony_ci    av_log_set_callback(log_callback_help);
578cabdff1aSopenharmony_ci
579cabdff1aSopenharmony_ci    topic = av_strdup(arg ? arg : "");
580cabdff1aSopenharmony_ci    if (!topic)
581cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
582cabdff1aSopenharmony_ci    par = strchr(topic, '=');
583cabdff1aSopenharmony_ci    if (par)
584cabdff1aSopenharmony_ci        *par++ = 0;
585cabdff1aSopenharmony_ci
586cabdff1aSopenharmony_ci    if (!*topic) {
587cabdff1aSopenharmony_ci        show_help_default(topic, par);
588cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "decoder")) {
589cabdff1aSopenharmony_ci        show_help_codec(par, 0);
590cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "encoder")) {
591cabdff1aSopenharmony_ci        show_help_codec(par, 1);
592cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "demuxer")) {
593cabdff1aSopenharmony_ci        show_help_demuxer(par);
594cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "muxer")) {
595cabdff1aSopenharmony_ci        show_help_muxer(par);
596cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "protocol")) {
597cabdff1aSopenharmony_ci        show_help_protocol(par);
598cabdff1aSopenharmony_ci#if CONFIG_AVFILTER
599cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "filter")) {
600cabdff1aSopenharmony_ci        show_help_filter(par);
601cabdff1aSopenharmony_ci#endif
602cabdff1aSopenharmony_ci    } else if (!strcmp(topic, "bsf")) {
603cabdff1aSopenharmony_ci        show_help_bsf(par);
604cabdff1aSopenharmony_ci    } else {
605cabdff1aSopenharmony_ci        show_help_default(topic, par);
606cabdff1aSopenharmony_ci    }
607cabdff1aSopenharmony_ci
608cabdff1aSopenharmony_ci    av_freep(&topic);
609cabdff1aSopenharmony_ci    return 0;
610cabdff1aSopenharmony_ci}
611cabdff1aSopenharmony_ci
612cabdff1aSopenharmony_cistatic void print_codecs_for_id(enum AVCodecID id, int encoder)
613cabdff1aSopenharmony_ci{
614cabdff1aSopenharmony_ci    void *iter = NULL;
615cabdff1aSopenharmony_ci    const AVCodec *codec;
616cabdff1aSopenharmony_ci
617cabdff1aSopenharmony_ci    printf(" (%s: ", encoder ? "encoders" : "decoders");
618cabdff1aSopenharmony_ci
619cabdff1aSopenharmony_ci    while ((codec = next_codec_for_id(id, &iter, encoder)))
620cabdff1aSopenharmony_ci        printf("%s ", codec->name);
621cabdff1aSopenharmony_ci
622cabdff1aSopenharmony_ci    printf(")");
623cabdff1aSopenharmony_ci}
624cabdff1aSopenharmony_ci
625cabdff1aSopenharmony_cistatic int compare_codec_desc(const void *a, const void *b)
626cabdff1aSopenharmony_ci{
627cabdff1aSopenharmony_ci    const AVCodecDescriptor * const *da = a;
628cabdff1aSopenharmony_ci    const AVCodecDescriptor * const *db = b;
629cabdff1aSopenharmony_ci
630cabdff1aSopenharmony_ci    return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
631cabdff1aSopenharmony_ci           strcmp((*da)->name, (*db)->name);
632cabdff1aSopenharmony_ci}
633cabdff1aSopenharmony_ci
634cabdff1aSopenharmony_cistatic unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
635cabdff1aSopenharmony_ci{
636cabdff1aSopenharmony_ci    const AVCodecDescriptor *desc = NULL;
637cabdff1aSopenharmony_ci    const AVCodecDescriptor **codecs;
638cabdff1aSopenharmony_ci    unsigned nb_codecs = 0, i = 0;
639cabdff1aSopenharmony_ci
640cabdff1aSopenharmony_ci    while ((desc = avcodec_descriptor_next(desc)))
641cabdff1aSopenharmony_ci        nb_codecs++;
642cabdff1aSopenharmony_ci    if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
643cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
644cabdff1aSopenharmony_ci        exit_program(1);
645cabdff1aSopenharmony_ci    }
646cabdff1aSopenharmony_ci    desc = NULL;
647cabdff1aSopenharmony_ci    while ((desc = avcodec_descriptor_next(desc)))
648cabdff1aSopenharmony_ci        codecs[i++] = desc;
649cabdff1aSopenharmony_ci    av_assert0(i == nb_codecs);
650cabdff1aSopenharmony_ci    qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
651cabdff1aSopenharmony_ci    *rcodecs = codecs;
652cabdff1aSopenharmony_ci    return nb_codecs;
653cabdff1aSopenharmony_ci}
654cabdff1aSopenharmony_ci
655cabdff1aSopenharmony_cistatic char get_media_type_char(enum AVMediaType type)
656cabdff1aSopenharmony_ci{
657cabdff1aSopenharmony_ci    switch (type) {
658cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_VIDEO:    return 'V';
659cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_AUDIO:    return 'A';
660cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_DATA:     return 'D';
661cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_SUBTITLE: return 'S';
662cabdff1aSopenharmony_ci        case AVMEDIA_TYPE_ATTACHMENT:return 'T';
663cabdff1aSopenharmony_ci        default:                    return '?';
664cabdff1aSopenharmony_ci    }
665cabdff1aSopenharmony_ci}
666cabdff1aSopenharmony_ci
667cabdff1aSopenharmony_ciint show_codecs(void *optctx, const char *opt, const char *arg)
668cabdff1aSopenharmony_ci{
669cabdff1aSopenharmony_ci    const AVCodecDescriptor **codecs;
670cabdff1aSopenharmony_ci    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
671cabdff1aSopenharmony_ci
672cabdff1aSopenharmony_ci    printf("Codecs:\n"
673cabdff1aSopenharmony_ci           " D..... = Decoding supported\n"
674cabdff1aSopenharmony_ci           " .E.... = Encoding supported\n"
675cabdff1aSopenharmony_ci           " ..V... = Video codec\n"
676cabdff1aSopenharmony_ci           " ..A... = Audio codec\n"
677cabdff1aSopenharmony_ci           " ..S... = Subtitle codec\n"
678cabdff1aSopenharmony_ci           " ..D... = Data codec\n"
679cabdff1aSopenharmony_ci           " ..T... = Attachment codec\n"
680cabdff1aSopenharmony_ci           " ...I.. = Intra frame-only codec\n"
681cabdff1aSopenharmony_ci           " ....L. = Lossy compression\n"
682cabdff1aSopenharmony_ci           " .....S = Lossless compression\n"
683cabdff1aSopenharmony_ci           " -------\n");
684cabdff1aSopenharmony_ci    for (i = 0; i < nb_codecs; i++) {
685cabdff1aSopenharmony_ci        const AVCodecDescriptor *desc = codecs[i];
686cabdff1aSopenharmony_ci        const AVCodec *codec;
687cabdff1aSopenharmony_ci        void *iter = NULL;
688cabdff1aSopenharmony_ci
689cabdff1aSopenharmony_ci        if (strstr(desc->name, "_deprecated"))
690cabdff1aSopenharmony_ci            continue;
691cabdff1aSopenharmony_ci
692cabdff1aSopenharmony_ci        printf(" ");
693cabdff1aSopenharmony_ci        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
694cabdff1aSopenharmony_ci        printf(avcodec_find_encoder(desc->id) ? "E" : ".");
695cabdff1aSopenharmony_ci
696cabdff1aSopenharmony_ci        printf("%c", get_media_type_char(desc->type));
697cabdff1aSopenharmony_ci        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
698cabdff1aSopenharmony_ci        printf((desc->props & AV_CODEC_PROP_LOSSY)      ? "L" : ".");
699cabdff1aSopenharmony_ci        printf((desc->props & AV_CODEC_PROP_LOSSLESS)   ? "S" : ".");
700cabdff1aSopenharmony_ci
701cabdff1aSopenharmony_ci        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
702cabdff1aSopenharmony_ci
703cabdff1aSopenharmony_ci        /* print decoders/encoders when there's more than one or their
704cabdff1aSopenharmony_ci         * names are different from codec name */
705cabdff1aSopenharmony_ci        while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
706cabdff1aSopenharmony_ci            if (strcmp(codec->name, desc->name)) {
707cabdff1aSopenharmony_ci                print_codecs_for_id(desc->id, 0);
708cabdff1aSopenharmony_ci                break;
709cabdff1aSopenharmony_ci            }
710cabdff1aSopenharmony_ci        }
711cabdff1aSopenharmony_ci        iter = NULL;
712cabdff1aSopenharmony_ci        while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
713cabdff1aSopenharmony_ci            if (strcmp(codec->name, desc->name)) {
714cabdff1aSopenharmony_ci                print_codecs_for_id(desc->id, 1);
715cabdff1aSopenharmony_ci                break;
716cabdff1aSopenharmony_ci            }
717cabdff1aSopenharmony_ci        }
718cabdff1aSopenharmony_ci
719cabdff1aSopenharmony_ci        printf("\n");
720cabdff1aSopenharmony_ci    }
721cabdff1aSopenharmony_ci    av_free(codecs);
722cabdff1aSopenharmony_ci    return 0;
723cabdff1aSopenharmony_ci}
724cabdff1aSopenharmony_ci
725cabdff1aSopenharmony_cistatic void print_codecs(int encoder)
726cabdff1aSopenharmony_ci{
727cabdff1aSopenharmony_ci    const AVCodecDescriptor **codecs;
728cabdff1aSopenharmony_ci    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
729cabdff1aSopenharmony_ci
730cabdff1aSopenharmony_ci    printf("%s:\n"
731cabdff1aSopenharmony_ci           " V..... = Video\n"
732cabdff1aSopenharmony_ci           " A..... = Audio\n"
733cabdff1aSopenharmony_ci           " S..... = Subtitle\n"
734cabdff1aSopenharmony_ci           " .F.... = Frame-level multithreading\n"
735cabdff1aSopenharmony_ci           " ..S... = Slice-level multithreading\n"
736cabdff1aSopenharmony_ci           " ...X.. = Codec is experimental\n"
737cabdff1aSopenharmony_ci           " ....B. = Supports draw_horiz_band\n"
738cabdff1aSopenharmony_ci           " .....D = Supports direct rendering method 1\n"
739cabdff1aSopenharmony_ci           " ------\n",
740cabdff1aSopenharmony_ci           encoder ? "Encoders" : "Decoders");
741cabdff1aSopenharmony_ci    for (i = 0; i < nb_codecs; i++) {
742cabdff1aSopenharmony_ci        const AVCodecDescriptor *desc = codecs[i];
743cabdff1aSopenharmony_ci        const AVCodec *codec;
744cabdff1aSopenharmony_ci        void *iter = NULL;
745cabdff1aSopenharmony_ci
746cabdff1aSopenharmony_ci        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
747cabdff1aSopenharmony_ci            printf(" %c", get_media_type_char(desc->type));
748cabdff1aSopenharmony_ci            printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
749cabdff1aSopenharmony_ci            printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
750cabdff1aSopenharmony_ci            printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
751cabdff1aSopenharmony_ci            printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
752cabdff1aSopenharmony_ci            printf((codec->capabilities & AV_CODEC_CAP_DR1)           ? "D" : ".");
753cabdff1aSopenharmony_ci
754cabdff1aSopenharmony_ci            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
755cabdff1aSopenharmony_ci            if (strcmp(codec->name, desc->name))
756cabdff1aSopenharmony_ci                printf(" (codec %s)", desc->name);
757cabdff1aSopenharmony_ci
758cabdff1aSopenharmony_ci            printf("\n");
759cabdff1aSopenharmony_ci        }
760cabdff1aSopenharmony_ci    }
761cabdff1aSopenharmony_ci    av_free(codecs);
762cabdff1aSopenharmony_ci}
763cabdff1aSopenharmony_ci
764cabdff1aSopenharmony_ciint show_decoders(void *optctx, const char *opt, const char *arg)
765cabdff1aSopenharmony_ci{
766cabdff1aSopenharmony_ci    print_codecs(0);
767cabdff1aSopenharmony_ci    return 0;
768cabdff1aSopenharmony_ci}
769cabdff1aSopenharmony_ci
770cabdff1aSopenharmony_ciint show_encoders(void *optctx, const char *opt, const char *arg)
771cabdff1aSopenharmony_ci{
772cabdff1aSopenharmony_ci    print_codecs(1);
773cabdff1aSopenharmony_ci    return 0;
774cabdff1aSopenharmony_ci}
775cabdff1aSopenharmony_ci
776cabdff1aSopenharmony_ciint show_bsfs(void *optctx, const char *opt, const char *arg)
777cabdff1aSopenharmony_ci{
778cabdff1aSopenharmony_ci    const AVBitStreamFilter *bsf = NULL;
779cabdff1aSopenharmony_ci    void *opaque = NULL;
780cabdff1aSopenharmony_ci
781cabdff1aSopenharmony_ci    printf("Bitstream filters:\n");
782cabdff1aSopenharmony_ci    while ((bsf = av_bsf_iterate(&opaque)))
783cabdff1aSopenharmony_ci        printf("%s\n", bsf->name);
784cabdff1aSopenharmony_ci    printf("\n");
785cabdff1aSopenharmony_ci    return 0;
786cabdff1aSopenharmony_ci}
787cabdff1aSopenharmony_ci
788cabdff1aSopenharmony_ciint show_filters(void *optctx, const char *opt, const char *arg)
789cabdff1aSopenharmony_ci{
790cabdff1aSopenharmony_ci#if CONFIG_AVFILTER
791cabdff1aSopenharmony_ci    const AVFilter *filter = NULL;
792cabdff1aSopenharmony_ci    char descr[64], *descr_cur;
793cabdff1aSopenharmony_ci    void *opaque = NULL;
794cabdff1aSopenharmony_ci    int i, j;
795cabdff1aSopenharmony_ci    const AVFilterPad *pad;
796cabdff1aSopenharmony_ci
797cabdff1aSopenharmony_ci    printf("Filters:\n"
798cabdff1aSopenharmony_ci           "  T.. = Timeline support\n"
799cabdff1aSopenharmony_ci           "  .S. = Slice threading\n"
800cabdff1aSopenharmony_ci           "  ..C = Command support\n"
801cabdff1aSopenharmony_ci           "  A = Audio input/output\n"
802cabdff1aSopenharmony_ci           "  V = Video input/output\n"
803cabdff1aSopenharmony_ci           "  N = Dynamic number and/or type of input/output\n"
804cabdff1aSopenharmony_ci           "  | = Source or sink filter\n");
805cabdff1aSopenharmony_ci    while ((filter = av_filter_iterate(&opaque))) {
806cabdff1aSopenharmony_ci        descr_cur = descr;
807cabdff1aSopenharmony_ci        for (i = 0; i < 2; i++) {
808cabdff1aSopenharmony_ci            unsigned nb_pads;
809cabdff1aSopenharmony_ci            if (i) {
810cabdff1aSopenharmony_ci                *(descr_cur++) = '-';
811cabdff1aSopenharmony_ci                *(descr_cur++) = '>';
812cabdff1aSopenharmony_ci            }
813cabdff1aSopenharmony_ci            pad = i ? filter->outputs : filter->inputs;
814cabdff1aSopenharmony_ci            nb_pads = avfilter_filter_pad_count(filter, i);
815cabdff1aSopenharmony_ci            for (j = 0; j < nb_pads; j++) {
816cabdff1aSopenharmony_ci                if (descr_cur >= descr + sizeof(descr) - 4)
817cabdff1aSopenharmony_ci                    break;
818cabdff1aSopenharmony_ci                *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
819cabdff1aSopenharmony_ci            }
820cabdff1aSopenharmony_ci            if (!j)
821cabdff1aSopenharmony_ci                *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
822cabdff1aSopenharmony_ci                                  ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
823cabdff1aSopenharmony_ci        }
824cabdff1aSopenharmony_ci        *descr_cur = 0;
825cabdff1aSopenharmony_ci        printf(" %c%c%c %-17s %-10s %s\n",
826cabdff1aSopenharmony_ci               filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
827cabdff1aSopenharmony_ci               filter->flags & AVFILTER_FLAG_SLICE_THREADS    ? 'S' : '.',
828cabdff1aSopenharmony_ci               filter->process_command                        ? 'C' : '.',
829cabdff1aSopenharmony_ci               filter->name, descr, filter->description);
830cabdff1aSopenharmony_ci    }
831cabdff1aSopenharmony_ci#else
832cabdff1aSopenharmony_ci    printf("No filters available: libavfilter disabled\n");
833cabdff1aSopenharmony_ci#endif
834cabdff1aSopenharmony_ci    return 0;
835cabdff1aSopenharmony_ci}
836cabdff1aSopenharmony_ci
837cabdff1aSopenharmony_cistatic int is_device(const AVClass *avclass)
838cabdff1aSopenharmony_ci{
839cabdff1aSopenharmony_ci    if (!avclass)
840cabdff1aSopenharmony_ci        return 0;
841cabdff1aSopenharmony_ci    return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
842cabdff1aSopenharmony_ci}
843cabdff1aSopenharmony_ci
844cabdff1aSopenharmony_cistatic int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
845cabdff1aSopenharmony_ci{
846cabdff1aSopenharmony_ci    void *ifmt_opaque = NULL;
847cabdff1aSopenharmony_ci    const AVInputFormat *ifmt  = NULL;
848cabdff1aSopenharmony_ci    void *ofmt_opaque = NULL;
849cabdff1aSopenharmony_ci    const AVOutputFormat *ofmt = NULL;
850cabdff1aSopenharmony_ci    const char *last_name;
851cabdff1aSopenharmony_ci    int is_dev;
852cabdff1aSopenharmony_ci
853cabdff1aSopenharmony_ci    printf("%s\n"
854cabdff1aSopenharmony_ci           " D. = Demuxing supported\n"
855cabdff1aSopenharmony_ci           " .E = Muxing supported\n"
856cabdff1aSopenharmony_ci           " --\n", device_only ? "Devices:" : "File formats:");
857cabdff1aSopenharmony_ci    last_name = "000";
858cabdff1aSopenharmony_ci    for (;;) {
859cabdff1aSopenharmony_ci        int decode = 0;
860cabdff1aSopenharmony_ci        int encode = 0;
861cabdff1aSopenharmony_ci        const char *name      = NULL;
862cabdff1aSopenharmony_ci        const char *long_name = NULL;
863cabdff1aSopenharmony_ci
864cabdff1aSopenharmony_ci        if (muxdemuxers !=SHOW_DEMUXERS) {
865cabdff1aSopenharmony_ci            ofmt_opaque = NULL;
866cabdff1aSopenharmony_ci            while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
867cabdff1aSopenharmony_ci                is_dev = is_device(ofmt->priv_class);
868cabdff1aSopenharmony_ci                if (!is_dev && device_only)
869cabdff1aSopenharmony_ci                    continue;
870cabdff1aSopenharmony_ci                if ((!name || strcmp(ofmt->name, name) < 0) &&
871cabdff1aSopenharmony_ci                    strcmp(ofmt->name, last_name) > 0) {
872cabdff1aSopenharmony_ci                    name      = ofmt->name;
873cabdff1aSopenharmony_ci                    long_name = ofmt->long_name;
874cabdff1aSopenharmony_ci                    encode    = 1;
875cabdff1aSopenharmony_ci                }
876cabdff1aSopenharmony_ci            }
877cabdff1aSopenharmony_ci        }
878cabdff1aSopenharmony_ci        if (muxdemuxers != SHOW_MUXERS) {
879cabdff1aSopenharmony_ci            ifmt_opaque = NULL;
880cabdff1aSopenharmony_ci            while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
881cabdff1aSopenharmony_ci                is_dev = is_device(ifmt->priv_class);
882cabdff1aSopenharmony_ci                if (!is_dev && device_only)
883cabdff1aSopenharmony_ci                    continue;
884cabdff1aSopenharmony_ci                if ((!name || strcmp(ifmt->name, name) < 0) &&
885cabdff1aSopenharmony_ci                    strcmp(ifmt->name, last_name) > 0) {
886cabdff1aSopenharmony_ci                    name      = ifmt->name;
887cabdff1aSopenharmony_ci                    long_name = ifmt->long_name;
888cabdff1aSopenharmony_ci                    encode    = 0;
889cabdff1aSopenharmony_ci                }
890cabdff1aSopenharmony_ci                if (name && strcmp(ifmt->name, name) == 0)
891cabdff1aSopenharmony_ci                    decode = 1;
892cabdff1aSopenharmony_ci            }
893cabdff1aSopenharmony_ci        }
894cabdff1aSopenharmony_ci        if (!name)
895cabdff1aSopenharmony_ci            break;
896cabdff1aSopenharmony_ci        last_name = name;
897cabdff1aSopenharmony_ci
898cabdff1aSopenharmony_ci        printf(" %c%c %-15s %s\n",
899cabdff1aSopenharmony_ci               decode ? 'D' : ' ',
900cabdff1aSopenharmony_ci               encode ? 'E' : ' ',
901cabdff1aSopenharmony_ci               name,
902cabdff1aSopenharmony_ci            long_name ? long_name:" ");
903cabdff1aSopenharmony_ci    }
904cabdff1aSopenharmony_ci    return 0;
905cabdff1aSopenharmony_ci}
906cabdff1aSopenharmony_ci
907cabdff1aSopenharmony_ciint show_formats(void *optctx, const char *opt, const char *arg)
908cabdff1aSopenharmony_ci{
909cabdff1aSopenharmony_ci    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
910cabdff1aSopenharmony_ci}
911cabdff1aSopenharmony_ci
912cabdff1aSopenharmony_ciint show_muxers(void *optctx, const char *opt, const char *arg)
913cabdff1aSopenharmony_ci{
914cabdff1aSopenharmony_ci    return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
915cabdff1aSopenharmony_ci}
916cabdff1aSopenharmony_ci
917cabdff1aSopenharmony_ciint show_demuxers(void *optctx, const char *opt, const char *arg)
918cabdff1aSopenharmony_ci{
919cabdff1aSopenharmony_ci    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
920cabdff1aSopenharmony_ci}
921cabdff1aSopenharmony_ci
922cabdff1aSopenharmony_ciint show_devices(void *optctx, const char *opt, const char *arg)
923cabdff1aSopenharmony_ci{
924cabdff1aSopenharmony_ci    return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
925cabdff1aSopenharmony_ci}
926cabdff1aSopenharmony_ci
927cabdff1aSopenharmony_ciint show_protocols(void *optctx, const char *opt, const char *arg)
928cabdff1aSopenharmony_ci{
929cabdff1aSopenharmony_ci    void *opaque = NULL;
930cabdff1aSopenharmony_ci    const char *name;
931cabdff1aSopenharmony_ci
932cabdff1aSopenharmony_ci    printf("Supported file protocols:\n"
933cabdff1aSopenharmony_ci           "Input:\n");
934cabdff1aSopenharmony_ci    while ((name = avio_enum_protocols(&opaque, 0)))
935cabdff1aSopenharmony_ci        printf("  %s\n", name);
936cabdff1aSopenharmony_ci    printf("Output:\n");
937cabdff1aSopenharmony_ci    while ((name = avio_enum_protocols(&opaque, 1)))
938cabdff1aSopenharmony_ci        printf("  %s\n", name);
939cabdff1aSopenharmony_ci    return 0;
940cabdff1aSopenharmony_ci}
941cabdff1aSopenharmony_ci
942cabdff1aSopenharmony_ciint show_colors(void *optctx, const char *opt, const char *arg)
943cabdff1aSopenharmony_ci{
944cabdff1aSopenharmony_ci    const char *name;
945cabdff1aSopenharmony_ci    const uint8_t *rgb;
946cabdff1aSopenharmony_ci    int i;
947cabdff1aSopenharmony_ci
948cabdff1aSopenharmony_ci    printf("%-32s #RRGGBB\n", "name");
949cabdff1aSopenharmony_ci
950cabdff1aSopenharmony_ci    for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
951cabdff1aSopenharmony_ci        printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
952cabdff1aSopenharmony_ci
953cabdff1aSopenharmony_ci    return 0;
954cabdff1aSopenharmony_ci}
955cabdff1aSopenharmony_ci
956cabdff1aSopenharmony_ciint show_pix_fmts(void *optctx, const char *opt, const char *arg)
957cabdff1aSopenharmony_ci{
958cabdff1aSopenharmony_ci    const AVPixFmtDescriptor *pix_desc = NULL;
959cabdff1aSopenharmony_ci
960cabdff1aSopenharmony_ci    printf("Pixel formats:\n"
961cabdff1aSopenharmony_ci           "I.... = Supported Input  format for conversion\n"
962cabdff1aSopenharmony_ci           ".O... = Supported Output format for conversion\n"
963cabdff1aSopenharmony_ci           "..H.. = Hardware accelerated format\n"
964cabdff1aSopenharmony_ci           "...P. = Paletted format\n"
965cabdff1aSopenharmony_ci           "....B = Bitstream format\n"
966cabdff1aSopenharmony_ci           "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS\n"
967cabdff1aSopenharmony_ci           "-----\n");
968cabdff1aSopenharmony_ci
969cabdff1aSopenharmony_ci#if !CONFIG_SWSCALE
970cabdff1aSopenharmony_ci#   define sws_isSupportedInput(x)  0
971cabdff1aSopenharmony_ci#   define sws_isSupportedOutput(x) 0
972cabdff1aSopenharmony_ci#endif
973cabdff1aSopenharmony_ci
974cabdff1aSopenharmony_ci    while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
975cabdff1aSopenharmony_ci        enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
976cabdff1aSopenharmony_ci        printf("%c%c%c%c%c %-16s       %d            %3d      %d",
977cabdff1aSopenharmony_ci               sws_isSupportedInput (pix_fmt)              ? 'I' : '.',
978cabdff1aSopenharmony_ci               sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',
979cabdff1aSopenharmony_ci               pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',
980cabdff1aSopenharmony_ci               pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',
981cabdff1aSopenharmony_ci               pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
982cabdff1aSopenharmony_ci               pix_desc->name,
983cabdff1aSopenharmony_ci               pix_desc->nb_components,
984cabdff1aSopenharmony_ci               av_get_bits_per_pixel(pix_desc),
985cabdff1aSopenharmony_ci               pix_desc->comp[0].depth);
986cabdff1aSopenharmony_ci
987cabdff1aSopenharmony_ci        for (unsigned i = 1; i < pix_desc->nb_components; i++)
988cabdff1aSopenharmony_ci            printf("-%d", pix_desc->comp[i].depth);
989cabdff1aSopenharmony_ci        printf("\n");
990cabdff1aSopenharmony_ci    }
991cabdff1aSopenharmony_ci    return 0;
992cabdff1aSopenharmony_ci}
993cabdff1aSopenharmony_ci
994cabdff1aSopenharmony_ciint show_layouts(void *optctx, const char *opt, const char *arg)
995cabdff1aSopenharmony_ci{
996cabdff1aSopenharmony_ci    const AVChannelLayout *ch_layout;
997cabdff1aSopenharmony_ci    void *iter = NULL;
998cabdff1aSopenharmony_ci    char buf[128], buf2[128];
999cabdff1aSopenharmony_ci    int i = 0;
1000cabdff1aSopenharmony_ci
1001cabdff1aSopenharmony_ci    printf("Individual channels:\n"
1002cabdff1aSopenharmony_ci           "NAME           DESCRIPTION\n");
1003cabdff1aSopenharmony_ci    for (i = 0; i < 63; i++) {
1004cabdff1aSopenharmony_ci        av_channel_name(buf, sizeof(buf), i);
1005cabdff1aSopenharmony_ci        if (strstr(buf, "USR"))
1006cabdff1aSopenharmony_ci            continue;
1007cabdff1aSopenharmony_ci        av_channel_description(buf2, sizeof(buf2), i);
1008cabdff1aSopenharmony_ci        printf("%-14s %s\n", buf, buf2);
1009cabdff1aSopenharmony_ci    }
1010cabdff1aSopenharmony_ci    printf("\nStandard channel layouts:\n"
1011cabdff1aSopenharmony_ci           "NAME           DECOMPOSITION\n");
1012cabdff1aSopenharmony_ci    while (ch_layout = av_channel_layout_standard(&iter)) {
1013cabdff1aSopenharmony_ci            av_channel_layout_describe(ch_layout, buf, sizeof(buf));
1014cabdff1aSopenharmony_ci            printf("%-14s ", buf);
1015cabdff1aSopenharmony_ci            for (i = 0; i < 63; i++) {
1016cabdff1aSopenharmony_ci                int idx = av_channel_layout_index_from_channel(ch_layout, i);
1017cabdff1aSopenharmony_ci                if (idx >= 0) {
1018cabdff1aSopenharmony_ci                    av_channel_name(buf2, sizeof(buf2), i);
1019cabdff1aSopenharmony_ci                    printf("%s%s", idx ? "+" : "", buf2);
1020cabdff1aSopenharmony_ci                }
1021cabdff1aSopenharmony_ci            }
1022cabdff1aSopenharmony_ci            printf("\n");
1023cabdff1aSopenharmony_ci    }
1024cabdff1aSopenharmony_ci    return 0;
1025cabdff1aSopenharmony_ci}
1026cabdff1aSopenharmony_ci
1027cabdff1aSopenharmony_ciint show_sample_fmts(void *optctx, const char *opt, const char *arg)
1028cabdff1aSopenharmony_ci{
1029cabdff1aSopenharmony_ci    int i;
1030cabdff1aSopenharmony_ci    char fmt_str[128];
1031cabdff1aSopenharmony_ci    for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
1032cabdff1aSopenharmony_ci        printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
1033cabdff1aSopenharmony_ci    return 0;
1034cabdff1aSopenharmony_ci}
1035cabdff1aSopenharmony_ci
1036cabdff1aSopenharmony_ciint show_dispositions(void *optctx, const char *opt, const char *arg)
1037cabdff1aSopenharmony_ci{
1038cabdff1aSopenharmony_ci    for (int i = 0; i < 32; i++) {
1039cabdff1aSopenharmony_ci        const char *str = av_disposition_to_string(1U << i);
1040cabdff1aSopenharmony_ci        if (str)
1041cabdff1aSopenharmony_ci            printf("%s\n", str);
1042cabdff1aSopenharmony_ci    }
1043cabdff1aSopenharmony_ci    return 0;
1044cabdff1aSopenharmony_ci}
1045cabdff1aSopenharmony_ci
1046cabdff1aSopenharmony_ciint opt_cpuflags(void *optctx, const char *opt, const char *arg)
1047cabdff1aSopenharmony_ci{
1048cabdff1aSopenharmony_ci    int ret;
1049cabdff1aSopenharmony_ci    unsigned flags = av_get_cpu_flags();
1050cabdff1aSopenharmony_ci
1051cabdff1aSopenharmony_ci    if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
1052cabdff1aSopenharmony_ci        return ret;
1053cabdff1aSopenharmony_ci
1054cabdff1aSopenharmony_ci    av_force_cpu_flags(flags);
1055cabdff1aSopenharmony_ci    return 0;
1056cabdff1aSopenharmony_ci}
1057cabdff1aSopenharmony_ci
1058cabdff1aSopenharmony_ciint opt_cpucount(void *optctx, const char *opt, const char *arg)
1059cabdff1aSopenharmony_ci{
1060cabdff1aSopenharmony_ci    int ret;
1061cabdff1aSopenharmony_ci    int count;
1062cabdff1aSopenharmony_ci
1063cabdff1aSopenharmony_ci    static const AVOption opts[] = {
1064cabdff1aSopenharmony_ci        {"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX},
1065cabdff1aSopenharmony_ci        {NULL},
1066cabdff1aSopenharmony_ci    };
1067cabdff1aSopenharmony_ci    static const AVClass class = {
1068cabdff1aSopenharmony_ci        .class_name = "cpucount",
1069cabdff1aSopenharmony_ci        .item_name  = av_default_item_name,
1070cabdff1aSopenharmony_ci        .option     = opts,
1071cabdff1aSopenharmony_ci        .version    = LIBAVUTIL_VERSION_INT,
1072cabdff1aSopenharmony_ci    };
1073cabdff1aSopenharmony_ci    const AVClass *pclass = &class;
1074cabdff1aSopenharmony_ci
1075cabdff1aSopenharmony_ci    ret = av_opt_eval_int(&pclass, opts, arg, &count);
1076cabdff1aSopenharmony_ci
1077cabdff1aSopenharmony_ci    if (!ret) {
1078cabdff1aSopenharmony_ci        av_cpu_force_count(count);
1079cabdff1aSopenharmony_ci    }
1080cabdff1aSopenharmony_ci
1081cabdff1aSopenharmony_ci    return ret;
1082cabdff1aSopenharmony_ci}
1083cabdff1aSopenharmony_ci
1084cabdff1aSopenharmony_cistatic void expand_filename_template(AVBPrint *bp, const char *template,
1085cabdff1aSopenharmony_ci                                     struct tm *tm)
1086cabdff1aSopenharmony_ci{
1087cabdff1aSopenharmony_ci    int c;
1088cabdff1aSopenharmony_ci
1089cabdff1aSopenharmony_ci    while ((c = *(template++))) {
1090cabdff1aSopenharmony_ci        if (c == '%') {
1091cabdff1aSopenharmony_ci            if (!(c = *(template++)))
1092cabdff1aSopenharmony_ci                break;
1093cabdff1aSopenharmony_ci            switch (c) {
1094cabdff1aSopenharmony_ci            case 'p':
1095cabdff1aSopenharmony_ci                av_bprintf(bp, "%s", program_name);
1096cabdff1aSopenharmony_ci                break;
1097cabdff1aSopenharmony_ci            case 't':
1098cabdff1aSopenharmony_ci                av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
1099cabdff1aSopenharmony_ci                           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1100cabdff1aSopenharmony_ci                           tm->tm_hour, tm->tm_min, tm->tm_sec);
1101cabdff1aSopenharmony_ci                break;
1102cabdff1aSopenharmony_ci            case '%':
1103cabdff1aSopenharmony_ci                av_bprint_chars(bp, c, 1);
1104cabdff1aSopenharmony_ci                break;
1105cabdff1aSopenharmony_ci            }
1106cabdff1aSopenharmony_ci        } else {
1107cabdff1aSopenharmony_ci            av_bprint_chars(bp, c, 1);
1108cabdff1aSopenharmony_ci        }
1109cabdff1aSopenharmony_ci    }
1110cabdff1aSopenharmony_ci}
1111cabdff1aSopenharmony_ci
1112cabdff1aSopenharmony_cistatic void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
1113cabdff1aSopenharmony_ci{
1114cabdff1aSopenharmony_ci    va_list vl2;
1115cabdff1aSopenharmony_ci    char line[1024];
1116cabdff1aSopenharmony_ci    static int print_prefix = 1;
1117cabdff1aSopenharmony_ci
1118cabdff1aSopenharmony_ci    va_copy(vl2, vl);
1119cabdff1aSopenharmony_ci    av_log_default_callback(ptr, level, fmt, vl);
1120cabdff1aSopenharmony_ci    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
1121cabdff1aSopenharmony_ci    va_end(vl2);
1122cabdff1aSopenharmony_ci    if (report_file_level >= level) {
1123cabdff1aSopenharmony_ci        fputs(line, report_file);
1124cabdff1aSopenharmony_ci        fflush(report_file);
1125cabdff1aSopenharmony_ci    }
1126cabdff1aSopenharmony_ci}
1127cabdff1aSopenharmony_ci
1128cabdff1aSopenharmony_ciint init_report(const char *env, FILE **file)
1129cabdff1aSopenharmony_ci{
1130cabdff1aSopenharmony_ci    char *filename_template = NULL;
1131cabdff1aSopenharmony_ci    char *key, *val;
1132cabdff1aSopenharmony_ci    int ret, count = 0;
1133cabdff1aSopenharmony_ci    int prog_loglevel, envlevel = 0;
1134cabdff1aSopenharmony_ci    time_t now;
1135cabdff1aSopenharmony_ci    struct tm *tm;
1136cabdff1aSopenharmony_ci    AVBPrint filename;
1137cabdff1aSopenharmony_ci
1138cabdff1aSopenharmony_ci    if (report_file) /* already opened */
1139cabdff1aSopenharmony_ci        return 0;
1140cabdff1aSopenharmony_ci    time(&now);
1141cabdff1aSopenharmony_ci    tm = localtime(&now);
1142cabdff1aSopenharmony_ci
1143cabdff1aSopenharmony_ci    while (env && *env) {
1144cabdff1aSopenharmony_ci        if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
1145cabdff1aSopenharmony_ci            if (count)
1146cabdff1aSopenharmony_ci                av_log(NULL, AV_LOG_ERROR,
1147cabdff1aSopenharmony_ci                       "Failed to parse FFREPORT environment variable: %s\n",
1148cabdff1aSopenharmony_ci                       av_err2str(ret));
1149cabdff1aSopenharmony_ci            break;
1150cabdff1aSopenharmony_ci        }
1151cabdff1aSopenharmony_ci        if (*env)
1152cabdff1aSopenharmony_ci            env++;
1153cabdff1aSopenharmony_ci        count++;
1154cabdff1aSopenharmony_ci        if (!strcmp(key, "file")) {
1155cabdff1aSopenharmony_ci            av_free(filename_template);
1156cabdff1aSopenharmony_ci            filename_template = val;
1157cabdff1aSopenharmony_ci            val = NULL;
1158cabdff1aSopenharmony_ci        } else if (!strcmp(key, "level")) {
1159cabdff1aSopenharmony_ci            char *tail;
1160cabdff1aSopenharmony_ci            report_file_level = strtol(val, &tail, 10);
1161cabdff1aSopenharmony_ci            if (*tail) {
1162cabdff1aSopenharmony_ci                av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
1163cabdff1aSopenharmony_ci                exit_program(1);
1164cabdff1aSopenharmony_ci            }
1165cabdff1aSopenharmony_ci            envlevel = 1;
1166cabdff1aSopenharmony_ci        } else {
1167cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
1168cabdff1aSopenharmony_ci        }
1169cabdff1aSopenharmony_ci        av_free(val);
1170cabdff1aSopenharmony_ci        av_free(key);
1171cabdff1aSopenharmony_ci    }
1172cabdff1aSopenharmony_ci
1173cabdff1aSopenharmony_ci    av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
1174cabdff1aSopenharmony_ci    expand_filename_template(&filename,
1175cabdff1aSopenharmony_ci                             av_x_if_null(filename_template, "%p-%t.log"), tm);
1176cabdff1aSopenharmony_ci    av_free(filename_template);
1177cabdff1aSopenharmony_ci    if (!av_bprint_is_complete(&filename)) {
1178cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
1179cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
1180cabdff1aSopenharmony_ci    }
1181cabdff1aSopenharmony_ci
1182cabdff1aSopenharmony_ci    prog_loglevel = av_log_get_level();
1183cabdff1aSopenharmony_ci    if (!envlevel)
1184cabdff1aSopenharmony_ci        report_file_level = FFMAX(report_file_level, prog_loglevel);
1185cabdff1aSopenharmony_ci
1186cabdff1aSopenharmony_ci    report_file = fopen(filename.str, "w");
1187cabdff1aSopenharmony_ci    if (!report_file) {
1188cabdff1aSopenharmony_ci        int ret = AVERROR(errno);
1189cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
1190cabdff1aSopenharmony_ci               filename.str, strerror(errno));
1191cabdff1aSopenharmony_ci        return ret;
1192cabdff1aSopenharmony_ci    }
1193cabdff1aSopenharmony_ci    av_log_set_callback(log_callback_report);
1194cabdff1aSopenharmony_ci    av_log(NULL, AV_LOG_INFO,
1195cabdff1aSopenharmony_ci           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
1196cabdff1aSopenharmony_ci           "Report written to \"%s\"\n"
1197cabdff1aSopenharmony_ci           "Log level: %d\n",
1198cabdff1aSopenharmony_ci           program_name,
1199cabdff1aSopenharmony_ci           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1200cabdff1aSopenharmony_ci           tm->tm_hour, tm->tm_min, tm->tm_sec,
1201cabdff1aSopenharmony_ci           filename.str, report_file_level);
1202cabdff1aSopenharmony_ci    av_bprint_finalize(&filename, NULL);
1203cabdff1aSopenharmony_ci
1204cabdff1aSopenharmony_ci    if (file)
1205cabdff1aSopenharmony_ci        *file = report_file;
1206cabdff1aSopenharmony_ci
1207cabdff1aSopenharmony_ci    return 0;
1208cabdff1aSopenharmony_ci}
1209cabdff1aSopenharmony_ci
1210cabdff1aSopenharmony_ciint opt_report(void *optctx, const char *opt, const char *arg)
1211cabdff1aSopenharmony_ci{
1212cabdff1aSopenharmony_ci    return init_report(NULL, NULL);
1213cabdff1aSopenharmony_ci}
1214cabdff1aSopenharmony_ci
1215cabdff1aSopenharmony_ciint opt_max_alloc(void *optctx, const char *opt, const char *arg)
1216cabdff1aSopenharmony_ci{
1217cabdff1aSopenharmony_ci    char *tail;
1218cabdff1aSopenharmony_ci    size_t max;
1219cabdff1aSopenharmony_ci
1220cabdff1aSopenharmony_ci    max = strtol(arg, &tail, 10);
1221cabdff1aSopenharmony_ci    if (*tail) {
1222cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
1223cabdff1aSopenharmony_ci        exit_program(1);
1224cabdff1aSopenharmony_ci    }
1225cabdff1aSopenharmony_ci    av_max_alloc(max);
1226cabdff1aSopenharmony_ci    return 0;
1227cabdff1aSopenharmony_ci}
1228cabdff1aSopenharmony_ci
1229cabdff1aSopenharmony_ciint opt_loglevel(void *optctx, const char *opt, const char *arg)
1230cabdff1aSopenharmony_ci{
1231cabdff1aSopenharmony_ci    const struct { const char *name; int level; } log_levels[] = {
1232cabdff1aSopenharmony_ci        { "quiet"  , AV_LOG_QUIET   },
1233cabdff1aSopenharmony_ci        { "panic"  , AV_LOG_PANIC   },
1234cabdff1aSopenharmony_ci        { "fatal"  , AV_LOG_FATAL   },
1235cabdff1aSopenharmony_ci        { "error"  , AV_LOG_ERROR   },
1236cabdff1aSopenharmony_ci        { "warning", AV_LOG_WARNING },
1237cabdff1aSopenharmony_ci        { "info"   , AV_LOG_INFO    },
1238cabdff1aSopenharmony_ci        { "verbose", AV_LOG_VERBOSE },
1239cabdff1aSopenharmony_ci        { "debug"  , AV_LOG_DEBUG   },
1240cabdff1aSopenharmony_ci        { "trace"  , AV_LOG_TRACE   },
1241cabdff1aSopenharmony_ci    };
1242cabdff1aSopenharmony_ci    const char *token;
1243cabdff1aSopenharmony_ci    char *tail;
1244cabdff1aSopenharmony_ci    int flags = av_log_get_flags();
1245cabdff1aSopenharmony_ci    int level = av_log_get_level();
1246cabdff1aSopenharmony_ci    int cmd, i = 0;
1247cabdff1aSopenharmony_ci
1248cabdff1aSopenharmony_ci    av_assert0(arg);
1249cabdff1aSopenharmony_ci    while (*arg) {
1250cabdff1aSopenharmony_ci        token = arg;
1251cabdff1aSopenharmony_ci        if (*token == '+' || *token == '-') {
1252cabdff1aSopenharmony_ci            cmd = *token++;
1253cabdff1aSopenharmony_ci        } else {
1254cabdff1aSopenharmony_ci            cmd = 0;
1255cabdff1aSopenharmony_ci        }
1256cabdff1aSopenharmony_ci        if (!i && !cmd) {
1257cabdff1aSopenharmony_ci            flags = 0;  /* missing relative prefix, build absolute value */
1258cabdff1aSopenharmony_ci        }
1259cabdff1aSopenharmony_ci        if (av_strstart(token, "repeat", &arg)) {
1260cabdff1aSopenharmony_ci            if (cmd == '-') {
1261cabdff1aSopenharmony_ci                flags |= AV_LOG_SKIP_REPEATED;
1262cabdff1aSopenharmony_ci            } else {
1263cabdff1aSopenharmony_ci                flags &= ~AV_LOG_SKIP_REPEATED;
1264cabdff1aSopenharmony_ci            }
1265cabdff1aSopenharmony_ci        } else if (av_strstart(token, "level", &arg)) {
1266cabdff1aSopenharmony_ci            if (cmd == '-') {
1267cabdff1aSopenharmony_ci                flags &= ~AV_LOG_PRINT_LEVEL;
1268cabdff1aSopenharmony_ci            } else {
1269cabdff1aSopenharmony_ci                flags |= AV_LOG_PRINT_LEVEL;
1270cabdff1aSopenharmony_ci            }
1271cabdff1aSopenharmony_ci        } else {
1272cabdff1aSopenharmony_ci            break;
1273cabdff1aSopenharmony_ci        }
1274cabdff1aSopenharmony_ci        i++;
1275cabdff1aSopenharmony_ci    }
1276cabdff1aSopenharmony_ci    if (!*arg) {
1277cabdff1aSopenharmony_ci        goto end;
1278cabdff1aSopenharmony_ci    } else if (*arg == '+') {
1279cabdff1aSopenharmony_ci        arg++;
1280cabdff1aSopenharmony_ci    } else if (!i) {
1281cabdff1aSopenharmony_ci        flags = av_log_get_flags();  /* level value without prefix, reset flags */
1282cabdff1aSopenharmony_ci    }
1283cabdff1aSopenharmony_ci
1284cabdff1aSopenharmony_ci    for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
1285cabdff1aSopenharmony_ci        if (!strcmp(log_levels[i].name, arg)) {
1286cabdff1aSopenharmony_ci            level = log_levels[i].level;
1287cabdff1aSopenharmony_ci            goto end;
1288cabdff1aSopenharmony_ci        }
1289cabdff1aSopenharmony_ci    }
1290cabdff1aSopenharmony_ci
1291cabdff1aSopenharmony_ci    level = strtol(arg, &tail, 10);
1292cabdff1aSopenharmony_ci    if (*tail) {
1293cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
1294cabdff1aSopenharmony_ci               "Possible levels are numbers or:\n", arg);
1295cabdff1aSopenharmony_ci        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
1296cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
1297cabdff1aSopenharmony_ci        exit_program(1);
1298cabdff1aSopenharmony_ci    }
1299cabdff1aSopenharmony_ci
1300cabdff1aSopenharmony_ciend:
1301cabdff1aSopenharmony_ci    av_log_set_flags(flags);
1302cabdff1aSopenharmony_ci    av_log_set_level(level);
1303cabdff1aSopenharmony_ci    return 0;
1304cabdff1aSopenharmony_ci}
1305cabdff1aSopenharmony_ci
1306cabdff1aSopenharmony_ci#if CONFIG_AVDEVICE
1307cabdff1aSopenharmony_cistatic void print_device_list(const AVDeviceInfoList *device_list)
1308cabdff1aSopenharmony_ci{
1309cabdff1aSopenharmony_ci    // print devices
1310cabdff1aSopenharmony_ci    for (int i = 0; i < device_list->nb_devices; i++) {
1311cabdff1aSopenharmony_ci        const AVDeviceInfo *device = device_list->devices[i];
1312cabdff1aSopenharmony_ci        printf("%c %s [%s] (", device_list->default_device == i ? '*' : ' ',
1313cabdff1aSopenharmony_ci            device->device_name, device->device_description);
1314cabdff1aSopenharmony_ci        if (device->nb_media_types > 0) {
1315cabdff1aSopenharmony_ci            for (int j = 0; j < device->nb_media_types; ++j) {
1316cabdff1aSopenharmony_ci                const char* media_type = av_get_media_type_string(device->media_types[j]);
1317cabdff1aSopenharmony_ci                if (j > 0)
1318cabdff1aSopenharmony_ci                    printf(", ");
1319cabdff1aSopenharmony_ci                printf("%s", media_type ? media_type : "unknown");
1320cabdff1aSopenharmony_ci            }
1321cabdff1aSopenharmony_ci        } else {
1322cabdff1aSopenharmony_ci            printf("none");
1323cabdff1aSopenharmony_ci        }
1324cabdff1aSopenharmony_ci        printf(")\n");
1325cabdff1aSopenharmony_ci    }
1326cabdff1aSopenharmony_ci}
1327cabdff1aSopenharmony_ci
1328cabdff1aSopenharmony_cistatic int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
1329cabdff1aSopenharmony_ci{
1330cabdff1aSopenharmony_ci    int ret;
1331cabdff1aSopenharmony_ci    AVDeviceInfoList *device_list = NULL;
1332cabdff1aSopenharmony_ci
1333cabdff1aSopenharmony_ci    if (!fmt || !fmt->priv_class  || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
1334cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
1335cabdff1aSopenharmony_ci
1336cabdff1aSopenharmony_ci    printf("Auto-detected sources for %s:\n", fmt->name);
1337cabdff1aSopenharmony_ci    if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
1338cabdff1aSopenharmony_ci        printf("Cannot list sources: %s\n", av_err2str(ret));
1339cabdff1aSopenharmony_ci        goto fail;
1340cabdff1aSopenharmony_ci    }
1341cabdff1aSopenharmony_ci
1342cabdff1aSopenharmony_ci    print_device_list(device_list);
1343cabdff1aSopenharmony_ci
1344cabdff1aSopenharmony_ci  fail:
1345cabdff1aSopenharmony_ci    avdevice_free_list_devices(&device_list);
1346cabdff1aSopenharmony_ci    return ret;
1347cabdff1aSopenharmony_ci}
1348cabdff1aSopenharmony_ci
1349cabdff1aSopenharmony_cistatic int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
1350cabdff1aSopenharmony_ci{
1351cabdff1aSopenharmony_ci    int ret;
1352cabdff1aSopenharmony_ci    AVDeviceInfoList *device_list = NULL;
1353cabdff1aSopenharmony_ci
1354cabdff1aSopenharmony_ci    if (!fmt || !fmt->priv_class  || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
1355cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
1356cabdff1aSopenharmony_ci
1357cabdff1aSopenharmony_ci    printf("Auto-detected sinks for %s:\n", fmt->name);
1358cabdff1aSopenharmony_ci    if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
1359cabdff1aSopenharmony_ci        printf("Cannot list sinks: %s\n", av_err2str(ret));
1360cabdff1aSopenharmony_ci        goto fail;
1361cabdff1aSopenharmony_ci    }
1362cabdff1aSopenharmony_ci
1363cabdff1aSopenharmony_ci    print_device_list(device_list);
1364cabdff1aSopenharmony_ci
1365cabdff1aSopenharmony_ci  fail:
1366cabdff1aSopenharmony_ci    avdevice_free_list_devices(&device_list);
1367cabdff1aSopenharmony_ci    return ret;
1368cabdff1aSopenharmony_ci}
1369cabdff1aSopenharmony_ci
1370cabdff1aSopenharmony_cistatic int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
1371cabdff1aSopenharmony_ci{
1372cabdff1aSopenharmony_ci    int ret;
1373cabdff1aSopenharmony_ci    if (arg) {
1374cabdff1aSopenharmony_ci        char *opts_str = NULL;
1375cabdff1aSopenharmony_ci        av_assert0(dev && opts);
1376cabdff1aSopenharmony_ci        *dev = av_strdup(arg);
1377cabdff1aSopenharmony_ci        if (!*dev)
1378cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
1379cabdff1aSopenharmony_ci        if ((opts_str = strchr(*dev, ','))) {
1380cabdff1aSopenharmony_ci            *(opts_str++) = '\0';
1381cabdff1aSopenharmony_ci            if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
1382cabdff1aSopenharmony_ci                av_freep(dev);
1383cabdff1aSopenharmony_ci                return ret;
1384cabdff1aSopenharmony_ci            }
1385cabdff1aSopenharmony_ci        }
1386cabdff1aSopenharmony_ci    } else
1387cabdff1aSopenharmony_ci        printf("\nDevice name is not provided.\n"
1388cabdff1aSopenharmony_ci                "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
1389cabdff1aSopenharmony_ci    return 0;
1390cabdff1aSopenharmony_ci}
1391cabdff1aSopenharmony_ci
1392cabdff1aSopenharmony_ciint show_sources(void *optctx, const char *opt, const char *arg)
1393cabdff1aSopenharmony_ci{
1394cabdff1aSopenharmony_ci    const AVInputFormat *fmt = NULL;
1395cabdff1aSopenharmony_ci    char *dev = NULL;
1396cabdff1aSopenharmony_ci    AVDictionary *opts = NULL;
1397cabdff1aSopenharmony_ci    int ret = 0;
1398cabdff1aSopenharmony_ci    int error_level = av_log_get_level();
1399cabdff1aSopenharmony_ci
1400cabdff1aSopenharmony_ci    av_log_set_level(AV_LOG_WARNING);
1401cabdff1aSopenharmony_ci
1402cabdff1aSopenharmony_ci    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
1403cabdff1aSopenharmony_ci        goto fail;
1404cabdff1aSopenharmony_ci
1405cabdff1aSopenharmony_ci    do {
1406cabdff1aSopenharmony_ci        fmt = av_input_audio_device_next(fmt);
1407cabdff1aSopenharmony_ci        if (fmt) {
1408cabdff1aSopenharmony_ci            if (!strcmp(fmt->name, "lavfi"))
1409cabdff1aSopenharmony_ci                continue; //it's pointless to probe lavfi
1410cabdff1aSopenharmony_ci            if (dev && !av_match_name(dev, fmt->name))
1411cabdff1aSopenharmony_ci                continue;
1412cabdff1aSopenharmony_ci            print_device_sources(fmt, opts);
1413cabdff1aSopenharmony_ci        }
1414cabdff1aSopenharmony_ci    } while (fmt);
1415cabdff1aSopenharmony_ci    do {
1416cabdff1aSopenharmony_ci        fmt = av_input_video_device_next(fmt);
1417cabdff1aSopenharmony_ci        if (fmt) {
1418cabdff1aSopenharmony_ci            if (dev && !av_match_name(dev, fmt->name))
1419cabdff1aSopenharmony_ci                continue;
1420cabdff1aSopenharmony_ci            print_device_sources(fmt, opts);
1421cabdff1aSopenharmony_ci        }
1422cabdff1aSopenharmony_ci    } while (fmt);
1423cabdff1aSopenharmony_ci  fail:
1424cabdff1aSopenharmony_ci    av_dict_free(&opts);
1425cabdff1aSopenharmony_ci    av_free(dev);
1426cabdff1aSopenharmony_ci    av_log_set_level(error_level);
1427cabdff1aSopenharmony_ci    return ret;
1428cabdff1aSopenharmony_ci}
1429cabdff1aSopenharmony_ci
1430cabdff1aSopenharmony_ciint show_sinks(void *optctx, const char *opt, const char *arg)
1431cabdff1aSopenharmony_ci{
1432cabdff1aSopenharmony_ci    const AVOutputFormat *fmt = NULL;
1433cabdff1aSopenharmony_ci    char *dev = NULL;
1434cabdff1aSopenharmony_ci    AVDictionary *opts = NULL;
1435cabdff1aSopenharmony_ci    int ret = 0;
1436cabdff1aSopenharmony_ci    int error_level = av_log_get_level();
1437cabdff1aSopenharmony_ci
1438cabdff1aSopenharmony_ci    av_log_set_level(AV_LOG_WARNING);
1439cabdff1aSopenharmony_ci
1440cabdff1aSopenharmony_ci    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
1441cabdff1aSopenharmony_ci        goto fail;
1442cabdff1aSopenharmony_ci
1443cabdff1aSopenharmony_ci    do {
1444cabdff1aSopenharmony_ci        fmt = av_output_audio_device_next(fmt);
1445cabdff1aSopenharmony_ci        if (fmt) {
1446cabdff1aSopenharmony_ci            if (dev && !av_match_name(dev, fmt->name))
1447cabdff1aSopenharmony_ci                continue;
1448cabdff1aSopenharmony_ci            print_device_sinks(fmt, opts);
1449cabdff1aSopenharmony_ci        }
1450cabdff1aSopenharmony_ci    } while (fmt);
1451cabdff1aSopenharmony_ci    do {
1452cabdff1aSopenharmony_ci        fmt = av_output_video_device_next(fmt);
1453cabdff1aSopenharmony_ci        if (fmt) {
1454cabdff1aSopenharmony_ci            if (dev && !av_match_name(dev, fmt->name))
1455cabdff1aSopenharmony_ci                continue;
1456cabdff1aSopenharmony_ci            print_device_sinks(fmt, opts);
1457cabdff1aSopenharmony_ci        }
1458cabdff1aSopenharmony_ci    } while (fmt);
1459cabdff1aSopenharmony_ci  fail:
1460cabdff1aSopenharmony_ci    av_dict_free(&opts);
1461cabdff1aSopenharmony_ci    av_free(dev);
1462cabdff1aSopenharmony_ci    av_log_set_level(error_level);
1463cabdff1aSopenharmony_ci    return ret;
1464cabdff1aSopenharmony_ci}
1465cabdff1aSopenharmony_ci#endif /* CONFIG_AVDEVICE */
1466