MatroskaFile.hh 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**********
  2. This library is free software; you can redistribute it and/or modify it under
  3. the terms of the GNU Lesser General Public License as published by the
  4. Free Software Foundation; either version 3 of the License, or (at your
  5. option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
  6. This library is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  9. more details.
  10. You should have received a copy of the GNU Lesser General Public License
  11. along with this library; if not, write to the Free Software Foundation, Inc.,
  12. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  13. **********/
  14. // "liveMedia"
  15. // Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
  16. // A class that encapsulates a Matroska file.
  17. // C++ header
  18. #ifndef _MATROSKA_FILE_HH
  19. #define _MATROSKA_FILE_HH
  20. #ifndef _RTP_SINK_HH
  21. #include "RTPSink.hh"
  22. #endif
  23. #ifndef _FILE_SINK_HH
  24. #include "FileSink.hh"
  25. #endif
  26. #ifndef _HASH_TABLE_HH
  27. #include "HashTable.hh"
  28. #endif
  29. class MatroskaTrack; // forward
  30. class MatroskaDemux; // forward
  31. class MatroskaFile: public Medium {
  32. public:
  33. typedef void (onCreationFunc)(MatroskaFile* newFile, void* clientData);
  34. static void createNew(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
  35. char const* preferredLanguage = "eng");
  36. // Note: Unlike most "createNew()" functions, this one doesn't return a new object immediately. Instead, because this class
  37. // requires file reading (to parse the Matroska 'Track' headers) before a new object can be initialized, the creation of a new
  38. // object is signalled by calling - from the event loop - an 'onCreationFunc' that is passed as a parameter to "createNew()".
  39. MatroskaTrack* lookup(unsigned trackNumber) const;
  40. // Create a demultiplexor for extracting tracks from this file. (Separate clients will typically have separate demultiplexors.)
  41. MatroskaDemux* newDemux();
  42. // Parameters of the file ('Segment'); set when the file is parsed:
  43. unsigned timecodeScale() { return fTimecodeScale; } // in nanoseconds
  44. float segmentDuration() { return fSegmentDuration; } // in units of "timecodeScale()"
  45. float fileDuration(); // in seconds
  46. char const* fileName() const { return fFileName; }
  47. unsigned chosenVideoTrackNumber() { return fChosenVideoTrackNumber; }
  48. unsigned chosenAudioTrackNumber() { return fChosenAudioTrackNumber; }
  49. unsigned chosenSubtitleTrackNumber() { return fChosenSubtitleTrackNumber; }
  50. FramedSource*
  51. createSourceForStreaming(FramedSource* baseSource, unsigned trackNumber,
  52. unsigned& estBitrate, unsigned& numFiltersInFrontOfTrack);
  53. // Takes a data source (which must be a demultiplexed track from this file) and returns
  54. // a (possibly modified) data source that can be used for streaming.
  55. char const* trackMIMEType(unsigned trackNumber) const;
  56. // in the form "<medium-name>/<CODEC-NAME>", or NULL if no such track exists
  57. RTPSink* createRTPSinkForTrackNumber(unsigned trackNumber, Groupsock* rtpGroupsock,
  58. unsigned char rtpPayloadTypeIfDynamic);
  59. // Creates a "RTPSink" object that would be appropriate for streaming the specified track,
  60. // or NULL if no appropriate "RTPSink" exists
  61. FileSink* createFileSinkForTrackNumber(unsigned trackNumber, char const* fileName);
  62. // Creates a "FileSink" object that would be appropriate for recording the contents of
  63. // the specified track, or NULL if no appropriate "FileSink" exists.
  64. private:
  65. MatroskaFile(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
  66. char const* preferredLanguage);
  67. // called only by createNew()
  68. virtual ~MatroskaFile();
  69. static void handleEndOfTrackHeaderParsing(void* clientData);
  70. void handleEndOfTrackHeaderParsing();
  71. void addTrack(MatroskaTrack* newTrack, unsigned trackNumber);
  72. void addCuePoint(double cueTime, u_int64_t clusterOffsetInFile, unsigned blockNumWithinCluster);
  73. Boolean lookupCuePoint(double& cueTime, u_int64_t& resultClusterOffsetInFile, unsigned& resultBlockNumWithinCluster);
  74. void printCuePoints(FILE* fid);
  75. void removeDemux(MatroskaDemux* demux);
  76. void getH264ConfigData(MatroskaTrack const* track,
  77. u_int8_t*& sps, unsigned& spsSize,
  78. u_int8_t*& pps, unsigned& ppsSize);
  79. // "sps","pps" are dynamically allocated by this function, and must be delete[]d afterwards
  80. void getH265ConfigData(MatroskaTrack const* track,
  81. u_int8_t*& vps, unsigned& vpsSize,
  82. u_int8_t*& sps, unsigned& spsSize,
  83. u_int8_t*& pps, unsigned& ppsSize);
  84. // "vps","sps","pps" are dynamically allocated by this function, and must be delete[]d afterwards
  85. void getVorbisOrTheoraConfigData(MatroskaTrack const* track,
  86. u_int8_t*& identificationHeader, unsigned& identificationHeaderSize,
  87. u_int8_t*& commentHeader, unsigned& commentHeaderSize,
  88. u_int8_t*& setupHeader, unsigned& setupHeaderSize);
  89. // "identificationHeader", "commentHeader", "setupHeader" are dynamically allocated by this function, and must be delete[]d afterwards
  90. private:
  91. friend class MatroskaFileParser;
  92. friend class MatroskaDemux;
  93. char const* fFileName;
  94. onCreationFunc* fOnCreation;
  95. void* fOnCreationClientData;
  96. char const* fPreferredLanguage;
  97. unsigned fTimecodeScale; // in nanoseconds
  98. float fSegmentDuration; // in units of "fTimecodeScale"
  99. u_int64_t fSegmentDataOffset, fClusterOffset, fCuesOffset;
  100. class MatroskaTrackTable* fTrackTable;
  101. HashTable* fDemuxesTable;
  102. class CuePoint* fCuePoints;
  103. unsigned fChosenVideoTrackNumber, fChosenAudioTrackNumber, fChosenSubtitleTrackNumber;
  104. class MatroskaFileParser* fParserForInitialization;
  105. };
  106. // We define our own track type codes as bits (powers of 2), so we can use the set of track types as a bitmap, representing a set:
  107. // (Note that MATROSKA_TRACK_TYPE_OTHER must be last, and have the largest value.)
  108. #define MATROSKA_TRACK_TYPE_VIDEO 0x01
  109. #define MATROSKA_TRACK_TYPE_AUDIO 0x02
  110. #define MATROSKA_TRACK_TYPE_SUBTITLE 0x04
  111. #define MATROSKA_TRACK_TYPE_OTHER 0x08
  112. class MatroskaTrack {
  113. public:
  114. MatroskaTrack();
  115. virtual ~MatroskaTrack();
  116. // track parameters
  117. unsigned trackNumber;
  118. u_int8_t trackType;
  119. Boolean isEnabled, isDefault, isForced;
  120. unsigned defaultDuration;
  121. char* name;
  122. char* language;
  123. char* codecID;
  124. unsigned samplingFrequency;
  125. unsigned numChannels;
  126. char const* mimeType;
  127. unsigned codecPrivateSize;
  128. u_int8_t* codecPrivate;
  129. Boolean codecPrivateUsesH264FormatForH265; // a hack specifically for H.265 video tracks
  130. Boolean codecIsOpus; // a hack for Opus audio
  131. unsigned headerStrippedBytesSize;
  132. u_int8_t* headerStrippedBytes;
  133. char const* colorSampling;
  134. char const* colorimetry;
  135. unsigned pixelWidth;
  136. unsigned pixelHeight;
  137. unsigned bitDepth;
  138. unsigned subframeSizeSize; // 0 means: frames do not have subframes (the default behavior)
  139. Boolean haveSubframes() const { return subframeSizeSize > 0; }
  140. };
  141. class MatroskaDemux: public Medium {
  142. public:
  143. FramedSource* newDemuxedTrack();
  144. FramedSource* newDemuxedTrack(unsigned& resultTrackNumber);
  145. // Returns a new stream ("FramedSource" subclass) that represents the next preferred media
  146. // track (video, audio, subtitle - in that order) from the file. (Preferred media tracks
  147. // are based on the file's language preference.)
  148. // This function returns NULL when no more media tracks exist.
  149. FramedSource* newDemuxedTrackByTrackNumber(unsigned trackNumber);
  150. // As above, but creates a new stream for a specific track number within the Matroska file.
  151. // (You should not call this function more than once with the same track number.)
  152. // Note: We assume that:
  153. // - Every track created by "newDemuxedTrack()" is later read
  154. // - All calls to "newDemuxedTrack()" are made before any track is read
  155. protected:
  156. friend class MatroskaFile;
  157. friend class MatroskaFileParser;
  158. class MatroskaDemuxedTrack* lookupDemuxedTrack(unsigned trackNumber);
  159. MatroskaDemux(MatroskaFile& ourFile); // we're created only by a "MatroskaFile" (a friend)
  160. virtual ~MatroskaDemux();
  161. private:
  162. friend class MatroskaDemuxedTrack;
  163. void removeTrack(unsigned trackNumber);
  164. void continueReading(); // called by a demuxed track to tell us that it has a pending read ("doGetNextFrame()")
  165. void seekToTime(double& seekNPT);
  166. void pause();
  167. static void handleEndOfFile(void* clientData);
  168. void handleEndOfFile();
  169. void resetState();
  170. private:
  171. MatroskaFile& fOurFile;
  172. class MatroskaFileParser* fOurParser;
  173. HashTable* fDemuxedTracksTable;
  174. // Used to implement "newServerMediaSubsession()":
  175. u_int8_t fNextTrackTypeToCheck;
  176. };
  177. #endif