00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _MATROSKA_FILE_HH
00022 #define _MATROSKA_FILE_HH
00023
00024 #ifndef _MEDIA_HH
00025 #include "Media.hh"
00026 #endif
00027 #ifndef _HASH_TABLE_HH
00028 #include "HashTable.hh"
00029 #endif
00030
00031 class MatroskaTrack;
00032 class MatroskaDemux;
00033
00034 class MatroskaFile: public Medium {
00035 public:
00036 typedef void (onCreationFunc)(MatroskaFile* newFile, void* clientData);
00037 static void createNew(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
00038 char const* preferredLanguage = "eng");
00039
00040
00041
00042
00043
00044 class TrackTable {
00045 public:
00046 TrackTable();
00047 virtual ~TrackTable();
00048
00049 void add(MatroskaTrack* newTrack, unsigned trackNumber);
00050 MatroskaTrack* lookup(unsigned trackNumber);
00051
00052 unsigned numTracks() const;
00053
00054 class Iterator {
00055 public:
00056 Iterator(TrackTable& ourTable);
00057 virtual ~Iterator();
00058 MatroskaTrack* next();
00059 private:
00060 TrackTable& fOurTable;
00061 HashTable::Iterator* fIter;
00062 };
00063
00064 private:
00065 friend class Iterator;
00066 HashTable* fTable;
00067 };
00068
00069 MatroskaTrack* lookup(unsigned trackNumber) { return fTracks.lookup(trackNumber); }
00070
00071
00072 MatroskaDemux* newDemux();
00073
00074
00075 unsigned timecodeScale() { return fTimecodeScale; }
00076 float segmentDuration() { return fSegmentDuration; }
00077 float fileDuration();
00078 TrackTable& tracks() { return fTracks; }
00079
00080 char const* fileName() const { return fFileName; }
00081
00082 unsigned chosenVideoTrackNumber() { return fChosenVideoTrackNumber; }
00083 unsigned chosenAudioTrackNumber() { return fChosenAudioTrackNumber; }
00084 unsigned chosenSubtitleTrackNumber() { return fChosenSubtitleTrackNumber; }
00085
00086 private:
00087 MatroskaFile(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData,
00088 char const* preferredLanguage);
00089
00090 virtual ~MatroskaFile();
00091
00092 static void handleEndOfTrackHeaderParsing(void* clientData);
00093 void handleEndOfTrackHeaderParsing();
00094
00095 void addCuePoint(double cueTime, u_int64_t clusterOffsetInFile, unsigned blockNumWithinCluster);
00096 Boolean lookupCuePoint(double& cueTime, u_int64_t& resultClusterOffsetInFile, unsigned& resultBlockNumWithinCluster);
00097 void printCuePoints(FILE* fid);
00098
00099 void removeDemux(MatroskaDemux* demux);
00100
00101 private:
00102 friend class MatroskaFileParser;
00103 friend class MatroskaDemux;
00104 char const* fFileName;
00105 onCreationFunc* fOnCreation;
00106 void* fOnCreationClientData;
00107 char const* fPreferredLanguage;
00108
00109 unsigned fTimecodeScale;
00110 float fSegmentDuration;
00111 u_int64_t fSegmentDataOffset, fClusterOffset, fCuesOffset;
00112
00113 TrackTable fTracks;
00114 HashTable* fDemuxesTable;
00115 class CuePoint* fCuePoints;
00116 unsigned fChosenVideoTrackNumber, fChosenAudioTrackNumber, fChosenSubtitleTrackNumber;
00117 class MatroskaFileParser* fParserForInitialization;
00118 };
00119
00120
00121
00122 #define MATROSKA_TRACK_TYPE_VIDEO 0x01
00123 #define MATROSKA_TRACK_TYPE_AUDIO 0x02
00124 #define MATROSKA_TRACK_TYPE_SUBTITLE 0x04
00125 #define MATROSKA_TRACK_TYPE_OTHER 0x08
00126
00127 class MatroskaTrack {
00128 public:
00129 MatroskaTrack();
00130 virtual ~MatroskaTrack();
00131
00132
00133 unsigned trackNumber;
00134 u_int8_t trackType;
00135 Boolean isEnabled, isDefault, isForced;
00136 unsigned defaultDuration;
00137 char* name;
00138 char* language;
00139 char* codecID;
00140 unsigned samplingFrequency;
00141 unsigned numChannels;
00142 char const* mimeType;
00143 unsigned codecPrivateSize;
00144 u_int8_t* codecPrivate;
00145 unsigned headerStrippedBytesSize;
00146 u_int8_t* headerStrippedBytes;
00147 unsigned subframeSizeSize;
00148 Boolean haveSubframes() const { return subframeSizeSize > 0; }
00149
00150
00151 struct timeval prevPresentationTime;
00152 int durationImbalance;
00153 };
00154
00155 class MatroskaDemux: public Medium {
00156 public:
00157 FramedSource* newDemuxedTrack(unsigned trackNumber);
00158
00159
00160
00161
00162 class MatroskaDemuxedTrack* lookupDemuxedTrack(unsigned trackNumber);
00163
00164 protected:
00165 friend class MatroskaFile;
00166 MatroskaDemux(MatroskaFile& ourFile);
00167 virtual ~MatroskaDemux();
00168
00169 private:
00170 friend class MatroskaDemuxedTrack;
00171 void removeTrack(unsigned trackNumber);
00172 void continueReading();
00173 void seekToTime(double& seekNPT);
00174
00175 static void handleEndOfFile(void* clientData);
00176 void handleEndOfFile();
00177
00178 private:
00179 MatroskaFile& fOurFile;
00180 class MatroskaFileParser* fOurParser;
00181 HashTable* fDemuxedTracksTable;
00182 };
00183
00184 #endif