Mpeg4Container.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) Kuba Szczodrzyński 2022-1-8.
  2. #pragma once
  3. #include "BaseContainer.h"
  4. #include "Mpeg4Atoms.h"
  5. #include <memory>
  6. class Mpeg4Container : public BaseContainer {
  7. public:
  8. ~Mpeg4Container();
  9. /**
  10. * Start parsing the MP4 file. This method expects the source to read from 0th byte.
  11. * This method leaves pos at first mdat data byte, or mdat header for fMP4 files.
  12. */
  13. bool parse() override;
  14. int32_t getLoadingOffset(uint32_t timeMs) override;
  15. bool seekTo(uint32_t timeMs) override;
  16. int32_t getCurrentTimeMs() override;
  17. uint8_t *readSample(uint32_t &len) override;
  18. uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) override;
  19. void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position) override;
  20. private:
  21. /**
  22. * Parse a single movie fragment. This method expects the source to read moof data, without the header.
  23. * After running, [pos] is left at next mdat header. A new fragment will be created if [pos] does not exist
  24. * in [fragments] table.
  25. */
  26. bool parseMoof(uint32_t moofSize);
  27. bool goToData();
  28. // char mediaBrand[5];
  29. uint32_t totalDuration;
  30. bool totalDurationPresent = false;
  31. int8_t audioTrackId = -1;
  32. uint32_t timescale = 0;
  33. uint32_t sampleSizeMax = 0;
  34. uint8_t *sampleData = nullptr;
  35. uint32_t sampleDataLen = 0;
  36. bool isParsed = false;
  37. bool isFragmented = false;
  38. /** True if source reads **audio** mdat data bytes, false if source reads atom headers */
  39. bool isInData = false;
  40. private: // data for the entire movie:
  41. /** All fragments in the MPEG file */
  42. Mpeg4Fragment *fragments;
  43. uint16_t fragmentsLen;
  44. /** Default sample descriptions for each track */
  45. SampleDefaults *sampleDefs;
  46. uint32_t sampleDefsLen;
  47. /** Track IDs of [sampleDef] items */
  48. uint32_t *sampleDefTracks;
  49. /** Sample Description Table */
  50. SampleDescription *sampleDesc;
  51. uint32_t sampleDescLen;
  52. private: // data changing every fragment:
  53. /** Chunks in the current fragment */
  54. Mpeg4ChunkRange *chunks;
  55. uint32_t chunksLen;
  56. /** Absolute chunk offsets in the current fragment */
  57. Mpeg4ChunkOffset *chunkOffsets;
  58. uint32_t chunkOffsetsLen;
  59. /** All sample descriptors in the current fragment */
  60. Mpeg4SampleRange *samples;
  61. uint32_t samplesLen;
  62. /** All sample sizes in the current fragment */
  63. Mpeg4SampleSize *sampleSizes;
  64. uint32_t sampleSizesLen;
  65. private: // current status and position within the file
  66. /** Currently loaded fragment (ptr) */
  67. Mpeg4Fragment *curFragment;
  68. /** The chunk currently being processed */
  69. Mpeg4Chunk curChunk;
  70. /** Size of the current sample (ptr) */
  71. Mpeg4SampleSize *curSampleSize;
  72. private: // Mpeg4Utils.cpp
  73. void readAtomHeader(uint32_t &size, uint32_t &type);
  74. void freeAll();
  75. void freeFragment();
  76. SampleDefaults *getSampleDef(uint32_t trackId);
  77. void setCurrentFragment();
  78. void setCurrentSample();
  79. static bool isInFragment(Mpeg4Fragment *f, uint32_t offset);
  80. static AudioCodec getCodec(SampleDescription *desc);
  81. Mpeg4Fragment *createFragment();
  82. int64_t findSample(int64_t byTime, int32_t byPos, uint64_t startTime);
  83. private: // Mpeg4Parser.cpp
  84. /** Populate [chunks] using the Sample-to-chunk Table */
  85. void readStsc();
  86. /** Populate [chunkOffsets] using the Chunk Offset Table */
  87. void readStco();
  88. /** Populate [samples] using the Time-to-sample Table */
  89. void readStts();
  90. /** Populate [sampleSizes] using the Sample Size Table */
  91. void readStsz();
  92. /** Populate [sampleDesc] using the Sample Description Table */
  93. void readStsd();
  94. private: // Mpeg4ParserFrag.cpp
  95. /** Populate [fragments] using the Segment Index Table */
  96. void readSidx(uint32_t atomSize);
  97. /** Populate [sampleDefs] using Track Extends */
  98. void readTrex();
  99. /** Populate [sampleDefs] using Track Fragment Header */
  100. void readTfhd(uint32_t trafEnd, uint32_t moofOffset);
  101. /** Populate [chunks, chunkOffsets, samples, sampleSizes] using Track Fragment Run Table */
  102. void readTrun(uint32_t atomSize, uint32_t moofOffset);
  103. void allocSampleData();
  104. };