feat: add video-qr-size configuration for videochannel transport

This commit is contained in:
zarazaex69
2026-04-21 22:32:01 +03:00
parent 77ac433f36
commit af34cdbd8e
8 changed files with 33 additions and 5 deletions

View File

@@ -36,6 +36,7 @@ type config struct {
videoFPS int
videoBitrate string
videoHW string
videoQRSize int
}
func main() {
@@ -111,6 +112,7 @@ func parseFlags() config {
flag.IntVar(&cfg.videoFPS, "video-fps", 0, "Video frames per second (videochannel only)")
flag.StringVar(&cfg.videoBitrate, "video-bitrate", "", "Video bitrate (videochannel only)")
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.Parse()
return cfg
@@ -163,6 +165,7 @@ func toSessionConfig(cfg config) session.Config {
VideoFPS: cfg.videoFPS,
VideoBitrate: cfg.videoBitrate,
VideoHW: cfg.videoHW,
VideoQRSize: cfg.videoQRSize,
}
}

View File

@@ -71,6 +71,7 @@ type Config struct {
VideoFPS int
VideoBitrate string
VideoHW string
VideoQRSize int
}
// RegisterDefaults registers built-in providers and transports.
@@ -202,6 +203,7 @@ func Run(ctx context.Context, cfg Config) error {
cfg.VideoFPS,
cfg.VideoBitrate,
cfg.VideoHW,
cfg.VideoQRSize,
)
case "cnc":
return client.Run(
@@ -220,6 +222,7 @@ func Run(ctx context.Context, cfg Config) error {
cfg.VideoFPS,
cfg.VideoBitrate,
cfg.VideoHW,
cfg.VideoQRSize,
)
default:
return ErrModeRequired

View File

@@ -60,8 +60,9 @@ func Run(
videoFPS int,
videoBitrate string,
videoHW string,
videoQRSize int,
) error {
return RunWithReady(ctx, linkName, transportName, carrierName, roomURL, keyHex, localAddr, dnsServer, socksUser, socksPass, nil, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW)
return RunWithReady(ctx, linkName, transportName, carrierName, roomURL, keyHex, localAddr, dnsServer, socksUser, socksPass, nil, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW, videoQRSize)
}
// RunWithReady is like Run but accepts a callback that is called when the client is ready.
@@ -82,6 +83,7 @@ func RunWithReady(
videoFPS int,
videoBitrate string,
videoHW string,
videoQRSize int,
) error {
runCtx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -109,7 +111,7 @@ func RunWithReady(
const linkCount = 1
for i := range linkCount {
if err := c.addLink(runCtx, linkName, transportName, carrierName, roomURL, i, cancel, dnsServer, "", 0, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW); err != nil {
if err := c.addLink(runCtx, linkName, transportName, carrierName, roomURL, i, cancel, dnsServer, "", 0, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW, videoQRSize); err != nil {
return fmt.Errorf("addLink failed: %w", err)
}
}
@@ -212,6 +214,7 @@ func (c *Client) addLink(
socksProxyPort int,
videoWidth, videoHeight, videoFPS int,
videoBitrate, videoHW string,
videoQRSize int,
) error {
ln, err := link.New(ctx, linkName, link.Config{
Transport: transportName,
@@ -227,6 +230,7 @@ func (c *Client) addLink(
VideoFPS: videoFPS,
VideoBitrate: videoBitrate,
VideoHW: videoHW,
VideoQRSize: videoQRSize,
})
if err != nil {
return fmt.Errorf("failed to create link: %w", err)

View File

@@ -27,6 +27,8 @@ func New(ctx context.Context, cfg link.Config) (link.Link, error) {
VideoHeight: cfg.VideoHeight,
VideoFPS: cfg.VideoFPS,
VideoBitrate: cfg.VideoBitrate,
VideoHW: cfg.VideoHW,
VideoQRSize: cfg.VideoQRSize,
})
if err != nil {
return nil, fmt.Errorf("create transport for direct link: %w", err)

View File

@@ -38,6 +38,7 @@ type Config struct {
VideoFPS int
VideoBitrate string
VideoHW string
VideoQRSize int
}
// Factory creates a link instance.

View File

@@ -79,6 +79,7 @@ func Run(
videoFPS int,
videoBitrate string,
videoHW string,
videoQRSize int,
) error {
runCtx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -103,7 +104,7 @@ func Run(
const linkCount = 1
for i := range linkCount {
if err := s.addLink(runCtx, linkName, transportName, carrierName, roomURL, i, cancel, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW); err != nil {
if err := s.addLink(runCtx, linkName, transportName, carrierName, roomURL, i, cancel, videoWidth, videoHeight, videoFPS, videoBitrate, videoHW, videoQRSize); err != nil {
return fmt.Errorf("addLink failed: %w", err)
}
}
@@ -189,6 +190,7 @@ func (s *Server) addLink(
cancel context.CancelFunc,
videoWidth, videoHeight, videoFPS int,
videoBitrate, videoHW string,
videoQRSize int,
) error {
ln, err := link.New(ctx, linkName, link.Config{
Transport: transportName,
@@ -204,6 +206,7 @@ func (s *Server) addLink(
VideoFPS: videoFPS,
VideoBitrate: videoBitrate,
VideoHW: videoHW,
VideoQRSize: videoQRSize,
})
if err != nil {
return fmt.Errorf("failed to create link: %w", err)

View File

@@ -46,6 +46,7 @@ type Config struct {
VideoFPS int
VideoBitrate string
VideoHW string
VideoQRSize int
}
// Factory creates a transport instance.

View File

@@ -62,6 +62,7 @@ type streamTransport struct {
videoFPS int
videoBitrate string
videoHW string
videoQRSize int
}
// New creates a visual videochannel transport backed by a carrier-specific provider.
@@ -94,6 +95,11 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
return nil, fmt.Errorf("create local video track: %w", err)
}
qrSize := cfg.VideoQRSize
if qrSize <= 0 {
qrSize = defaultFragmentSize
}
tr := &streamTransport{
stream: stream,
track: track,
@@ -111,6 +117,7 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
videoFPS: cfg.VideoFPS,
videoBitrate: cfg.VideoBitrate,
videoHW: cfg.VideoHW,
videoQRSize: qrSize,
}
if err := stream.AddTrack(track); err != nil {
@@ -156,7 +163,7 @@ func (p *streamTransport) Send(data []byte) error {
seq := p.nextSeq.Add(1)
crc := crc32.ChecksumIEEE(data)
fragments := fragmentPayload(data, defaultFragmentSize)
fragments := fragmentPayload(data, p.videoQRSize)
waiter := make(chan uint32, 1)
p.ackMu.Lock()
@@ -235,11 +242,15 @@ func (p *streamTransport) CanSend() bool {
// Features describes the current videochannel transport semantics.
func (p *streamTransport) Features() transport.Features {
maxPayload := defaultMaxPayloadSize
if p.videoQRSize*64 > maxPayload {
maxPayload = p.videoQRSize * 64
}
return transport.Features{
Reliable: true,
Ordered: true,
MessageOriented: true,
MaxPayloadSize: defaultMaxPayloadSize,
MaxPayloadSize: maxPayload,
}
}