Fallback to primary encoding if redundant block overflow (#2858)

* Fallback to primary encoding if redundant block overflow

* revert mtu change
This commit is contained in:
cnderrauber
2024-07-12 16:39:54 +08:00
committed by GitHub
parent 1a4b1d30db
commit a995c71f84
2 changed files with 25 additions and 8 deletions
+10 -4
View File
@@ -406,12 +406,18 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters,
return webrtc.RTPCodecParameters{}, err
} else if strings.EqualFold(matchedUpstreamCodec.MimeType, "audio/red") {
d.isRED = true
var primaryPT, secondaryPT int
if n, err := fmt.Sscanf(matchedUpstreamCodec.SDPFmtpLine, "%d/%d", &primaryPT, &secondaryPT); err != nil || n != 2 {
d.params.Logger.Errorw("failed to parse upstream primary and secondary payload type for RED", err, "matchedCodec", codec)
for _, c := range d.upstreamCodecs {
// assume upstream primary codec is opus since we only support it for audio now
if strings.EqualFold(c.MimeType, "audio/opus") {
d.upstreamPrimaryPT = uint8(c.PayloadType)
break
}
}
if d.upstreamPrimaryPT == 0 {
d.params.Logger.Errorw("failed to find upstream primary opus payload type for RED", nil, "matchedCodec", codec, "upstreamCodec", d.upstreamCodecs)
}
d.upstreamPrimaryPT = uint8(primaryPT)
var primaryPT, secondaryPT int
if n, err := fmt.Sscanf(codec.SDPFmtpLine, "%d/%d", &primaryPT, &secondaryPT); err != nil || n != 2 {
d.params.Logger.Errorw("failed to parse primary and secondary payload type for RED", err, "matchedCodec", codec)
}
+15 -4
View File
@@ -29,13 +29,15 @@ import (
)
const (
maxRedCount = 2
mtuSize = 1500
maxRedCount = 2
mtuSize = 1500
maxRedPayload = 1 << 10 // fit into 10 bits length field
// the RedReceiver is only for chrome / native webrtc now, we always negotiate opus payload to 111 with those clients,
// so it is safe to use a fixed payload 111 here for performance(avoid encoding red blocks for each downtrack that
// have a different opus payload type).
opusPT = 111
opusPT = 111
opusRedPT = 63
)
type RedReceiver struct {
@@ -60,6 +62,14 @@ func (r *RedReceiver) ForwardRTP(pkt *buffer.ExtPacket, spatialLayer int32) int
if r.downTrackSpreader.DownTrackCount() == 0 {
return 0
}
// fallback to primary codec if payload size exceeds redundant block length
if len(pkt.Packet.Payload) >= maxRedPayload {
return r.downTrackSpreader.Broadcast(func(dt TrackSender) {
_ = dt.WriteRTP(pkt, spatialLayer)
})
}
redLen, err := r.encodeRedForPrimary(pkt.Packet, r.redPayloadBuf[:])
if err != nil {
r.logger.Errorw("red encoding failed", err)
@@ -68,6 +78,7 @@ func (r *RedReceiver) ForwardRTP(pkt *buffer.ExtPacket, spatialLayer int32) int
pPkt := *pkt
redRtpPacket := *pkt.Packet
redRtpPacket.PayloadType = 63
redRtpPacket.Payload = r.redPayloadBuf[:redLen]
pPkt.Packet = &redRtpPacket
@@ -117,7 +128,7 @@ func (r *RedReceiver) Close() {
}
func (r *RedReceiver) ReadRTP(buf []byte, layer uint8, sn uint16) (int, error) {
// red encoding don't support nack
// red encoding doesn't support nack
return 0, bucket.ErrPacketMismatch
}