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 SampleToChunkAtom Class */
21 /* ------------------------------------------------------------------- */
22 /*********************************************************************************/
23 /*
24 This SampleSizeAtom Class contains the sample count and a table giving the
25 size of each sample.
26 */
27
28
29 #define IMPLEMENT_SampleToChunkAtom_H__
30
31 #include "sampletochunkatom.h"
32 #include "atomutils.h"
33 #include "atomdefs.h"
34
35 #define DEFAULT_MAX_NUM_SAMPLES_PER_CHUNK 20
36 #define DEFAULT_MAX_CHUNK_DATA_SIZE 10240; // 10KB
37
38 // Stream-in ctor
39 // Create and return a new SampleToChunkAtom by reading in from an ifstream
SampleToChunkAtom(MP4_FF_FILE * fp,uint32 size,uint32 type,OSCL_wString & filename,uint32 parsingMode)40 SampleToChunkAtom::SampleToChunkAtom(MP4_FF_FILE *fp, uint32 size, uint32 type, OSCL_wString& filename, uint32 parsingMode)
41 : FullAtom(fp, size, type)
42 {
43 _pfirstChunkVec = NULL;
44 _psamplesPerChunkVec = NULL;
45 _psampleDescriptionIndexVec = NULL;
46
47 _Index = 0;
48 _numChunksInRun = 0;
49 _majorGetIndex = 0;
50 _currGetChunk = -1;
51 _numGetChunksInRun = 0;
52 _currGetSampleCount = 0;
53 _firstGetSampleInCurrChunk = 0;
54 _numGetSamplesPerChunk = 0;
55 _currGetSDI = 0;
56
57 _majorPeekIndex = 0;
58 _currPeekChunk = -1;
59 _numPeekChunksInRun = 0;
60 _currPeekSampleCount = 0;
61 _firstPeekSampleInCurrChunk = 0;
62 _numPeekSamplesPerChunk = 0;
63 _currPeekSDI = 0;
64
65 _parsed_entry_cnt = 0;
66 _fileptr = NULL;
67
68 _stbl_buff_size = MAX_CACHED_TABLE_ENTRIES_FILE;
69 _next_buff_number = 0;
70 _curr_buff_number = 0;
71 _curr_entry_point = 0;
72 _stbl_fptr_vec = NULL;
73 _parsing_mode = parsingMode;
74
75 iLogger = PVLogger::GetLoggerObject("mp4ffparser");
76 iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
77 iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
78
79 if (_success)
80 {
81 _currentChunkNumber = 0;
82 _maxNumSamplesPerChunk = DEFAULT_MAX_NUM_SAMPLES_PER_CHUNK;
83 _maxChunkDataSize = DEFAULT_MAX_CHUNK_DATA_SIZE;
84
85 if (!AtomUtils::read32(fp, _entryCount))
86 {
87 _success = false;
88 }
89 PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "SampleToChunkAtom::SampleToChunkAtom- _entryCount =%d", _entryCount));
90 uint32 dataSize = _size - (DEFAULT_FULL_ATOM_SIZE + 4);
91
92 uint32 entrySize = (4 + 4 + 4);
93
94 if ((_entryCount*entrySize) > dataSize)
95 {
96 _success = false;
97 }
98
99 if (_success)
100 {
101 if (_entryCount > 0)
102 {
103 if (_parsing_mode)
104 {
105 if ((_entryCount > _stbl_buff_size)) // cahce size is 4K so that optimization should work if entry_count is greater than 4K
106 {
107
108 uint32 fptrBuffSize = (_entryCount / _stbl_buff_size) + 1;
109
110 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (fptrBuffSize), _stbl_fptr_vec);
111 if (_stbl_fptr_vec == NULL)
112 {
113 _success = false;
114 _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
115 return;
116 }
117
118 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _pfirstChunkVec);
119 if (_pfirstChunkVec == NULL)
120 {
121 _success = false;
122 _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
123 return;
124 }
125
126 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psamplesPerChunkVec);
127 if (_psamplesPerChunkVec == NULL)
128 {
129 _success = false;
130 _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
131 return;
132 }
133 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psampleDescriptionIndexVec);
134 if (_psampleDescriptionIndexVec == NULL)
135 {
136 _success = false;
137 _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
138 return;
139 }
140
141 {
142 OsclAny* ptr = (MP4_FF_FILE *)(oscl_malloc(sizeof(MP4_FF_FILE)));
143 if (ptr == NULL)
144 {
145 _success = false;
146 _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
147 return;
148 }
149 _fileptr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE());
150 _fileptr->_fileServSession = fp->_fileServSession;
151 _fileptr->_pvfile.SetCPM(fp->_pvfile.GetCPM());
152 if (AtomUtils::OpenMP4File(filename,
153 Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
154 _fileptr) != 0)
155 {
156 _success = false;
157 _mp4ErrorCode = FILE_OPEN_FAILED;
158 }
159
160 _fileptr->_fileSize = fp->_fileSize;
161 }
162 int32 _head_offset = AtomUtils::getCurrentFilePosition(fp);
163 AtomUtils::seekFromCurrPos(fp, dataSize);
164 AtomUtils::seekFromStart(_fileptr, _head_offset);
165
166 return;
167 }
168 else
169 {
170 _parsing_mode = 0;
171 _stbl_buff_size = _entryCount;
172 }
173 }
174 else
175 {
176 _parsing_mode = 0;
177 _stbl_buff_size = _entryCount;
178 }
179
180 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _pfirstChunkVec);
181 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psamplesPerChunkVec);
182 PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psampleDescriptionIndexVec);
183
184 uint32 firstChunk;
185 uint32 samplesPerChunk;
186 uint32 sampleDescrIndex;
187
188 uint32 offSet = 0;
189
190 uint32 prevFirstChunk = 0;
191 uint32 j = 0;
192
193 for (uint32 i = 0; i < _entryCount; i++)
194 {
195 if (!AtomUtils::read32(fp, firstChunk))
196 {
197 _success = false;
198 break;
199 }
200
201 if (i == 0)
202 offSet = firstChunk;
203
204 if (!AtomUtils::read32(fp, samplesPerChunk))
205 {
206 _success = false;
207 break;
208 }
209 if (!AtomUtils::read32(fp, sampleDescrIndex))
210 {
211 _success = false;
212 break;
213 }
214
215 if (firstChunk > prevFirstChunk)
216 {
217 _pfirstChunkVec[j] = (firstChunk - offSet);
218 _psamplesPerChunkVec[j] = (samplesPerChunk);
219 _psampleDescriptionIndexVec[j] = (sampleDescrIndex);
220 prevFirstChunk = firstChunk;
221 j++;
222 }
223 }
224 _entryCount = j;
225 uint32 firstsamplenum = 0;
226 resetStateVariables(firstsamplenum);
227 }
228 else
229 {
230 _pfirstChunkVec = NULL;
231 _psamplesPerChunkVec = NULL;
232 _psampleDescriptionIndexVec = NULL;
233 }
234 }
235
236 if (!_success)
237 {
238 _mp4ErrorCode = READ_SAMPLE_TO_CHUNK_ATOM_FAILED;
239 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::SampleToChunkAtom- Read SampleToChunk Atom failed %d", _mp4ErrorCode));
240 }
241 }
242 else
243 {
244 if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
245 {
246 _mp4ErrorCode = READ_SAMPLE_TO_CHUNK_ATOM_FAILED;
247 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::SampleToChunkAtom- Read SampleToChunk Atom failed %d", _mp4ErrorCode));
248 }
249 }
250 }
ParseEntryUnit(uint32 sample_cnt)251 bool SampleToChunkAtom::ParseEntryUnit(uint32 sample_cnt)
252 {
253
254 uint32 prevFirstChunk = 0;
255
256
257 const uint32 threshold = 512;
258 sample_cnt += threshold;
259
260 if (sample_cnt > _entryCount)
261 sample_cnt = _entryCount;
262
263 while (_parsed_entry_cnt < sample_cnt)
264 {
265 _curr_entry_point = _parsed_entry_cnt % _stbl_buff_size;
266 _curr_buff_number = _parsed_entry_cnt / _stbl_buff_size;
267 if (_curr_buff_number == _next_buff_number)
268 {
269 uint32 currFilePointer = AtomUtils::getCurrentFilePosition(_fileptr);
270 _stbl_fptr_vec[_curr_buff_number] = currFilePointer;
271 _next_buff_number++;
272 }
273
274 if (!_curr_entry_point)
275 {
276 uint32 currFilePointer = _stbl_fptr_vec[_curr_buff_number];
277 AtomUtils::seekFromStart(_fileptr, currFilePointer);
278 }
279 uint32 firstChunk;
280 uint32 samplesPerChunk;
281 uint32 sampleDescrIndex;
282
283 if (!AtomUtils::read32(_fileptr, firstChunk))
284 {
285 _success = false;
286 break;
287 }
288 uint32 offSet = 1;
289 if (_parsed_entry_cnt == 0)
290 offSet = firstChunk;
291
292 if (!AtomUtils::read32(_fileptr, samplesPerChunk))
293 {
294 _success = false;
295 break;
296 }
297 if (!AtomUtils::read32(_fileptr, sampleDescrIndex))
298 {
299 _success = false;
300 break;
301 }
302 if (firstChunk > prevFirstChunk)
303 {
304 _pfirstChunkVec[_curr_entry_point] = (firstChunk - offSet);
305 _psamplesPerChunkVec[_curr_entry_point] = (samplesPerChunk);
306 _psampleDescriptionIndexVec[_curr_entry_point] = (sampleDescrIndex);
307 _parsed_entry_cnt++;
308 prevFirstChunk = firstChunk;
309 }
310 }
311 return true;
312 }
313
~SampleToChunkAtom()314 SampleToChunkAtom::~SampleToChunkAtom()
315 {
316 if (_pfirstChunkVec != NULL)
317 {
318 PV_MP4_ARRAY_DELETE(NULL, _pfirstChunkVec);
319 }
320 if (_psamplesPerChunkVec != NULL)
321 {
322 PV_MP4_ARRAY_DELETE(NULL, _psamplesPerChunkVec);
323 }
324 if (_psampleDescriptionIndexVec != NULL)
325 {
326 PV_MP4_ARRAY_DELETE(NULL, _psampleDescriptionIndexVec);
327 }
328 if (_fileptr != NULL)
329 {
330 if (_fileptr->IsOpen())
331 {
332 AtomUtils::CloseMP4File(_fileptr);
333 }
334
335 oscl_free(_fileptr);
336 }
337 if (_stbl_fptr_vec != NULL)
338 PV_MP4_ARRAY_DELETE(NULL, _stbl_fptr_vec);
339
340 }
341
342 // Returns the chunk number of the first chunk in run[index]
343 int32
getFirstChunkAt(uint32 index)344 SampleToChunkAtom::getFirstChunkAt(uint32 index)
345 {
346 if (_pfirstChunkVec == NULL)
347 {
348 return PV_ERROR;
349 }
350 if (index < _entryCount)
351 {
352 if (_parsing_mode == 1)
353 {
354 CheckAndParseEntry(index);
355 }
356 return (_pfirstChunkVec[index%_stbl_buff_size]);
357 }
358 else
359 {
360 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::getFirstChunkAt index = %d", index));
361 return PV_ERROR;
362 }
363 }
364
365 // Returns the samples per chunk of all the chunks in run[index]
366 int32
getSamplesPerChunkAt(uint32 index)367 SampleToChunkAtom::getSamplesPerChunkAt(uint32 index)
368 {
369 if (_psamplesPerChunkVec == NULL)
370 {
371 return PV_ERROR;
372 }
373 if (index < _entryCount)
374 {
375 if (_parsing_mode == 1)
376 {
377 CheckAndParseEntry(index);
378 }
379 return (_psamplesPerChunkVec[index%_stbl_buff_size]);
380 }
381 else
382 {
383 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::getSamplesPerChunkAt index = %d", index));
384 return PV_ERROR;
385 }
386
387 }
388
389 // Returns the samples description index for the samples in all the chunks in run[index]
390 uint32
getSDIndex() const391 SampleToChunkAtom::getSDIndex() const
392 {
393 if (_psampleDescriptionIndexVec == NULL)
394 {
395 return (uint32)PV_ERROR;
396 }
397
398 if (_Index < _entryCount)
399 {
400 return (_psampleDescriptionIndexVec[_Index%_stbl_buff_size]);
401 }
402 else
403 {
404 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndex"));
405 return (uint32) PV_ERROR;
406 }
407 }
408
409 // Returns the chunk number for the given sample number
410 uint32
getChunkNumberForSampleGet(uint32 sampleNum)411 SampleToChunkAtom::getChunkNumberForSampleGet(uint32 sampleNum)
412 {
413 if ((_pfirstChunkVec == NULL) ||
414 (_psamplesPerChunkVec == NULL))
415 {
416 return (uint32)PV_ERROR;
417 }
418
419 if (_parsing_mode == 1)
420 {
421 CheckAndParseEntry(_majorGetIndex);
422 }
423
424 if (sampleNum < _currGetSampleCount)
425 {
426 return (_currGetChunk);
427 }
428 else if (_numGetChunksInRun > 1)
429 {
430 _firstGetSampleInCurrChunk = _currGetSampleCount;
431 _currGetSampleCount += _numGetSamplesPerChunk;
432 _currGetChunk++;
433
434 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _firstGetSampleInCurrChunk =%d", _firstGetSampleInCurrChunk));
435 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount));
436 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk));
437
438 // to handle special case, every sample is a chunk
439 if (_entryCount > 1)
440 {
441 _numGetChunksInRun--;
442 }
443
444 if (sampleNum < _currGetSampleCount)
445 {
446 return (_currGetChunk);
447 }
448 else
449 {
450 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum));
451 return (uint32)PV_ERROR;
452 }
453 }
454 else if (_numGetChunksInRun <= 1)
455 {
456 if (_majorGetIndex < (int32)(_entryCount - 1))
457 {
458 uint32 prevFirstChunk = _pfirstChunkVec[_majorGetIndex%_stbl_buff_size];
459 _numGetSamplesPerChunk = _psamplesPerChunkVec[_majorGetIndex%_stbl_buff_size];
460 _currGetSDI = _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size];
461
462 if (_parsing_mode == 1)
463 {
464 CheckAndParseEntry(_majorGetIndex + 1);
465 }
466
467 uint32 nextFirstChunk = _pfirstChunkVec[(_majorGetIndex+1)%_stbl_buff_size];
468 _numGetChunksInRun = nextFirstChunk - prevFirstChunk;
469 _numChunksInRun = _numGetChunksInRun;
470
471
472 _majorGetIndex++;
473 _firstGetSampleInCurrChunk = _currGetSampleCount;
474 _currGetSampleCount += _numGetSamplesPerChunk;
475 _currGetChunk++;
476
477 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetChunksInRun =%d", _numGetChunksInRun));
478 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetSamplesPerChunk =%d", _numGetSamplesPerChunk));
479 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount));
480 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk));
481 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _majorGetIndex =%d", _majorGetIndex));
482
483 if (sampleNum < _currGetSampleCount)
484 {
485 return (_currGetChunk);
486 }
487 else
488 {
489 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum));
490 return (uint32)PV_ERROR;
491 }
492 }
493 else if (_majorGetIndex == (int32)(_entryCount - 1))
494 {
495 // Last run of chunks
496 _numGetChunksInRun = 1;
497
498 _numChunksInRun = _numGetChunksInRun;
499
500 _currGetSDI = _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size];
501
502 _numGetSamplesPerChunk =
503 _psamplesPerChunkVec[_majorGetIndex%_stbl_buff_size];
504
505 _firstGetSampleInCurrChunk = _currGetSampleCount;
506
507 _currGetSampleCount += _numGetSamplesPerChunk;
508 _currGetChunk++;
509
510 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetSamplesPerChunk =%d", _firstGetSampleInCurrChunk));
511 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _firstGetSampleInCurrChunk =%d", _firstGetSampleInCurrChunk));
512 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount));
513 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk));
514
515 if (sampleNum < _currGetSampleCount)
516 {
517 return (_currGetChunk);
518 }
519 else
520 {
521 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum));
522 return (uint32)PV_ERROR;
523 }
524 }
525 else
526 {
527 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet _majorGetIndex = %d _entryCount= %d", _majorGetIndex, _entryCount));
528 return (uint32)PV_ERROR;
529 }
530 }
531
532 return (uint32)PV_ERROR; // Should never get here
533 }
534
535 // Returns the chunk number for the given sample number
536 uint32
getChunkNumberForSample(uint32 sampleNum)537 SampleToChunkAtom::getChunkNumberForSample(uint32 sampleNum)
538 {
539 if ((_pfirstChunkVec == NULL) ||
540 (_psamplesPerChunkVec == NULL))
541 {
542 return (uint32)PV_ERROR;
543 }
544
545 uint32 sampleCount = 0;
546
547 for (uint32 i = 0; i < _entryCount; i++)
548 {
549 uint32 chunkNum = 0;
550 uint32 samplesPerChunkInRun = 0;
551
552 if (_parsing_mode == 1)
553 {
554 CheckAndParseEntry(i);
555 }
556 chunkNum = _pfirstChunkVec[i%_stbl_buff_size];
557 samplesPerChunkInRun = _psamplesPerChunkVec[i%_stbl_buff_size];
558
559 if ((i + 1) < _entryCount)
560 {
561 if (_parsing_mode == 1)
562 {
563 CheckAndParseEntry(i + 1);
564 }
565
566 uint32 nextChunkNum = _pfirstChunkVec[(int32)((i+1)%_stbl_buff_size)];
567 uint32 numChunksInRun = nextChunkNum - chunkNum;
568 uint32 count = sampleCount + samplesPerChunkInRun * numChunksInRun;
569
570 if (count < sampleNum)
571 { // Haven't found chunk yet - running count still less than sampleNum
572 sampleCount = count;
573 continue;
574 }
575 else
576 { // Found run of chunks in which sample lies - now find actual chunk
577 for (int32 j = 0; j < (int32)numChunksInRun; j++)
578 {
579 sampleCount += samplesPerChunkInRun; // samples for jth chunk
580 if (sampleNum < sampleCount)
581 { // Found specific chunk
582 _Index = i;
583 return chunkNum + j; // Return jth chunk in run
584 }
585 }
586 }
587 }
588 else
589 { // Last run of chunks - simply find specific chunk
590 int k = 0;
591 while (sampleNum >= sampleCount)
592 {
593 // Continue until find chunk number - we do not know how many chunks are in
594 // this final run so keep going til we find a number
595 sampleCount += samplesPerChunkInRun;
596 if (sampleNum < sampleCount)
597 {
598 // Found specific chunk
599 _Index = i;
600 return chunkNum + k; // Return ith chunk in run
601 // Since we do not actually know how many chunk are in this last run,
602 // the chunkNum that is returned may not be a valid chunk!
603 // This is handled in the exception handling in the chunkOffset atom
604 }
605 k++;
606 }
607 }
608 }
609 return (uint32)PV_ERROR; // Should never get here
610 }
611
612
613 // Returns the sampleNum of the first sample in chunk with chunk number 'chunkNum'
614 // Note that since the coding of this table does not indicate the total number of
615 // chunks (i.e. don't know how many chunks in last run) this method may return a
616 // sample number that is not valid. This should be taken care of in the exception
617 // handling in the chunkoffset and samplesize atoms
618 uint32
getFirstSampleNumInChunk(uint32 chunkNum)619 SampleToChunkAtom::getFirstSampleNumInChunk(uint32 chunkNum)
620 {
621 if ((_pfirstChunkVec == NULL) ||
622 (_psamplesPerChunkVec == NULL))
623 {
624 return (uint32)PV_ERROR;
625 }
626
627 uint32 firstChunkCurrentRun = 0; // chunk number of first chunk in this run
628 uint32 firstChunkNextRun = 0; // chunk number of first chunk in next run
629 uint32 firstSample = 0; // number of first sample in the run of chunks in which chunk 'chunkNum' lies
630 // once we find the correct run, this value holds the sample number of the first
631 // sample in chunk 'chunkNum'
632 uint32 samplesInRun = 0; // Number of samples in the entire run of chunks (not just in each chunk)
633
634 for (uint32 i = 0; i < _entryCount; i++)
635 {
636 // Go through vector of first chunks in runs
637
638 if (_parsing_mode == 1)
639 {
640 CheckAndParseEntry(i);
641 }
642
643 firstChunkCurrentRun = _pfirstChunkVec[i%_stbl_buff_size]; // Get first chunk number for run i
644
645 if (chunkNum < firstChunkCurrentRun)
646 {
647 // Chunk is in previous run of chunks
648 firstSample -= samplesInRun; // Backtrack to first sample of last run
649
650 // Now need to find specific chunk and sample in this run
651 if (_parsing_mode == 1)
652 {
653 CheckAndParseEntry(i - 1);
654 }
655
656 firstChunkCurrentRun = _pfirstChunkVec[(int32)((i-1)%_stbl_buff_size)]; // Backtrack to last run
657 uint32 samplesPerChunk = _psamplesPerChunkVec[(int32)((i-1)%_stbl_buff_size)];
658
659 uint32 chunkOffset = chunkNum - firstChunkCurrentRun; // Offset from firstChunk
660 uint32 sampleOffset = chunkOffset * samplesPerChunk;
661 firstSample += sampleOffset;
662
663 return firstSample;
664 }
665 else if (chunkNum == firstChunkCurrentRun)
666 {
667 // Requested chunk is first in this run
668 return firstSample; // Return first sample in this run
669 }
670 else
671 {
672 // Haven't found chunk in run
673
674 if ((i + 1) < _entryCount)
675 {
676 if (_parsing_mode == 1)
677 {
678 CheckAndParseEntry(i + 1);
679 }
680
681 firstChunkNextRun = _pfirstChunkVec[(int32)(((i+1)%_stbl_buff_size))]; // If we are out of range of the vector
682 // This means we are in the last run of chunks
683 int32 numChunks = firstChunkNextRun - firstChunkCurrentRun;
684 samplesInRun = _psamplesPerChunkVec[i%_stbl_buff_size] * numChunks; // Once you advance, this value maintains the
685 // number of samples in the previous run
686 firstSample += samplesInRun;
687 }
688 else
689 {
690 // In last run of chunks - we know the chunk is here
691 // Now need to find specific chunk and sample
692
693 firstChunkCurrentRun = _pfirstChunkVec[i%_stbl_buff_size]; // Get first chunk number for this run
694 uint32 samplesPerChunk = _psamplesPerChunkVec[i%_stbl_buff_size];
695
696 uint32 chunkOffset = chunkNum - firstChunkCurrentRun; // Offset from firstChunk
697 uint32 sampleOffset = chunkOffset * samplesPerChunk;
698 firstSample += sampleOffset;
699
700 return firstSample;
701 }
702 }
703 }
704
705 return 0; // Error condition
706 }
707
708 uint32
getNumChunksInRunofChunks(uint32 chunk)709 SampleToChunkAtom::getNumChunksInRunofChunks(uint32 chunk)
710 {
711 if (_pfirstChunkVec == NULL)
712 {
713 return (uint32)PV_ERROR;
714 }
715
716 if ((chunk + 1) < _entryCount)
717 {
718 for (uint32 i = 0; i < _entryCount; i++)
719 {
720 if (_parsing_mode == 1)
721 {
722 CheckAndParseEntry(i);
723 }
724
725 if (_pfirstChunkVec[i%_stbl_buff_size] < chunk)
726 {
727 continue;
728 }
729 else if (_pfirstChunkVec[i%_stbl_buff_size] == chunk)
730 {
731 uint32 chunkNum = _pfirstChunkVec[(int32)(i%_stbl_buff_size)];
732 if (_parsing_mode == 1)
733 {
734 CheckAndParseEntry(i + 1);
735 }
736 uint32 nextChunkNum = _pfirstChunkVec[(int32)((i+1)%_stbl_buff_size)];
737 return(nextChunkNum - chunkNum);
738 }
739 else if (_pfirstChunkVec[(i%_stbl_buff_size)] > chunk)
740 {
741 return(_pfirstChunkVec[(i%_stbl_buff_size)] - chunk);
742 }
743 }
744 }
745 else
746 {
747 return (1);
748 }
749
750 return (uint32)PV_ERROR;
751 }
752
753 uint32
getSamplesPerChunkCorrespondingToSample(uint32 sampleNum)754 SampleToChunkAtom::getSamplesPerChunkCorrespondingToSample(uint32 sampleNum)
755 {
756 uint32 sampleCount = 0;
757
758 if ((_pfirstChunkVec == NULL) ||
759 (_psamplesPerChunkVec == NULL))
760 {
761 return (uint32)PV_ERROR;
762 }
763
764 for (uint32 i = 0; i < _entryCount; i++)
765 {
766 if (_parsing_mode == 1)
767 {
768 CheckAndParseEntry(i);
769 }
770
771 uint32 chunkNum = 0;
772 uint32 samplesPerChunkInRun = 0;
773
774 chunkNum = _pfirstChunkVec[(i%_stbl_buff_size)];
775 samplesPerChunkInRun = _psamplesPerChunkVec[(i%_stbl_buff_size)];
776
777 if ((i + 1) < _entryCount)
778 {
779 if (_parsing_mode == 1)
780 {
781 CheckAndParseEntry(i + 1);
782 }
783
784 uint32 nextChunkNum = _pfirstChunkVec[(int32)(((i+1)%_stbl_buff_size))];
785 uint32 numChunksInRun = nextChunkNum - chunkNum;
786 uint32 count = sampleCount + samplesPerChunkInRun * numChunksInRun;
787
788 if (count < sampleNum)
789 { // Haven't found chunk yet - running count still less than sampleNum
790 sampleCount = count;
791 continue;
792 }
793 else
794 { // Found run of chunks in which sample lies - now find actual chunk
795 for (int32 j = 0; j < (int32)numChunksInRun; j++)
796 {
797 sampleCount += samplesPerChunkInRun; // samples for jth chunk
798 if (sampleNum < sampleCount)
799 { // Found specific chunk
800 return (samplesPerChunkInRun);
801 }
802 }
803 }
804 }
805 else
806 {
807 // Last run of chunks - simply find specific chunk
808 int k = 0;
809 int for_ever = 1;
810 while (for_ever)
811 {
812 // Continue until find chunk number - we do not know how many chunks are in
813 // this final run so keep going til we find a number
814 sampleCount += samplesPerChunkInRun;
815 if (sampleNum < sampleCount)
816 { // Found specific chunk
817 return (samplesPerChunkInRun);
818 // Since we do not actually know how many chunk are in this last run,
819 // the chunkNum that is returned may not be a valid chunk!
820 // This is handled in the exception handling in the chunkOffset atom
821 }
822 k++;
823 }
824 }
825 }
826 return 0; // Should never get here
827 }
828
829
830 // Returns the chunk number for the given sample number
831 uint32
getSDIndexPeek() const832 SampleToChunkAtom::getSDIndexPeek() const
833 {
834 if (_psampleDescriptionIndexVec == NULL)
835 {
836 return (uint32)PV_ERROR;
837 }
838
839 if (_currPeekSDI != 0)
840 {
841 return (_currPeekSDI);
842 }
843 else
844 {
845 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndexPeek _currPeekSDI = %d", _currPeekSDI));
846 return (uint32) PV_ERROR;
847 }
848 }
849 uint32
getSDIndexGet() const850 SampleToChunkAtom::getSDIndexGet() const
851 {
852 if (_psampleDescriptionIndexVec == NULL)
853 {
854 return (uint32)PV_ERROR;
855 }
856
857 if (_currGetSDI != 0)
858 {
859 return (_currGetSDI);
860 }
861 else
862 {
863 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndexGet _currGetSDI = %d", _currGetSDI));
864 return (uint32) PV_ERROR;
865 }
866 }
867
868
869 uint32
getFirstSampleNumInChunkGet() const870 SampleToChunkAtom::getFirstSampleNumInChunkGet() const
871 {
872 if ((_pfirstChunkVec == NULL) ||
873 (_psamplesPerChunkVec == NULL))
874 {
875 return (uint32)PV_ERROR;
876 }
877
878 return (_firstGetSampleInCurrChunk);
879 }
880
881
882 uint32
getChunkNumberForSamplePeek(uint32 sampleNum)883 SampleToChunkAtom::getChunkNumberForSamplePeek(uint32 sampleNum)
884 {
885 if ((_pfirstChunkVec == NULL) ||
886 (_psamplesPerChunkVec == NULL))
887 {
888 return (uint32)PV_ERROR;
889 }
890 if (_parsing_mode == 1)
891 {
892 CheckAndParseEntry(_majorPeekIndex);
893 }
894
895 if (sampleNum < _currPeekSampleCount)
896 {
897 return (_currPeekChunk);
898 }
899 else if (_numPeekChunksInRun > 1)
900 {
901 _firstPeekSampleInCurrChunk = _currPeekSampleCount;
902 _currPeekSampleCount += _numPeekSamplesPerChunk;
903 _currPeekChunk++;
904
905 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk));
906 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount));
907 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk));
908 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekChunk =%d", _currPeekChunk));
909
910 // to handle special case, every sample is a chunk
911 if (_entryCount > 1)
912 {
913 _numPeekChunksInRun--;
914 }
915
916 if (sampleNum < _currPeekSampleCount)
917 {
918 return (_currPeekChunk);
919 }
920 else
921 {
922 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum));
923 return (uint32)PV_ERROR;
924 }
925 }
926 else if (_numPeekChunksInRun <= 1)
927 {
928 if (_majorPeekIndex < (int32)(_entryCount - 1))
929 {
930 uint32 prevNextChunk = _pfirstChunkVec[_majorPeekIndex%_stbl_buff_size];
931 _numPeekSamplesPerChunk = _psamplesPerChunkVec[_majorPeekIndex%_stbl_buff_size];
932 _currPeekSDI = _psampleDescriptionIndexVec[_majorPeekIndex%_stbl_buff_size];
933
934 if (_parsing_mode == 1)
935 {
936 CheckAndParseEntry(_majorPeekIndex + 1);
937 }
938
939 uint32 nextfirstChunk = _pfirstChunkVec[(_majorPeekIndex+1)%_stbl_buff_size];
940
941 _numPeekChunksInRun = nextfirstChunk - prevNextChunk;
942
943 _majorPeekIndex++;
944
945 _firstPeekSampleInCurrChunk = _currPeekSampleCount;
946 _currPeekSampleCount += _numPeekSamplesPerChunk;
947 _currPeekChunk++;
948
949 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekChunksInRun =%d", _numPeekChunksInRun));
950 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk));
951 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _majorPeekIndex =%d", _majorPeekIndex));
952 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk));
953 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount));
954 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk));
955
956 if (sampleNum < _currPeekSampleCount)
957 {
958 return (_currPeekChunk);
959 }
960 else
961 {
962 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum));
963 return (uint32)PV_ERROR;
964 }
965 }
966 else if (_majorPeekIndex == (int32)(_entryCount - 1))
967 {
968 _numPeekChunksInRun = 1;
969
970 _currPeekSDI =
971 _psampleDescriptionIndexVec[_majorPeekIndex%_stbl_buff_size];
972
973 _numPeekSamplesPerChunk =
974 _psamplesPerChunkVec[_majorPeekIndex%_stbl_buff_size];
975
976 _firstPeekSampleInCurrChunk = _currPeekSampleCount;
977
978 _currPeekSampleCount += _numPeekSamplesPerChunk;
979 _currPeekChunk++;
980
981 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk));
982 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _majorPeekIndex =%d", _majorPeekIndex));
983 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk));
984 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount));
985 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk));
986
987 if (sampleNum < _currPeekSampleCount)
988 {
989 return (_currPeekChunk);
990 }
991 else
992 {
993 PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum));
994 return (uint32)PV_ERROR;
995 }
996 }
997 else
998 {
999 return (uint32)PV_ERROR;
1000 }
1001 }
1002
1003 return (uint32)PV_ERROR; // Should never get here
1004 }
1005 uint32
getNumChunksInRunofChunksGet() const1006 SampleToChunkAtom::getNumChunksInRunofChunksGet() const
1007 {
1008 if (_pfirstChunkVec == NULL)
1009 {
1010 return (uint32)PV_ERROR;
1011 }
1012
1013 if (_numChunksInRun != 0)
1014 {
1015 return (_numChunksInRun);
1016 }
1017 return (uint32)PV_ERROR;
1018 }
1019
1020 uint32
getSamplesPerChunkCorrespondingToSampleGet() const1021 SampleToChunkAtom::getSamplesPerChunkCorrespondingToSampleGet() const
1022 {
1023
1024 if ((_pfirstChunkVec == NULL) ||
1025 (_psamplesPerChunkVec == NULL))
1026 {
1027 return (uint32)PV_ERROR;
1028 }
1029
1030 if (_numGetSamplesPerChunk != 0)
1031 {
1032 return (_numGetSamplesPerChunk);
1033 }
1034
1035 return 0; // Should never get here
1036 }
1037 uint32
getFirstSampleNumInChunkPeek() const1038 SampleToChunkAtom::getFirstSampleNumInChunkPeek() const
1039 {
1040 if ((_pfirstChunkVec == NULL) ||
1041 (_psamplesPerChunkVec == NULL))
1042 {
1043 return (uint32)PV_ERROR;
1044 }
1045
1046 return (_firstPeekSampleInCurrChunk);
1047 }
1048
1049 int32
resetStateVariables()1050 SampleToChunkAtom::resetStateVariables()
1051 {
1052 _majorGetIndex = 0;
1053 _currGetChunk = -1;
1054 _numGetChunksInRun = 0;
1055 _currGetSampleCount = 0;
1056 _firstGetSampleInCurrChunk = 0;
1057 _numGetSamplesPerChunk = 0;
1058 _currGetSDI = 0;
1059
1060 _majorPeekIndex = 0;
1061 _currPeekChunk = -1;
1062 _numPeekChunksInRun = 0;
1063 _currPeekSampleCount = 0;
1064 _firstPeekSampleInCurrChunk = 0;
1065 _numPeekSamplesPerChunk = 0;
1066 _currPeekSDI = 0;
1067
1068 return (EVERYTHING_FINE);
1069 }
1070
1071 int32
resetStateVariables(uint32 sampleNum)1072 SampleToChunkAtom::resetStateVariables(uint32 sampleNum)
1073 {
1074 _majorGetIndex = 0;
1075 _currGetChunk = -1;
1076 _numGetChunksInRun = 0;
1077 _currGetSampleCount = 0;
1078 _firstGetSampleInCurrChunk = 0;
1079 _numGetSamplesPerChunk = 0;
1080 _currGetSDI = 0;
1081
1082 _majorPeekIndex = 0;
1083 _currPeekChunk = -1;
1084 _numPeekChunksInRun = 0;
1085 _currPeekSampleCount = 0;
1086 _firstPeekSampleInCurrChunk = 0;
1087 _numPeekSamplesPerChunk = 0;
1088 _currPeekSDI = 0;
1089
1090 if ((_pfirstChunkVec == NULL) ||
1091 (_psamplesPerChunkVec == NULL))
1092 {
1093 return PV_ERROR;
1094 }
1095
1096 uint32 sampleCount = 0;
1097
1098 for (uint32 i = 0; i < _entryCount; i++)
1099 {
1100 uint32 chunkNum = 0;
1101 uint32 samplesPerChunkInRun = 0;
1102
1103 if (_parsing_mode == 1)
1104 {
1105 CheckAndParseEntry(i + 1);
1106 }
1107
1108 chunkNum = _pfirstChunkVec[i%_stbl_buff_size];
1109 samplesPerChunkInRun = _psamplesPerChunkVec[i%_stbl_buff_size];
1110
1111 if ((i + 1) < _entryCount)
1112 {
1113 uint32 nextChunkNum = _pfirstChunkVec[(int32)(i+1)%_stbl_buff_size];
1114 uint32 numChunksInRun = nextChunkNum - chunkNum;
1115 uint32 count = sampleCount + samplesPerChunkInRun * numChunksInRun;
1116
1117 if (count < sampleNum)
1118 {
1119 // Haven't found chunk yet - running count still less than sampleNum
1120 sampleCount = count;
1121 continue;
1122 }
1123 else
1124 {
1125 _numGetChunksInRun = numChunksInRun;
1126
1127 // Found run of chunks in which sample lies - now find actual chunk
1128 for (int32 j = 0; j < (int32)numChunksInRun; j++)
1129 {
1130 // samples for jth chunk
1131 _firstGetSampleInCurrChunk = sampleCount;
1132 _numGetSamplesPerChunk = samplesPerChunkInRun;
1133 sampleCount += samplesPerChunkInRun;
1134
1135 if (sampleNum < sampleCount)
1136 {
1137 _majorGetIndex = i;
1138 _numChunksInRun = numChunksInRun;
1139 _currGetSampleCount = sampleCount;
1140 _currGetChunk = chunkNum + j;
1141 _currGetSDI =
1142 _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size];
1143
1144 goto END_OF_RESET;
1145 }
1146 _numGetChunksInRun--;
1147 }
1148 }
1149 }
1150 else
1151 {
1152 // Last run of chunks - simply find specific chunk
1153 int k = 0;
1154 while (sampleNum >= sampleCount)
1155 {
1156 // Continue until find chunk number - we do not know how many chunks are in
1157 // this final run so keep going til we find a number
1158 _firstGetSampleInCurrChunk = sampleCount;
1159 _numGetSamplesPerChunk = samplesPerChunkInRun;
1160
1161 sampleCount += samplesPerChunkInRun;
1162
1163 if (sampleNum < sampleCount)
1164 {
1165 // Found specific chunk
1166 _majorGetIndex = i;
1167 _numGetChunksInRun = 1;
1168 _numChunksInRun = _numGetChunksInRun;
1169 _currGetSampleCount = sampleCount;
1170 _currGetChunk = chunkNum + k;
1171 _currGetSDI =
1172 _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size];
1173
1174 goto END_OF_RESET;
1175 // Return ith chunk in run
1176 // Since we do not actually know how many chunk are in this last run,
1177 // the chunkNum that is returned may not be a valid chunk!
1178 // This is handled in the exception handling in the chunkOffset atom
1179 }
1180 k++;
1181 }
1182 }
1183 }
1184
1185 return PV_ERROR; // Should never get here
1186
1187 END_OF_RESET:
1188 {
1189 if (_majorGetIndex < (int32)(_entryCount - 1))
1190 {
1191 _majorGetIndex++;
1192 }
1193 _majorPeekIndex = _majorGetIndex;
1194 _currPeekChunk = _currGetChunk;
1195 _numPeekChunksInRun = _numGetChunksInRun;
1196 _currPeekSampleCount = _currGetSampleCount;
1197 _firstPeekSampleInCurrChunk = _firstGetSampleInCurrChunk;
1198 _numPeekSamplesPerChunk = _numGetSamplesPerChunk;
1199 _currPeekSDI = _currGetSDI;
1200
1201 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _majorPeekIndex = _majorGetIndex =%d", _majorPeekIndex));
1202 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _currPeekChunk = _currGetChunk =%d", _currPeekChunk));
1203 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _numPeekChunksInRun = _numGetChunksInRun = %d", _numPeekChunksInRun));
1204 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _currPeekSampleCount = _currGetSampleCount = %d", _currPeekSampleCount));
1205 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _firstPeekSampleInCurrChunk = _firstGetSampleInCurrChunk = %d", _firstPeekSampleInCurrChunk));
1206 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _numPeekSamplesPerChunk = _numGetSamplesPerChunk = %d", _numPeekSamplesPerChunk));
1207 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::resetStateVariables- _numPeekSamplesPerChunk = _currGetSDI = %d", _currPeekSDI));
1208
1209 return (EVERYTHING_FINE);
1210 }
1211 }
1212
resetPeekwithGet()1213 int32 SampleToChunkAtom::resetPeekwithGet()
1214 {
1215 _majorPeekIndex = _majorGetIndex;
1216 _currPeekChunk = _currGetChunk;
1217 _numPeekChunksInRun = _numGetChunksInRun;
1218 _currPeekSampleCount = _currGetSampleCount;
1219 _firstPeekSampleInCurrChunk = _firstGetSampleInCurrChunk;
1220 _numPeekSamplesPerChunk = _numGetSamplesPerChunk;
1221 _currPeekSDI = _currGetSDI;
1222 return (EVERYTHING_FINE);
1223 }
CheckAndParseEntry(uint32 i)1224 void SampleToChunkAtom::CheckAndParseEntry(uint32 i)
1225 {
1226 if (i >= _parsed_entry_cnt)
1227 {
1228 ParseEntryUnit(i);
1229 }
1230 else
1231 {
1232 uint32 entryLoc = i / _stbl_buff_size;
1233 if (_curr_buff_number != entryLoc)
1234 {
1235 _parsed_entry_cnt = entryLoc * _stbl_buff_size;
1236 while (_parsed_entry_cnt <= i)
1237 ParseEntryUnit(_parsed_entry_cnt);
1238 }
1239 }
1240 }
1241