Browse Source

1 fix keyframes may be incorrect bug 修改了关键帧判定可能不正确的bug

2 fix H265 keyframe not correct bug 修改了265流关键正不对的bug
pull/132/head
macbookpro 6 years ago
parent
commit
d8eb94f9a0
  1. 80
      rtsp/rtp-parser.go
  2. 2
      rtsp/sdp-parser.go

80
rtsp/rtp-parser.go

@ -19,6 +19,7 @@ type RTPInfo struct {
Timestamp int
SSRC int
Payload []byte
NaluType uint8
}
func ParseRTP(rtpBytes []byte) *RTPInfo {
@ -58,11 +59,39 @@ func ParseRTP(rtpBytes []byte) *RTPInfo {
}
}
info.Payload = rtpBytes[offset:end]
if end-offset < 1 {
return nil
}
payloadHeader := rtpBytes[offset] //https://tools.ietf.org/html/rfc6184#section-5.2
info.NaluType = uint8(payloadHeader & 0x1F)
return info
}
func (rtp *RTPInfo) IsKeyframeStart() bool {
if len(rtp.Payload) >= 2 && rtp.Payload[0] == 0x7c && (rtp.Payload[1] == 0x87 || rtp.Payload[1] == 0x85) {
var realNALU uint8
switch {
case rtp.NaluType <= 23:
realNALU = rtp.Payload[0]
//log.Printf("Single NAL:%d", rtp.NaluType)
case rtp.NaluType == 28 || rtp.NaluType == 29:
realNALU = rtp.Payload[1]
if realNALU&0x80 != 0 {
//log.Printf("FU NAL Begin :%d", rtp.NaluType)
} else {
return false
}
if realNALU&0x40 != 0 {
//log.Printf("FU NAL End :%d", rtp.NaluType)
}
}
if realNALU&0x1F == 0x05 {
return true
}
if realNALU&0x1F == 0x07 { // maybe sps pps header + key frame?
if len(rtp.Payload) < 200 { // consider sps pps header only.
return false
}
return true
}
return false
@ -72,13 +101,50 @@ func (rtp *RTPInfo) IsKeyframeStartH265() bool {
if len(rtp.Payload) >= 3 {
firstByte := rtp.Payload[0]
headerType := (firstByte >> 1) & 0x3f
if headerType == 49 {
frametByte := rtp.Payload[2]
frameType := frametByte & 0x3f
rtpStart := (frametByte & 0x80) >> 7
if rtpStart == 1 && (frameType == 19 || frameType == 20 || frameType == 21 || frameType == 32 || frameType == 33 || frameType == 34) {
return true
var frameType uint8
if headerType == 49 { //Fragmentation Units
FUHeader := rtp.Payload[2]
/*
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E| FuType |
+---------------+
*/
rtpStart := (FUHeader & 0x80) != 0
if !rtpStart {
if (FUHeader & 0x40) != 0 {
//log.Printf("FU frame end")
}
return false
} else {
//log.Printf("FU frame start")
}
frameType = FUHeader & 0x3f
} else if headerType == 48 { //Aggregation Packets
} else if headerType == 50 { //PACI Packets
} else { // Single NALU
/*
+---------------+---------------+
|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F| Type | LayerId | TID |
+-------------+-----------------+
*/
frameType = firstByte & 0x7e
}
if frameType >= 16 && frameType <= 21 {
return true
}
if frameType == 32 {
// vps sps pps...
if len(rtp.Payload) < 200 { // consider sps pps header only.
return false
}
return true
}
}
return false

2
rtsp/sdp-parser.go

@ -64,6 +64,8 @@ func ParseSDP(sdpRaw string) map[string]*SDPInfo {
info.Codec = "aac"
case "H264":
info.Codec = "h264"
case "H265":
info.Codec = "h265"
}
if i, err := strconv.Atoi(keyval[1]); err == nil {
info.TimeScale = i

Loading…
Cancel
Save