| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime.InteropServices;
- namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
- {
- static partial 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 = maxVersion; version >= minVersion; 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);
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial AVFrame* av_frame_alloc();
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial void av_frame_unref(AVFrame* frame);
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial void av_free(AVFrame* frame);
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial void av_log_set_level(AVLog level);
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial void av_log_set_callback(av_log_set_callback_callback callback);
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial AVLog av_log_get_level();
- [LibraryImport(AvUtilLibraryName)]
- internal static unsafe partial void av_log_format_line(void* ptr, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string fmt, byte* vl, byte* line, int lineSize, int* printPrefix);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial AVCodec* avcodec_find_decoder(AVCodecID id);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial AVCodecContext* avcodec_alloc_context3(AVCodec* codec);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, void **options);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial int avcodec_close(AVCodecContext* avctx);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial void avcodec_free_context(AVCodecContext** avctx);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial AVPacket* av_packet_alloc();
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial void av_packet_unref(AVPacket* pkt);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial void av_packet_free(AVPacket** pkt);
- [LibraryImport(AvCodecLibraryName)]
- internal static unsafe partial int avcodec_version();
- }
- }
|