aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Nvdec.FFmpeg/Native
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Nvdec.FFmpeg/Native')
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs25
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs171
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs8
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs26
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs37
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs15
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs26
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs8
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs23
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs23
-rw-r--r--Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs129
11 files changed, 491 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs
new file mode 100644
index 00000000..93edb788
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct AVCodec
+ {
+#pragma warning disable CS0649
+ public unsafe byte* Name;
+ public unsafe byte* LongName;
+ public int Type;
+ public AVCodecID Id;
+ public int Capabilities;
+ public byte MaxLowRes;
+ public unsafe AVRational* SupportedFramerates;
+ public IntPtr PixFmts;
+ public IntPtr SupportedSamplerates;
+ public IntPtr SampleFmts;
+ // Deprecated
+ public unsafe ulong* ChannelLayouts;
+ public unsafe IntPtr PrivClass;
+ public IntPtr Profiles;
+ public unsafe byte* WrapperName;
+#pragma warning restore CS0649
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs
new file mode 100644
index 00000000..11bd63b0
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs
@@ -0,0 +1,171 @@
+using Ryujinx.Common.Memory;
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct AVCodecContext
+ {
+#pragma warning disable CS0649
+ public unsafe IntPtr AvClass;
+ public int LogLevelOffset;
+ public int CodecType;
+ public unsafe AVCodecLegacy* Codec;
+ public AVCodecID CodecId;
+ public uint CodecTag;
+ public IntPtr PrivData;
+ public IntPtr Internal;
+ public IntPtr Opaque;
+ public long BitRate;
+ public int BitRateTolerance;
+ public int GlobalQuality;
+ public int CompressionLevel;
+ public int Flags;
+ public int Flags2;
+ public IntPtr ExtraData;
+ public int ExtraDataSize;
+ public AVRational TimeBase;
+ public int TicksPerFrame;
+ public int Delay;
+ public int Width;
+ public int Height;
+ public int CodedWidth;
+ public int CodedHeight;
+ public int GopSize;
+ public int PixFmt;
+ public IntPtr DrawHorizBand;
+ public IntPtr GetFormat;
+ public int MaxBFrames;
+ public float BQuantFactor;
+ public float BQuantOffset;
+ public int HasBFrames;
+ public float IQuantFactor;
+ public float IQuantOffset;
+ public float LumiMasking;
+ public float TemporalCplxMasking;
+ public float SpatialCplxMasking;
+ public float PMasking;
+ public float DarkMasking;
+ public int SliceCount;
+ public IntPtr SliceOffset;
+ public AVRational SampleAspectRatio;
+ public int MeCmp;
+ public int MeSubCmp;
+ public int MbCmp;
+ public int IldctCmp;
+ public int DiaSize;
+ public int LastPredictorCount;
+ public int MePreCmp;
+ public int PreDiaSize;
+ public int MeSubpelQuality;
+ public int MeRange;
+ public int SliceFlags;
+ public int MbDecision;
+ public IntPtr IntraMatrix;
+ public IntPtr InterMatrix;
+ public int IntraDcPrecision;
+ public int SkipTop;
+ public int SkipBottom;
+ public int MbLmin;
+ public int MbLmax;
+ public int BidirRefine;
+ public int KeyintMin;
+ public int Refs;
+ public int Mv0Threshold;
+ public int ColorPrimaries;
+ public int ColorPrc;
+ public int Colorspace;
+ public int ColorRange;
+ public int ChromaSampleLocation;
+ public int Slices;
+ public int FieldOrder;
+ public int SampleRate;
+ public int Channels;
+ public int SampleFmt;
+ public int FrameSize;
+ public int FrameNumber;
+ public int BlockAlign;
+ public int CutOff;
+ public ulong ChannelLayout;
+ public ulong RequestChannelLayout;
+ public int AudioServiceType;
+ public int RequestSampleFmt;
+ public IntPtr GetBuffer2;
+ public float QCompress;
+ public float QBlur;
+ public int QMin;
+ public int QMax;
+ public int MaxQdiff;
+ public int RcBufferSize;
+ public int RcOverrideCount;
+ public IntPtr RcOverride;
+ public long RcMaxRate;
+ public long RcMinRate;
+ public float RcMax_available_vbv_use;
+ public float RcMin_vbv_overflow_use;
+ public int RcInitialBufferOccupancy;
+ public int Trellis;
+ public IntPtr StatsOut;
+ public IntPtr StatsIn;
+ public int WorkaroundBugs;
+ public int StrictStdCompliance;
+ public int ErrorConcealment;
+ public int Debug;
+ public int ErrRecognition;
+ public long ReorderedOpaque;
+ public IntPtr HwAccel;
+ public IntPtr HwAccelContext;
+ public Array8<ulong> Error;
+ public int DctAlgo;
+ public int IdctAlgo;
+ public int BitsPerCodedSample;
+ public int BitsPerRawSample;
+ public int LowRes;
+ public int ThreadCount;
+ public int ThreadType;
+ public int ActiveThreadType;
+ public int ThreadSafeCallbacks;
+ public IntPtr Execute;
+ public IntPtr Execute2;
+ public int NsseWeight;
+ public int Profile;
+ public int Level;
+ public int SkipLoopFilter;
+ public int SkipIdct;
+ public int SkipFrame;
+ public IntPtr SubtitleHeader;
+ public int SubtitleHeaderSize;
+ public int InitialPadding;
+ public AVRational Framerate;
+ public int SwPixFmt;
+ public AVRational PktTimebase;
+ public IntPtr CodecDescriptor;
+ public long PtsCorrectionNumFaultyPts;
+ public long PtsCorrectionNumFaultyDts;
+ public long PtsCorrectionLastPts;
+ public long PtsCorrectionLastDts;
+ public IntPtr SubCharenc;
+ public int SubCharencMode;
+ public int SkipAlpha;
+ public int SeekPreroll;
+ public int DebugMv;
+ public IntPtr ChromaIntraMatrix;
+ public IntPtr DumpSeparator;
+ public IntPtr CodecWhitelist;
+ public uint Properties;
+ public IntPtr CodedSideData;
+ public int NbCodedSideData;
+ public IntPtr HwFramesCtx;
+ public int SubTextFormat;
+ public int TrailingPadding;
+ public long MaxPixels;
+ public IntPtr HwDeviceCtx;
+ public int HwAccelFlags;
+ public int applyCropping;
+ public int ExtraHwFrames;
+ public int DiscardDamagedPercentage;
+ public long MaxSamples;
+ public int ExportSideData;
+ public IntPtr GetEncodeBuffer;
+#pragma warning restore CS0649
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs
new file mode 100644
index 00000000..b371de9e
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ enum AVCodecID
+ {
+ AV_CODEC_ID_H264 = 27,
+ AV_CODEC_ID_VP8 = 139,
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs
new file mode 100644
index 00000000..0913cbc4
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct AVCodecLegacy
+ {
+#pragma warning disable CS0649
+ public unsafe byte* Name;
+ public unsafe byte* LongName;
+ public int Type;
+ public AVCodecID Id;
+ public int Capabilities;
+ public byte MaxLowRes;
+ public unsafe AVRational* SupportedFramerates;
+ public IntPtr PixFmts;
+ public IntPtr SupportedSamplerates;
+ public IntPtr SampleFmts;
+ // Deprecated
+ public unsafe ulong* ChannelLayouts;
+ public unsafe IntPtr PrivClass;
+ public IntPtr Profiles;
+ public unsafe byte* WrapperName;
+ public IntPtr ChLayouts;
+#pragma warning restore CS0649
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs
new file mode 100644
index 00000000..faaf5c7d
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs
@@ -0,0 +1,37 @@
+using Ryujinx.Common.Memory;
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct AVFrame
+ {
+#pragma warning disable CS0649
+ public Array8<IntPtr> Data;
+ public Array8<int> LineSize;
+ public IntPtr ExtendedData;
+ public int Width;
+ public int Height;
+ public int NumSamples;
+ public int Format;
+ public int KeyFrame;
+ public int PictureType;
+ public AVRational SampleAspectRatio;
+ public long Pts;
+ public long PktDts;
+ public AVRational TimeBase;
+ public int CodedPictureNumber;
+ public int DisplayPictureNumber;
+ public int Quality;
+ public IntPtr Opaque;
+ public int RepeatPicture;
+ public int InterlacedFrame;
+ public int TopFieldFirst;
+ public int PaletteHasChanged;
+ public long ReorderedOpaque;
+ public int SampleRate;
+ public ulong ChannelLayout;
+#pragma warning restore CS0649
+
+ // NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs
new file mode 100644
index 00000000..4224de9e
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ enum AVLog
+ {
+ Panic = 0,
+ Fatal = 8,
+ Error = 16,
+ Warning = 24,
+ Info = 32,
+ Verbose = 40,
+ Debug = 48,
+ Trace = 56,
+ MaxOffset = 64
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs
new file mode 100644
index 00000000..d5b02104
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs
@@ -0,0 +1,26 @@
+using System;
+
+using AVBufferRef = System.IntPtr;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct AVPacket
+ {
+#pragma warning disable CS0649
+ public unsafe AVBufferRef *Buf;
+ public long Pts;
+ public long Dts;
+ public unsafe byte* Data;
+ public int Size;
+ public int StreamIndex;
+ public int Flags;
+ public IntPtr SizeData;
+ public int SizeDataElems;
+ public long Duration;
+ public long Position;
+ public IntPtr Opaque;
+ public unsafe AVBufferRef *OpaqueRef;
+ public AVRational TimeBase;
+#pragma warning restore CS0649
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs
new file mode 100644
index 00000000..cad5fde0
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ public struct AVRational
+ {
+ public int Numerator;
+ public int Denominator;
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs
new file mode 100644
index 00000000..8b08c02c
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct FFCodec
+ {
+ public unsafe delegate int AVCodec_decode(AVCodecContext* avctx, void* outdata, int* got_frame_ptr, AVPacket* avpkt);
+
+#pragma warning disable CS0649
+ public AVCodec Base;
+ public int CapsInternalOrCbType;
+ public int PrivDataSize;
+ public IntPtr UpdateThreadContext;
+ public IntPtr UpdateThreadContextForUser;
+ public IntPtr Defaults;
+ public IntPtr InitStaticData;
+ public IntPtr Init;
+ public IntPtr CodecCallback;
+#pragma warning restore CS0649
+
+ // NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs
new file mode 100644
index 00000000..910270a5
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ struct FFCodecLegacy<T> where T: struct
+ {
+#pragma warning disable CS0649
+ public T Base;
+ public uint CapsInternalOrCbType;
+ public int PrivDataSize;
+ public IntPtr UpdateThreadContext;
+ public IntPtr UpdateThreadContextForUser;
+ public IntPtr Defaults;
+ public IntPtr InitStaticData;
+ public IntPtr Init;
+ public IntPtr EncodeSub;
+ public IntPtr Encode2;
+ public IntPtr Decode;
+#pragma warning restore CS0649
+
+ // NOTE: There is more after, but the layout kind of changed a bit and we don't need more than this. This is safe as we only manipulate this behind a reference.
+ }
+}
diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs
new file mode 100644
index 00000000..4c010783
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
+{
+ static class FFmpegApi
+ {
+ public const string AvCodecLibraryName = "avcodec";
+ public const string AvUtilLibraryName = "avutil";
+
+ private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new Dictionary<string, (int, int)>
+ {
+ { AvCodecLibraryName, (58, 59) },
+ { AvUtilLibraryName, (56, 57) }
+ };
+
+ private static string FormatLibraryNameForCurrentOs(string libraryName, int version)
+ {
+ if (OperatingSystem.IsWindows())
+ {
+ return $"{libraryName}-{version}.dll";
+ }
+ else if (OperatingSystem.IsLinux())
+ {
+ return $"lib{libraryName}.so.{version}";
+ }
+ else if (OperatingSystem.IsMacOS())
+ {
+ return $"lib{libraryName}.{version}.dylib";
+ }
+ else
+ {
+ throw new NotImplementedException($"Unsupported OS for FFmpeg: {RuntimeInformation.RuntimeIdentifier}");
+ }
+ }
+
+
+ private static bool TryLoadWhitelistedLibrary(string libraryName, Assembly assembly, DllImportSearchPath? searchPath, out IntPtr handle)
+ {
+ handle = IntPtr.Zero;
+
+ if (_librariesWhitelist.TryGetValue(libraryName, out var value))
+ {
+ (int minVersion, int maxVersion) = value;
+
+ for (int version = minVersion; version <= maxVersion; version++)
+ {
+ if (NativeLibrary.TryLoad(FormatLibraryNameForCurrentOs(libraryName, version), assembly, searchPath, out handle))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static FFmpegApi()
+ {
+ NativeLibrary.SetDllImportResolver(typeof(FFmpegApi).Assembly, (name, assembly, path) =>
+ {
+ IntPtr handle;
+
+ if (name == AvUtilLibraryName && TryLoadWhitelistedLibrary(AvUtilLibraryName, assembly, path, out handle))
+ {
+ return handle;
+ }
+ else if (name == AvCodecLibraryName && TryLoadWhitelistedLibrary(AvCodecLibraryName, assembly, path, out handle))
+ {
+ return handle;
+ }
+
+ return IntPtr.Zero;
+ });
+ }
+
+ public unsafe delegate void av_log_set_callback_callback(void* a0, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string a2, byte* a3);
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern AVFrame* av_frame_alloc();
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_frame_unref(AVFrame* frame);
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_free(AVFrame* frame);
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_log_set_level(AVLog level);
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_log_set_callback(av_log_set_callback_callback callback);
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern AVLog av_log_get_level();
+
+ [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_log_format_line(void* ptr, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string fmt, byte* vl, byte* line, int lineSize, int* printPrefix);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern AVCodec* avcodec_find_decoder(AVCodecID id);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern AVCodecContext* avcodec_alloc_context3(AVCodec* codec);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, void **options);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern int avcodec_close(AVCodecContext* avctx);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void avcodec_free_context(AVCodecContext** avctx);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern AVPacket* av_packet_alloc();
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_packet_unref(AVPacket* pkt);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern void av_packet_free(AVPacket** pkt);
+
+ [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)]
+ internal static unsafe extern int avcodec_version();
+ }
+}