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

Implement pid and mark rewriting for VP9, fix VP9 sync bits.

The sync bits were incorrect.  In addition, we need to set the
marker at the new end of the frame when doing spatial decimation.
This commit is contained in:
Juliusz Chroboczek 2021-08-03 05:05:21 +02:00
parent 56226a2934
commit 4f7be19644
3 changed files with 109 additions and 17 deletions

View file

@ -230,12 +230,15 @@ func KeyframeDimensions(codec string, packet *rtp.Packet) (uint32, uint32) {
type Flags struct { type Flags struct {
Seqno uint16 Seqno uint16
Marker bool
Start bool Start bool
Pid uint16 // only if it needs rewriting End bool
Keyframe bool
Pid uint16
Tid uint8 Tid uint8
Sid uint8 Sid uint8
TidUpSync bool TidUpSync bool
SidSync bool SidUpSync bool
SidNonReference bool SidNonReference bool
Discardable bool Discardable bool
} }
@ -248,6 +251,7 @@ func PacketFlags(codec string, buf []byte) (Flags, error) {
var flags Flags var flags Flags
flags.Seqno = (uint16(buf[2]) << 8) | uint16(buf[3]) flags.Seqno = (uint16(buf[2]) << 8) | uint16(buf[3])
flags.Marker = (buf[1] & 0x80) != 0
if strings.EqualFold(codec, "video/vp8") { if strings.EqualFold(codec, "video/vp8") {
var packet rtp.Packet var packet rtp.Packet
@ -261,10 +265,13 @@ func PacketFlags(codec string, buf []byte) (Flags, error) {
return flags, err return flags, err
} }
flags.Start = vp8.S == 1 && vp8.PID == 0 flags.Start = vp8.S != 0 && vp8.PID == 0
flags.End = packet.Marker
flags.Keyframe = vp8.S != 0 && (vp8.Payload[0]&0x1) == 0
flags.Pid = vp8.PictureID flags.Pid = vp8.PictureID
flags.Tid = vp8.TID flags.Tid = vp8.TID
flags.TidUpSync = vp8.Y == 1 flags.TidUpSync = flags.Keyframe || vp8.Y == 1
flags.SidUpSync = flags.Keyframe
flags.Discardable = vp8.N == 1 flags.Discardable = vp8.N == 1
return flags, nil return flags, nil
} else if strings.EqualFold(codec, "video/vp9") { } else if strings.EqualFold(codec, "video/vp9") {
@ -279,22 +286,35 @@ func PacketFlags(codec string, buf []byte) (Flags, error) {
return flags, err return flags, err
} }
flags.Start = vp9.B flags.Start = vp9.B
flags.End = vp9.E
if (vp9.Payload[0] & 0xc0) == 0x80 {
profile := (vp9.Payload[0] >> 4) & 0x3
if profile != 3 {
flags.Keyframe = (vp9.Payload[0] & 0xC) == 0
} else {
flags.Keyframe = (vp9.Payload[0] & 0x6) == 0
}
}
flags.Pid = vp9.PictureID
flags.Tid = vp9.TID flags.Tid = vp9.TID
flags.Sid = vp9.SID flags.Sid = vp9.SID
flags.TidUpSync = vp9.U flags.TidUpSync = flags.Keyframe || vp9.U
flags.SidSync = vp9.P flags.SidUpSync = flags.Keyframe || !vp9.P
// not yet in pion/rtp
flags.SidNonReference = (packet.Payload[0] & 0x01) != 0 flags.SidNonReference = (packet.Payload[0] & 0x01) != 0
return flags, nil return flags, nil
} }
return flags, nil return flags, nil
} }
func RewritePacket(codec string, data []byte, seqno uint16, delta uint16) error { func RewritePacket(codec string, data []byte, setMarker bool, seqno uint16, delta uint16) error {
if len(data) < 12 { if len(data) < 12 {
return errTruncated return errTruncated
} }
if(setMarker) {
data[1] |= 0x80
}
data[2] = uint8(seqno >> 8) data[2] = uint8(seqno >> 8)
data[3] = uint8(seqno) data[3] = uint8(seqno)
if delta == 0 { if delta == 0 {
@ -335,6 +355,23 @@ func RewritePacket(codec string, data []byte, seqno uint16, delta uint16) error
data[offset+2] = (data[offset+2] + uint8(delta)) & 0x7F data[offset+2] = (data[offset+2] + uint8(delta)) & 0x7F
} }
return nil return nil
} else if strings.EqualFold(codec, "video/vp9") {
i := (data[offset] & 0x80) != 0
if !i {
return nil
} }
m := (data[offset+1] & 0x80) != 0
if m {
pid := (uint16(data[offset+1]&0x7F) << 8) |
uint16(data[offset+2])
pid = (pid + delta) & 0x7FFF
data[offset+1] = 0x80 | byte((pid>>8)&0x7F)
data[offset+2] = byte(pid & 0xFF)
} else {
data[offset+1] = (data[offset+1] + uint8(delta)) & 0x7F
}
return nil
}
return errUnsupportedCodec return errUnsupportedCodec
} }

