Fix green video from RTSP H264
This commit is contained in:
@@ -1,3 +1,14 @@
|
|||||||
|
## RTP H264
|
||||||
|
|
||||||
|
Camera | NALu
|
||||||
|
-------|-----
|
||||||
|
EZVIZ C3S | 7f, 8f, 28:28:28 -> 5t, 28:28:28 -> 1t, 1t, 1t, 1t
|
||||||
|
Sonoff GK-200MP2-B | 28:28:28 -> 5t, 1t, 1t, 1t
|
||||||
|
Dahua IPC-K42 | 7f, 8f, 28:28:28 -> 5t, 28:28:28 -> 1t, 28:28:28 -> 1t
|
||||||
|
FFmpeg copy | 5t, 1t, 1t, 28:28:28 -> 1t, 28:28:28 -> 1t
|
||||||
|
FFmpeg h264 | 24 -> 6:5:5:5:5t, 24 -> 1:1:1:1t, 28:28:28 -> 5f, 28:28:28 -> 5f, 28:28:28 -> 5t
|
||||||
|
FFmpeg resize | 6f, 28:28:28 -> 5f, 28... -> 5t, 24 -> 1:1f, 24 -> 1:1t
|
||||||
|
|
||||||
## WebRTC
|
## WebRTC
|
||||||
|
|
||||||
Video codec | Media string | Device
|
Video codec | Media string | Device
|
||||||
|
|||||||
+38
-32
@@ -22,52 +22,62 @@ func RTPDepay(track *streamer.Track) streamer.WrapperFunc {
|
|||||||
return func(packet *rtp.Packet) error {
|
return func(packet *rtp.Packet) error {
|
||||||
//nalUnitType := packet.Payload[0] & 0x1F
|
//nalUnitType := packet.Payload[0] & 0x1F
|
||||||
//fmt.Printf(
|
//fmt.Printf(
|
||||||
// "[RTP] codec: %s, nalu: %2d, size: %6d, ts: %10d, pt: %2d, ssrc: %d\n",
|
// "[RTP] codec: %s, nalu: %2d, size: %6d, ts: %10d, pt: %2d, ssrc: %d, seq: %d\n",
|
||||||
// track.Codec.Name, nalUnitType, len(packet.Payload), packet.Timestamp,
|
// track.Codec.Name, nalUnitType, len(packet.Payload), packet.Timestamp,
|
||||||
// packet.PayloadType, packet.SSRC,
|
// packet.PayloadType, packet.SSRC, packet.SequenceNumber,
|
||||||
//)
|
//)
|
||||||
|
|
||||||
// NALu packets can be split in different ways:
|
data, err := depack.Unmarshal(packet.Payload)
|
||||||
// - single type 7 and type 8 packets
|
if len(data) == 0 || err != nil {
|
||||||
// - 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
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(units) > 0 {
|
for {
|
||||||
i := int(binary.BigEndian.Uint32(units)) + 4
|
unitType := NALUType(data)
|
||||||
unit := units[:i] // NAL Unit with AVC header
|
//fmt.Printf("[H264] nalu: %2d, size: %6d\n", unitType, len(data))
|
||||||
units = units[i:]
|
|
||||||
|
// multiple 5 and 1 in one payload is OK
|
||||||
|
if unitType != NALUTypeIFrame && unitType != NALUTypePFrame {
|
||||||
|
i := int(binary.BigEndian.Uint32(data)) + 4
|
||||||
|
if i < len(data) {
|
||||||
|
data0 := data[:i] // NAL Unit with AVC header
|
||||||
|
data = data[i:]
|
||||||
|
switch unitType {
|
||||||
|
case NALUTypeSPS:
|
||||||
|
sps = data0
|
||||||
|
continue
|
||||||
|
case NALUTypePPS:
|
||||||
|
pps = data0
|
||||||
|
continue
|
||||||
|
case NALUTypeSEI:
|
||||||
|
// some unnecessary text information
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unitType := NALUType(unit)
|
|
||||||
//fmt.Printf("[H264] type: %2d, size: %6d\n", unitType, i)
|
|
||||||
switch unitType {
|
switch unitType {
|
||||||
case NALUTypeSPS:
|
case NALUTypeSPS:
|
||||||
//println("new SPS")
|
sps = data
|
||||||
sps = unit
|
return nil
|
||||||
continue
|
|
||||||
case NALUTypePPS:
|
case NALUTypePPS:
|
||||||
//println("new PPS")
|
pps = data
|
||||||
pps = unit
|
return nil
|
||||||
continue
|
|
||||||
case NALUTypeSEI:
|
case NALUTypeSEI:
|
||||||
// some unnecessary text information
|
// some unnecessary text information
|
||||||
continue
|
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, unit...)
|
buffer = append(buffer, data...)
|
||||||
continue
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if buffer != nil {
|
if buffer != nil {
|
||||||
buffer = append(buffer, unit...)
|
buffer = append(buffer, data...)
|
||||||
unit = buffer
|
data = buffer
|
||||||
buffer = nil
|
buffer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,13 +101,9 @@ func RTPDepay(track *streamer.Track) streamer.WrapperFunc {
|
|||||||
|
|
||||||
clone = *packet
|
clone = *packet
|
||||||
clone.Version = RTPPacketVersionAVC
|
clone.Version = RTPPacketVersionAVC
|
||||||
clone.Payload = unit
|
clone.Payload = data
|
||||||
if err = push(&clone); err != nil {
|
return push(&clone)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user