h264reader.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. // Package h264reader implements a H264 Annex-B Reader
  4. package h264reader
  5. import (
  6. "bytes"
  7. "errors"
  8. "io"
  9. )
  10. // H264Reader reads data from stream and constructs h264 nal units
  11. type H264Reader struct {
  12. stream io.Reader
  13. nalBuffer []byte
  14. countOfConsecutiveZeroBytes int
  15. nalPrefixParsed bool
  16. readBuffer []byte
  17. tmpReadBuf []byte
  18. }
  19. var (
  20. errNilReader = errors.New("stream is nil")
  21. errDataIsNotH264Stream = errors.New("data is not a H264 bitstream")
  22. )
  23. // NewReader creates new H264Reader
  24. func NewReader(in io.Reader) (*H264Reader, error) {
  25. if in == nil {
  26. return nil, errNilReader
  27. }
  28. reader := &H264Reader{
  29. stream: in,
  30. nalBuffer: make([]byte, 0),
  31. nalPrefixParsed: false,
  32. readBuffer: make([]byte, 0),
  33. tmpReadBuf: make([]byte, 4096),
  34. }
  35. return reader, nil
  36. }
  37. // NAL H.264 Network Abstraction Layer
  38. type NAL struct {
  39. PictureOrderCount uint32
  40. // NAL header
  41. ForbiddenZeroBit bool
  42. RefIdc uint8
  43. UnitType NalUnitType
  44. Data []byte // header byte + rbsp
  45. }
  46. func (reader *H264Reader) read(numToRead int) (data []byte, e error) {
  47. for len(reader.readBuffer) < numToRead {
  48. n, err := reader.stream.Read(reader.tmpReadBuf)
  49. if err != nil {
  50. return nil, err
  51. }
  52. if n == 0 {
  53. break
  54. }
  55. reader.readBuffer = append(reader.readBuffer, reader.tmpReadBuf[0:n]...)
  56. }
  57. var numShouldRead int
  58. if numToRead <= len(reader.readBuffer) {
  59. numShouldRead = numToRead
  60. } else {
  61. numShouldRead = len(reader.readBuffer)
  62. }
  63. data = reader.readBuffer[0:numShouldRead]
  64. reader.readBuffer = reader.readBuffer[numShouldRead:]
  65. return data, nil
  66. }
  67. func (reader *H264Reader) bitStreamStartsWithH264Prefix() (prefixLength int, e error) {
  68. nalPrefix3Bytes := []byte{0, 0, 1}
  69. nalPrefix4Bytes := []byte{0, 0, 0, 1}
  70. prefixBuffer, e := reader.read(4)
  71. if e != nil {
  72. return
  73. }
  74. n := len(prefixBuffer)
  75. if n == 0 {
  76. return 0, io.EOF
  77. }
  78. if n < 3 {
  79. return 0, errDataIsNotH264Stream
  80. }
  81. nalPrefix3BytesFound := bytes.Equal(nalPrefix3Bytes, prefixBuffer[:3])
  82. if n == 3 {
  83. if nalPrefix3BytesFound {
  84. return 0, io.EOF
  85. }
  86. return 0, errDataIsNotH264Stream
  87. }
  88. // n == 4
  89. if nalPrefix3BytesFound {
  90. reader.nalBuffer = append(reader.nalBuffer, prefixBuffer[3])
  91. return 3, nil
  92. }
  93. nalPrefix4BytesFound := bytes.Equal(nalPrefix4Bytes, prefixBuffer)
  94. if nalPrefix4BytesFound {
  95. return 4, nil
  96. }
  97. return 0, errDataIsNotH264Stream
  98. }
  99. // NextNAL reads from stream and returns then next NAL,
  100. // and an error if there is incomplete frame data.
  101. // Returns all nil values when no more NALs are available.
  102. func (reader *H264Reader) NextNAL() (*NAL, error) {
  103. if !reader.nalPrefixParsed {
  104. _, err := reader.bitStreamStartsWithH264Prefix()
  105. if err != nil {
  106. return nil, err
  107. }
  108. reader.nalPrefixParsed = true
  109. }
  110. for {
  111. buffer, err := reader.read(1)
  112. if err != nil {
  113. break
  114. }
  115. n := len(buffer)
  116. if n != 1 {
  117. break
  118. }
  119. readByte := buffer[0]
  120. nalFound := reader.processByte(readByte)
  121. if nalFound {
  122. nal := newNal(reader.nalBuffer)
  123. nal.parseHeader()
  124. if nal.UnitType == NalUnitTypeSEI {
  125. reader.nalBuffer = nil
  126. continue
  127. }
  128. break
  129. }
  130. reader.nalBuffer = append(reader.nalBuffer, readByte)
  131. }
  132. if len(reader.nalBuffer) == 0 {
  133. return nil, io.EOF
  134. }
  135. nal := newNal(reader.nalBuffer)
  136. reader.nalBuffer = nil
  137. nal.parseHeader()
  138. return nal, nil
  139. }
  140. func (reader *H264Reader) processByte(readByte byte) (nalFound bool) {
  141. nalFound = false
  142. switch readByte {
  143. case 0:
  144. reader.countOfConsecutiveZeroBytes++
  145. case 1:
  146. if reader.countOfConsecutiveZeroBytes >= 2 {
  147. countOfConsecutiveZeroBytesInPrefix := 2
  148. if reader.countOfConsecutiveZeroBytes > 2 {
  149. countOfConsecutiveZeroBytesInPrefix = 3
  150. }
  151. if nalUnitLength := len(reader.nalBuffer) - countOfConsecutiveZeroBytesInPrefix; nalUnitLength > 0 {
  152. reader.nalBuffer = reader.nalBuffer[0:nalUnitLength]
  153. nalFound = true
  154. }
  155. }
  156. reader.countOfConsecutiveZeroBytes = 0
  157. default:
  158. reader.countOfConsecutiveZeroBytes = 0
  159. }
  160. return nalFound
  161. }
  162. func newNal(data []byte) *NAL {
  163. return &NAL{PictureOrderCount: 0, ForbiddenZeroBit: false, RefIdc: 0, UnitType: NalUnitTypeUnspecified, Data: data}
  164. }
  165. func (h *NAL) parseHeader() {
  166. firstByte := h.Data[0]
  167. h.ForbiddenZeroBit = (((firstByte & 0x80) >> 7) == 1) // 0x80 = 0b10000000
  168. h.RefIdc = (firstByte & 0x60) >> 5 // 0x60 = 0b01100000
  169. h.UnitType = NalUnitType((firstByte & 0x1F) >> 0) // 0x1F = 0b00011111
  170. }