mirror of https://git.ffmpeg.org/ffmpeg.git
fftools/ffmpeg_enc: split Encoder into a private and public part
Similar to what was previously done for other components, e.g. decoders
(see 3b84140a1b
).
Start by moving {samples,frames}_encoded into the public struct.
This commit is contained in:
parent
f295b4d8a0
commit
434377a764
|
@ -569,7 +569,13 @@ typedef struct KeyframeForceCtx {
|
|||
int dropped_keyframe;
|
||||
} KeyframeForceCtx;
|
||||
|
||||
typedef struct Encoder Encoder;
|
||||
typedef struct Encoder {
|
||||
const AVClass *class;
|
||||
|
||||
// number of frames/samples sent to the encoder
|
||||
uint64_t frames_encoded;
|
||||
uint64_t samples_encoded;
|
||||
} Encoder;
|
||||
|
||||
enum CroppingType {
|
||||
CROP_DISABLED = 0,
|
||||
|
@ -621,9 +627,6 @@ typedef struct OutputStream {
|
|||
/* stats */
|
||||
// number of packets send to the muxer
|
||||
atomic_uint_least64_t packets_written;
|
||||
// number of frames/samples sent to the encoder
|
||||
uint64_t frames_encoded;
|
||||
uint64_t samples_encoded;
|
||||
|
||||
/* packet quality factor */
|
||||
atomic_int quality;
|
||||
|
|
|
@ -38,8 +38,9 @@
|
|||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
struct Encoder {
|
||||
const AVClass *class;
|
||||
typedef struct EncoderPriv {
|
||||
Encoder e;
|
||||
|
||||
void *log_parent;
|
||||
char log_name[32];
|
||||
|
||||
|
@ -54,7 +55,12 @@ struct Encoder {
|
|||
|
||||
Scheduler *sch;
|
||||
unsigned sch_idx;
|
||||
};
|
||||
} EncoderPriv;
|
||||
|
||||
static EncoderPriv *ep_from_enc(Encoder *enc)
|
||||
{
|
||||
return (EncoderPriv*)enc;
|
||||
}
|
||||
|
||||
// data that is local to the decoder thread and not visible outside of it
|
||||
typedef struct EncoderThread {
|
||||
|
@ -74,38 +80,38 @@ void enc_free(Encoder **penc)
|
|||
|
||||
static const char *enc_item_name(void *obj)
|
||||
{
|
||||
const Encoder *e = obj;
|
||||
const EncoderPriv *ep = obj;
|
||||
|
||||
return e->log_name;
|
||||
return ep->log_name;
|
||||
}
|
||||
|
||||
static const AVClass enc_class = {
|
||||
.class_name = "Encoder",
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.parent_log_context_offset = offsetof(Encoder, log_parent),
|
||||
.parent_log_context_offset = offsetof(EncoderPriv, log_parent),
|
||||
.item_name = enc_item_name,
|
||||
};
|
||||
|
||||
int enc_alloc(Encoder **penc, const AVCodec *codec,
|
||||
Scheduler *sch, unsigned sch_idx, void *log_parent)
|
||||
{
|
||||
Encoder *enc;
|
||||
EncoderPriv *ep;
|
||||
|
||||
*penc = NULL;
|
||||
|
||||
enc = av_mallocz(sizeof(*enc));
|
||||
if (!enc)
|
||||
ep = av_mallocz(sizeof(*ep));
|
||||
if (!ep)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
enc->class = &enc_class;
|
||||
enc->log_parent = log_parent;
|
||||
ep->e.class = &enc_class;
|
||||
ep->log_parent = log_parent;
|
||||
|
||||
enc->sch = sch;
|
||||
enc->sch_idx = sch_idx;
|
||||
ep->sch = sch;
|
||||
ep->sch_idx = sch_idx;
|
||||
|
||||
snprintf(enc->log_name, sizeof(enc->log_name), "enc:%s", codec->name);
|
||||
snprintf(ep->log_name, sizeof(ep->log_name), "enc:%s", codec->name);
|
||||
|
||||
*penc = enc;
|
||||
*penc = &ep->e;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -166,6 +172,7 @@ int enc_open(void *opaque, const AVFrame *frame)
|
|||
OutputStream *ost = opaque;
|
||||
InputStream *ist = ost->ist;
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(e);
|
||||
AVCodecContext *enc_ctx = ost->enc_ctx;
|
||||
Decoder *dec = NULL;
|
||||
const AVCodec *enc = enc_ctx->codec;
|
||||
|
@ -174,7 +181,7 @@ int enc_open(void *opaque, const AVFrame *frame)
|
|||
int frame_samples = 0;
|
||||
int ret;
|
||||
|
||||
if (e->opened)
|
||||
if (ep->opened)
|
||||
return 0;
|
||||
|
||||
// frame is always non-NULL for audio and video
|
||||
|
@ -320,7 +327,7 @@ int enc_open(void *opaque, const AVFrame *frame)
|
|||
return ret;
|
||||
}
|
||||
|
||||
e->opened = 1;
|
||||
ep->opened = 1;
|
||||
|
||||
if (enc_ctx->frame_size)
|
||||
frame_samples = enc_ctx->frame_size;
|
||||
|
@ -352,6 +359,7 @@ static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *
|
|||
AVPacket *pkt)
|
||||
{
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(e);
|
||||
int subtitle_out_max_size = 1024 * 1024;
|
||||
int subtitle_out_size, nb, i, ret;
|
||||
AVCodecContext *enc;
|
||||
|
@ -403,7 +411,7 @@ static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *
|
|||
local_sub.rects += i;
|
||||
}
|
||||
|
||||
ost->frames_encoded++;
|
||||
e->frames_encoded++;
|
||||
|
||||
subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub);
|
||||
if (subtitle_out_size < 0) {
|
||||
|
@ -425,7 +433,7 @@ static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *
|
|||
}
|
||||
pkt->dts = pkt->pts;
|
||||
|
||||
ret = sch_enc_send(e->sch, e->sch_idx, pkt);
|
||||
ret = sch_enc_send(ep->sch, ep->sch_idx, pkt);
|
||||
if (ret < 0) {
|
||||
av_packet_unref(pkt);
|
||||
return ret;
|
||||
|
@ -440,6 +448,7 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
|
|||
uint64_t frame_num)
|
||||
{
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(e);
|
||||
AVIOContext *io = es->io;
|
||||
AVRational tb = frame ? frame->time_base : pkt->time_base;
|
||||
int64_t pts = frame ? frame->pts : pkt->pts;
|
||||
|
@ -477,7 +486,7 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
|
|||
|
||||
if (frame) {
|
||||
switch (c->type) {
|
||||
case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, ost->samples_encoded); continue;
|
||||
case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, e->samples_encoded); continue;
|
||||
case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
|
@ -495,7 +504,7 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
|
|||
}
|
||||
case ENC_STATS_AVG_BITRATE: {
|
||||
double duration = pkt->dts * av_q2d(tb);
|
||||
avio_printf(io, "%g", duration > 0 ? 8.0 * e->data_size / duration : -1.);
|
||||
avio_printf(io, "%g", duration > 0 ? 8.0 * ep->data_size / duration : -1.);
|
||||
continue;
|
||||
}
|
||||
default: av_assert0(0);
|
||||
|
@ -515,7 +524,7 @@ static inline double psnr(double d)
|
|||
|
||||
static int update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats)
|
||||
{
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(ost->enc);
|
||||
const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
|
||||
NULL);
|
||||
AVCodecContext *enc = ost->enc_ctx;
|
||||
|
@ -549,7 +558,7 @@ static int update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_
|
|||
}
|
||||
}
|
||||
|
||||
frame_number = e->packets_encoded;
|
||||
frame_number = ep->packets_encoded;
|
||||
if (vstats_version <= 1) {
|
||||
fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number,
|
||||
quality / (float)FF_QP2LAMBDA);
|
||||
|
@ -569,9 +578,9 @@ static int update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_
|
|||
ti1 = 0.01;
|
||||
|
||||
bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0;
|
||||
avg_bitrate = (double)(e->data_size * 8) / ti1 / 1000.0;
|
||||
avg_bitrate = (double)(ep->data_size * 8) / ti1 / 1000.0;
|
||||
fprintf(vstats_file, "s_size= %8.0fKiB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
|
||||
(double)e->data_size / 1024, ti1, bitrate, avg_bitrate);
|
||||
(double)ep->data_size / 1024, ti1, bitrate, avg_bitrate);
|
||||
fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(pict_type));
|
||||
|
||||
return 0;
|
||||
|
@ -581,6 +590,7 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
|||
AVPacket *pkt)
|
||||
{
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(e);
|
||||
AVCodecContext *enc = ost->enc_ctx;
|
||||
const char *type_desc = av_get_media_type_string(enc->codec_type);
|
||||
const char *action = frame ? "encode" : "flush";
|
||||
|
@ -596,10 +606,10 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
|||
|
||||
if (ost->enc_stats_pre.io)
|
||||
enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL,
|
||||
ost->frames_encoded);
|
||||
e->frames_encoded);
|
||||
|
||||
ost->frames_encoded++;
|
||||
ost->samples_encoded += frame->nb_samples;
|
||||
e->frames_encoded++;
|
||||
e->samples_encoded += frame->nb_samples;
|
||||
|
||||
if (debug_ts) {
|
||||
av_log(e, AV_LOG_INFO, "encoder <- type:%s "
|
||||
|
@ -653,7 +663,7 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
|||
|
||||
// attach stream parameters to first packet if requested
|
||||
avcodec_parameters_free(&fd->par_enc);
|
||||
if (e->attach_par && !e->packets_encoded) {
|
||||
if (ep->attach_par && !ep->packets_encoded) {
|
||||
fd->par_enc = avcodec_parameters_alloc();
|
||||
if (!fd->par_enc)
|
||||
return AVERROR(ENOMEM);
|
||||
|
@ -673,7 +683,7 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
|||
|
||||
if (ost->enc_stats_post.io)
|
||||
enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt,
|
||||
e->packets_encoded);
|
||||
ep->packets_encoded);
|
||||
|
||||
if (debug_ts) {
|
||||
av_log(e, AV_LOG_INFO, "encoder -> type:%s "
|
||||
|
@ -685,11 +695,11 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
|||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
|
||||
}
|
||||
|
||||
e->data_size += pkt->size;
|
||||
ep->data_size += pkt->size;
|
||||
|
||||
e->packets_encoded++;
|
||||
ep->packets_encoded++;
|
||||
|
||||
ret = sch_enc_send(e->sch, e->sch_idx, pkt);
|
||||
ret = sch_enc_send(ep->sch, ep->sch_idx, pkt);
|
||||
if (ret < 0) {
|
||||
av_packet_unref(pkt);
|
||||
return ret;
|
||||
|
@ -826,6 +836,7 @@ int encoder_thread(void *arg)
|
|||
{
|
||||
OutputStream *ost = arg;
|
||||
Encoder *e = ost->enc;
|
||||
EncoderPriv *ep = ep_from_enc(e);
|
||||
EncoderThread et;
|
||||
int ret = 0, input_status = 0;
|
||||
int name_set = 0;
|
||||
|
@ -848,11 +859,11 @@ int encoder_thread(void *arg)
|
|||
}
|
||||
|
||||
while (!input_status) {
|
||||
input_status = sch_enc_receive(e->sch, e->sch_idx, et.frame);
|
||||
input_status = sch_enc_receive(ep->sch, ep->sch_idx, et.frame);
|
||||
if (input_status < 0) {
|
||||
if (input_status == AVERROR_EOF) {
|
||||
av_log(e, AV_LOG_VERBOSE, "Encoder thread received EOF\n");
|
||||
if (e->opened)
|
||||
if (ep->opened)
|
||||
break;
|
||||
|
||||
av_log(e, AV_LOG_ERROR, "Could not open encoder before EOF\n");
|
||||
|
@ -905,6 +916,7 @@ finish:
|
|||
|
||||
int enc_loopback(Encoder *enc)
|
||||
{
|
||||
enc->attach_par = 1;
|
||||
return enc->sch_idx;
|
||||
EncoderPriv *ep = ep_from_enc(enc);
|
||||
ep->attach_par = 1;
|
||||
return ep->sch_idx;
|
||||
}
|
||||
|
|
|
@ -723,9 +723,9 @@ static void mux_final_stats(Muxer *mux)
|
|||
of->index, j, av_get_media_type_string(type));
|
||||
if (ost->enc) {
|
||||
av_log(of, AV_LOG_VERBOSE, "%"PRIu64" frames encoded",
|
||||
ost->frames_encoded);
|
||||
ost->enc->frames_encoded);
|
||||
if (type == AVMEDIA_TYPE_AUDIO)
|
||||
av_log(of, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ost->samples_encoded);
|
||||
av_log(of, AV_LOG_VERBOSE, " (%"PRIu64" samples)", ost->enc->samples_encoded);
|
||||
av_log(of, AV_LOG_VERBOSE, "; ");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue