diff options
author | wm4 <wm4@nowhere> | 2020-09-03 14:13:17 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-09-03 14:13:17 +0200 |
commit | 80bf6b26ba800b0bf65b40123940481e4e9911b7 (patch) | |
tree | 65106662d790ffd7b8c6b3f4562e9063c7913506 /common | |
parent | 2761f37fe48aa5b3aae3c4d4ce611a6ef07db0ae (diff) | |
download | mpv-80bf6b26ba800b0bf65b40123940481e4e9911b7.tar.bz2 mpv-80bf6b26ba800b0bf65b40123940481e4e9911b7.tar.xz |
encode: disable unsupported media types automatically
If you encode to e.g. an audio-only format, then video is disabled
automatically. This also takes care of the very cryptic error message.
It says "[vo/lavc] codec for video not found". Sort of true, but
obscures the real problem if it's e.g. an audio-only format.
Diffstat (limited to 'common')
-rw-r--r-- | common/encode.h | 2 | ||||
-rw-r--r-- | common/encode_lavc.c | 63 |
2 files changed, 47 insertions, 18 deletions
diff --git a/common/encode.h b/common/encode.h index 974651e103..c951e95d51 100644 --- a/common/encode.h +++ b/common/encode.h @@ -54,6 +54,8 @@ bool encode_lavc_free(struct encode_lavc_context *ctx); void encode_lavc_discontinuity(struct encode_lavc_context *ctx); bool encode_lavc_showhelp(struct mp_log *log, struct encode_opts *options); int encode_lavc_getstatus(struct encode_lavc_context *ctx, char *buf, int bufsize, float relative_position); +bool encode_lavc_stream_type_ok(struct encode_lavc_context *ctx, + enum stream_type type); void encode_lavc_expect_stream(struct encode_lavc_context *ctx, enum stream_type type); void encode_lavc_set_metadata(struct encode_lavc_context *ctx, diff --git a/common/encode_lavc.c b/common/encode_lavc.c index 410b909f94..2af93d239f 100644 --- a/common/encode_lavc.c +++ b/common/encode_lavc.c @@ -735,6 +735,47 @@ static void encoder_destroy(void *ptr) free_stream(p->twopass_bytebuffer); } +static AVCodec *find_codec_for(struct encode_lavc_context *ctx, + enum stream_type type, bool *used_auto) +{ + char *codec_name = type == STREAM_VIDEO + ? ctx->options->vcodec + : ctx->options->acodec; + enum AVMediaType codec_type = mp_to_av_stream_type(type); + const char *tname = stream_type_name(type); + + *used_auto = !(codec_name && codec_name[0]); + + AVCodec *codec; + if (*used_auto) { + codec = avcodec_find_encoder(av_guess_codec(ctx->oformat, NULL, + ctx->options->file, NULL, + codec_type)); + } else { + codec = avcodec_find_encoder_by_name(codec_name); + if (!codec) + MP_FATAL(ctx, "codec '%s' not found.\n", codec_name); + } + + if (codec && codec->type != codec_type) { + MP_FATAL(ctx, "codec for %s has wrong media type\n", tname); + codec = NULL; + } + + return codec; +} + +// Return whether the stream type is "supposed" to work. +bool encode_lavc_stream_type_ok(struct encode_lavc_context *ctx, + enum stream_type type) +{ + // If a codec was forced, let it proceed to actual encoding, and then error + // if it doesn't work. (Worried that av_guess_codec() may return NULL for + // some formats where a specific codec works anyway.) + bool auto_codec; + return !!find_codec_for(ctx, type, &auto_codec) || !auto_codec; +} + struct encoder_context *encoder_context_alloc(struct encode_lavc_context *ctx, enum stream_type type, struct mp_log *log) @@ -755,27 +796,13 @@ struct encoder_context *encoder_context_alloc(struct encode_lavc_context *ctx, .encode_lavc_ctx = ctx, }; - char *codec_name = type == STREAM_VIDEO - ? p->options->vcodec - : p->options->acodec; - enum AVMediaType codec_type = mp_to_av_stream_type(type); + bool auto_codec; + AVCodec *codec = find_codec_for(ctx, type, &auto_codec); const char *tname = stream_type_name(type); - AVCodec *codec; - if (codec_name&& codec_name[0]) { - codec = avcodec_find_encoder_by_name(codec_name); - } else { - codec = avcodec_find_encoder(av_guess_codec(p->oformat, NULL, - p->options->file, NULL, - codec_type)); - } - if (!codec) { - MP_FATAL(p, "codec for %s not found\n", tname); - goto fail; - } - if (codec->type != codec_type) { - MP_FATAL(p, "codec for %s has wrong media type\n", tname); + if (auto_codec) + MP_FATAL(p, "codec for %s not found\n", tname); goto fail; } |