mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 20:42:49 +08:00 
			
		
		
		
	Add a -force_key_frames option to ffmpeg.
The option is useful to ensure that there is a seek point exactly at a place the user will probably want to jump precisely sometime, the major example would be the end of an opening and the beginning of a chapter. The scene change detection system will often make it happen, but not always for example if there is a fade-in. See the thread: Subject: [FFmpeg-devel] [PATCH] -force_key_frames option Date: Tue, 12 Oct 2010 15:16:26 +0200 Patch by Nicolas George -mail nicolas,george,normalesup,org. Originally committed as revision 25526 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		 Nicolas George
					Nicolas George
				
			
				
					committed by
					
						 Stefano Sabatini
						Stefano Sabatini
					
				
			
			
				
	
			
			
			 Stefano Sabatini
						Stefano Sabatini
					
				
			
						parent
						
							43945b2766
						
					
				
				
					commit
					4ad08021e8
				
			| @@ -48,6 +48,7 @@ version <next>: | ||||
| - cropdetect filter | ||||
| - ffmpeg -crop* options removed | ||||
| - transpose filter added | ||||
| - ffmpeg -force_key_frames option added | ||||
|  | ||||
|  | ||||
| version 0.6: | ||||
|   | ||||
| @@ -495,6 +495,12 @@ Bitstream filters available are "dump_extra", "remove_extra", "noise", "h264_mp4 | ||||
| @example | ||||
| ffmpeg -i h264.mp4 -vcodec copy -vbsf h264_mp4toannexb -an out.h264 | ||||
| @end example | ||||
| @item -force_key_frames @var{time}[,@var{time}...] | ||||
| Force key frames at the specified timestamps, more precisely at the first | ||||
| frames after each specified time. | ||||
| This option can be useful to ensure that a seek point is present at a | ||||
| chapter mark or any other designated place in the output file. | ||||
| The timestamps must be specified in ascending order. | ||||
| @end table | ||||
|  | ||||
| @section Audio Options | ||||
|   | ||||
							
								
								
									
										41
									
								
								ffmpeg.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								ffmpeg.c
									
									
									
									
									
								
							| @@ -225,6 +225,7 @@ static int nb_frames_drop = 0; | ||||
| static int input_sync; | ||||
| static uint64_t limit_filesize = 0; | ||||
| static int force_fps = 0; | ||||
| static char *forced_key_frames = NULL; | ||||
|  | ||||
| static int pgmyuv_compatibility_hack=0; | ||||
| static float dts_delta_threshold = 10; | ||||
| @@ -272,6 +273,11 @@ typedef struct AVOutputStream { | ||||
|     int original_height; | ||||
|     int original_width; | ||||
|  | ||||
|     /* forced key frames */ | ||||
|     int64_t *forced_kf_pts; | ||||
|     int forced_kf_count; | ||||
|     int forced_kf_index; | ||||
|  | ||||
|     /* audio only */ | ||||
|     int audio_resample; | ||||
|     ReSampleContext *resample; /* for audio resampling */ | ||||
| @@ -1189,6 +1195,11 @@ static void do_video_out(AVFormatContext *s, | ||||
|             big_picture.pts= ost->sync_opts; | ||||
| //            big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den); | ||||
| //av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts); | ||||
|             if (ost->forced_kf_index < ost->forced_kf_count && | ||||
|                 big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) { | ||||
|                 big_picture.pict_type = FF_I_TYPE; | ||||
|                 ost->forced_kf_index++; | ||||
|             } | ||||
|             ret = avcodec_encode_video(enc, | ||||
|                                        bit_buffer, bit_buffer_size, | ||||
|                                        &big_picture); | ||||
| @@ -1837,6 +1848,29 @@ static int copy_chapters(int infile, int outfile) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static void parse_forced_key_frames(char *kf, AVOutputStream *ost, | ||||
|                                     AVCodecContext *avctx) | ||||
| { | ||||
|     char *p; | ||||
|     int n = 1, i; | ||||
|     int64_t t; | ||||
|  | ||||
|     for (p = kf; *p; p++) | ||||
|         if (*p == ',') | ||||
|             n++; | ||||
|     ost->forced_kf_count = n; | ||||
|     ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); | ||||
|     if (!ost->forced_kf_pts) { | ||||
|         av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); | ||||
|         ffmpeg_exit(1); | ||||
|     } | ||||
|     for (i = 0; i < n; i++) { | ||||
|         p = i ? strchr(p, ',') + 1 : kf; | ||||
|         t = parse_time_or_die("force_key_frames", p, 1); | ||||
|         ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The following code is the main loop of the file converter | ||||
|  */ | ||||
| @@ -2578,6 +2612,7 @@ static int transcode(AVFormatContext **output_files, | ||||
|                 av_fifo_free(ost->fifo); /* works even if fifo is not | ||||
|                                              initialized but set to zero */ | ||||
|                 av_free(ost->pict_tmp.data[0]); | ||||
|                 av_free(ost->forced_kf_pts); | ||||
|                 if (ost->video_resample) | ||||
|                     sws_freeContext(ost->img_resample_ctx); | ||||
|                 if (ost->resample) | ||||
| @@ -3333,6 +3368,9 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) | ||||
|                 video_enc->flags |= CODEC_FLAG_PASS2; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (forced_key_frames) | ||||
|             parse_forced_key_frames(forced_key_frames, ost, video_enc); | ||||
|     } | ||||
|     if (video_language) { | ||||
|         av_metadata_set2(&st->metadata, "language", video_language, 0); | ||||
| @@ -3342,6 +3380,7 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) | ||||
|     /* reset some key parameters */ | ||||
|     video_disable = 0; | ||||
|     av_freep(&video_codec_name); | ||||
|     av_freep(&forced_key_frames); | ||||
|     video_stream_copy = 0; | ||||
|     frame_pix_fmt = PIX_FMT_NONE; | ||||
| } | ||||
| @@ -3644,6 +3683,7 @@ static void opt_output_file(const char *filename) | ||||
|     set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); | ||||
|  | ||||
|     nb_streamid_map = 0; | ||||
|     av_freep(&forced_key_frames); | ||||
| } | ||||
|  | ||||
| /* same option as mencoder */ | ||||
| @@ -4094,6 +4134,7 @@ static const OptionDef options[] = { | ||||
|     { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" }, | ||||
|     { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" }, | ||||
|     { "streamid", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" }, | ||||
|     { "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void *)&forced_key_frames}, "force key frames at specified timestamps", "timestamps" }, | ||||
|  | ||||
|     /* audio options */ | ||||
|     { "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user