Mpeg4Parser.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright (c) Kuba Szczodrzyński 2022-1-10.
  2. #include "BellUtils.h"
  3. #include "Mpeg4Container.h"
  4. #include "Mpeg4Types.h"
  5. using namespace bell;
  6. /** Populate [chunks] using the Sample-to-chunk Table */
  7. void Mpeg4Container::readStsc() {
  8. skipBytes(4); // skip version and flags
  9. chunksLen = readUint32();
  10. chunks = (Mpeg4ChunkRange *)malloc(chunksLen * sizeof(Mpeg4ChunkRange));
  11. for (uint32_t i = 0; i < chunksLen; i++) {
  12. chunks[i].count = readUint32();
  13. chunks[i].samples = readUint32();
  14. chunks[i].sampleDescriptionId = readUint32();
  15. if (i > 0) {
  16. chunks[i - 1].count = chunks[i].count - chunks[i - 1].count;
  17. }
  18. }
  19. if (chunkOffsetsLen) {
  20. chunks[chunksLen - 1].count = chunkOffsetsLen - chunks[chunksLen - 1].count + 1;
  21. }
  22. }
  23. /** Populate [chunkOffsets] using the Chunk Offset Table */
  24. void Mpeg4Container::readStco() {
  25. skipBytes(4); // skip version and flags
  26. chunkOffsetsLen = readUint32();
  27. chunkOffsets = (Mpeg4ChunkOffset *)malloc(chunkOffsetsLen * sizeof(Mpeg4ChunkOffset));
  28. for (uint32_t i = 0; i < chunkOffsetsLen; i++) {
  29. chunkOffsets[i] = readUint32();
  30. }
  31. if (chunksLen) {
  32. chunks[chunksLen - 1].count = chunkOffsetsLen - chunks[chunksLen - 1].count + 1;
  33. }
  34. }
  35. /** Populate [samples] using the Time-to-sample Table */
  36. void Mpeg4Container::readStts() {
  37. skipBytes(4); // skip version and flags
  38. samplesLen = readUint32();
  39. samples = (Mpeg4SampleRange *)malloc(samplesLen * sizeof(Mpeg4SampleRange));
  40. for (uint32_t i = 0; i < samplesLen; i++) {
  41. samples[i].count = readUint32();
  42. samples[i].duration = readUint32();
  43. }
  44. }
  45. /** Populate [sampleSizes] using the Sample Size Table */
  46. void Mpeg4Container::readStsz() {
  47. skipBytes(4); // skip version and flags
  48. uint32_t sampleSize = readUint32();
  49. sampleSizesLen = readUint32();
  50. if (sampleSize) {
  51. sampleSizesLen = 1;
  52. }
  53. sampleSizes = (Mpeg4SampleSize *)malloc(sampleSizesLen * sizeof(Mpeg4SampleSize));
  54. if (sampleSize) {
  55. sampleSizes[0] = sampleSize;
  56. if (sampleSize > sampleSizeMax)
  57. sampleSizeMax = sampleSize;
  58. return;
  59. }
  60. for (uint32_t i = 0; i < sampleSizesLen; i++) {
  61. sampleSize = readUint32();
  62. if (sampleSize > sampleSizeMax)
  63. sampleSizeMax = sampleSize;
  64. sampleSizes[i] = sampleSize;
  65. }
  66. // reallocate sampleData if the max size changes
  67. allocSampleData();
  68. }
  69. /** Populate [sampleDesc] using the Sample Description Table */
  70. void Mpeg4Container::readStsd() {
  71. // Helpful resources:
  72. // - STSD atom structure - ISO/IEC 14496-1 (page 277) - seems to cover QT desc ver.0
  73. // - ESDS atom structure - ISO/IEC 14496-1 (page 28)
  74. freeAndNull((void *&)sampleDesc);
  75. skipBytes(4); // skip version and flags
  76. sampleDescLen = readUint32();
  77. sampleDesc = (SampleDescription *)malloc(sampleDescLen * sizeof(SampleDescription));
  78. for (SampleDescription *desc = sampleDesc; desc < sampleDesc + sampleDescLen; desc++) {
  79. uint32_t entryEnd = readUint32() - 4 + pos;
  80. uint32_t esdsEnd = entryEnd;
  81. // https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-BBCHHGBH
  82. // General Structure of a Sample Description
  83. desc->format = (AudioSampleFormat)readUint32();
  84. desc->mp4aObjectType = MP4AObjectType::UNDEFINED;
  85. desc->mp4aProfile = MP4AProfile::UNDEFINED;
  86. skipBytes(6); // reserved
  87. desc->dataReferenceIndex = readUint16();
  88. // https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-75770
  89. // Sound Sample Description (Version 0)
  90. uint16_t version = readUint16();
  91. skipBytes(6); // skip Revision level(2), Vendor(4)
  92. channelCount = readUint16();
  93. bitDepth = readUint16();
  94. skipBytes(4); // skip Compression ID(2), Packet size(2)
  95. sampleRate = readUint16();
  96. skipBytes(2); // decimal part of sample rate
  97. if (version >= 1) {
  98. // Sound Sample Description (Version 1)
  99. skipBytes(16); // skip Samples per packet(4), Bytes per packet(4), Bytes per frame(4), Bytes per sample(4)
  100. }
  101. // read the child atom
  102. uint32_t atomSize;
  103. AtomType atomType;
  104. readAtomHeader(atomSize, (uint32_t &)atomType);
  105. if (atomType == AtomType::ATOM_WAVE) {
  106. do {
  107. readAtomHeader(atomSize, (uint32_t &)atomType);
  108. if (atomType == AtomType::ATOM_ESDS) {
  109. esdsEnd = pos + atomSize;
  110. break;
  111. }
  112. skipBytes(atomSize);
  113. } while (pos < entryEnd);
  114. if (pos >= entryEnd) // something went wrong
  115. continue;
  116. }
  117. if (atomType != AtomType::ATOM_ESDS) {
  118. desc->dataType = (uint32_t)atomType;
  119. desc->dataLength = atomSize;
  120. desc->data = (uint8_t *)malloc(desc->dataLength);
  121. readBytes(desc->data, desc->dataLength);
  122. continue;
  123. }
  124. // read ESDS
  125. skipBytes(4); // skip esds flags
  126. while (pos < esdsEnd) {
  127. uint8_t tag = readUint8();
  128. uint32_t size = readVarint32();
  129. uint8_t flags;
  130. switch (tag) {
  131. case 0x03: // ES_Descriptor
  132. skipBytes(2);
  133. flags = readUint8();
  134. if (flags & 0b10000000)
  135. skipBytes(2);
  136. if (flags & 0b01000000)
  137. skipBytes(readUint8());
  138. if (flags & 0b00100000)
  139. skipBytes(2);
  140. break;
  141. case 0x04: // DecoderConfigDescriptor
  142. desc->mp4aObjectType = (MP4AObjectType)readUint8();
  143. skipBytes(12);
  144. break;
  145. case 0x05: // DecoderSpecificInfo
  146. if (desc->mp4aObjectType == MP4AObjectType::MP4A) {
  147. desc->mp4aProfile = (MP4AProfile)(readUint8() >> 3);
  148. skipBytes(size - 1);
  149. } else {
  150. desc->dataType = 0;
  151. desc->dataLength = size;
  152. desc->data = (uint8_t *)malloc(desc->dataLength);
  153. readBytes(desc->data, desc->dataLength);
  154. }
  155. break;
  156. default:
  157. skipBytes(size);
  158. break;
  159. }
  160. }
  161. // skip leftover atoms for version 1 QuickTime descriptors
  162. skipTo(entryEnd);
  163. }
  164. }