Add configurable B codec parameters

This commit is contained in:
zarazaex69
2026-04-27 06:11:25 +03:00
parent f1f5a584f5
commit 98ad27bec5
7 changed files with 34 additions and 4 deletions

View File

@@ -38,6 +38,8 @@ type config struct {
videoHW string
videoQRSize int
videoCodec string
videoBModule int
videoBColors int
vp8FPS int
vp8BatchSize int
}
@@ -117,6 +119,8 @@ func parseFlags() config {
flag.StringVar(&cfg.videoHW, "video-hw", "", "Hardware acceleration (none, nvenc)")
flag.IntVar(&cfg.videoQRSize, "video-qr-size", 0, "Video QR code fragment size (videochannel only)")
flag.StringVar(&cfg.videoCodec, "video-codec", "qrcode", "Visual codec: qrcode (slow, stable) or b (fast, unstable)")
flag.IntVar(&cfg.videoBModule, "video-b-module", 4, "B codec pixels per module (default 4)")
flag.IntVar(&cfg.videoBColors, "video-b-colors", 8, "B codec colors (4, 8, 16, 32, 64, 128, 256)")
flag.IntVar(&cfg.vp8FPS, "vp8-fps", 0, "VP8 frames per second (vp8channel only, default 25)")
flag.IntVar(&cfg.vp8BatchSize, "vp8-batch", 0, "VP8 frames per tick (vp8channel only, default 1)")
flag.Parse()
@@ -173,6 +177,8 @@ func toSessionConfig(cfg config) session.Config {
VideoHW: cfg.videoHW,
VideoQRSize: cfg.videoQRSize,
VideoCodec: cfg.videoCodec,
VideoBModule: cfg.videoBModule,
VideoBColors: cfg.videoBColors,
VP8FPS: cfg.vp8FPS,
VP8BatchSize: cfg.vp8BatchSize,
}

View File

@@ -79,6 +79,8 @@ type Config struct {
VideoHW string
VideoQRSize int
VideoCodec string
VideoBModule int
VideoBColors int
VP8FPS int
VP8BatchSize int
}

View File

@@ -30,6 +30,8 @@ func New(ctx context.Context, cfg link.Config) (link.Link, error) {
VideoHW: cfg.VideoHW,
VideoQRSize: cfg.VideoQRSize,
VideoCodec: cfg.VideoCodec,
VideoBModule: cfg.VideoBModule,
VideoBColors: cfg.VideoBColors,
VP8FPS: cfg.VP8FPS,
VP8BatchSize: cfg.VP8BatchSize,
})

View File

@@ -40,6 +40,8 @@ type Config struct {
VideoHW string
VideoQRSize int
VideoCodec string
VideoBModule int
VideoBColors int
VP8FPS int
VP8BatchSize int
}

View File

@@ -48,6 +48,8 @@ type Config struct {
VideoHW string
VideoQRSize int
VideoCodec string
VideoBModule int
VideoBColors int
VP8FPS int
VP8BatchSize int
}

View File

@@ -64,6 +64,8 @@ type streamTransport struct {
videoHW string
videoQRSize int
videoCodec string
videoBModule int
videoBColors int
}
// New creates a visual videochannel transport backed by a carrier-specific provider.
@@ -120,6 +122,8 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
videoHW: cfg.VideoHW,
videoQRSize: qrSize,
videoCodec: cfg.VideoCodec,
videoBModule: cfg.VideoBModule,
videoBColors: cfg.VideoBColors,
}
if err := stream.AddTrack(track); err != nil {
@@ -280,7 +284,7 @@ func (p *streamTransport) writerLoop() {
var rawFrame []byte
var err error
if p.videoCodec == "b" {
rawFrame, err = renderVisualFrameB(payload, p.videoW, p.videoH)
rawFrame, err = renderVisualFrameB(payload, p.videoW, p.videoH, p.videoBModule, p.videoBColors)
} else {
rawFrame, err = renderVisualFrame(payload, p.videoW, p.videoH)
}
@@ -393,7 +397,7 @@ func (p *streamTransport) handleFrame(frame []byte) {
var payload []byte
var err error
if p.videoCodec == "b" {
payload, err = extractVisualPayloadB(frame, p.videoW, p.videoH)
payload, err = extractVisualPayloadB(frame, p.videoW, p.videoH, p.videoBModule, p.videoBColors)
} else {
payload, err = extractVisualPayload(frame, p.videoW, p.videoH)
}

View File

@@ -10,7 +10,7 @@ import (
"github.com/zarazaex69/b/go"
)
func renderVisualFrameB(payload []byte, width, height int) ([]byte, error) {
func renderVisualFrameB(payload []byte, width, height, modulePx, colors int) ([]byte, error) {
rgba := make([]byte, width*height*4)
for i := 0; i < len(rgba); i += 4 {
rgba[i] = 0xff
@@ -24,6 +24,12 @@ func renderVisualFrameB(payload []byte, width, height int) ([]byte, error) {
}
cfg := b.DefaultConfig()
if modulePx > 0 {
cfg.ModulePx = uint32(modulePx)
}
if colors > 0 {
cfg.Colors = uint32(colors)
}
result, err := b.Encode(payload, cfg)
if err != nil {
return nil, fmt.Errorf("b encode: %w", err)
@@ -54,7 +60,7 @@ func renderVisualFrameB(payload []byte, width, height int) ([]byte, error) {
var frameCounter int
func extractVisualPayloadB(frame []byte, width, height int) ([]byte, error) {
func extractVisualPayloadB(frame []byte, width, height, modulePx, colors int) ([]byte, error) {
expectedSize := width * height * 4
if len(frame) != expectedSize {
return nil, fmt.Errorf("unexpected frame size: %d (expected %dx%dx4=%d)", len(frame), width, height, expectedSize)
@@ -72,6 +78,12 @@ func extractVisualPayloadB(frame []byte, width, height int) ([]byte, error) {
}
cfg := b.DefaultConfig()
if modulePx > 0 {
cfg.ModulePx = uint32(modulePx)
}
if colors > 0 {
cfg.Colors = uint32(colors)
}
decoded, err := b.Decode(frame, uint32(width), uint32(height), cfg)
if err != nil {
logger.Debugf("b decode failed: %v", err)