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