mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
avplay: Allow to override the codec
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
parent
6fa464f8d2
commit
eef9f06508
61
avplay.c
61
avplay.c
@ -222,6 +222,9 @@ typedef struct PlayerState {
|
|||||||
float skip_frames;
|
float skip_frames;
|
||||||
float skip_frames_index;
|
float skip_frames_index;
|
||||||
int refresh;
|
int refresh;
|
||||||
|
|
||||||
|
SpecifierOpt *codec_names;
|
||||||
|
int nb_codec_names;
|
||||||
} PlayerState;
|
} PlayerState;
|
||||||
|
|
||||||
/* options specified by the user */
|
/* options specified by the user */
|
||||||
@ -2044,6 +2047,52 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type)
|
||||||
|
{
|
||||||
|
const AVCodecDescriptor *desc;
|
||||||
|
AVCodec *codec = avcodec_find_decoder_by_name(name);
|
||||||
|
|
||||||
|
if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
|
||||||
|
codec = avcodec_find_decoder(desc->id);
|
||||||
|
if (codec)
|
||||||
|
av_log(NULL, AV_LOG_VERBOSE, "Matched decoder '%s' for codec '%s'.\n",
|
||||||
|
codec->name, desc->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!codec) {
|
||||||
|
av_log(NULL, AV_LOG_FATAL, "Unknown decoder '%s'\n", name);
|
||||||
|
exit_program(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec->type != type) {
|
||||||
|
av_log(NULL, AV_LOG_FATAL, "Invalid decoder type '%s'\n", name);
|
||||||
|
exit_program(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AVCodec *choose_decoder(PlayerState *is, AVFormatContext *ic, AVStream *st)
|
||||||
|
{
|
||||||
|
char *codec_name = NULL;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
for (i = 0; i < is->nb_codec_names; i++) {
|
||||||
|
char *spec = is->codec_names[i].specifier;
|
||||||
|
if ((ret = check_stream_specifier(ic, st, spec)) > 0)
|
||||||
|
codec_name = is->codec_names[i].u.str;
|
||||||
|
else if (ret < 0)
|
||||||
|
exit_program(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec_name) {
|
||||||
|
AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type);
|
||||||
|
st->codec->codec_id = codec->id;
|
||||||
|
return codec;
|
||||||
|
} else
|
||||||
|
return avcodec_find_decoder(st->codec->codec_id);
|
||||||
|
}
|
||||||
|
|
||||||
/* open a given stream. Return 0 if OK */
|
/* open a given stream. Return 0 if OK */
|
||||||
static int stream_component_open(PlayerState *is, int stream_index)
|
static int stream_component_open(PlayerState *is, int stream_index)
|
||||||
{
|
{
|
||||||
@ -2061,7 +2110,7 @@ static int stream_component_open(PlayerState *is, int stream_index)
|
|||||||
|
|
||||||
opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], NULL);
|
opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], NULL);
|
||||||
|
|
||||||
codec = avcodec_find_decoder(avctx->codec_id);
|
codec = choose_decoder(is, ic, ic->streams[stream_index]);
|
||||||
avctx->workaround_bugs = workaround_bugs;
|
avctx->workaround_bugs = workaround_bugs;
|
||||||
avctx->idct_algo = idct;
|
avctx->idct_algo = idct;
|
||||||
avctx->skip_frame = skip_frame;
|
avctx->skip_frame = skip_frame;
|
||||||
@ -2302,6 +2351,7 @@ static int stream_setup(PlayerState *is)
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
|
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
|
||||||
ret = AVERROR_OPTION_NOT_FOUND;
|
ret = AVERROR_OPTION_NOT_FOUND;
|
||||||
@ -2315,6 +2365,9 @@ static int stream_setup(PlayerState *is)
|
|||||||
opts = setup_find_stream_info_opts(ic, codec_opts);
|
opts = setup_find_stream_info_opts(ic, codec_opts);
|
||||||
orig_nb_streams = ic->nb_streams;
|
orig_nb_streams = ic->nb_streams;
|
||||||
|
|
||||||
|
for (i = 0; i < ic->nb_streams; i++)
|
||||||
|
ic->streams[i]->codec->codec = choose_decoder(is, ic, ic->streams[i]);
|
||||||
|
|
||||||
err = avformat_find_stream_info(ic, opts);
|
err = avformat_find_stream_info(ic, opts);
|
||||||
|
|
||||||
for (i = 0; i < orig_nb_streams; i++)
|
for (i = 0; i < orig_nb_streams; i++)
|
||||||
@ -2904,6 +2957,7 @@ static int opt_duration(void *optctx, const char *opt, const char *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OFF(x) offsetof(PlayerState, x)
|
||||||
static const OptionDef options[] = {
|
static const OptionDef options[] = {
|
||||||
#include "cmdutils_common_opts.h"
|
#include "cmdutils_common_opts.h"
|
||||||
{ "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
|
{ "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
|
||||||
@ -2946,6 +3000,9 @@ static const OptionDef options[] = {
|
|||||||
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { opt_default }, "generic catch all option", "" },
|
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { opt_default }, "generic catch all option", "" },
|
||||||
{ "i", 0, { NULL }, "avconv compatibility dummy option", ""},
|
{ "i", 0, { NULL }, "avconv compatibility dummy option", ""},
|
||||||
{ "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
|
{ "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
|
||||||
|
{ "c", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFF(codec_names) }, "codec name", "codec" },
|
||||||
|
{ "codec", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFF(codec_names) }, "codec name", "codec" },
|
||||||
|
|
||||||
{ NULL, },
|
{ NULL, },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3018,7 +3075,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
show_banner();
|
show_banner();
|
||||||
|
|
||||||
parse_options(NULL, argc, argv, options, opt_input_file);
|
parse_options(player, argc, argv, options, opt_input_file);
|
||||||
|
|
||||||
if (!input_filename) {
|
if (!input_filename) {
|
||||||
show_usage();
|
show_usage();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user