rewrite handleH264Payload, support BuggyCameraHasAnnexbH264Packet
This commit is contained in:
parent
e6b1c2561e
commit
b0ccdad10b
173
client.go
173
client.go
@ -531,16 +531,7 @@ func (self *Stream) makeCodecData() (err error) {
|
|||||||
case av.H264:
|
case av.H264:
|
||||||
for _, nalu := range media.SpropParameterSets {
|
for _, nalu := range media.SpropParameterSets {
|
||||||
if len(nalu) > 0 {
|
if len(nalu) > 0 {
|
||||||
switch nalu[0] & 0x1f {
|
self.handleH264Payload(0, nalu)
|
||||||
case 7:
|
|
||||||
if len(self.sps) == 0 {
|
|
||||||
self.sps = nalu
|
|
||||||
}
|
|
||||||
case 8:
|
|
||||||
if len(self.pps) == 0 {
|
|
||||||
self.pps = nalu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,16 +539,7 @@ func (self *Stream) makeCodecData() (err error) {
|
|||||||
if nalus, ok := h264parser.SplitNALUs(media.Config); ok {
|
if nalus, ok := h264parser.SplitNALUs(media.Config); ok {
|
||||||
for _, nalu := range nalus {
|
for _, nalu := range nalus {
|
||||||
if len(nalu) > 0 {
|
if len(nalu) > 0 {
|
||||||
switch nalu[0] & 0x1f {
|
self.handleH264Payload(0, nalu)
|
||||||
case 7:
|
|
||||||
if len(self.sps) == 0 {
|
|
||||||
self.sps = nalu
|
|
||||||
}
|
|
||||||
case 8:
|
|
||||||
if len(self.pps) == 0 {
|
|
||||||
self.pps = nalu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -600,7 +582,30 @@ func (self *Stream) makeCodecData() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Stream) handleH264Payload(naluType byte, timestamp uint32, packet []byte) (err error) {
|
func (self *Stream) handleBuggyCameraHasAnnexbH264Packet(timestamp uint32, packet []byte) (isBuggy bool, err error) {
|
||||||
|
if len(packet) >= 4 && packet[0] == 0 && packet[1] == 0 && packet[2] == 0 && packet[3] == 1 {
|
||||||
|
isBuggy = true
|
||||||
|
if nalus, ok := h264parser.SplitNALUs(packet); ok {
|
||||||
|
for _, nalu := range nalus {
|
||||||
|
if len(nalu) > 0 {
|
||||||
|
if err = self.handleH264Payload(timestamp, nalu); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Stream) handleH264Payload(timestamp uint32, packet []byte) (err error) {
|
||||||
|
var isBuggy bool
|
||||||
|
if isBuggy, err = self.handleBuggyCameraHasAnnexbH264Packet(timestamp, packet); isBuggy {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
naluType := packet[0]&0x1f
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Table 7-1 – NAL unit type codes
|
Table 7-1 – NAL unit type codes
|
||||||
1 Coded slice of a non-IDR picture
|
1 Coded slice of a non-IDR picture
|
||||||
@ -608,68 +613,6 @@ func (self *Stream) handleH264Payload(naluType byte, timestamp uint32, packet []
|
|||||||
6 Supplemental enhancement information (SEI)
|
6 Supplemental enhancement information (SEI)
|
||||||
7 Sequence parameter set
|
7 Sequence parameter set
|
||||||
8 Picture parameter set
|
8 Picture parameter set
|
||||||
*/
|
|
||||||
switch naluType {
|
|
||||||
case 6: // SEI ignored
|
|
||||||
|
|
||||||
case 7: // sps
|
|
||||||
if self.client != nil && self.client.DebugRtp {
|
|
||||||
fmt.Println("rtsp: got sps")
|
|
||||||
}
|
|
||||||
if bytes.Compare(self.sps, packet) != 0 {
|
|
||||||
self.spsChanged = true
|
|
||||||
self.sps = packet
|
|
||||||
if self.client != nil && self.client.DebugRtp {
|
|
||||||
fmt.Println("rtsp: sps changed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case 8: // pps
|
|
||||||
if self.client != nil && self.client.DebugRtp {
|
|
||||||
fmt.Println("rtsp: got pps")
|
|
||||||
}
|
|
||||||
if bytes.Compare(self.pps, packet) != 0 {
|
|
||||||
self.ppsChanged = true
|
|
||||||
self.pps = packet
|
|
||||||
if self.client != nil && self.client.DebugRtp {
|
|
||||||
fmt.Println("rtsp: pps changed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
if naluType == 5 {
|
|
||||||
self.pkt.IsKeyFrame = true
|
|
||||||
}
|
|
||||||
self.gotpkt = true
|
|
||||||
self.pkt.Data = packet
|
|
||||||
self.timestamp = timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
|
|
||||||
if self.isCodecDataChange() {
|
|
||||||
err = ErrCodecDataChange
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch self.Type() {
|
|
||||||
case av.H264:
|
|
||||||
/*
|
|
||||||
+---------------+
|
|
||||||
|0|1|2|3|4|5|6|7|
|
|
||||||
+-+-+-+-+-+-+-+-+
|
|
||||||
|F|NRI| Type |
|
|
||||||
+---------------+
|
|
||||||
*/
|
|
||||||
naluType := packet[0] & 0x1f
|
|
||||||
|
|
||||||
/*
|
|
||||||
NAL Unit Packet Packet Type Name Section
|
|
||||||
Type Type
|
|
||||||
-------------------------------------------------------------
|
|
||||||
0 reserved -
|
|
||||||
1-23 NAL unit Single NAL unit packet 5.6
|
1-23 NAL unit Single NAL unit packet 5.6
|
||||||
24 STAP-A Single-time aggregation packet 5.7.1
|
24 STAP-A Single-time aggregation packet 5.7.1
|
||||||
25 STAP-B Single-time aggregation packet 5.7.1
|
25 STAP-B Single-time aggregation packet 5.7.1
|
||||||
@ -681,12 +624,49 @@ func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
default:
|
||||||
case naluType >= 1 && naluType <= 23:
|
if naluType >= 1 && naluType <= 23 {
|
||||||
if err = self.handleH264Payload(naluType, timestamp, packet); err != nil {
|
if naluType == 5 {
|
||||||
|
self.pkt.IsKeyFrame = true
|
||||||
|
}
|
||||||
|
self.gotpkt = true
|
||||||
|
self.pkt.Data = packet
|
||||||
|
self.timestamp = timestamp
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("rtsp: unsupported H264 naluType=%d", naluType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case naluType == 6: // SEI ignored
|
||||||
|
|
||||||
|
case naluType == 7: // sps
|
||||||
|
if self.client != nil && self.client.DebugRtp {
|
||||||
|
fmt.Println("rtsp: got sps")
|
||||||
|
}
|
||||||
|
if len(self.sps) == 0 {
|
||||||
|
self.sps = packet
|
||||||
|
} else if bytes.Compare(self.sps, packet) != 0 {
|
||||||
|
self.spsChanged = true
|
||||||
|
self.sps = packet
|
||||||
|
if self.client != nil && self.client.DebugRtp {
|
||||||
|
fmt.Println("rtsp: sps changed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case naluType == 8: // pps
|
||||||
|
if self.client != nil && self.client.DebugRtp {
|
||||||
|
fmt.Println("rtsp: got pps")
|
||||||
|
}
|
||||||
|
if len(self.pps) == 0 {
|
||||||
|
self.pps = packet
|
||||||
|
} else if bytes.Compare(self.pps, packet) != 0 {
|
||||||
|
self.ppsChanged = true
|
||||||
|
self.pps = packet
|
||||||
|
if self.client != nil && self.client.DebugRtp {
|
||||||
|
fmt.Println("rtsp: pps changed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case naluType == 28: // FU-A
|
case naluType == 28: // FU-A
|
||||||
/*
|
/*
|
||||||
0 1 2 3
|
0 1 2 3
|
||||||
@ -740,13 +720,12 @@ func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
|
|||||||
fuHeader := packet[1]
|
fuHeader := packet[1]
|
||||||
isStart := fuHeader&0x80 != 0
|
isStart := fuHeader&0x80 != 0
|
||||||
isEnd := fuHeader&0x40 != 0
|
isEnd := fuHeader&0x40 != 0
|
||||||
naluType := fuHeader & 0x1f
|
|
||||||
if isStart {
|
if isStart {
|
||||||
self.fuBuffer = []byte{fuIndicator&0xe0 | fuHeader&0x1f}
|
self.fuBuffer = []byte{fuIndicator&0xe0 | fuHeader&0x1f}
|
||||||
}
|
}
|
||||||
self.fuBuffer = append(self.fuBuffer, packet[2:]...)
|
self.fuBuffer = append(self.fuBuffer, packet[2:]...)
|
||||||
if isEnd {
|
if isEnd {
|
||||||
if err = self.handleH264Payload(naluType, timestamp, self.fuBuffer); err != nil {
|
if err = self.handleH264Payload(timestamp, self.fuBuffer); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -754,9 +733,23 @@ func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
|
|||||||
case naluType == 24:
|
case naluType == 24:
|
||||||
err = fmt.Errorf("rtsp: unsupported H264 STAP-A")
|
err = fmt.Errorf("rtsp: unsupported H264 STAP-A")
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
return
|
||||||
err = fmt.Errorf("rtsp: unsupported H264 naluType=%d", naluType)
|
}
|
||||||
|
|
||||||
|
func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
|
||||||
|
if self.isCodecDataChange() {
|
||||||
|
err = ErrCodecDataChange
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch self.Type() {
|
||||||
|
case av.H264:
|
||||||
|
if self.client != nil && self.client.DebugRtp {
|
||||||
|
fmt.Printf("rtsp: h264 data=%x\n", packet)
|
||||||
|
}
|
||||||
|
if err = self.handleH264Payload(timestamp, packet); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user