New file |
| | |
| | | /********** |
| | | 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-2017 Live Networks, Inc. All rights reserved. |
| | | // Media Sinks |
| | | // C++ header |
| | | |
| | | #ifndef _MEDIA_SINK_HH |
| | | #define _MEDIA_SINK_HH |
| | | |
| | | #ifndef _FRAMED_SOURCE_HH |
| | | #include "FramedSource.hh" |
| | | #endif |
| | | |
| | | class MediaSink: public Medium { |
| | | public: |
| | | static Boolean lookupByName(UsageEnvironment& env, char const* sinkName, |
| | | MediaSink*& resultSink); |
| | | |
| | | typedef void (afterPlayingFunc)(void* clientData); |
| | | Boolean startPlaying(MediaSource& source, |
| | | afterPlayingFunc* afterFunc, |
| | | void* afterClientData); |
| | | virtual void stopPlaying(); |
| | | |
| | | // Test for specific types of sink: |
| | | virtual Boolean isRTPSink() const; |
| | | |
| | | FramedSource* source() const {return fSource;} |
| | | |
| | | protected: |
| | | MediaSink(UsageEnvironment& env); // abstract base class |
| | | virtual ~MediaSink(); |
| | | |
| | | virtual Boolean sourceIsCompatibleWithUs(MediaSource& source); |
| | | // called by startPlaying() |
| | | virtual Boolean continuePlaying() = 0; |
| | | // called by startPlaying() |
| | | |
| | | static void onSourceClosure(void* clientData); // can be used in "getNextFrame()" calls |
| | | void onSourceClosure(); |
| | | // should be called (on ourselves) by continuePlaying() when it |
| | | // discovers that the source we're playing from has closed. |
| | | |
| | | FramedSource* fSource; |
| | | |
| | | private: |
| | | // redefined virtual functions: |
| | | virtual Boolean isSink() const; |
| | | |
| | | private: |
| | | // The following fields are used when we're being played: |
| | | afterPlayingFunc* fAfterFunc; |
| | | void* fAfterClientData; |
| | | }; |
| | | |
| | | // A data structure that a sink may use for an output packet: |
| | | class OutPacketBuffer { |
| | | public: |
| | | OutPacketBuffer(unsigned preferredPacketSize, unsigned maxPacketSize, |
| | | unsigned maxBufferSize = 0); |
| | | // if "maxBufferSize" is >0, use it - instead of "maxSize" to compute the buffer size |
| | | ~OutPacketBuffer(); |
| | | |
| | | static unsigned maxSize; |
| | | static void increaseMaxSizeTo(unsigned newMaxSize) { if (newMaxSize > OutPacketBuffer::maxSize) OutPacketBuffer::maxSize = newMaxSize; } |
| | | |
| | | unsigned char* curPtr() const {return &fBuf[fPacketStart + fCurOffset];} |
| | | unsigned totalBytesAvailable() const { |
| | | return fLimit - (fPacketStart + fCurOffset); |
| | | } |
| | | unsigned totalBufferSize() const { return fLimit; } |
| | | unsigned char* packet() const {return &fBuf[fPacketStart];} |
| | | unsigned curPacketSize() const {return fCurOffset;} |
| | | |
| | | void increment(unsigned numBytes) {fCurOffset += numBytes;} |
| | | |
| | | void enqueue(unsigned char const* from, unsigned numBytes); |
| | | void enqueueWord(u_int32_t word); |
| | | void insert(unsigned char const* from, unsigned numBytes, unsigned toPosition); |
| | | void insertWord(u_int32_t word, unsigned toPosition); |
| | | void extract(unsigned char* to, unsigned numBytes, unsigned fromPosition); |
| | | u_int32_t extractWord(unsigned fromPosition); |
| | | |
| | | void skipBytes(unsigned numBytes); |
| | | |
| | | Boolean isPreferredSize() const {return fCurOffset >= fPreferred;} |
| | | Boolean wouldOverflow(unsigned numBytes) const { |
| | | return (fCurOffset+numBytes) > fMax; |
| | | } |
| | | unsigned numOverflowBytes(unsigned numBytes) const { |
| | | return (fCurOffset+numBytes) - fMax; |
| | | } |
| | | Boolean isTooBigForAPacket(unsigned numBytes) const { |
| | | return numBytes > fMax; |
| | | } |
| | | |
| | | void setOverflowData(unsigned overflowDataOffset, |
| | | unsigned overflowDataSize, |
| | | struct timeval const& presentationTime, |
| | | unsigned durationInMicroseconds); |
| | | unsigned overflowDataSize() const {return fOverflowDataSize;} |
| | | struct timeval overflowPresentationTime() const {return fOverflowPresentationTime;} |
| | | unsigned overflowDurationInMicroseconds() const {return fOverflowDurationInMicroseconds;} |
| | | Boolean haveOverflowData() const {return fOverflowDataSize > 0;} |
| | | void useOverflowData(); |
| | | |
| | | void adjustPacketStart(unsigned numBytes); |
| | | void resetPacketStart(); |
| | | void resetOffset() { fCurOffset = 0; } |
| | | void resetOverflowData() { fOverflowDataOffset = fOverflowDataSize = 0; } |
| | | |
| | | private: |
| | | unsigned fPacketStart, fCurOffset, fPreferred, fMax, fLimit; |
| | | unsigned char* fBuf; |
| | | |
| | | unsigned fOverflowDataOffset, fOverflowDataSize; |
| | | struct timeval fOverflowPresentationTime; |
| | | unsigned fOverflowDurationInMicroseconds; |
| | | }; |
| | | |
| | | #endif |