diff options
Diffstat (limited to 'Ryujinx.Graphics.Nvdec.FFmpeg/Native')
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs | 25 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs | 171 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecID.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecLegacy.cs | 26 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs | 37 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVLog.cs | 15 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVPacket.cs | 26 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVRational.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs | 23 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs | 23 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs | 129 |
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(); + } +} |
