Fix green video from RTSP H264

This commit is contained in:
Alexey Khit
2022-09-15 06:55:05 +03:00
parent 7784b0e64c
commit 3a10cb25bb
2 changed files with 49 additions and 32 deletions
+11
View File
@@ -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
View File
@@ -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
} }
} }
} }