mirror of https://github.com/mpv-player/mpv
encode: add options --ovfirst and --oafirst
This allows to define which stream is to be used as first output stream. This is useful because dvdauthor refuses VOB files where the audio stream is the first stream.
This commit is contained in:
parent
53c6a7480f
commit
327a5d0ecf
|
@ -56,8 +56,8 @@ You can encode files from one format/codec to another using this facility.
|
|||
avoid --oautofps.
|
||||
|
||||
--oac=<codec>
|
||||
Specifies the output audio codec.
|
||||
See --oac=help for a full list of supported codecs.
|
||||
Specifies the output audio codec. This can be a comma separated list of
|
||||
possible codecs to try. See --oac=help for a full list of supported codecs.
|
||||
|
||||
--oaoffset=<value>
|
||||
Shifts audio data by the given time (in seconds) by adding/removing
|
||||
|
@ -86,27 +86,18 @@ You can encode files from one format/codec to another using this facility.
|
|||
--oacopts-clr
|
||||
Completely empties the options list.
|
||||
|
||||
--oafirst
|
||||
Force the audio stream to become the first stream in the output. By default
|
||||
the order is unspecified.
|
||||
|
||||
--ovc=<codec>
|
||||
Specifies the output video codec.
|
||||
See --ovc=help for a full list of supported codecs.
|
||||
Specifies the output video codec. This can be a comma separated list of
|
||||
possible codecs to try. See --ovc=help for a full list of supported codecs.
|
||||
|
||||
--ovoffset=<value>
|
||||
Shifts video data by the given time (in seconds) by shifting the pts
|
||||
values.
|
||||
|
||||
--ocopyts
|
||||
Copies input pts to the output video (not supported by some output
|
||||
container formats, e.g. avi). Discontinuities are still fixed.
|
||||
By default, audio pts are set to playback time and video pts are
|
||||
synchronized to match audio pts, as some output formats do not support
|
||||
anything else.
|
||||
|
||||
--orawts
|
||||
Copies input pts to the output video (not supported by some output
|
||||
container formats, e.g. avi). In this modem discontinuities are not fixed
|
||||
and all pts are passed through as-is. Never seek backwards or use multiple
|
||||
input files in this mode!
|
||||
|
||||
--ovcopts <options>
|
||||
Specifies the output video codec options for libavcodec.
|
||||
See --ovcopts=help for a full list of supported options.
|
||||
|
@ -132,3 +123,20 @@ You can encode files from one format/codec to another using this facility.
|
|||
|
||||
--ovcopts-clr
|
||||
Completely empties the options list.
|
||||
|
||||
--ovfirst
|
||||
Force the video stream to become the first stream in the output. By default
|
||||
the order is unspecified.
|
||||
|
||||
--ocopyts
|
||||
Copies input pts to the output video (not supported by some output
|
||||
container formats, e.g. avi). Discontinuities are still fixed.
|
||||
By default, audio pts are set to playback time and video pts are
|
||||
synchronized to match audio pts, as some output formats do not support
|
||||
anything else.
|
||||
|
||||
--orawts
|
||||
Copies input pts to the output video (not supported by some output
|
||||
container formats, e.g. avi). In this modem discontinuities are not fixed
|
||||
and all pts are passed through as-is. Never seek backwards or use multiple
|
||||
input files in this mode!
|
||||
|
|
|
@ -760,6 +760,8 @@ const m_option_t mplayer_opts[]={
|
|||
OPT_MAKE_FLAGS("orawts", encode_output.rawts, CONF_GLOBAL),
|
||||
OPT_MAKE_FLAGS("oautofps", encode_output.autofps, CONF_GLOBAL),
|
||||
OPT_MAKE_FLAGS("oneverdrop", encode_output.neverdrop, CONF_GLOBAL),
|
||||
OPT_MAKE_FLAGS("ovfirst", encode_output.video_first, CONF_GLOBAL),
|
||||
OPT_MAKE_FLAGS("oafirst", encode_output.audio_first, CONF_GLOBAL),
|
||||
|
||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||
};
|
||||
|
|
|
@ -208,6 +208,13 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options)
|
|||
ctx->vbytes = 0;
|
||||
ctx->frames = 0;
|
||||
|
||||
if (options->video_first) {
|
||||
ctx->video_first = true;
|
||||
}
|
||||
if (options->audio_first) {
|
||||
ctx->audio_first = true;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -408,6 +415,26 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||
// already have a stream of that type, this cannot really happen
|
||||
return NULL;
|
||||
|
||||
if (ctx->avc->nb_streams == 0) {
|
||||
// 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");
|
||||
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");
|
||||
avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now
|
||||
}
|
||||
} else {
|
||||
// find possibly preallocated stream
|
||||
for (i = 0; i < ctx->avc->nb_streams; ++i)
|
||||
if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_UNKNOWN) // preallocated stream
|
||||
stream = ctx->avc->streams[i];
|
||||
}
|
||||
if (!stream)
|
||||
stream = avformat_new_stream(ctx->avc, NULL);
|
||||
|
||||
if (ctx->timebase.den == 0) {
|
||||
AVRational r;
|
||||
|
||||
|
@ -447,7 +474,6 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||
encode_lavc_fail(ctx, "vo-lavc: encoder not found\n");
|
||||
return NULL;
|
||||
}
|
||||
stream = avformat_new_stream(ctx->avc, NULL);
|
||||
avcodec_get_context_defaults3(stream->codec, ctx->vc);
|
||||
|
||||
// stream->time_base = ctx->timebase;
|
||||
|
@ -455,9 +481,7 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||
// which doesn't properly force the time base to be 90000
|
||||
// furthermore, ffmpeg.c doesn't do this either and works
|
||||
|
||||
stream->codec->codec_id = ctx->vc->id;
|
||||
stream->codec->time_base = ctx->timebase;
|
||||
stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
|
||||
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
|
||||
|
@ -498,12 +522,9 @@ AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx,
|
|||
encode_lavc_fail(ctx, "ao-lavc: encoder not found\n");
|
||||
return NULL;
|
||||
}
|
||||
stream = avformat_new_stream(ctx->avc, NULL);
|
||||
avcodec_get_context_defaults3(stream->codec, ctx->ac);
|
||||
|
||||
stream->codec->codec_id = ctx->ac->id;
|
||||
stream->codec->time_base = ctx->timebase;
|
||||
stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
|
||||
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
|
||||
|
@ -676,12 +697,16 @@ int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet)
|
|||
return -1;
|
||||
|
||||
mp_msg(MSGT_ENCODE, MSGL_DBG2,
|
||||
"encode-lavc: write frame: stream %d ptsi %d (%f) size %d\n",
|
||||
"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) {
|
||||
|
|
|
@ -59,8 +59,11 @@ struct encode_lavc_context {
|
|||
struct stream *twopass_bytebuffer_v;
|
||||
unsigned int t0;
|
||||
unsigned int frames;
|
||||
|
||||
bool expect_video;
|
||||
bool expect_audio;
|
||||
bool video_first;
|
||||
bool audio_first;
|
||||
|
||||
// has encoding failed?
|
||||
bool failed;
|
||||
|
|
|
@ -124,26 +124,26 @@ ofopts-clr = yes
|
|||
# target devices #
|
||||
##################
|
||||
[enc-to-dvdpal]
|
||||
profile-desc = "DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en"
|
||||
profile-desc = "DVD-Video PAL, use dvdauthor -v pal -a ac3+en (MUST be used with 4:3 or 16:9 aspect, and 720x576, 704x576, 352x576 or 352x288 resolution)"
|
||||
profile = enc-v-mpeg2
|
||||
profile = enc-a-ac3
|
||||
of = dvd
|
||||
ofopts-add = packetsize=2048,muxrate=10080000
|
||||
ofps = 25
|
||||
oharddup = yes
|
||||
vf-add = expand=aspect=4/3,scale=w=720:h=576
|
||||
ovfirst = yes # dvdauthor needs this
|
||||
srate = 48000
|
||||
ovcopts-add = g=15,b=6000000,maxrate=9000000,minrate=0,bufsize=1835008
|
||||
|
||||
[enc-to-dvdntsc]
|
||||
profile-desc = "DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en"
|
||||
profile-desc = "DVD-Video NTSC, use dvdauthor -v ntsc -a ac3+en (MUST be used with 4:3 or 16:9 aspect, and 720x480, 704x480, 352x480 or 352x240 resolution)"
|
||||
profile = enc-v-mpeg2
|
||||
profile = enc-a-ac3
|
||||
of = dvd
|
||||
ofopts-add = packetsize=2048,muxrate=10080000
|
||||
ofps = 24000/1001
|
||||
oharddup = yes
|
||||
vf-add = expand=aspect=4/3,scale=w=720:h=480
|
||||
ovfirst = yes # dvdauthor needs this
|
||||
srate = 48000
|
||||
ovcopts-add = g=18,b=6000000,maxrate=9000000,minrate=0,bufsize=1835008
|
||||
|
||||
|
|
|
@ -405,6 +405,8 @@ static int encode(struct ao *ao, double apts, void *data)
|
|||
|
||||
encode_lavc_write_stats(ao->encode_lavc_ctx, ac->stream);
|
||||
|
||||
packet.stream_index = ac->stream->index;
|
||||
|
||||
// Do we need this at all? Better be safe than sorry...
|
||||
if (packet.pts == AV_NOPTS_VALUE) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: encoder lost pts, why?\n");
|
||||
|
|
14
mplayer.c
14
mplayer.c
|
@ -3961,6 +3961,13 @@ goto_enable_cache:
|
|||
|
||||
preselect_demux_streams(mpctx);
|
||||
|
||||
#ifdef CONFIG_ENCODING
|
||||
if (mpctx->encode_lavc_ctx && mpctx->current_track[STREAM_VIDEO])
|
||||
encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
if (mpctx->encode_lavc_ctx && mpctx->current_track[STREAM_AUDIO])
|
||||
encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_AUDIO);
|
||||
#endif
|
||||
|
||||
reinit_video_chain(mpctx);
|
||||
reinit_audio_chain(mpctx);
|
||||
reinit_subs(mpctx);
|
||||
|
@ -3988,13 +3995,6 @@ goto_enable_cache:
|
|||
goto terminate_playback;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ENCODING
|
||||
if (mpctx->encode_lavc_ctx && mpctx->sh_video)
|
||||
encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
if (mpctx->encode_lavc_ctx && mpctx->sh_audio)
|
||||
encode_lavc_expect_stream(mpctx->encode_lavc_ctx, AVMEDIA_TYPE_AUDIO);
|
||||
#endif
|
||||
|
||||
if (opts->playing_msg) {
|
||||
char *msg = property_expand_string(mpctx, opts->playing_msg);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", msg);
|
||||
|
|
Loading…
Reference in New Issue