/********** 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 .) 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-2024 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 LIVEMEDIA_API 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 LIVEMEDIA_API 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