1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001 - 2004. All Rights Reserved.
*
* 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
* and was contributed by Ximpo Group Ltd.
*
* Portions created by Ximpo Group Ltd. are
* Copyright (C) Ximpo Group Ltd. 2003, 2004. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
* Ximpo Group Ltd. mp4v2@ximpo.com
*/
#ifndef __MP4_TRACK_INCLUDED__
#define __MP4_TRACK_INCLUDED__
#include "mp4property.h"
// forward declarations
class MP4File;
class MP4Atom;
class MP4Property;
class MP4StringProperty;
class MP4Track {
public:
MP4Track(MP4File* pFile, MP4Atom* pTrakAtom);
virtual ~MP4Track();
MP4TrackId GetId() {
return m_trackId;
}
const char* GetType();
void SetType(const char* type);
MP4File* GetFile() {
return m_pFile;
}
MP4Atom* GetTrakAtom() {
return m_pTrakAtom;
}
void ReadSample(
// input parameters
MP4SampleId sampleId,
// output parameters
u_int8_t** ppBytes,
u_int32_t* pNumBytes,
MP4Timestamp* pStartTime = NULL,
MP4Duration* pDuration = NULL,
MP4Duration* pRenderingOffset = NULL,
bool* pIsSyncSample = NULL);
void WriteSample(
const u_int8_t* pBytes,
u_int32_t numBytes,
MP4Duration duration = 0,
MP4Duration renderingOffset = 0,
bool isSyncSample = true);
virtual void FinishWrite();
u_int64_t GetDuration(); // in track timeScale units
u_int32_t GetTimeScale();
u_int32_t GetNumberOfSamples();
u_int32_t GetSampleSize(MP4SampleId sampleId);
u_int32_t GetMaxSampleSize();
u_int64_t GetTotalOfSampleSizes();
u_int32_t GetAvgBitrate(); // in bps
u_int32_t GetMaxBitrate(); // in bps
MP4Duration GetFixedSampleDuration();
void SetFixedSampleDuration(MP4Duration duration);
void GetSampleTimes(MP4SampleId sampleId,
MP4Timestamp* pStartTime, MP4Duration* pDuration);
bool IsSyncSample(MP4SampleId sampleId);
MP4SampleId GetSampleIdFromTime(
MP4Timestamp when,
bool wantSyncSample = false,
bool rewind = false);
MP4ChunkId GetChunkIdFromTime(MP4Timestamp when);
MP4Duration GetSampleRenderingOffset(MP4SampleId sampleId);
void SetSampleRenderingOffset(MP4SampleId sampleId,
MP4Duration renderingOffset);
MP4EditId AddEdit(
MP4EditId editId = MP4_INVALID_EDIT_ID);
void DeleteEdit(
MP4EditId editId);
MP4Timestamp GetEditStart(
MP4EditId editId);
MP4Timestamp GetEditTotalDuration(
MP4EditId editId);
MP4SampleId GetSampleIdFromEditTime(
MP4Timestamp editWhen,
MP4Timestamp* pStartTime = NULL,
MP4Duration* pDuration = NULL);
// special operation for use during hint track packet assembly
void ReadSampleFragment(
MP4SampleId sampleId,
u_int32_t sampleOffset,
u_int16_t sampleLength,
u_int8_t* pDest);
// special operations for use during optimization
u_int32_t GetNumberOfChunks();
MP4Timestamp GetChunkTime(MP4ChunkId chunkId);
void ReadChunk(MP4ChunkId chunkId,
u_int8_t** ppChunk, u_int32_t* pChunkSize,
MP4Timestamp* pStartTime = NULL,
MP4Duration* pDuration = NULL);
void RewriteChunk(MP4ChunkId chunkId,
u_int8_t* pChunk, u_int32_t chunkSize);
protected:
bool InitEditListProperties();
FILE* GetSampleFile(MP4SampleId sampleId);
u_int64_t GetSampleFileOffset(MP4SampleId sampleId);
u_int32_t GetSampleStscIndex(MP4SampleId sampleId);
u_int32_t GetChunkStscIndex(MP4ChunkId chunkId);
u_int32_t GetChunkSize(MP4ChunkId chunkId);
u_int32_t GetSampleCttsIndex(MP4SampleId sampleId,
MP4SampleId* pFirstSampleId = NULL);
MP4SampleId GetNextSyncSample(MP4SampleId sampleId);
MP4SampleId GetSyncSample(MP4SampleId sampleId, bool rewind = false);
void UpdateSampleSizes(MP4SampleId sampleId,
u_int32_t numBytes);
bool IsChunkFull(MP4SampleId sampleId);
void UpdateSampleToChunk(MP4SampleId sampleId,
MP4ChunkId chunkId, u_int32_t samplesPerChunk);
void UpdateChunkOffsets(u_int64_t chunkOffset);
void UpdateSampleTimes(MP4Duration duration);
void UpdateRenderingOffsets(MP4SampleId sampleId,
MP4Duration renderingOffset);
void UpdateSyncSamples(MP4SampleId sampleId,
bool isSyncSample);
MP4Atom* AddAtom(char* parentName, char* childName);
void UpdateDurations(MP4Duration duration);
MP4Duration ToMovieDuration(MP4Duration trackDuration);
void UpdateModificationTimes();
void WriteChunkBuffer();
void CalculateBytesPerSample();
protected:
MP4File* m_pFile;
MP4Atom* m_pTrakAtom; // moov.trak[]
MP4TrackId m_trackId; // moov.trak[].tkhd.trackId
MP4StringProperty* m_pTypeProperty; // moov.trak[].mdia.hdlr.handlerType
u_int32_t m_lastStsdIndex;
FILE* m_lastSampleFile;
// for efficient construction of hint track packets
MP4SampleId m_cachedReadSampleId;
u_int8_t* m_pCachedReadSample;
u_int32_t m_cachedReadSampleSize;
// for writing
MP4SampleId m_writeSampleId;
MP4Duration m_fixedSampleDuration;
u_int8_t* m_pChunkBuffer;
u_int32_t m_chunkBufferSize;
u_int32_t m_chunkSamples;
MP4Duration m_chunkDuration;
// controls for chunking
u_int32_t m_samplesPerChunk;
MP4Duration m_durationPerChunk;
u_int32_t m_bytesPerSample;
// controls for AMR chunking
int m_isAmr;
u_int8_t m_curMode;
MP4Integer32Property* m_pTimeScaleProperty;
MP4IntegerProperty* m_pTrackDurationProperty; // 32 or 64 bits
MP4IntegerProperty* m_pMediaDurationProperty; // 32 or 64 bits
MP4IntegerProperty* m_pTrackModificationProperty; // 32 or 64 bits
MP4IntegerProperty* m_pMediaModificationProperty; // 32 or 64 bits
MP4Integer32Property* m_pStszFixedSampleSizeProperty;
MP4Integer32Property* m_pStszSampleCountProperty;
void SampleSizePropertyAddValue(uint32_t bytes);
uint8_t m_stsz_sample_bits;
bool m_have_stz2_4bit_sample;
uint8_t m_stz2_4bit_sample_value;
MP4IntegerProperty* m_pStszSampleSizeProperty;
MP4Integer32Property* m_pStscCountProperty;
MP4Integer32Property* m_pStscFirstChunkProperty;
MP4Integer32Property* m_pStscSamplesPerChunkProperty;
MP4Integer32Property* m_pStscSampleDescrIndexProperty;
MP4Integer32Property* m_pStscFirstSampleProperty;
MP4Integer32Property* m_pChunkCountProperty;
MP4IntegerProperty* m_pChunkOffsetProperty; // 32 or 64 bits
MP4Integer32Property* m_pSttsCountProperty;
MP4Integer32Property* m_pSttsSampleCountProperty;
MP4Integer32Property* m_pSttsSampleDeltaProperty;
// for improve sequental timestamp index access
u_int32_t m_cachedSttsIndex;
MP4SampleId m_cachedSttsSid;
MP4Timestamp m_cachedSttsElapsed;
MP4Integer32Property* m_pCttsCountProperty;
MP4Integer32Property* m_pCttsSampleCountProperty;
MP4Integer32Property* m_pCttsSampleOffsetProperty;
MP4Integer32Property* m_pStssCountProperty;
MP4Integer32Property* m_pStssSampleProperty;
MP4Integer32Property* m_pElstCountProperty;
MP4IntegerProperty* m_pElstMediaTimeProperty; // 32 or 64 bits
MP4IntegerProperty* m_pElstDurationProperty; // 32 or 64 bits
MP4Integer16Property* m_pElstRateProperty;
MP4Integer16Property* m_pElstReservedProperty;
};
MP4ARRAY_DECL(MP4Track, MP4Track*);
#endif /* __MP4_TRACK_INCLUDED__ */
|