Move keyframe handling to the sender side.
This is simpler and gets rid of ErrKeyframeNeeded.
This commit is contained in:
+4
-52
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
@@ -223,33 +222,22 @@ func sendKeyframe(kf []uint16, track conn.DownTrack, cache *packetcache.Cache) {
|
||||
return
|
||||
}
|
||||
err = track.WriteRTP(&packet)
|
||||
if err != nil && err != conn.ErrKeyframeNeeded {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
track.Accumulate(uint32(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
kfUnneeded = iota
|
||||
kfNeededPLI
|
||||
kfNeededFIR
|
||||
kfNeededNewFIR
|
||||
)
|
||||
|
||||
// rtpWriterLoop is the main loop of an rtpWriter.
|
||||
func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||
defer close(writer.done)
|
||||
|
||||
codec := track.track.Codec()
|
||||
|
||||
buf := make([]byte, packetcache.BufSize)
|
||||
var packet rtp.Packet
|
||||
|
||||
local := make([]conn.DownTrack, 0)
|
||||
|
||||
kfNeeded := kfUnneeded
|
||||
|
||||
for {
|
||||
select {
|
||||
case action := <-writer.action:
|
||||
@@ -277,8 +265,7 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||
|
||||
found, _, lts := track.cache.Last()
|
||||
kts, _, kf := track.cache.Keyframe()
|
||||
if strings.ToLower(codec.MimeType) == "video/vp8" &&
|
||||
found && len(kf) > 0 {
|
||||
if found && len(kf) > 0 {
|
||||
if ((lts-kts)&0x80000000) != 0 ||
|
||||
lts-kts < 2*90000 {
|
||||
// we got a recent keyframe
|
||||
@@ -288,8 +275,7 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||
track.cache,
|
||||
)
|
||||
} else {
|
||||
// Request a new keyframe
|
||||
kfNeeded = kfNeededNewFIR
|
||||
track.RequestKeyframe()
|
||||
}
|
||||
} else {
|
||||
// no keyframe yet, one should
|
||||
@@ -333,44 +319,10 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) {
|
||||
for _, l := range local {
|
||||
err := l.WriteRTP(&packet)
|
||||
if err != nil {
|
||||
if err == conn.ErrKeyframeNeeded {
|
||||
kfNeeded = kfNeededPLI
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
l.Accumulate(uint32(bytes))
|
||||
}
|
||||
|
||||
if kfNeeded > kfUnneeded {
|
||||
kf, kfKnown :=
|
||||
isKeyframe(codec.MimeType, &packet)
|
||||
if kf {
|
||||
kfNeeded = kfUnneeded
|
||||
}
|
||||
|
||||
if kfNeeded >= kfNeededFIR {
|
||||
err := up.sendFIR(
|
||||
track,
|
||||
kfNeeded >= kfNeededNewFIR,
|
||||
)
|
||||
if err == ErrUnsupportedFeedback {
|
||||
kfNeeded = kfNeededPLI
|
||||
} else {
|
||||
kfNeeded = kfNeededFIR
|
||||
}
|
||||
}
|
||||
|
||||
if kfNeeded == kfNeededPLI {
|
||||
up.sendPLI(track)
|
||||
}
|
||||
|
||||
if !kfKnown {
|
||||
// we cannot detect keyframes for
|
||||
// this codec, reset our state
|
||||
kfNeeded = kfUnneeded
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user