1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-13 21:28:01 +02:00

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

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

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)

View File

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

View File

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