1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// Media Sinks
19// C++ header
20
21#ifndef _MEDIA_SINK_HH
22#define _MEDIA_SINK_HH
23
24#ifndef _FRAMED_SOURCE_HH
25#include "FramedSource.hh"
26#endif
27
28class MediaSink: public Medium {
29public:
30 static Boolean lookupByName(UsageEnvironment& env, char const* sinkName,
31 MediaSink*& resultSink);
32
33 typedef void (afterPlayingFunc)(void* clientData);
34 Boolean startPlaying(MediaSource& source,
35 afterPlayingFunc* afterFunc,
36 void* afterClientData);
37 virtual void stopPlaying();
38
39 // Test for specific types of sink:
40 virtual Boolean isRTPSink() const;
41
42 FramedSource* source() const {return fSource;}
43
44protected:
45 MediaSink(UsageEnvironment& env); // abstract base class
46 virtual ~MediaSink();
47
48 virtual Boolean sourceIsCompatibleWithUs(MediaSource& source);
49 // called by startPlaying()
50 virtual Boolean continuePlaying() = 0;
51 // called by startPlaying()
52
53 static void onSourceClosure(void* clientData); // can be used in "getNextFrame()" calls
54 void onSourceClosure();
55 // should be called (on ourselves) by continuePlaying() when it
56 // discovers that the source we're playing from has closed.
57
58 FramedSource* fSource;
59
60private:
61 // redefined virtual functions:
62 virtual Boolean isSink() const;
63
64private:
65 // The following fields are used when we're being played:
66 afterPlayingFunc* fAfterFunc;
67 void* fAfterClientData;
68};
69
70// A data structure that a sink may use for an output packet:
71class OutPacketBuffer {
72public:
73 OutPacketBuffer(unsigned preferredPacketSize, unsigned maxPacketSize,
74 unsigned maxBufferSize = 0);
75 // if "maxBufferSize" is >0, use it - instead of "maxSize" to compute the buffer size
76 ~OutPacketBuffer();
77
78 static unsigned maxSize;
79 static void increaseMaxSizeTo(unsigned newMaxSize) { if (newMaxSize > OutPacketBuffer::maxSize) OutPacketBuffer::maxSize = newMaxSize; }
80
81 unsigned char* curPtr() const {return &fBuf[fPacketStart + fCurOffset];}
82 unsigned totalBytesAvailable() const {
83 return fLimit - (fPacketStart + fCurOffset);
84 }
85 unsigned totalBufferSize() const { return fLimit; }
86 unsigned char* packet() const {return &fBuf[fPacketStart];}
87 unsigned curPacketSize() const {return fCurOffset;}
88
89 void increment(unsigned numBytes) {fCurOffset += numBytes;}
90
91 void enqueue(unsigned char const* from, unsigned numBytes);
92 void enqueueWord(u_int32_t word);
93 void insert(unsigned char const* from, unsigned numBytes, unsigned toPosition);
94 void insertWord(u_int32_t word, unsigned toPosition);
95 void extract(unsigned char* to, unsigned numBytes, unsigned fromPosition);
96 u_int32_t extractWord(unsigned fromPosition);
97
98 void skipBytes(unsigned numBytes);
99
100 Boolean isPreferredSize() const {return fCurOffset >= fPreferred;}
101 Boolean wouldOverflow(unsigned numBytes) const {
102 return (fCurOffset+numBytes) > fMax;
103 }
104 unsigned numOverflowBytes(unsigned numBytes) const {
105 return (fCurOffset+numBytes) - fMax;
106 }
107 Boolean isTooBigForAPacket(unsigned numBytes) const {
108 return numBytes > fMax;
109 }
110
111 void setOverflowData(unsigned overflowDataOffset,
112 unsigned overflowDataSize,
113 struct timeval const& presentationTime,
114 unsigned durationInMicroseconds);
115 unsigned overflowDataSize() const {return fOverflowDataSize;}
116 struct timeval overflowPresentationTime() const {return fOverflowPresentationTime;}
117 unsigned overflowDurationInMicroseconds() const {return fOverflowDurationInMicroseconds;}
118 Boolean haveOverflowData() const {return fOverflowDataSize > 0;}
119 void useOverflowData();
120
121 void adjustPacketStart(unsigned numBytes);
122 void resetPacketStart();
123 void resetOffset() { fCurOffset = 0; }
124 void resetOverflowData() { fOverflowDataOffset = fOverflowDataSize = 0; }
125
126private:
127 unsigned fPacketStart, fCurOffset, fPreferred, fMax, fLimit;
128 unsigned char* fBuf;
129
130 unsigned fOverflowDataOffset, fOverflowDataSize;
131 struct timeval fOverflowPresentationTime;
132 unsigned fOverflowDurationInMicroseconds;
133};
134
135#endif
136