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 #define IMPLEMENT_TrackFragmentRunAtom
19
20 #include "trackfragmentrunatom.h"
21 #include "atomutils.h"
22 #include "atomdefs.h"
23
24 typedef Oscl_Vector<TFrunSampleTable*, OsclMemAllocator> _pTFrunSampleTableVecType;
25
TFrunSampleTable(MP4_FF_FILE * fp,uint32 tr_flag,uint32 base_data_offset,uint64 sampleTS)26 TFrunSampleTable::TFrunSampleTable(MP4_FF_FILE *fp , uint32 tr_flag, uint32 base_data_offset,
27 uint64 sampleTS)
28 {
29 _sample_duration = 0;
30 _sample_size = 0;
31 _sample_flags = 0;
32 _sample_composition_time_offset = 0;
33 _sample_offset = 0;
34 _sample_timestamp = sampleTS;
35 _sample_offset = base_data_offset;
36
37 if (tr_flag & 0x000100)
38 {
39 if (!AtomUtils::read32(fp, _sample_duration))
40 {
41 return;
42 }
43 }
44
45 if (tr_flag & 0x000200)
46 {
47 if (!AtomUtils::read32(fp, _sample_size))
48 {
49 return;
50 }
51 }
52
53 if (tr_flag & 0x000400)
54 {
55 if (!AtomUtils::read32(fp, _sample_flags))
56 {
57 return;
58 }
59 }
60
61 if (tr_flag & 0x000800)
62 {
63 if (!AtomUtils::read32(fp, _sample_composition_time_offset))
64 {
65 return;
66 }
67 }
68 }
69
TrackFragmentRunAtom(MP4_FF_FILE * fp,uint32 size,uint32 type,uint32 baseDataOffset,uint32 & currentTrunOffset,uint32 & offset,uint64 trackDuration,bool bdo_present,bool & trunParsingCompleted,uint32 & countOfTrunsParsed)70 TrackFragmentRunAtom ::TrackFragmentRunAtom(MP4_FF_FILE *fp, uint32 size, uint32 type,
71 uint32 baseDataOffset,
72 uint32 ¤tTrunOffset,
73 uint32 &offset,
74 uint64 trackDuration,
75 bool bdo_present,
76 bool &trunParsingCompleted,
77 uint32 &countOfTrunsParsed)
78 : FullAtom(fp, size, type)
79 {
80 OSCL_UNUSED_ARG(type);
81 _data_offset = 0;
82 _sample_count = 0;
83 _first_sample_flags = 0;
84 _sampleTimeStamp = trackDuration;
85 tr_flag = getFlags();
86 _trun_start_offset = currentTrunOffset;
87 _samplesToBeParsed = 0;
88 _partialTrunOffset = 0;
89
90 iLogger = PVLogger::GetLoggerObject("mp4ffparser");
91 iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
92 iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
93
94 if (_success)
95 {
96 if (!AtomUtils::read32(fp, _sample_count))
97 {
98 _success = false;
99 _mp4ErrorCode = READ_TRACK_FRAGMENT_RUN_ATOM_FAILED;
100 return;
101 }
102
103 if (tr_flag & 0x000001)
104 {
105 if (!AtomUtils::read32(fp, _data_offset))
106 {
107 _success = false;
108 _mp4ErrorCode = READ_TRACK_FRAGMENT_RUN_ATOM_FAILED;
109 return;
110 }
111 _trun_start_offset = baseDataOffset;
112 _trun_start_offset += _data_offset;
113 }
114 else if (bdo_present)
115 {
116 }
117 else
118 {
119 _trun_start_offset += offset;
120 }
121
122 if (tr_flag & 0x000004)
123 {
124 if (!AtomUtils::read32(fp, _first_sample_flags))
125 {
126 _success = false;
127 _mp4ErrorCode = READ_TRACK_FRAGMENT_RUN_ATOM_FAILED;
128 return;
129 }
130 }
131
132 if (_sample_count > 0)
133 {
134 PV_MP4_FF_NEW(fp->auditCB, _pTFrunSampleTableVecType, (), _pTFrunSampleTable);
135 _pTFrunSampleTable->reserve(_sample_count);
136 _samplesToBeParsed = _sample_count;
137 }
138
139 if ((countOfTrunsParsed > COUNT_OF_TRUNS_PARSED_THRESHOLD) && (_sample_count > 25))
140 {
141 if (trunParsingCompleted)
142 {
143 trunParsingCompleted = false;
144 _samplesToBeParsed = _sample_count / 2;
145 if (_sample_count % 2 != 0)
146 {
147 _samplesToBeParsed += 1;
148 }
149 }
150 else
151 {
152 trunParsingCompleted = true;
153 _samplesToBeParsed = _sample_count - _samplesToBeParsed;
154 }
155 }
156
157 uint32 sigmaSampleSize = 0;
158 uint32 sample_offset = _trun_start_offset;
159 for (uint32 idx = 0; idx < _samplesToBeParsed ; idx++)
160 {
161 TFrunSampleTable *pTFrunSampleTable = NULL;
162 PV_MP4_FF_NEW(fp->auditCB, TFrunSampleTable, (fp, tr_flag, sample_offset, _sampleTimeStamp), pTFrunSampleTable);
163 _pTFrunSampleTable->push_back(pTFrunSampleTable);
164 if (pTFrunSampleTable != NULL)
165 {
166 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Number =%d", idx));
167 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Offset =%d", sample_offset));
168 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Sample Size =%d", pTFrunSampleTable->_sample_size));
169 sample_offset += pTFrunSampleTable->_sample_size;
170 sigmaSampleSize += pTFrunSampleTable->_sample_size;
171 _sampleTimeStamp += pTFrunSampleTable->_sample_duration;
172
173 }
174 }
175 offset = sigmaSampleSize;
176 currentTrunOffset = _trun_start_offset;
177 _partialTrunOffset = sample_offset;
178
179 if (trunParsingCompleted)
180 {
181 countOfTrunsParsed++;
182 }
183
184 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "###################################"));
185
186 }
187 }
188 // Destructor
~TrackFragmentRunAtom()189 TrackFragmentRunAtom::~TrackFragmentRunAtom()
190 {
191 if (_pTFrunSampleTable != NULL)
192 {
193 // CLEAN UP VECTOR!!
194 for (uint32 i = 0; i < _pTFrunSampleTable->size(); i++)
195 {
196 PV_MP4_FF_DELETE(NULL, TFrunSampleTable, (*_pTFrunSampleTable)[i]);
197 }
198 PV_MP4_FF_TEMPLATED_DELETE(NULL, _pTFrunSampleTableVecType, Oscl_Vector, _pTFrunSampleTable);
199 }
200
201 }
202
ParseTrunAtom(MP4_FF_FILE * fp,uint32 & offset,bool & trunParsingCompleted,uint32 & countOfTrunsParsed)203 void TrackFragmentRunAtom::ParseTrunAtom(MP4_FF_FILE *fp,
204 uint32 &offset,
205 bool &trunParsingCompleted,
206 uint32 &countOfTrunsParsed)
207 {
208 if (countOfTrunsParsed > COUNT_OF_TRUNS_PARSED_THRESHOLD)
209 {
210 if (trunParsingCompleted)
211 {
212 trunParsingCompleted = false;
213 _samplesToBeParsed = _sample_count / 2;
214 if (_sample_count % 2 != 0)
215 {
216 _samplesToBeParsed += 1;
217 }
218 }
219 else
220 {
221 trunParsingCompleted = true;
222 _samplesToBeParsed = _sample_count - _samplesToBeParsed;
223 }
224 }
225
226 uint32 sigmaSampleSize = 0;
227 uint32 sample_offset = _partialTrunOffset;
228 for (uint32 idx = 0; idx < _samplesToBeParsed ; idx++)
229 {
230 TFrunSampleTable *pTFrunSampleTable = NULL;
231 PV_MP4_FF_NEW(fp->auditCB, TFrunSampleTable, (fp, tr_flag, sample_offset, _sampleTimeStamp), pTFrunSampleTable);
232 _pTFrunSampleTable->push_back(pTFrunSampleTable);
233 if (pTFrunSampleTable != NULL)
234 {
235 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Number =%d", idx));
236 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Offset =%d", sample_offset));
237 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Sample Sample Size =%d", pTFrunSampleTable->_sample_size));
238 sample_offset += pTFrunSampleTable->_sample_size;
239 sigmaSampleSize += pTFrunSampleTable->_sample_size;
240 _sampleTimeStamp += pTFrunSampleTable->_sample_duration;
241
242 }
243 }
244 offset += sigmaSampleSize;
245
246 if (trunParsingCompleted)
247 {
248 countOfTrunsParsed++;
249 }
250 }
251
setDefaultDuration(uint32 default_duration)252 void TrackFragmentRunAtom::setDefaultDuration(uint32 default_duration)
253 {
254 for (uint32 idx = 0; idx < _sample_count ; idx++)
255 {
256 TFrunSampleTable *pTFrunSampleTable = NULL;
257 if (_pTFrunSampleTable != NULL)
258 {
259 pTFrunSampleTable = (*_pTFrunSampleTable)[idx];
260 pTFrunSampleTable->setDefaultDuration(Oscl_Int64_Utils::get_uint64_lower32(_sampleTimeStamp), default_duration);
261 _sampleTimeStamp += default_duration;
262 }
263 }
264
265 }
setSampleDurationAndTimeStampFromSampleNum(uint32 startSampleNum,uint32 startSampleTS,uint32 default_duration)266 void TrackFragmentRunAtom::setSampleDurationAndTimeStampFromSampleNum(uint32 startSampleNum, uint32 startSampleTS, uint32 default_duration)
267 {
268 _sampleTimeStamp = startSampleTS;
269 for (uint32 idx = startSampleNum; idx < _sample_count ; idx++)
270 {
271 TFrunSampleTable *pTFrunSampleTable = NULL;
272 if (_pTFrunSampleTable != NULL)
273 {
274 pTFrunSampleTable = (*_pTFrunSampleTable)[idx];
275 if (pTFrunSampleTable->_sample_duration != 0)
276 {
277 default_duration = pTFrunSampleTable->_sample_duration;
278 }
279 pTFrunSampleTable->setDefaultDuration(Oscl_Int64_Utils::get_uint64_lower32(_sampleTimeStamp), default_duration);
280 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Track Fragment Run=>Set Sample TS >>>>>>>>>>>>=%d", pTFrunSampleTable->_sample_timestamp));
281 _sampleTimeStamp += default_duration;
282 }
283 }
284
285 }
setDefaultSampleSize(uint32 default_samplesize,uint32 & sigmaSampleSize)286 void TrackFragmentRunAtom::setDefaultSampleSize(uint32 default_samplesize, uint32 &sigmaSampleSize)
287 {
288 uint32 sumSampleSize = 0;
289 uint32 sample_offset = _trun_start_offset;
290 for (uint32 idx = 0; idx < _sample_count ; idx++)
291 {
292 TFrunSampleTable *pTFrunSampleTable = NULL;
293 if (_pTFrunSampleTable != NULL)
294 {
295 pTFrunSampleTable = (*_pTFrunSampleTable)[idx];
296 pTFrunSampleTable->setDefaultSampleSize(sample_offset, default_samplesize);
297 sample_offset += default_samplesize;
298 sumSampleSize += default_samplesize;
299 }
300
301 }
302 sigmaSampleSize = sumSampleSize;
303 }
304
305