Files
staxrip/General/VideoEncoder.vb
T
2016-03-14 03:24:20 +01:00

1915 lines
68 KiB
VB.net

Imports System.Globalization
Imports System.Text
Imports StaxRip.UI
Imports StaxRip.CommandLine
<Serializable()>
MustInherit Class VideoEncoder
Inherits Profile
Implements IComparable(Of VideoEncoder)
MustOverride Sub Encode()
MustOverride ReadOnly Property OutputFileType As String
Overridable Property Passes As Integer
Overridable Property QualityMode As Boolean
Property AutoCompCheckValue As Integer = 70
Property Muxer As Muxer = New MkvMuxer
Public MustOverride Sub ShowConfigDialog()
Sub New(name As String)
MyBase.New(name)
CanEditValue = True
End Sub
Private OutputPathValue As String
Overridable ReadOnly Property OutputPath() As String
Get
If TypeOf Muxer Is EncoderMuxerBase OrElse TypeOf Muxer Is NullMuxer Then
Return p.TargetFile
Else
Return p.TempDir + p.Name + "_out." + OutputFileType
End If
End Get
End Property
Overridable Function GetMenu() As MenuList
End Function
Sub AfterEncoding()
If Not g.WasFileJustWritten(OutputPath) Then
Throw New ErrorAbortException("Encoder output file is missing", OutputPath)
Else
Log.WriteLine(MediaInfo.GetSummary(OutputPath))
End If
End Sub
Overrides Function CreateEditControl() As Control
Dim ret As New ToolStripEx
ret.ShowItemToolTips = False
ret.GripStyle = ToolStripGripStyle.Hidden
ret.BackColor = System.Drawing.SystemColors.Window
ret.Dock = DockStyle.Fill
ret.BackColor = System.Drawing.SystemColors.Window
ret.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow
ret.Padding = New Padding(1, 1, 0, 0)
For Each i In GetMenu()
Dim b As New ToolStripButton
b.Margin = New Padding(0)
b.Text = i.Key
b.Padding = New Padding(4)
Dim happy = i
AddHandler b.Click, Sub() happy.Value.Invoke()
b.TextAlign = ContentAlignment.MiddleLeft
ret.Items.Add(b)
Next
Return ret
End Function
Overridable ReadOnly Property IsCompCheckEnabled() As Boolean
Get
Return Not QualityMode
End Get
End Property
Protected Sub OnAfterCompCheck()
If p.CompCheckAction = CompCheckAction.AdjustFileSize Then
Dim oldSize = g.MainForm.tbSize.Text
g.MainForm.tbSize.Text = g.GetAutoSize(AutoCompCheckValue).ToString
Log.WriteLine("Target size: " & oldSize & " MB -> " + g.MainForm.tbSize.Text + " MB")
ElseIf p.CompCheckAction = CompCheckAction.AdjustImageSize Then
AutoSetImageSize()
End If
End Sub
Sub AutoSetImageSize()
If p.VideoEncoder.AutoCompCheckValue > 0 AndAlso Calc.GetPercent <> 0 AndAlso
p.Script.IsFilterActive("Resize") Then
Dim oldWidth = p.TargetWidth
Dim oldHeight = p.TargetHeight
p.TargetWidth = Calc.FixMod16(CInt((p.SourceHeight - p.CropTop - p.CropBottom) * Calc.GetTargetDAR()))
Dim cropw = p.SourceWidth - p.CropLeft - p.CropRight
If p.TargetWidth > cropw Then
p.TargetWidth = cropw
End If
p.TargetHeight = Calc.FixMod16(CInt(p.TargetWidth / Calc.GetTargetDAR()))
While Calc.GetPercent < p.VideoEncoder.AutoCompCheckValue
If p.TargetWidth - 16 >= 320 Then
p.TargetWidth -= 16
p.TargetHeight = Calc.FixMod16(CInt(p.TargetWidth / Calc.GetTargetDAR()))
Else
Exit While
End If
End While
g.MainForm.tbTargetWidth.Text = p.TargetWidth.ToString
g.MainForm.tbTargetHeight.Text = p.TargetHeight.ToString
Log.WriteLine("Target image size: " & oldWidth.ToString & "x" & oldHeight.ToString & " -> " & p.TargetWidth.ToString & "x" & p.TargetHeight.ToString)
If p.AutoSmartCrop Then
g.MainForm.PerformSmartCrop()
End If
End If
End Sub
Overrides Sub Clean()
Muxer.Clean()
End Sub
Overridable Function GetFrameRate() As Double
Return p.Script.GetFramerate
End Function
Overridable Function GetError() As String
Return Nothing
End Function
Sub OnStateChange()
g.MainForm.UpdateEncoderStateRelatedControls()
g.MainForm.SetEncoderControl(p.VideoEncoder.CreateEditControl)
g.MainForm.lgbEncoder.Text = g.ConvertPath(p.VideoEncoder.Name).Shorten(38)
g.MainForm.llMuxer.Text = p.VideoEncoder.Muxer.OutputType.ToUpper
g.MainForm.tbSize_TextChanged()
End Sub
Public Enum Modes
First = 1
Second = 2
CompCheck = 4
End Enum
Sub OpenMuxerConfigDialog()
Dim m = ObjectHelp.GetCopy(Of Muxer)(Muxer)
If m.Edit = DialogResult.OK Then
Muxer = m
g.MainForm.llMuxer.Text = Muxer.OutputType.ToUpper
g.MainForm.Refresh()
g.MainForm.tbSize_TextChanged()
g.MainForm.Assistant()
End If
End Sub
Function OpenMuxerProfilesDialog() As DialogResult
Using f As New ProfilesForm("Muxer Profiles", s.MuxerProfiles,
AddressOf LoadMuxer,
AddressOf GetMuxerProfile,
AddressOf Muxer.GetDefaults)
Return f.ShowDialog()
End Using
End Function
Sub LoadMuxer(profile As Profile)
Muxer = DirectCast(ObjectHelp.GetCopy(profile), Muxer)
Muxer.Init()
g.MainForm.llMuxer.Text = Muxer.OutputType.ToUpper
g.MainForm.tbTargetFile.Text = p.TargetFile.ChangeExt(Muxer.GetExtension)
g.MainForm.RecalcBitrate()
g.MainForm.Assistant()
End Sub
Private Function GetMuxerProfile() As Profile
Dim sb As New SelectionBox(Of Muxer)
sb.Title = "New Profile"
sb.Text = "Please choose a profile."
sb.AddItem("Current Project", Muxer)
For Each i In StaxRip.Muxer.GetDefaults()
sb.AddItem(i)
Next
If sb.Show = DialogResult.OK Then Return sb.SelectedItem
Return Nothing
End Function
Shared Function Getx264Encoder(
name As String,
device As x264DeviceMode,
Optional mode As x264Mode = x264Mode.SingleCRF) As x264Encoder
Return Getx264Encoder(name, mode, x264PresetMode.Medium, x264TuneMode.Disabled, device)
End Function
Shared Function Getx264Encoder(name As String,
mode As x264Mode,
preset As x264PresetMode,
tuning As x264TuneMode,
device As x264DeviceMode) As x264Encoder
Dim r As New x264Encoder()
r.Name = name
r.Params.Mode.Value = mode
r.Params.Preset.Value = preset
r.Params.Tune.Value = tuning
r.Params.Device.Value = device
r.Params.ApplyDeviceSettings()
r.Params.ApplyDefaults(r.Params)
r.Params.ApplyDeviceSettings()
r.SetMuxer()
Return r
End Function
Shared Function GetDefaults() As List(Of VideoEncoder)
Dim ret As New List(Of VideoEncoder)
ret.Add(Getx264Encoder("x264", x264Mode.SingleCRF, x264PresetMode.Medium, x264TuneMode.Disabled, x264DeviceMode.Disabled))
Dim x265crf = New x265.x265Encoder
x265crf.Params.ApplyPresetDefaultValues()
x265crf.Params.ApplyPresetValues()
ret.Add(x265crf)
Dim intel264 As New IntelEncoder("Intel H.264")
intel264.Params.BFrames.Value = 3
ret.Add(intel264)
Dim intel265 As New IntelEncoder("Intel H.265")
intel265.Params.Codec.Value = 1
intel265.Params.BFrames.Value = 2
ret.Add(intel265)
Dim nvidia264 As New NvidiaEncoder("NVIDIA H.264")
nvidia264.Params.Mode.Value = 3
ret.Add(nvidia264)
Dim nvidia265 As New NvidiaEncoder("NVIDIA H.265")
nvidia265.Params.Mode.Value = 3
nvidia265.Params.Codec.Value = 1
ret.Add(nvidia265)
Dim amd264 As New AMDEncoder("AMD H.264")
amd264.Params.Mode.Value = 2
ret.Add(amd264)
Dim vp9ffmpeg = New ffmpegEncoder()
vp9ffmpeg.Name = "VP9"
ret.Add(vp9ffmpeg)
Dim xvid As New BatchEncoder()
xvid.OutputFileTypeValue = "avi"
xvid.Name = "XviD"
xvid.Muxer = New ffmpegMuxer("AVI")
xvid.QualityMode = True
xvid.CommandLines = """%app:xvid_encraw%"" -cq 2 -smoother 0 -max_key_interval 250 -nopacked -vhqmode 4 -qpel -notrellis -max_bframes 1 -bvhq -bquant_ratio 162 -bquant_offset 0 -threads 1 -i ""%script_file%"" -avi ""%encoder_out_file%"" -par %target_sar%"
ret.Add(xvid)
ret.Add(New NullEncoder("Just Mux"))
ret.Add(Getx264Encoder("2 pass | x264", x264Mode.TwoPass, x264PresetMode.Medium, x264TuneMode.Disabled, x264DeviceMode.Disabled))
Dim x265_2pass = New x265.x265Encoder
x265_2pass.Name = "2 pass | x265"
x265_2pass.Params.Mode.Value = x265.RateMode.TwoPass
x265_2pass.Params.ApplyPresetDefaultValues()
x265_2pass.Params.ApplyPresetValues()
ret.Add(x265_2pass)
Dim xvid2pass As New BatchEncoder()
xvid2pass.OutputFileTypeValue = "avi"
xvid2pass.Name = "2 pass | XviD"
xvid2pass.Muxer = New ffmpegMuxer("AVI")
xvid2pass.CommandLines = """%app:xvid_encraw%"" -smoother 0 -max_key_interval 250 -nopacked -vhqmode 4 -qpel -notrellis -max_bframes 1 -bvhq -bquant_ratio 162 -bquant_offset 0 -threads 1 -bitrate %video_bitrate% -par %target_sar% -turbo -pass1 ""%temp_file%.stats"" -i ""%script_file%"" || exit" + CrLf +
"""%app:xvid_encraw%"" -smoother 0 -max_key_interval 250 -nopacked -vhqmode 4 -qpel -notrellis -max_bframes 1 -bvhq -bquant_ratio 162 -bquant_offset 0 -threads 1 -bitrate %video_bitrate% -par %target_sar% -pass2 ""%temp_file%.stats"" -i ""%script_file%"" -avi ""%encoder_out_file%"""
xvid2pass.CompCheckCommandLines = """%app:xvid_encraw%"" -cq 2 -smoother 0 -max_key_interval 250 -nopacked -vhqmode 4 -qpel -notrellis -max_bframes 1 -bvhq -bquant_ratio 162 -bquant_offset 0 -threads 1 -par %target_sar% -i ""%temp_file%_CompCheck.%script_ext%"" -avi ""%temp_file%_CompCheck.avi"""
ret.Add(xvid2pass)
Dim x264cli As New BatchEncoder()
x264cli.OutputFileTypeValue = "h264"
x264cli.Name = "Command Line | x264"
x264cli.Muxer = New MkvMuxer()
x264cli.AutoCompCheckValue = 50
x264cli.CommandLines = """%app:x264%"" --pass 1 --bitrate %video_bitrate% --stats ""%temp_file%.stats"" --output NUL ""%script_file%"" || exit" + CrLf + """%app:x264%"" --pass 2 --bitrate %video_bitrate% --stats ""%temp_file%.stats"" --output ""%encoder_out_file%"" ""%script_file%"""
x264cli.CompCheckCommandLines = """%app:x264%"" --crf 18 --output ""%temp_file%_CompCheck%encoder_ext%"" ""%temp_file%_CompCheck.%script_ext%"""
ret.Add(x264cli)
Dim divx As New BatchEncoder()
divx.OutputFileTypeValue = "h265"
divx.Name = "Command Line | DivX H.265"
divx.Muxer = New MkvMuxer()
divx.CommandLines = """%app:DivX265%"" -i ""%script_file%"" -o ""%encoder_out_file%"" -br %video_bitrate% -10"
ret.Add(divx)
Dim nvencH265 As New BatchEncoder()
nvencH265.OutputFileTypeValue = "h265"
nvencH265.Name = "Command Line | NVIDIA H.265"
nvencH265.Muxer = New MkvMuxer()
nvencH265.QualityMode = True
nvencH265.CommandLines = """%app:ffmpeg%"" -i ""%script_file%"" -f yuv4mpegpipe -pix_fmt yuv420p -loglevel error - | ""%app:NVEncC%"" --sar %target_sar% --codec h265 --y4m --cqp 20 --input - --output ""%encoder_out_file%"""
ret.Add(nvencH265)
ret.Add(Getx264Encoder("Devices | DivX Plus", x264DeviceMode.DivXPlus))
ret.Add(Getx264Encoder("Devices | Blu-ray", x264DeviceMode.BluRay))
ret.Add(Getx264Encoder("Devices | iPhone", x264DeviceMode.iPhone))
ret.Add(Getx264Encoder("Devices | PlayStation", x264DeviceMode.PlayStation))
ret.Add(Getx264Encoder("Devices | Xbox", x264DeviceMode.Xbox))
Return ret
End Function
Function CompareToVideoEncoder(other As VideoEncoder) As Integer Implements System.IComparable(Of VideoEncoder).CompareTo
Return Name.CompareTo(other.Name)
End Function
Overridable Sub RunCompCheck()
End Sub
Overrides Function Edit() As DialogResult
Using f As New ControlHostForm(Name)
f.AddControl(CreateEditControl, Nothing)
f.ShowDialog()
End Using
Return DialogResult.OK
End Function
Public Class MenuList
Inherits List(Of KeyValuePair(Of String, Action))
Overloads Sub Add(text As String, action As Action)
Add(New KeyValuePair(Of String, Action)(text, action))
End Sub
End Class
End Class
<Serializable()>
Class BatchEncoder
Inherits VideoEncoder
Sub New()
MyBase.New("Command Line")
Muxer = New MkvMuxer()
End Sub
Property CommandLines As String = ""
Property CompCheckCommandLines As String = ""
Property OutputFileTypeValue As String
Overrides ReadOnly Property OutputfileType As String
Get
If OutputFileTypeValue = "" Then OutputFileTypeValue = "h264"
Return OutputFileTypeValue
End Get
End Property
Overrides Sub ShowConfigDialog()
Using f As New BatchEncoderForm(Me)
If f.ShowDialog() = DialogResult.OK Then
OnStateChange()
End If
End Using
End Sub
Overrides Function GetMenu() As MenuList
Dim ret As New MenuList
ret.Add("Codec Configuration", AddressOf ShowConfigDialog)
If IsCompCheckEnabled Then
ret.Add("Run Compressibility Check", AddressOf RunCompCheck)
End If
ret.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return ret
End Function
Function GetSkipStrings(commands As String) As String()
If commands.Contains("DivX265") Then
Return {"encoded @"}
ElseIf commands.Contains("xvid_encraw") Then
Return {"key="}
ElseIf commands.Contains("x264") Then
Return {"frames,"}
ElseIf commands.Contains("NVEncC") Then
Return {"frames: "}
Else
Return {" [ETA ", ", eta ", "frames: ", "frame= "}
End If
End Function
Overrides Sub Encode()
Dim commands = Macro.Solve(CommandLines).Trim
If commands.Contains("|") OrElse commands.Contains(CrLf) Then
Dim batchPath = p.TempDir + Filepath.GetBase(p.TargetFile) + "_encode.bat"
File.WriteAllText(batchPath, commands, Encoding.GetEncoding(850))
Using proc As New Proc
proc.Init("Encoding video command line encoder: " + Name)
proc.SkipStrings = GetSkipStrings(commands)
proc.WriteLine(commands + CrLf2)
proc.File = "cmd.exe"
proc.Arguments = "/C call """ + batchPath + """"
Try
proc.Start()
Catch ex As AbortException
Throw ex
Catch ex As Exception
ProcessForm.CloseProcessForm()
g.ShowException(ex)
Throw New AbortException
End Try
End Using
Else
Using proc As New Proc
proc.Init("Encoding video command line encoder: " + Name)
proc.SkipStrings = GetSkipStrings(commands)
proc.CommandLine = commands
Try
proc.Start()
Catch ex As AbortException
Throw ex
Catch ex As Exception
ProcessForm.CloseProcessForm()
g.ShowException(ex)
Throw New AbortException
End Try
End Using
End If
End Sub
Overrides Sub RunCompCheck()
If CompCheckCommandLines = "" OrElse CompCheckCommandLines.Trim = "" Then
ShowConfigDialog()
Exit Sub
End If
If Not Paths.VerifyRequirements Then Exit Sub
If Not g.IsValidSource Then Exit Sub
ProcessForm.ShowForm()
Log.WriteHeader("Compressibility Check")
Dim script As New VideoScript
script.Engine = p.Script.Engine
script.Filters = p.Script.GetFiltersCopy
Dim code As String
Dim every = ((100 \ p.CompCheckRange) * 14).ToString
If script.Engine = ScriptingEngine.AviSynth Then
code = "SelectRangeEvery(" + every + ",14)"
Else
code = "fpsnum = clip.fps_num" + CrLf + "fpsden = clip.fps_den" + CrLf +
"clip = core.std.SelectEvery(clip = clip, cycle = " + every + ", offsets = range(14))" + CrLf +
"clip = core.std.AssumeFPS(clip = clip, fpsnum = fpsnum, fpsden = fpsden)"
End If
Log.WriteLine(code + CrLf2)
script.Filters.Add(New VideoFilter("aaa", "aaa", code))
script.Path = p.TempDir + p.Name + "_CompCheck." + script.FileType
script.Synchronize()
Dim batchPath = p.TempDir + Filepath.GetBase(p.TargetFile) + "_CompCheck.bat"
Dim command = Macro.Solve(CompCheckCommandLines)
File.WriteAllText(batchPath, command, Encoding.GetEncoding(850))
Log.WriteLine(command + CrLf2)
Using proc As New Proc
proc.Init(Nothing)
proc.SkipStrings = GetSkipStrings(command)
proc.File = "cmd.exe"
proc.Arguments = "/C call """ + batchPath + """"
Try
proc.Start()
Catch ex As AbortException
ProcessForm.CloseProcessForm()
Exit Sub
Catch ex As Exception
ProcessForm.CloseProcessForm()
g.ShowException(ex)
Exit Sub
End Try
End Using
Dim bits = (New FileInfo(p.TempDir + p.Name + "_CompCheck." + OutputfileType).Length) * 8
p.Compressibility = (bits / script.GetFrames) / (p.TargetWidth * p.TargetHeight)
OnAfterCompCheck()
g.MainForm.Assistant()
Log.WriteLine(CInt(Calc.GetPercent).ToString() + " %")
ProcessForm.CloseProcessForm()
End Sub
End Class
<Serializable()>
Class NullEncoder
Inherits VideoEncoder
Sub New(name As String)
MyBase.New(name)
Muxer = New MkvMuxer()
QualityMode = True
End Sub
Function GetSource() As String
For Each i In {".h264", ".avc", ".h265", ".hevc", ".mpg", ".avi"}
If File.Exists(Filepath.GetDirAndBase(p.SourceFile) + "_out" + i) Then
Return Filepath.GetDirAndBase(p.SourceFile) + "_out" + i
ElseIf File.Exists(p.TempDir + p.Name + "_out" + i)
Return p.TempDir + p.Name + "_out" + i
End If
Next
If FileTypes.VideoIndex.Contains(Filepath.GetExt(p.SourceFile)) Then
Return p.LastOriginalSourceFile
Else
Return p.SourceFile
End If
End Function
Overrides ReadOnly Property OutputPath As String
Get
Dim source = GetSource()
If Not p.VideoEncoder.Muxer.IsSupported(Filepath.GetExt(source)) Then
Select Case Filepath.GetExt(source)
Case "mkv"
Dim streams = MediaInfo.GetVideoStreams(source)
If streams.Count = 0 Then Return source
Dim stream = streams(0)
If stream.Extension = "" Then Throw New Exception("demuxing of video stream format is not implemented")
Return p.TempDir + Filepath.GetBase(source) + "_out" + stream.Extension
End Select
End If
Return source
End Get
End Property
Overrides ReadOnly Property OutputFileType As String
Get
Return Filepath.GetExt(OutputPath)
End Get
End Property
Overrides Sub Encode()
Dim source = GetSource()
If Not p.VideoEncoder.Muxer.IsSupported(Filepath.GetExt(source)) Then
Select Case Filepath.GetExt(source)
Case "mkv"
Video.DemuxMKV(source)
End Select
End If
End Sub
Overrides Function GetMenu() As MenuList
Dim ret As New MenuList
ret.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return ret
End Function
Overrides Sub ShowConfigDialog()
End Sub
End Class
<Serializable()>
Class ffmpegEncoder
Inherits VideoEncoder
Property ParamsStore As New PrimitiveStore
Sub New()
MyBase.New("ffmpeg")
Muxer = New ffmpegMuxer("AVI")
End Sub
<NonSerialized>
Private ParamsValue As ffmpegParams
Property Params As ffmpegParams
Get
If ParamsValue Is Nothing Then
ParamsValue = New ffmpegParams
ParamsValue.Init(ParamsStore)
End If
Return ParamsValue
End Get
Set(value As ffmpegParams)
ParamsValue = value
End Set
End Property
Overrides Sub ShowConfigDialog()
Dim newParams As New ffmpegParams
Dim store = DirectCast(ObjectHelp.GetCopy(ParamsStore), PrimitiveStore)
newParams.Init(store)
Using f As New CommandLineForm(newParams)
If f.ShowDialog() = DialogResult.OK Then
Params = newParams
ParamsStore = store
OnStateChange()
End If
End Using
End Sub
Overrides ReadOnly Property OutputFileType() As String
Get
Select Case Params.Codec.OptionText
Case "Xvid", "ASP"
Return "avi"
Case "VP9"
Return "webm"
Case Else
Return "mkv"
End Select
End Get
End Property
Overrides ReadOnly Property IsCompCheckEnabled() As Boolean
Get
Return False
End Get
End Property
Overrides Sub Encode()
p.Script.Synchronize()
Params.RaiseValueChanged(Nothing)
If Params.Mode.OptionText = "Two Pass" Then
Encode(Params.GetArgs(1, p.Script.Path, "NUL", True))
Encode(Params.GetArgs(2, p.Script.Path, Filepath.GetDirAndBase(OutputPath) + "." + OutputFileType, True))
Else
Encode(Params.GetArgs(1, p.Script.Path, Filepath.GetDirAndBase(OutputPath) + "." + OutputFileType, True))
End If
AfterEncoding()
End Sub
Overloads Sub Encode(args As String)
Using proc As New Proc
proc.Init("Encoding " + Params.Codec.OptionText + " using ffmpeg", "frame=")
proc.Encoding = Encoding.UTF8
proc.WorkingDirectory = p.TempDir
proc.File = Packs.ffmpeg.GetPath
proc.Arguments = args
proc.Start()
End Using
End Sub
Overrides Function GetMenu() As MenuList
Dim r As New MenuList
r.Add("Encoder Options", AddressOf ShowConfigDialog)
r.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return r
End Function
Overrides Property QualityMode() As Boolean
Get
Return Params.Mode.Value = EncodingMode.Quality
End Get
Set(Value As Boolean)
End Set
End Property
Class ffmpegParams
Inherits CommandLineParams
Sub New()
Title = "ffmpeg Encoding Options"
End Sub
Property Codec As New OptionParam With {
.Switch = "-c:v",
.Text = "Codec:",
.AlwaysOn = True,
.Options = {"VP9", "Xvid", "ASP", "Theora"},
.Values = {"libvpx-vp9", "libxvid", "mpeg4", "libtheora"}}
Property Mode As New OptionParam With {
.Name = "Mode",
.Text = "Mode:",
.Options = {"Quality", "One Pass", "Two Pass"}}
Property Speed As New OptionParam With {
.Switch = "-speed",
.Text = "Speed:",
.AlwaysOn = True,
.Options = {"6 - Fastest", "5 - Faster", "4 - Fast", "3 - Medium", "2 - Slow", "1 - Slower", "0 - Slowest"},
.Values = {"6", "5", "4", "3", "2", "1", "0"},
.Value = 5}
Property AQmode As New OptionParam With {
.Switch = "-aq-mode",
.Text = "AQ Mode:",
.Options = {"Disabled", "0", "1", "2", "3"},
.Values = {"Disabled", "0", "1", "2", "3"}}
Property Quality As New NumParam With {
.Name = "Quality",
.Text = "Quality:",
.MinMaxStep = {1, 63, 1},
.Value = 25}
Property Threads As New NumParam With {
.Switch = "-threads",
.Text = "Threads:",
.Value = 8,
.DefaultValue = -1}
Property TileColumns As New NumParam With {
.Switch = "-tile-columns",
.Text = "Tile Columns:",
.Value = 6,
.DefaultValue = -1}
Property FrameParallel As New NumParam With {
.Switch = "-frame-parallel",
.Text = "Frame Parallel:",
.Value = 1,
.DefaultValue = -1}
Property AutoAltRef As New NumParam With {
.Switch = "-auto-alt-ref",
.Text = "Auto Alt Ref:",
.Value = 1,
.DefaultValue = -1}
Property LagInFrames As New NumParam With {
.Switch = "-lag-in-frames",
.Text = "Lag In Frames:",
.Value = 25,
.DefaultValue = -1}
Property Custom As New StringParam With {
.Text = "Custom Switches:"}
Private ItemsValue As List(Of CommandLineItem)
Overrides ReadOnly Property Items As List(Of CommandLineItem)
Get
If ItemsValue Is Nothing Then
ItemsValue = New List(Of CommandLineItem)
ItemsValue.AddRange({Codec, Mode, Speed, AQmode, Quality, Threads, TileColumns, FrameParallel, AutoAltRef, LagInFrames, Custom})
End If
Return ItemsValue
End Get
End Property
Protected Overrides Sub OnValueChanged(item As CommandLineItem)
Speed.Visible = Codec.OptionText = "VP9"
Threads.Visible = Codec.OptionText = "VP9"
TileColumns.Visible = Codec.OptionText = "VP9"
FrameParallel.Visible = Codec.OptionText = "VP9"
AutoAltRef.Visible = Codec.OptionText = "VP9"
LagInFrames.Visible = Codec.OptionText = "VP9"
AQmode.Visible = Codec.OptionText = "VP9"
Quality.Visible = Mode.Value = EncodingMode.Quality
MyBase.OnValueChanged(item)
End Sub
Overloads Overrides Function GetCommandLine(includePaths As Boolean,
includeExecutable As Boolean) As String
Return GetArgs(1, p.Script.Path, Filepath.GetDirAndBase(p.VideoEncoder.OutputPath) +
"." + p.VideoEncoder.OutputFileType, includePaths)
End Function
Overloads Function GetArgs(pass As Integer,
sourcePath As String,
targetPath As String,
Optional includePaths As Boolean = True) As String
Dim ret As String
If includePaths Then
ret += "-i """ + p.Script.Path + """"
End If
Dim q = From i In Items Where i.GetArgs <> ""
If q.Count > 0 Then
ret += " " + q.Select(Function(item) item.GetArgs).Join(" ")
End If
If Calc.IsARSignalingRequired Then
ret += " -aspect " + Calc.GetTargetDAR.ToString(CultureInfo.InvariantCulture).Shorten(8)
End If
Select Case Mode.Value
Case EncodingMode.Quality
If Codec.OptionText = "VP9" Then
ret += " -crf " & Quality.Value & " -b:v 0"
Else
ret += " -q:v " & Quality.Value
End If
Case EncodingMode.TwoPass
ret += " -pass " & pass
ret += " -b:v " & p.VideoBitrate & "k"
If Codec.OptionText = "Xvid" OrElse Codec.OptionText = "ASP" Then
ret += " -f avi"
ElseIf Codec.OptionText = "VP9" Then
ret += " -f webm"
Else
ret += " -f mkv"
End If
Case EncodingMode.OnePass
ret += " -b:v " & p.VideoBitrate & "k"
End Select
Select Case Codec.OptionText
Case "Xvid"
ret += " -tag:v xvid"
End Select
If Custom.Value <> "" Then ret += " " + Custom.Value
ret += " -y"
If includePaths Then
ret += " """ + targetPath + """"
End If
Return ret.Trim
End Function
Public Overrides Function GetPackage() As Package
Return Packs.ffmpeg
End Function
End Class
Enum EncodingMode
Quality
OnePass
TwoPass
End Enum
End Class
<Serializable()>
Class NvidiaEncoder
Inherits VideoEncoder
Property ParamsStore As New PrimitiveStore
Sub New(profileName As String)
MyBase.New(profileName)
End Sub
<NonSerialized>
Private ParamsValue As EncoderParams
Property Params As EncoderParams
Get
If ParamsValue Is Nothing Then
ParamsValue = New EncoderParams
ParamsValue.Init(ParamsStore)
End If
Return ParamsValue
End Get
Set(value As EncoderParams)
ParamsValue = value
End Set
End Property
Overrides Sub ShowConfigDialog()
Dim newParams As New EncoderParams
Dim store = DirectCast(ObjectHelp.GetCopy(ParamsStore), PrimitiveStore)
newParams.Init(store)
Using f As New CommandLineForm(newParams)
f.cms.Items.Add(New ActionMenuItem("Check Hardware", Sub() MsgInfo(ProcessHelp.GetStdOut(Packs.NVEncC.GetPath, "--check-hw"))))
f.cms.Items.Add(New ActionMenuItem("Check Features", Sub() g.ShowCode("Check Features", ProcessHelp.GetStdOut(Packs.NVEncC.GetPath, "--check-features"))))
f.cms.Items.Add(New ActionMenuItem("Check Environment", Sub() g.ShowCode("Check Environment", ProcessHelp.GetErrorOutput(Packs.NVEncC.GetPath, "--check-environment"))))
If f.ShowDialog() = DialogResult.OK Then
Params = newParams
ParamsStore = store
OnStateChange()
End If
End Using
End Sub
Overrides ReadOnly Property OutputFileType() As String
Get
Return Params.Codec.ValueText
End Get
End Property
Overrides Sub Encode()
p.Script.Synchronize()
Dim cl = Params.GetCommandLine(True, False)
If cl.Contains(" | ") Then
Dim batchPath = p.TempDir + p.TargetFile.Base + "_NVEncC.bat"
File.WriteAllText(batchPath, cl, Encoding.GetEncoding(850))
Using proc As New Proc
proc.Init("Encoding using NVEncC")
proc.SkipStrings = {"%]", " frames: "}
proc.WriteLine(cl + CrLf2)
proc.File = "cmd.exe"
proc.Arguments = "/C call """ + batchPath + """"
proc.Start()
End Using
Else
Using proc As New Proc
proc.Init("Encoding using NVEncC")
proc.SkipStrings = {"%]"}
proc.File = Packs.NVEncC.GetPath
proc.Arguments = cl
proc.Start()
End Using
End If
AfterEncoding()
End Sub
Overrides Function GetMenu() As MenuList
Dim r As New MenuList
r.Add("Encoder Options", AddressOf ShowConfigDialog)
r.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return r
End Function
Overrides Property QualityMode() As Boolean
Get
Return Params.Mode.OptionText = "CQP"
End Get
Set(Value As Boolean)
End Set
End Property
Class EncoderParams
Inherits CommandLineParams
Sub New()
Title = "NVIDIA Encoding Options"
End Sub
Property Decoder As New OptionParam With {
.Text = "Decoder:",
.Options = {"AviSynth/VapourSynth", "NVEncC cuvid", "QSVEncC Quick Sync", "ffmpeg dxva2"},
.Values = {"avs", "nv", "qs", "ff"}}
Property Mode As New OptionParam With {
.Text = "Mode:",
.Options = {"CBR", "VBR", "VBR2", "CQP"}}
Property Codec As New OptionParam With {
.Switch = "--codec",
.Text = "Codec:",
.Options = {"H264/AVC", "H265/HEVC"},
.Values = {"h264", "h265"}}
Property Profile As New OptionParam With {
.Switch = "--profile",
.Text = "Profile:",
.ValueIsName = True,
.Options = {"baseline", "main", "high", "high444"},
.Value = 2,
.DefaultValue = 2}
Property LevelH264 As New OptionParam With {
.Name = "LevelH264",
.Switch = "--level",
.Text = "Level:",
.Options = {"Unrestricted", "1", "1.1", "1.2", "1.3", "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1", "5.2"},
.Values = {"", "1", "1.1", "1.2", "1.3", "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1", "5.2"}}
Property LevelH265 As New OptionParam With {
.Name = "LevelH265",
.Switch = "--level",
.Text = "Level:",
.Options = {"Unrestricted", "1", "2", "2.1", "3", "3.1", "4", "4.1", "5", "5.1", "5.2", "6", "6.1", "6.2"},
.Values = {"", "1", "2", "2.1", "3", "3.1", "4", "4.1", "5", "5.1", "5.2", "6", "6.1", "6.2"}}
Property mvPrecision As New OptionParam With {
.Switch = "--mv-precision",
.Text = "MV Precision:",
.Options = {"Q-pel", "half-pel", "full-pel"},
.Values = {"Q-pel", "half-pel", "full-pel"}}
Property QPI As New NumParam With {
.Text = "Constant QP I:",
.Value = 20,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property QPP As New NumParam With {
.Text = "Constant QP P:",
.Value = 23,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property QPB As New NumParam With {
.Text = "Constant QP B:",
.Value = 25,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property MaxBitrate As New NumParam With {
.Switch = "--max-bitrate",
.Text = "Maximum Bitrate:",
.Value = 17500,
.DefaultValue = 17500,
.MinMaxStep = {0, 1000000, 1}}
Property GOPLength As New NumParam With {
.Switch = "--gop-len",
.Text = "GOP Length (0=auto):",
.MinMaxStep = {0, 10000, 1}}
Property BFrames As New NumParam With {
.Switch = "--bframes",
.Text = "B Frames:",
.Value = 3,
.DefaultValue = 3,
.MinMaxStep = {0, 16, 1}}
Property Ref As New NumParam With {
.Switch = "--ref",
.Text = "Reference Frames:",
.Value = 3,
.DefaultValue = 3,
.MinMaxStep = {0, 16, 1}}
Property Lossless As New BoolParam With {
.Switch = "--lossless",
.Text = "Lossless",
.VisibleFunc = Function() Codec.ValueText = "h264",
.Value = False,
.DefaultValue = False}
Property FullRange As New BoolParam With {
.Switch = "--fullrange",
.Text = "Full Range",
.VisibleFunc = Function() Codec.ValueText = "h264",
.Value = False,
.DefaultValue = False}
Property AQ As New BoolParam With {
.Switch = "--aq",
.Text = "Adaptive Quantization",
.Value = False,
.DefaultValue = False}
Property Custom As New StringParam With {
.Text = "Custom Switches:",
.ArgsFunc = Function() Custom.Value}
Private ItemsValue As List(Of CommandLineItem)
Overrides ReadOnly Property Items As List(Of CommandLineItem)
Get
If ItemsValue Is Nothing Then
ItemsValue = New List(Of CommandLineItem)
Add("Basic", Decoder, Mode, Codec, Profile, LevelH264, LevelH265,
QPI, QPP, QPB, GOPLength, BFrames, Ref)
Add("Advanced", mvPrecision, MaxBitrate, AQ, Lossless, FullRange, Custom)
End If
Return ItemsValue
End Get
End Property
Private AddedList As New List(Of String)
Private Sub Add(path As String, ParamArray items As CommandLineItem())
For Each i In items
i.Path = path
ItemsValue.Add(i)
If i.GetKey = "" OrElse AddedList.Contains(i.GetKey) Then
Throw New Exception
End If
Next
End Sub
Protected Overrides Sub OnValueChanged(item As CommandLineItem)
Profile.Visible = Codec.ValueText = "h264"
Lossless.Visible = Profile.Visible
LevelH264.Visible = Codec.ValueText = "h264"
LevelH265.Visible = Codec.ValueText = "h265"
MyBase.OnValueChanged(item)
End Sub
Overrides Function GetCommandLine(includePaths As Boolean, includeExecutable As Boolean) As String
Dim ret As String
Dim sourcePath As String
Dim targetPath = p.VideoEncoder.OutputPath.ChangeExt(p.VideoEncoder.OutputFileType)
If includePaths AndAlso includeExecutable Then
ret = Packs.NVEncC.GetPath.AddPathQuotes
End If
Select Case Decoder.ValueText
Case "avs"
sourcePath = p.Script.Path
Case "nv"
sourcePath = p.LastOriginalSourceFile
Case "qs"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.QSVEncC.GetPath.AddPathQuotes, "QSVEncC") + " --output-file - --codec raw" + " --input-file " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " | " + If(includePaths, Packs.NVEncC.GetPath.AddPathQuotes, "NVEncC")
Case "ff"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.ffmpeg.GetPath.AddPathQuotes, "ffmpeg") + " -threads 1 -hwaccel dxva2 -i " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " -f yuv4mpegpipe -pix_fmt yuv420p -loglevel error - | " + If(includePaths, Packs.NVEncC.GetPath.AddPathQuotes, "NVEncC")
End Select
Dim q = From i In Items Where i.GetArgs <> ""
If q.Count > 0 Then
ret += " " + q.Select(Function(item) item.GetArgs).Join(" ")
End If
If Not Lossless.Value Then
Select Case Mode.OptionText
Case "CBR"
ret += " --cbr " & p.VideoBitrate
Case "VBR"
ret += " --vbr " & p.VideoBitrate
Case "VBR2"
ret += " --vbr2 " & p.VideoBitrate
Case "CQP"
ret += " --cqp " & QPI.Value & ":" & QPP.Value & ":" & QPB.Value
End Select
End If
If CInt(p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) <> 0 AndAlso
p.Script.IsFilterActive("Crop") Then
ret += " --crop " & p.CropLeft & "," & p.CropTop & "," & p.CropRight & "," & p.CropBottom
End If
If p.Script.IsFilterActive("Resize", "Hardware Encoder") OrElse
(Decoder.ValueText <> "avs" AndAlso p.Script.IsFilterActive("Resize")) Then
ret += " --output-res " & p.TargetWidth & "x" & p.TargetHeight
ElseIf p.AutoARSignaling Then
Dim par = Calc.GetTargetPAR
If par <> New Point(1, 1) Then ret += " --sar " & par.X & ":" & par.Y
End If
If sourcePath = "-" Then
ret += " --y4m --fps " &
p.Script.GetFramerate.ToString("f6", CultureInfo.InvariantCulture)
End If
If includePaths Then
ret += " --input " + sourcePath.AddPathQuotes + " --output " + targetPath.AddPathQuotes
End If
Return ret.Trim
End Function
Public Overrides Function GetPackage() As Package
Return Packs.NVEncC
End Function
End Class
End Class
<Serializable()>
Class IntelEncoder
Inherits VideoEncoder
Property ParamsStore As New PrimitiveStore
Sub New(profileName As String)
MyBase.New(profileName)
End Sub
<NonSerialized>
Private ParamsValue As EncoderParams
Property Params As EncoderParams
Get
If ParamsValue Is Nothing Then
ParamsValue = New EncoderParams
ParamsValue.Init(ParamsStore)
End If
Return ParamsValue
End Get
Set(value As EncoderParams)
ParamsValue = value
End Set
End Property
Public Overrides Function GetFrameRate() As Double
If Params.Deinterlace.OptionText = "Double Framerate" Then
Return MyBase.GetFrameRate() * 2
End If
Return MyBase.GetFrameRate()
End Function
Overrides Sub ShowConfigDialog()
Dim newParams As New EncoderParams
Dim store = DirectCast(ObjectHelp.GetCopy(ParamsStore), PrimitiveStore)
newParams.Init(store)
Using f As New CommandLineForm(newParams)
f.HTMLHelp = Strings.Intel
f.cms.Items.Add(New ActionMenuItem("Check Environment", Sub() g.ShowCode("Check Environment", ProcessHelp.GetStdOut(Packs.QSVEncC.GetPath, "--check-environment"))))
f.cms.Items.Add(New ActionMenuItem("Check Hardware", Sub() MsgInfo(ProcessHelp.GetStdOut(Packs.QSVEncC.GetPath, "--check-hw"))))
f.cms.Items.Add(New ActionMenuItem("Check Features", Sub() g.ShowCode("Check Features", ProcessHelp.GetStdOut(Packs.QSVEncC.GetPath, "--check-features"))))
f.cms.Items.Add(New ActionMenuItem("Check Library", Sub() MsgInfo(ProcessHelp.GetStdOut(Packs.QSVEncC.GetPath, "--check-lib"))))
If f.ShowDialog() = DialogResult.OK Then
Params = newParams
ParamsStore = store
OnStateChange()
End If
End Using
End Sub
Overrides ReadOnly Property OutputFileType() As String
Get
If Params.Codec.ValueText = "mpeg2" Then Return "m2v"
Return Params.Codec.ValueText
End Get
End Property
Overrides Sub Encode()
p.Script.Synchronize()
Params.RaiseValueChanged(Nothing)
Dim cl = Params.GetCommandLine(True, False)
If cl.Contains(" | ") Then
Dim batchPath = p.TempDir + p.TargetFile.Base + "_QSVEncC.bat"
File.WriteAllText(batchPath, cl, Encoding.GetEncoding(850))
Using proc As New Proc
proc.Init("Encoding using QSVEncC")
proc.SkipStrings = {"%]", " frames: "}
proc.WriteLine(cl + CrLf2)
proc.File = "cmd.exe"
proc.Arguments = "/C call """ + batchPath + """"
proc.Start()
End Using
Else
Using proc As New Proc
proc.Init("Encoding using QSVEncC")
proc.SkipStrings = {"%]"}
proc.File = Packs.QSVEncC.GetPath
proc.Arguments = cl
proc.Start()
End Using
End If
AfterEncoding()
End Sub
Overrides Function GetMenu() As MenuList
Dim r As New MenuList
r.Add("Encoder Options", AddressOf ShowConfigDialog)
r.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return r
End Function
Overrides Property QualityMode() As Boolean
Get
Return {"cqp", "vqp", "icq", "la-icq", "qvbr-q"}.Contains(Params.Mode.ValueText)
End Get
Set(Value As Boolean)
End Set
End Property
Class EncoderParams
Inherits CommandLineParams
Shared Modes As New List(Of StringPair) From {
New StringPair("avbr", "AVBR - Average Variable Bitrate"),
New StringPair("cbr", "CBR - Constant Bitrate"),
New StringPair("cqp", "CQP - Constant QP"),
New StringPair("icq", "ICQ - Intelligent Constant Quality"),
New StringPair("la", "LA - VBR Lookahead"),
New StringPair("la-hrd", "LA-HRD - VBR HRD Lookahead"),
New StringPair("la-icq", "LA-ICQ - Intelligent Constant Quality Lookahead"),
New StringPair("qvbr", "QVBR - Quality Variable Bitrate using bitrate"),
New StringPair("qvbr-q", "QVBR-Q - Quality Variable Bitrate using quality"),
New StringPair("vbr", "VBR - Variable Bitrate"),
New StringPair("vcm", "VCM - Video Conferencing Mode"),
New StringPair("vqp", "VQP - Variable QP")}
Sub New()
Title = "Intel Encoding Options"
End Sub
Property Decoder As New OptionParam With {
.Text = "Decoder:",
.Options = {"AviSynth/VapourSynth", "NVEncC", "VCEEncC", "QSVEncC", "ffmpeg dxva2"},
.Values = {"avs", "nv", "vce", "qs", "ff"}}
Property Codec As New OptionParam With {
.Switch = "--codec",
.Text = "Codec:",
.Options = {"H264/AVC", "H265/HEVC", "MPEG-2"},
.Values = {"h264", "hevc", "mpeg2"}}
Property Mode As New OptionParam With {
.Name = "Mode",
.Text = "Mode:",
.Expand = True,
.Options = Modes.Select(Function(a) a.Value).ToArray,
.Values = Modes.Select(Function(a) a.Name).ToArray,
.Value = 2,
.DefaultValue = 2}
Property QualitySpeed As New OptionParam With {
.Switch = "--quality",
.Text = "Quality/Speed:",
.Options = {"best", "higher", "high", "balanced", "fast", "faster", "fastest"},
.Values = {"best", "higher", "high", "balanced", "fast", "faster", "fastest"},
.Value = 3,
.DefaultValue = 3}
Property Deinterlace As New OptionParam With {
.Switch = "--vpp-deinterlace",
.Text = "Deinterlace:",
.Options = {"None", "Normal", "Inverse Telecine", "Double Framerate"},
.Values = {"none", "normal", "it", "bob"}}
Property TFF As New BoolParam With {
.Switch = "--tff",
.Text = "Top Field First"}
Property BFF As New BoolParam With {
.Switch = "--bff",
.Text = "Bottom Field First"}
Property Quality As New NumParam With {
.Text = "Quality:",
.Value = 23,
.DefaultValue = 23,
.VisibleFunc = Function() {"icq", "la-icq", "qvbr-q"}.Contains(Mode.ValueText),
.MinMaxStep = {0, 51, 1}}
Property QPI As New NumParam With {
.Text = "QP I:",
.Value = 24,
.DefaultValue = 24,
.VisibleFunc = Function() {"cqp", "vqp"}.Contains(Mode.ValueText),
.MinMaxStep = {0, 51, 1}}
Property QPP As New NumParam With {
.Text = "QP P:",
.Value = 26,
.DefaultValue = 26,
.VisibleFunc = Function() {"cqp", "vqp"}.Contains(Mode.ValueText),
.MinMaxStep = {0, 51, 1}}
Property QPB As New NumParam With {
.Text = "QP B:",
.Value = 27,
.DefaultValue = 27,
.VisibleFunc = Function() {"cqp", "vqp"}.Contains(Mode.ValueText),
.MinMaxStep = {0, 51, 1}}
Property MaxBitrate As New NumParam With {
.Switch = "--max-bitrate",
.Text = "Maximum Bitrate:",
.Value = 17500,
.DefaultValue = 17500,
.MinMaxStep = {0, 1000000, 1}}
Property GOPLength As New NumParam With {
.Switch = "--gop-len",
.Text = "GOP Length (0=auto):",
.MinMaxStep = {0, 10000, 1}}
Property BFrames As New NumParam With {
.Switch = "--bframes",
.Text = "B Frames:",
.MinMaxStep = {0, 16, 1}}
Property LookaheadDepth As New NumParam With {
.Switch = "--la-depth",
.Text = "Lookahead Depth:",
.Value = 30,
.VisibleFunc = Function() {"la", "la-hrd", "la-icq"}.Contains(Mode.ValueText),
.MinMaxStep = {0, 100, 1}}
Property Ref As New NumParam With {
.Switch = "--ref",
.Text = "Ref Frames (0=auto):",
.MinMaxStep = {0, 16, 1}}
Property Scenechange As New BoolParam With {
.Switch = "--scenechange",
.NoSwitch = "--no-scenechange",
.VisibleFunc = Function() Decoder.ValueText = "avs",
.Text = "Scenechange"}
Property MBBRC As New BoolParam With {
.Switch = "--mbbrc",
.NoSwitch = "--no-mbbrc",
.Text = "Per macro block rate control",
.VisibleFunc = Function() Not {"cqp", "la", "la-hrd", "la-icq", "vqp", "icq"}.Contains(Mode.ValueText),
.Value = False,
.DefaultValue = False}
Property Custom As New StringParam With {
.Text = "Custom Switches:",
.ArgsFunc = Function() Custom.Value}
Property LevelH264 As New OptionParam With {
.Switch = "--level",
.Text = "Level:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 0,
.Options = {"Automatic", "1", "1b", "1.1", "1.2", "1.3", "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1", "5.2"}}
Property LevelHEVC As New OptionParam With {
.Name = "LevelHEVC",
.Switch = "--level",
.Text = "Level:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 1,
.Options = {"Automatic", "1", "2", "2.1", "3", "3.1", "4", "4.1", "5", "5.1", "5.2", "6", "6.1", "6.2"}}
Property LevelMPEG2 As New OptionParam With {
.Name = "LevelMPEG2",
.Switch = "--level",
.Text = "Level:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 2,
.Options = {"Automatic", "low", "main", "high", "High1440"}}
Property ProfileH264 As New OptionParam With {
.Switch = "--profile",
.Text = "Profile:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 0,
.Options = {"Automatic", "Baseline", "Main", "High"}}
Property ProfileHEVC As New OptionParam With {
.Name = "ProfileHEVC",
.Switch = "--profile",
.Text = "Profile:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 1,
.Options = {"Main"}}
Property ProfileMPEG2 As New OptionParam With {
.Name = "ProfileMPEG2",
.Switch = "--profile",
.Text = "Profile:",
.ValueIsName = True,
.VisibleFunc = Function() Codec.Value = 2,
.Options = {"Automatic", "Simple", "Main", "High"}}
Property Rotate As New OptionParam With {
.Switch = "--vpp-rotate",
.Text = "Rotate:",
.ValueIsName = True,
.Options = {"0", "90", "180", "270"}}
Private ItemsValue As List(Of CommandLineItem)
Overrides ReadOnly Property Items As List(Of CommandLineItem)
Get
If ItemsValue Is Nothing Then
ItemsValue = New List(Of CommandLineItem)
Add("Basic", Decoder, Codec, QualitySpeed, Mode, Quality, QPI, QPP, QPB)
Add("Advanced", ProfileH264, ProfileHEVC, ProfileMPEG2, LevelHEVC, LevelH264, LevelMPEG2, Rotate, BFrames, Ref, GOPLength, LookaheadDepth, Scenechange, MBBRC, Custom)
Add("Deinterlace", Deinterlace, TFF, BFF)
End If
Return ItemsValue
End Get
End Property
Private AddedList As New List(Of String)
Private Sub Add(path As String, ParamArray items As CommandLineItem())
For Each i In items
i.Path = path
ItemsValue.Add(i)
If i.GetKey = "" OrElse AddedList.Contains(i.GetKey) Then
Throw New Exception
End If
Next
End Sub
Function GetMode(name As String) As Integer
For x = 0 To Modes.Count - 1
If Modes(x).Name = name Then Return x
Next
End Function
Protected Overrides Sub OnValueChanged(item As CommandLineItem)
If item Is Deinterlace Then
If Deinterlace.ValueText = "normal" OrElse Deinterlace.ValueText = "bob" Then
If Not TFF.Value AndAlso Not BFF.Value Then TFF.Value = True
Else
TFF.Value = False
BFF.Value = False
End If
End If
If item Is Codec OrElse item Is Nothing Then
If Codec.ValueText = "hevc" Then
BFrames.DefaultValue = 2
Else
BFrames.DefaultValue = 3
End If
End If
If item Is Codec Then
Mode.Value = 2
If Codec.ValueText = "hevc" Then
BFrames.Value = 2
Else
BFrames.Value = 3
End If
End If
Mode.HideOptions(Codec.ValueText = "h264", GetMode("avbr"), GetMode("la"),
GetMode("la-hrd"), GetMode("la-icq"), GetMode("qvbr"),
GetMode("qvbr-q"), GetMode("vcm"))
MyBase.OnValueChanged(item)
End Sub
Overrides Function GetCommandLine(includePaths As Boolean, includeExecutable As Boolean) As String
Dim ret As String
Dim sourcePath = p.Script.Path
Dim targetPath = p.VideoEncoder.OutputPath.ChangeExt(p.VideoEncoder.OutputFileType)
If includePaths AndAlso includeExecutable Then
ret = Packs.QSVEncC.GetPath.AddPathQuotes
End If
Select Case Decoder.ValueText
Case "avs"
sourcePath = p.Script.Path
Case "nv"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.NVEncC.GetPath.AddPathQuotes, "NVEncC") + " --output-file - --codec raw" + " --input-file " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " | " + If(includePaths, Packs.QSVEncC.GetPath.AddPathQuotes, "QSVEncC")
Case "vce"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.VCEEncC.GetPath.AddPathQuotes, "VCEEncC") + " --output-file - --codec raw" + " --input-file " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " | " + If(includePaths, Packs.QSVEncC.GetPath.AddPathQuotes, "QSVEncC")
Case "qs"
sourcePath = p.LastOriginalSourceFile
ret = " --avqsv"
Case "ff"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.ffmpeg.GetPath.AddPathQuotes, "ffmpeg") + " -threads 1 -hwaccel dxva2 -i " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " -f yuv4mpegpipe -pix_fmt yuv420p -loglevel error - | " + If(includePaths, Packs.QSVEncC.GetPath.AddPathQuotes, "QSVEncC")
End Select
Dim q = From i In Items Where i.GetArgs <> ""
If q.Count > 0 Then
ret += " " + q.Select(Function(item) item.GetArgs).Join(" ")
End If
Select Case Mode.ValueText
Case "icq", "la-icq"
ret += " --" + Mode.ValueText + " " & CInt(Quality.Value)
Case "qvbr-q"
ret += " --qvbr-q " & CInt(Quality.Value) & " --qvbr " & p.VideoBitrate
Case "cqp", "vqp"
ret += " --" + Mode.ValueText + " " & CInt(QPI.Value) & ":" & CInt(QPP.Value) & ":" & CInt(QPB.Value)
Case Else
ret += " --" + Mode.ValueText + " " & p.VideoBitrate
End Select
If p.Script.IsFilterActive("Resize", "Hardware Encoder") OrElse
(Decoder.ValueText <> "avs" AndAlso p.Script.IsFilterActive("Resize")) Then
ret += " --output-res " & p.TargetWidth & "x" & p.TargetHeight
ElseIf p.AutoARSignaling Then
Dim par = Calc.GetTargetPAR
If par <> New Point(1, 1) Then ret += " --sar " & par.X & ":" & par.Y
End If
If CInt(p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) <> 0 AndAlso
(p.Script.IsFilterActive("Crop", "Hardware Encoder") OrElse
(Decoder.ValueText <> "avs" AndAlso p.Script.IsFilterActive("Crop"))) Then
ret += " --crop " & p.CropLeft & "," & p.CropTop & "," & p.CropRight & "," & p.CropBottom
End If
If Decoder.ValueText <> "avs" Then
If p.Ranges.Count > 0 Then
ret += " --trim " + p.Ranges.Select(Function(range) range.Start & ":" & range.End).Join(",")
End If
If FileTypes.VideoText.Contains(Filepath.GetExt(p.SourceFile)) Then
sourcePath = p.LastOriginalSourceFile
Else
sourcePath = p.SourceFile
End If
End If
If sourcePath = "-" Then
ret += " --y4m --input-res " & p.TargetWidth & "x" & p.TargetHeight & " --fps " &
p.Script.GetFramerate.ToString("f6", CultureInfo.InvariantCulture)
End If
If includePaths Then ret += " --input-file " + sourcePath.AddPathQuotes + " --output-file " + targetPath.AddPathQuotes
Return ret.Trim
End Function
Public Overrides Function GetPackage() As Package
Return Packs.QSVEncC
End Function
End Class
End Class
<Serializable()>
Class AMDEncoder
Inherits VideoEncoder
Property ParamsStore As New PrimitiveStore
Sub New(profileName As String)
MyBase.New(profileName)
End Sub
<NonSerialized>
Private ParamsValue As EncoderParams
Property Params As EncoderParams
Get
If ParamsValue Is Nothing Then
ParamsValue = New EncoderParams
ParamsValue.Init(ParamsStore)
End If
Return ParamsValue
End Get
Set(value As EncoderParams)
ParamsValue = value
End Set
End Property
Overrides Sub ShowConfigDialog()
Dim newParams As New EncoderParams
Dim store = DirectCast(ObjectHelp.GetCopy(ParamsStore), PrimitiveStore)
newParams.Init(store)
Using f As New CommandLineForm(newParams)
f.cms.Items.Add(New ActionMenuItem("Check VCE Support", Sub() MsgInfo(ProcessHelp.GetStdOut(Packs.NVEncC.GetPath, "--check-vce"))))
If f.ShowDialog() = DialogResult.OK Then
Params = newParams
ParamsStore = store
OnStateChange()
End If
End Using
End Sub
Overrides ReadOnly Property OutputFileType() As String
Get
Return "h264"
End Get
End Property
Overrides Sub Encode()
p.Script.Synchronize()
Dim cl = Params.GetCommandLine(True, False)
If cl.Contains(" | ") Then
Dim batchPath = p.TempDir + p.TargetFile.Base + "_VCEEncC.bat"
File.WriteAllText(batchPath, cl, Encoding.GetEncoding(850))
Using proc As New Proc
proc.Init("Encoding using VCEEncC")
proc.SkipStrings = {"%]", " frames: "}
proc.WriteLine(cl + CrLf2)
proc.File = "cmd.exe"
proc.Arguments = "/C call """ + batchPath + """"
proc.Start()
End Using
Else
Using proc As New Proc
proc.Init("Encoding using VCEEncC")
proc.SkipStrings = {"%]"}
proc.File = Packs.VCEEncC.GetPath
proc.Arguments = cl
proc.Start()
End Using
End If
AfterEncoding()
End Sub
Overrides Function GetMenu() As MenuList
Dim r As New MenuList
r.Add("Encoder Options", AddressOf ShowConfigDialog)
r.Add("Container Configuration", AddressOf OpenMuxerConfigDialog)
Return r
End Function
Overrides Property QualityMode() As Boolean
Get
Return Params.Mode.OptionText = "CQP"
End Get
Set(Value As Boolean)
End Set
End Property
Class EncoderParams
Inherits CommandLineParams
Sub New()
Title = "AMD Encoding Options"
End Sub
Property Mode As New OptionParam With {
.Name = "Mode",
.Text = "Mode:",
.Options = {"CBR", "VBR", "CQP"}}
Property Decoder As New OptionParam With {
.Text = "Decoder:",
.Options = {"AviSynth/VapourSynth", "VCEEncC", "QSVEncC Quick Sync", "ffmpeg dxva2"},
.Values = {"avs", "vce", "qs", "ff"}}
Property Quality As New OptionParam With {
.Switch = "--quality",
.Text = "Quality:",
.ValueIsName = True,
.Options = {"fast", "balanced", "slow"},
.Value = 1,
.DefaultValue = 1}
Property QPI As New NumParam With {
.Text = "Constant QP I:",
.Value = 22,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property QPP As New NumParam With {
.Text = "Constant QP P:",
.Value = 24,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property QPB As New NumParam With {
.Text = "Constant QP B:",
.Value = 27,
.VisibleFunc = Function() "CQP" = Mode.OptionText,
.MinMaxStep = {0, 51, 1}}
Property MaxBitrate As New NumParam With {
.Switch = "--max-bitrate",
.Text = "Maximum Bitrate:",
.Value = 20000,
.DefaultValue = 20000,
.MinMaxStep = {0, 1000000, 1}}
Property GOPLength As New NumParam With {
.Switch = "--gop-len",
.Text = "GOP Length (0=auto):",
.MinMaxStep = {0, 10000, 1}}
Property BFrames As New NumParam With {
.Switch = "--bframes",
.Text = "B Frames:",
.MinMaxStep = {0, 16, 1}}
Property QPMax As New NumParam With {
.Switch = "--qp-max",
.Text = "QP Max:",
.MinMaxStep = {0, 100, 1},
.Value = 100,
.DefaultValue = 100}
Property QPMin As New NumParam With {
.Switch = "--qp-min",
.Text = "QP Min:",
.MinMaxStep = {0, 100, 1}}
Property VBVBufsize As New NumParam With {
.Switch = "--vbv-bufsize",
.Text = "VBV Bufsize:",
.MinMaxStep = {0, 1000000, 1},
.Value = 20000,
.DefaultValue = 20000}
Property Custom As New StringParam With {
.Text = "Custom Switches:",
.ArgsFunc = Function() Custom.Value}
Private ItemsValue As List(Of CommandLineItem)
Overrides ReadOnly Property Items As List(Of CommandLineItem)
Get
If ItemsValue Is Nothing Then
ItemsValue = New List(Of CommandLineItem)
Add("Basic", Decoder, Mode, Quality, QPI, QPP, QPB, GOPLength, BFrames)
Add("Advanced", MaxBitrate, VBVBufsize, QPMin, QPMax, Custom)
End If
Return ItemsValue
End Get
End Property
Private AddedList As New List(Of String)
Private Sub Add(path As String, ParamArray items As CommandLineItem())
For Each i In items
i.Path = path
ItemsValue.Add(i)
If i.GetKey = "" OrElse AddedList.Contains(i.GetKey) Then
Throw New Exception
End If
Next
End Sub
Protected Overrides Sub OnValueChanged(item As CommandLineItem)
MyBase.OnValueChanged(item)
End Sub
Overrides Function GetCommandLine(includePaths As Boolean, includeExecutable As Boolean) As String
Dim ret As String
Dim sourcePath As String
Dim targetPath = p.VideoEncoder.OutputPath.ChangeExt(p.VideoEncoder.OutputFileType)
If includePaths AndAlso includeExecutable Then
ret = Packs.VCEEncC.GetPath.AddPathQuotes
End If
Select Case Decoder.ValueText
Case "avs"
sourcePath = p.Script.Path
Case "vce"
sourcePath = p.LastOriginalSourceFile
Case "qs"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.QSVEncC.GetPath.AddPathQuotes, "QSVEncC") + " --output-file - --codec raw" + " --input-file " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " | " + If(includePaths, Packs.VCEEncC.GetPath.AddPathQuotes, "VCEEncC")
Case "ff"
sourcePath = "-"
If includePaths Then ret = If(includePaths, Packs.ffmpeg.GetPath.AddPathQuotes, "ffmpeg") + " -threads 1 -hwaccel dxva2 -i " + If(includePaths, p.SourceFile.AddPathQuotes, "path") + " -f yuv4mpegpipe -pix_fmt yuv420p -loglevel error - | " + If(includePaths, Packs.VCEEncC.GetPath.AddPathQuotes, "VCEEncC")
End Select
Dim q = From i In Items Where i.GetArgs <> ""
If q.Count > 0 Then
ret += " " + q.Select(Function(item) item.GetArgs).Join(" ")
End If
Select Case Mode.OptionText
Case "CBR"
ret += " --cbr " & p.VideoBitrate
Case "VBR"
ret += " --vbr " & p.VideoBitrate
Case "CQP"
ret += " --cqp " & QPI.Value & ":" & QPP.Value & ":" & QPB.Value
End Select
If sourcePath = "-" Then
ret += " --y4m --fps " &
p.Script.GetFramerate.ToString("f6", CultureInfo.InvariantCulture)
End If
If includePaths Then
ret += " --input-file " + sourcePath.AddPathQuotes + " --output-file " + targetPath.AddPathQuotes
End If
Return ret.Trim
End Function
Public Overrides Function GetPackage() As Package
Return Packs.VCEEncC
End Function
End Class
End Class