forked from Mirror/Ryujinx
eb528ae0f0
* Add workflow to perform automated checks for PRs * Downgrade Microsoft.CodeAnalysis to 4.4.0 This is a workaround to fix issues with dotnet-format. See: - https://github.com/dotnet/format/issues/1805 - https://github.com/dotnet/format/issues/1800 * Adjust editorconfig to be more compatible with Ryujinx code-style * Adjust .editorconfig line endings to match .gitattributes * Disable 'prefer switch expression' rule * Remove naming styles These are the default rules, so we don't need to override them. * Silence IDE0060 in .editorconfig * Slightly adjust .editorconfig * Add lost workflow changes * Move .editorconfig comment to the top * .editorconfig: private static readonly fields should be _lowerCamelCase * .editorconfig: Remove alignment for declarations as well * editorconfig: Add rule for local constants * Disable CA1822 for HLE services * Disable CA1822 for ViewModels Bindings won't work with static members, but this issue is silently ignored. * Run dotnet format for the whole solution * Check result code of SDL_GetDisplayBounds * Fix dotnet format style issues * Add missing trailing commas * Update Microsoft.CodeAnalysis.CSharp to 4.6.0 Skipping 4.5.0 since it breaks dotnet format * Restore old default naming rules for dotnet format * Add naming rule exception for CPU tests * checks: Include all files before excluding paths * Fix dotnet format issues * Check dotnet format version * checks: Run dotnet format with severity info again * checks: Disable naming style rules until they won't crash the process anymore * Remove unread private member * checks: Attempt to run analyzers 3 times before giving up * checks: Enable naming style rules again with the new retry logic
128 lines
4.7 KiB
C#
128 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, 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) =>
|
|
{
|
|
|
|
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 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();
|
|
}
|
|
}
|