mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-11-08 16:32:43 -05:00
As stated in the title, win-arm64 (Windows 11 ARM) has been added to the workflows, so these builds should automatically compile for this PR and all other releases going forward. Also updated the FFmpeg runtimes from 5.0.3 to 6.1.2. macOS (x64/arm64) is _currently_ excluded from the update until a proper cross-compiling environment can be set up for these architectures. Windows 11 ARM users, please test the win-arm64 build for any issues. --------- Co-authored-by: Evan Husted <greem@greemdev.net>
129 lines
4.7 KiB
C#
129 lines
4.7 KiB
C#
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()
|
|
{
|
|
{ AvCodecLibraryName, (58, 61) },
|
|
{ AvUtilLibraryName, (56, 59) },
|
|
};
|
|
|
|
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 nint handle)
|
|
{
|
|
handle = nint.Zero;
|
|
|
|
if (_librariesWhitelist.TryGetValue(libraryName, out (int, int) 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) =>
|
|
{
|
|
|
|
if (name == AvUtilLibraryName && TryLoadWhitelistedLibrary(AvUtilLibraryName, assembly, path, out nint handle))
|
|
{
|
|
return handle;
|
|
}
|
|
else if (name == AvCodecLibraryName && TryLoadWhitelistedLibrary(AvCodecLibraryName, assembly, path, out handle))
|
|
{
|
|
return handle;
|
|
}
|
|
|
|
return nint.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();
|
|
}
|
|
}
|