Fix RTSP from RTMP stream
This commit is contained in:
+36
-14
@@ -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,43 +20,55 @@ 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)
|
||||||
|
switch unitType {
|
||||||
case NALUTypeSPS:
|
case NALUTypeSPS:
|
||||||
//println("new SPS")
|
//println("new SPS")
|
||||||
sps = data
|
sps = unitAVC
|
||||||
return nil
|
return nil
|
||||||
case NALUTypePPS:
|
case NALUTypePPS:
|
||||||
//println("new PPS")
|
//println("new PPS")
|
||||||
pps = data
|
pps = unitAVC
|
||||||
return nil
|
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
|
||||||
@@ -73,8 +86,17 @@ func RTPDepay(track *streamer.Track) streamer.WrapperFunc {
|
|||||||
|
|
||||||
clone = *packet
|
clone = *packet
|
||||||
clone.Version = RTPPacketVersionAVC
|
clone.Version = RTPPacketVersionAVC
|
||||||
clone.Payload = data
|
clone.Payload = unitAVC
|
||||||
return push(&clone)
|
if err = push(&clone); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(units) == i {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
units = units[i:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user