diff mbox series

[FFmpeg-devel,02/13] fftools/ffmpeg_enc: add an AVClass to Encoder

Message ID 20240924071000.11428-2-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/13] doc/ffmpeg; improve wording in the description section | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov Sept. 24, 2024, 7:09 a.m. UTC
Log decoder messages to the encoder rather than OutputStream.

This is a step towards decoupling encoders from muxers, similarly to
what was previously done to decoders and demuxers.
---
 fftools/ffmpeg.h          |  2 +-
 fftools/ffmpeg_enc.c      | 62 +++++++++++++++++++++++++++------------
 fftools/ffmpeg_mux_init.c |  2 +-
 3 files changed, 45 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 733d551fa4..122372440f 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -858,7 +858,7 @@  int dec_request_view(Decoder *dec, const ViewSpecifier *vs,
                      SchedulerNode *src);
 
 int enc_alloc(Encoder **penc, const AVCodec *codec,
-              Scheduler *sch, unsigned sch_idx);
+              Scheduler *sch, unsigned sch_idx, void *log_parent);
 void enc_free(Encoder **penc);
 
 int enc_open(void *opaque, const AVFrame *frame);
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index c1c8aa0e78..2e1c7f27c1 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -39,6 +39,10 @@ 
 #include "libavcodec/avcodec.h"
 
 struct Encoder {
+    const AVClass *class;
+    void          *log_parent;
+    char           log_name[32];
+
     // combined size of all the packets received from the encoder
     uint64_t data_size;
 
@@ -68,8 +72,22 @@  void enc_free(Encoder **penc)
     av_freep(penc);
 }
 
