fftools/ffmpeg: add encoder private data
Start by moving OutputStream.last_frame to it. In the future it will hold other encoder-internal state.
This commit is contained in:
		
							parent
							
								
									44accfef41
								
							
						
					
					
						commit
						f30b620e98
					
				| @ -557,6 +557,8 @@ typedef struct KeyframeForceCtx { | |||||||
|     int          dropped_keyframe; |     int          dropped_keyframe; | ||||||
| } KeyframeForceCtx; | } KeyframeForceCtx; | ||||||
| 
 | 
 | ||||||
|  | typedef struct Encoder Encoder; | ||||||
|  | 
 | ||||||
| typedef struct OutputStream { | typedef struct OutputStream { | ||||||
|     const AVClass *class; |     const AVClass *class; | ||||||
| 
 | 
 | ||||||
| @ -588,9 +590,9 @@ typedef struct OutputStream { | |||||||
|     AVRational mux_timebase; |     AVRational mux_timebase; | ||||||
|     AVRational enc_timebase; |     AVRational enc_timebase; | ||||||
| 
 | 
 | ||||||
|  |     Encoder *enc; | ||||||
|     AVCodecContext *enc_ctx; |     AVCodecContext *enc_ctx; | ||||||
|     AVFrame *filtered_frame; |     AVFrame *filtered_frame; | ||||||
|     AVFrame *last_frame; |  | ||||||
|     AVFrame *sq_frame; |     AVFrame *sq_frame; | ||||||
|     AVPacket *pkt; |     AVPacket *pkt; | ||||||
|     int64_t last_dropped; |     int64_t last_dropped; | ||||||
| @ -824,6 +826,9 @@ AVBufferRef *hw_device_for_filter(void); | |||||||
| 
 | 
 | ||||||
| int hwaccel_decode_init(AVCodecContext *avctx); | int hwaccel_decode_init(AVCodecContext *avctx); | ||||||
| 
 | 
 | ||||||
|  | int enc_alloc(Encoder **penc, const AVCodec *codec); | ||||||
|  | void enc_free(Encoder **penc); | ||||||
|  | 
 | ||||||
| int enc_open(OutputStream *ost, AVFrame *frame); | int enc_open(OutputStream *ost, AVFrame *frame); | ||||||
| void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub); | void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub); | ||||||
| void enc_frame(OutputStream *ost, AVFrame *frame); | void enc_frame(OutputStream *ost, AVFrame *frame); | ||||||
|  | |||||||
| @ -43,8 +43,48 @@ | |||||||
| 
 | 
 | ||||||
| #include "libavformat/avformat.h" | #include "libavformat/avformat.h" | ||||||
| 
 | 
 | ||||||
|  | struct Encoder { | ||||||
|  |     AVFrame *last_frame; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static uint64_t dup_warning = 1000; | static uint64_t dup_warning = 1000; | ||||||
| 
 | 
 | ||||||
|  | void enc_free(Encoder **penc) | ||||||
|  | { | ||||||
|  |     Encoder *enc = *penc; | ||||||
|  | 
 | ||||||
|  |     if (!enc) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     av_frame_free(&enc->last_frame); | ||||||
|  | 
 | ||||||
|  |     av_freep(penc); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int enc_alloc(Encoder **penc, const AVCodec *codec) | ||||||
|  | { | ||||||
|  |     Encoder *enc; | ||||||
|  | 
 | ||||||
|  |     *penc = NULL; | ||||||
|  | 
 | ||||||
|  |     enc = av_mallocz(sizeof(*enc)); | ||||||
|  |     if (!enc) | ||||||
|  |         return AVERROR(ENOMEM); | ||||||
|  | 
 | ||||||
|  |     if (codec->type == AVMEDIA_TYPE_VIDEO) { | ||||||
|  |         enc->last_frame = av_frame_alloc(); | ||||||
|  |         if (!enc->last_frame) | ||||||
|  |             goto fail; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *penc = enc; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | fail: | ||||||
|  |     enc_free(&enc); | ||||||
|  |     return AVERROR(ENOMEM); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void set_encoder_id(OutputFile *of, OutputStream *ost) | static void set_encoder_id(OutputFile *of, OutputStream *ost) | ||||||
| { | { | ||||||
|     const char *cname = ost->enc_ctx->codec->name; |     const char *cname = ost->enc_ctx->codec->name; | ||||||
| @ -919,6 +959,7 @@ static void do_video_out(OutputFile *of, | |||||||
|                          AVFrame *next_picture) |                          AVFrame *next_picture) | ||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
|  |     Encoder *e = ost->enc; | ||||||
|     AVCodecContext *enc = ost->enc_ctx; |     AVCodecContext *enc = ost->enc_ctx; | ||||||
|     AVRational frame_rate; |     AVRational frame_rate; | ||||||
|     int64_t nb_frames, nb_frames_prev, i; |     int64_t nb_frames, nb_frames_prev, i; | ||||||
| @ -965,7 +1006,7 @@ static void do_video_out(OutputFile *of, | |||||||
|         nb_frames_drop++; |         nb_frames_drop++; | ||||||
|         av_log(ost, AV_LOG_VERBOSE, |         av_log(ost, AV_LOG_VERBOSE, | ||||||
|                "*** dropping frame %"PRId64" at ts %"PRId64"\n", |                "*** dropping frame %"PRId64" at ts %"PRId64"\n", | ||||||
|                ost->vsync_frame_number, ost->last_frame->pts); |                ost->vsync_frame_number, e->last_frame->pts); | ||||||
|     } |     } | ||||||
|     if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) { |     if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) { | ||||||
|         if (nb_frames > dts_error_threshold * 30) { |         if (nb_frames > dts_error_threshold * 30) { | ||||||
| @ -987,8 +1028,8 @@ static void do_video_out(OutputFile *of, | |||||||
|     for (i = 0; i < nb_frames; i++) { |     for (i = 0; i < nb_frames; i++) { | ||||||
|         AVFrame *in_picture; |         AVFrame *in_picture; | ||||||
| 
 | 
 | ||||||
|         if (i < nb_frames_prev && ost->last_frame->buf[0]) { |         if (i < nb_frames_prev && e->last_frame->buf[0]) { | ||||||
|             in_picture = ost->last_frame; |             in_picture = e->last_frame; | ||||||
|         } else |         } else | ||||||
|             in_picture = next_picture; |             in_picture = next_picture; | ||||||
| 
 | 
 | ||||||
| @ -1013,9 +1054,9 @@ static void do_video_out(OutputFile *of, | |||||||
|         ost->vsync_frame_number++; |         ost->vsync_frame_number++; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     av_frame_unref(ost->last_frame); |     av_frame_unref(e->last_frame); | ||||||
|     if (next_picture) |     if (next_picture) | ||||||
|         av_frame_move_ref(ost->last_frame, next_picture); |         av_frame_move_ref(e->last_frame, next_picture); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void enc_frame(OutputStream *ost, AVFrame *frame) | void enc_frame(OutputStream *ost, AVFrame *frame) | ||||||
|  | |||||||
| @ -643,6 +643,8 @@ static void ost_free(OutputStream **post) | |||||||
|         return; |         return; | ||||||
|     ms = ms_from_ost(ost); |     ms = ms_from_ost(ost); | ||||||
| 
 | 
 | ||||||
|  |     enc_free(&ost->enc); | ||||||
|  | 
 | ||||||
|     if (ost->logfile) { |     if (ost->logfile) { | ||||||
|         if (fclose(ost->logfile)) |         if (fclose(ost->logfile)) | ||||||
|             av_log(ms, AV_LOG_ERROR, |             av_log(ms, AV_LOG_ERROR, | ||||||
| @ -662,7 +664,6 @@ static void ost_free(OutputStream **post) | |||||||
| 
 | 
 | ||||||
|     av_frame_free(&ost->filtered_frame); |     av_frame_free(&ost->filtered_frame); | ||||||
|     av_frame_free(&ost->sq_frame); |     av_frame_free(&ost->sq_frame); | ||||||
|     av_frame_free(&ost->last_frame); |  | ||||||
|     av_packet_free(&ost->pkt); |     av_packet_free(&ost->pkt); | ||||||
|     av_dict_free(&ost->encoder_opts); |     av_dict_free(&ost->encoder_opts); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -462,6 +462,10 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o, | |||||||
|         if (!ost->enc_ctx) |         if (!ost->enc_ctx) | ||||||
|             report_and_exit(AVERROR(ENOMEM)); |             report_and_exit(AVERROR(ENOMEM)); | ||||||
| 
 | 
 | ||||||
|  |         ret = enc_alloc(&ost->enc, enc); | ||||||
|  |         if (ret < 0) | ||||||
|  |             report_and_exit(ret); | ||||||
|  | 
 | ||||||
|         av_strlcat(ms->log_name, "/",       sizeof(ms->log_name)); |         av_strlcat(ms->log_name, "/",       sizeof(ms->log_name)); | ||||||
|         av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name)); |         av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name)); | ||||||
|     } else { |     } else { | ||||||
| @ -933,10 +937,6 @@ static OutputStream *new_video_stream(Muxer *mux, const OptionsContext *o, Input | |||||||
|         ost->avfilter = get_ost_filters(o, oc, ost); |         ost->avfilter = get_ost_filters(o, oc, ost); | ||||||
|         if (!ost->avfilter) |         if (!ost->avfilter) | ||||||
|             exit_program(1); |             exit_program(1); | ||||||
| 
 |  | ||||||
|         ost->last_frame = av_frame_alloc(); |  | ||||||
|         if (!ost->last_frame) |  | ||||||
|             report_and_exit(AVERROR(ENOMEM)); |  | ||||||
|     } else |     } else | ||||||
|         check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO); |         check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user