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:
Anton Khirnov
2023-03-25 19:46:28 +01:00
parent 44accfef41
commit f30b620e98
4 changed files with 58 additions and 11 deletions

View File

@@ -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)