mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-27 05:00:37 +00:00
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>
This commit is contained in:
parent
6ce57fb3c2
commit
2b06f2d2e2
@ -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
|
||||
|
31
ffmpeg.c
31
ffmpeg.c
@ -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
ffmpeg.h
3
ffmpeg.h
@ -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
ffmpeg_opt.c
16
ffmpeg_opt.c
@ -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…
Reference in New Issue
Block a user