refactor(videochannel): remove b codec

This commit is contained in:
zarazaex69
2026-04-30 01:55:17 +03:00
parent e848bde8de
commit 9c7b4e316f
9 changed files with 2 additions and 199 deletions

View File

@@ -39,8 +39,6 @@ type config struct {
videoQRSize int
videoQRRecovery string
videoCodec string
videoBModule int
videoBColors int
vp8FPS int
vp8BatchSize int
}
@@ -121,8 +119,6 @@ func parseFlags() config {
flag.IntVar(&cfg.videoQRSize, "video-qr-size", 0, "Video QR code fragment size (videochannel only)")
flag.StringVar(&cfg.videoQRRecovery, "video-qr-recovery", "low", "QR error correction: low (7%), medium (15%), high (25%), highest (30%)")
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()
@@ -180,8 +176,6 @@ func toSessionConfig(cfg config) session.Config {
VideoQRSize: cfg.videoQRSize,
VideoQRRecovery: cfg.videoQRRecovery,
VideoCodec: cfg.videoCodec,
VideoBModule: cfg.videoBModule,
VideoBColors: cfg.videoBColors,
VP8FPS: cfg.vp8FPS,
VP8BatchSize: cfg.vp8BatchSize,
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -65,8 +65,6 @@ type streamTransport struct {
videoQRSize int
videoQRRecovery string
videoCodec string
videoBModule int
videoBColors int
}
// New creates a visual videochannel transport backed by a carrier-specific provider.
@@ -124,8 +122,6 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
videoQRSize: qrSize,
videoQRRecovery: cfg.VideoQRRecovery,
videoCodec: cfg.VideoCodec,
videoBModule: cfg.VideoBModule,
videoBColors: cfg.VideoBColors,
}
if err := stream.AddTrack(track); err != nil {
@@ -285,11 +281,7 @@ func (p *streamTransport) writerLoop() {
var rawFrame []byte
var err error
if p.videoCodec == "b" {
rawFrame, err = renderVisualFrameB(payload, p.videoW, p.videoH, p.videoBModule, p.videoBColors, p.videoQRRecovery)
} else {
rawFrame, err = renderVisualFrame(payload, p.videoW, p.videoH, p.videoQRRecovery)
}
rawFrame, err = renderVisualFrame(payload, p.videoW, p.videoH, p.videoQRRecovery)
if err != nil {
logger.Debugf("videochannel render error: %v", err)
continue
@@ -398,11 +390,7 @@ func (p *streamTransport) handleRemoteTrack(track *webrtc.TrackRemote, _ *webrtc
func (p *streamTransport) handleFrame(frame []byte) {
var payload []byte
var err error
if p.videoCodec == "b" {
payload, err = extractVisualPayloadB(frame, p.videoW, p.videoH, p.videoBModule, p.videoBColors)
} else {
payload, err = extractVisualPayload(frame, p.videoW, p.videoH)
}
payload, err = extractVisualPayload(frame, p.videoW, p.videoH)
if err != nil || len(payload) == 0 {
if err != nil {
logger.Debugf("videochannel extract visual payload error: %v", err)

View File

@@ -1,113 +0,0 @@
//go:build b
package videochannel
import (
"fmt"
"os"
"github.com/openlibrecommunity/olcrtc/internal/logger"
"github.com/zarazaex69/b/go"
)
func renderVisualFrameB(payload []byte, width, height, modulePx, colors int, _ string) ([]byte, error) {
rgba := make([]byte, width*height*4)
for i := 0; i < len(rgba); i += 4 {
rgba[i] = 0xff
rgba[i+1] = 0xff
rgba[i+2] = 0xff
rgba[i+3] = 0xff
}
if len(payload) == 0 {
return rgba, nil
}
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)
}
bmpW := int(result.Width)
bmpH := int(result.Height)
offsetX := (width - bmpW) / 2
offsetY := (height - bmpH) / 2
for y := 0; y < bmpH; y++ {
for x := 0; x < bmpW; x++ {
srcIdx := (y*bmpW + x) * 4
pixelX := offsetX + x
pixelY := offsetY + y
if pixelX >= 0 && pixelX < width && pixelY >= 0 && pixelY < height {
dstIdx := (pixelY*width + pixelX) * 4
rgba[dstIdx] = result.RGBA[srcIdx]
rgba[dstIdx+1] = result.RGBA[srcIdx+1]
rgba[dstIdx+2] = result.RGBA[srcIdx+2]
rgba[dstIdx+3] = result.RGBA[srcIdx+3]
}
}
}
return rgba, nil
}
var frameCounter int
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)
}
if isWhiteFrame(frame) {
return nil, nil
}
frameCounter++
if frameCounter <= 3 {
fname := fmt.Sprintf("/tmp/b_frame_%d.rgba", frameCounter)
_ = writeFile(fname, frame)
logger.Debugf("saved non-white frame to %s", fname)
}
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)
return nil, nil
}
return decoded, nil
}
func isWhiteFrame(frame []byte) bool {
for i := 0; i < len(frame); i += 4 {
if frame[i] != 0xff || frame[i+1] != 0xff || frame[i+2] != 0xff {
return false
}
}
return true
}
func writeFile(path string, data []byte) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(data)
return err
}

View File

@@ -1,11 +0,0 @@
//go:build !b
package videochannel
func renderVisualFrameB(payload []byte, width, height, modulePx, colors int, recoveryLevel string) ([]byte, error) {
return renderVisualFrame(payload, width, height, recoveryLevel)
}
func extractVisualPayloadB(frame []byte, width, height, modulePx, colors int) ([]byte, error) {
return extractVisualPayload(frame, width, height)
}

View File

@@ -1,47 +0,0 @@
//go:build b
package videochannel
import (
"bytes"
"testing"
)
func TestBCodecRoundtrip(t *testing.T) {
data := []byte("Hello JABCode test 123456789012345678901234567890")
width, height := 480, 480
frame, err := renderVisualFrameB(data, width, height)
if err != nil {
t.Fatalf("renderVisualFrameB failed: %v", err)
}
expectedSize := width * height * 4
if len(frame) != expectedSize {
t.Fatalf("unexpected frame size: %d, want %d", len(frame), expectedSize)
}
payload, err := extractVisualPayloadB(frame, width, height)
if err != nil {
t.Fatalf("extractVisualPayloadB failed: %v", err)
}
if payload == nil {
t.Fatal("extractVisualPayloadB returned nil payload")
}
if !bytes.Equal(payload, data) {
t.Fatalf("roundtrip mismatch:\noriginal: %q\ndecoded: %q", string(data), string(payload))
}
}
func TestBCodecEmptyPayload(t *testing.T) {
width, height := 480, 480
frame, err := renderVisualFrameB(nil, width, height)
if err != nil {
t.Fatalf("renderVisualFrameB with empty payload failed: %v", err)
}
expectedSize := width * height * 4
if len(frame) != expectedSize {
t.Fatalf("unexpected frame size: %d", len(frame))
}
}