123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /**********
- 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-2019 Live Networks, Inc. All rights reserved.
- // A class that encapsulates an Ogg file
- // C++ header
- #ifndef _OGG_FILE_HH
- #define _OGG_FILE_HH
- #ifndef _RTP_SINK_HH
- #include "RTPSink.hh"
- #endif
- #ifndef _HASH_TABLE_HH
- #include "HashTable.hh"
- #endif
- class OggTrack; // forward
- class OggDemux; // forward
- class OggFile: public Medium {
- public:
- typedef void (onCreationFunc)(OggFile* newFile, void* clientData);
- static void createNew(UsageEnvironment& env, char const* fileName,
- onCreationFunc* onCreation, void* onCreationClientData);
- // Note: Unlike most "createNew()" functions, this one doesn't return a new object
- // immediately. Instead, because this class requires file reading (to parse the
- // Ogg 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()".
- OggTrack* lookup(u_int32_t trackNumber);
- OggDemux* newDemux();
- // Creates a demultiplexor for extracting tracks from this file.
- // (Separate clients will typically have separate demultiplexors.)
- char const* fileName() const { return fFileName; }
- unsigned numTracks() const;
- FramedSource*
- createSourceForStreaming(FramedSource* baseSource, u_int32_t 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(u_int32_t 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
- class OggTrackTable& trackTable() { return *fTrackTable; }
- private:
- OggFile(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData);
- // called only by createNew()
- virtual ~OggFile();
- static void handleEndOfBosPageParsing(void* clientData);
- void handleEndOfBosPageParsing();
- void addTrack(OggTrack* newTrack);
- void removeDemux(OggDemux* demux);
- private:
- friend class OggFileParser;
- friend class OggDemux;
- char const* fFileName;
- onCreationFunc* fOnCreation;
- void* fOnCreationClientData;
- class OggTrackTable* fTrackTable;
- HashTable* fDemuxesTable;
- class OggFileParser* fParserForInitialization;
- };
- class OggTrack {
- public:
- OggTrack();
- virtual ~OggTrack();
- // track parameters
- u_int32_t trackNumber; // bitstream serial number
- char const* mimeType; // NULL if not known
- unsigned samplingFrequency, numChannels; // for audio tracks
- unsigned estBitrate; // estimate, in kbps (for RTCP)
- // Special headers for Vorbis audio, Theora video, and Opus audio tracks:
- struct _vtoHdrs {
- u_int8_t* header[3]; // "identification", "comment", "setup"
- unsigned headerSize[3];
- // Fields specific to Vorbis audio:
- unsigned blocksize[2]; // samples per frame (packet)
- unsigned uSecsPerPacket[2]; // computed as (blocksize[i]*1000000)/samplingFrequency
- unsigned vorbis_mode_count;
- unsigned ilog_vorbis_mode_count_minus_1;
- u_int8_t* vorbis_mode_blockflag;
- // an array (of size "vorbis_mode_count") of indexes into the (2-entry) "blocksize" array
- // Fields specific to Theora video:
- u_int8_t KFGSHIFT;
- unsigned uSecsPerFrame;
- } vtoHdrs;
- Boolean weNeedHeaders() const {
- return
- vtoHdrs.header[0] == NULL ||
- vtoHdrs.header[1] == NULL ||
- (vtoHdrs.header[2] == NULL && strcmp(mimeType, "audio/OPUS") != 0);
- }
- };
- class OggTrackTableIterator {
- public:
- OggTrackTableIterator(class OggTrackTable& ourTable);
- virtual ~OggTrackTableIterator();
- OggTrack* next();
- private:
- HashTable::Iterator* fIter;
- };
- class OggDemux: public Medium {
- public:
- FramedSource* newDemuxedTrack(u_int32_t& resultTrackNumber);
- // Returns a new stream ("FramedSource" subclass) that represents the next media track
- // from the file. 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 OggFile;
- friend class OggFileParser;
- class OggDemuxedTrack* lookupDemuxedTrack(u_int32_t trackNumber);
- OggDemux(OggFile& ourFile);
- virtual ~OggDemux();
- private:
- friend class OggDemuxedTrack;
- void removeTrack(u_int32_t trackNumber);
- void continueReading(); // called by a demuxed track to tell us that it has a pending read ("doGetNextFrame()")
- static void handleEndOfFile(void* clientData);
- void handleEndOfFile();
- private:
- OggFile& fOurFile;
- class OggFileParser* fOurParser;
- HashTable* fDemuxedTracksTable;
- OggTrackTableIterator* fIter;
- };
- #endif
|