You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02: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:
		
				
					committed by
					
						 Michael Niedermayer
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						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" }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user