• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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