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 - 2004.  All Rights Reserved.
17  *
18  * 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
19  * and was contributed by Ximpo Group Ltd.
20  *
21  * Portions created by Ximpo Group Ltd. are
22  * Copyright (C) Ximpo Group Ltd. 2003, 2004.  All Rights Reserved.
23  *
24  * Contributor(s):
25  *      Dave Mackie     dmackie@cisco.com
26  *              Ximpo Group Ltd.        mp4v2@ximpo.com
27  */
28 
29 #ifndef MP4V2_IMPL_MP4TRACK_H
30 #define MP4V2_IMPL_MP4TRACK_H
31 
32 namespace mp4v2 { namespace impl {
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 typedef uint32_t MP4ChunkId;
37 
38 // forward declarations
39 class MP4File;
40 class MP4Atom;
41 class MP4Property;
42 class MP4IntegerProperty;
43 class MP4Integer8Property;
44 class MP4Integer16Property;
45 class MP4Integer32Property;
46 class MP4Integer64Property;
47 class MP4StringProperty;
48 
49 class MP4Track
50 {
51 public:
52     MP4Track(MP4File& file, MP4Atom& trakAtom);
53 
54     virtual ~MP4Track();
55 
GetId()56     MP4TrackId GetId() {
57         return m_trackId;
58     }
59 
60     const char* GetType();
61 
62     void SetType(const char* type);
63 
GetFile()64     MP4File& GetFile() {
65         return m_File;
66     }
67 
GetTrakAtom()68     MP4Atom& GetTrakAtom() {
69         return m_trakAtom;
70     }
71 
72     void ReadSample(
73         // input parameters
74         MP4SampleId sampleId,
75         // output parameters
76         uint8_t**     ppBytes,
77         uint32_t*     pNumBytes,
78         MP4Timestamp* pStartTime = NULL,
79         MP4Duration*  pDuration = NULL,
80         MP4Duration*  pRenderingOffset = NULL,
81         bool*         pIsSyncSample = NULL,
82         bool*         hasDependencyFlags = NULL,
83         uint32_t*     dependencyFlags = NULL );
84 
85     void WriteSample(
86         const uint8_t* pBytes,
87         uint32_t numBytes,
88         MP4Duration duration = 0,
89         MP4Duration renderingOffset = 0,
90         bool isSyncSample = true);
91 
92     void WriteSampleDependency(
93         const uint8_t* pBytes,
94         uint32_t       numBytes,
95         MP4Duration    duration,
96         MP4Duration    renderingOffset,
97         bool           isSyncSample,
98         uint32_t       dependencyFlags );
99 
100     virtual void FinishWrite(uint32_t options = 0);
101 
102     uint64_t    GetDuration();      // in track timeScale units
103     uint32_t    GetTimeScale();
104     uint32_t    GetNumberOfSamples();
105     uint32_t    GetSampleSize(MP4SampleId sampleId);
106     uint32_t    GetMaxSampleSize();
107     uint64_t    GetTotalOfSampleSizes();
108     uint32_t    GetAvgBitrate();    // in bps
109     uint32_t    GetMaxBitrate();    // in bps
110 
111     MP4Duration GetFixedSampleDuration();
112     void        SetFixedSampleDuration(MP4Duration duration);
113 
114     void        GetSampleTimes(MP4SampleId sampleId,
115                                MP4Timestamp* pStartTime, MP4Duration* pDuration);
116 
117     bool        IsSyncSample(MP4SampleId sampleId);
118 
119     MP4SampleId GetSampleIdFromTime(
120         MP4Timestamp when,
121         bool wantSyncSample = false);
122 
123     MP4Duration GetSampleRenderingOffset(MP4SampleId sampleId);
124     void        SetSampleRenderingOffset(MP4SampleId sampleId,
125                                          MP4Duration renderingOffset);
126 
127     MP4EditId   AddEdit(
128         MP4EditId editId = MP4_INVALID_EDIT_ID);
129 
130     void        DeleteEdit(
131         MP4EditId editId);
132 
133     MP4Timestamp GetEditStart(
134         MP4EditId editId);
135 
136     MP4Timestamp GetEditTotalDuration(
137         MP4EditId editId);
138 
139     MP4SampleId GetSampleIdFromEditTime(
140         MP4Timestamp editWhen,
141         MP4Timestamp* pStartTime = NULL,
142         MP4Duration* pDuration = NULL);
143 
144     // special operation for use during hint track packet assembly
145     void ReadSampleFragment(
146         MP4SampleId sampleId,
147         uint32_t sampleOffset,
148         uint16_t sampleLength,
149         uint8_t* pDest);
150 
151     // special operations for use during optimization
152 
153     uint32_t GetNumberOfChunks();
154 
155     MP4Timestamp GetChunkTime(MP4ChunkId chunkId);
156 
157     void ReadChunk(MP4ChunkId chunkId,
158                    uint8_t** ppChunk, uint32_t* pChunkSize);
159 
160     void RewriteChunk(MP4ChunkId chunkId,
161                       uint8_t* pChunk, uint32_t chunkSize);
162 
163     MP4Duration GetDurationPerChunk();
164     void        SetDurationPerChunk( MP4Duration );
165 
166 protected:
167     bool        InitEditListProperties();
168 
169     File*       GetSampleFile( MP4SampleId sampleId );
170     uint64_t    GetSampleFileOffset(MP4SampleId sampleId);
171     uint32_t    GetSampleStscIndex(MP4SampleId sampleId);
172     uint32_t    GetChunkStscIndex(MP4ChunkId chunkId);
173     uint32_t    GetChunkSize(MP4ChunkId chunkId);
174     uint32_t    GetSampleCttsIndex(MP4SampleId sampleId,
175                                    MP4SampleId* pFirstSampleId = NULL);
176     MP4SampleId GetNextSyncSample(MP4SampleId sampleId);
177 
178     void UpdateSampleSizes(MP4SampleId sampleId,
179                            uint32_t numBytes);
180     bool IsChunkFull(MP4SampleId sampleId);
181     void UpdateSampleToChunk(MP4SampleId sampleId,
182                              MP4ChunkId chunkId, uint32_t samplesPerChunk);
183     void UpdateChunkOffsets(uint64_t chunkOffset);
184     void UpdateSampleTimes(MP4Duration duration);
185     void UpdateRenderingOffsets(MP4SampleId sampleId,
186                                 MP4Duration renderingOffset);
187     void UpdateSyncSamples(MP4SampleId sampleId,
188                            bool isSyncSample);
189 
190     MP4Atom* AddAtom(const char* parentName, const char* childName);
191 
192     void UpdateDurations(MP4Duration duration);
193     MP4Duration ToMovieDuration(MP4Duration trackDuration);
194 
195     void UpdateModificationTimes();
196 
197     void WriteChunkBuffer();
198 
199     void CalculateBytesPerSample();
200 
201     void FinishSdtp();
202 
203 protected:
204     MP4File&    m_File;
205     MP4Atom&    m_trakAtom;         // moov.trak[]
206     MP4TrackId  m_trackId;          // moov.trak[].tkhd.trackId
207     MP4StringProperty* m_pTypeProperty; // moov.trak[].mdia.hdlr.handlerType
208 
209     uint32_t m_lastStsdIndex;
210     File*    m_lastSampleFile;
211 
212     // for efficient construction of hint track packets
213     MP4SampleId m_cachedReadSampleId;
214     uint8_t*    m_pCachedReadSample;
215     uint32_t    m_cachedReadSampleSize;
216 
217     // for writing
218     MP4SampleId m_writeSampleId;
219     MP4Duration m_fixedSampleDuration;
220     uint8_t*    m_pChunkBuffer;
221     uint32_t    m_chunkBufferSize;          // Actual size of our chunk buffer.
222     uint32_t    m_sizeOfDataInChunkBuffer;  // Size of the data in the chunk buffer.
223     uint32_t    m_chunkSamples;
224     MP4Duration m_chunkDuration;
225 
226     // controls for chunking
227     uint32_t    m_samplesPerChunk;
228     MP4Duration m_durationPerChunk;
229 
230     uint32_t       m_bytesPerSample;
231 
232     // controls for AMR chunking
233     int     m_isAmr;
234     uint8_t m_curMode;
235 
236     MP4Integer32Property* m_pTimeScaleProperty;
237     MP4IntegerProperty* m_pTrackDurationProperty;       // 32 or 64 bits
238     MP4IntegerProperty* m_pMediaDurationProperty;       // 32 or 64 bits
239     MP4IntegerProperty* m_pTrackModificationProperty;   // 32 or 64 bits
240     MP4IntegerProperty* m_pMediaModificationProperty;   // 32 or 64 bits
241 
242     MP4Integer32Property* m_pStszFixedSampleSizeProperty;
243     MP4Integer32Property* m_pStszSampleCountProperty;
244 
245     void SampleSizePropertyAddValue(uint32_t bytes);
246     uint8_t m_stsz_sample_bits;
247     bool m_have_stz2_4bit_sample;
248     uint8_t m_stz2_4bit_sample_value;
249     MP4IntegerProperty* m_pStszSampleSizeProperty;
250 
251     MP4Integer32Property* m_pStscCountProperty;
252     MP4Integer32Property* m_pStscFirstChunkProperty;
253     MP4Integer32Property* m_pStscSamplesPerChunkProperty;
254     MP4Integer32Property* m_pStscSampleDescrIndexProperty;
255     MP4Integer32Property* m_pStscFirstSampleProperty;
256 
257     MP4Integer32Property* m_pChunkCountProperty;
258     MP4IntegerProperty*   m_pChunkOffsetProperty;       // 32 or 64 bits
259 
260     MP4Integer32Property* m_pSttsCountProperty;
261     MP4Integer32Property* m_pSttsSampleCountProperty;
262     MP4Integer32Property* m_pSttsSampleDeltaProperty;
263 
264     // for improve sequental timestamp index access
265     uint32_t    m_cachedSttsIndex;
266     MP4SampleId m_cachedSttsSid;
267     MP4Timestamp    m_cachedSttsElapsed;
268 
269     uint32_t    m_cachedCttsIndex;
270     MP4SampleId m_cachedCttsSid;
271 
272     MP4Integer32Property* m_pCttsCountProperty;
273     MP4Integer32Property* m_pCttsSampleCountProperty;
274     MP4Integer32Property* m_pCttsSampleOffsetProperty;
275 
276     MP4Integer32Property* m_pStssCountProperty;
277     MP4Integer32Property* m_pStssSampleProperty;
278 
279     MP4Integer32Property* m_pElstCountProperty;
280     MP4IntegerProperty*   m_pElstMediaTimeProperty;     // 32 or 64 bits
281     MP4IntegerProperty*   m_pElstDurationProperty;      // 32 or 64 bits
282     MP4Integer16Property* m_pElstRateProperty;
283     MP4Integer16Property* m_pElstReservedProperty;
284 
285     string m_sdtpLog; // records frame types for H264 samples
286 };
287 
288 MP4ARRAY_DECL(MP4Track, MP4Track*);
289 
290 ///////////////////////////////////////////////////////////////////////////////
291 
292 }} // namespace mp4v2::impl
293 
294 #endif // MP4V2_IMPL_MP4TRACK_H
295