PR #23395 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23395
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23395.patch


>From ada9dfcd7a8a923d483c35f65b1bbe00e58d6f9b Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Sun, 7 Jun 2026 10:54:40 -0300
Subject: [PATCH 1/2] avcodec/lcevcdec: don't inherit the parent decoder
 logging context

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/decode.c   |  6 +++---
 libavcodec/lcevcdec.c | 50 ++++++++++++++++++++++++++-----------------
 libavcodec/lcevcdec.h |  7 ++++--
 3 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 81659435a0..92b613f5c0 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1639,7 +1639,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame 
*frame)
 
     if (dc->lcevc.frame) {
         ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame, &dc->lcevc.format,
-                                       &dc->lcevc.width, &dc->lcevc.height, 
avctx);
+                                   &dc->lcevc.width, &dc->lcevc.height);
         if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
             return ret;
 
@@ -1716,7 +1716,7 @@ int ff_attach_decode_data(AVCodecContext *avctx, AVFrame 
*frame)
 
         if (dc->lcevc.frame) {
             int ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame, 
&dc->lcevc.format,
-                                           &dc->lcevc.width, 
&dc->lcevc.height, avctx);
+                                           &dc->lcevc.width, 
&dc->lcevc.height);
             if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
 
@@ -2140,7 +2140,7 @@ av_cold int ff_decode_preinit(AVCodecContext *avctx)
     if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) {
         if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
 #if CONFIG_LIBLCEVC_DEC
-            ret = ff_lcevc_alloc(&dc->lcevc.ctx, avctx);
+            ret = ff_lcevc_alloc(&dc->lcevc.ctx);
             if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
 #endif
diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c
index 722da8cdaf..ae07024fe5 100644
--- a/libavcodec/lcevcdec.c
+++ b/libavcodec/lcevcdec.c
@@ -74,7 +74,7 @@ static LCEVC_ColorFormat map_format(int format)
     return LCEVC_ColorFormat_Unknown;
 }
 
