BaseContainer.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (c) Kuba Szczodrzyński 2022-1-7.
  2. #pragma once
  3. #include "BinaryReader.h"
  4. #include "ByteStream.h"
  5. #include <cstdint>
  6. #include <memory>
  7. /**
  8. * Either the media file or the requested position/offset is not loaded yet.
  9. */
  10. #define SAMPLE_NOT_LOADED -1
  11. /**
  12. * The media file does not contain the requested position/offset.
  13. */
  14. #define SAMPLE_NOT_FOUND -2
  15. /**
  16. * The file is not seekable (i.e. doesn't contain an index table).
  17. */
  18. #define SAMPLE_NOT_SEEKABLE -3
  19. enum class AudioCodec;
  20. class BaseContainer {
  21. public:
  22. BaseContainer() = default;
  23. /**
  24. * Feed a new data source to the container.
  25. * @param stream ByteStream reading source data
  26. * @param position absolute position of the current ByteStream within the source media
  27. */
  28. virtual void feed(const std::shared_ptr<bell::ByteStream> &stream, uint32_t position);
  29. /**
  30. * Try to parse the media provided by the source stream.
  31. * @return whether parsing was successful
  32. */
  33. virtual bool parse() = 0;
  34. /**
  35. * Get absolute offset within the source media for the given timestamp.
  36. * When seeking to a specified time, the caller should run feed() with a stream
  37. * reader starting at the returned offset. Depending on the container type,
  38. * the returned offset may not point to the exact time position (i.e. chunks with
  39. * headers), so seekTo() should be used afterwards.
  40. *
  41. * @param timeMs requested timestamp, in milliseconds
  42. * @return byte offset within the source media that should be loaded
  43. * in order to seek to the requested position; negative value on error
  44. */
  45. virtual int32_t getLoadingOffset(uint32_t timeMs) = 0;
  46. /**
  47. * Try to seek to the specified position (in milliseconds), using the currently
  48. * loaded source stream. This method will fail if the source stream does not yield
  49. * data for the requested position, or block until the stream loads data for this position.
  50. *
  51. * @param timeMs requested timestamp, in milliseconds
  52. */
  53. virtual bool seekTo(uint32_t timeMs) = 0;
  54. /**
  55. * Get the current playback position, in milliseconds. May return -1 if the track
  56. * is not playing (has ended or not started yet).
  57. */
  58. virtual int32_t getCurrentTimeMs() = 0;
  59. /**
  60. * Read an encoded audio sample from the container, starting at the current position.
  61. *
  62. * @param [out] len length of the data stored in the returned pointer, in bytes
  63. * @return pointer to data allocated inside the container object; should not be freed or changed.
  64. * On failure, nullptr is returned, and len is left unchanged.
  65. */
  66. virtual uint8_t *readSample(uint32_t &len) = 0;
  67. /**
  68. * Get optional initialization data for the specified codec. This may be used by a codec,
  69. * for containers that contain the setup data.
  70. *
  71. * @param [out] len length of the setup data
  72. * @return ptr to [len] setup data bytes, or nullptr if not available/not supported
  73. */
  74. virtual uint8_t *getSetupData(uint32_t &len, AudioCodec matchCodec) = 0;
  75. public:
  76. bool closed = false;
  77. bool isSeekable = false;
  78. // audio parameters
  79. AudioCodec codec = (AudioCodec)0;
  80. uint32_t sampleRate = 0;
  81. uint8_t channelCount = 0;
  82. uint8_t bitDepth = 0;
  83. uint32_t durationMs = 0;
  84. protected:
  85. std::unique_ptr<bell::BinaryReader> reader;
  86. std::shared_ptr<bell::ByteStream> source;
  87. uint32_t pos = 0;
  88. uint8_t readUint8();
  89. uint16_t readUint16();
  90. uint32_t readUint24();
  91. uint32_t readUint32();
  92. uint64_t readUint64();
  93. uint32_t readVarint32();
  94. uint32_t readBytes(uint8_t *dst, uint32_t num);
  95. uint32_t skipBytes(uint32_t num);
  96. uint32_t skipTo(uint32_t offset);
  97. };