Browse Source

ffmpeg: add enc_time_base option

add a per-stream option for setting the encoder timebase.
the following values are allowed:
0 - for video, use 1/frame_rate, for audio use 1/sample_rate (this is
  the default)
-1 - match the input timebase (when possible)
>0 - set the timebase to provided number

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
tags/n3.4
erankor Michael Niedermayer 8 years ago
parent
commit
2b06f2d2e2
4 changed files with 72 additions and 2 deletions
  1. +24
    -0
      doc/ffmpeg.texi
  2. +29
    -2
      ffmpeg.c
  3. +3
    -0
      ffmpeg.h
  4. +16
    -0
      ffmpeg_opt.c

+ 24
- 0
doc/ffmpeg.texi View File

@@ -1176,6 +1176,30 @@ Try to make the choice automatically, in order to generate a sane output.

Default value is -1.

@item -enc_time_base[:@var{stream_specifier}] @var{timebase} (@emph{output,per-stream})
Set the encoder timebase. @var{timebase} is a floating point number,
and can assume one of the following values:

@table @option
@item 0
Assign a default value according to the media type.

For video - use 1/framerate, for audio - use 1/samplerate.

@item -1
Use the input stream timebase when possible.

If an input stream is not available, the default timebase will be used.

@item >0
Use the provided number as the timebase.

This field can be provided as a ratio of two integers (e.g. 1:24, 1:48000)
or as a floating point number (e.g. 0.04166, 2.0833e-5)
@end table

Default value is 0.

@item -shortest (@emph{output})
Finish encoding when the shortest input stream ends.
@item -dts_delta_threshold


+ 29
- 2
ffmpeg.c View File

@@ -3234,6 +3234,30 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost,
ost->forced_kf_pts = pts;
}

static void init_encoder_time_base(OutputStream *ost, AVRational default_time_base)
{
InputStream *ist = get_input_stream(ost);
AVCodecContext *enc_ctx = ost->enc_ctx;
AVFormatContext *oc;

if (ost->enc_timebase.num > 0) {
enc_ctx->time_base = ost->enc_timebase;
return;
}

if (ost->enc_timebase.num < 0) {
if (ist) {
enc_ctx->time_base = ist->st->time_base;
return;
}

oc = output_files[ost->file_index]->ctx;
av_log(oc, AV_LOG_WARNING, "Input stream data not available, using default time base\n");
}

enc_ctx->time_base = default_time_base;
}

static int init_output_stream_encode(OutputStream *ost)
{
InputStream *ist = get_input_stream(ost);
@@ -3304,10 +3328,13 @@ static int init_output_stream_encode(OutputStream *ost)
enc_ctx->sample_rate = av_buffersink_get_sample_rate(ost->filter->filter);
enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter);
enc_ctx->channels = av_buffersink_get_channels(ost->filter->filter);
enc_ctx->time_base = (AVRational){ 1, enc_ctx->sample_rate };

init_encoder_time_base(ost, av_make_q(1, enc_ctx->sample_rate));
break;

case AVMEDIA_TYPE_VIDEO:
enc_ctx->time_base = av_inv_q(ost->frame_rate);
init_encoder_time_base(ost, av_inv_q(ost->frame_rate));

if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
enc_ctx->time_base = av_buffersink_get_time_base(ost->filter->filter);
if ( av_q2d(enc_ctx->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH


+ 3
- 0
ffmpeg.h View File

@@ -226,6 +226,8 @@ typedef struct OptionsContext {
int nb_program;
SpecifierOpt *time_bases;
int nb_time_bases;
SpecifierOpt *enc_time_bases;
int nb_enc_time_bases;
} OptionsContext;

typedef struct InputFilter {
@@ -453,6 +455,7 @@ typedef struct OutputStream {
int64_t last_mux_dts;
// the timebase of the packets sent to the muxer
AVRational mux_timebase;
AVRational enc_timebase;

int nb_bitstream_filters;
uint8_t *bsf_extradata_updated;


+ 16
- 0
ffmpeg_opt.c View File

@@ -1311,6 +1311,17 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
st->time_base = q;
}

MATCH_PER_STREAM_OPT(enc_time_bases, str, time_base, oc, st);
if (time_base) {
AVRational q;
if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
q.den <= 0) {
av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
exit_program(1);
}
ost->enc_timebase = q;
}

ost->max_frames = INT64_MAX;
MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
for (i = 0; i<o->nb_max_frames; i++) {
@@ -3629,6 +3640,11 @@ const OptionDef options[] = {

{ "time_base", HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(time_bases) },
"set the desired time base hint for output stream (1:24, 1:48000 or 0.04166, 2.0833e-5)", "ratio" },
{ "enc_time_base", HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(enc_time_bases) },
"set the desired time base for the encoder (1:24, 1:48000 or 0.04166, 2.0833e-5). "
"two special values are defined - "
"0 = use frame rate (video) or sample rate (audio),"
"-1 = match source time base", "ratio" },

{ "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
"A comma-separated list of bitstream filters", "bitstream_filters" },


Loading…
Cancel
Save