SHA256
Add License Exception
This commit is contained in:
16 files changed
+1055
-1011
No files matched your search
@@ -4,7 +4,7 @@ using MelonLoader;
|
|||||||
using MelonLoader.Utils;
|
using MelonLoader.Utils;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Data;
|
namespace ADOFAIRenderer.Core.Data;
|
||||||
|
|
||||||
public class GlobalConfig
|
public class GlobalConfig
|
||||||
{
|
{
|
||||||
File renamed without changes.
@@ -7,6 +7,7 @@ using System.Buffers;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ADOFAIRenderer.API;
|
using ADOFAIRenderer.API;
|
||||||
|
using ADOFAIRenderer.Core.Data;
|
||||||
using ADOFAIRenderer.Data;
|
using ADOFAIRenderer.Data;
|
||||||
using ADOFAIRenderer.UI;
|
using ADOFAIRenderer.UI;
|
||||||
using ADOFAIRenderer.UI.Window;
|
using ADOFAIRenderer.UI.Window;
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using FFmpeg.AutoGen;
|
||||||
|
|
||||||
|
namespace ADOFAIRenderer.Data;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
public enum Codec
|
||||||
|
{
|
||||||
|
H264, H265, VP9, AV1, VVC
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class CodecUtil
|
||||||
|
{
|
||||||
|
public static readonly Dictionary<Codec, AVCodecID> AudioCodecMatch = new()
|
||||||
|
{
|
||||||
|
[Codec.H264] = AVCodecID.AV_CODEC_ID_AAC,
|
||||||
|
[Codec.H265] = AVCodecID.AV_CODEC_ID_AAC,
|
||||||
|
[Codec.VP9] = AVCodecID.AV_CODEC_ID_OPUS,
|
||||||
|
[Codec.AV1] = AVCodecID.AV_CODEC_ID_OPUS,
|
||||||
|
[Codec.VVC] = AVCodecID.AV_CODEC_ID_OPUS
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly Dictionary<AVCodecID, List<int>> AvailableSampleRate = new()
|
||||||
|
{
|
||||||
|
[AVCodecID.AV_CODEC_ID_AAC] = new List<int> { 44100, 48000, 96000 },
|
||||||
|
[AVCodecID.AV_CODEC_ID_OPUS] = new List<int> { 48000 }
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace ADOFAIRenderer.Data;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
public enum RateControlMode
|
||||||
|
{
|
||||||
|
CBR,
|
||||||
|
VBR,
|
||||||
|
CQP
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using ADOFAIRenderer.Util.FFmpeg;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Data;
|
namespace ADOFAIRenderer.Data;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# ADOFAIRenderer API & Data Linking Exception (Dynamic Linking Only)
|
||||||
|
|
||||||
|
> **Additional Permission under GNU General Public License version 3 section 7**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Legal Terms (Official)
|
||||||
|
|
||||||
|
Linking this Program statically or dynamically with other modules is making a combined work based on this Program. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
|
||||||
|
|
||||||
|
As a special exception, the copyright holders of this Program give you permission to dynamically link this Program with independent modules that interact with or reference this Program solely through the public application programming interfaces (APIs), types, and data structures declared within the following namespaces:
|
||||||
|
|
||||||
|
- `ADOFAIRenderer.API`
|
||||||
|
- `ADOFAIRenderer.Data`
|
||||||
|
|
||||||
|
and to copy, convey, and distribute the resulting combined work under terms of your choice, without requiring such combined work or independent modules to be covered under the GNU General Public License version 3, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module.
|
||||||
|
|
||||||
|
This exception applies exclusively to dynamic linking. Static linking, including but not limited to combining, embedding, compiling this Program into another binary, or merging assemblies (such as via ILMerge or Costura), is explicitly excluded from this exception and remains fully subject to the terms and copyleft requirements of the GNU General Public License version 3.
|
||||||
|
|
||||||
|
An **"independent module"** is a separate and distinct software module that is not derived from or based on this Program, other than referencing or communicating with the interfaces and types declared within the designated namespaces above.
|
||||||
|
|
||||||
|
This exception does not grant any permission to modify the source code of this Program itself outside the terms of the GNU General Public License version 3.
|
||||||
|
|
||||||
|
In accordance with section 7 of the GNU GPL version 3, if you modify this Program, you may extend this exception to your version of the Program, but you are not obligated to do so. If you do not wish to provide this exception in your derivative work, you may remove this exception statement from your version.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 조항 해설 (Korean Guide)
|
||||||
|
|
||||||
|
본 문서는 GNU General Public License 버전 3 (GPLv3) 제7조(추가적인 허가, Additional Permissions)에 따라 제공되는 공식 예외 조항입니다.
|
||||||
|
|
||||||
|
### 핵심 요약
|
||||||
|
|
||||||
|
- **동적 링킹(Dynamic Linking)만 허용**:
|
||||||
|
- 본 예외 조항은 **동적 링킹(런타임 참조 및 어셈블리 동적 로드)**에만 배타적으로 적용됩니다.
|
||||||
|
- ADOFAIRenderer 또는 그 일부 코드를 대상 모드/프로그램에 직접 병합하거나 포함(ILMerge, Costura, 바이너리 직접 내장/정적 컴파일 등)하는 **정적 링킹(Static Linking)은 본 예외 대상에서 제외**되며, 순수 GPLv3의 카피레프트(전염성) 의무가 그대로 적용됩니다.
|
||||||
|
- **외부 모드의 라이선스 자유**:
|
||||||
|
- 제3자 모드 또는 외부 프로그램이 동적 링킹을 통해 `ADOFAIRenderer.API` 및 `ADOFAIRenderer.Data` 네임스페이스의 공개 API, 클래스, 데이터 구조만을 참조·호출하여 연동하는 경우, 해당 모드는 **GPLv3의 카피레프트 의무를 적용받지 않습니다.**
|
||||||
|
- 외부 모드 개발자는 자신의 모드를 MIT, Apache-2.0, 독점/상용 라이선스 등 원하는 라이선스로 자유롭게 배포할 수 있습니다.
|
||||||
|
- **ADOFAIRenderer 코어 보호**:
|
||||||
|
- ADOFAIRenderer 자체의 소스 코드(렌더링 파이프라인, 코어 패치, 내부 유틸리티 등)를 수정하거나 재배포하는 경우에는 본 예외 조항이 적용되지 않으며, 순수 GPLv3 라이선스 조건이 그대로 적용됩니다.
|
||||||
|
|
||||||
@@ -90,4 +90,6 @@ The compiled mod will be output to `bin/Release/netstandard2.1/ADOFAIRenderer.dl
|
|||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
This project is licensed under the GNU General Public License v3.0 (GPLv3). See `LICENSE` for details.
|
This project is licensed under the **GNU General Public License v3.0 with API & Data Linking Exception (GPLv3 with Exception, Dynamic Linking Only)**.
|
||||||
|
- Third-party mods and external tools that reference or dynamically link to ADOFAIRenderer solely via the `ADOFAIRenderer.API` and `ADOFAIRenderer.Data` namespaces are exempt from GPLv3 copyleft requirements and may be distributed under terms of their author's choice. (Static linking is excluded from this exception.)
|
||||||
|
- For full license terms and exception details, see [LICENSE](LICENSE) and [LICENSE-EXCEPTION.md](LICENSE-EXCEPTION.md).
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using ADOFAIRenderer;
|
using ADOFAIRenderer;
|
||||||
using ADOFAIRenderer.Core;
|
using ADOFAIRenderer.Core;
|
||||||
|
using ADOFAIRenderer.Core.Data;
|
||||||
using ADOFAIRenderer.Data;
|
using ADOFAIRenderer.Data;
|
||||||
using ADOFAIRenderer.UI;
|
using ADOFAIRenderer.UI;
|
||||||
using FFmpeg.AutoGen;
|
using FFmpeg.AutoGen;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ADOFAIRenderer.API;
|
using ADOFAIRenderer.API;
|
||||||
using ADOFAIRenderer.Core;
|
using ADOFAIRenderer.Core;
|
||||||
|
using ADOFAIRenderer.Core.Data;
|
||||||
using ADOFAIRenderer.Data;
|
using ADOFAIRenderer.Data;
|
||||||
using ADOFAIRenderer.Localization;
|
using ADOFAIRenderer.Localization;
|
||||||
using ADOFAIRenderer.Util;
|
using ADOFAIRenderer.Util;
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using FFmpeg.AutoGen;
|
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Util.FFmpeg
|
|
||||||
{
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public enum Codec
|
|
||||||
{
|
|
||||||
H264, H265, VP9, AV1, VVC
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class CodecUtil
|
|
||||||
{
|
|
||||||
public static readonly Dictionary<Codec, AVCodecID> AudioCodecMatch = new()
|
|
||||||
{
|
|
||||||
[Codec.H264] = AVCodecID.AV_CODEC_ID_AAC,
|
|
||||||
[Codec.H265] = AVCodecID.AV_CODEC_ID_AAC,
|
|
||||||
[Codec.VP9] = AVCodecID.AV_CODEC_ID_OPUS,
|
|
||||||
[Codec.AV1] = AVCodecID.AV_CODEC_ID_OPUS,
|
|
||||||
[Codec.VVC] = AVCodecID.AV_CODEC_ID_OPUS
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly Dictionary<AVCodecID, List<int>> AvailableSampleRate = new()
|
|
||||||
{
|
|
||||||
[AVCodecID.AV_CODEC_ID_AAC] = new List<int> { 44100, 48000, 96000 },
|
|
||||||
[AVCodecID.AV_CODEC_ID_OPUS] = new List<int> { 48000 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+739
-740
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using ADOFAIRenderer.Data;
|
||||||
using FFmpeg.AutoGen;
|
using FFmpeg.AutoGen;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using Unity.Collections;
|
using Unity.Collections;
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Util.FFmpeg
|
|
||||||
{
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public enum RateControlMode
|
|
||||||
{
|
|
||||||
CBR,
|
|
||||||
VBR,
|
|
||||||
CQP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+106
-106
@@ -2,112 +2,112 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using ADOFAIRenderer.Data;
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Util.FFmpeg
|
namespace ADOFAIRenderer.Util.FFmpeg;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
internal enum EncoderKind
|
||||||
{
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
Software,
|
||||||
public enum EncoderKind
|
NVENC,
|
||||||
{
|
AMF,
|
||||||
Software,
|
QSV,
|
||||||
NVENC,
|
VideoToolbox
|
||||||
AMF,
|
}
|
||||||
QSV,
|
|
||||||
VideoToolbox
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
}
|
internal sealed class VideoEncoder : IEquatable<VideoEncoder>
|
||||||
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
internal sealed class VideoEncoder : IEquatable<VideoEncoder>
|
|
||||||
{
|
// ── H.264 ──
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
public static readonly VideoEncoder H264_NVENC = new("h264_nvenc", Codec.H264, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
||||||
|
public static readonly VideoEncoder H264_QSV = new("h264_qsv", Codec.H264, GPUVendor.Intel, EncoderKind.QSV);
|
||||||
// ── H.264 ──
|
public static readonly VideoEncoder H264_AMF = new("h264_amf", Codec.H264, GPUVendor.AMD, EncoderKind.AMF);
|
||||||
public static readonly VideoEncoder H264_NVENC = new("h264_nvenc", Codec.H264, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
public static readonly VideoEncoder H264_VideoToolbox = new("h264_videotoolbox", Codec.H264, GPUVendor.Apple, EncoderKind.VideoToolbox);
|
||||||
public static readonly VideoEncoder H264_QSV = new("h264_qsv", Codec.H264, GPUVendor.Intel, EncoderKind.QSV);
|
public static readonly VideoEncoder Libx264 = new("libx264", Codec.H264, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
public static readonly VideoEncoder H264_AMF = new("h264_amf", Codec.H264, GPUVendor.AMD, EncoderKind.AMF);
|
|
||||||
public static readonly VideoEncoder H264_VideoToolbox = new("h264_videotoolbox", Codec.H264, GPUVendor.Apple, EncoderKind.VideoToolbox);
|
// ── H.265 (HEVC) ──
|
||||||
public static readonly VideoEncoder Libx264 = new("libx264", Codec.H264, GPUVendor.Unknown, EncoderKind.Software);
|
public static readonly VideoEncoder HEVC_NVENC = new("hevc_nvenc", Codec.H265, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
||||||
|
public static readonly VideoEncoder HEVC_QSV = new("hevc_qsv", Codec.H265, GPUVendor.Intel, EncoderKind.QSV);
|
||||||
// ── H.265 (HEVC) ──
|
public static readonly VideoEncoder HEVC_AMF = new("hevc_amf", Codec.H265, GPUVendor.AMD, EncoderKind.AMF);
|
||||||
public static readonly VideoEncoder HEVC_NVENC = new("hevc_nvenc", Codec.H265, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
public static readonly VideoEncoder HEVC_VideoToolbox = new("hevc_videotoolbox", Codec.H265, GPUVendor.Apple, EncoderKind.VideoToolbox);
|
||||||
public static readonly VideoEncoder HEVC_QSV = new("hevc_qsv", Codec.H265, GPUVendor.Intel, EncoderKind.QSV);
|
public static readonly VideoEncoder Libx265 = new("libx265", Codec.H265, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
public static readonly VideoEncoder HEVC_AMF = new("hevc_amf", Codec.H265, GPUVendor.AMD, EncoderKind.AMF);
|
|
||||||
public static readonly VideoEncoder HEVC_VideoToolbox = new("hevc_videotoolbox", Codec.H265, GPUVendor.Apple, EncoderKind.VideoToolbox);
|
// ── VP9 ──
|
||||||
public static readonly VideoEncoder Libx265 = new("libx265", Codec.H265, GPUVendor.Unknown, EncoderKind.Software);
|
public static readonly VideoEncoder VP9_NVENC = new("vp9_nvenc", Codec.VP9, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
||||||
|
public static readonly VideoEncoder VP9_QSV = new("vp9_qsv", Codec.VP9, GPUVendor.Intel, EncoderKind.QSV);
|
||||||
// ── VP9 ──
|
public static readonly VideoEncoder LibvpxVP9 = new("libvpx-vp9", Codec.VP9, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
public static readonly VideoEncoder VP9_NVENC = new("vp9_nvenc", Codec.VP9, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
|
||||||
public static readonly VideoEncoder VP9_QSV = new("vp9_qsv", Codec.VP9, GPUVendor.Intel, EncoderKind.QSV);
|
// ── AV1 ──
|
||||||
public static readonly VideoEncoder LibvpxVP9 = new("libvpx-vp9", Codec.VP9, GPUVendor.Unknown, EncoderKind.Software);
|
public static readonly VideoEncoder AV1_NVENC = new("av1_nvenc", Codec.AV1, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
||||||
|
public static readonly VideoEncoder AV1_QSV = new("av1_qsv", Codec.AV1, GPUVendor.Intel, EncoderKind.QSV);
|
||||||
// ── AV1 ──
|
public static readonly VideoEncoder AV1_AMF = new("av1_amf", Codec.AV1, GPUVendor.AMD, EncoderKind.AMF);
|
||||||
public static readonly VideoEncoder AV1_NVENC = new("av1_nvenc", Codec.AV1, GPUVendor.NVIDIA, EncoderKind.NVENC);
|
public static readonly VideoEncoder LibSvtAv1 = new("libsvtav1", Codec.AV1, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
public static readonly VideoEncoder AV1_QSV = new("av1_qsv", Codec.AV1, GPUVendor.Intel, EncoderKind.QSV);
|
public static readonly VideoEncoder LibAomAv1 = new("libaom-av1", Codec.AV1, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
public static readonly VideoEncoder AV1_AMF = new("av1_amf", Codec.AV1, GPUVendor.AMD, EncoderKind.AMF);
|
|
||||||
public static readonly VideoEncoder LibSvtAv1 = new("libsvtav1", Codec.AV1, GPUVendor.Unknown, EncoderKind.Software);
|
// ── VVC ──
|
||||||
public static readonly VideoEncoder LibAomAv1 = new("libaom-av1", Codec.AV1, GPUVendor.Unknown, EncoderKind.Software);
|
public static readonly VideoEncoder LibVvenc = new("libvvenc", Codec.VVC, GPUVendor.Unknown, EncoderKind.Software);
|
||||||
|
|
||||||
// ── VVC ──
|
// ReSharper restore MemberCanBePrivate.Global
|
||||||
public static readonly VideoEncoder LibVvenc = new("libvvenc", Codec.VVC, GPUVendor.Unknown, EncoderKind.Software);
|
|
||||||
|
public static readonly IReadOnlyList<VideoEncoder> All = new[]
|
||||||
// ReSharper restore MemberCanBePrivate.Global
|
{
|
||||||
|
H264_NVENC, H264_QSV, H264_AMF, H264_VideoToolbox, Libx264,
|
||||||
public static readonly IReadOnlyList<VideoEncoder> All = new[]
|
HEVC_NVENC, HEVC_QSV, HEVC_AMF, HEVC_VideoToolbox, Libx265,
|
||||||
{
|
VP9_NVENC, VP9_QSV, LibvpxVP9,
|
||||||
H264_NVENC, H264_QSV, H264_AMF, H264_VideoToolbox, Libx264,
|
AV1_NVENC, AV1_QSV, AV1_AMF, LibSvtAv1, LibAomAv1,
|
||||||
HEVC_NVENC, HEVC_QSV, HEVC_AMF, HEVC_VideoToolbox, Libx265,
|
LibVvenc
|
||||||
VP9_NVENC, VP9_QSV, LibvpxVP9,
|
};
|
||||||
AV1_NVENC, AV1_QSV, AV1_AMF, LibSvtAv1, LibAomAv1,
|
|
||||||
LibVvenc
|
private static readonly Dictionary<string, VideoEncoder> ByName =
|
||||||
};
|
All.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private static readonly Dictionary<string, VideoEncoder> ByName =
|
public string Name { get; }
|
||||||
All.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase);
|
public Codec Codec { get; }
|
||||||
|
public GPUVendor Vendor { get; }
|
||||||
public string Name { get; }
|
public EncoderKind Kind { get; }
|
||||||
public Codec Codec { get; }
|
public bool IsHardware => Kind != EncoderKind.Software;
|
||||||
public GPUVendor Vendor { get; }
|
|
||||||
public EncoderKind Kind { get; }
|
private VideoEncoder(string name, Codec codec, GPUVendor vendor, EncoderKind kind)
|
||||||
public bool IsHardware => Kind != EncoderKind.Software;
|
{
|
||||||
|
Name = name;
|
||||||
private VideoEncoder(string name, Codec codec, GPUVendor vendor, EncoderKind kind)
|
Codec = codec;
|
||||||
{
|
Vendor = vendor;
|
||||||
Name = name;
|
Kind = kind;
|
||||||
Codec = codec;
|
}
|
||||||
Vendor = vendor;
|
|
||||||
Kind = kind;
|
public static VideoEncoder? FromName(string name)
|
||||||
}
|
{
|
||||||
|
return string.IsNullOrEmpty(name) ? null : ByName.GetValueOrDefault(name);
|
||||||
public static VideoEncoder? FromName(string name)
|
}
|
||||||
{
|
|
||||||
return string.IsNullOrEmpty(name) ? null : ByName.GetValueOrDefault(name);
|
public bool Equals(VideoEncoder other)
|
||||||
}
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
public bool Equals(VideoEncoder other)
|
return ReferenceEquals(this, other) || string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
|
||||||
{
|
}
|
||||||
if (ReferenceEquals(null, other)) return false;
|
|
||||||
return ReferenceEquals(this, other) || string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
|
public override bool Equals(object? obj)
|
||||||
}
|
{
|
||||||
|
return ReferenceEquals(this, obj) || obj is VideoEncoder other && Equals(other);
|
||||||
public override bool Equals(object? obj)
|
}
|
||||||
{
|
|
||||||
return ReferenceEquals(this, obj) || obj is VideoEncoder other && Equals(other);
|
public override int GetHashCode()
|
||||||
}
|
{
|
||||||
|
return StringComparer.OrdinalIgnoreCase.GetHashCode(Name);
|
||||||
public override int GetHashCode()
|
}
|
||||||
{
|
|
||||||
return StringComparer.OrdinalIgnoreCase.GetHashCode(Name);
|
public static bool operator ==(VideoEncoder left, VideoEncoder right)
|
||||||
}
|
{
|
||||||
|
return Equals(left, right);
|
||||||
public static bool operator ==(VideoEncoder left, VideoEncoder right)
|
}
|
||||||
{
|
|
||||||
return Equals(left, right);
|
public static bool operator !=(VideoEncoder left, VideoEncoder right)
|
||||||
}
|
{
|
||||||
|
return !Equals(left, right);
|
||||||
public static bool operator !=(VideoEncoder left, VideoEncoder right)
|
}
|
||||||
{
|
|
||||||
return !Equals(left, right);
|
public override string ToString() => Name;
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() => Name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+120
-120
@@ -2,152 +2,152 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using ADOFAIRenderer.Data;
|
||||||
using ADOFAIRenderer.Util.FFmpeg;
|
using ADOFAIRenderer.Util.FFmpeg;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Util
|
namespace ADOFAIRenderer.Util;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
internal enum GPUVendor
|
||||||
{
|
{
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
Unknown, NVIDIA, AMD, Intel, Apple
|
||||||
internal enum GPUVendor
|
}
|
||||||
|
|
||||||
|
internal static class GPUUtil
|
||||||
|
{
|
||||||
|
private const string NvidiaPattern =
|
||||||
|
@"^NVIDIA GeForce [RG]TX [0-9]+(?> SUPER| Ti(?> SUPER)?)?(?> [0-9]+GB)?(?> Laptop GPU)?(?>/PCIe/SSE2)?$";
|
||||||
|
|
||||||
|
private const string IntelPattern =
|
||||||
|
@"^Intel(?>\(R\))? (?>U?HD Graphics [0-9]+|Arc\(TM\) [A-C][0-9]+ Graphics)(?> \([^)]+\))?$";
|
||||||
|
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
|
private const string AMDPattern =
|
||||||
|
@"^AMD Radeon RX [0-9]+(?> XT)?$";
|
||||||
|
|
||||||
|
private static GPUVendor _cachedVendor = GPUVendor.Unknown;
|
||||||
|
private static bool _hasCachedVendor;
|
||||||
|
|
||||||
|
private static GPUVendor GetActiveGPUVendor()
|
||||||
{
|
{
|
||||||
Unknown, NVIDIA, AMD, Intel, Apple
|
if (_hasCachedVendor) return _cachedVendor;
|
||||||
}
|
|
||||||
|
|
||||||
internal static class GPUUtil
|
var gpuName = SystemInfo.graphicsDeviceName;
|
||||||
{
|
Melon<RenderMod>.Logger.Msg($"Active GPU: {gpuName}");
|
||||||
private const string NvidiaPattern =
|
|
||||||
@"^NVIDIA GeForce [RG]TX [0-9]+(?> SUPER| Ti(?> SUPER)?)?(?> [0-9]+GB)?(?> Laptop GPU)?(?>/PCIe/SSE2)?$";
|
|
||||||
|
|
||||||
private const string IntelPattern =
|
_cachedVendor = GPUVendor.Unknown;
|
||||||
@"^Intel(?>\(R\))? (?>U?HD Graphics [0-9]+|Arc\(TM\) [A-C][0-9]+ Graphics)(?> \([^)]+\))?$";
|
foreach (Match unused in Regex.Matches(gpuName, NvidiaPattern))
|
||||||
|
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
private const string AMDPattern =
|
|
||||||
@"^AMD Radeon RX [0-9]+(?> XT)?$";
|
|
||||||
|
|
||||||
private static GPUVendor _cachedVendor = GPUVendor.Unknown;
|
|
||||||
private static bool _hasCachedVendor;
|
|
||||||
|
|
||||||
private static GPUVendor GetActiveGPUVendor()
|
|
||||||
{
|
{
|
||||||
if (_hasCachedVendor) return _cachedVendor;
|
_cachedVendor = GPUVendor.NVIDIA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var gpuName = SystemInfo.graphicsDeviceName;
|
if (_cachedVendor == GPUVendor.Unknown)
|
||||||
Melon<RenderMod>.Logger.Msg($"Active GPU: {gpuName}");
|
{
|
||||||
|
foreach (Match unused in Regex.Matches(gpuName, IntelPattern))
|
||||||
_cachedVendor = GPUVendor.Unknown;
|
|
||||||
foreach (Match unused in Regex.Matches(gpuName, NvidiaPattern))
|
|
||||||
{
|
{
|
||||||
_cachedVendor = GPUVendor.NVIDIA;
|
_cachedVendor = GPUVendor.Intel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cachedVendor == GPUVendor.Unknown)
|
|
||||||
{
|
|
||||||
foreach (Match unused in Regex.Matches(gpuName, IntelPattern))
|
|
||||||
{
|
|
||||||
_cachedVendor = GPUVendor.Intel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cachedVendor == GPUVendor.Unknown)
|
|
||||||
{
|
|
||||||
foreach (Match unused in Regex.Matches(gpuName, AMDPattern))
|
|
||||||
{
|
|
||||||
_cachedVendor = GPUVendor.AMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cachedVendor == GPUVendor.Unknown && Application.platform == RuntimePlatform.OSXPlayer)
|
|
||||||
{
|
|
||||||
_cachedVendor = GPUVendor.Apple;
|
|
||||||
}
|
|
||||||
|
|
||||||
_hasCachedVendor = true;
|
|
||||||
return _cachedVendor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double? _cachedNvidiaVersion;
|
if (_cachedVendor == GPUVendor.Unknown)
|
||||||
private static bool _hasCachedNvidiaVersion;
|
|
||||||
|
|
||||||
public static double? GetNvidiaDriverVersion()
|
|
||||||
{
|
{
|
||||||
if (_hasCachedNvidiaVersion) return _cachedNvidiaVersion;
|
foreach (Match unused in Regex.Matches(gpuName, AMDPattern))
|
||||||
|
|
||||||
_hasCachedNvidiaVersion = true;
|
|
||||||
_cachedNvidiaVersion = null;
|
|
||||||
|
|
||||||
if (GetActiveGPUVendor() != GPUVendor.NVIDIA) return null;
|
|
||||||
|
|
||||||
// 1. Try parsing from UnityEngine.SystemInfo.graphicsDeviceVersion
|
|
||||||
var deviceVersion = SystemInfo.graphicsDeviceVersion;
|
|
||||||
if (!string.IsNullOrEmpty(deviceVersion))
|
|
||||||
{
|
{
|
||||||
var match = Regex.Match(deviceVersion, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
_cachedVendor = GPUVendor.AMD;
|
||||||
if (match.Success)
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cachedVendor == GPUVendor.Unknown && Application.platform == RuntimePlatform.OSXPlayer)
|
||||||
|
{
|
||||||
|
_cachedVendor = GPUVendor.Apple;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasCachedVendor = true;
|
||||||
|
return _cachedVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double? _cachedNvidiaVersion;
|
||||||
|
private static bool _hasCachedNvidiaVersion;
|
||||||
|
|
||||||
|
public static double? GetNvidiaDriverVersion()
|
||||||
|
{
|
||||||
|
if (_hasCachedNvidiaVersion) return _cachedNvidiaVersion;
|
||||||
|
|
||||||
|
_hasCachedNvidiaVersion = true;
|
||||||
|
_cachedNvidiaVersion = null;
|
||||||
|
|
||||||
|
if (GetActiveGPUVendor() != GPUVendor.NVIDIA) return null;
|
||||||
|
|
||||||
|
// 1. Try parsing from UnityEngine.SystemInfo.graphicsDeviceVersion
|
||||||
|
var deviceVersion = SystemInfo.graphicsDeviceVersion;
|
||||||
|
if (!string.IsNullOrEmpty(deviceVersion))
|
||||||
|
{
|
||||||
|
var match = Regex.Match(deviceVersion, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
if (int.TryParse(match.Groups[3].Value, out var sub) && int.TryParse(match.Groups[4].Value, out int build))
|
||||||
{
|
{
|
||||||
if (int.TryParse(match.Groups[3].Value, out var sub) && int.TryParse(match.Groups[4].Value, out int build))
|
var nvidiaVerInt = sub % 10 * 10000 + build;
|
||||||
{
|
_cachedNvidiaVersion = nvidiaVerInt / 100.0;
|
||||||
var nvidiaVerInt = sub % 10 * 10000 + build;
|
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from SystemInfo: {_cachedNvidiaVersion:F2}");
|
||||||
_cachedNvidiaVersion = nvidiaVerInt / 100.0;
|
return _cachedNvidiaVersion;
|
||||||
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from SystemInfo: {_cachedNvidiaVersion:F2}");
|
|
||||||
return _cachedNvidiaVersion;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Fallback to Windows Registry (only on Windows NT platforms via RegistryUtil)
|
|
||||||
if (System.Environment.OSVersion.Platform != System.PlatformID.Win32NT) return null;
|
|
||||||
const string classKey = @"SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}";
|
|
||||||
var subkeys = RegistryUtil.GetHKLMSubKeyNames(classKey);
|
|
||||||
if (subkeys == null) return null;
|
|
||||||
|
|
||||||
foreach (var subkey in subkeys)
|
|
||||||
{
|
|
||||||
var subkeyPath = classKey + "\\" + subkey;
|
|
||||||
var provider = RegistryUtil.GetHKLMValue(subkeyPath, "ProviderName");
|
|
||||||
if (provider == null || !provider.Contains("NVIDIA")) continue;
|
|
||||||
|
|
||||||
var driverVersionStr = RegistryUtil.GetHKLMValue(subkeyPath, "DriverVersion");
|
|
||||||
if (string.IsNullOrEmpty(driverVersionStr)) continue;
|
|
||||||
|
|
||||||
var regMatch = Regex.Match(driverVersionStr, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
|
||||||
if (!regMatch.Success) continue;
|
|
||||||
if (!int.TryParse(regMatch.Groups[3].Value, out var sub) ||
|
|
||||||
!int.TryParse(regMatch.Groups[4].Value, out var build)) continue;
|
|
||||||
|
|
||||||
var nvidiaVerInt = sub % 10 * 10000 + build;
|
|
||||||
_cachedNvidiaVersion = nvidiaVerInt / 100f;
|
|
||||||
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from Registry (RegistryUtil): {_cachedNvidiaVersion:F2}");
|
|
||||||
return _cachedNvidiaVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<VideoEncoder> GetPrioritizedEncoders(Codec codec, bool forceSoftware = false)
|
// 2. Fallback to Windows Registry (only on Windows NT platforms via RegistryUtil)
|
||||||
|
if (System.Environment.OSVersion.Platform != System.PlatformID.Win32NT) return null;
|
||||||
|
const string classKey = @"SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}";
|
||||||
|
var subkeys = RegistryUtil.GetHKLMSubKeyNames(classKey);
|
||||||
|
if (subkeys == null) return null;
|
||||||
|
|
||||||
|
foreach (var subkey in subkeys)
|
||||||
{
|
{
|
||||||
var encoders = VideoEncoder.All.Where(e => e.Codec == codec).ToList();
|
var subkeyPath = classKey + "\\" + subkey;
|
||||||
if (forceSoftware)
|
var provider = RegistryUtil.GetHKLMValue(subkeyPath, "ProviderName");
|
||||||
{
|
if (provider == null || !provider.Contains("NVIDIA")) continue;
|
||||||
return encoders.Where(e => !e.IsHardware).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
var vendor = GetActiveGPUVendor();
|
var driverVersionStr = RegistryUtil.GetHKLMValue(subkeyPath, "DriverVersion");
|
||||||
var prioritized = new List<VideoEncoder>();
|
if (string.IsNullOrEmpty(driverVersionStr)) continue;
|
||||||
var others = new List<VideoEncoder>();
|
|
||||||
|
|
||||||
foreach (var item in encoders)
|
var regMatch = Regex.Match(driverVersionStr, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
||||||
{
|
if (!regMatch.Success) continue;
|
||||||
if (item.Vendor == vendor) prioritized.Add(item);
|
if (!int.TryParse(regMatch.Groups[3].Value, out var sub) ||
|
||||||
else others.Add(item);
|
!int.TryParse(regMatch.Groups[4].Value, out var build)) continue;
|
||||||
}
|
|
||||||
|
|
||||||
prioritized.AddRange(others);
|
var nvidiaVerInt = sub % 10 * 10000 + build;
|
||||||
return prioritized;
|
_cachedNvidiaVersion = nvidiaVerInt / 100f;
|
||||||
|
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from Registry (RegistryUtil): {_cachedNvidiaVersion:F2}");
|
||||||
|
return _cachedNvidiaVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<VideoEncoder> GetPrioritizedEncoders(Codec codec, bool forceSoftware = false)
|
||||||
|
{
|
||||||
|
var encoders = VideoEncoder.All.Where(e => e.Codec == codec).ToList();
|
||||||
|
if (forceSoftware)
|
||||||
|
{
|
||||||
|
return encoders.Where(e => !e.IsHardware).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var vendor = GetActiveGPUVendor();
|
||||||
|
var prioritized = new List<VideoEncoder>();
|
||||||
|
var others = new List<VideoEncoder>();
|
||||||
|
|
||||||
|
foreach (var item in encoders)
|
||||||
|
{
|
||||||
|
if (item.Vendor == vendor) prioritized.Add(item);
|
||||||
|
else others.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
prioritized.AddRange(others);
|
||||||
|
return prioritized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user