Fix RTSP from RTMP stream

This commit is contained in:
Alexey Khit
2022-09-05 20:04:30 +03:00
parent 0e71bd4dcb
commit f442aab176
+61 -39
View File
@@ -1,6 +1,7 @@
package h264 package h264
import ( import (
"encoding/binary"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"github.com/pion/rtp" "github.com/pion/rtp"
"github.com/pion/rtp/codecs" "github.com/pion/rtp/codecs"
@@ -19,62 +20,83 @@ func RTPDepay(track *streamer.Track) streamer.WrapperFunc {
return func(push streamer.WriterFunc) streamer.WriterFunc { return func(push streamer.WriterFunc) streamer.WriterFunc {
return func(packet *rtp.Packet) error { return func(packet *rtp.Packet) error {
//println(packet.SequenceNumber, packet.Payload[0]&0x1F, packet.Payload[0], packet.Payload[1], packet.Marker, packet.Timestamp) //nalUnitType := packet.Payload[0] & 0x1F
//fmt.Printf(
// "[RTP] codec: %s, nalu: %2d, size: %6d, ts: %10d, pt: %2d, ssrc: %d\n",
// track.Codec.Name, nalUnitType, len(packet.Payload), packet.Timestamp,
// packet.PayloadType, packet.SSRC,
//)
data, err := depack.Unmarshal(packet.Payload) // NALu packets can be split in different ways:
if len(data) == 0 || err != nil { // - single type 7 and type 8 packets
// - join type 7 and type 8 packet (type 24)
// - split type 5 on multiple 28 packets
// - split type 5 on multiple separate 28 packets
units, err := depack.Unmarshal(packet.Payload)
if len(units) == 0 || err != nil {
return nil return nil
} }
naluType := NALUType(data) for {
//println(naluType, len(data)) i := int(binary.BigEndian.Uint32(units)) + 4
unitAVC := units[:i]
switch naluType { unitType := NALUType(unitAVC)
case NALUTypeSPS: switch unitType {
//println("new SPS") case NALUTypeSPS:
sps = data //println("new SPS")
return nil sps = unitAVC
case NALUTypePPS: return nil
//println("new PPS") case NALUTypePPS:
pps = data //println("new PPS")
return nil pps = unitAVC
} return nil
}
// ffmpeg with `-tune zerolatency` enable option `-x264opts sliced-threads=1` // ffmpeg with `-tune zerolatency` enable option `-x264opts sliced-threads=1`
// and every NALU will be sliced to multiple NALUs // and every NALU will be sliced to multiple NALUs
if !packet.Marker { if !packet.Marker {
buffer = append(buffer, data...) buffer = append(buffer, unitAVC...)
return nil return nil
} }
if buffer != nil { if buffer != nil {
buffer = append(buffer, data...) buffer = append(buffer, unitAVC...)
data = buffer unitAVC = buffer
buffer = nil buffer = nil
} }
var clone rtp.Packet var clone rtp.Packet
if naluType == NALUTypeIFrame { if unitType == NALUTypeIFrame {
clone = *packet clone = *packet
clone.Version = RTPPacketVersionAVC clone.Version = RTPPacketVersionAVC
clone.Payload = sps clone.Payload = sps
if err = push(&clone); err != nil { if err = push(&clone); err != nil {
return err return err
}
clone = *packet
clone.Version = RTPPacketVersionAVC
clone.Payload = pps
if err = push(&clone); err != nil {
return err
}
} }
clone = *packet clone = *packet
clone.Version = RTPPacketVersionAVC clone.Version = RTPPacketVersionAVC
clone.Payload = pps clone.Payload = unitAVC
if err = push(&clone); err != nil { if err = push(&clone); err != nil {
return err return err
} }
}
clone = *packet if len(units) == i {
clone.Version = RTPPacketVersionAVC return nil
clone.Payload = data }
return push(&clone)
units = units[i:]
}
} }
} }
} }