1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /*********************************************************************************/
19 /* ------------------------------------------------------------------- */
20 /* MPEG-4 TrackAtom Class */
21 /* ------------------------------------------------------------------- */
22 /*********************************************************************************/
23 /*
24 This TrackAtom Class is the container for a single track in the MPEG-4
25 presentation.
26 */
27
28 #define IMPLEMENT_TrackAtom
29
30 #include "movieatom.h"
31 #include "trackatom.h"
32 #include "atomdefs.h"
33 #include "atomutils.h"
34
getObjectTypeIndication()35 OSCL_EXPORT_REF uint8 TrackAtom::getObjectTypeIndication()
36 {
37 if (_pmediaAtom != NULL)
38 {
39 return _pmediaAtom->getObjectTypeIndication();
40 }
41 else
42 {
43 return 0xFF;
44 }
45 } // Based on OTI value
46
47 // Constructor
TrackAtom(MP4_FF_FILE * fp,OSCL_wString & filename,uint32 size,uint32 type,bool oPVContent,bool oPVContentDownloadable,uint32 parsingMode)48 TrackAtom::TrackAtom(MP4_FF_FILE *fp,
49 OSCL_wString& filename,
50 uint32 size,
51 uint32 type,
52 bool oPVContent,
53 bool oPVContentDownloadable,
54 uint32 parsingMode)
55 : Atom(fp, size, type)
56 {
57
58 _ptrackHeader = NULL;
59 _ptrackReference = NULL;
60 _pmediaAtom = NULL;
61 _puserdataatom = NULL;
62 _pEditAtom = NULL;
63
64 if (_success)
65 {
66 // Generalized so can read in atoms in ANY ORDER!
67 _pparent = NULL;
68 _ptrackReference = NULL;
69
70 uint32 atomType = UNKNOWN_ATOM;
71 uint32 atomSize = 0;
72
73 int32 count = _size - DEFAULT_ATOM_SIZE;
74
75 while (((atomType == TRACK_REFERENCE_ATOM) ||
76 (atomType == TRACK_HEADER_ATOM) ||
77 (atomType == MEDIA_ATOM) ||
78 (atomType == USER_DATA_ATOM) ||
79 (atomType == EDIT_ATOM) ||
80 (atomType == FREE_SPACE_ATOM) ||
81
82 (atomType == UUID_ATOM) ||
83 (atomType == UNKNOWN_ATOM))
84 && (count > 0))
85 {
86 AtomUtils::getNextAtomType(fp, atomSize, atomType);
87
88 if (atomType == EDIT_ATOM)
89 {
90 PV_MP4_FF_NEW(fp->auditCB, EditAtom, (fp, atomSize, atomType), _pEditAtom);
91
92 if (!_pEditAtom->MP4Success())
93 {
94 _success = false;
95 _mp4ErrorCode = _pEditAtom->GetMP4Error();
96 break;
97 }
98
99 count -= _pEditAtom->getSize();
100 }
101 else if ((atomType == FREE_SPACE_ATOM)
102 || (atomType == UUID_ATOM)
103 || (atomType == UNKNOWN_ATOM))
104 {
105 if (atomSize < DEFAULT_ATOM_SIZE)
106 {
107 _success = false;
108 _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
109 break;
110 }
111 if (count < (int32)atomSize)
112 {
113 _success = false;
114 _mp4ErrorCode = READ_FAILED;
115 break;
116 }
117 count -= atomSize;
118 atomSize -= DEFAULT_ATOM_SIZE;
119 AtomUtils::seekFromCurrPos(fp, atomSize);
120 }
121 else if (atomType == USER_DATA_ATOM)
122 {
123 if (oPVContent)
124 {
125 if (_puserdataatom == NULL)
126 {
127 PV_MP4_FF_NEW(fp->auditCB, UserDataAtom, (fp, atomSize, atomType), _puserdataatom);
128 if (!_puserdataatom->MP4Success())
129 {
130 _success = false;
131 _mp4ErrorCode = _puserdataatom->GetMP4Error();
132 break;
133 }
134 count -= _puserdataatom->getSize();
135 }
136 else
137 {
138 _success = false;
139 _mp4ErrorCode = READ_USER_DATA_ATOM_FAILED;
140 break;
141 }
142 }
143 else
144 {
145 //Skip third party user data atom
146 if (atomSize < DEFAULT_ATOM_SIZE)
147 {
148 _success = false;
149 _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
150 break;
151 }
152 if (count < (int32)atomSize)
153 {
154 _success = false;
155 _mp4ErrorCode = READ_FAILED;
156 break;
157 }
158 count -= atomSize;
159 atomSize -= DEFAULT_ATOM_SIZE;
160 AtomUtils::seekFromCurrPos(fp, atomSize);
161 }
162 }
163 else if (atomType == TRACK_REFERENCE_ATOM)
164 {
165 // tref
166 if (_ptrackReference != NULL)
167 {
168 _success = false;
169 _mp4ErrorCode = DUPLICATE_TRACK_REFERENCE_ATOMS;
170 break;
171 }
172 PV_MP4_FF_NEW(fp->auditCB, TrackReferenceAtom, (fp, atomSize, atomType), _ptrackReference);
173 if (!_ptrackReference->MP4Success())
174 {
175 _success = false;
176 _mp4ErrorCode = _ptrackReference->GetMP4Error();
177 break;
178 }
179 _ptrackReference->setParent(this);
180 count -= _ptrackReference->getSize();
181 }
182 else if (atomType == TRACK_HEADER_ATOM)
183 {
184 // tkhd
185 if (_ptrackHeader != NULL)
186 {
187 _success = false;
188 _mp4ErrorCode = DUPLICATE_TRACK_HEADER_ATOMS;
189 break;
190 }
191 PV_MP4_FF_NEW(fp->auditCB, TrackHeaderAtom, (fp, atomSize, atomType), _ptrackHeader);
192
193 if (!_ptrackHeader->MP4Success())
194 {
195 _success = false;
196 _mp4ErrorCode = _ptrackHeader->GetMP4Error();
197 break;
198 }
199 _ptrackHeader->setParent(this);
200 count -= _ptrackHeader->getSize();
201 }
202 else if (atomType == MEDIA_ATOM)
203 { // mdia
204 if (_pmediaAtom != NULL)
205 {
206 _success = false;
207 _mp4ErrorCode = DUPLICATE_MEDIA_ATOMS;
208 break;
209 }
210 PV_MP4_FF_NEW(fp->auditCB, MediaAtom, (fp, filename, atomSize, atomType, oPVContentDownloadable, parsingMode), _pmediaAtom);
211
212 if (!_pmediaAtom->MP4Success())
213 {
214 _success = false;
215 _mp4ErrorCode = _pmediaAtom->GetMP4Error();
216 break;
217 }
218 _pmediaAtom->setParent(this);
219 count -= _pmediaAtom->getSize();
220 }
221 }
222
223 if (_success)
224 {
225 if (NULL == _ptrackHeader)
226 {
227 _success = false;
228 _mp4ErrorCode = NO_TRACK_HEADER_ATOM_PRESENT;
229 return;
230 }
231
232 if (NULL == _pmediaAtom)
233 {
234 _success = false;
235 _mp4ErrorCode = NO_MEDIA_ATOM_PRESENT;
236 return;
237 }
238 _pMediaType =
239 AtomUtils::getMediaTypeFromHandlerType(_pmediaAtom->getMediaHandlerType());
240 }
241 }
242 else
243 {
244 _mp4ErrorCode = READ_TRACK_ATOM_FAILED;
245 }
246 }
247
NEWsetTrackTSOffset(uint32 ts)248 int32 TrackAtom::NEWsetTrackTSOffset(uint32 ts)
249 {
250 if (_pmediaAtom != NULL)
251 {
252 if (_pEditAtom != NULL)
253 {
254 uint32 initTimeOffset = (uint32)(_pEditAtom->getInitialTimeOffset());
255
256 float fTS = (float)_pmediaAtom->getMediaTimescale();
257 fTS *= (float)initTimeOffset;
258 fTS /= (float)ts;
259 _pmediaAtom->setTrackTSOffset((uint32)(fTS));
260 }
261 }
262 return EVERYTHING_FINE;
263 }
264
getTrackTSOffset(uint32 & aTSOffset,uint32 aMovieTimeScale)265 int32 TrackAtom::getTrackTSOffset(uint32& aTSOffset, uint32 aMovieTimeScale)
266 {
267 aTSOffset = 0;
268 if (_pmediaAtom != NULL)
269 {
270 if (_pEditAtom != NULL)
271 {
272 uint32 initTimeOffset = (uint32)(_pEditAtom->getInitialTimeOffset());
273
274 float fTS = (float)_pmediaAtom->getMediaTimescale();
275 fTS *= (float)initTimeOffset;
276 fTS /= (float)aMovieTimeScale;
277 aTSOffset = (uint32)(fTS);
278 }
279 }
280 return EVERYTHING_FINE;
281 }
282
283 // Destructor
~TrackAtom()284 TrackAtom::~TrackAtom()
285 {
286 if (_ptrackHeader != NULL)
287 PV_MP4_FF_DELETE(NULL, TrackHeaderAtom, _ptrackHeader);
288
289 if (_pmediaAtom != NULL)
290 PV_MP4_FF_DELETE(NULL, MediaAtom, _pmediaAtom);
291
292 if (_puserdataatom != NULL)
293 PV_MP4_FF_DELETE(NULL, UserDataAtom, _puserdataatom);
294
295 if (_ptrackReference != NULL)
296 PV_MP4_FF_DELETE(NULL, TrackReferenceAtom, _ptrackReference);
297
298 if (_pEditAtom != NULL)
299 PV_MP4_FF_DELETE(NULL, EditAtom, _pEditAtom);
300 }
301
302
303
304
305
306
307