[FFmpeg-cvslog] fftools/ffmpeg: add encoder private data
Anton Khirnov
git at videolan.org
Sun Apr 9 16:50:41 EEST 2023
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Mar 25 19:46:28 2023 +0100| [f30b620e98ca35eb669fae4fbe4911b779c8413d] | committer: Anton Khirnov
fftools/ffmpeg: add encoder private data
Start by moving OutputStream.last_frame to it. In the future it will
hold other encoder-internal state.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f30b620e98ca35eb669fae4fbe4911b779c8413d
---
fftools/ffmpeg.h | 7 ++++++-
fftools/ffmpeg_enc.c | 51 ++++++++++++++++++++++++++++++++++++++++++-----
fftools/ffmpeg_mux.c | 3 ++-
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);
More information about the ffmpeg-cvslog
mailing list