Add UnmarshalHeader func to OPUS codec

This commit is contained in:
Alex X
2025-12-11 22:01:36 +03:00
parent 76a5e160c2
commit c5277daa45
2 changed files with 87 additions and 68 deletions
-68
View File
@@ -1,68 +0,0 @@
package opus
import (
"time"
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/pion/rtp"
)
func Log(handler core.HandlerFunc) core.HandlerFunc {
var ts uint32
return func(pkt *rtp.Packet) {
if ts == 0 {
ts = pkt.Timestamp
}
toc := pkt.Payload[0]
//config := toc >> 3
code := toc & 0b11
frame := parseFrameSize(toc)
rate := parseSampleRate(toc)
log.Printf(
"[RTP/OPUS] frame=%s rate=%5d code=%d size=%6d ts=%10d dt=%5d pt=%2d ssrc=%d seq=%d mark=%t",
frame, rate, code, len(pkt.Payload), pkt.Timestamp, pkt.Timestamp-ts, pkt.PayloadType, pkt.SSRC, pkt.SequenceNumber, pkt.Marker,
)
ts = pkt.Timestamp
handler(pkt)
}
}
func parseFrameSize(toc byte) time.Duration {
switch toc >> 3 {
case 0, 4, 8, 12, 14, 18, 22, 26, 30:
return 10_000_000
case 1, 5, 9, 13, 15, 19, 23, 27, 31:
return 20_000_000
case 2, 6, 10:
return 40_000_000
case 3, 7, 11:
return 60_000_000
case 16, 20, 24, 28:
return 2_500_000
case 17, 21, 25, 29:
return 5_000_000
}
return 0
}
func parseSampleRate(toc byte) uint16 {
switch toc >> 3 {
case 0, 1, 2, 3, 16, 17, 18, 19:
return 8000
case 4, 5, 6, 7:
return 12000
case 8, 9, 10, 11, 20, 21, 22, 23:
return 16000
case 12, 13, 24, 25, 26, 27:
return 24000
case 14, 15, 28, 29, 30, 31:
return 48000
}
return 0
}
+87
View File
@@ -0,0 +1,87 @@
package opus
import (
"time"
)
type Header struct {
Mode string
SampleRate uint16
FrameSize time.Duration
Channels byte
Frames byte
}
func UnmarshalHeader(b []byte) *Header {
// https://datatracker.ietf.org/doc/html/rfc6716#section-3.1
b0 := b[0]
config := b0 >> 3
return &Header{
Mode: parseMode(config),
SampleRate: parseSampleRate(config),
FrameSize: parseFrameSize(config),
Channels: parseChannels(b0 >> 2 & 0b1),
Frames: parseFrames(b0 & 0b11),
}
}
func parseMode(config byte) string {
if config <= 11 {
return "silk"
}
if config <= 15 {
return "hybrid"
}
return "celt"
}
func parseSampleRate(config byte) uint16 {
switch config {
case 0, 1, 2, 3, 16, 17, 18, 19:
return 8000 // NB (narrowband)
case 4, 5, 6, 7:
return 12000 // MB (medium-band)
case 8, 9, 10, 11, 20, 21, 22, 23:
return 16000 // WB (wideband)
case 12, 13, 24, 25, 26, 27:
return 24000 // SWB (super-wideband)
case 14, 15, 28, 29, 30, 31:
return 48000 // FB (fullband)
}
return 0
}
func parseFrameSize(config byte) time.Duration {
switch config {
case 0, 4, 8, 12, 14, 18, 22, 26, 30:
return 10_000_000
case 1, 5, 9, 13, 15, 19, 23, 27, 31:
return 20_000_000
case 2, 6, 10:
return 40_000_000
case 3, 7, 11:
return 60_000_000
case 16, 20, 24, 28:
return 2_500_000
case 17, 21, 25, 29:
return 5_000_000
}
return 0
}
func parseChannels(s byte) byte {
if s == 1 {
return 2
}
return 1
}
func parseFrames(c byte) byte {
switch c {
case 0:
return 1
case 1, 2:
return 2
}
return 0xFF
}