2
0

ADTSContainer.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "ADTSContainer.h"
  2. #include <cstring> // for memmove
  3. #include <iostream>
  4. #include "StreamInfo.h" // for BitWidth, BitWidth::BW_16, SampleRate, Sampl...
  5. // #include "aacdec.h" // for AACFindSyncWord
  6. using namespace bell;
  7. #define SYNC_WORLD_LEN 4
  8. #define SYNCWORDH 0xff
  9. #define SYNCWORDL 0xf0
  10. // AAC ADTS frame header len
  11. #define AAC_ADTS_FRAME_HEADER_LEN 9
  12. // AAC ADTS frame sync verify
  13. #define AAC_ADTS_SYNC_VERIFY(buf) \
  14. ((buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0))
  15. // AAC ADTS Frame size value stores in 13 bits started at the 31th bit from header
  16. #define AAC_ADTS_FRAME_GETSIZE(buf) \
  17. ((buf[3] & 0x03) << 11 | buf[4] << 3 | buf[5] >> 5)
  18. ADTSContainer::ADTSContainer(std::istream& istr, const std::byte* headingBytes)
  19. : bell::AudioContainer(istr) {
  20. if (headingBytes != nullptr) {
  21. memcpy(buffer.data(), headingBytes, 7);
  22. bytesInBuffer = 7;
  23. }
  24. }
  25. bool ADTSContainer::fillBuffer() {
  26. if (this->bytesInBuffer < AAC_MAX_FRAME_SIZE * 2) {
  27. this->istr.read((char*)buffer.data() + bytesInBuffer,
  28. buffer.size() - bytesInBuffer);
  29. this->bytesInBuffer += istr.gcount();
  30. }
  31. return this->bytesInBuffer >= AAC_MAX_FRAME_SIZE;
  32. }
  33. bool ADTSContainer::resyncADTS() {
  34. int resyncOffset = 0;
  35. bool resyncValid = false;
  36. size_t validBytes = bytesInBuffer - dataOffset;
  37. while (!resyncValid && resyncOffset < validBytes) {
  38. uint8_t* buf = (uint8_t*)this->buffer.data() + dataOffset + resyncOffset;
  39. if (AAC_ADTS_SYNC_VERIFY(buf)) {
  40. // Read frame size, and check if a consecutive frame is available
  41. uint32_t frameSize = AAC_ADTS_FRAME_GETSIZE(buf);
  42. if (frameSize + resyncOffset > validBytes) {
  43. // Not enough data, discard this frame
  44. resyncOffset++;
  45. continue;
  46. }
  47. buf =
  48. (uint8_t*)this->buffer.data() + dataOffset + resyncOffset + frameSize;
  49. if (AAC_ADTS_SYNC_VERIFY(buf)) {
  50. buf += AAC_ADTS_FRAME_GETSIZE(buf);
  51. if (AAC_ADTS_SYNC_VERIFY(buf)) {
  52. protectionAbsent = (buf[1] & 1);
  53. // Found 3 consecutive frames, resynced
  54. resyncValid = true;
  55. }
  56. }
  57. } else {
  58. resyncOffset++;
  59. }
  60. }
  61. dataOffset += resyncOffset;
  62. return resyncValid;
  63. }
  64. void ADTSContainer::consumeBytes(uint32_t len) {
  65. dataOffset += len;
  66. }
  67. std::byte* ADTSContainer::readSample(uint32_t& len) {
  68. // Align data if previous read was offseted
  69. if (dataOffset > 0 && bytesInBuffer > 0) {
  70. size_t toConsume = std::min(dataOffset, bytesInBuffer);
  71. memmove(buffer.data(), buffer.data() + toConsume,
  72. buffer.size() - toConsume);
  73. dataOffset -= toConsume;
  74. bytesInBuffer -= toConsume;
  75. }
  76. if (!this->fillBuffer()) {
  77. len = 0;
  78. return nullptr;
  79. }
  80. uint8_t* buf = (uint8_t*)buffer.data() + dataOffset;
  81. if (!AAC_ADTS_SYNC_VERIFY(buf)) {
  82. if (!resyncADTS()) {
  83. len = 0;
  84. return nullptr;
  85. }
  86. } else {
  87. protectionAbsent = (buf[1] & 1);
  88. }
  89. len = AAC_ADTS_FRAME_GETSIZE(buf);
  90. if (len > bytesInBuffer - dataOffset) {
  91. if (!resyncADTS()) {
  92. len = 0;
  93. return nullptr;
  94. }
  95. }
  96. return buffer.data() + dataOffset;
  97. }
  98. void ADTSContainer::parseSetupData() {
  99. channels = 2;
  100. sampleRate = bell::SampleRate::SR_44100;
  101. bitWidth = bell::BitWidth::BW_16;
  102. }