diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs
index 1597805c81..28b344cd34 100644
--- a/Ryujinx.Common/Logging/LogClass.cs
+++ b/Ryujinx.Common/Logging/LogClass.cs
@@ -9,6 +9,7 @@ namespace Ryujinx.Common.Logging
         Cpu,
         Font,
         Emulation,
+        FFmpeg,
         Gpu,
         Hid,
         Host1x,
diff --git a/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs b/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs
index 98754c767c..c402c574b2 100644
--- a/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs
+++ b/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs
@@ -1,16 +1,25 @@
 using FFmpeg.AutoGen;
+using Ryujinx.Common.Logging;
 using System;
+using System.Runtime.InteropServices;
 
 namespace Ryujinx.Graphics.Nvdec.H264
 {
     unsafe class FFmpegContext : IDisposable
     {
+        private readonly av_log_set_callback_callback _logFunc;
         private readonly AVCodec* _codec;
         private AVPacket* _packet;
         private AVCodecContext* _context;
 
         public FFmpegContext()
         {
+            _logFunc = Log;
+
+            // Redirect log output
+            ffmpeg.av_log_set_level(ffmpeg.AV_LOG_MAX_OFFSET);
+            ffmpeg.av_log_set_callback(_logFunc);
+
             _codec = ffmpeg.avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
             _context = ffmpeg.avcodec_alloc_context3(_codec);
 
@@ -19,6 +28,42 @@ namespace Ryujinx.Graphics.Nvdec.H264
             _packet = ffmpeg.av_packet_alloc();
         }
 
+        private void Log(void* p0, int level, string format, byte* vl)
+        {
+            if (level > ffmpeg.av_log_get_level())
+            {
+                return;
+            }
+
+            int lineSize = 1024;
+            byte* lineBuffer = stackalloc byte[lineSize];
+            int printPrefix = 1;
+
+            ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix);
+
+            string line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer).Trim();
+
+            switch (level)
+            {
+                case ffmpeg.AV_LOG_PANIC:
+                case ffmpeg.AV_LOG_FATAL:
+                case ffmpeg.AV_LOG_ERROR:
+                    Logger.Error?.Print(LogClass.FFmpeg, line);
+                    break;
+                case ffmpeg.AV_LOG_WARNING:
+                    Logger.Warning?.Print(LogClass.FFmpeg, line);
+                    break;
+                case ffmpeg.AV_LOG_INFO:
+                    Logger.Info?.Print(LogClass.FFmpeg, line);
+                    break;
+                case ffmpeg.AV_LOG_VERBOSE:
+                case ffmpeg.AV_LOG_DEBUG:
+                case ffmpeg.AV_LOG_TRACE:
+                    Logger.Debug?.Print(LogClass.FFmpeg, line);
+                    break;
+            }
+        }
+
         public int DecodeFrame(Surface output, ReadOnlySpan<byte> bitstream)
         {
             // Ensure the packet is clean before proceeding