rewrite handleH264Payload, support BuggyCameraHasAnnexbH264Packet

This commit is contained in:
nareix 2016-06-15 10:28:34 +08:00
parent e6b1c2561e
commit b0ccdad10b

173
client.go
View File

@ -531,16 +531,7 @@ func (self *Stream) makeCodecData() (err error) {
case av.H264:
for _, nalu := range media.SpropParameterSets {
if len(nalu) > 0 {
switch nalu[0] & 0x1f {
case 7:
if len(self.sps) == 0 {
self.sps = nalu
}
case 8:
if len(self.pps) == 0 {
self.pps = nalu
}
}
self.handleH264Payload(0, nalu)
}
}
@ -548,16 +539,7 @@ func (self *Stream) makeCodecData() (err error) {
if nalus, ok := h264parser.SplitNALUs(media.Config); ok {
for _, nalu := range nalus {
if len(nalu) > 0 {
switch nalu[0] & 0x1f {
case 7:
if len(self.sps) == 0 {
self.sps = nalu
}
case 8:
if len(self.pps) == 0 {
self.pps = nalu
}
}
self.handleH264Payload(0, nalu)
}
}
}
@ -600,7 +582,30 @@ func (self *Stream) makeCodecData() (err error) {
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
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)
7 Sequence 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
24 STAP-A 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 {
case naluType >= 1 && naluType <= 23:
if err = self.handleH264Payload(naluType, timestamp, packet); err != nil {
default:
if naluType >= 1 && naluType <= 23 {
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
}
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
/*
0 1 2 3
@ -740,13 +720,12 @@ func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
fuHeader := packet[1]
isStart := fuHeader&0x80 != 0
isEnd := fuHeader&0x40 != 0
naluType := fuHeader & 0x1f
if isStart {
self.fuBuffer = []byte{fuIndicator&0xe0 | fuHeader&0x1f}
}
self.fuBuffer = append(self.fuBuffer, packet[2:]...)
if isEnd {
if err = self.handleH264Payload(naluType, timestamp, self.fuBuffer); err != nil {
if err = self.handleH264Payload(timestamp, self.fuBuffer); err != nil {
return
}
}
@ -754,9 +733,23 @@ func (self *Stream) handlePacket(timestamp uint32, packet []byte) (err error) {
case naluType == 24:
err = fmt.Errorf("rtsp: unsupported H264 STAP-A")
return
}
default:
err = fmt.Errorf("rtsp: unsupported H264 naluType=%d", naluType)
return
}
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
}