+static const char *enc_item_name(void *obj)
+{
+    const Encoder *e = obj;
+
+    return e->log_name;
+}
+
+static const AVClass enc_class = {
+    .class_name                = "Encoder",
+    .version                   = LIBAVUTIL_VERSION_INT,
+    .parent_log_context_offset = offsetof(Encoder, log_parent),
+    .item_name                 = enc_item_name,
+};
+
 int enc_alloc(Encoder **penc, const AVCodec *codec,
-              Scheduler *sch, unsigned sch_idx)
+              Scheduler *sch, unsigned sch_idx, void *log_parent)
 {
     Encoder *enc;
 
@@ -79,9 +97,14 @@  int enc_alloc(Encoder **penc, const AVCodec *codec,
     if (!enc)
         return AVERROR(ENOMEM);
 
+    enc->class      = &enc_class;
+    enc->log_parent = log_parent;
+
     enc->sch     = sch;
     enc->sch_idx = sch_idx;
 
+    snprintf(enc->log_name, sizeof(enc->log_name), "enc:%s", codec->name);
+
     *penc = enc;
 
     return 0;
@@ -314,14 +337,14 @@  int enc_open(void *opaque, const AVFrame *frame)
 
     ret = hw_device_setup_for_encode(ost, frame ? frame->hw_frames_ctx : NULL);
     if (ret < 0) {
-        av_log(ost, AV_LOG_ERROR,
+        av_log(e, AV_LOG_ERROR,
                "Encoding hardware device setup failed: %s\n", av_err2str(ret));
         return ret;
     }
 
     if ((ret = avcodec_open2(ost->enc_ctx, enc, NULL)) < 0) {
         if (ret != AVERROR_EXPERIMENTAL)
-            av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe "
+            av_log(e, AV_LOG_ERROR, "Error while opening encoder - maybe "
                    "incorrect parameters such as bit_rate, rate, width or height.\n");
         return ret;
     }
@@ -333,12 +356,12 @@  int enc_open(void *opaque, const AVFrame *frame)
 
     if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 &&
         ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */)
-        av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low."
+        av_log(e, AV_LOG_WARNING, "The bitrate parameter is set too low."
                                     " It takes bits/s as argument, not kbits/s\n");
 
     ret = avcodec_parameters_from_context(ost->par_in, ost->enc_ctx);
     if (ret < 0) {
-        av_log(ost, AV_LOG_FATAL,
+        av_log(e, AV_LOG_FATAL,
                "Error initializing the output stream codec context.\n");
         return ret;
     }
@@ -375,7 +398,7 @@  static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *
     int64_t pts;
 
     if (sub->pts == AV_NOPTS_VALUE) {
-        av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
+        av_log(e, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
         return exit_on_error ? AVERROR(EINVAL) : 0;
     }
     if ((of->start_time != AV_NOPTS_VALUE && sub->pts < of->start_time))
@@ -424,7 +447,7 @@  static int do_subtitle_out(OutputFile *of, OutputStream *ost, const AVSubtitle *
 
         subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub);
         if (subtitle_out_size < 0) {
-            av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n");
+            av_log(e, AV_LOG_FATAL, "Subtitle encoding failed\n");
             return subtitle_out_size;
         }
 
@@ -619,7 +642,7 @@  static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
         ost->samples_encoded += frame->nb_samples;
 
         if (debug_ts) {
-            av_log(ost, AV_LOG_INFO, "encoder <- type:%s "
+            av_log(e, AV_LOG_INFO, "encoder <- type:%s "
                    "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
                    type_desc,
                    av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base),
@@ -634,7 +657,7 @@  static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
 
     ret = avcodec_send_frame(enc, frame);
     if (ret < 0 && !(ret == AVERROR_EOF && !frame)) {
-        av_log(ost, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n",
+        av_log(e, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n",
                type_desc);
         return ret;
     }
@@ -659,7 +682,7 @@  static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
             return 0;
         } else if (ret < 0) {
             if (ret != AVERROR_EOF)
-                av_log(ost, AV_LOG_ERROR, "%s encoding failed\n", type_desc);
+                av_log(e, AV_LOG_ERROR, "%s encoding failed\n", type_desc);
             return ret;
         }
 
@@ -693,7 +716,7 @@  static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
                             e->packets_encoded);
 
         if (debug_ts) {
-            av_log(ost, AV_LOG_INFO, "encoder -> type:%s "
+            av_log(e, AV_LOG_INFO, "encoder -> type:%s "
                    "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
                    "duration:%s duration_time:%s\n",
                    type_desc,
@@ -764,6 +787,7 @@  force_keyframe:
 
 static int frame_encode(OutputStream *ost, AVFrame *frame, AVPacket *pkt)
 {
+    Encoder *e = ost->enc;
     OutputFile *of = ost->file;
     enum AVMediaType type = ost->type;
 
@@ -782,7 +806,7 @@  static int frame_encode(OutputStream *ost, AVFrame *frame, AVPacket *pkt)
 
         if (type == AVMEDIA_TYPE_VIDEO) {
             frame->quality   = ost->enc_ctx->global_quality;
-            frame->pict_type = forced_kf_apply(ost, &ost->kf, frame);
+            frame->pict_type = forced_kf_apply(e, &ost->kf, frame);
 
 #if FFMPEG_OPT_TOP
             if (ost->top_field_first >= 0) {
@@ -793,7 +817,7 @@  static int frame_encode(OutputStream *ost, AVFrame *frame, AVPacket *pkt)
         } else {
             if (!(ost->enc_ctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) &&
                 ost->enc_ctx->ch_layout.nb_channels != frame->ch_layout.nb_channels) {
-                av_log(ost, AV_LOG_ERROR,
+                av_log(e, AV_LOG_ERROR,
                        "Audio channel count changed and encoder does not support parameter changes\n");
                 return 0;
             }
@@ -867,14 +891,14 @@  int encoder_thread(void *arg)
         input_status = sch_enc_receive(e->sch, e->sch_idx, et.frame);
         if (input_status < 0) {
             if (input_status == AVERROR_EOF) {
-                av_log(ost, AV_LOG_VERBOSE, "Encoder thread received EOF\n");
+                av_log(e, AV_LOG_VERBOSE, "Encoder thread received EOF\n");
                 if (e->opened)
                     break;
 
-                av_log(ost, AV_LOG_ERROR, "Could not open encoder before EOF\n");
+                av_log(e, AV_LOG_ERROR, "Could not open encoder before EOF\n");
                 ret = AVERROR(EINVAL);
             } else {
-                av_log(ost, AV_LOG_ERROR, "Error receiving a frame for encoding: %s\n",
+                av_log(e, AV_LOG_ERROR, "Error receiving a frame for encoding: %s\n",
                        av_err2str(ret));
                 ret = input_status;
             }
@@ -893,9 +917,9 @@  int encoder_thread(void *arg)
 
         if (ret < 0) {
             if (ret == AVERROR_EOF)
-                av_log(ost, AV_LOG_VERBOSE, "Encoder returned EOF, finishing\n");
+                av_log(e, AV_LOG_VERBOSE, "Encoder returned EOF, finishing\n");
             else
-                av_log(ost, AV_LOG_ERROR, "Error encoding a frame: %s\n",
+                av_log(e, AV_LOG_ERROR, "Error encoding a frame: %s\n",
                        av_err2str(ret));
             break;
         }
@@ -905,7 +929,7 @@  int encoder_thread(void *arg)
     if (ret == 0 || ret == AVERROR_EOF) {
         ret = frame_encode(ost, NULL, et.pkt);
         if (ret < 0 && ret != AVERROR_EOF)
-            av_log(ost, AV_LOG_ERROR, "Error flushing encoder: %s\n",
+            av_log(e, AV_LOG_ERROR, "Error flushing encoder: %s\n",
                    av_err2str(ret));
     }
 
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 8afb018de8..1b75430e4e 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -1227,7 +1227,7 @@  static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
             return ret;
         ms->sch_idx_enc = ret;
 
-        ret = enc_alloc(&ost->enc, enc, mux->sch, ms->sch_idx_enc);
+        ret = enc_alloc(&ost->enc, enc, mux->sch, ms->sch_idx_enc, ost);
         if (ret < 0)
             return ret;