1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-09 18:25:58 +01:00

Implement empty VP8 headers.

According to RFC 7741 Section 4.4, a packetizer may ignore VP8
partition boundaries.  In that case, it might generate VP8
packets with S=0 and no data at all in the header.
This commit is contained in:
Juliusz Chroboczek 2023-01-06 22:59:20 +01:00
parent 260b80fe93
commit f9ec0f9b43
4 changed files with 69 additions and 16 deletions

View file

@ -233,7 +233,8 @@ type Flags struct {
Start bool Start bool
End bool End bool
Keyframe bool Keyframe bool
Pid uint16 // only returned for VP8 MissingPid bool // only returned for VP8
Pid uint16 // only returned for VP8
Tid uint8 Tid uint8
Sid uint8 Sid uint8
TidUpSync bool TidUpSync bool
@ -243,7 +244,7 @@ type Flags struct {
} }
func PacketFlags(codec string, buf []byte) (Flags, error) { func PacketFlags(codec string, buf []byte) (Flags, error) {
if len(buf) < 12 { if len(buf) < 4 {
return Flags{}, errTruncated return Flags{}, errTruncated
} }
@ -267,6 +268,7 @@ func PacketFlags(codec string, buf []byte) (Flags, error) {
flags.Start = vp8.S != 0 && vp8.PID == 0 flags.Start = vp8.S != 0 && vp8.PID == 0
flags.End = packet.Marker flags.End = packet.Marker
flags.Keyframe = vp8.S != 0 && (vp8.Payload[0]&0x1) == 0 flags.Keyframe = vp8.S != 0 && (vp8.Payload[0]&0x1) == 0
flags.MissingPid = vp8.S == 0 && vp8.I == 0
flags.Pid = vp8.PictureID flags.Pid = vp8.PictureID
flags.Tid = vp8.TID flags.Tid = vp8.TID
flags.TidUpSync = flags.Keyframe || vp8.Y == 1 flags.TidUpSync = flags.Keyframe || vp8.Y == 1
@ -309,7 +311,7 @@ func RewritePacket(codec string, data []byte, setMarker bool, seqno uint16, delt
return errTruncated return errTruncated
} }
if(setMarker) { if setMarker {
data[1] |= 0x80 data[1] |= 0x80
} }
@ -321,7 +323,7 @@ func RewritePacket(codec string, data []byte, setMarker bool, seqno uint16, delt
offset := 12 offset := 12
offset += int(data[0]&0x0F) * 4 offset += int(data[0]&0x0F) * 4
if len(data) < offset+4 { if len(data) <= offset {
return errTruncated return errTruncated
} }
@ -339,19 +341,30 @@ func RewritePacket(codec string, data []byte, setMarker bool, seqno uint16, delt
if !x { if !x {
return nil return nil
} }
i := (data[offset+1] & 0x80) != 0 offset++
if len(data) <= offset {
return errTruncated
}
i := (data[offset] & 0x80) != 0
if !i { if !i {
return nil return nil
} }
m := (data[offset+2] & 0x80) != 0 offset++
if len(data) <= offset {
return errTruncated
}
m := (data[offset] & 0x80) != 0
if m { if m {
pid := (uint16(data[offset+2]&0x7F) << 8) | if len(data) <= offset+1 {
uint16(data[offset+3]) return errTruncated
}
pid := (uint16(data[offset]&0x7F) << 8) |
uint16(data[offset+1])
pid = (pid + delta) & 0x7FFF pid = (pid + delta) & 0x7FFF
data[offset+2] = 0x80 | byte((pid>>8)&0x7F) data[offset] = 0x80 | byte((pid>>8)&0x7F)
data[offset+3] = byte(pid & 0xFF) data[offset+1] = byte(pid & 0xFF)
} else { } else {
data[offset+2] = (data[offset+2] + uint8(delta)) & 0x7F data[offset] = (data[offset] + uint8(delta)) & 0x7F
} }
return nil return nil
} }

View file

@ -138,10 +138,19 @@ var vp8 = []byte{
0, 0, 0, 0, 0, 0, 0, 0,
} }
var emptyVP8 = []byte{
0x80, 0, 0, 42,
0, 0, 0, 0,
0, 0, 0, 0,
0x00,
}
func TestPacketFlagsVP8(t *testing.T) { func TestPacketFlagsVP8(t *testing.T) {
buf := append([]byte{}, vp8...) buf := append([]byte{}, vp8...)
flags, err := PacketFlags("video/vp8", buf) flags, err := PacketFlags("video/vp8", buf)
if flags.Seqno != 42 || !flags.Start || flags.Pid != 57 || if flags.Seqno != 42 || !flags.Start ||
flags.MissingPid || flags.Pid != 57 ||
flags.Sid != 0 || flags.Tid != 0 || flags.Sid != 0 || flags.Tid != 0 ||
!flags.TidUpSync || flags.Discardable || err != nil { !flags.TidUpSync || flags.Discardable || err != nil {
t.Errorf("Got %v, %v, %v, %v, %v, %v (%v)", t.Errorf("Got %v, %v, %v, %v, %v, %v (%v)",
@ -151,6 +160,19 @@ func TestPacketFlagsVP8(t *testing.T) {
} }
} }
func TestEmptyPacketFlagsVP8(t *testing.T) {
buf := append([]byte{}, emptyVP8...)
flags, err := PacketFlags("video/vp8", buf)
if flags.Seqno != 42 || flags.Start || !flags.MissingPid ||
flags.Sid != 0 || flags.Tid != 0 ||
flags.TidUpSync || flags.Discardable || err != nil {
t.Errorf("Got %v, %v, %v, %v, %v, %v (%v)",
flags.Seqno, flags.Start, flags.Pid, flags.Sid,
flags.TidUpSync, flags.Discardable, err,
)
}
}
func TestRewriteVP8(t *testing.T) { func TestRewriteVP8(t *testing.T) {
for i := uint16(0); i < 0x7fff; i++ { for i := uint16(0); i < 0x7fff; i++ {
buf := append([]byte{}, vp8...) buf := append([]byte{}, vp8...)
@ -169,6 +191,24 @@ func TestRewriteVP8(t *testing.T) {
} }
} }
func TestRewriteEmptyVP8(t *testing.T) {
for i := uint16(0); i < 0x7fff; i++ {
buf := append([]byte{}, emptyVP8...)
err := RewritePacket("video/vp8", buf, true, i, i)
if err != nil {
t.Errorf("rewrite: %v", err)
continue
}
flags, err := PacketFlags("video/vp8", buf)
if err != nil || flags.Seqno != i ||
!flags.MissingPid || !flags.Marker {
t.Errorf("Expected %v %v, got %v %v (%v)",
i, (57+i)&0x7FFF,
flags.Seqno, flags.Pid, err)
}
}
}
var vp9 = []byte{ var vp9 = []byte{
0x80, 0, 0, 42, 0x80, 0, 0, 42,
0, 0, 0, 0, 0, 0, 0, 0,

2
go.mod
View file

@ -19,3 +19,5 @@ require (
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
) )
replace github.com/pion/rtp => github.com/jech/rtp v1.6.6-0.20230106211622-35cc0f7fad45

6
go.sum
View file

@ -29,6 +29,8 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jech/cert v0.0.0-20210819231831-aca735647728 h1:tN+W1ll2oKuJGMCaO1CRK4rr+xSRjVSfWmnKlACdx38= github.com/jech/cert v0.0.0-20210819231831-aca735647728 h1:tN+W1ll2oKuJGMCaO1CRK4rr+xSRjVSfWmnKlACdx38=
github.com/jech/cert v0.0.0-20210819231831-aca735647728/go.mod h1:FXUA/zpiQfV4uBVN2kAwkf3X7pU7l1l2ovS45CsSYZs= github.com/jech/cert v0.0.0-20210819231831-aca735647728/go.mod h1:FXUA/zpiQfV4uBVN2kAwkf3X7pU7l1l2ovS45CsSYZs=
github.com/jech/rtp v1.6.6-0.20230106211622-35cc0f7fad45 h1:VqLy+KBoTQBYgd7dqr1WwJiKmTojw+rTcAnpV97SbXk=
github.com/jech/rtp v1.6.6-0.20230106211622-35cc0f7fad45/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/jech/samplebuilder v0.0.0-20220417174833-7353a593563a h1:yFkaguK4pmi0K33b8TA9T5Qoj0mZHpNPMCFdtru2yDg= github.com/jech/samplebuilder v0.0.0-20220417174833-7353a593563a h1:yFkaguK4pmi0K33b8TA9T5Qoj0mZHpNPMCFdtru2yDg=
github.com/jech/samplebuilder v0.0.0-20220417174833-7353a593563a/go.mod h1:U83y/Kl/5BrI9ceNw17+lmguIrlUlMVntxKmZmei5EA= github.com/jech/samplebuilder v0.0.0-20220417174833-7353a593563a/go.mod h1:U83y/Kl/5BrI9ceNw17+lmguIrlUlMVntxKmZmei5EA=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -71,10 +73,6 @@ github.com/pion/rtcp v1.2.8/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqN
github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo= github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc= github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
github.com/pion/rtp v1.7.0/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.7.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0= github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sctp v1.7.12/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s= github.com/pion/sctp v1.7.12/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s= github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=