-static int alloc_base_frame(void *logctx, FFLCEVCContext *lcevc,
+static int alloc_base_frame(FFLCEVCContext *lcevc,
                             const AVFrame *frame, LCEVC_PictureHandle *picture)
 {
     LCEVC_PictureDesc desc;
@@ -109,7 +109,7 @@ static int alloc_base_frame(void *logctx, FFLCEVCContext 
*lcevc,
     return 0;
 }
 
-static int alloc_enhanced_frame(void *logctx, FFLCEVCFrame *frame_ctx,
+static int alloc_enhanced_frame(FFLCEVCFrame *frame_ctx,
                                 LCEVC_PictureHandle *picture)
 {
     FFLCEVCContext *lcevc = frame_ctx->lcevc;
@@ -136,7 +136,7 @@ static int alloc_enhanced_frame(void *logctx, FFLCEVCFrame 
*frame_ctx,
     return 0;
 }
 
-static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const 
AVFrame *in)
+static int lcevc_send_frame(FFLCEVCFrame *frame_ctx, const AVFrame *in)
 {
     FFLCEVCContext *lcevc = frame_ctx->lcevc;
     LCEVC_ColorFormat fmt = map_format(in->format);
@@ -153,7 +153,7 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame 
*frame_ctx, const AVFrame
     if (res != LCEVC_Success)
         return AVERROR_EXTERNAL;
 
-    ret = alloc_base_frame(logctx, lcevc, in, &picture);
+    ret = alloc_base_frame(lcevc, in, &picture);
     if (ret < 0)
         return ret;
 
@@ -178,7 +178,7 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame 
*frame_ctx, const AVFrame
     }
 
     memset(&picture, 0, sizeof(picture));
-    ret = alloc_enhanced_frame(logctx, frame_ctx, &picture);
+    ret = alloc_enhanced_frame(frame_ctx, &picture);
     if (ret < 0)
         return ret;
 
@@ -191,7 +191,7 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame 
*frame_ctx, const AVFrame
     return 0;
 }
 
-static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out)
+static int generate_output(FFLCEVCFrame *frame_ctx, AVFrame *out)
 {
     FFLCEVCContext *lcevc = frame_ctx->lcevc;
     LCEVC_PictureDesc desc;
@@ -224,7 +224,7 @@ static int generate_output(void *logctx, FFLCEVCFrame 
*frame_ctx, AVFrame *out)
     out->width = desc.width + out->crop_left + out->crop_right;
     out->height = desc.height + out->crop_top + out->crop_bottom;
 
-    av_log(logctx, AV_LOG_DEBUG, "out PTS %"PRId64", %dx%d, "
+    av_log(lcevc, AV_LOG_DEBUG,  "out PTS %"PRId64", %dx%d, "
                                  "%zu/%zu/%zu/%zu, "
                                  "SAR %d:%d, "
                                  "hasEnhancement %d, enhanced %d\n",
@@ -265,12 +265,12 @@ static int lcevc_flush_pictures(FFLCEVCContext *lcevc)
     return 0;
 }
 
-static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame 
*out)
+static int lcevc_receive_frame(FFLCEVCFrame *frame_ctx, AVFrame *out)
 {
     FFLCEVCContext *lcevc = frame_ctx->lcevc;
     int ret;
 
-    ret = generate_output(logctx, frame_ctx, out);
+    ret = generate_output(frame_ctx, out);
     if (ret < 0)
         return ret;
 
@@ -331,22 +331,22 @@ static av_cold void 
lcevc_frame_free_entry_cb(AVRefStructOpaque unused, void *ob
     av_frame_free(&frame->frame);
 }
 
-static int lcevc_init(FFLCEVCContext *lcevc, void *logctx)
+static int lcevc_init(FFLCEVCContext *lcevc)
 {
     LCEVC_AccelContextHandle dummy = { 0 };
     const int32_t event = LCEVC_Log;
 
     if (LCEVC_CreateDecoder(&lcevc->decoder, dummy) != LCEVC_Success) {
-        av_log(logctx, AV_LOG_ERROR, "Failed to create LCEVC decoder\n");
+        av_log(lcevc, AV_LOG_ERROR, "Failed to create LCEVC decoder\n");
         return AVERROR_EXTERNAL;
     }
 
     LCEVC_ConfigureDecoderInt(lcevc->decoder, "log_level", 4);
     LCEVC_ConfigureDecoderIntArray(lcevc->decoder, "events", 1, &event);
-    LCEVC_SetDecoderEventCallback(lcevc->decoder, event_callback, logctx);
+    LCEVC_SetDecoderEventCallback(lcevc->decoder, event_callback, lcevc);
 
     if (LCEVC_InitializeDecoder(lcevc->decoder) != LCEVC_Success) {
-        av_log(logctx, AV_LOG_ERROR, "Failed to initialize LCEVC decoder\n");
+        av_log(lcevc, AV_LOG_ERROR, "Failed to initialize LCEVC decoder\n");
         LCEVC_DestroyDecoder(lcevc->decoder);
         return AVERROR_EXTERNAL;
     }
@@ -364,7 +364,7 @@ int ff_lcevc_process(void *logctx, AVFrame *frame)
     int ret;
 
     if (!lcevc->initialized) {
-        ret = lcevc_init(lcevc, logctx);
+        ret = lcevc_init(lcevc);
         if (ret < 0)
             return ret;
     }
@@ -372,11 +372,11 @@ int ff_lcevc_process(void *logctx, AVFrame *frame)
     av_assert0(frame_ctx->frame);
 
 
-    ret = lcevc_send_frame(logctx, frame_ctx, frame);
+    ret = lcevc_send_frame(frame_ctx, frame);
     if (ret)
         return ret < 0 ? ret : 0;
 
-    ret = lcevc_receive_frame(logctx, frame_ctx, frame);
+    ret = lcevc_receive_frame(frame_ctx, frame);
     if (ret < 0)
         return ret;
 
@@ -386,7 +386,7 @@ int ff_lcevc_process(void *logctx, AVFrame *frame)
 }
 
 int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const AVFrame *frame,
-                         enum AVPixelFormat *format, int *width, int *height, 
void *logctx)
+                         enum AVPixelFormat *format, int *width, int *height)
 {
     LCEVCRawProcessBlock *block = NULL;
     const LCEVCRawGlobalConfig *gc;
@@ -395,7 +395,7 @@ int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const 
AVFrame *frame,
 
     ret = ff_cbs_read(lcevc->cbc, lcevc->frag, NULL, sd->data, sd->size);
     if (ret < 0) {
-        av_log(logctx, AV_LOG_ERROR, "Failed to parse Access Unit.\n");
+        av_log(lcevc, AV_LOG_ERROR, "Failed to parse Access Unit.\n");
         goto end;
     }
 
@@ -429,7 +429,15 @@ static const CodedBitstreamUnitType decompose_unit_types[] 
= {
     LCEVC_NON_IDR_NUT,
 };
 
-int ff_lcevc_alloc(FFLCEVCContext **plcevc, void *logctx)
+
+static const AVClass lcevcdec_context_class = {
+    .class_name     = "liblcevc_dec",
+    .item_name      = av_default_item_name,
+    .version        = LIBAVUTIL_VERSION_INT,
+    .category       = AV_CLASS_CATEGORY_DECODER,
+};
+
+int ff_lcevc_alloc(FFLCEVCContext **plcevc)
 {
     FFLCEVCContext *lcevc = NULL;
     int ret;
@@ -444,7 +452,7 @@ int ff_lcevc_alloc(FFLCEVCContext **plcevc, void *logctx)
         goto fail;
     }
 
-    ret = ff_cbs_init(&lcevc->cbc, AV_CODEC_ID_LCEVC, logctx);
+    ret = ff_cbs_init(&lcevc->cbc, AV_CODEC_ID_LCEVC, lcevc);
     if (ret < 0)
         goto fail;
 
@@ -460,6 +468,8 @@ int ff_lcevc_alloc(FFLCEVCContext **plcevc, void *logctx)
         goto fail;
     }
 
+    lcevc->class = &lcevcdec_context_class;
+
     *plcevc = lcevc;
     return 0;
 fail:
diff --git a/libavcodec/lcevcdec.h b/libavcodec/lcevcdec.h
index 3120f423d1..4b15cbb4aa 100644
--- a/libavcodec/lcevcdec.h
+++ b/libavcodec/lcevcdec.h
@@ -21,6 +21,8 @@
 
 #include "config.h"
 
+#include "libavutil/log.h"
+
 #include <stdint.h>
 #if CONFIG_LIBLCEVC_DEC
 #include <LCEVC/lcevc_dec.h>
@@ -32,6 +34,7 @@ struct CodedBitstreamContext;
 struct CodedBitstreamFragment;
 
 typedef struct FFLCEVCContext {
+    const AVClass *class;
     LCEVC_DecoderHandle decoder;
     struct CodedBitstreamContext *cbc;
     struct CodedBitstreamFragment *frag;
@@ -46,9 +49,9 @@ typedef struct FFLCEVCFrame {
     struct AVFrame *frame;
 } FFLCEVCFrame;
 
-int ff_lcevc_alloc(FFLCEVCContext **plcevc, void *logctx);
+int ff_lcevc_alloc(FFLCEVCContext **plcevc);
 int ff_lcevc_process(void *logctx, struct AVFrame *frame);
 int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const struct AVFrame *frame,
-                         enum AVPixelFormat *format, int *width, int *height, 
void *logctx);
+                         enum AVPixelFormat *format, int *width, int *height);
 
 #endif /* AVCODEC_LCEVCDEC_H */
