MP4_ERROR_CODE TimeToSampleAtom::GetSampleCountAt(uint32 aIndex, uint32& aCount) { MP4_ERROR_CODE retval = READ_FAILED; if ((aIndex < _entryCount) && _psampleCountVec) { if (_parsing_mode == 1) CheckAndParseEntry(aIndex); aCount = _psampleCountVec[aIndex%_stbl_buff_size]; retval = EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getSampleCountAt aIndex = %d", aIndex)); } return retval; }
// Return sample offset at index MP4_ERROR_CODE CompositionOffsetAtom::GetTimeOffsetForSampleNumberPeek(uint32 aSampleNumber, uint32& aTimeOffset) { MP4_ERROR_CODE retval = DEFAULT_ERROR; // It is assumed that sample 0 has a ts of 0 - i.e. the first // entry in the table starts with the delta between sample 1 and sample 0 if ((_psampleOffsetVec == NULL) || (_psampleCountVec == NULL) || (_entryCount == 0)) { return retval; } // note that aSampleNumber is a zero based index while _currGetSampleCount is 1 based index if (aSampleNumber < _currPeekSampleCount) { aTimeOffset = _currPeekTimeOffset; retval = EVERYTHING_FINE; } else { do { _currPeekIndex++; if (_parsing_mode) CheckAndParseEntry(_currPeekIndex); _currPeekSampleCount += _psampleCountVec[_currPeekIndex%_stbl_buff_size]; _currPeekTimeOffset = _psampleOffsetVec[_currPeekIndex%_stbl_buff_size]; } while (_currPeekSampleCount == 0); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekIndex =%d", _currPeekIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekSampleCount =%d", _currPeekSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekTimeOffset =%d", _currPeekTimeOffset)); if (aSampleNumber < _currPeekSampleCount) { aTimeOffset = _currPeekTimeOffset; retval = EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>CompositionOffsetAtom::getTimeOffsetForaSampleNumberberPeek aSampleNumber = %d", aSampleNumber)); } } return retval; }
// Return the number of samples at index MP4_ERROR_CODE CompositionOffsetAtom::GetSampleCountAt(uint32 aIndex, uint32& aSampleCount) { MP4_ERROR_CODE retval = DEFAULT_ERROR; if ((aIndex < _entryCount) && _psampleCountVec) { if (_parsing_mode == 1) CheckAndParseEntry(aIndex); aSampleCount = _psampleCountVec[aIndex%_stbl_buff_size]; retval = EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>CompositionOffsetAtom::getSampleCountAt aIndex = %d", aIndex)); } return retval; }
// Returns the timestamp delta (ms) for the current sample given by num. This value // is the difference in timestamps between the sample (num) and the previous sample // in the track. It is implicit that sample[0] occurs at timestamp ts=0. MP4_ERROR_CODE TimeToSampleAtom::GetTimeDeltaForSampleNumberGet(uint32 aSampleNumber, uint32& aTimeDelta) { MP4_ERROR_CODE retval = READ_FAILED; // It is assumed that sample 0 has a ts of 0 - i.e. the first // entry in the table starts with the delta between sample 1 and sample 0 if ((NULL == _psampleDeltaVec) || (NULL == _psampleCountVec) || (0 == _entryCount)) { return retval; } // note that sampleNum is a zero based index while _currGetSampleCount is 1 based index if (aSampleNumber < _currGetSampleCount) { aTimeDelta = _currGetTimeDelta; return EVERYTHING_FINE; } do { ++_currGetIndex; if (_parsing_mode) CheckAndParseEntry(_currGetIndex); _currGetSampleCount += _psampleCountVec[_currGetIndex%_stbl_buff_size]; _currGetTimeDelta = _psampleDeltaVec[_currGetIndex%_stbl_buff_size]; } while (0 == _currGetSampleCount); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetIndex =%d", _currGetIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TimeToSampleAtom::getTimeDeltaForSampleNumberGet- _currGetTimeDelta =%d", _currGetTimeDelta)); if (aSampleNumber < _currGetSampleCount) { aTimeDelta = _currGetTimeDelta; retval = EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getTimeDeltaForSampleNumberGet sampleNum = %d", aSampleNumber)); } return retval; }
int32 CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek(uint32 sampleNum) { // It is assumed that sample 0 has a ts of 0 - i.e. the first // entry in the table starts with the delta between sample 1 and sample 0 if ((_psampleOffsetVec == NULL) || (_psampleCountVec == NULL) || (_entryCount == 0)) { return PV_ERROR; } // note that sampleNum is a zero based index while _currGetSampleCount is 1 based index if (sampleNum < _currPeekSampleCount) { return (_currPeekTimeOffset); } else { do { _currPeekIndex++; if (_parsing_mode) CheckAndParseEntry(_currPeekIndex); _currPeekSampleCount += _psampleCountVec[_currPeekIndex%_stbl_buff_size]; _currPeekTimeOffset = _psampleOffsetVec[_currPeekIndex%_stbl_buff_size]; } while (_currPeekSampleCount == 0); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekIndex =%d", _currPeekIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekSampleCount =%d", _currPeekSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek- _currPeekTimeOffset =%d", _currPeekTimeOffset)); if (sampleNum < _currPeekSampleCount) { return (_currPeekTimeOffset); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>CompositionOffsetAtom::getTimeOffsetForSampleNumberPeek sampleNum = %d", sampleNum)); return (PV_ERROR); } } }
// This is the most widely used API // Returns the offset (ms) for the sample given by num. This is used when // randomly accessing a frame and the timestamp has not been accumulated. MP4_ERROR_CODE CompositionOffsetAtom::GetTimeOffsetForSampleNumberGet(uint32 aSampleNum, uint32& aTimeOffset) { MP4_ERROR_CODE retval = DEFAULT_ERROR; if ((_psampleOffsetVec == NULL) || (_psampleCountVec == NULL) || (_entryCount == 0)) { return retval; } // note that aSampleNum is a zero based index while _currGetSampleCount is 1 based index if (aSampleNum < _currGetSampleCount) { aTimeOffset = _currGetTimeOffset; retval = EVERYTHING_FINE; } else { do { _currGetIndex++; if (_parsing_mode) CheckAndParseEntry(_currGetIndex); _currGetSampleCount += _psampleCountVec[_currGetIndex%_stbl_buff_size]; _currGetTimeOffset = _psampleOffsetVec[_currGetIndex%_stbl_buff_size]; } while (_currGetSampleCount == 0); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForaSampleNumberGet- _currGetIndex =%d", _currGetIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForaSampleNumberGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForaSampleNumberGet- _currGetTimeOffset =%d", _currGetTimeOffset)); if (aSampleNum < _currGetSampleCount) { aTimeOffset = _currGetTimeOffset; retval = EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getTimeDeltaForaSampleNumberGet aSampleNum = %d", aSampleNum)); } } return retval; }
uint32 SampleToChunkAtom::getSDIndexGet() const { if (_psampleDescriptionIndexVec == NULL) { return (uint32)PV_ERROR; } if (_currGetSDI != 0) { return (_currGetSDI); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndexGet _currGetSDI = %d", _currGetSDI)); return (uint32) PV_ERROR; } }
// Returns the samples description index for the samples in all the chunks in run[index] uint32 SampleToChunkAtom::getSDIndex() const { if (_psampleDescriptionIndexVec == NULL) { return (uint32)PV_ERROR; } if (_Index < _entryCount) { return (_psampleDescriptionIndexVec[_Index%_stbl_buff_size]); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndex")); return (uint32) PV_ERROR; } }
MP4_ERROR_CODE SampleToChunkAtom::getSDIndexGet(uint32 &SDIndex) const { if (_psampleDescriptionIndexVec == NULL) { return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } if (_currGetSDI != 0) { SDIndex = (_currGetSDI); return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndexGet _currGetSDI = %d", _currGetSDI)); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } }
// Returns the samples description index for the samples in all the chunks in run[index] MP4_ERROR_CODE SampleToChunkAtom::getSDIndex(uint32& SDIndex) const { if (_psampleDescriptionIndexVec == NULL) { return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } if (_Index < _entryCount) { SDIndex = (_psampleDescriptionIndexVec[_Index%_stbl_buff_size]); return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getSDIndex")); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } }
// This is the most widely used API // Returns the offset (ms) for the sample given by num. This is used when // randomly accessing a frame and the timestamp has not been accumulated. int32 CompositionOffsetAtom::getTimeOffsetForSampleNumberGet(uint32 sampleNum) { if ((_psampleOffsetVec == NULL) || (_psampleCountVec == NULL) || (_entryCount == 0)) { return PV_ERROR; } // note that sampleNum is a zero based index while _currGetSampleCount is 1 based index if (sampleNum < _currGetSampleCount) { return (_currGetTimeOffset); } else { do { _currGetIndex++; if (_parsing_mode) CheckAndParseEntry(_currGetIndex); _currGetSampleCount += _psampleCountVec[_currGetIndex%_stbl_buff_size]; _currGetTimeOffset = _psampleOffsetVec[_currGetIndex%_stbl_buff_size]; } while (_currGetSampleCount == 0); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberGet- _currGetIndex =%d", _currGetIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "CompositionOffsetAtom::getTimeOffsetForSampleNumberGet- _currGetTimeOffset =%d", _currGetTimeOffset)); if (sampleNum < _currGetSampleCount) { return (_currGetTimeOffset); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>TimeToSampleAtom::getTimeDeltaForSampleNumberGet sampleNum = %d", sampleNum)); return (PV_ERROR); } } }
// Return sample offset at index int32 CompositionOffsetAtom::getSampleOffsetAt(int32 index) { if (_psampleOffsetVec == NULL) { return PV_ERROR; } if (index < (int32)_entryCount) { if (_parsing_mode == 1) CheckAndParseEntry(index); return (int32)(_psampleOffsetVec[index%_stbl_buff_size]); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>CompositionOffsetAtom::getSampleOffsetAt index = %d", index)); return PV_ERROR; } }
// Returns the chunk number of the first chunk in run[index] int32 SampleToChunkAtom::getFirstChunkAt(uint32 index) { if (_pfirstChunkVec == NULL) { return PV_ERROR; } if (index < _entryCount) { if (_parsing_mode == 1) { CheckAndParseEntry(index); } return (_pfirstChunkVec[index%_stbl_buff_size]); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::getFirstChunkAt index = %d", index)); return PV_ERROR; } }
// Returns the chunk number of the first chunk in run[index] MP4_ERROR_CODE SampleToChunkAtom::getFirstChunkAt(uint32 index, int32& pos) { if (_pfirstChunkVec == NULL) { return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } if (index < _entryCount) { if (_parsing_mode == 1) { CheckAndParseEntry(index); } pos = (_pfirstChunkVec[index%_stbl_buff_size]); return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::getFirstChunkAt index = %d", index)); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } }
MetaDataAtom::MetaDataAtom(MP4_FF_FILE *fp, uint32 size, uint32 type): Atom(fp, size, type) { _success = true; // User ilst Data _pITunesILSTAtom = NULL; _pHdlrAtom = NULL; int32 _count = _size - getDefaultSize(); uint32 data_32_hdlr = 0; iLogger = PVLogger::GetLoggerObject("mp4ffparser"); // Skip first 4 bytes. if (!AtomUtils::read32(fp, data_32_hdlr)) { _success = false; _mp4ErrorCode = READ_META_DATA_FAILED; PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>MetaDataAtom::MetaDataAtom READ_META_DATA_FAILED if(!AtomUtils::read32(fp,data_32_hdlr)))")); return; } _count -= 4; while (_count > 0) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; uint32 currPtr = AtomUtils::getCurrentFilePosition(fp); AtomUtils::getNextAtomType(fp, atomSize, atomType); // Validate atomSize if (atomSize < DEFAULT_ATOM_SIZE) { _success = false; _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE; break; } if ((atomType == FREE_SPACE_ATOM) || (atomType == UNKNOWN_ATOM)) { //skip the atom if (_count < atomSize) { AtomUtils::seekFromStart(fp, currPtr); AtomUtils::seekFromCurrPos(fp, _count); _count = 0; return; } _count -= atomSize; atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } else if (atomType == HANDLER_ATOM) { PV_MP4_FF_NEW(fp->auditCB, HandlerAtom, (fp, atomSize, atomType), _pHdlrAtom); if (!_pHdlrAtom->MP4Success()) { AtomUtils::seekFromStart(fp, currPtr); AtomUtils::seekFromCurrPos(fp, atomSize); PV_MP4_FF_DELETE(NULL, HandlerAtom, _pHdlrAtom); _pHdlrAtom = NULL; _count -= atomSize; } if (_pHdlrAtom != NULL) { if (_pHdlrAtom->getHandlerType() != ITUNES_MDIRAPPL_HDLR_PART1) { // Skip the parsing... fp->_pvfile.Seek(atomSize, Oscl_File::SEEKCUR); return; } _count -= _pHdlrAtom->getSize(); } } // Read the ilst Atom else if (atomType == ITUNES_ILST_ATOM) { PV_MP4_FF_NEW(fp->auditCB, ITunesILSTAtom, (fp, atomSize, atomType), _pITunesILSTAtom); if (!_pITunesILSTAtom->MP4Success()) { AtomUtils::seekFromStart(fp, currPtr); AtomUtils::seekFromCurrPos(fp, atomSize); PV_MP4_FF_DELETE(NULL, ITunesILSTAtom, _pITunesILSTAtom); _pITunesILSTAtom = NULL; _count -= atomSize; } else _count -= _pITunesILSTAtom->getSize(); } else { //Unexpected atomType. Flag an error. _success = false; _mp4ErrorCode = READ_META_DATA_FAILED; break; } } }
// Stream-in ctor // Create and return a new SampleToChunkAtom by reading in from an ifstream SampleToChunkAtom::SampleToChunkAtom(MP4_FF_FILE *fp, uint32 size, uint32 type, OSCL_wString& filename, uint32 parsingMode) : FullAtom(fp, size, type) { _pfirstChunkVec = NULL; _psamplesPerChunkVec = NULL; _psampleDescriptionIndexVec = NULL; _Index = 0; _numChunksInRun = 0; _majorGetIndex = 0; _currGetChunk = -1; _numGetChunksInRun = 0; _currGetSampleCount = 0; _firstGetSampleInCurrChunk = 0; _numGetSamplesPerChunk = 0; _currGetSDI = 0; _majorPeekIndex = 0; _currPeekChunk = -1; _numPeekChunksInRun = 0; _currPeekSampleCount = 0; _firstPeekSampleInCurrChunk = 0; _numPeekSamplesPerChunk = 0; _currPeekSDI = 0; _parsed_entry_cnt = 0; _fileptr = NULL; _stbl_buff_size = MAX_CACHED_TABLE_ENTRIES_FILE; _next_buff_number = 0; _curr_buff_number = 0; _curr_entry_point = 0; _stbl_fptr_vec = NULL; _parsing_mode = parsingMode; iLogger = PVLogger::GetLoggerObject("mp4ffparser"); iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats"); iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata"); if (_success) { _currentChunkNumber = 0; _maxNumSamplesPerChunk = DEFAULT_MAX_NUM_SAMPLES_PER_CHUNK; _maxChunkDataSize = DEFAULT_MAX_CHUNK_DATA_SIZE; if (!AtomUtils::read32(fp, _entryCount)) { _success = false; } PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "SampleToChunkAtom::SampleToChunkAtom- _entryCount =%d", _entryCount)); TOsclFileOffset dataSize = _size - (DEFAULT_FULL_ATOM_SIZE + 4); uint32 entrySize = (4 + 4 + 4); if ((TOsclFileOffset)(_entryCount*entrySize) > dataSize) { _success = false; } if (_success) { if (_entryCount > 0) { if (_parsing_mode) { if ((_entryCount > _stbl_buff_size)) // cahce size is 4K so that optimization should work if entry_count is greater than 4K { uint32 fptrBuffSize = (_entryCount / _stbl_buff_size) + 1; PV_MP4_FF_ARRAY_NEW(NULL, TOsclFileOffset, (fptrBuffSize), _stbl_fptr_vec); if (_stbl_fptr_vec == NULL) { _success = false; _mp4ErrorCode = MEMORY_ALLOCATION_FAILED; return; } PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _pfirstChunkVec); if (_pfirstChunkVec == NULL) { _success = false; _mp4ErrorCode = MEMORY_ALLOCATION_FAILED; return; } PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psamplesPerChunkVec); if (_psamplesPerChunkVec == NULL) { _success = false; _mp4ErrorCode = MEMORY_ALLOCATION_FAILED; return; } PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_stbl_buff_size), _psampleDescriptionIndexVec); if (_psampleDescriptionIndexVec == NULL) { _success = false; _mp4ErrorCode = MEMORY_ALLOCATION_FAILED; return; } { OsclAny* ptr = (MP4_FF_FILE *)(oscl_malloc(sizeof(MP4_FF_FILE))); if (ptr == NULL) { _success = false; _mp4ErrorCode = MEMORY_ALLOCATION_FAILED; return; } _fileptr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE()); _fileptr->_fileServSession = fp->_fileServSession; _fileptr->_pvfile.SetCPM(fp->_pvfile.GetCPM()); _fileptr->_pvfile.SetFileHandle(fp->_pvfile.iFileHandle); if (AtomUtils::OpenMP4File(filename, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, _fileptr) != 0) { _success = false; _mp4ErrorCode = FILE_OPEN_FAILED; } _fileptr->_fileSize = fp->_fileSize; } TOsclFileOffset _head_offset = AtomUtils::getCurrentFilePosition(fp); AtomUtils::seekFromCurrPos(fp, dataSize); AtomUtils::seekFromStart(_fileptr, _head_offset); ParseEntryUnit(0); uint32 firstsamplenum = 0; resetStateVariables(firstsamplenum); return; } else { _parsing_mode = 0; _stbl_buff_size = _entryCount; } } else { _parsing_mode = 0; _stbl_buff_size = _entryCount; } PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _pfirstChunkVec); PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psamplesPerChunkVec); PV_MP4_FF_ARRAY_NEW(NULL, uint32, (_entryCount), _psampleDescriptionIndexVec); uint32 firstChunk; uint32 samplesPerChunk; uint32 sampleDescrIndex; uint32 offSet = 0; uint32 prevFirstChunk = 0; uint32 j = 0; for (uint32 i = 0; i < _entryCount; i++) { if (!AtomUtils::read32(fp, firstChunk)) { _success = false; break; } if (i == 0) offSet = firstChunk; if (!AtomUtils::read32(fp, samplesPerChunk)) { _success = false; break; } if (!AtomUtils::read32(fp, sampleDescrIndex)) { _success = false; break; } if (firstChunk > prevFirstChunk) { _pfirstChunkVec[j] = (firstChunk - offSet); _psamplesPerChunkVec[j] = (samplesPerChunk); _psampleDescriptionIndexVec[j] = (sampleDescrIndex); prevFirstChunk = firstChunk; j++; } } _entryCount = j; uint32 firstsamplenum = 0; resetStateVariables(firstsamplenum); } else { _pfirstChunkVec = NULL; _psamplesPerChunkVec = NULL; _psampleDescriptionIndexVec = NULL; } } if (!_success) { _mp4ErrorCode = READ_SAMPLE_TO_CHUNK_ATOM_FAILED; PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::SampleToChunkAtom- Read SampleToChunk Atom failed %d", _mp4ErrorCode)); } } else { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED) { _mp4ErrorCode = READ_SAMPLE_TO_CHUNK_ATOM_FAILED; PVMF_MP4FFPARSER_LOGERROR((0, "ERROR =>SampleToChunkAtom::SampleToChunkAtom- Read SampleToChunk Atom failed %d", _mp4ErrorCode)); } } }
// Returns the chunk number for the given sample number uint32 SampleToChunkAtom::getChunkNumberForSampleGet(uint32 sampleNum) { if ((_pfirstChunkVec == NULL) || (_psamplesPerChunkVec == NULL)) { return (uint32)PV_ERROR; } if (_parsing_mode == 1) { CheckAndParseEntry(_majorGetIndex); } if (sampleNum < _currGetSampleCount) { return (_currGetChunk); } else if (_numGetChunksInRun > 1) { _firstGetSampleInCurrChunk = _currGetSampleCount; _currGetSampleCount += _numGetSamplesPerChunk; _currGetChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _firstGetSampleInCurrChunk =%d", _firstGetSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk)); // to handle special case, every sample is a chunk if (_entryCount > 1) { _numGetChunksInRun--; } if (sampleNum < _currGetSampleCount) { return (_currGetChunk); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum)); return (uint32)PV_ERROR; } } else if (_numGetChunksInRun <= 1) { if (_majorGetIndex < (int32)(_entryCount - 1)) { uint32 prevFirstChunk = _pfirstChunkVec[_majorGetIndex%_stbl_buff_size]; _numGetSamplesPerChunk = _psamplesPerChunkVec[_majorGetIndex%_stbl_buff_size]; _currGetSDI = _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size]; if (_parsing_mode == 1) { CheckAndParseEntry(_majorGetIndex + 1); } uint32 nextFirstChunk = _pfirstChunkVec[(_majorGetIndex+1)%_stbl_buff_size]; _numGetChunksInRun = nextFirstChunk - prevFirstChunk; _numChunksInRun = _numGetChunksInRun; _majorGetIndex++; _firstGetSampleInCurrChunk = _currGetSampleCount; _currGetSampleCount += _numGetSamplesPerChunk; _currGetChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetChunksInRun =%d", _numGetChunksInRun)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetSamplesPerChunk =%d", _numGetSamplesPerChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _majorGetIndex =%d", _majorGetIndex)); if (sampleNum < _currGetSampleCount) { return (_currGetChunk); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum)); return (uint32)PV_ERROR; } } else if (_majorGetIndex == (int32)(_entryCount - 1)) { // Last run of chunks _numGetChunksInRun = 1; _numChunksInRun = _numGetChunksInRun; _currGetSDI = _psampleDescriptionIndexVec[_majorGetIndex%_stbl_buff_size]; _numGetSamplesPerChunk = _psamplesPerChunkVec[_majorGetIndex%_stbl_buff_size]; _firstGetSampleInCurrChunk = _currGetSampleCount; _currGetSampleCount += _numGetSamplesPerChunk; _currGetChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _numGetSamplesPerChunk =%d", _firstGetSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _firstGetSampleInCurrChunk =%d", _firstGetSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetSampleCount =%d", _currGetSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSampleGet- _currGetChunk =%d", _currGetChunk)); if (sampleNum < _currGetSampleCount) { return (_currGetChunk); } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet sampleNum= %d", sampleNum)); return (uint32)PV_ERROR; } } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSampleGet _majorGetIndex = %d _entryCount= %d", _majorGetIndex, _entryCount)); return (uint32)PV_ERROR; } } return (uint32)PV_ERROR; // Should never get here }
MP4_ERROR_CODE SampleToChunkAtom::getChunkNumberForSamplePeek(uint32 sampleNum, uint32& ChunkNumber) { if ((_pfirstChunkVec == NULL) || (_psamplesPerChunkVec == NULL)) { return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } if (_parsing_mode == 1) { CheckAndParseEntry(_majorPeekIndex); } if (sampleNum < _currPeekSampleCount) { ChunkNumber = _currPeekChunk; return EVERYTHING_FINE; } else if (_numPeekChunksInRun > 1) { _firstPeekSampleInCurrChunk = _currPeekSampleCount; _currPeekSampleCount += _numPeekSamplesPerChunk; _currPeekChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekChunk =%d", _currPeekChunk)); // to handle special case, every sample is a chunk if (_entryCount > 1) { _numPeekChunksInRun--; } if (sampleNum < _currPeekSampleCount) { ChunkNumber = _currPeekChunk; return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum)); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } } else if (_numPeekChunksInRun <= 1) { if (_majorPeekIndex < (int32)(_entryCount - 1)) { uint32 prevNextChunk = _pfirstChunkVec[_majorPeekIndex%_stbl_buff_size]; _numPeekSamplesPerChunk = _psamplesPerChunkVec[_majorPeekIndex%_stbl_buff_size]; _currPeekSDI = _psampleDescriptionIndexVec[_majorPeekIndex%_stbl_buff_size]; if (_parsing_mode == 1) { CheckAndParseEntry(_majorPeekIndex + 1); } uint32 nextfirstChunk = _pfirstChunkVec[(_majorPeekIndex+1)%_stbl_buff_size]; _numPeekChunksInRun = nextfirstChunk - prevNextChunk; _majorPeekIndex++; _firstPeekSampleInCurrChunk = _currPeekSampleCount; _currPeekSampleCount += _numPeekSamplesPerChunk; _currPeekChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekChunksInRun =%d", _numPeekChunksInRun)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _majorPeekIndex =%d", _majorPeekIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk)); if (sampleNum < _currPeekSampleCount) { ChunkNumber = _currPeekChunk; return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum)); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } } else if (_majorPeekIndex == (int32)(_entryCount - 1)) { _numPeekChunksInRun = 1; _currPeekSDI = _psampleDescriptionIndexVec[_majorPeekIndex%_stbl_buff_size]; _numPeekSamplesPerChunk = _psamplesPerChunkVec[_majorPeekIndex%_stbl_buff_size]; _firstPeekSampleInCurrChunk = _currPeekSampleCount; _currPeekSampleCount += _numPeekSamplesPerChunk; _currPeekChunk++; PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _majorPeekIndex =%d", _majorPeekIndex)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _firstPeekSampleInCurrChunk =%d", _firstPeekSampleInCurrChunk)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _currPeekSampleCount =%d", _currPeekSampleCount)); PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "SampleToChunkAtom::getChunkNumberForSamplePeek- _numPeekSamplesPerChunk =%d", _numPeekSamplesPerChunk)); if (sampleNum < _currPeekSampleCount) { ChunkNumber = _currPeekChunk; return EVERYTHING_FINE; } else { PVMF_MP4FFPARSER_LOGERROR((0, "ERROR=>SampleToChunkAtom::getChunkNumberForSamplePeek sampleNum = %d", sampleNum)); return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } } else { return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; } } return READ_SAMPLE_TO_CHUNK_ATOM_FAILED; // Should never get here }