1 /*
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * The Original Code is MPEG4IP.
13  *
14  * The Initial Developer of the Original Code is Cisco Systems Inc.
15  * Portions created by Cisco Systems Inc. are
16  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
17  *
18  * Contributor(s):
19  *      Dave Mackie     dmackie@cisco.com
20  */
21 
22 #ifndef MP4V2_IMPL_RTPHINT_H
23 #define MP4V2_IMPL_RTPHINT_H
24 
25 namespace mp4v2 {
26 namespace impl {
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 
30 // forward declarations
31 class MP4RtpHintTrack;
32 class MP4RtpHint;
33 class MP4RtpPacket;
34 
35 class MP4RtpData : public MP4Container {
36 public:
37     MP4RtpData(MP4RtpPacket& packet);
38 
GetPacket()39     MP4RtpPacket& GetPacket() {
40         return m_packet;
41     }
42 
43     virtual uint16_t GetDataSize() = 0;
44     virtual void GetData(uint8_t* pDest) = 0;
45 
46     MP4Track* FindTrackFromRefIndex(uint8_t refIndex);
47 
WriteEmbeddedData(MP4File & file,uint64_t startPos)48     virtual void WriteEmbeddedData(MP4File& file, uint64_t startPos) {
49         // default is no-op
50     }
51 
52 protected:
53     MP4RtpPacket& m_packet;
54 };
55 
MP4ARRAY_DECL(MP4RtpData,MP4RtpData *)56 MP4ARRAY_DECL(MP4RtpData, MP4RtpData*)
57 
58 class MP4RtpNullData : public MP4RtpData {
59 public:
60     MP4RtpNullData(MP4RtpPacket& packet);
61 
62     uint16_t GetDataSize() {
63         return 0;
64     }
65 
66     void GetData(uint8_t* pDest) {
67         // no-op
68     }
69 };
70 
71 class MP4RtpImmediateData : public MP4RtpData {
72 public:
73     MP4RtpImmediateData(MP4RtpPacket& packet);
74 
75     void Set(const uint8_t* pBytes, uint8_t numBytes);
76 
77     uint16_t GetDataSize();
78 
79     void GetData(uint8_t* pDest);
80 };
81 
82 class MP4RtpSampleData : public MP4RtpData {
83 public:
84     MP4RtpSampleData(MP4RtpPacket& packet);
85 
~MP4RtpSampleData(void)86     ~MP4RtpSampleData(void) {
87         CHECK_AND_FREE(m_pRefData);
88     };
89 
90     void SetEmbeddedImmediate(
91         MP4SampleId sampleId,
92         uint8_t* pData, uint16_t dataLength);
93 
94     void SetReferenceSample(
95         MP4SampleId refSampleId, uint32_t refSampleOffset,
96         uint16_t sampleLength);
97 
98     void SetEmbeddedSample(
99         MP4SampleId sampleId, MP4Track* pRefTrack,
100         MP4SampleId refSampleId, uint32_t refSampleOffset,
101         uint16_t sampleLength);
102 
103     uint16_t GetDataSize();
104 
105     void GetData(uint8_t* pDest);
106 
107     void WriteEmbeddedData(MP4File& file, uint64_t startPos);
108 
109 protected:
110     uint8_t*        m_pRefData;
111 
112     MP4Track*       m_pRefTrack;
113     MP4SampleId     m_refSampleId;
114     uint32_t        m_refSampleOffset;
115 };
116 
117 class MP4RtpSampleDescriptionData : public MP4RtpData {
118 public:
119     MP4RtpSampleDescriptionData(MP4RtpPacket& packet);
120 
121     void Set(uint32_t sampleDescrIndex,
122              uint32_t offset, uint16_t length);
123 
124     uint16_t GetDataSize();
125 
126     void GetData(uint8_t* pDest);
127 };
128 
129 class MP4RtpPacket : public MP4Container {
130 public:
131     MP4RtpPacket(MP4RtpHint& hint);
132 
133     ~MP4RtpPacket();
134 
135     void AddExtraProperties();
136 
GetHint()137     MP4RtpHint& GetHint() {
138         return m_hint;
139     }
140 
141     void Set(uint8_t payloadNumber, uint32_t packetId, bool setMbit);
142 
143     int32_t GetTransmitOffset();
144 
145     bool GetPBit();
146 
147     bool GetXBit();
148 
149     bool GetMBit();
150 
151     uint8_t GetPayload();
152 
153     uint16_t GetSequenceNumber();
154 
155     void SetTransmitOffset(int32_t transmitOffset);
156 
157     bool IsBFrame();
158 
159     void SetBFrame(bool isBFrame);
160 
161     void SetTimestampOffset(uint32_t timestampOffset);
162 
163     void AddData(MP4RtpData* pData);
164 
165     uint32_t GetDataSize();
166 
167     void GetData(uint8_t* pDest);
168 
169     void Read(MP4File& file);
170 
171     void ReadExtra(MP4File& file);
172 
173     void Write(MP4File& file);
174 
175     void WriteEmbeddedData(MP4File& file, uint64_t startPos);
176 
177     void Dump(uint8_t indent, bool dumpImplicits);
178 
179 protected:
180     MP4RtpHint&         m_hint;
181     MP4RtpDataArray     m_rtpData;
182 };
183 
MP4ARRAY_DECL(MP4RtpPacket,MP4RtpPacket *)184 MP4ARRAY_DECL(MP4RtpPacket, MP4RtpPacket*)
185 
186 class MP4RtpHint : public MP4Container {
187 public:
188     MP4RtpHint(MP4RtpHintTrack& track);
189 
190     ~MP4RtpHint();
191 
192     MP4RtpHintTrack& GetTrack() {
193         return m_track;
194     }
195 
196     uint16_t GetNumberOfPackets() {
197         return m_rtpPackets.Size();
198     }
199 
200     bool IsBFrame() {
201         return m_isBFrame;
202     }
203     void SetBFrame(bool isBFrame) {
204         m_isBFrame = isBFrame;
205     }
206 
207     uint32_t GetTimestampOffset() {
208         return m_timestampOffset;
209     }
210     void SetTimestampOffset(uint32_t timestampOffset) {
211         m_timestampOffset = timestampOffset;
212     }
213 
214     MP4RtpPacket* AddPacket();
215 
216     MP4RtpPacket* GetPacket(uint16_t index) {
217         return m_rtpPackets[index];
218     }
219 
220     MP4RtpPacket* GetCurrentPacket() {
221         if (m_rtpPackets.Size() == 0) {
222             return NULL;
223         }
224         return m_rtpPackets[m_rtpPackets.Size() - 1];
225     }
226 
227     void Read(MP4File& file);
228 
229     void Write(MP4File& file);
230 
231     void Dump(uint8_t indent, bool dumpImplicits);
232 
233 protected:
234     MP4RtpHintTrack&    m_track;
235     MP4RtpPacketArray   m_rtpPackets;
236 
237     // values when adding packets to a hint (write mode)
238     bool                m_isBFrame;
239     uint32_t            m_timestampOffset;
240 };
241 
242 class MP4RtpHintTrack : public MP4Track {
243 public:
244     MP4RtpHintTrack(MP4File& file, MP4Atom& trakAtom);
245 
246     ~MP4RtpHintTrack();
247 
248     void InitRefTrack();
249 
250     void InitPayload();
251 
252     void InitRtpStart();
253 
254     void InitStats();
255 
GetRefTrack()256     MP4Track* GetRefTrack() {
257         InitRefTrack();
258         return m_pRefTrack;
259     }
260 
261     void GetPayload(
262         char** ppPayloadName = NULL,
263         uint8_t* pPayloadNumber = NULL,
264         uint16_t* pMaxPayloadSize = NULL,
265         char **ppEncodingParams = NULL);
266 
267     void SetPayload(
268         const char* payloadName,
269         uint8_t payloadNumber,
270         uint16_t maxPayloadSize,
271         const char *encoding_parms,
272         bool add_rtpmap,
273         bool add_mpeg4_esid);
274 
275     void ReadHint(
276         MP4SampleId hintSampleId,
277         uint16_t* pNumPackets = NULL);
278 
279     uint16_t GetHintNumberOfPackets();
280 
281     bool GetPacketBFrame(uint16_t packetIndex);
282 
283     uint16_t GetPacketTransmitOffset(uint16_t packetIndex);
284 
285     void ReadPacket(
286         uint16_t packetIndex,
287         uint8_t** ppBytes,
288         uint32_t* pNumBytes,
289         uint32_t ssrc,
290         bool includeHeader = true,
291         bool includePayload = true);
292 
293     MP4Timestamp GetRtpTimestampStart();
294 
295     void SetRtpTimestampStart(MP4Timestamp start);
296 
297     void AddHint(bool isBFrame, uint32_t timestampOffset);
298 
299     void AddPacket(bool setMbit, int32_t transmitOffset = 0);
300 
301     void AddImmediateData(const uint8_t* pBytes, uint32_t numBytes);
302 
303     void AddSampleData(MP4SampleId sampleId,
304                        uint32_t dataOffset, uint32_t dataLength);
305 
306     void AddESConfigurationPacket();
307 
308     void WriteHint(MP4Duration duration, bool isSyncSample);
309 
310     void FinishWrite(uint32_t options = 0);
311 
312 protected:
313     MP4Track*   m_pRefTrack;
314 
315     MP4StringProperty*      m_pRtpMapProperty;
316     MP4Integer32Property*   m_pPayloadNumberProperty;
317     MP4Integer32Property*   m_pMaxPacketSizeProperty;
318     MP4Integer32Property*   m_pSnroProperty;
319     MP4Integer32Property*   m_pTsroProperty;
320     uint32_t                m_rtpSequenceStart;
321     uint32_t                m_rtpTimestampStart;
322 
323     // reading
324     MP4RtpHint* m_pReadHint;
325     uint8_t*    m_pReadHintSample;
326     uint32_t    m_readHintSampleSize;
327     MP4Timestamp m_readHintTimestamp;
328 
329     // writing
330     MP4RtpHint* m_pWriteHint;
331     MP4SampleId m_writeHintId;
332     uint32_t    m_writePacketId;
333 
334     // statistics
335     // in trak.udta.hinf
336     MP4Integer64Property*   m_pTrpy;
337     MP4Integer64Property*   m_pNump;
338     MP4Integer64Property*   m_pTpyl;
339     MP4Integer32Property*   m_pMaxr;
340     MP4Integer64Property*   m_pDmed;
341     MP4Integer64Property*   m_pDimm;
342     MP4Integer32Property*   m_pPmax;
343     MP4Integer32Property*   m_pDmax;
344 
345     // in trak.mdia.minf.hmhd
346     MP4Integer16Property*   m_pMaxPdu;
347     MP4Integer16Property*   m_pAvgPdu;
348     MP4Integer32Property*   m_pMaxBitRate;
349     MP4Integer32Property*   m_pAvgBitRate;
350 
351     MP4Timestamp            m_thisSec;
352     uint32_t                m_bytesThisSec;
353     uint32_t                m_bytesThisHint;
354     uint32_t                m_bytesThisPacket;
355 };
356 
357 ///////////////////////////////////////////////////////////////////////////////
358 
359 }
360 } // namespace mp4v2::impl
361 
362 #endif // MP4V2_IMPL_RTPHINT_H
363