Browse Source

fix: Support FFmpeg 5.1.x for decoding (#3816)

For some reason FFmpeg 5.1.x reverted part of the changes made in 5.0.x
on AVCodec.

This fix decoding issues with it.
Mary-nyan 3 years ago
parent
commit
7d8e198c33

+ 6 - 4
Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs

@@ -7,7 +7,9 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
 {
 {
     unsafe class FFmpegContext : IDisposable
     unsafe class FFmpegContext : IDisposable
     {
     {
-        private readonly FFCodec.AVCodec_decode _decodeFrame;
+        private unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
+
+        private readonly AVCodec_decode _decodeFrame;
         private static readonly FFmpegApi.av_log_set_callback_callback _logFunc;
         private static readonly FFmpegApi.av_log_set_callback_callback _logFunc;
         private readonly AVCodec* _codec;
         private readonly AVCodec* _codec;
         private AVPacket* _packet;
         private AVPacket* _packet;
@@ -53,17 +55,17 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
             // libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
             // libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
             if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
             if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
             {
             {
-                _decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodec*)_codec)->CodecCallback);
+                _decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodec<AVCodec>*)_codec)->CodecCallback);
             }
             }
             // libavcodec 59.x changed AvCodec private API layout.
             // libavcodec 59.x changed AvCodec private API layout.
             else if (avCodecMajorVersion == 59)
             else if (avCodecMajorVersion == 59)
             {
             {
-                _decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodec>*)_codec)->Decode);
+                _decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodecLegacy<AVCodec501>*)_codec)->Decode);
             }
             }
             // libavcodec 58.x and lower
             // libavcodec 58.x and lower
             else
             else
             {
             {
-                _decodeFrame = Marshal.GetDelegateForFunctionPointer<FFCodec.AVCodec_decode>(((FFCodecLegacy<AVCodecLegacy>*)_codec)->Decode);
+                _decodeFrame = Marshal.GetDelegateForFunctionPointer<AVCodec_decode>(((FFCodecLegacy<AVCodec>*)_codec)->Decode);
             }
             }
         }
         }
 
 

+ 1 - 0
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs

@@ -20,6 +20,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
         public unsafe IntPtr PrivClass;
         public unsafe IntPtr PrivClass;
         public IntPtr Profiles;
         public IntPtr Profiles;
         public unsafe byte* WrapperName;
         public unsafe byte* WrapperName;
+        public IntPtr ChLayouts;
 #pragma warning restore CS0649
 #pragma warning restore CS0649
     }
     }
 }
 }

+ 1 - 2
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs → Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs

@@ -2,7 +2,7 @@
 
 
 namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
 namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
 {
 {
-    struct AVCodecLegacy
+    struct AVCodec501
     {
     {
 #pragma warning disable CS0649
 #pragma warning disable CS0649
         public unsafe byte* Name;
         public unsafe byte* Name;
@@ -20,7 +20,6 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
         public unsafe IntPtr PrivClass;
         public unsafe IntPtr PrivClass;
         public IntPtr Profiles;
         public IntPtr Profiles;
         public unsafe byte* WrapperName;
         public unsafe byte* WrapperName;
-        public IntPtr ChLayouts;
 #pragma warning restore CS0649
 #pragma warning restore CS0649
     }
     }
 }
 }

+ 1 - 1
Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs

@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
         public unsafe IntPtr AvClass;
         public unsafe IntPtr AvClass;
         public int LogLevelOffset;
         public int LogLevelOffset;
         public int CodecType;
         public int CodecType;
-        public unsafe AVCodecLegacy* Codec;
+        public unsafe AVCodec* Codec;
         public AVCodecID CodecId;
         public AVCodecID CodecId;
         public uint CodecTag;
         public uint CodecTag;
         public IntPtr PrivData;
         public IntPtr PrivData;

+ 2 - 4
Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs

@@ -2,12 +2,10 @@
 
 
 namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
 namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
 {
 {
-    struct FFCodec
+    struct FFCodec<T> where T: struct
     {
     {
-        public unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
-
 #pragma warning disable CS0649
 #pragma warning disable CS0649
-        public AVCodec Base;
+        public T Base;
         public int CapsInternalOrCbType;
         public int CapsInternalOrCbType;
         public int PrivDataSize;
         public int PrivDataSize;
         public IntPtr UpdateThreadContext;
         public IntPtr UpdateThreadContext;