aac.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package aac
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "github.com/AlexxIT/go2rtc/pkg/bits"
  6. "github.com/AlexxIT/go2rtc/pkg/core"
  7. )
  8. const (
  9. TypeAACMain = 1
  10. TypeAACLC = 2 // Low Complexity
  11. TypeAACLD = 23 // Low Delay (48000, 44100, 32000, 24000, 22050)
  12. TypeESCAPE = 31
  13. TypeAACELD = 39 // Enhanced Low Delay
  14. AUTime = 1024
  15. // FMTP streamtype=5 - audio stream
  16. FMTP = "streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config="
  17. )
  18. var sampleRates = [16]uint32{
  19. 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350,
  20. 0, 0, 0, // protection from request sampleRates[15]
  21. }
  22. func ConfigToCodec(conf []byte) *core.Codec {
  23. // https://en.wikipedia.org/wiki/MPEG-4_Part_3#MPEG-4_Audio_Object_Types
  24. rd := bits.NewReader(conf)
  25. codec := &core.Codec{
  26. FmtpLine: FMTP + hex.EncodeToString(conf),
  27. PayloadType: core.PayloadTypeRAW,
  28. }
  29. objType := rd.ReadBits(5)
  30. if objType == TypeESCAPE {
  31. objType = 32 + rd.ReadBits(6)
  32. }
  33. switch objType {
  34. case TypeAACLC, TypeAACLD, TypeAACELD:
  35. codec.Name = core.CodecAAC
  36. default:
  37. codec.Name = fmt.Sprintf("AAC-%X", objType)
  38. }
  39. if sampleRateIdx := rd.ReadBits8(4); sampleRateIdx < 0x0F {
  40. codec.ClockRate = sampleRates[sampleRateIdx]
  41. } else {
  42. codec.ClockRate = rd.ReadBits(24)
  43. }
  44. codec.Channels = rd.ReadBits16(4)
  45. return codec
  46. }
  47. func DecodeConfig(b []byte) (objType, sampleFreqIdx, channels byte, sampleRate uint32) {
  48. rd := bits.NewReader(b)
  49. objType = rd.ReadBits8(5)
  50. if objType == 0b11111 {
  51. objType = 32 + rd.ReadBits8(6)
  52. }
  53. sampleFreqIdx = rd.ReadBits8(4)
  54. if sampleFreqIdx == 0b1111 {
  55. sampleRate = rd.ReadBits(24)
  56. } else {
  57. sampleRate = sampleRates[sampleFreqIdx]
  58. }
  59. channels = rd.ReadBits8(4)
  60. return
  61. }
  62. func EncodeConfig(objType byte, sampleRate uint32, channels byte, shortFrame bool) []byte {
  63. wr := bits.NewWriter(nil)
  64. if objType < TypeESCAPE {
  65. wr.WriteBits8(objType, 5)
  66. } else {
  67. wr.WriteBits8(TypeESCAPE, 5)
  68. wr.WriteBits8(objType-32, 6)
  69. }
  70. i := indexUint32(sampleRates[:], sampleRate)
  71. if i >= 0 {
  72. wr.WriteBits8(byte(i), 4)
  73. } else {
  74. wr.WriteBits8(0xF, 4)
  75. wr.WriteBits(sampleRate, 24)
  76. }
  77. wr.WriteBits8(channels, 4)
  78. switch objType {
  79. case TypeAACLD:
  80. // https://github.com/FFmpeg/FFmpeg/blob/67d392b97941bb51fb7af3a3c9387f5ab895fa46/libavcodec/aacdec_template.c#L841
  81. wr.WriteBool(shortFrame)
  82. wr.WriteBit(0) // dependsOnCoreCoder
  83. wr.WriteBit(0) // extension_flag
  84. wr.WriteBits8(0, 2) // ep_config
  85. case TypeAACELD:
  86. // https://github.com/FFmpeg/FFmpeg/blob/67d392b97941bb51fb7af3a3c9387f5ab895fa46/libavcodec/aacdec_template.c#L922
  87. wr.WriteBool(shortFrame)
  88. wr.WriteBits8(0, 3) // res_flags
  89. wr.WriteBit(0) // ldSbrPresentFlag
  90. wr.WriteBits8(0, 4) // ELDEXT_TERM
  91. wr.WriteBits8(0, 2) // ep_config
  92. }
  93. return wr.Bytes()
  94. }
  95. func indexUint32(s []uint32, v uint32) int {
  96. for i := range s {
  97. if v == s[i] {
  98. return i
  99. }
  100. }
  101. return -1
  102. }