From: "Gregory J. Wolfe" <[email protected]>

File libopenh264enc.c has been modified so that the encoder uses av_log()
to log messages (error, warning, info, etc.) instead of logging them
directly to stderr.  At the time the encoder is created, the current
libav log level is mapped to an equivalent libopenh264 log level.  This
log level, and a message logging function that invokes av_log() to
actually log messages, are then set on the encoder.

This contains further changes by Michael Niedermayer and
Martin Storsjö.
---
In addition to the cleanups done by Michael, I further fixed the
coding style to match the normal, and did the following changes:

- Removed the extra log level check against av_log_get_level(), since
  av_log() does that internally
- Mapped WELS_LOG_INFO to AV_LOG_VERBOSE; OpenH264 doesn't print
  WELS_LOG_INFO by default (and it is pretty verbose). This makes
  sure that the amount of messages printed (by default) before and
  after this patch remain the same.
- Mapped WELS_LOG_DETAIL to AV_LOG_TRACE instead of AV_LOG_DEBUG+1
---
 libavcodec/libopenh264enc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index fb153c4..8b81605 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -59,6 +59,47 @@ static const AVClass class = {
     "libopenh264enc", av_default_item_name, options, LIBAVUTIL_VERSION_INT
 };
 
+// Convert libav log level to equivalent libopenh264 log level.  Given the
+// conversions below, you must set the libav log level to something greater
+// than AV_LOG_DEBUG if you want to see WELS_LOG_DETAIL messages.
+static int libav_to_libopenh264_log_level(int libav_log_level)
+{
+    if      (libav_log_level >  AV_LOG_DEBUG)   return WELS_LOG_DETAIL;
+    else if (libav_log_level >= AV_LOG_DEBUG)   return WELS_LOG_DEBUG;
+    else if (libav_log_level >= AV_LOG_VERBOSE) return WELS_LOG_INFO;
+    else if (libav_log_level >= AV_LOG_WARNING) return WELS_LOG_WARNING;
+    else if (libav_log_level >= AV_LOG_ERROR)   return WELS_LOG_ERROR;
+    else                                        return WELS_LOG_QUIET;
+}
+
+// Convert libopenh264 log level to equivalent libav log level.
+static int libopenh264_to_libav_log_level(int libopenh264_log_level)
+{
+    if      (libopenh264_log_level >= WELS_LOG_DETAIL)  return AV_LOG_TRACE;
+    else if (libopenh264_log_level >= WELS_LOG_DEBUG)   return AV_LOG_DEBUG;
+    else if (libopenh264_log_level >= WELS_LOG_INFO)    return AV_LOG_VERBOSE;
+    else if (libopenh264_log_level >= WELS_LOG_WARNING) return AV_LOG_WARNING;
+    else if (libopenh264_log_level >= WELS_LOG_ERROR)   return AV_LOG_ERROR;
+    else                                                return AV_LOG_QUIET;
+}
+
+// This function will be provided to the libopenh264 library.  The function 
will be called
+// when libopenh264 wants to log a message (error, warning, info, etc.).  The 
signature for
+// this function (defined in .../codec/api/svc/codec_api.h) is:
+//
+//        typedef void (*WelsTraceCallback) (void* ctx, int level, const char* 
string);
+
+static void libopenh264_trace_callback(void *ctx, int level, char const *msg)
+{
+    // The message will be logged only if the requested EQUIVALENT libav log 
level is
+    // less than or equal to the current libav log level.  Note, however, that 
before
+    // this function is called, welsCodecTrace::CodecTrace() will have already 
discarded
+    // the message (and this function will not be called) if the requested 
libopenh264
+    // log level "level" is greater than the current libopenh264 log level.
+    int equiv_libav_log_level = libopenh264_to_libav_log_level(level);
+    av_log(ctx, equiv_libav_log_level, "%s\n", msg);
+}
+
 static av_cold int svc_encode_close(AVCodecContext *avctx)
 {
     SVCContext *s = avctx->priv_data;
@@ -73,6 +114,8 @@ static av_cold int svc_encode_init(AVCodecContext *avctx)
     SVCContext *s = avctx->priv_data;
     SEncParamExt param = { 0 };
     int err = AVERROR_UNKNOWN;
+    int equiv_libopenh264_log_level;
+    WelsTraceCallback callback_function;
 
     // Mingw GCC < 4.7 on x86_32 uses an incorrect/buggy ABI for the 
WelsGetCodecVersion
     // function (for functions returning larger structs), thus skip the check 
in those
@@ -90,6 +133,28 @@ static av_cold int svc_encode_init(AVCodecContext *avctx)
         return AVERROR_UNKNOWN;
     }
 
+    // Set libopenh264 message logging level for this instance of the encoder 
using
+    // the current libav log level converted to the equivalent libopenh264 
level.
+    //
+    // The client should have the libav level set to the desired value before 
creating
+    // the libopenh264 encoder.  Once the encoder has been created, the 
libopenh264
+    // log level is fixed for that encoder.  Changing the libav log level to a 
LOWER
+    // value, in the expectation that higher level libopenh264 messages will 
no longer
+    // be logged, WILL have the expected effect.  However, changing the libav 
log level
+    // to a HIGHER value, in the expectation that higher level libopenh264 
messages will
+    // now be logged, WILL NOT have the expected effect.  This is because the 
higher
+    // level messages will be discarded by the libopenh264 logging system 
before our
+    // message logging callback function can be invoked.
+    equiv_libopenh264_log_level = 
libav_to_libopenh264_log_level(av_log_get_level());
+    (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_LEVEL, 
&equiv_libopenh264_log_level);
+
+    // Set the logging callback function to one that uses av_log() (see 
implementation above).
+    callback_function = (WelsTraceCallback) libopenh264_trace_callback;
+    (*s->encoder)->SetOption(s->encoder, ENCODER_OPTION_TRACE_CALLBACK, (void 
*)&callback_function);
+
+    // Set the AVCodecContext as the libopenh264 callback context so that it 
can be passed to av_log().
+    (*s->encoder)->SetOption(s->encoder, 
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, (void *)&avctx);
+
     (*s->encoder)->GetDefaultParams(s->encoder, &param);
 
     param.fMaxFrameRate              = avctx->time_base.den / 
avctx->time_base.num;
-- 
2.3.2 (Apple Git-55)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to