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// A sink that generates a QuickTime file from a composite media session
19// C++ header
20
21#ifndef _QUICKTIME_FILE_SINK_HH
22#define _QUICKTIME_FILE_SINK_HH
23
24#ifndef _MEDIA_SESSION_HH
25#include "MediaSession.hh"
26#endif
27
28class QuickTimeFileSink: public Medium {
29public:
30 static QuickTimeFileSink* createNew(UsageEnvironment& env,
31 MediaSession& inputSession,
32 char const* outputFileName,
33 unsigned bufferSize = 20000,
34 unsigned short movieWidth = 240,
35 unsigned short movieHeight = 180,
36 unsigned movieFPS = 15,
37 Boolean packetLossCompensate = False,
38 Boolean syncStreams = False,
39 Boolean generateHintTracks = False,
40 Boolean generateMP4Format = False);
41
42 typedef void (afterPlayingFunc)(void* clientData);
43 Boolean startPlaying(afterPlayingFunc* afterFunc,
44 void* afterClientData);
45
46 unsigned numActiveSubsessions() const { return fNumSubsessions; }
47
48protected:
49 QuickTimeFileSink(UsageEnvironment& env, MediaSession& inputSession,
50 char const* outputFileName, unsigned bufferSize,
51 unsigned short movieWidth, unsigned short movieHeight,
52 unsigned movieFPS, Boolean packetLossCompensate,
53 Boolean syncStreams, Boolean generateHintTracks,
54 Boolean generateMP4Format);
55 // called only by createNew()
56 virtual ~QuickTimeFileSink();
57
58 virtual void noteRecordedFrame(MediaSubsession& inputSubsession,
59 unsigned packetDataSize, struct timeval const& presentationTime);
60
61private:
62 Boolean continuePlaying();
63 static void afterGettingFrame(void* clientData, unsigned frameSize,
64 unsigned numTruncatedBytes,
65 struct timeval presentationTime,
66 unsigned durationInMicroseconds);
67 static void onSourceClosure(void* clientData);
68 void onSourceClosure1();
69 static void onRTCPBye(void* clientData);
70 void completeOutputFile();
71
72private:
73 friend class SubsessionIOState;
74 MediaSession& fInputSession;
75 FILE* fOutFid;
76 unsigned fBufferSize;
77 Boolean fPacketLossCompensate;
78 Boolean fSyncStreams, fGenerateMP4Format;
79 struct timeval fNewestSyncTime, fFirstDataTime;
80 Boolean fAreCurrentlyBeingPlayed;
81 afterPlayingFunc* fAfterFunc;
82 void* fAfterClientData;
83 unsigned fAppleCreationTime;
84 unsigned fLargestRTPtimestampFrequency;
85 unsigned fNumSubsessions, fNumSyncedSubsessions;
86 struct timeval fStartTime;
87 Boolean fHaveCompletedOutputFile;
88
89private:
90 ///// Definitions specific to the QuickTime file format:
91
92 unsigned addWord64(u_int64_t word);
93 unsigned addWord(unsigned word);
94 unsigned addHalfWord(unsigned short halfWord);
95 unsigned addByte(unsigned char byte) {
96 putc(byte, fOutFid);
97 return 1;
98 }
99 unsigned addZeroWords(unsigned numWords);
100 unsigned add4ByteString(char const* str);
101 unsigned addArbitraryString(char const* str,
102 Boolean oneByteLength = True);
103 unsigned addAtomHeader(char const* atomName);
104 unsigned addAtomHeader64(char const* atomName);
105 // strlen(atomName) must be 4
106 void setWord(int64_t filePosn, unsigned size);
107 void setWord64(int64_t filePosn, u_int64_t size);
108
109 unsigned movieTimeScale() const {return fLargestRTPtimestampFrequency;}
110
111 // Define member functions for outputting various types of atom:
112#define _atom(name) unsigned addAtom_##name()
113 _atom(ftyp); // for MP4 format files
114 _atom(moov);
115 _atom(mvhd);
116 _atom(iods); // for MP4 format files
117 _atom(trak);
118 _atom(tkhd);
119 _atom(edts);
120 _atom(elst);
121 _atom(tref);
122 _atom(hint);
123 _atom(mdia);
124 _atom(mdhd);
125 _atom(hdlr);
126 _atom(minf);
127 _atom(smhd);
128 _atom(vmhd);
129 _atom(gmhd);
130 _atom(gmin);
131 unsigned addAtom_hdlr2();
132 _atom(dinf);
133 _atom(dref);
134 _atom(alis);
135 _atom(stbl);
136 _atom(stsd);
137 unsigned addAtom_genericMedia();
138 unsigned addAtom_soundMediaGeneral();
139 _atom(ulaw);
140 _atom(alaw);
141 _atom(Qclp);
142 _atom(wave);
143 _atom(frma);
144 _atom(Fclp);
145 _atom(Hclp);
146 _atom(mp4a);
147// _atom(wave);
148// _atom(frma);
149 _atom(esds);
150 _atom(srcq);
151 _atom(h263);
152 _atom(avc1);
153 _atom(avcC);
154 _atom(mp4v);
155 _atom(rtp);
156 _atom(tims);
157 _atom(stts);
158 _atom(stss);
159 _atom(stsc);
160 _atom(stsz);
161 _atom(co64);
162 _atom(udta);
163 _atom(name);
164 _atom(hnti);
165 _atom(sdp);
166 _atom(hinf);
167 _atom(totl);
168 _atom(npck);
169 _atom(tpay);
170 _atom(trpy);
171 _atom(nump);
172 _atom(tpyl);
173 _atom(dmed);
174 _atom(dimm);
175 _atom(drep);
176 _atom(tmin);
177 _atom(tmax);
178 _atom(pmax);
179 _atom(dmax);
180 _atom(payt);
181 unsigned addAtom_dummy();
182
183private:
184 unsigned short fMovieWidth, fMovieHeight;
185 unsigned fMovieFPS;
186 int64_t fMDATposition;
187 int64_t fMVHD_durationPosn;
188 unsigned fMaxTrackDurationM; // in movie time units
189 class SubsessionIOState* fCurrentIOState;
190};
191
192#endif
193