mirror of
https://github.com/staxrip/staxrip.git
synced 2026-10-18 14:40:32 +08:00
720 lines
28 KiB
VB.net
720 lines
28 KiB
VB.net
Imports System.Text
|
|
Imports StaxRip.UI
|
|
Imports StaxRip.VideoEncoderCommandLine
|
|
|
|
<Serializable()>
|
|
Public Class VvencffappEnc
|
|
Inherits BasicVideoEncoder
|
|
|
|
Property ParamsStore As New PrimitiveStore
|
|
|
|
Sub New()
|
|
Name = "vvencFFapp"
|
|
Params.ApplyPresetDefaultValues()
|
|
Params.ApplyPresetValues()
|
|
End Sub
|
|
|
|
Overloads Shared ReadOnly Property Package As Package
|
|
Get
|
|
Return Package.VVenCFFapp
|
|
End Get
|
|
End Property
|
|
|
|
<NonSerialized>
|
|
Private ParamsValue As VvencffappParams
|
|
|
|
Property Params As VvencffappParams
|
|
Get
|
|
If ParamsValue Is Nothing Then
|
|
ParamsValue = New VvencffappParams
|
|
ParamsValue.Init(ParamsStore)
|
|
End If
|
|
|
|
Return ParamsValue
|
|
End Get
|
|
Set(value As VvencffappParams)
|
|
ParamsValue = value
|
|
End Set
|
|
End Property
|
|
|
|
Public Overrides Property OverridesTargetFileName As Boolean
|
|
Get
|
|
Return Params.OverrideTargetFileName.Value
|
|
End Get
|
|
Set(value As Boolean)
|
|
If Params.OverrideTargetFileName.Value <> value Then
|
|
Params.OverrideTargetFileName.Value = value
|
|
Params.RaiseValueChanged(Params.OverrideTargetFileName)
|
|
End If
|
|
End Set
|
|
End Property
|
|
|
|
Public Overrides ReadOnly Property OverridingTargetFileName As String
|
|
Get
|
|
Dim value = Macro.ExpandParamValues(Params.TargetFileName.Value, Params.Items)
|
|
value = value.Replace(Environment.NewLine, "")
|
|
Return value
|
|
End Get
|
|
End Property
|
|
|
|
Overrides ReadOnly Property Codec As String
|
|
Get
|
|
Return "vvc"
|
|
End Get
|
|
End Property
|
|
|
|
Overrides ReadOnly Property OutputExt As String
|
|
Get
|
|
Return "vvc"
|
|
End Get
|
|
End Property
|
|
|
|
Overrides Sub Encode()
|
|
Encode("Video encoding", GetArgs(1, 0, 0, Nothing, p.Script), s.EncoderProcessPriority)
|
|
|
|
If Params.Mode.Value = VvencffappRateMode.TwoPass Then
|
|
Encode("Video encoding second pass", GetArgs(2, 0, 0, Nothing, p.Script), s.EncoderProcessPriority)
|
|
End If
|
|
End Sub
|
|
|
|
Overloads Sub Encode(passName As String, commandLine As String, priority As ProcessPriorityClass)
|
|
If Not CanChunkEncode() Then
|
|
p.Script.Synchronize()
|
|
End If
|
|
|
|
Using proc As New Proc
|
|
proc.Package = Package.VVenCFFapp
|
|
proc.Header = passName
|
|
proc.Encoding = Encoding.UTF8
|
|
proc.Priority = priority
|
|
proc.FrameCount = p.Script.GetFrameCount
|
|
proc.SkipString = "TId: "
|
|
|
|
If commandLine.Contains("|") Then
|
|
proc.File = "cmd.exe"
|
|
proc.Arguments = "/S /C """ + commandLine + """"
|
|
Else
|
|
proc.CommandLine = commandLine
|
|
End If
|
|
|
|
proc.Start()
|
|
End Using
|
|
End Sub
|
|
|
|
Overrides Property Bitrate As Integer
|
|
Get
|
|
Return CInt(Params.TargetBitrate.Value)
|
|
End Get
|
|
Set(value As Integer)
|
|
Params.TargetBitrate.Value = value
|
|
End Set
|
|
End Property
|
|
|
|
Overrides Function CanChunkEncode() As Boolean
|
|
Return CInt(Params.Chunks.Value) > 1
|
|
End Function
|
|
|
|
Overrides Function GetChunks() As Integer
|
|
Return CInt(Params.Chunks.Value)
|
|
End Function
|
|
|
|
Overrides Function GetChunkEncodeActions() As List(Of Action)
|
|
Dim maxFrame = If(Params.Decoder.Value = 0, p.Script.GetFrameCount(), p.SourceFrames)
|
|
Dim chunkCount = CInt(Params.Chunks.Value)
|
|
Dim startFrame = CInt(Params.FrameSkip.Value)
|
|
Dim length = If(CInt(Params.FramesToBeEncoded.Value) > 0, CInt(Params.FramesToBeEncoded.Value), maxFrame - startFrame)
|
|
Dim endFrame = Math.Min(startFrame + length - 1, maxFrame)
|
|
Dim chunkLength = length \ chunkCount
|
|
Dim ret As New List(Of Action)
|
|
|
|
For chunk = 0 To chunkCount - 1
|
|
Dim chunkStart = startFrame + (chunk * chunkLength)
|
|
Dim chunkEnd = If(chunk <> chunkCount - 1, chunkStart + (chunkLength - 1), endFrame)
|
|
Dim chunkName = ""
|
|
Dim passName = ""
|
|
|
|
If chunkCount > 1 Then
|
|
chunkName = "_chunk" & (chunk + 1)
|
|
passName = " chunk " & (chunk + 1)
|
|
End If
|
|
|
|
If Params.Mode.Value = VvencffappRateMode.TwoPass Then
|
|
ret.Add(Sub()
|
|
Encode("Video encoding pass 1" + passName, GetArgs(1, chunkStart, chunkEnd, chunkName, p.Script), s.EncoderProcessPriority)
|
|
Encode("Video encoding pass 2" + passName, GetArgs(2, chunkStart, chunkEnd, chunkName, p.Script), s.EncoderProcessPriority)
|
|
End Sub)
|
|
Else
|
|
ret.Add(Sub() Encode("Video encoding" + passName, GetArgs(1, chunkStart, chunkEnd, chunkName, p.Script), s.EncoderProcessPriority))
|
|
End If
|
|
Next
|
|
|
|
Return ret
|
|
End Function
|
|
|
|
Overrides Sub RunCompCheck()
|
|
If Not g.VerifyRequirements OrElse Not g.IsValidSource Then
|
|
Exit Sub
|
|
End If
|
|
|
|
Dim newParams As New VvencffappParams
|
|
Dim newStore = ObjectHelp.GetCopy(ParamsStore)
|
|
newParams.Init(newStore)
|
|
|
|
Dim enc As New VvencffappEnc
|
|
enc.Params = newParams
|
|
enc.Params.Mode.Value = VvencffappRateMode.SingleQuant
|
|
enc.Params.Quant.Value = enc.Params.CompCheck.Value
|
|
|
|
Dim script As New VideoScript
|
|
script.Engine = p.Script.Engine
|
|
script.Filters = p.Script.GetFiltersCopy
|
|
Dim code As String
|
|
Dim framerate = p.Script.GetFramerate()
|
|
Dim totalFrames = p.Script.GetFrameCount()
|
|
Dim range = framerate * p.CompCheckTestblockSeconds
|
|
Dim every = (100 / p.CompCheckPercentage) * range
|
|
|
|
If script.Engine = ScriptEngine.AviSynth Then
|
|
code = $"SelectRangeEvery({CInt(every)},{CInt(range)})"
|
|
Else
|
|
code = "fpsnum = clip.fps_num" + BR
|
|
code += "fpsden = clip.fps_den" + BR
|
|
code += $"clip = core.std.SelectEvery(clip = clip, cycle = {CInt(every)}, offsets = range({CInt(range)}))" + BR
|
|
code += "clip = core.std.AssumeFPS(clip = clip, fpsnum = fpsnum, fpsden = fpsden)"
|
|
End If
|
|
|
|
script.Filters.Add(New VideoFilter("aaa", "aaa", code))
|
|
script.Path = Path.Combine(p.TempDir, p.TargetFile.Base + "_CompCheck." + script.FileType)
|
|
script.Synchronize()
|
|
|
|
Log.WriteLine(BR + script.GetFullScript + BR)
|
|
|
|
Dim commandLine = enc.Params.GetArgs(0, 0, 0, Nothing, script, Path.Combine(p.TempDir, p.TargetFile.Base + "_CompCheck." + OutputExt), True, True)
|
|
|
|
Try
|
|
Encode("Compressibility Check", commandLine, s.EncoderProcessPriority)
|
|
Catch ex As AbortException
|
|
Exit Sub
|
|
Catch ex As Exception
|
|
g.ShowException(ex)
|
|
Exit Sub
|
|
End Try
|
|
|
|
Dim bits = (New FileInfo(Path.Combine(p.TempDir, p.TargetFile.Base + "_CompCheck." + OutputExt)).Length) * 8
|
|
p.Compressibility = (bits / script.GetFrameCount) / (p.TargetWidth * p.TargetHeight)
|
|
|
|
OnAfterCompCheck()
|
|
g.MainForm.Assistant()
|
|
|
|
Log.WriteLine("Quality: " & CInt(Calc.GetPercent).ToString() + " %")
|
|
Log.WriteLine("Compressibility: " + p.Compressibility.ToString("f3"))
|
|
Log.Save()
|
|
End Sub
|
|
|
|
Overloads Function GetArgs(
|
|
pass As Integer,
|
|
startFrame As Integer,
|
|
endFrame As Integer,
|
|
chunkName As String,
|
|
script As VideoScript,
|
|
Optional includePaths As Boolean = True) As String
|
|
|
|
Return Params.GetArgs(pass, startFrame, endFrame, chunkName, script, OutputPath.DirAndBase + OutputExtFull, includePaths, True)
|
|
End Function
|
|
|
|
Overrides Sub ShowConfigDialog(Optional param As CommandLineParam = Nothing)
|
|
Dim newParams As New VvencffappParams
|
|
Dim store = ObjectHelp.GetCopy(ParamsStore)
|
|
newParams.Init(store)
|
|
newParams.ApplyPresetDefaultValues()
|
|
|
|
Using form As New CommandLineForm(newParams)
|
|
form.HTMLHelpFunc = Function() $"<p><a href=""{Package.VVenCFFapp.HelpURL}"">vvencFFapp Online Help</a></p>" +
|
|
$"<h2>vvencFFapp Console Help</h2><pre>{HelpDocument.ConvertChars(Package.VVenCFFapp.CreateHelpfile())}</pre>"
|
|
|
|
Dim a = Sub()
|
|
Dim enc = ObjectHelp.GetCopy(Me)
|
|
Dim params2 As New VvencffappParams
|
|
Dim store2 = ObjectHelp.GetCopy(store)
|
|
params2.Init(store2)
|
|
enc.Params = params2
|
|
enc.ParamsStore = store2
|
|
SaveProfile(enc)
|
|
End Sub
|
|
|
|
form.cms.Add("Save Profile...", a, Keys.Control Or Keys.S, Symbol.Save)
|
|
|
|
If Not String.IsNullOrWhiteSpace(param?.Path) Then
|
|
form.SimpleUI.ShowPage(param?.Path)
|
|
form.cbGoTo.Text = param.GetSwitches().FirstOrDefault()
|
|
End If
|
|
|
|
If form.ShowDialog() = DialogResult.OK Then
|
|
AutoCompCheckValue = CInt(newParams.CompCheckAimedQuality.Value)
|
|
Params = newParams
|
|
ParamsStore = store
|
|
OnStateChange()
|
|
UpdateTargetFile()
|
|
End If
|
|
End Using
|
|
End Sub
|
|
|
|
Overrides Property QualityMode() As Boolean
|
|
Get
|
|
Return Params.Mode.Value = VvencffappRateMode.SingleQuant
|
|
End Get
|
|
Set(Value As Boolean)
|
|
End Set
|
|
End Property
|
|
|
|
Public Overrides ReadOnly Property CommandLineParams As CommandLineParams
|
|
Get
|
|
Return Params
|
|
End Get
|
|
End Property
|
|
|
|
Sub SetMuxer()
|
|
Muxer = New MP4Muxer()
|
|
End Sub
|
|
|
|
Overrides Function CreateEditControl() As Control
|
|
Return New VvencffappControl(Me) With {.Dock = DockStyle.Fill}
|
|
End Function
|
|
|
|
Shared Function Test() As String
|
|
Dim tester As New ConsolAppTester
|
|
|
|
tester.IgnoredSwitches = ""
|
|
|
|
tester.UndocumentedSwitches = ""
|
|
|
|
tester.Package = Package.VVenCFFapp
|
|
tester.CodeFile = Path.Combine(Folder.Startup.Parent, "Encoding", "VvencffappEnc.vb")
|
|
|
|
Return tester.Test
|
|
End Function
|
|
End Class
|
|
|
|
Public Class VvencffappParams
|
|
Inherits CommandLineParams
|
|
|
|
Sub New()
|
|
Title = "vvencFFapp Options"
|
|
End Sub
|
|
|
|
Public Overrides ReadOnly Property Package As Package
|
|
Get
|
|
Return VvencffappEnc.Package
|
|
End Get
|
|
End Property
|
|
|
|
|
|
Property OverrideTargetFileName As New BoolParam() With {
|
|
.Text = "Override Target File Name",
|
|
.Init = False}
|
|
|
|
Property TargetFileName As New StringParam With {
|
|
.Text = "Target File Name",
|
|
.Quotes = QuotesMode.Never,
|
|
.TextChangedAction = Sub(text) TargetFileNamePreview.Value = Macro.ExpandParamValues(text, Items),
|
|
.Init = "%source_name%_new",
|
|
.InitAction = Sub(tb)
|
|
tb.Edit.MultilineHeightFactor = 6
|
|
tb.Edit.TextBox.Font = FontManager.GetCodeFont()
|
|
End Sub}
|
|
|
|
Property TargetFileNamePreview As New StringParam With {
|
|
.Text = "Preview",
|
|
.Quotes = QuotesMode.Never,
|
|
.InitAction = Sub(tb)
|
|
tb.Edit.MultilineHeightFactor = 3
|
|
tb.Edit.TextBox.Font = FontManager.GetCodeFont()
|
|
tb.Edit.TextBox.ReadOnly = True
|
|
BlockValueChanged = True
|
|
.Value = Macro.ExpandParamValues(TargetFileName.Value, Items)
|
|
BlockValueChanged = False
|
|
End Sub}
|
|
|
|
Property Decoder As New OptionParam With {
|
|
.Text = "Decoder",
|
|
.Options = {"AviSynth/VapourSynth", "QSVEnc (Intel)", "ffmpeg (Intel)", "ffmpeg (DXVA2)"},
|
|
.Values = {"script", "qs", "ffqsv", "ffdxva"}}
|
|
|
|
Property PipingToolAVS As New OptionParam With {
|
|
.Name = "PipingToolAVS",
|
|
.Text = "Pipe",
|
|
.VisibleFunc = Function() p.Script.IsAviSynth AndAlso Decoder.Value = 0,
|
|
.Options = {"Automatic", "avs2pipemod", "ffmpeg"}}
|
|
|
|
Property PipingToolVS As New OptionParam With {
|
|
.Name = "PipingToolVS",
|
|
.Text = "Pipe",
|
|
.VisibleFunc = Function() p.Script.IsVapourSynth AndAlso Decoder.Value = 0,
|
|
.Options = {"Automatic", "vspipe", "ffmpeg"}}
|
|
|
|
Property CompCheck As New NumParam With {
|
|
.Name = "CompCheckQuant",
|
|
.Text = "Comp. Check",
|
|
.Value = 18,
|
|
.Help = "QP value used as 100% for the compressibility check.",
|
|
.Config = {1, 50}}
|
|
|
|
Property CompCheckAimedQuality As New NumParam With {
|
|
.Name = "CompCheckAimedQuality",
|
|
.Text = "Aimed Quality",
|
|
.Value = 50,
|
|
.Help = "Percent value to adjusts the target file size or image size after the compressibility check accordingly.",
|
|
.Config = {1, 100}}
|
|
|
|
Property Chunks As New NumParam With {
|
|
.Text = "Chunks",
|
|
.Init = 1,
|
|
.Config = {1, 32}}
|
|
|
|
Property Mode As New OptionParam With {
|
|
.Switches = {"--TargetBitrate", "--QP", "--Pass", "--NumPasses", "--RCStatsFile"},
|
|
.Name = "Mode",
|
|
.Text = "Mode",
|
|
.Options = {"Bitrate", "Quantizer", "Two Pass"},
|
|
.Value = 1}
|
|
|
|
Property Quant As New NumParam With {
|
|
.Switches = {"--QP", "-q"},
|
|
.Name = "Quant",
|
|
.Text = "Quantizer",
|
|
.DefaultValue = 32,
|
|
.Value = 32,
|
|
.VisibleFunc = Function() Mode.Value = VvencffappRateMode.SingleQuant,
|
|
.Config = {0, 63, 1}}
|
|
|
|
Property TargetBitrate As New NumParam With {
|
|
.HelpSwitch = "--TargetBitrate",
|
|
.Text = "Target Bitrate",
|
|
.Init = 5000,
|
|
.VisibleFunc = Function() Mode.Value <> VvencffappRateMode.SingleQuant,
|
|
.Config = {0, 1000000, 100}}
|
|
|
|
Property Preset As New OptionParam With {
|
|
.Switch = "--preset",
|
|
.Text = "Preset",
|
|
.Options = {"None", "Faster", "Fast", "Medium", "Slow", "Slower", "Medium_LowDecEnergy", "Firstpass", "ToolTest"},
|
|
.Init = 3}
|
|
|
|
Property FrameSkip As New NumParam With {
|
|
.HelpSwitch = "--FrameSkip",
|
|
.Text = "Frames To Be Skipped"}
|
|
|
|
Property FramesToBeEncoded As New NumParam With {
|
|
.HelpSwitch = "--FramesToBeEncoded",
|
|
.Text = "Frames To Be Encoded"}
|
|
|
|
|
|
|
|
|
|
Property Custom As New StringParam With {
|
|
.Text = "Custom",
|
|
.Quotes = QuotesMode.Never,
|
|
.AlwaysOn = True,
|
|
.InitAction = Sub(tb)
|
|
tb.Edit.MultilineHeightFactor = 6
|
|
tb.Edit.TextBox.Font = FontManager.GetCodeFont()
|
|
End Sub}
|
|
|
|
Property CustomFirstPass As New StringParam With {
|
|
.Text = "Custom" + BR + "First Pass",
|
|
.Quotes = QuotesMode.Never,
|
|
.VisibleFunc = Function() Mode.Value = VvencffappRateMode.TwoPass,
|
|
.InitAction = Sub(tb)
|
|
tb.Edit.MultilineHeightFactor = 6
|
|
tb.Edit.TextBox.Font = FontManager.GetCodeFont()
|
|
End Sub}
|
|
|
|
Property CustomSecondPass As New StringParam With {
|
|
.Text = "Custom" + BR + "Second Pass",
|
|
.Quotes = QuotesMode.Never,
|
|
.VisibleFunc = Function() Mode.Value = VvencffappRateMode.TwoPass,
|
|
.InitAction = Sub(tb)
|
|
tb.Edit.MultilineHeightFactor = 6
|
|
tb.Edit.TextBox.Font = FontManager.GetCodeFont()
|
|
End Sub}
|
|
|
|
|
|
|
|
Overrides ReadOnly Property Items As List(Of CommandLineParam)
|
|
Get
|
|
If ItemsValue Is Nothing Then
|
|
ItemsValue = New List(Of CommandLineParam)
|
|
|
|
Add("Basic", Decoder, PipingToolAVS, PipingToolVS, Mode, TargetBitrate, Quant, Preset,
|
|
New OptionParam() With {.Switch = "--Profile", .Name = "Profile", .Text = "Profile", .Options = {"Automatic", "main_10", "main_10_still_picture"}},
|
|
New OptionParam() With {.Switch = "--Level", .Name = "Level", .Text = "Level", .Options = {"Automatic", "1.0", "2.0", "2.1", "3.0", "3.1", "4.0", "4.1", "5.0", "5.1", "5.2", "6.0", "6.1", "6.2", "6.3", "15.5"}},
|
|
New OptionParam() With {.Switch = "--Tier", .Name = "Tier", .Text = "Tier", .Options = {"Main", "High"}},
|
|
New OptionParam() With {.Switch = "--Verbosity", .Name = "Verbosity", .Text = "Verbosity", .Options = {"0: Silent", "1: Error", "2: Warning", "3: Info", "4: Notice", "5: Verbose (Default)", "6: Debug"}, .Init = 5, .IntegerValue = True},
|
|
New OptionParam() With {.Switch = "--SIMD", .Name = "SIMD", .Text = "SIMD", .Options = {"Automatic", "SCALAR", "SSE41", "SSE42", "AVX", "AVX2", "AVX512"}}
|
|
)
|
|
Add("I/O",
|
|
New OptionParam() With {.Switch = "--OutputBitDepth", .Name = "OutputBitDepth", .Text = "Output Bit-Depth", .Options = {"Automatic", "8", "10", "12"}},
|
|
FrameSkip, FramesToBeEncoded
|
|
)
|
|
Add("Threading",
|
|
New NumParam() With {.Switch = "--Threads", .Name = "Threads", .Text = "Threads", .Config = {0, 128, 1, 0}},
|
|
New NumParam() With {.Switch = "--MaxParallelFrames", .Name = "MaxParallelFrames", .Text = "Max Parallel Frames", .Config = {-1, 128, 1, 0}, .Init = -1}
|
|
)
|
|
'Add("Slice Decision",
|
|
|
|
')
|
|
Add("Rate Control",
|
|
New NumParam() With {.Switch = "--LookAhead", .Name = "LookAhead", .Text = "LookAhead", .Config = {-1, 1, 1, 0}, .Init = -1}
|
|
)
|
|
'Add("Quantization",
|
|
|
|
')
|
|
Add("Custom", Custom, CustomFirstPass, CustomSecondPass)
|
|
Add("Other",
|
|
OverrideTargetFileName, TargetFileName, TargetFileNamePreview,
|
|
New LineParam(),
|
|
Chunks,
|
|
CompCheck, CompCheckAimedQuality
|
|
)
|
|
|
|
'ItemsValue = ItemsValue.OrderBy(Function(i) i.Weight).ToList
|
|
End If
|
|
|
|
Return ItemsValue
|
|
End Get
|
|
End Property
|
|
|
|
Overrides Function GetCommandLinePreview() As String
|
|
Dim ret = GetCommandLine(True, True, 1)
|
|
|
|
If Mode.Value = VvencffappRateMode.TwoPass Then
|
|
ret += BR2 + GetCommandLine(True, True, 2)
|
|
End If
|
|
|
|
Return ret
|
|
End Function
|
|
|
|
Public Overrides Sub ShowHelp(options As String())
|
|
Using td As New TaskDialog(Of String)
|
|
td.Title = String.Join(", ", options)
|
|
td.AddCommand("Online Help")
|
|
td.AddCommand("Console Help")
|
|
|
|
Select Case td.Show
|
|
Case "Online Help"
|
|
Dim ret = GetHelpOption(options)
|
|
|
|
If ret <> "" Then
|
|
g.ShellExecute("https://github.com/fraunhoferhhi/vvenc/wiki/Usage#how-to-use-the-full-featured-expert-mode-encoder")
|
|
End If
|
|
Case "Console Help"
|
|
ShowConsoleHelp(Package.VVenCFFapp, options)
|
|
End Select
|
|
End Using
|
|
End Sub
|
|
|
|
Private BlockValueChanged As Boolean
|
|
|
|
Protected Overrides Sub OnValueChanged(item As CommandLineParam)
|
|
If BlockValueChanged Then Exit Sub
|
|
|
|
If item Is Preset Then
|
|
BlockValueChanged = True
|
|
ApplyPresetValues()
|
|
BlockValueChanged = False
|
|
End If
|
|
|
|
If item IsNot TargetFileName AndAlso item IsNot TargetFileNamePreview Then TargetFileName.TextChangedAction?.Invoke(TargetFileName.Value)
|
|
|
|
MyBase.OnValueChanged(item)
|
|
End Sub
|
|
|
|
Overloads Overrides Function GetCommandLine(
|
|
includePaths As Boolean,
|
|
includeExecutable As Boolean,
|
|
Optional pass As Integer = 1) As String
|
|
|
|
Return GetArgs(pass, 0, 0, Nothing, p.Script, p.VideoEncoder.OutputPath.DirAndBase + p.VideoEncoder.OutputExtFull, includePaths, includeExecutable)
|
|
End Function
|
|
|
|
Overloads Function GetArgs(
|
|
pass As Integer,
|
|
startFrame As Integer,
|
|
endFrame As Integer,
|
|
chunkName As String,
|
|
script As VideoScript,
|
|
targetPath As String,
|
|
includePaths As Boolean,
|
|
includeExecutable As Boolean) As String
|
|
|
|
ApplyPresetDefaultValues()
|
|
|
|
Dim sb As New StringBuilder
|
|
Dim pipeTool = If(p.Script.IsAviSynth, PipingToolAVS, PipingToolVS).ValueText.ToLowerInvariant()
|
|
Dim isSingleChunk = endFrame = 0
|
|
|
|
If includePaths AndAlso includeExecutable Then
|
|
Dim isCropped = (p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) <> 0 AndAlso Decoder.ValueText <> "avs" AndAlso p.Script.IsFilterActive("Crop")
|
|
Dim pipeString = ""
|
|
|
|
Select Case Decoder.ValueText.ToLowerInvariant()
|
|
Case "script"
|
|
'Broken ANSI fallback taken from x265
|
|
If pipeTool = "automatic" OrElse (p.Script.IsAviSynth AndAlso Not TextEncoding.IsProcessUTF8 AndAlso Not TextEncoding.ArePathsSupportedByASCIIEncoding) Then
|
|
pipeTool = If(p.Script.IsAviSynth, "avs2pipemod", "vspipe")
|
|
End If
|
|
|
|
Select Case pipeTool
|
|
Case "avs2pipemod"
|
|
Dim chunk = If(isSingleChunk, "", $" -trim={startFrame},{endFrame}")
|
|
Dim dll = If(FrameServerHelp.IsPortable, $" -dll={Package.AviSynth.Path.Escape}", "")
|
|
pipeString = Package.avs2pipemod.Path.Escape + dll + chunk + " -y4mp " + script.Path.Escape
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
Case "vspipe"
|
|
Dim chunk = If(isSingleChunk, "", $" --start {startFrame} --end {endFrame}")
|
|
pipeString = Package.vspipe.Path.Escape + " " + script.Path.Escape + " - --container y4m" + chunk
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
Case "ffmpeg"
|
|
pipeString = Package.ffmpeg.Path.Escape + If(p.Script.IsVapourSynth, " -f vapoursynth", "") + " -i " + script.Path.Escape + " -f yuv4mpegpipe -strict -1 -loglevel fatal -hide_banner -"
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
End Select
|
|
Case "qs"
|
|
Dim crop = If(isCropped, " --crop " & p.CropLeft & "," & p.CropTop & "," & p.CropRight & "," & p.CropBottom, "")
|
|
pipeString = Package.QSVEncC.Path.Escape + " -o - -c raw" + crop + " -i " + p.SourceFile.Escape
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
Case "ffqsv"
|
|
Dim crop = If(isCropped, $" -vf ""crop={p.SourceWidth - p.CropLeft - p.CropRight}:{p.SourceHeight - p.CropTop - p.CropBottom}:{p.CropLeft}:{p.CropTop}""", "")
|
|
Dim pix_fmt = If(p.SourceVideoBitDepth = 10 OrElse p.Script.Info.BitDepth >= 10, "yuv420p10le", "yuv420p")
|
|
pipeString = Package.ffmpeg.Path.Escape + " -threads 1 -hwaccel qsv -i " + p.SourceFile.Escape + " -f yuv4mpegpipe -pix_fmt " + pix_fmt + " -strict -1" + crop + " -loglevel fatal -hide_banner -"
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
Case "ffdxva"
|
|
Dim crop = If(isCropped, $" -vf ""crop={p.SourceWidth - p.CropLeft - p.CropRight}:{p.SourceHeight - p.CropTop - p.CropBottom}:{p.CropLeft}:{p.CropTop}""", "")
|
|
Dim pix_fmt = If(p.SourceVideoBitDepth = 10 OrElse p.Script.Info.BitDepth >= 10, "yuv420p10le", "yuv420p")
|
|
pipeString = Package.ffmpeg.Path.Escape + " -threads 1 -hwaccel dxva2 -i " + p.SourceFile.Escape + " -f yuv4mpegpipe -pix_fmt " + pix_fmt + " -strict -1" + crop + " -loglevel fatal -hide_banner -"
|
|
|
|
sb.Append(pipeString & " | " & Package.VVenCFFapp.Path.Escape)
|
|
End Select
|
|
End If
|
|
|
|
If includePaths Then
|
|
Dim input = If(Decoder.Value = 0 AndAlso pipeTool = "automatic", script.Path.Escape, " --InputFile -")
|
|
|
|
If (Mode.Value = VvencffappRateMode.TwoPass AndAlso pass = 1) Then
|
|
sb.Append(input)
|
|
sb.Append(" --BitstreamFile NUL")
|
|
Else
|
|
sb.Append(input)
|
|
sb.Append(" --BitstreamFile " + (targetPath.DirAndBase + chunkName + targetPath.ExtFull).Escape)
|
|
End If
|
|
|
|
If Decoder.Value <> 0 OrElse pipeTool <> "automatic" Then
|
|
sb.Append(" --y4m")
|
|
End If
|
|
|
|
If Mode.Value = VvencffappRateMode.TwoPass Then
|
|
sb.Append(" --RCStatsFile " + (targetPath.DirAndBase + chunkName + ".stats").Escape)
|
|
End If
|
|
End If
|
|
|
|
If isSingleChunk Then
|
|
If FrameSkip.Value > 0 AndAlso Not IsCustom(pass, "--FrameSkip") Then
|
|
sb.Append($" --FrameSkip {FrameSkip.Value}")
|
|
End If
|
|
|
|
If FramesToBeEncoded.Value > 0 AndAlso Not IsCustom(pass, "--FramesToBeEncoded") Then
|
|
Dim maxFrames = If(script.GetFrameCount > 0, script.GetFrameCount - FrameSkip.Value, FramesToBeEncoded.Value)
|
|
maxFrames = If(maxFrames < 0, 0, maxFrames)
|
|
sb.Append($" --FramesToBeEncoded {Math.Min(maxFrames, FramesToBeEncoded.Value)}")
|
|
End If
|
|
'Else
|
|
' If includePaths Then
|
|
' sb.Append($" --FrameSkip {startFrame} --FramesToBeEncoded {endFrame - startFrame + 1}")
|
|
' End If
|
|
End If
|
|
|
|
If includePaths Then
|
|
sb.Append($" --Size {p.TargetWidth}x{p.TargetHeight}")
|
|
End If
|
|
|
|
If Mode.Value = VvencffappRateMode.TwoPass Then
|
|
sb.Append(" --NumPasses 2")
|
|
sb.Append(" --Pass " & pass)
|
|
|
|
If pass = 1 Then
|
|
If CustomFirstPass.Value <> "" Then
|
|
sb.Append(" " + CustomFirstPass.Value)
|
|
End If
|
|
Else
|
|
If CustomSecondPass.Value <> "" Then
|
|
sb.Append(" " + CustomSecondPass.Value)
|
|
End If
|
|
End If
|
|
End If
|
|
|
|
'If includePaths AndAlso (MultiPassOptDistortion.Value OrElse MultiPassOptAnalysis.Value) Then
|
|
' sb.Append(" --analysis-reuse-file " + (targetPath.DirAndBase + chunkName + ".analysis").Escape)
|
|
'End If
|
|
|
|
If Mode.Value = VvencffappRateMode.SingleQuant Then
|
|
If Not IsCustom(pass, "--QP") AndAlso Quant.Value <> Quant.DefaultValue Then
|
|
sb.Append(" --QP " + CInt(Quant.Value).ToString)
|
|
End If
|
|
Else
|
|
If Not IsCustom(pass, "--TargetBitrate") Then
|
|
sb.Append(" --TargetBitrate " & If(pass = 1, TargetBitrate.Value, p.VideoBitrate) & "k")
|
|
End If
|
|
End If
|
|
|
|
Dim q = From i In Items Where i.GetArgs <> "" AndAlso Not IsCustom(pass, i.GetSwitches())
|
|
|
|
If q.Count > 0 Then
|
|
sb.Append(" " + q.Select(Function(item) item.GetArgs).Join(" "))
|
|
End If
|
|
|
|
Return Macro.Expand(sb.ToString.Trim.FixBreak.Replace(BR, " "))
|
|
End Function
|
|
|
|
Function IsCustom(pass As Integer, switches As String()) As Boolean
|
|
If switches Is Nothing Then Return False
|
|
|
|
Return switches.Any(Function(switch) IsCustom(pass, switch))
|
|
End Function
|
|
|
|
Function IsCustom(pass As Integer, switch As String) As Boolean
|
|
If switch = "" Then
|
|
Return False
|
|
End If
|
|
|
|
If Mode.Value = VvencffappRateMode.TwoPass Then
|
|
If pass = 1 Then
|
|
If CustomFirstPass.Value?.Contains(switch + " ") OrElse CustomFirstPass.Value?.EndsWith(switch) Then
|
|
Return True
|
|
End If
|
|
Else
|
|
If CustomSecondPass.Value?.Contains(switch + " ") OrElse CustomSecondPass.Value?.EndsWith(switch) Then
|
|
Return True
|
|
End If
|
|
End If
|
|
End If
|
|
|
|
Return If(Custom.Value?.Contains(switch + " ") OrElse Custom.Value?.EndsWith(switch), False)
|
|
End Function
|
|
|
|
Sub ApplyPresetValues()
|
|
End Sub
|
|
|
|
Sub ApplyPresetDefaultValues()
|
|
End Sub
|
|
End Class
|
|
|
|
Public Enum VvencffappRateMode
|
|
SingleBitrate
|
|
SingleQuant
|
|
TwoPass
|
|
End Enum
|