-- 
2.52.0


>From 79962e0241d617a59d4f246d1258cda542b8a7f0 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Sun, 7 Jun 2026 12:04:07 -0300
Subject: [PATCH 2/2] avcodec/lcevcdec: respect log level from the external
 library

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/decode.c   |  2 +-
 libavcodec/lcevcdec.c | 37 ++++++++++++++++++++++++++++++++-----
 libavcodec/lcevcdec.h |  3 ++-
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 92b613f5c0..4c03f522de 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -2140,7 +2140,7 @@ av_cold int ff_decode_preinit(AVCodecContext *avctx)
     if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) {
         if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
 #if CONFIG_LIBLCEVC_DEC
-            ret = ff_lcevc_alloc(&dc->lcevc.ctx);
+            ret = ff_lcevc_alloc(&dc->lcevc.ctx, av_log_get_level());
             if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
 #endif
diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c
index ae07024fe5..fecf68e39d 100644
--- a/libavcodec/lcevcdec.c
+++ b/libavcodec/lcevcdec.c
@@ -277,14 +277,27 @@ static int lcevc_receive_frame(FFLCEVCFrame *frame_ctx, 
AVFrame *out)
     return lcevc_flush_pictures(lcevc);
 }
 
+static const uint8_t level_map[LCEVC_LogLevelCount] = {
+    [LCEVC_LogFatal]   = AV_LOG_FATAL,
+    [LCEVC_LogError]   = AV_LOG_ERROR,
+    [LCEVC_LogWarning] = AV_LOG_WARNING,
+    [LCEVC_LogInfo]    = AV_LOG_INFO,
+    [LCEVC_LogDebug]   = AV_LOG_DEBUG,
+    [LCEVC_LogTrace]   = AV_LOG_TRACE,
+};
+
 static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event,
     LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info,
     const uint8_t *data, uint32_t size, void *logctx)
 {
     switch (event) {
-    case LCEVC_Log:
-        av_log(logctx, AV_LOG_INFO, "%s\n", data);
-        break;
+    case LCEVC_Log: {
+        int ret, level = 0;
+        ret = sscanf(data, "%d ", &level);
+        if (ret != 1 || !level || level >= LCEVC_LogLevelCount)
+            break;
+        av_log(logctx, level_map[level], "%s\n", data);
+    }
     default:
         break;
     }
@@ -335,13 +348,26 @@ static int lcevc_init(FFLCEVCContext *lcevc)
 {
     LCEVC_AccelContextHandle dummy = { 0 };
     const int32_t event = LCEVC_Log;
+    int level;
 
     if (LCEVC_CreateDecoder(&lcevc->decoder, dummy) != LCEVC_Success) {
         av_log(lcevc, AV_LOG_ERROR, "Failed to create LCEVC decoder\n");
         return AVERROR_EXTERNAL;
     }
 
-    LCEVC_ConfigureDecoderInt(lcevc->decoder, "log_level", 4);
+    switch (lcevc->loglevel) {
+    case AV_LOG_PANIC:
+    case AV_LOG_FATAL:   level = LCEVC_LogFatal; break;
+    case AV_LOG_ERROR:   level = LCEVC_LogError; break;
+    case AV_LOG_WARNING: level = LCEVC_LogWarning; break;
+    case AV_LOG_VERBOSE:
+    case AV_LOG_INFO:    level = LCEVC_LogInfo; break;
+    case AV_LOG_DEBUG:   level = LCEVC_LogDebug; break;
+    case AV_LOG_TRACE:   level = LCEVC_LogTrace; break;
+    default:             level = LCEVC_LogDisabled; break;
+    }
+
+    LCEVC_ConfigureDecoderInt(lcevc->decoder, "log_level", level);
     LCEVC_ConfigureDecoderIntArray(lcevc->decoder, "events", 1, &event);
     LCEVC_SetDecoderEventCallback(lcevc->decoder, event_callback, lcevc);
 
@@ -437,7 +463,7 @@ static const AVClass lcevcdec_context_class = {
     .category       = AV_CLASS_CATEGORY_DECODER,
 };
 
-int ff_lcevc_alloc(FFLCEVCContext **plcevc)
+int ff_lcevc_alloc(FFLCEVCContext **plcevc, int loglevel)
 {
     FFLCEVCContext *lcevc = NULL;
     int ret;
@@ -469,6 +495,7 @@ int ff_lcevc_alloc(FFLCEVCContext **plcevc)
     }
 
     lcevc->class = &lcevcdec_context_class;
+    lcevc->loglevel = loglevel;
 
     *plcevc = lcevc;
     return 0;
diff --git a/libavcodec/lcevcdec.h b/libavcodec/lcevcdec.h
index 4b15cbb4aa..e51d3de989 100644
--- a/libavcodec/lcevcdec.h
+++ b/libavcodec/lcevcdec.h
@@ -39,6 +39,7 @@ typedef struct FFLCEVCContext {
     struct CodedBitstreamContext *cbc;
     struct CodedBitstreamFragment *frag;
     struct AVRefStructPool *frame_pool; ///< pool of FFLCEVCFrame
+    int loglevel;
     int initialized;
 } FFLCEVCContext;
 
@@ -49,7 +50,7 @@ typedef struct FFLCEVCFrame {
     struct AVFrame *frame;
 } FFLCEVCFrame;
 
-int ff_lcevc_alloc(FFLCEVCContext **plcevc);
+int ff_lcevc_alloc(FFLCEVCContext **plcevc, int loglevel);
 int ff_lcevc_process(void *logctx, struct AVFrame *frame);
 int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const struct AVFrame *frame,
                          enum AVPixelFormat *format, int *width, int *height);
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to