diff --git a/DOCS/man/en/encode.rst b/DOCS/man/en/encode.rst index 20b4d35487..93b1b84f28 100644 --- a/DOCS/man/en/encode.rst +++ b/DOCS/man/en/encode.rst @@ -10,8 +10,8 @@ You can encode files from one format/codec to another using this facility. --of= Specifies the output format (overrides autodetection by the extension of - the file specified by -o). - See --of=help for a full list of supported formats. + the file specified by -o). This can be a comma separated list of possible + formats to try. See --of=help for a full list of supported formats. --ofopts= Specifies the output format options for libavformat. diff --git a/encode_lavc.c b/encode_lavc.c index d3f8f9761c..e38ca5bca8 100644 --- a/encode_lavc.c +++ b/encode_lavc.c @@ -30,83 +30,62 @@ #include "talloc.h" #include "stream/stream.h" -static int set_to_avdictionary(void *ctx, AVDictionary **dictp, void *octx, - const char *str, const char *key_val_sep, - const char *pairs_sep) +static int set_to_avdictionary(AVDictionary **dictp, const char *key, + const char *val) { - int good = 0; - int errorcode = 0; - const AVOption *o; + char keybuf[1024]; + char valuebuf[1024]; - while (*str) { - char *key_ = av_get_token(&str, key_val_sep); - char *val_; - char *key, *val; - char valuebuf[1024]; - - if (*key_ && strspn(str, key_val_sep)) { - str++; - val_ = av_get_token(&str, pairs_sep); - } else { - av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value " - "separator found after key '%s'\n", key_); - av_free(key_); - if (!errorcode) - errorcode = AVERROR(EINVAL); - if (*str) - ++str; - continue; + if (key == NULL) { + // we need to split at equals sign + const char *equals = strchr(val, '='); + if (!equals || equals - val >= sizeof(keybuf)) { + mp_msg(MSGT_ENCODE, MSGL_WARN, + "encode-lavc: option '%s' does not contain an equals sign\n", + val); + return 0; } - - key = key_; - val = val_; - - if(!strcmp(key, "qscale") && val[0] != '+' && val[0] != '-' && !av_opt_find(octx, key, NULL, 0, AV_OPT_SEARCH_CHILDREN)) - { - // hack: support "qscale" key as virtual "global_quality" key that multiplies by QP2LAMBDA - key = "global_quality"; - snprintf(valuebuf, sizeof(valuebuf), "(%s)*QP2LAMBDA", val); - valuebuf[sizeof(valuebuf)-1] = 0; - val = valuebuf; - } - - av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", - val, key); - - if((o = av_opt_find(octx, key, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { - if (av_dict_set(dictp, key, *val ? val : NULL, (o->type == FF_OPT_TYPE_FLAGS && (val[0] == '+' || val[0] == '-')) ? AV_DICT_APPEND : 0) >= 0) - ++good; - else - errorcode = AVERROR(EINVAL); - } else { - errorcode = AVERROR(ENOENT); - } - - av_free(key_); - av_free(val_); - - if (*str) - ++str; + memcpy(keybuf, val, equals - val); + keybuf[equals - val] = 0; + key = keybuf; + val = equals + 1; } - return errorcode ? errorcode : good; + + // hack: support "qscale" key as virtual "global_quality" key that multiplies by QP2LAMBDA + if (!strcmp(key, "qscale")) { + key = "global_quality"; + snprintf(valuebuf, sizeof(valuebuf), + "%.1s(%s)*QP2LAMBDA", + (val[0] == '+' || val[0] == '-') ? val : "", + (val[0] == '+' || val[0] == '-') ? val + 1 : val); + valuebuf[sizeof(valuebuf) - 1] = 0; + val = valuebuf; + } + + mp_msg(MSGT_ENCODE, MSGL_V, + "encode-lavc: setting value '%s' for key '%s'\n", + val, + key); + + if (av_dict_set(dictp, key, *val ? val : NULL, + (val[0] == '+' || val[0] == '-') ? AV_DICT_APPEND : 0) >= 0) + return 1; + + return 0; } static bool value_has_flag(const char *value, const char *flag) { bool state = true; bool ret = false; - while(*value) - { + while (*value) { size_t l = strcspn(value, "+-"); - if(l == 0) - { + if (l == 0) { state = (*value == '+'); ++value; - } - else - { - if(l == strlen(flag)) - if(!memcmp(value, flag, l)) + } else { + if (l == strlen(flag)) + if (!memcmp(value, flag, l)) ret = state; value += l; } @@ -115,8 +94,10 @@ static bool value_has_flag(const char *value, const char *flag) } #define CHECK_FAIL(ctx, val) \ - if(ctx && (ctx->failed || ctx->finished)) { \ - mp_msg(MSGT_ENCODE, MSGL_ERR, "Called a function on a %s encoding context. Bailing out.\n", ctx->failed ? "failed" : "finished"); \ + if (ctx && (ctx->failed || ctx->finished)) { \ + mp_msg(MSGT_ENCODE, MSGL_ERR, \ + "Called a function on a %s encoding context. Bailing out.\n", \ + ctx->failed ? "failed" : "finished"); \ return val; \ } @@ -140,19 +121,36 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) encode_lavc_discontinuity(ctx); ctx->options = options; - ctx->avc = NULL; - avformat_alloc_output_context2(&ctx->avc, NULL, ctx->options->format, ctx->options->file); - if (!ctx->avc) { - encode_lavc_fail(ctx, "encode-lavc: avformat context allocation failed\n"); + ctx->avc = avformat_alloc_context(); + + if (ctx->options->format) { + char *tok; + const char *in = ctx->options->format; + while (*in) { + tok = av_get_token(&in, ","); + ctx->avc->oformat = av_guess_format(tok, ctx->options->file, NULL); + av_free(tok); + if (ctx->avc->oformat) + break; + if (*in) + ++in; + } + } else + ctx->avc->oformat = av_guess_format(NULL, ctx->options->file, NULL); + + if (!ctx->avc->oformat) { + encode_lavc_fail(ctx, "encode-lavc: format not found\n"); return NULL; } + av_strlcpy(ctx->avc->filename, ctx->options->file, + sizeof(ctx->avc->filename)); + ctx->foptions = NULL; if (ctx->options->fopts) { char **p; for (p = ctx->options->fopts; *p; ++p) { - if (set_to_avdictionary(ctx->avc, &ctx->foptions, ctx->avc, *p, "=", "") - <= 0) + if (!set_to_avdictionary(&ctx->foptions, NULL, *p)) mp_msg(MSGT_ENCODE, MSGL_WARN, "encode-lavc: could not set option %s\n", *p); } @@ -174,7 +172,8 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) } } else ctx->vc = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, - ctx->avc->filename, NULL, AVMEDIA_TYPE_VIDEO)); + ctx->avc->filename, NULL, + AVMEDIA_TYPE_VIDEO)); if (ctx->options->acodec) { char *tok; @@ -192,10 +191,12 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) } } else ctx->ac = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, - ctx->avc->filename, NULL, AVMEDIA_TYPE_AUDIO)); + ctx->avc->filename, NULL, + AVMEDIA_TYPE_AUDIO)); if (!ctx->vc && !ctx->ac) { - encode_lavc_fail(ctx, "encode-lavc: neither audio nor video codec was found\n"); + encode_lavc_fail( + ctx, "encode-lavc: neither audio nor video codec was found\n"); return NULL; } @@ -208,12 +209,10 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) ctx->vbytes = 0; ctx->frames = 0; - if (options->video_first) { + if (options->video_first) ctx->video_first = true; - } - if (options->audio_first) { + if (options->audio_first) ctx->audio_first = true; - } return ctx; } @@ -248,8 +247,10 @@ int encode_lavc_start(struct encode_lavc_context *ctx) ctx->header_written = -1; if (!(ctx->avc->oformat->flags & AVFMT_NOFILE)) { - if (avio_open(&ctx->avc->pb, ctx->avc->filename, AVIO_FLAG_WRITE) < 0) { - encode_lavc_fail(ctx, "encode-lavc: could not open '%s'\n", ctx->avc->filename); + if (avio_open(&ctx->avc->pb, ctx->avc->filename, + AVIO_FLAG_WRITE) < 0) { + encode_lavc_fail(ctx, "encode-lavc: could not open '%s'\n", + ctx->avc->filename); return 0; } } @@ -263,7 +264,7 @@ int encode_lavc_start(struct encode_lavc_context *ctx) for (de = NULL; (de = av_dict_get(ctx->foptions, "", de, AV_DICT_IGNORE_SUFFIX));) - av_log(ctx->avc, AV_LOG_ERROR, "Key '%s' not found.\n", de->key); + mp_msg(MSGT_ENCODE, MSGL_WARN, "ofopts: key '%s' not found.\n", de->key); av_dict_free(&ctx->foptions); ctx->header_written = 1; @@ -276,7 +277,8 @@ void encode_lavc_free(struct encode_lavc_context *ctx) return; if (!ctx->finished) - encode_lavc_fail(ctx, "called encode_lavc_free without encode_lavc_finish\n"); + encode_lavc_fail(ctx, + "called encode_lavc_free without encode_lavc_finish\n"); talloc_free(ctx); } @@ -351,7 +353,8 @@ void encode_lavc_finish(struct encode_lavc_context *ctx) ctx->finished = true; } -static void encode_2pass_prepare(struct encode_lavc_context *ctx, AVDictionary **dictp, void *octx, +static void encode_2pass_prepare(struct encode_lavc_context *ctx, + AVDictionary **dictp, AVStream *stream, struct stream **bytebuf, const char *prefix) { @@ -368,7 +371,7 @@ static void encode_2pass_prepare(struct encode_lavc_context *ctx, AVDictionary * mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', " "disabling 2-pass encoding at pass 2\n", prefix, buf); stream->codec->flags &= ~CODEC_FLAG_PASS2; - set_to_avdictionary(stream->codec, dictp, octx, "flags=-pass2", "=", ""); + set_to_avdictionary(dictp, "flags", "-pass2"); } else { struct bstr content = stream_read_complete(*bytebuf, NULL, 1000000000, 1); @@ -387,10 +390,12 @@ static void encode_2pass_prepare(struct encode_lavc_context *ctx, AVDictionary * if (value_has_flag(de ? de->value : "", "pass1")) { if (!(*bytebuf = open_output_stream(buf, NULL))) { - mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', disabling " - "2-pass encoding at pass 1\n", - prefix, ctx->avc->filename); - set_to_avdictionary(stream->codec, dictp, octx, "flags=-pass1", "=", ""); + mp_msg( + MSGT_ENCODE, MSGL_WARN, + "%s: could not open '%s', disabling " + "2-pass encoding at pass 1\n", + prefix, ctx->avc->filename); + set_to_avdictionary(dictp, "flags", "-pass1"); } } } @@ -403,7 +408,6 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, AVStream *stream = NULL; char **p; int i; - AVCodecContext *dummy; CHECK_FAIL(ctx, NULL); @@ -419,11 +423,13 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, // if this stream isn't stream #0, allocate a dummy stream first for // the next loop to use if (mt == AVMEDIA_TYPE_VIDEO && ctx->audio_first) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: preallocated audio stream for later use\n"); + mp_msg(MSGT_ENCODE, MSGL_INFO, + "vo-lavc: preallocated audio stream for later use\n"); avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now } if (mt == AVMEDIA_TYPE_AUDIO && ctx->video_first) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "ao-lavc: preallocated video stream for later use\n"); + mp_msg(MSGT_ENCODE, MSGL_INFO, + "ao-lavc: preallocated video stream for later use\n"); avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now } } else { @@ -442,9 +448,10 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, r = av_d2q(ctx->options->fps, ctx->options->fps * 1001 + 2); else if (ctx->options->autofps && vo_fps > 0) { r = av_d2q(vo_fps, vo_fps * 1001 + 2); - mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified " - "but -oautofps is active, using guess of %u/%u\n", - (unsigned)r.num, (unsigned)r.den); + mp_msg( + MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified " + "but -oautofps is active, using guess of %u/%u\n", + (unsigned)r.num, (unsigned)r.den); } else { // we want to handle: // 1/25 @@ -455,9 +462,10 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, // so let's take 1001/30000 out r.num = 24000; r.den = 1; - mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified " - "and fps could not be inferred, using guess of %u/%u\n", - (unsigned)r.num, (unsigned)r.den); + mp_msg( + MSGT_ENCODE, MSGL_INFO, "vo-lavc: option -ofps not specified " + "and fps could not be inferred, using guess of %u/%u\n", + (unsigned)r.num, (unsigned)r.den); } if (ctx->vc && ctx->vc->supported_framerates) @@ -483,38 +491,24 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, stream->codec->time_base = ctx->timebase; - dummy = avcodec_alloc_context3(ctx->vc); - dummy->codec = ctx->vc; // FIXME remove this once we can, caused by a bug in libav, elenril is aware of this - // FIXME: - // currently, to eradicate this dummy: - // add here: stream->codec->codec = ctx->vc; // SAME PROBLEM AS ABOVE - // replace dummy by stream->codec - // at the end of this block: stream->codec->codec = NULL; // OR SEGV LATER - ctx->voptions = NULL; - // libx264: default to preset=medium - if (!strcmp(ctx->vc->name, "libx264")) - set_to_avdictionary(stream->codec, &ctx->voptions, dummy, "preset=medium", "=", ""); - if (ctx->options->vopts) for (p = ctx->options->vopts; *p; ++p) - if (set_to_avdictionary(stream->codec, &ctx->voptions, dummy, - *p, "=", "") <= 0) + if (!set_to_avdictionary(&ctx->voptions, NULL, *p)) mp_msg(MSGT_ENCODE, MSGL_WARN, "vo-lavc: could not set option %s\n", *p); de = av_dict_get(ctx->voptions, "global_quality", NULL, 0); - if(de) - set_to_avdictionary(stream->codec, &ctx->voptions, dummy, "flags=+qscale", "=", ""); + if (de) + set_to_avdictionary(&ctx->voptions, "flags", "+qscale"); if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) - set_to_avdictionary(stream->codec, &ctx->voptions, dummy, "flags=+global_header", "=", ""); + set_to_avdictionary(&ctx->voptions, "flags", "+global_header"); - encode_2pass_prepare(ctx, &ctx->voptions, dummy, stream, &ctx->twopass_bytebuffer_v, + encode_2pass_prepare(ctx, &ctx->voptions, stream, + &ctx->twopass_bytebuffer_v, "vo-lavc"); - - av_free(dummy); break; case AVMEDIA_TYPE_AUDIO: @@ -526,34 +520,24 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, stream->codec->time_base = ctx->timebase; - dummy = avcodec_alloc_context3(ctx->ac); - dummy->codec = ctx->ac; // FIXME remove this once we can, caused by a bug in libav, elenril is aware of this - // FIXME: - // currently, to eradicate this dummy: - // add here: stream->codec->codec = ctx->ac; // SAME PROBLEM AS ABOVE - // replace dummy by stream->codec - // at the end of this block: stream->codec->codec = NULL; // OR SEGV LATER - ctx->aoptions = NULL; if (ctx->options->aopts) for (p = ctx->options->aopts; *p; ++p) - if (set_to_avdictionary(stream->codec, &ctx->aoptions, dummy, - *p, "=", "") <= 0) + if (!set_to_avdictionary(&ctx->aoptions, NULL, *p)) mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: could not set option %s\n", *p); de = av_dict_get(ctx->aoptions, "global_quality", NULL, 0); - if(de) - set_to_avdictionary(stream->codec, &ctx->aoptions, dummy, "flags=+qscale", "=", ""); + if (de) + set_to_avdictionary(&ctx->aoptions, "flags", "+qscale"); if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) - set_to_avdictionary(stream->codec, &ctx->aoptions, dummy, "flags=+global_header", "=", ""); + set_to_avdictionary(&ctx->aoptions, "flags", "+global_header"); - encode_2pass_prepare(ctx, &ctx->aoptions, dummy, stream, &ctx->twopass_bytebuffer_a, + encode_2pass_prepare(ctx, &ctx->aoptions, stream, + &ctx->twopass_bytebuffer_a, "ao-lavc"); - - av_free(dummy); break; default: @@ -588,77 +572,79 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream) CHECK_FAIL(ctx, -1); switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) { - stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - av_log(ctx->avc, AV_LOG_ERROR, _( - "\n\n" - " ********************************************\n" - " **** Experimental VIDEO codec selected! ****\n" - " ********************************************\n\n" - "This means the output file may be broken or bad.\n" - "Possible reasons, problems, workarounds:\n" - "- Codec implementation in ffmpeg/libav is not finished yet.\n" - " Try updating ffmpeg or libav.\n" - "- Bad picture quality, blocks, blurriness.\n" - " Experiment with codec settings (-ovcopts) to maybe still get the\n" - " desired quality output at the expense of bitrate.\n" - "- Slow compression.\n" - " Bear with it.\n" - "- Crashes.\n" - " Happens. Try varying options to work around.\n" - "If none of this helps you, try another codec in place of %s.\n\n"), - ctx->vc->name); - } + case AVMEDIA_TYPE_VIDEO: + if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) { + stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + mp_msg(MSGT_ENCODE, MSGL_WARN, _( + "\n\n" + " ********************************************\n" + " **** Experimental VIDEO codec selected! ****\n" + " ********************************************\n\n" + "This means the output file may be broken or bad.\n" + "Possible reasons, problems, workarounds:\n" + "- Codec implementation in ffmpeg/libav is not finished yet.\n" + " Try updating ffmpeg or libav.\n" + "- Bad picture quality, blocks, blurriness.\n" + " Experiment with codec settings (-ovcopts) to maybe still get the\n" + " desired quality output at the expense of bitrate.\n" + "- Slow compression.\n" + " Bear with it.\n" + "- Crashes.\n" + " Happens. Try varying options to work around.\n" + "If none of this helps you, try another codec in place of %s.\n\n"), + ctx->vc->name); + } - ret = avcodec_open2(stream->codec, ctx->vc, &ctx->voptions); + ret = avcodec_open2(stream->codec, ctx->vc, &ctx->voptions); - // complain about all remaining options, then free the dict - for (de = NULL; (de = av_dict_get(ctx->voptions, "", de, - AV_DICT_IGNORE_SUFFIX));) - av_log(ctx->avc, AV_LOG_ERROR, "Key '%s' not found.\n", de->key); - av_dict_free(&ctx->voptions); + // complain about all remaining options, then free the dict + for (de = NULL; (de = av_dict_get(ctx->voptions, "", de, + AV_DICT_IGNORE_SUFFIX));) + mp_msg(MSGT_ENCODE, MSGL_WARN, "ovcopts: key '%s' not found.\n", + de->key); + av_dict_free(&ctx->voptions); - break; - case AVMEDIA_TYPE_AUDIO: - if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) { - stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - av_log(ctx->avc, AV_LOG_ERROR, _( - "\n\n" - " ********************************************\n" - " **** Experimental AUDIO codec selected! ****\n" - " ********************************************\n\n" - "This means the output file may be broken or bad.\n" - "Possible reasons, problems, workarounds:\n" - "- Codec implementation in ffmpeg/libav is not finished yet.\n" - " Try updating ffmpeg or libav.\n" - "- Bad sound quality, noise, clicking, whistles, choppiness.\n" - " Experiment with codec settings (-oacopts) to maybe still get the\n" - " desired quality output at the expense of bitrate.\n" - "- Slow compression.\n" - " Bear with it.\n" - "- Crashes.\n" - " Happens. Try varying options to work around.\n" - "If none of this helps you, try another codec in place of %s.\n\n"), - ctx->ac->name); - } - ret = avcodec_open2(stream->codec, ctx->ac, &ctx->aoptions); + break; + case AVMEDIA_TYPE_AUDIO: + if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) { + stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + mp_msg(MSGT_ENCODE, MSGL_WARN, _( + "\n\n" + " ********************************************\n" + " **** Experimental AUDIO codec selected! ****\n" + " ********************************************\n\n" + "This means the output file may be broken or bad.\n" + "Possible reasons, problems, workarounds:\n" + "- Codec implementation in ffmpeg/libav is not finished yet.\n" + " Try updating ffmpeg or libav.\n" + "- Bad sound quality, noise, clicking, whistles, choppiness.\n" + " Experiment with codec settings (-oacopts) to maybe still get the\n" + " desired quality output at the expense of bitrate.\n" + "- Slow compression.\n" + " Bear with it.\n" + "- Crashes.\n" + " Happens. Try varying options to work around.\n" + "If none of this helps you, try another codec in place of %s.\n\n"), + ctx->ac->name); + } + ret = avcodec_open2(stream->codec, ctx->ac, &ctx->aoptions); - // complain about all remaining options, then free the dict - for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de, - AV_DICT_IGNORE_SUFFIX));) - av_log(ctx->avc, AV_LOG_ERROR, "Key '%s' not found.\n", de->key); - av_dict_free(&ctx->aoptions); + // complain about all remaining options, then free the dict + for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de, + AV_DICT_IGNORE_SUFFIX));) + mp_msg(MSGT_ENCODE, MSGL_WARN, "oacopts: key '%s' not found.\n", + de->key); + av_dict_free(&ctx->aoptions); - break; - default: - ret = -1; - break; + break; + default: + ret = -1; + break; } - if(ret < 0) { - encode_lavc_fail(ctx, "unable to open encoder (see above for the cause)"); - } + if (ret < 0) + encode_lavc_fail(ctx, + "unable to open encoder (see above for the cause)"); return ret; } @@ -696,18 +682,19 @@ int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet) if (ctx->header_written <= 0) return -1; - mp_msg(MSGT_ENCODE, MSGL_DBG2, - "encode-lavc: write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n", - (int)packet->stream_index, - (int)packet->pts, - packet->pts * (double)ctx->avc->streams[packet->stream_index]-> - time_base.num / (double)ctx->avc->streams[packet-> - stream_index]->time_base.den, - (int)packet->dts, - packet->dts * (double)ctx->avc->streams[packet->stream_index]-> - time_base.num / (double)ctx->avc->streams[packet-> - stream_index]->time_base.den, - (int)packet->size); + mp_msg( + MSGT_ENCODE, MSGL_DBG2, + "encode-lavc: write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n", + (int)packet->stream_index, + (int)packet->pts, + packet->pts + * (double)ctx->avc->streams[packet->stream_index]->time_base.num + / (double)ctx->avc->streams[packet->stream_index]->time_base.den, + (int)packet->dts, + packet->dts + * (double)ctx->avc->streams[packet->stream_index]->time_base.num + / (double)ctx->avc->streams[packet->stream_index]->time_base.den, + (int)packet->size); switch (ctx->avc->streams[packet->stream_index]->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -736,9 +723,9 @@ int encode_lavc_supports_pixfmt(struct encode_lavc_context *ctx, if (pix_fmt == PIX_FMT_NONE) return 0; - if (!ctx->vc->pix_fmts) { + if (!ctx->vc->pix_fmts) return VFCAP_CSP_SUPPORTED; - } else { + else { const enum PixelFormat *p; for (p = ctx->vc->pix_fmts; *p >= 0; ++p) { if (pix_fmt == *p) @@ -834,10 +821,12 @@ static void encode_lavc_printoptions(void *obj, const char *indent, bool encode_lavc_showhelp(struct MPOpts *opts) { bool help_output = false; - if(av_codec_next(NULL) == NULL) + if (av_codec_next(NULL) == NULL) mp_msg(MSGT_ENCODE, MSGL_ERR, "NO CODECS\n"); -#define CHECKS(str) ((str) && strcmp((str), "help") == 0 ? (help_output |= 1) : 0) -#define CHECKV(strv) ((strv) && (strv)[0] && strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0) +#define CHECKS(str) ((str) && \ + strcmp((str), "help") == 0 ? (help_output |= 1) : 0) +#define CHECKV(strv) ((strv) && (strv)[0] && \ + strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0) if (CHECKS(opts->encode_output.format)) { AVOutputFormat *c = NULL; mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output formats:\n"); @@ -849,7 +838,8 @@ bool encode_lavc_showhelp(struct MPOpts *opts) if (CHECKV(opts->encode_output.fopts)) { AVFormatContext *c = avformat_alloc_context(); AVOutputFormat *format = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output format ctx->options:\n"); + mp_msg(MSGT_ENCODE, MSGL_INFO, + "Available output format ctx->options:\n"); encode_lavc_printoptions(c, " -ofopts ", " ", NULL, AV_OPT_FLAG_ENCODING_PARAM, AV_OPT_FLAG_ENCODING_PARAM); @@ -870,24 +860,31 @@ bool encode_lavc_showhelp(struct MPOpts *opts) AVCodec *codec = NULL; mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output video codec ctx->options:\n"); - encode_lavc_printoptions(c, " -ovcopts ", " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM); + encode_lavc_printoptions( + c, " -ovcopts ", " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM); av_free(c); while ((codec = av_codec_next(codec))) { if (!av_codec_is_encoder(codec)) continue; if (codec->type != AVMEDIA_TYPE_VIDEO) continue; - if (opts->encode_output.vcodec && opts->encode_output.vcodec[0] && strcmp(opts->encode_output.vcodec, codec->name) != 0) + if (opts->encode_output.vcodec && opts->encode_output.vcodec[0] && + strcmp(opts->encode_output.vcodec, codec->name) != 0) continue; if (codec->priv_class) { mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for -ovc %s:\n", codec->name); - encode_lavc_printoptions(&codec->priv_class, " -ovcopts ", - " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM); + encode_lavc_printoptions( + &codec->priv_class, " -ovcopts ", + " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM); } } } @@ -896,24 +893,31 @@ bool encode_lavc_showhelp(struct MPOpts *opts) AVCodec *codec = NULL; mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output audio codec ctx->options:\n"); - encode_lavc_printoptions(c, " -oacopts ", " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM); + encode_lavc_printoptions( + c, " -oacopts ", " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM); av_free(c); while ((codec = av_codec_next(codec))) { if (!av_codec_is_encoder(codec)) continue; if (codec->type != AVMEDIA_TYPE_AUDIO) continue; - if (opts->encode_output.acodec && opts->encode_output.acodec[0] && strcmp(opts->encode_output.acodec, codec->name) != 0) + if (opts->encode_output.acodec && opts->encode_output.acodec[0] && + strcmp(opts->encode_output.acodec, codec->name) != 0) continue; if (codec->priv_class) { mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for -oac %s:\n", codec->name); - encode_lavc_printoptions(&codec->priv_class, " -oacopts ", - " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM); + encode_lavc_printoptions( + &codec->priv_class, " -oacopts ", + " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM); } } } @@ -972,7 +976,7 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx, CHECK_FAIL(ctx, -1); - minutes = (GetTimerMS() - ctx->t0) / 60000.0 * (1-f) / f; + minutes = (GetTimerMS() - ctx->t0) / 60000.0 * (1 - f) / f; megabytes = ctx->avc->pb ? (avio_size(ctx->avc->pb) / 1048576.0 / f) : 0; fps = ctx->frames / ((GetTimerMS() - ctx->t0) / 1000.0); x = playback_time / ((GetTimerMS() - ctx->t0) / 1000.0); @@ -986,11 +990,12 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx, return 0; } -void encode_lavc_expect_stream(struct encode_lavc_context *ctx, enum AVMediaType mt) +void encode_lavc_expect_stream(struct encode_lavc_context *ctx, + enum AVMediaType mt) { CHECK_FAIL(ctx, ); - switch(mt) { + switch (mt) { case AVMEDIA_TYPE_VIDEO: ctx->expect_video = true; break; @@ -1010,7 +1015,7 @@ void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...) va_list va; va_start(va, format); mp_msg_va(MSGT_ENCODE, MSGL_ERR, format, va); - if(ctx->failed) + if (ctx->failed) return; ctx->failed = true; encode_lavc_finish(ctx);