MatroskaFile.hh 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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-2019 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 _HASH_TABLE_HH
  24. #include "HashTable.hh"
  25. #endif
  26. class MatroskaTrack; // forward
  27. class MatroskaDemux; // forward
  28. class MatroskaFile: public Medium {
  29. public:
  30. typedef void (onCreationFunc)(MatroskaFile* newFile, void* clientData);
  31. static void createNew(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
  32. char const* preferredLanguage = "eng");
  33. // Note: Unlike most "createNew()" functions, this one doesn't return a new object immediately. Instead, because this class
  34. // requires file reading (to parse the Matroska 'Track' headers) before a new object can be initialized, the creation of a new
  35. // object is signalled by calling - from the event loop - an 'onCreationFunc' that is passed as a parameter to "createNew()".
  36. MatroskaTrack* lookup(unsigned trackNumber) const;
  37. // Create a demultiplexor for extracting tracks from this file. (Separate clients will typically have separate demultiplexors.)
  38. MatroskaDemux* newDemux();
  39. // Parameters of the file ('Segment'); set when the file is parsed:
  40. unsigned timecodeScale() { return fTimecodeScale; } // in nanoseconds
  41. float segmentDuration() { return fSegmentDuration; } // in units of "timecodeScale()"
  42. float fileDuration(); // in seconds
  43. char const* fileName() const { return fFileName; }
  44. unsigned chosenVideoTrackNumber() { return fChosenVideoTrackNumber; }
  45. unsigned chosenAudioTrackNumber() { return fChosenAudioTrackNumber; }
  46. unsigned chosenSubtitleTrackNumber() { return fChosenSubtitleTrackNumber; }
  47. FramedSource*
  48. createSourceForStreaming(FramedSource* baseSource, unsigned trackNumber,
  49. unsigned& estBitrate, unsigned& numFiltersInFrontOfTrack);
  50. // Takes a data source (which must be a demultiplexed track from this file) and returns
  51. // a (possibly modified) data source that can be used for streaming.
  52. RTPSink* createRTPSinkForTrackNumber(unsigned trackNumber, Groupsock* rtpGroupsock,
  53. unsigned char rtpPayloadTypeIfDynamic);
  54. // Creates a "RTPSink" object that would be appropriate for streaming the specified track,
  55. // or NULL if no appropriate "RTPSink" exists
  56. private:
  57. MatroskaFile(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
  58. char const* preferredLanguage);
  59. // called only by createNew()
  60. virtual ~MatroskaFile();
  61. static void handleEndOfTrackHeaderParsing(void* clientData);
  62. void handleEndOfTrackHeaderParsing();
  63. void addTrack(MatroskaTrack* newTrack, unsigned trackNumber);
  64. void addCuePoint(double cueTime, u_int64_t clusterOffsetInFile, unsigned blockNumWithinCluster);
  65. Boolean lookupCuePoint(double& cueTime, u_int64_t& resultClusterOffsetInFile, unsigned& resultBlockNumWithinCluster);
  66. void printCuePoints(FILE* fid);
  67. void removeDemux(MatroskaDemux* demux);
  68. private:
  69. friend class MatroskaFileParser;
  70. friend class MatroskaDemux;
  71. char const* fFileName;
  72. onCreationFunc* fOnCreation;
  73. void* fOnCreationClientData;
  74. char const* fPreferredLanguage;
  75. unsigned fTimecodeScale; // in nanoseconds
  76. float fSegmentDuration; // in units of "fTimecodeScale"
  77. u_int64_t fSegmentDataOffset, fClusterOffset, fCuesOffset;
  78. class MatroskaTrackTable* fTrackTable;
  79. HashTable* fDemuxesTable;
  80. class CuePoint* fCuePoints;
  81. unsigned fChosenVideoTrackNumber, fChosenAudioTrackNumber, fChosenSubtitleTrackNumber;
  82. class MatroskaFileParser* fParserForInitialization;
  83. };
  84. // 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:
  85. // (Note that MATROSKA_TRACK_TYPE_OTHER must be last, and have the largest value.)
  86. #define MATROSKA_TRACK_TYPE_VIDEO 0x01
  87. #define MATROSKA_TRACK_TYPE_AUDIO 0x02
  88. #define MATROSKA_TRACK_TYPE_SUBTITLE 0x04
  89. #define MATROSKA_TRACK_TYPE_OTHER 0x08
  90. class MatroskaTrack {
  91. public:
  92. MatroskaTrack();
  93. virtual ~MatroskaTrack();
  94. // track parameters
  95. unsigned trackNumber;
  96. u_int8_t trackType;
  97. Boolean isEnabled, isDefault, isForced;
  98. unsigned defaultDuration;
  99. char* name;
  100. char* language;
  101. char* codecID;
  102. unsigned samplingFrequency;
  103. unsigned numChannels;
  104. char const* mimeType;
  105. unsigned codecPrivateSize;
  106. u_int8_t* codecPrivate;
  107. Boolean codecPrivateUsesH264FormatForH265; // a hack specifically for H.265 video tracks
  108. Boolean codecIsOpus; // a hack for Opus audio
  109. unsigned headerStrippedBytesSize;
  110. u_int8_t* headerStrippedBytes;
  111. char const* colorSampling;
  112. char const* colorimetry;
  113. unsigned pixelWidth;
  114. unsigned pixelHeight;
  115. unsigned bitDepth;
  116. unsigned subframeSizeSize; // 0 means: frames do not have subframes (the default behavior)
  117. Boolean haveSubframes() const { return subframeSizeSize > 0; }
  118. };
  119. class MatroskaDemux: public Medium {
  120. public:
  121. FramedSource* newDemuxedTrack();
  122. FramedSource* newDemuxedTrack(unsigned& resultTrackNumber);
  123. // Returns a new stream ("FramedSource" subclass) that represents the next preferred media
  124. // track (video, audio, subtitle - in that order) from the file. (Preferred media tracks
  125. // are based on the file's language preference.)
  126. // This function returns NULL when no more media tracks exist.
  127. FramedSource* newDemuxedTrackByTrackNumber(unsigned trackNumber);
  128. // As above, but creates a new stream for a specific track number within the Matroska file.
  129. // (You should not call this function more than once with the same track number.)
  130. // Note: We assume that:
  131. // - Every track created by "newDemuxedTrack()" is later read
  132. // - All calls to "newDemuxedTrack()" are made before any track is read
  133. protected:
  134. friend class MatroskaFile;
  135. friend class MatroskaFileParser;
  136. class MatroskaDemuxedTrack* lookupDemuxedTrack(unsigned trackNumber);
  137. MatroskaDemux(MatroskaFile& ourFile); // we're created only by a "MatroskaFile" (a friend)
  138. virtual ~MatroskaDemux();
  139. private:
  140. friend class MatroskaDemuxedTrack;
  141. void removeTrack(unsigned trackNumber);
  142. void continueReading(); // called by a demuxed track to tell us that it has a pending read ("doGetNextFrame()")
  143. void seekToTime(double& seekNPT);
  144. static void handleEndOfFile(void* clientData);
  145. void handleEndOfFile();
  146. private:
  147. MatroskaFile& fOurFile;
  148. class MatroskaFileParser* fOurParser;
  149. HashTable* fDemuxedTracksTable;
  150. // Used to implement "newServerMediaSubsession()":
  151. u_int8_t fNextTrackTypeToCheck;
  152. };
  153. #endif