View file

@ -138,7 +138,7 @@ var vp8 = []byte{
0, 0, 0, 0, 0, 0, 0, 0,
} }
func TestPacketFlags(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.Pid != 57 ||
@ -151,17 +151,56 @@ func TestPacketFlags(t *testing.T) {
} }
} }
func TestRewrite(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...)
err := RewritePacket("video/vp8", buf, i, i) err := RewritePacket("video/vp8", buf, true, i, i)
if err != nil { if err != nil {
t.Errorf("rewrite: %v", err) t.Errorf("rewrite: %v", err)
continue continue
} }
flags, err := PacketFlags("video/vp8", buf) flags, err := PacketFlags("video/vp8", buf)
if err != nil || flags.Seqno != i || if err != nil || flags.Seqno != i ||
flags.Pid != (57+i)&0x7FFF { flags.Pid != (57+i)&0x7FFF || !flags.Marker {
t.Errorf("Expected %v %v, got %v %v (%v)",
i, (57+i)&0x7FFF,
flags.Seqno, flags.Pid, err)
}
}
}
var vp9 = []byte{
0x80, 0, 0, 42,
0, 0, 0, 0,
0, 0, 0, 0,
0x88, 0x80, 57, 0,
}
func TestPacketFlagsVP9(t *testing.T) {
buf := append([]byte{}, vp9...)
flags, err := PacketFlags("video/vp9", buf)
if flags.Seqno != 42 || !flags.Start || flags.Pid != 57 ||
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 TestRewriteVP9(t *testing.T) {
for i := uint16(0); i < 0x7fff; i++ {
buf := append([]byte{}, vp9...)
err := RewritePacket("video/vp9", buf, true, i, i)
if err != nil {
t.Errorf("rewrite: %v", err)
continue
}
flags, err := PacketFlags("video/vp9", buf)
if err != nil || flags.Seqno != i ||
flags.Pid != (57+i)&0x7FFF || !flags.Marker {
t.Errorf("Expected %v %v, got %v %v (%v)", t.Errorf("Expected %v %v, got %v %v (%v)",
i, (57+i)&0x7FFF, i, (57+i)&0x7FFF,
flags.Seqno, flags.Pid, err) flags.Seqno, flags.Pid, err)

View file

@ -248,9 +248,23 @@ func (down *rtpDownTrack) Write(buf []byte) (int, error) {
} }
if flags.Start && (layer.sid != layer.wantedSid) { if flags.Start && (layer.sid != layer.wantedSid) {
if flags.SidSync { if layer.wantedSid < layer.sid {
if flags.Keyframe {
layer.sid = layer.wantedSid layer.sid = layer.wantedSid
down.setLayerInfo(layer) down.setLayerInfo(layer)
} else {
down.remote.RequestKeyframe()
}
} else if layer.wantedSid > layer.sid {
if flags.Keyframe {
layer.sid = layer.wantedSid
down.setLayerInfo(layer)
} else if flags.SidUpSync {
layer.sid = layer.sid + 1
down.setLayerInfo(layer)
} else {
down.remote.RequestKeyframe()
}
} }
} }
@ -267,7 +281,9 @@ func (down *rtpDownTrack) Write(buf []byte) (int, error) {
return 0, nil return 0, nil
} }
if newseqno == flags.Seqno && piddelta == 0 { setMarker := flags.Sid == layer.sid && flags.End && !flags.Marker
if !setMarker && newseqno == flags.Seqno && piddelta == 0 {
return down.write(buf) return down.write(buf)
} }
@ -276,7 +292,7 @@ func (down *rtpDownTrack) Write(buf []byte) (int, error) {
buf2 := ibuf2.([]byte) buf2 := ibuf2.([]byte)
n := copy(buf2, buf) n := copy(buf2, buf)
err = codecs.RewritePacket(codec, buf2[:n], newseqno, piddelta) err = codecs.RewritePacket(codec, buf2[:n], setMarker, newseqno, piddelta)
if err != nil { if err != nil {
return 0, err return 0, err
} }