diff options
author | Anton Khirnov <anton@khirnov.net> | 2023-03-25 19:46:28 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2023-04-09 15:47:45 +0200 |
commit | f30b620e98ca35eb669fae4fbe4911b779c8413d (patch) | |
tree | 715d62bfbd8f8c8d14397426958d18c574916ba3 /fftools | |
parent | 44accfef41d6c9711f2ad62b91bcaf0f0f935030 (diff) | |
download | ffmpeg-f30b620e98ca35eb669fae4fbe4911b779c8413d.tar.gz |
fftools/ffmpeg: add encoder private data
Start by moving OutputStream.last_frame to it. In the future it will
hold other encoder-internal state.
Diffstat (limited to 'fftools')
-rw-r--r-- | fftools/ffmpeg.h | 7 | ||||
-rw-r--r-- | fftools/ffmpeg_enc.c | 51 | ||||
-rw-r--r-- | fftools/ffmpeg_mux.c | 3 | ||||
-rw-r--r-- | fftools/ffmpeg_mux_init.c | 8 |
4 files changed, 58 insertions, 11 deletions
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index c30659176e..8193dabb57 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -557,6 +557,8 @@ typedef struct KeyframeForceCtx { int dropped_keyframe; } KeyframeForceCtx; +typedef struct Encoder Encoder; + typedef struct OutputStream { const AVClass *class; @@ -588,9 +590,9 @@ typedef struct OutputStream { AVRational mux_timebase; AVRational enc_timebase; + Encoder *enc; AVCodecContext *enc_ctx; AVFrame *filtered_frame; - AVFrame *last_frame; AVFrame *sq_frame; AVPacket *pkt; int64_t last_dropped; @@ -824,6 +826,9 @@ AVBufferRef *hw_device_for_filter(void); 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); void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub); void enc_frame(OutputStream *ost, AVFrame *frame); diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index c0e3eaa1e8..1387e05cf6 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -43,8 +43,48 @@ #include "libavformat/avformat.h" +struct Encoder { + AVFrame *last_frame; +}; + 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) { const char *cname = ost->enc_ctx->codec->name; @@ -919,6 +959,7 @@ static void do_video_out(OutputFile *of, AVFrame *next_picture) { int ret; + Encoder *e = ost->enc; AVCodecContext *enc = ost->enc_ctx; AVRational frame_rate; int64_t nb_frames, nb_frames_prev, i; @@ -965,7 +1006,7 @@ static void do_video_out(OutputFile *of, nb_frames_drop++; av_log(ost, AV_LOG_VERBOSE, "*** 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 > dts_error_threshold * 30) { @@ -987,8 +1028,8 @@ static void do_video_out(OutputFile *of, for (i = 0; i < nb_frames; i++) { AVFrame *in_picture; - if (i < nb_frames_prev && ost->last_frame->buf[0]) { - in_picture = ost->last_frame; + if (i < nb_frames_prev && e->last_frame->buf[0]) { + in_picture = e->last_frame; } else in_picture = next_picture; @@ -1013,9 +1054,9 @@ static void do_video_out(OutputFile *of, ost->vsync_frame_number++; } - av_frame_unref(ost->last_frame); + av_frame_unref(e->last_frame); 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) diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 1937bc2aa7..527567831f 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -643,6 +643,8 @@ static void ost_free(OutputStream **post) return; ms = ms_from_ost(ost); + enc_free(&ost->enc); + if (ost->logfile) { if (fclose(ost->logfile)) 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->sq_frame); - av_frame_free(&ost->last_frame); av_packet_free(&ost->pkt); av_dict_free(&ost->encoder_opts); diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 2e9bdcfde1..6c53a8810d 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -462,6 +462,10 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o, if (!ost->enc_ctx) 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, enc->name, sizeof(ms->log_name)); } else { @@ -933,10 +937,6 @@ static OutputStream *new_video_stream(Muxer *mux, const OptionsContext *o, Input ost->avfilter = get_ost_filters(o, oc, ost); if (!ost->avfilter) exit_program(1); - - ost->last_frame = av_frame_alloc(); - if (!ost->last_frame) - report_and_exit(AVERROR(ENOMEM)); } else check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO); |