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:
Rudolf Polzer 2012-09-29 15:04:40 +02:00
parent 53c6a7480f
commit 327a5d0ecf
8 changed files with 77 additions and 35 deletions

View File

@ -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!

View File

@ -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}
};

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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");

View File

@ -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);

View File

@ -176,6 +176,8 @@ typedef struct MPOpts {
int rawts;
int autofps;
int neverdrop;
int video_first;
int audio_first;
} encode_output;
} MPOpts;