SHA256
Add Force Software Encoder Feature
This commit is contained in:
5 files changed
+33
-10
No files matched your search
@@ -466,6 +466,8 @@ namespace ADOFAIRenderer.Core
|
|||||||
TargetBitrate = Configuration.EncodingConfig.Bitrate,
|
TargetBitrate = Configuration.EncodingConfig.Bitrate,
|
||||||
MaxBitrate = Configuration.EncodingConfig.MaxBitrate,
|
MaxBitrate = Configuration.EncodingConfig.MaxBitrate,
|
||||||
GopSize = Configuration.EncodingConfig.KeyframeInterval
|
GopSize = Configuration.EncodingConfig.KeyframeInterval
|
||||||
|
GopSize = Configuration.EncodingConfig.KeyframeInterval,
|
||||||
|
ForceSoftware = Configuration.EncodingConfig.ForceSoftwareEncoder
|
||||||
};
|
};
|
||||||
|
|
||||||
videoFFmpeg = new FFmpegNativeEncoder(settings);
|
videoFFmpeg = new FFmpegNativeEncoder(settings);
|
||||||
|
|||||||
@@ -29,5 +29,6 @@ namespace ADOFAIRenderer.Data
|
|||||||
// ReSharper disable once InconsistentNaming
|
// ReSharper disable once InconsistentNaming
|
||||||
public int QP;
|
public int QP;
|
||||||
public double KeyframeInterval;
|
public double KeyframeInterval;
|
||||||
|
public bool ForceSoftwareEncoder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Text;
|
|
||||||
using ADOFAIRenderer.Core;
|
using ADOFAIRenderer.Core;
|
||||||
using ADOFAIRenderer.Data;
|
using ADOFAIRenderer.Data;
|
||||||
using ADOFAIRenderer.Util.FFmpeg;
|
using ADOFAIRenderer.Util.FFmpeg;
|
||||||
@@ -103,7 +102,8 @@ namespace ADOFAIRenderer.UI
|
|||||||
Bitrate = config.EncodingConfig.Bitrate,
|
Bitrate = config.EncodingConfig.Bitrate,
|
||||||
MaxBitrate = config.EncodingConfig.MaxBitrate,
|
MaxBitrate = config.EncodingConfig.MaxBitrate,
|
||||||
QP = config.EncodingConfig.QP,
|
QP = config.EncodingConfig.QP,
|
||||||
KeyframeInterval = config.EncodingConfig.KeyframeInterval
|
KeyframeInterval = config.EncodingConfig.KeyframeInterval,
|
||||||
|
ForceSoftwareEncoder = config.EncodingConfig.ForceSoftwareEncoder
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_root.Contains(_encodingConfigContainer))
|
if (_root.Contains(_encodingConfigContainer))
|
||||||
@@ -203,6 +203,14 @@ namespace ADOFAIRenderer.UI
|
|||||||
keyframeRow.Add(keyframeField);
|
keyframeRow.Add(keyframeField);
|
||||||
_encodingConfigContainer.Add(keyframeRow);
|
_encodingConfigContainer.Add(keyframeRow);
|
||||||
|
|
||||||
|
// 6.75. 강제 소프트웨어 인코더 로우 (라벨 + 토글)
|
||||||
|
var forceSoftwareRow = CreateRow();
|
||||||
|
var forceSoftwareLabel = CreateFormLabel("소프트웨어 인코더");
|
||||||
|
var forceSoftwareToggle = new Toggle { name = "ForceSoftwareEncoder", label = "", value = tempConfig.ForceSoftwareEncoder };
|
||||||
|
forceSoftwareRow.Add(forceSoftwareLabel);
|
||||||
|
forceSoftwareRow.Add(forceSoftwareToggle);
|
||||||
|
_encodingConfigContainer.Add(forceSoftwareRow);
|
||||||
|
|
||||||
// 7. QP = 0 (무손실) 경고 라벨 로우 생성 (ui-row 클래스를 상속받아 NanumSquareNeo 폰트가 적용되도록 처리)
|
// 7. QP = 0 (무손실) 경고 라벨 로우 생성 (ui-row 클래스를 상속받아 NanumSquareNeo 폰트가 적용되도록 처리)
|
||||||
var warningRow = CreateRow();
|
var warningRow = CreateRow();
|
||||||
warningRow.style.height = StyleKeyword.Auto;
|
warningRow.style.height = StyleKeyword.Auto;
|
||||||
@@ -240,10 +248,10 @@ namespace ADOFAIRenderer.UI
|
|||||||
{
|
{
|
||||||
if (System.Enum.TryParse<RateControlMode>(selectedModeStr, out var mode))
|
if (System.Enum.TryParse<RateControlMode>(selectedModeStr, out var mode))
|
||||||
{
|
{
|
||||||
bitrateRow.style.display = (mode == RateControlMode.CBR || mode == RateControlMode.VBR) ? DisplayStyle.Flex : DisplayStyle.None;
|
bitrateRow.style.display = mode is RateControlMode.CBR or RateControlMode.VBR ? DisplayStyle.Flex : DisplayStyle.None;
|
||||||
maxBitrateRow.style.display = (mode == RateControlMode.VBR) ? DisplayStyle.Flex : DisplayStyle.None;
|
maxBitrateRow.style.display = mode == RateControlMode.VBR ? DisplayStyle.Flex : DisplayStyle.None;
|
||||||
qpRow.style.display = (mode == RateControlMode.CQP) ? DisplayStyle.Flex : DisplayStyle.None;
|
qpRow.style.display = mode == RateControlMode.CQP ? DisplayStyle.Flex : DisplayStyle.None;
|
||||||
warningRow.style.display = (mode == RateControlMode.CQP && qpField.value == 0) ? DisplayStyle.Flex : DisplayStyle.None;
|
warningRow.style.display = mode == RateControlMode.CQP && qpField.value == 0 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +300,7 @@ namespace ADOFAIRenderer.UI
|
|||||||
tempConfig.MaxBitrate = maxBitrateField.value;
|
tempConfig.MaxBitrate = maxBitrateField.value;
|
||||||
tempConfig.QP = qpField.value;
|
tempConfig.QP = qpField.value;
|
||||||
tempConfig.KeyframeInterval = keyframeField.value;
|
tempConfig.KeyframeInterval = keyframeField.value;
|
||||||
|
tempConfig.ForceSoftwareEncoder = forceSoftwareToggle.value;
|
||||||
|
|
||||||
if (tempConfig.RateControlMode == RateControlMode.VBR && tempConfig.MaxBitrate < tempConfig.Bitrate)
|
if (tempConfig.RateControlMode == RateControlMode.VBR && tempConfig.MaxBitrate < tempConfig.Bitrate)
|
||||||
{
|
{
|
||||||
@@ -362,7 +371,8 @@ namespace ADOFAIRenderer.UI
|
|||||||
{
|
{
|
||||||
RateControlMode = RateControlMode.CBR,
|
RateControlMode = RateControlMode.CBR,
|
||||||
Bitrate = 30000, MaxBitrate = 50000,
|
Bitrate = 30000, MaxBitrate = 50000,
|
||||||
QP = 18, KeyframeInterval = 2.0
|
QP = 18, KeyframeInterval = 2.0,
|
||||||
|
ForceSoftwareEncoder = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
|||||||
|
|
||||||
/// <summary>GOP(Group of Pictures) 크기 (초). 키프레임 간격을 의미합니다.</summary>
|
/// <summary>GOP(Group of Pictures) 크기 (초). 키프레임 간격을 의미합니다.</summary>
|
||||||
public double GopSize;
|
public double GopSize;
|
||||||
|
|
||||||
|
/// <summary>소프트웨어 CPU 인코더를 강제 사용할지 여부.</summary>
|
||||||
|
public bool ForceSoftware;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ──────────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────────
|
||||||
@@ -214,7 +217,7 @@ namespace ADOFAIRenderer.Util.FFmpeg
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private string[] GetEncoderCandidates()
|
private string[] GetEncoderCandidates()
|
||||||
{
|
{
|
||||||
return GPUUtil.GetPrioritizedEncoderCandidates(_settings.Codec).ToArray();
|
return GPUUtil.GetPrioritizedEncoderCandidates(_settings.Codec, _settings.ForceSoftware).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
+9
-2
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using ADOFAIRenderer.Util.FFmpeg;
|
using ADOFAIRenderer.Util.FFmpeg;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
@@ -130,12 +131,18 @@ namespace ADOFAIRenderer.Util
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetPrioritizedEncoderCandidates(Codec codec)
|
public static List<string> GetPrioritizedEncoderCandidates(Codec codec, bool forceSoftware = false)
|
||||||
{
|
{
|
||||||
if (!CodecMap.TryGetValue(codec, out var list)) return new List<string>();
|
if (!CodecMap.TryGetValue(codec, out var list)) return new List<string>();
|
||||||
|
|
||||||
var vendor = GetActiveGPUVendor();
|
|
||||||
var prioritized = new List<string>();
|
var prioritized = new List<string>();
|
||||||
|
if (forceSoftware)
|
||||||
|
{
|
||||||
|
prioritized.AddRange(from item in list where item.Item1 == GPUVendor.Unknown select item.Item2);
|
||||||
|
return prioritized;
|
||||||
|
}
|
||||||
|
|
||||||
|
var vendor = GetActiveGPUVendor();
|
||||||
var others = new List<string>();
|
var others = new List<string>();
|
||||||
|
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
|
|||||||
Reference in new issue
Block a user