h264.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package track
  2. import (
  3. "bytes"
  4. "time"
  5. //"fmt"
  6. "go.uber.org/zap"
  7. "m7s.live/engine/v4/codec"
  8. . "m7s.live/engine/v4/common"
  9. "m7s.live/engine/v4/log"
  10. "m7s.live/engine/v4/util"
  11. )
  12. var _ SpesificTrack = (*H264)(nil)
  13. type H264 struct {
  14. Video
  15. buf util.Buffer // rtp 包临时缓存,对于不规范的 rtp 包(sps 放到了 fua 中导致)需要缓存
  16. }
  17. func NewH264(stream IStream, stuff ...any) (vt *H264) {
  18. vt = &H264{}
  19. vt.Video.CodecID = codec.CodecID_H264
  20. vt.SetStuff("h264", byte(96), uint32(90000), vt, stuff, stream)
  21. if vt.BytesPool == nil {
  22. vt.BytesPool = make(util.BytesPool, 17)
  23. }
  24. vt.ParamaterSets = make(ParamaterSets, 2)
  25. vt.nalulenSize = 4
  26. vt.dtsEst = NewDTSEstimator()
  27. return
  28. }
  29. func (vt *H264) WriteSliceBytes(slice []byte) {
  30. if len(slice) > 4 && bytes.Equal(slice[:4], codec.NALU_Delimiter2) {
  31. slice = slice[4:] // 有些设备厂商不规范,所以需要移除前导的 00 00 00 01
  32. }
  33. if len(slice) == 0 {
  34. vt.Error("H264 WriteSliceBytes got empty slice")
  35. return
  36. }
  37. naluType := codec.ParseH264NALUType(slice[0])
  38. if log.Trace {
  39. vt.Trace("naluType", zap.Uint8("naluType", naluType.Byte()))
  40. }
  41. switch naluType {
  42. case codec.NALU_SPS:
  43. spsInfo, _ := codec.ParseSPS(slice)
  44. if spsInfo.Width != vt.SPSInfo.Width || spsInfo.Height != vt.SPSInfo.Height {
  45. vt.Debug("SPS", zap.Any("SPSInfo", spsInfo))
  46. }
  47. vt.SPSInfo = spsInfo
  48. vt.Video.SPS = slice
  49. vt.ParamaterSets[0] = slice
  50. case codec.NALU_PPS:
  51. vt.Video.PPS = slice
  52. vt.ParamaterSets[1] = slice
  53. lenSPS := len(vt.Video.SPS)
  54. lenPPS := len(vt.Video.PPS)
  55. var b util.Buffer
  56. if lenSPS > 3 {
  57. b.Write(codec.RTMP_AVC_HEAD[:6])
  58. b.Write(vt.Video.SPS[1:4])
  59. b.Write(codec.RTMP_AVC_HEAD[9:10])
  60. } else {
  61. b.Write(codec.RTMP_AVC_HEAD)
  62. }
  63. b.WriteByte(0xE1)
  64. b.WriteUint16(uint16(lenSPS))
  65. b.Write(vt.Video.SPS)
  66. b.WriteByte(0x01)
  67. b.WriteUint16(uint16(lenPPS))
  68. b.Write(vt.Video.PPS)
  69. vt.WriteSequenceHead(b)
  70. case codec.NALU_IDR_Picture:
  71. vt.Value.IFrame = true
  72. vt.AppendAuBytes(slice)
  73. case codec.NALU_Non_IDR_Picture,
  74. codec.NALU_Data_Partition_A,
  75. codec.NALU_Data_Partition_B,
  76. codec.NALU_Data_Partition_C:
  77. vt.Value.IFrame = false
  78. vt.AppendAuBytes(slice)
  79. case codec.NALU_SEI:
  80. vt.AppendAuBytes(slice)
  81. case codec.NALU_Access_Unit_Delimiter:
  82. case codec.NALU_Filler_Data:
  83. default:
  84. if vt.Value.IFrame {
  85. vt.AppendAuBytes(slice)
  86. return
  87. }
  88. vt.Error("nalu type not support", zap.Int("type", int(naluType)))
  89. }
  90. }
  91. func (vt *H264) WriteSequenceHead(head []byte) (err error) {
  92. var info codec.AVCDecoderConfigurationRecord
  93. if _, err = info.Unmarshal(head[5:]); err == nil {
  94. vt.SPSInfo, _ = codec.ParseSPS(info.SequenceParameterSetNALUnit)
  95. vt.nalulenSize = int(info.LengthSizeMinusOne&3 + 1)
  96. vt.SPS = info.SequenceParameterSetNALUnit
  97. vt.PPS = info.PictureParameterSetNALUnit
  98. vt.ParamaterSets[0] = vt.SPS
  99. vt.ParamaterSets[1] = vt.PPS
  100. vt.Video.WriteSequenceHead(head)
  101. } else {
  102. vt.Stream.Error("H264 ParseSpsPps Error")
  103. vt.Stream.Close()
  104. }
  105. return
  106. }
  107. func (vt *H264) WriteRTPFrame(rtpItem *util.ListItem[RTPFrame]) {
  108. defer func() {
  109. err := recover()
  110. if err != nil {
  111. vt.Error("WriteRTPFrame panic", zap.Any("err", err))
  112. vt.Stream.Close()
  113. }
  114. }()
  115. //.Println("WriteRTPFrame 1111111111111111111111111111111111111111111111111111")
  116. if vt.lastSeq != vt.lastSeq2+1 && vt.lastSeq2 != 0 {
  117. vt.lostFlag = true
  118. vt.Warn("lost rtp packet", zap.Uint16("lastSeq", vt.lastSeq), zap.Uint16("lastSeq2", vt.lastSeq2))
  119. }
  120. frame := &rtpItem.Value
  121. pts := frame.Timestamp
  122. rv := vt.Value
  123. // 有些流的 rtp 包中没有设置 marker 导致无法判断是否是最后一个包,此时通过时间戳变化判断,先 flush 之前的帧
  124. if rv.PTS != time.Duration(pts) {
  125. if rv.AUList.ByteLength > 0 {
  126. if !vt.dcChanged && rv.IFrame {
  127. vt.insertDCRtp()
  128. }
  129. vt.Flush()
  130. //fmt.Println("264 WriteRTPFrame 1``````````````")
  131. rv = vt.Value
  132. }
  133. vt.generateTimestamp(pts)
  134. }
  135. rv.RTP.Push(rtpItem)
  136. if naluType := frame.H264Type(); naluType < 24 {
  137. vt.WriteSliceBytes(frame.Payload)
  138. } else {
  139. offset := naluType.Offset()
  140. switch naluType {
  141. case codec.NALU_STAPA, codec.NALU_STAPB:
  142. if len(frame.Payload) <= offset {
  143. vt.Error("invalid nalu size", zap.Int("naluType", int(naluType)))
  144. return
  145. }
  146. for buffer := util.Buffer(frame.Payload[offset:]); buffer.CanRead(); {
  147. nextSize := int(buffer.ReadUint16())
  148. if buffer.Len() >= nextSize {
  149. vt.WriteSliceBytes(buffer.ReadN(nextSize))
  150. } else {
  151. vt.Error("invalid nalu size", zap.Int("naluType", int(naluType)))
  152. return
  153. }
  154. }
  155. case codec.NALU_FUA, codec.NALU_FUB:
  156. b1 := frame.Payload[1]
  157. if util.Bit1(b1, 0) {
  158. naluType = naluType.Parse(b1)
  159. firstByte := naluType.Or(frame.Payload[0] & 0x60)
  160. switch naluType {
  161. case codec.NALU_SPS, codec.NALU_PPS:
  162. vt.buf.WriteByte(firstByte)
  163. default:
  164. vt.WriteSliceByte(firstByte)
  165. }
  166. }
  167. if vt.buf.Len() > 0 {
  168. vt.buf.Write(frame.Payload[offset:])
  169. } else {
  170. if rv.AUList.Pre != nil && rv.AUList.Pre.Value != nil {
  171. rv.AUList.Pre.Value.Push(vt.BytesPool.GetShell(frame.Payload[offset:]))
  172. } else {
  173. vt.Error("fu have no start")
  174. return
  175. }
  176. }
  177. if !util.Bit1(b1, 1) {
  178. // fua 还没结束
  179. return
  180. } else if vt.buf.Len() > 0 {
  181. vt.WriteAnnexB(uint32(rv.PTS), uint32(rv.DTS), vt.buf)
  182. vt.buf = nil
  183. }
  184. }
  185. }
  186. if rv = vt.Value; frame.Marker && rv.AUList.ByteLength > 0 {
  187. if !vt.dcChanged && rv.IFrame {
  188. vt.insertDCRtp()
  189. }
  190. //fmt.Println("264 WriteRTPFrame 22222222222222222222222``````````````")
  191. vt.Flush()
  192. }
  193. }
  194. // RTP格式补完
  195. func (vt *H264) CompleteRTP(value *AVFrame) {
  196. var out [][][]byte
  197. if value.IFrame {
  198. out = append(out, [][]byte{vt.SPS}, [][]byte{vt.PPS})
  199. }
  200. vt.Value.AUList.Range(func(au *util.BLL) bool {
  201. if au.ByteLength < RTPMTU {
  202. out = append(out, au.ToBuffers())
  203. } else {
  204. startIndex := len(out)
  205. var naluType codec.H264NALUType
  206. r := au.NewReader()
  207. b0, _ := r.ReadByte()
  208. naluType = naluType.Parse(b0)
  209. b0 = codec.NALU_FUA.Or(b0 & 0x60)
  210. for bufs := r.ReadN(RTPMTU); len(bufs) > 0; bufs = r.ReadN(RTPMTU) {
  211. out = append(out, append([][]byte{{b0, naluType.Byte()}}, bufs...))
  212. }
  213. out[startIndex][0][1] |= 1 << 7 // set start bit
  214. out[len(out)-1][0][1] |= 1 << 6 // set end bit
  215. }
  216. return true
  217. })
  218. vt.PacketizeRTP(out...)
  219. }
  220. func (vt *H264) GetNALU_SEI() (item *util.ListItem[util.Buffer]) {
  221. item = vt.BytesPool.Get(1)
  222. item.Value[0] = byte(codec.NALU_SEI)
  223. return
  224. }