adts.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package aac
  2. import (
  3. "encoding/hex"
  4. "github.com/AlexxIT/go2rtc/pkg/bits"
  5. "github.com/AlexxIT/go2rtc/pkg/core"
  6. "github.com/pion/rtp"
  7. )
  8. func IsADTS(b []byte) bool {
  9. return len(b) > 7 && b[0] == 0xFF && b[1]&0xF6 == 0xF0
  10. }
  11. func ADTSToCodec(b []byte) *core.Codec {
  12. // 1. Check ADTS header
  13. if !IsADTS(b) {
  14. return nil
  15. }
  16. // 2. Decode ADTS params
  17. // https://wiki.multimedia.cx/index.php/ADTS
  18. rd := bits.NewReader(b)
  19. _ = rd.ReadBits(12) // Syncword, all bits must be set to 1
  20. _ = rd.ReadBit() // MPEG Version, set to 0 for MPEG-4 and 1 for MPEG-2
  21. _ = rd.ReadBits(2) // Layer, always set to 0
  22. _ = rd.ReadBit() // Protection absence, set to 1 if there is no CRC and 0 if there is CRC
  23. objType := rd.ReadBits8(2) + 1 // Profile, the MPEG-4 Audio Object Type minus 1
  24. sampleRateIdx := rd.ReadBits8(4) // MPEG-4 Sampling Frequency Index
  25. _ = rd.ReadBit() // Private bit, guaranteed never to be used by MPEG, set to 0 when encoding, ignore when decoding
  26. channels := rd.ReadBits16(3) // MPEG-4 Channel Configuration
  27. //_ = rd.ReadBit() // Originality, set to 1 to signal originality of the audio and 0 otherwise
  28. //_ = rd.ReadBit() // Home, set to 1 to signal home usage of the audio and 0 otherwise
  29. //_ = rd.ReadBit() // Copyright ID bit
  30. //_ = rd.ReadBit() // Copyright ID start
  31. //_ = rd.ReadBits(13) // Frame length
  32. //_ = rd.ReadBits(11) // Buffer fullness
  33. //_ = rd.ReadBits(2) // Number of AAC frames (Raw Data Blocks) in ADTS frame minus 1
  34. //_ = rd.ReadBits(16) // CRC check
  35. // 3. Encode RTP config
  36. wr := bits.NewWriter(nil)
  37. wr.WriteBits8(objType, 5)
  38. wr.WriteBits8(sampleRateIdx, 4)
  39. wr.WriteBits16(channels, 4)
  40. conf := wr.Bytes()
  41. codec := &core.Codec{
  42. Name: core.CodecAAC,
  43. ClockRate: sampleRates[sampleRateIdx],
  44. Channels: channels,
  45. FmtpLine: FMTP + hex.EncodeToString(conf),
  46. }
  47. return codec
  48. }
  49. func ReadADTSSize(b []byte) uint16 {
  50. // AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)
  51. _ = b[5] // bounds
  52. return uint16(b[3]&0x03)<<(8+3) | uint16(b[4])<<3 | uint16(b[5]>>5)
  53. }
  54. func WriteADTSSize(b []byte, size uint16) {
  55. // AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)
  56. _ = b[5] // bounds
  57. b[3] |= byte(size >> (8 + 3))
  58. b[4] = byte(size >> 3)
  59. b[5] |= byte(size << 5)
  60. return
  61. }
  62. func ADTSTimeSize(b []byte) uint32 {
  63. var units uint32
  64. for len(b) > ADTSHeaderSize {
  65. auSize := ReadADTSSize(b)
  66. b = b[auSize:]
  67. units++
  68. }
  69. return units * AUTime
  70. }
  71. func CodecToADTS(codec *core.Codec) []byte {
  72. s := core.Between(codec.FmtpLine, "config=", ";")
  73. conf, err := hex.DecodeString(s)
  74. if err != nil {
  75. return nil
  76. }
  77. objType, sampleFreqIdx, channels, _ := DecodeConfig(conf)
  78. profile := objType - 1
  79. wr := bits.NewWriter(nil)
  80. wr.WriteAllBits(1, 12) // Syncword, all bits must be set to 1
  81. wr.WriteBit(0) // MPEG Version, set to 0 for MPEG-4 and 1 for MPEG-2
  82. wr.WriteBits8(0, 2) // Layer, always set to 0
  83. wr.WriteBit(1) // Protection absence, set to 1 if there is no CRC and 0 if there is CRC
  84. wr.WriteBits8(profile, 2) // Profile, the MPEG-4 Audio Object Type minus 1
  85. wr.WriteBits8(sampleFreqIdx, 4) // MPEG-4 Sampling Frequency Index
  86. wr.WriteBit(0) // Private bit, guaranteed never to be used by MPEG, set to 0 when encoding, ignore when decoding
  87. wr.WriteBits8(channels, 3) // MPEG-4 Channel Configuration
  88. wr.WriteBit(0) // Originality, set to 1 to signal originality of the audio and 0 otherwise
  89. wr.WriteBit(0) // Home, set to 1 to signal home usage of the audio and 0 otherwise
  90. wr.WriteBit(0) // Copyright ID bit
  91. wr.WriteBit(0) // Copyright ID start
  92. wr.WriteBits16(0, 13) // Frame length
  93. wr.WriteAllBits(1, 11) // Buffer fullness (variable bitrate)
  94. wr.WriteBits8(0, 2) // Number of AAC frames (Raw Data Blocks) in ADTS frame minus 1
  95. return wr.Bytes()
  96. }
  97. func EncodeToADTS(codec *core.Codec, handler core.HandlerFunc) core.HandlerFunc {
  98. adts := CodecToADTS(codec)
  99. return func(packet *rtp.Packet) {
  100. if !IsADTS(packet.Payload) {
  101. b := make([]byte, ADTSHeaderSize+len(packet.Payload))
  102. copy(b, adts)
  103. copy(b[ADTSHeaderSize:], packet.Payload)
  104. WriteADTSSize(b, uint16(len(b)))
  105. clone := *packet
  106. clone.Payload = b
  107. handler(&clone)
  108. } else {
  109. handler(packet)
  110. }
  111. }
  112. }