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 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 } 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 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 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 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 391 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 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 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 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 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 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 832 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 850 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 870 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 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 1006 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 1021 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 1038 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 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 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 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 } 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