mirror of
https://github.com/jech/galene.git
synced 2024-11-12 19:55:59 +01:00
Make isKeyframe codec-agnostic.
This commit is contained in:
parent
ed9377e38f
commit
cc35931ad1
3 changed files with 71 additions and 20 deletions
48
rtpconn/rtp_test.go
Normal file
48
rtpconn/rtp_test.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package rtpconn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pion/rtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVP8Keyframe(t *testing.T) {
|
||||||
|
ps := [][]byte{
|
||||||
|
{
|
||||||
|
|
||||||
|
0x80, 0xe0, 0x71, 0x3e, 0x5d, 0x6f, 0x3c, 0xc5,
|
||||||
|
0x75, 0xc, 0x80, 0x96, 0x90, 0x80, 0xb0, 0x4c,
|
||||||
|
0x90, 0x2, 0x0, 0x9d, 0x1, 0x2a, 0x10, 0x0, 0x10,
|
||||||
|
0x0, 0x39, 0x3, 0x0, 0x0, 0x1c, 0x22, 0x16, 0x16,
|
||||||
|
0x22, 0x66, 0x12, 0x20, 0x4, 0x90, 0x40, 0x4e,
|
||||||
|
0x9e, 0x8d, 0xe9, 0x40, 0xfe, 0xff, 0xab, 0x59,
|
||||||
|
0x72, 0x30, 0xd1, 0xaf, 0xe4, 0x6a, 0x11, 0x3,
|
||||||
|
0xfd, 0x15, 0xe9, 0x2, 0x2e, 0xdf, 0xd9, 0xd1,
|
||||||
|
0xb8, 0x0, 0x0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x80, 0x6f, 0x61, 0x8f, 0xd5, 0x36, 0xdc, 0x15,
|
||||||
|
0x1b, 0x4a, 0xb5, 0x29, 0x78, 0x9, 0xa1, 0x93,
|
||||||
|
0xa0, 0x5b, 0xd8, 0xf1, 0xde, 0x87, 0x23, 0x5a,
|
||||||
|
0xb9, 0x19, 0x97, 0xb7, 0xbd, 0xbf, 0xf7, 0x6e,
|
||||||
|
0xad, 0x82, 0xc4, 0x70, 0x1c, 0xc9, 0x3a, 0xb4,
|
||||||
|
0x1f, 0x13, 0x45, 0xb5, 0xf1, 0x0, 0xa5, 0xa5,
|
||||||
|
0xa9, 0xd0, 0xa5, 0xdf, 0x67, 0x88, 0x26, 0x30,
|
||||||
|
0x32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var packet rtp.Packet
|
||||||
|
|
||||||
|
for i, p := range ps {
|
||||||
|
err := packet.Unmarshal(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unmarshal(p%v): %v", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kf, kfKnown := isKeyframe("video/vp8", &packet)
|
||||||
|
if kf != (i == 0) || !kfKnown {
|
||||||
|
t.Errorf("isKeyframe(p%v): %v %v", i, kf, kfKnown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,15 +13,26 @@ import (
|
||||||
"github.com/jech/galene/rtptime"
|
"github.com/jech/galene/rtptime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isVP8Keyframe(packet *rtp.Packet) bool {
|
// isKeyframe determines if packet is the start of a keyframe.
|
||||||
var vp8 codecs.VP8Packet
|
// It returns (true, true) if that is the case, (false, true) if that is
|
||||||
_, err := vp8.Unmarshal(packet.Payload)
|
// definitely not the case, and (false, false) if the information cannot
|
||||||
if err != nil {
|
// be determined.
|
||||||
return false
|
func isKeyframe(codec string, packet *rtp.Packet) (bool, bool) {
|
||||||
}
|
switch strings.ToLower(codec) {
|
||||||
|
case "video/vp8":
|
||||||
|
var vp8 codecs.VP8Packet
|
||||||
|
_, err := vp8.Unmarshal(packet.Payload)
|
||||||
|
if err != nil || len(vp8.Payload) < 1 {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
||||||
return vp8.S != 0 && vp8.PID == 0 &&
|
if vp8.S != 0 && vp8.PID == 0 && (vp8.Payload[0]&0x1) == 0 {
|
||||||
len(vp8.Payload) > 0 && (vp8.Payload[0]&0x1) == 0
|
return true, true
|
||||||
|
}
|
||||||
|
return false, true
|
||||||
|
default:
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
|
func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
|
||||||
|
@ -54,10 +65,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
|
||||||
|
|
||||||
track.jitter.Accumulate(packet.Timestamp)
|
track.jitter.Accumulate(packet.Timestamp)
|
||||||
|
|
||||||
kf := false
|
kf, _ := isKeyframe(codec.MimeType, &packet)
|
||||||
if isvideo && strings.ToLower(codec.MimeType) == "video/vp8" {
|
|
||||||
kf = isVP8Keyframe(&packet)
|
|
||||||
}
|
|
||||||
|
|
||||||
first, index := track.cache.Store(
|
first, index := track.cache.Store(
|
||||||
packet.SequenceNumber, packet.Timestamp,
|
packet.SequenceNumber, packet.Timestamp,
|
||||||
|
|
|
@ -343,13 +343,8 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if kfNeeded > kfUnneeded {
|
if kfNeeded > kfUnneeded {
|
||||||
kf := false
|
kf, kfKnown :=
|
||||||
kfValid := false
|
isKeyframe(codec.MimeType, &packet)
|
||||||
switch strings.ToLower(codec.MimeType) {
|
|
||||||
case "video/vp8":
|
|
||||||
kf = isVP8Keyframe(&packet)
|
|
||||||
kfValid = true
|
|
||||||
}
|
|
||||||
if kf {
|
if kf {
|
||||||
kfNeeded = kfUnneeded
|
kfNeeded = kfUnneeded
|
||||||
}
|
}
|
||||||
|
@ -370,7 +365,7 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||||
up.sendPLI(track)
|
up.sendPLI(track)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !kfValid {
|
if !kfKnown {
|
||||||
// we cannot detect keyframes for
|
// we cannot detect keyframes for
|
||||||
// this codec, reset our state
|
// this codec, reset our state
|
||||||
kfNeeded = kfUnneeded
|
kfNeeded = kfUnneeded
|
||||||
|
|
Loading…
Reference in a new issue