WebmContainer.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (c) Kuba Szczodrzyński 2022-1-16.
  2. #pragma once
  3. #include "BaseContainer.h"
  4. enum class ElementId;
  5. class WebmContainer : public BaseContainer {
  6. public:
  7. ~WebmContainer();
  8. bool parse() override;
  9. int32_t getLoadingOffset(uint32_t timeMs) override;
  10. bool seekTo(uint32_t timeMs) override;
  11. int32_t getCurrentTimeMs() override;
  12. uint8_t *readSample(uint32_t &len) override;
  13. uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) override;
  14. void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position) override;
  15. private:
  16. typedef struct {
  17. uint32_t time;
  18. uint32_t offset;
  19. } CuePoint;
  20. private:
  21. // used while parsing
  22. uint32_t esize;
  23. ElementId eid;
  24. // container parameters
  25. char *docType = nullptr;
  26. uint8_t audioTrackId = 255;
  27. float timescale = 0.0f;
  28. char *codecId = nullptr;
  29. uint8_t *codecPrivate = nullptr;
  30. uint32_t codecPrivateLen = 0;
  31. // container state
  32. CuePoint *cues = nullptr;
  33. uint16_t cuesLen = 0;
  34. uint32_t clusterEnd = 0;
  35. uint32_t clusterTime = 0;
  36. uint32_t currentTime = 0;
  37. bool isParsed = false;
  38. // buffer
  39. uint8_t *sampleData = nullptr;
  40. uint32_t sampleLen = 0;
  41. // lacing parameters
  42. uint32_t *laceSizes = nullptr;
  43. uint32_t *laceCurrent = nullptr;
  44. uint8_t laceLeft = 0;
  45. // set to read the current buffer instead of loading new frames
  46. uint16_t readOutFrameSize = 0;
  47. private:
  48. uint32_t readVarNum32(bool raw = false);
  49. uint64_t readVarNum64();
  50. uint32_t readUint(uint8_t len);
  51. uint64_t readUlong(uint8_t len);
  52. float readFloat(uint8_t len);
  53. void readElem();
  54. void parseSegment(uint32_t start);
  55. void parseTrack(uint32_t end);
  56. void parseCuePoint(uint16_t idx, uint32_t end, uint32_t segmentStart);
  57. /**
  58. * Continue reading elements until a block is encountered.
  59. *
  60. * If [untilTime] is set, the method will keep reading until [currentTime]
  61. * is less than [untilTime]. Because of how WebM works, [pos] will be one frame later
  62. * than the requested time, although the container will report the correct position.
  63. *
  64. * @return size of the frame pointed by [pos]
  65. */
  66. uint32_t readCluster(uint32_t untilTime = 0);
  67. /**
  68. * Parse a single block within a cluster. This method will populate lacing parameters if needed.
  69. * @param end offset of the next byte after this block
  70. * @return size of the frame pointed by [pos]
  71. */
  72. uint32_t readBlock(uint32_t end);
  73. uint8_t *readFrame(uint32_t size, uint32_t &outLen);
  74. };