From 0e9732a6b49e36ef4cce3ae7d9b360e80ece136c Mon Sep 17 00:00:00 2001 From: Speykious Date: Fri, 3 Mar 2023 20:15:49 +0100 Subject: [PATCH 1/3] Make FFmpeg logs customizable with a delegate --- SeeShark/FFmpeg/FFmpegManager.cs | 51 +++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/SeeShark/FFmpeg/FFmpegManager.cs b/SeeShark/FFmpeg/FFmpegManager.cs index 9324363..fd18fcc 100644 --- a/SeeShark/FFmpeg/FFmpegManager.cs +++ b/SeeShark/FFmpeg/FFmpegManager.cs @@ -63,7 +63,7 @@ public static string FFmpegRootPath /// /// Setup FFmpeg: root path and logging. ///
- /// It will only setup FFmpeg once. Any non-first call will do nothing. + /// It will only setup FFmpeg once. Any non-first call to this method will do nothing. ///
/// SeeShark is designed such that this method is called whenever it is /// necessary to have FFmpeg ready. @@ -71,10 +71,30 @@ public static string FFmpegRootPath /// However, if you want to, you can still call it at the beginning of /// your program to customize your FFmpeg setup. ///
- /// Root path for loading FFmpeg libraries. /// Log level for FFmpeg. /// Color of the FFmpeg logs. + /// List of valid paths for loading FFmpeg libraries. public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, params string[] paths) + { + SetupFFmpeg(logLevel, logColor, null, paths); + } + + /// + /// Setup FFmpeg: root path and logging, with custom log delegate. + ///
+ /// It will only setup FFmpeg once. Any non-first call to this method will do nothing. + ///
+ /// SeeShark is designed such that this method is called whenever it is + /// necessary to have FFmpeg ready. + ///
+ /// However, if you want to, you can still call it at the beginning of + /// your program to customize your FFmpeg setup. + ///
+ /// Log level for FFmpeg. + /// Color of the FFmpeg logs. + /// Custom delegate to redirect FFmpeg logs. + /// List of valid paths for loading FFmpeg libraries. + public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, FFmpegLog? ffmpegLog, params string[] paths) { if (IsFFmpegSetup) return; @@ -91,7 +111,7 @@ public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, p TrySetRootPath(requiredLibs, AppDomain.CurrentDomain.BaseDirectory); else TrySetRootPath(requiredLibs, paths); - SetupFFmpegLogging(logLevel, logColor); + SetupFFmpegLogging(logLevel, logColor, ffmpegLog); ffmpeg.avdevice_register_all(); IsFFmpegSetup = true; @@ -99,27 +119,36 @@ public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, p public static void SetupFFmpeg(params string[] paths) => SetupFFmpeg(FFmpegLogLevel.Panic, ConsoleColor.Yellow, paths); - internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleColor logColor) + public delegate void FFmpegLog(FFmpegLogLevel logLevel, ConsoleColor logColor, string? message); + + private static void defaultFFmpegLog(FFmpegLogLevel logLevel, ConsoleColor logColor, string? message) + { + Console.ForegroundColor = logColor; + Console.Write(message); + Console.ResetColor(); + } + + internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleColor logColor, FFmpegLog? ffmpegLog = null) { ffmpeg.av_log_set_level((int)logLevel); + ffmpegLog ??= new FFmpegLog(defaultFFmpegLog); + // Do not convert to local function! logCallback = (p0, level, format, vl) => { if (level > ffmpeg.av_log_get_level()) return; - var lineSize = 1024; - var lineBuffer = stackalloc byte[lineSize]; - var printPrefix = 1; + int lineSize = 1024; + byte* lineBuffer = stackalloc byte[lineSize]; + int printPrefix = 1; ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix); - var line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer); + string? message = Marshal.PtrToStringAnsi((IntPtr)lineBuffer); // TODO: maybe make it possible to log this in any stream? - Console.ForegroundColor = logColor; - Console.Write(line); - Console.ResetColor(); + ffmpegLog(logLevel, logColor, message); }; ffmpeg.av_log_set_callback(logCallback); From def3d89beb005837506e44d95be42e4bb844d00d Mon Sep 17 00:00:00 2001 From: Speykious Date: Fri, 3 Mar 2023 20:16:29 +0100 Subject: [PATCH 2/3] Update ASCII example to include custom logger --- SeeShark.Example.Ascii/Program.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/SeeShark.Example.Ascii/Program.cs b/SeeShark.Example.Ascii/Program.cs index 77a8157..c64285f 100644 --- a/SeeShark.Example.Ascii/Program.cs +++ b/SeeShark.Example.Ascii/Program.cs @@ -4,10 +4,12 @@ using System; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using SeeShark.Decode; using SeeShark.Device; +using SeeShark.FFmpeg; using static SeeShark.FFmpeg.FFmpegManager; namespace SeeShark.Example.Ascii; @@ -18,6 +20,16 @@ class Program static CameraManager? manager; static FrameConverter? converter; + static StreamWriter logFile = new StreamWriter("ffmpeg.log"); + + /// + /// A custom FFmpeg logging callback. There is already a default one baked in which just writes to the console, so you don't need to make one yourself if that's what you want. + /// + static void ffmpegLog(FFmpegLogLevel logLevel, ConsoleColor _logColor, string? message) + { + logFile.Write($"[{logLevel}] {message}"); + } + static void Main(string[] args) { // Casually displaying "Oof :(" when exiting the program with force. @@ -32,8 +44,9 @@ static void Main(string[] args) // You can add your own path for FFmpeg libraries here! SetupFFmpeg( - FFmpeg.FFmpegLogLevel.Info, + FFmpegLogLevel.Debug, ConsoleColor.Yellow, + ffmpegLog, AppDomain.CurrentDomain.BaseDirectory, "/usr/lib", "/usr/lib64" From 27c6568a0a6884a83c5f546892dadba77a69f78e Mon Sep 17 00:00:00 2001 From: Speykious Date: Fri, 3 Mar 2023 20:18:53 +0100 Subject: [PATCH 3/3] Make default FFmpeg log delegate use stderr --- SeeShark/FFmpeg/FFmpegManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SeeShark/FFmpeg/FFmpegManager.cs b/SeeShark/FFmpeg/FFmpegManager.cs index fd18fcc..55e6271 100644 --- a/SeeShark/FFmpeg/FFmpegManager.cs +++ b/SeeShark/FFmpeg/FFmpegManager.cs @@ -124,7 +124,7 @@ public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, F private static void defaultFFmpegLog(FFmpegLogLevel logLevel, ConsoleColor logColor, string? message) { Console.ForegroundColor = logColor; - Console.Write(message); + Console.Error.Write(message); Console.ResetColor(); }