Move keyframe interval to common Video config and set it to 120 frames

This commit is contained in:
sergystepanov 2026-06-12 16:39:41 +03:00
parent 7ece426518
commit 10c2727a38
6 changed files with 41 additions and 46 deletions

View file

@ -56,9 +56,10 @@ type Audio struct {
}
type Video struct {
Codec string
Threads int
H264 struct {
Codec string
KeyframeInterval int
Threads int
H264 struct {
Mode string
Crf uint8
MaxRate int
@ -69,11 +70,10 @@ type Video struct {
Tune string
}
Vpx struct {
Bitrate uint
KeyframeInterval uint
CpuUsed int
TileColumns int
Tune string
Bitrate uint
CpuUsed int
TileColumns int
Tune string
}
}

View file

@ -53,14 +53,14 @@ func NewVideoEncoder(w, h, dw, dh int, scale float64, conf config.Video, log *lo
switch codec {
case H264:
opts := h264.Options(conf.H264)
enc, err = h264.NewEncoder(dw, dh, conf.Threads, &opts)
enc, err = h264.NewEncoder(dw, dh, conf.Threads, conf.KeyframeInterval, &opts)
case VP8, VP9, VPX:
opts := vpx.Options(conf.Vpx)
v := 8
if codec == VP9 {
v = 9
}
enc, err = vpx.NewEncoder(dw, dh, conf.Threads, v, &opts)
enc, err = vpx.NewEncoder(dw, dh, conf.Threads, conf.KeyframeInterval, v, &opts)
default:
err = fmt.Errorf("unsupported codec: %v", conf.Codec)
}

View file

@ -98,7 +98,7 @@ type Options struct {
Tune string
}
func NewEncoder(w, h int, th int, opts *Options) (encoder *H264, err error) {
func NewEncoder(w, h int, th int, kfi int, opts *Options) (encoder *H264, err error) {
ver := Version()
if ver < 150 {
@ -146,7 +146,11 @@ func NewEncoder(w, h int, th int, opts *Options) (encoder *H264, err error) {
param.i_width = C.int(w)
param.i_height = C.int(h)
param.i_log_level = C.int(opts.LogLevel)
param.i_keyint_max = 120
if kfi > 0 {
param.i_keyint_max = C.int(kfi)
} else {
param.i_keyint_max = 120
}
param.i_sync_lookahead = 0
param.i_threads = C.int(th)
if th != 1 {

View file

@ -3,7 +3,7 @@ package h264
import "testing"
func TestH264Encode(t *testing.T) {
h264, err := NewEncoder(120, 120, 0, nil)
h264, err := NewEncoder(120, 120, 0, 120, nil)
if err != nil {
t.Error(err)
return
@ -17,7 +17,7 @@ func TestH264Encode(t *testing.T) {
func Benchmark(b *testing.B) {
w, h := 1920, 1080
h264, err := NewEncoder(w, h, 0, nil)
h264, err := NewEncoder(w, h, 0, 120, nil)
if err != nil {
b.Error(err)
return

View file

@ -127,10 +127,7 @@ func autoThreads(configured, cpus int) int {
if configured != 0 {
return configured
}
reserve := cpus / 4
if reserve < 1 {
reserve = 1
}
reserve := max(cpus/4, 1)
if t := cpus - reserve; t > 0 {
return t
}
@ -140,8 +137,6 @@ func autoThreads(configured, cpus int) int {
type Options struct {
// Target bandwidth to use for this stream, in kilobits per second.
Bitrate uint
// Force keyframe interval.
KeyframeInterval uint
// Speed/quality tradeoff (0=auto, 18 manual). Defaults to 0.
// Applies to both VP8 and VP9.
CpuUsed int
@ -151,28 +146,21 @@ type Options struct {
Tune string
}
func NewEncoder(w, h int, th int, version int, opts *Options) (*Vpx, error) {
idx := 0
if version == 9 {
idx = 1
}
encoder := &C.vpx_encoders[idx]
if encoder == nil {
return nil, fmt.Errorf("couldn't get the encoder")
}
func NewEncoder(w, h int, th int, kfi int, version int, opts *Options) (*Vpx, error) {
if opts == nil {
opts = &Options{
Bitrate: 1200,
KeyframeInterval: 120,
TileColumns: 2,
Tune: "screen",
Bitrate: 1200,
TileColumns: 2,
Tune: "screen",
}
}
if kfi == 0 {
kfi = 120
}
vpx := Vpx{
frameCount: C.int(0),
kfi: C.int(opts.KeyframeInterval),
kfi: C.int(kfi),
v: version,
}
@ -180,6 +168,12 @@ func NewEncoder(w, h int, th int, version int, opts *Options) (*Vpx, error) {
return nil, fmt.Errorf("vpx_img_alloc failed")
}
idx := 0
if version == 9 {
idx = 1
}
encoder := &C.vpx_encoders[idx]
var cfg C.vpx_codec_enc_cfg_t
if C.call_vpx_codec_enc_config_default(encoder, &cfg) != 0 {
return nil, fmt.Errorf("failed to get default codec config")
@ -274,9 +268,7 @@ func (vpx *Vpx) IntraRefresh() {
}
func (vpx *Vpx) Shutdown() error {
//if &vpx.image != nil {
C.vpx_img_free(&vpx.image)
//}
C.vpx_codec_destroy(&vpx.codecCtx)
vpx.flipped = false
return nil

View file

@ -37,8 +37,9 @@ func BenchmarkVP8(b *testing.B) { run(1920, 1080, encoder.VP8, b.N, nil, nil, b
func run(w, h int, cod encoder.VideoCodec, count int, a *image.RGBA, b *image.RGBA, backend testing.TB) {
conf := config.Video{
Codec: string(cod),
Threads: 0,
Codec: string(cod),
Threads: 0,
KeyframeInterval: 120,
H264: struct {
Mode string
Crf uint8
@ -56,14 +57,12 @@ func run(w, h int, cod encoder.VideoCodec, count int, a *image.RGBA, b *image.RG
Tune: "zerolatency",
},
Vpx: struct {
Bitrate uint
KeyframeInterval uint
CpuUsed int
TileColumns int
Tune string
Bitrate uint
CpuUsed int
TileColumns int
Tune string
}{
Bitrate: 1000,
KeyframeInterval: 5,
Bitrate: 1000,
},
}