mirror of
https://github.com/harshabose/transcode.git
synced 2025-10-08 13:20:19 +08:00
updated x264 options
This commit is contained in:
@@ -2,6 +2,7 @@ package transcode
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
buffer "github.com/harshabose/tools/buffer/pkg"
|
buffer "github.com/harshabose/tools/buffer/pkg"
|
||||||
|
|
||||||
@@ -16,37 +17,80 @@ type codecSettings interface {
|
|||||||
ForEach(func(string, string) error) error
|
ForEach(func(string, string) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type X264Settings struct {
|
type X264Opts struct {
|
||||||
Preset string `x264:"preset"`
|
// RateControl string `x264-opts:"rate-control"`
|
||||||
Tune string `x264:"tune"`
|
Bitrate string `x264-opts:"bitrate"`
|
||||||
Refs string `x264:"refs"`
|
VBVMaxBitrate string `x264-opts:"vbv-maxrate"`
|
||||||
Profile string `x264:"profile"`
|
VBVBuffer string `x264-opts:"vbv-bufsize"`
|
||||||
Level string `x264:"level"`
|
RateTol string `x264-opts:"ratetol"`
|
||||||
Qmin string `x264:"qmin"`
|
SyncLookAhead string `x264-opts:"sync-lookahead"`
|
||||||
Qmax string `x264:"qmax"`
|
AnnexB string `x264-opts:"annexb"`
|
||||||
BFrames string `x264:"bframes"`
|
|
||||||
BAdapt string `x264:"b-adapt"`
|
|
||||||
NGOP string `x264:"keyint"`
|
|
||||||
NGOPMin string `x264:"min-keyint"`
|
|
||||||
Scenecut string `x264:"scenecut"`
|
|
||||||
InfraRefresh string `x264:"intra-refresh"`
|
|
||||||
LookAhead string `x264:"rc-lookahead"`
|
|
||||||
SlicedThreads string `x264:"sliced-threads"`
|
|
||||||
SyncLookAhead string `x264:"sync-lookahead"`
|
|
||||||
ForceIDR string `x264:"force-idr"`
|
|
||||||
AQMode string `x264:"aq-mode"`
|
|
||||||
AQStrength string `x264:"aq-strength"`
|
|
||||||
MBTree string `x264:"mbtree"`
|
|
||||||
Bitrate string `x264:"bitrate"`
|
|
||||||
VBVMaxBitrate string `x264:"vbv-maxrate"`
|
|
||||||
VBVBuffer string `x264:"vbv-bufsize"`
|
|
||||||
RateTol string `x264:"ratetol"`
|
|
||||||
Threads string `x264:"threads"`
|
|
||||||
AnnexB string `x264:"annexb"`
|
|
||||||
Aud string `x264:"aud"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s X264Settings) ForEach(fn func(key, value string) error) error {
|
func (x264 X264Opts) ForEach(fn func(string, string) error) error {
|
||||||
|
t := reflect.TypeOf(x264)
|
||||||
|
v := reflect.ValueOf(x264)
|
||||||
|
|
||||||
|
// Build a single x264opts string
|
||||||
|
var optParts []string
|
||||||
|
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
tag := field.Tag.Get("x264-opts")
|
||||||
|
if tag != "" && v.Field(i).String() != "" {
|
||||||
|
optParts = append(optParts, tag+"="+v.Field(i).String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join all options with colons
|
||||||
|
if len(optParts) > 0 {
|
||||||
|
x264optsValue := strings.Join(optParts, ":")
|
||||||
|
// Set as a single parameter
|
||||||
|
if err := fn("x264opts", x264optsValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also apply any regular x264 parameters
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
tag := field.Tag.Get("x264")
|
||||||
|
if tag != "" {
|
||||||
|
if err := fn(tag, v.Field(i).String()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type X264OpenSettings struct {
|
||||||
|
X264Opts
|
||||||
|
Preset string `x264:"preset"` // exists
|
||||||
|
Tune string `x264:"tune"` // exists
|
||||||
|
Refs string `x264:"refs"` // exists
|
||||||
|
Profile string `x264:"profile"` // exists
|
||||||
|
Level string `x264:"level"` // exists
|
||||||
|
Qmin string `x264:"qmin"` // exists
|
||||||
|
Qmax string `x264:"qmax"` // exists
|
||||||
|
BFrames string `x264:"bf"` // exists
|
||||||
|
BAdapt string `x264:"b_strategy"` // exists
|
||||||
|
NGOP string `x264:"g"` // exists
|
||||||
|
NGOPMin string `x264:"keyint_min"` // exists
|
||||||
|
Scenecut string `x264:"sc_threshold"` // exists
|
||||||
|
InfraRefresh string `x264:"intra-refresh"` // exists
|
||||||
|
LookAhead string `x264:"rc-lookahead"` // exists
|
||||||
|
SlicedThreads string `x264:"slice"` // exists
|
||||||
|
ForceIDR string `x264:"force-idr"` // exists
|
||||||
|
AQMode string `x264:"aq-mode"` // exists
|
||||||
|
AQStrength string `x264:"aq-strength"` // exists
|
||||||
|
MBTree string `x264:"mbtree"` // exists
|
||||||
|
Threads string `x264:"threads"` // exists
|
||||||
|
Aud string `x264:"aud"` // exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s X264OpenSettings) ForEach(fn func(key, value string) error) error {
|
||||||
t := reflect.TypeOf(s)
|
t := reflect.TypeOf(s)
|
||||||
v := reflect.ValueOf(s)
|
v := reflect.ValueOf(s)
|
||||||
|
|
||||||
@@ -59,10 +103,20 @@ func (s X264Settings) ForEach(fn func(key, value string) error) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return s.X264Opts.ForEach(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultX264Settings = X264Settings{
|
var DefaultX264Settings = X264OpenSettings{
|
||||||
|
X264Opts: X264Opts{
|
||||||
|
// RateControl: "abr",
|
||||||
|
Bitrate: "4000",
|
||||||
|
VBVMaxBitrate: "5000",
|
||||||
|
VBVBuffer: "8000",
|
||||||
|
RateTol: "1",
|
||||||
|
SyncLookAhead: "1",
|
||||||
|
AnnexB: "1",
|
||||||
|
},
|
||||||
Preset: "medium",
|
Preset: "medium",
|
||||||
Tune: "film",
|
Tune: "film",
|
||||||
Refs: "6",
|
Refs: "6",
|
||||||
@@ -78,21 +132,24 @@ var DefaultX264Settings = X264Settings{
|
|||||||
InfraRefresh: "0",
|
InfraRefresh: "0",
|
||||||
LookAhead: "40",
|
LookAhead: "40",
|
||||||
SlicedThreads: "0",
|
SlicedThreads: "0",
|
||||||
SyncLookAhead: "1",
|
|
||||||
ForceIDR: "0",
|
ForceIDR: "0",
|
||||||
AQMode: "1",
|
AQMode: "1",
|
||||||
AQStrength: "1.0",
|
AQStrength: "1.0",
|
||||||
MBTree: "1",
|
MBTree: "1",
|
||||||
Bitrate: "4000",
|
|
||||||
VBVMaxBitrate: "5000",
|
|
||||||
VBVBuffer: "8000",
|
|
||||||
RateTol: "1",
|
|
||||||
Threads: "0",
|
Threads: "0",
|
||||||
AnnexB: "1",
|
|
||||||
Aud: "0",
|
Aud: "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
var LowBandwidthX264Settings = X264Settings{
|
var LowBandwidthX264Settings = X264OpenSettings{
|
||||||
|
X264Opts: X264Opts{
|
||||||
|
// RateControl: "abr",
|
||||||
|
Bitrate: "1500",
|
||||||
|
VBVMaxBitrate: "1800",
|
||||||
|
VBVBuffer: "3000",
|
||||||
|
RateTol: "0.25",
|
||||||
|
SyncLookAhead: "0",
|
||||||
|
AnnexB: "1",
|
||||||
|
},
|
||||||
Preset: "veryfast",
|
Preset: "veryfast",
|
||||||
Tune: "fastdecode",
|
Tune: "fastdecode",
|
||||||
Refs: "2",
|
Refs: "2",
|
||||||
@@ -108,21 +165,24 @@ var LowBandwidthX264Settings = X264Settings{
|
|||||||
InfraRefresh: "0",
|
InfraRefresh: "0",
|
||||||
LookAhead: "20",
|
LookAhead: "20",
|
||||||
SlicedThreads: "1",
|
SlicedThreads: "1",
|
||||||
SyncLookAhead: "0",
|
|
||||||
ForceIDR: "0",
|
ForceIDR: "0",
|
||||||
AQMode: "0",
|
AQMode: "0",
|
||||||
AQStrength: "1.2",
|
AQStrength: "1.2",
|
||||||
MBTree: "0",
|
MBTree: "0",
|
||||||
Bitrate: "1500",
|
|
||||||
VBVMaxBitrate: "1800",
|
|
||||||
VBVBuffer: "3000",
|
|
||||||
RateTol: "0.25",
|
|
||||||
Threads: "0",
|
Threads: "0",
|
||||||
AnnexB: "1",
|
|
||||||
Aud: "0",
|
Aud: "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
var LowLatencyX264Settings = X264Settings{
|
var LowLatencyX264Settings = X264OpenSettings{
|
||||||
|
X264Opts: X264Opts{
|
||||||
|
// RateControl: "abr",
|
||||||
|
Bitrate: "5000",
|
||||||
|
VBVMaxBitrate: "12000",
|
||||||
|
VBVBuffer: "20000",
|
||||||
|
RateTol: "0.5",
|
||||||
|
SyncLookAhead: "0",
|
||||||
|
AnnexB: "1",
|
||||||
|
},
|
||||||
Preset: "ultrafast",
|
Preset: "ultrafast",
|
||||||
Tune: "zerolatency",
|
Tune: "zerolatency",
|
||||||
Refs: "1",
|
Refs: "1",
|
||||||
@@ -138,21 +198,25 @@ var LowLatencyX264Settings = X264Settings{
|
|||||||
InfraRefresh: "1",
|
InfraRefresh: "1",
|
||||||
LookAhead: "10",
|
LookAhead: "10",
|
||||||
SlicedThreads: "1",
|
SlicedThreads: "1",
|
||||||
SyncLookAhead: "0",
|
|
||||||
ForceIDR: "1",
|
ForceIDR: "1",
|
||||||
AQMode: "0",
|
AQMode: "0",
|
||||||
AQStrength: "0",
|
AQStrength: "0",
|
||||||
MBTree: "0",
|
MBTree: "0",
|
||||||
Bitrate: "2500",
|
|
||||||
VBVMaxBitrate: "3000",
|
Threads: "0",
|
||||||
VBVBuffer: "5000",
|
Aud: "1",
|
||||||
RateTol: "0.5",
|
|
||||||
Threads: "0",
|
|
||||||
AnnexB: "1",
|
|
||||||
Aud: "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var HighQualityX264Settings = X264Settings{
|
var HighQualityX264Settings = X264OpenSettings{
|
||||||
|
X264Opts: X264Opts{
|
||||||
|
// RateControl: "abr",
|
||||||
|
Bitrate: "15000",
|
||||||
|
VBVMaxBitrate: "20000",
|
||||||
|
VBVBuffer: "30000",
|
||||||
|
RateTol: "2.0",
|
||||||
|
SyncLookAhead: "1",
|
||||||
|
AnnexB: "1",
|
||||||
|
},
|
||||||
Preset: "slow",
|
Preset: "slow",
|
||||||
Tune: "film",
|
Tune: "film",
|
||||||
Refs: "8",
|
Refs: "8",
|
||||||
@@ -168,18 +232,13 @@ var HighQualityX264Settings = X264Settings{
|
|||||||
InfraRefresh: "0",
|
InfraRefresh: "0",
|
||||||
LookAhead: "60",
|
LookAhead: "60",
|
||||||
SlicedThreads: "0",
|
SlicedThreads: "0",
|
||||||
SyncLookAhead: "1",
|
|
||||||
ForceIDR: "0",
|
ForceIDR: "0",
|
||||||
AQMode: "0",
|
AQMode: "0",
|
||||||
AQStrength: "1.3",
|
AQStrength: "1.3",
|
||||||
MBTree: "1",
|
MBTree: "1",
|
||||||
Bitrate: "15000",
|
|
||||||
VBVMaxBitrate: "20000",
|
Threads: "0",
|
||||||
VBVBuffer: "30000",
|
Aud: "0",
|
||||||
RateTol: "2.0",
|
|
||||||
Threads: "0",
|
|
||||||
AnnexB: "1",
|
|
||||||
Aud: "0",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithX264DefaultOptions(encoder *Encoder) error {
|
func WithX264DefaultOptions(encoder *Encoder) error {
|
||||||
|
Reference in New Issue
Block a user