// Constructor PVA_FF_SampleTableAtom::PVA_FF_SampleTableAtom(uint32 mediaType, PVA_FF_MP4_CODEC_TYPE codecType, uint32 fileAuthoringFlags, uint32 protocol, uint8 profile, uint8 profileComp, uint8 level) : PVA_FF_Atom(SAMPLE_TABLE_ATOM) { _oInterLeaveMode = false; if (fileAuthoringFlags & PVMP4FF_SET_MEDIA_INTERLEAVE_MODE) { _oInterLeaveMode = true; } bool isprotected = false; if ((fileAuthoringFlags & PVMP4FF_PIFF_MODE) == PVMP4FF_PIFF_MODE) { isprotected = true; } PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TimeToSampleAtom, (mediaType), _ptimeToSampleAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SampleDescriptionAtom, (mediaType, codecType, isprotected, protocol, profile, profileComp, level), _psampleDescriptionAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SampleSizeAtom, (mediaType), _psampleSizeAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SampleToChunkAtom, (mediaType, fileAuthoringFlags), _psampleToChunkAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_ChunkOffsetAtom, (mediaType, fileAuthoringFlags), _pchunkOffsetAtom); if (mediaType == MEDIA_TYPE_VISUAL) { PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SyncSampleAtom, (), _psyncSampleAtom); _psyncSampleAtom->setParent(this); }
// Constructor PVA_FF_MediaAtom::PVA_FF_MediaAtom(int32 mediaType, int32 codecType, uint32 fileAuthoringFlags, bool o3GPPCompliant, uint32 protocol, uint8 profile, uint8 profileComp, uint8 level) : PVA_FF_Atom(MEDIA_ATOM) { PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaHeaderAtom, (), _pmediaHeader); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_HandlerAtom, (mediaType, (uint8)0, (uint8)0), _phandler); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaInformationAtom, (mediaType, codecType, fileAuthoringFlags, o3GPPCompliant, protocol, profile, profileComp, level), _pmediaInformation); recomputeSize(); _pmediaHeader->setParent(this); _phandler->setParent(this); _pmediaInformation->setParent(this); }
// Constructor PVA_FF_TrackAtom::PVA_FF_TrackAtom(int32 type, uint32 id, uint32 fileAuthoringFlags, int32 codecType, uint32 protocol, uint8 profile, uint8 profileComp, uint8 level) : PVA_FF_Atom(TRACK_ATOM) { _success = true; FIRST_SAMPLE = true; _intialTrackTimeOffsetInMilliSeconds = 0; _eList = NULL; _mediaType = type; _codecType = codecType; _oInterLeaveMode = false; if (fileAuthoringFlags & PVMP4FF_SET_MEDIA_INTERLEAVE_MODE) { _oInterLeaveMode = true; } _pUserDataAtom = NULL; if ((codecType == CODEC_TYPE_MPEG4_VIDEO) || (codecType == CODEC_TYPE_AAC_AUDIO)) { _setDecoderSpecificInfoDone = false; } else { _setDecoderSpecificInfoDone = true; } PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackHeaderAtom, (type, id, (uint8)0, (uint32)0x000001, fileAuthoringFlags), _ptrackHeader); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MediaAtom, (type, codecType, fileAuthoringFlags, protocol, profile, profileComp, level), _pmediaAtom); _ptrackReference = NULL; recomputeSize(); _ptrackHeader->setParent(this); _pmediaAtom->setParent(this); }
// Stream-in Constructor ObjectDescriptorAtom::ObjectDescriptorAtom(MP4_FF_FILE *fp, uint32 size, uint32 type) : FullAtom(fp, size, type) { _pOD = NULL; if (_success) { _pparent = NULL; PV_MP4_FF_NEW(fp->auditCB, InitialObjectDescriptor, (fp), _pOD); if (!_pOD->MP4Success()) { _success = false; _mp4ErrorCode = _pOD->GetMP4Error(); } if (_success) _pOD->setParent(this); } else { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED) _mp4ErrorCode = READ_OBJECT_DESCRIPTOR_ATOM_FAILED; } }
// constructor PVA_FF_TrackFragmentAtom::PVA_FF_TrackFragmentAtom(uint32 mediaType, uint32 codecType, uint32 trackId, uint32 interleaveDuration, uint32 timescale) : PVA_FF_Atom(TRACK_FRAGMENT_ATOM) { _mediaType = mediaType; _codecType = codecType; // no interleaving flag, as movie fragments are there in interleaving mode _timescale = timescale; _firstEntry = true; _prevTS = 0; _interleaveDuration = interleaveDuration; _fragmentDuration = 0; _ofirstTrun = true; // intialise track fragment header atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackFragmentHeaderAtom, (trackId), _pTfhdAtom); // initialise track run vector PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackFragmentRunAtomVecType, (), _pTrunList); recomputeSize(); }
TextStyleBox:: TextStyleBox(uint8 *buf) : Atom(buf) { _pparent = NULL; _pStyleRecordVec = NULL; if (_success) { PV_MP4_FF_NEW(fp->auditCB, styleRecordVecType, (), _pStyleRecordVec); if (!AtomUtils::read16(buf, _entryCount)) { _success = false; _mp4ErrorCode = READ_TEXT_SAMPLE_MODIFIERS_FAILED; return; } for (uint16 i = 0; i < _entryCount; i++) { StyleRecord *pStyleRecord = NULL; PV_MP4_FF_NEW(fp->auditCB, StyleRecord, (buf), pStyleRecord); if (!pStyleRecord->MP4Success()) { _success = false; _mp4ErrorCode = pStyleRecord->GetMP4Error(); return; } _pStyleRecordVec->push_back(pStyleRecord); } } else {
OSCL_EXPORT_REF IMpeg4File* IMpeg4File::readMP4File(MP4_FF_FILE_REFERENCE fileRef, uint32 parsingMode) { //optimized mode is not supported if multiple file ptrs are not allowed if (parsingMode == 1) { #ifndef OPEN_FILE_ONCE_PER_TRACK parsingMode = 0; #endif } //Create a dummy string to hold the file name OSCL_wHeapString<OsclMemAllocator> filename(_STRLIT("")); MP4_FF_FILE fileStruct; MP4_FF_FILE *fp = &fileStruct; fp->_pvfile.SetFilePtr(fileRef); int32 fileSize; int32 filePointer; AtomUtils::seekFromStart(fp, 0); filePointer = AtomUtils::getCurrentFilePosition(fp); AtomUtils::seekToEnd(fp); fileSize = AtomUtils::getCurrentFilePosition(fp); AtomUtils::seekFromStart(fp, filePointer); fp->_fileSize = fileSize; Mpeg4File *mp4 = NULL; PV_MP4_FF_NEW(fp->auditCB, Mpeg4File, (fp, filename, parsingMode), mp4); return mp4; }
// Stream-in ctor DataReferenceAtom::DataReferenceAtom(MP4_FF_FILE *fp, uint32 size, uint32 type) : FullAtom(fp, size, type) { _pdataEntryVec = NULL; if (_success) { _pparent = NULL; PV_MP4_FF_NEW(fp->auditCB, dataEntryUrlAtomVecType, (), _pdataEntryVec); if (!AtomUtils::read32(fp, _entryCount)) { _success = false; _mp4ErrorCode = READ_DATA_REFERENCE_ATOM_FAILED; } else { // THERE MUST BE ATLEAST ONE ENTRY int32 temp = (int32)(_entryCount); if (temp <= 0) { _success = false; _mp4ErrorCode = READ_DATA_REFERENCE_ATOM_FAILED; } } if (_success) { DataEntryUrlAtom *deua = NULL; for (uint32 i = 0; i < _entryCount; i++) { PV_MP4_FF_NEW(fp->auditCB, DataEntryUrlAtom, (fp), deua); if (!deua->MP4Success()) { _success = false; _mp4ErrorCode = deua->GetMP4Error(); if (deua != NULL) { PV_MP4_FF_DELETE(NULL, DataEntryUrlAtom, deua); deua = NULL; } break; } else { (*_pdataEntryVec).push_back(deua); deua->setParent(this); } } } } else { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
// Stream-in ctor AudioSampleEntry::AudioSampleEntry(MP4_FF_FILE *fp, uint32 size, uint32 type) : SampleEntry(fp, size, type) { _pes = NULL; _pparent = NULL; if (_success) { // Read reserved values if (!AtomUtils::read32read32(fp, _reserved1[0], _reserved1[1])) _success = false; if (!AtomUtils::read16read16(fp, _reserved2, _reserved3)) _success = false; if (!AtomUtils::read32(fp, _reserved4)) _success = false; if (!AtomUtils::read16read16(fp, _timeScale, _reserved5)) _success = false; if (_success) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomType == ESD_ATOM) { PV_MP4_FF_NEW(fp->auditCB, ESDAtom, (fp, atomSize, atomType), _pes); if (!_pes->MP4Success()) { _success = false; _mp4ErrorCode = _pes->GetMP4Error(); } else { _pes->setParent(this); } } else { _success = false; _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED; } } else { _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED; } } else { _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED; } }
bool AVCSampleEntry::createDecoderSpecificInfo(MP4_FF_FILE *fp) { uint32 numSPS = getNumSequenceParamSets(); uint32 numPPS = getNumPictureParamSets(); uint32 totalSPSLen = getTotalSeqParameterSetLength(); uint32 totalPPSLen = getTotalPictureParameterSetLength(); uint32 len = (numSPS * 2) + (numPPS * 2) + totalSPSLen + totalPPSLen; if ((int32)len > 0) { PV_MP4_FF_NEW(fp->auditCB, DecoderSpecificInfo, (fp, true), _decoderSpecificInfo); uint8* info = (uint8*)(oscl_malloc(sizeof(uint8) * len)); if (!info) return false; // malloc failed (unlikely) uint8* destPtr = info; if (numSPS > 0) { for (uint32 i = 0; i < numSPS; i++) { uint16 len = 0; uint8* ptr = NULL; if (getSequenceParamSet(i, len, ptr) == false) { OSCL_FREE(info); return false; } oscl_memcpy(destPtr, &len, sizeof(uint16)); destPtr += sizeof(uint16); oscl_memcpy(destPtr, ptr, len); destPtr += len; } } if (numPPS > 0) { for (uint32 i = 0; i < numPPS; i++) { uint16 len = 0; uint8* ptr = NULL; if (getPictureParamSet(i, len, ptr) == false) { OSCL_FREE(info); return false; } oscl_memcpy(destPtr, &len, sizeof(uint16)); destPtr += sizeof(uint16); oscl_memcpy(destPtr, ptr, len); destPtr += len; } } _decoderSpecificInfo->setInfoSize(len); _decoderSpecificInfo->setInfo(info); } return true; }
// Constructor PVA_FF_AudioSampleEntry::PVA_FF_AudioSampleEntry(PVA_FF_MP4_CODEC_TYPE codecType) : PVA_FF_SampleEntry(FourCharConstToUint32('m', 'p', '4', 'a')) { PV_MP4_FF_NEW(fp->auditCB, PVA_FF_ESDAtom, (MEDIA_TYPE_AUDIO, codecType), _pes); init(); recomputeSize(); _pes->setParent(this); }
// add new track void PVA_FF_MovieFragmentRandomAccessAtom::addTrackFragmentRandomAccessAtom(uint32 trackId) { PVA_FF_TfraAtom* pTfraAtom; PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TfraAtom, ((trackId)), pTfraAtom); _pTfraList->push_back(pTfraAtom); pTfraAtom->setParent(this); recomputeSize(); }
void PVA_FF_AssetInfoKeyWordsAtom::setKeyWord(uint32 aKeyWordBinarySize, PVA_FF_UNICODE_HEAP_STRING aKeyWord) { PVA_FF_AssetInfoKeyWordStruct* keyWordStruct = NULL; PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoKeyWordStruct, (aKeyWordBinarySize, aKeyWord), keyWordStruct); _pKeyWordVect->push_back(keyWordStruct); _keyWordCnt++; recomputeSize(); }
// Constructor PVA_FF_ESDAtom::PVA_FF_ESDAtom(int32 streamType, PVA_FF_MP4_CODEC_TYPE codecType) : PVA_FF_FullAtom(ESD_ATOM, (uint8)0, (uint32)0) { PV_MP4_FF_NEW(fp->auditCB, PVA_FF_ESDescriptor, (streamType, codecType), _pdescriptor); init(); recomputeSize(); _pdescriptor->setParent(this); }
SchemeInformationBox:: SchemeInformationBox(MP4_FF_FILE *fp, uint32 size, uint32 type) : Atom(fp, size, type) { _pOMADRMKMSBox = NULL; if (!_success) { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED) { _mp4ErrorCode = READ_SCHEME_INFORMATION_BOX_FAILED; } return; } uint32 count = (_size - DEFAULT_ATOM_SIZE); while (count > 0) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomType == OMADRM_KMS_BOX) { if (_pOMADRMKMSBox == NULL) { PV_MP4_FF_NEW(fp->auditCB, OMADRMKMSBox, (fp, atomSize, atomType), _pOMADRMKMSBox); if (!_pOMADRMKMSBox->MP4Success()) { _success = false; _mp4ErrorCode = _pOMADRMKMSBox->GetMP4Error(); break; } _pOMADRMKMSBox->setParent(this); } else { _success = false; _mp4ErrorCode = DUPLICATE_OMADRM_KMS_BOX; break; } } else { //skip over atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } count -= atomSize; } return; }
// Constructor - used for a NEW stream (i.e. a new track) PVA_FF_ESDescriptor::PVA_FF_ESDescriptor(int32 streamType, PVA_FF_MP4_CODEC_TYPE codecType) : PVA_FF_BaseDescriptor(0x03) { PV_MP4_FF_NEW(fp->auditCB, PVA_FF_DecoderConfigDescriptor, (streamType, codecType), _pdcd); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SLConfigDescriptor, (), _pslcd); _ESID = 0; // Initialize the ESID, will be set later init(); recomputeSize(); _pdcd->setParent(this); _pslcd->setParent(this); }
// adds new track fragment to the moof void PVA_FF_MovieFragmentAtom::addTrackFragment(uint32 mediaType, uint32 codecType, uint32 trackId, uint32 timescale) { PVA_FF_TrackFragmentAtom* pTrafAtom; PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackFragmentAtom, ((mediaType), (codecType), (trackId), (_interleaveDuration), (timescale)), pTrafAtom); _pTrafList->push_back(pTrafAtom); pTrafAtom->setParent(this); // no need to recompute size. that is called by trun for parent recomputeSize(); return; }
// constructor PVA_FF_MovieFragmentAtom::PVA_FF_MovieFragmentAtom(uint32 sequenceNumber, uint32 movieFragmentDuration, uint32 interleaveDuration) : PVA_FF_Atom(MOVIE_FRAGMENT_ATOM) { _movieFragmentDuration = movieFragmentDuration; _interleaveDuration = interleaveDuration; // Initialise movie fragment header atom PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieFragmentHeaderAtom, ((sequenceNumber)), _pMfhdAtom); _pMfhdAtom->setParent(this); // initialise track fragment list PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackFragmentAtomVecType, (), _pTrafList); recomputeSize(); }
// Stream-in constructor MpegSampleEntry::MpegSampleEntry(MP4_FF_FILE *fp, uint32 size, uint32 type) : SampleEntry(fp, size, type) { _pes = NULL; if (_success) { _pparent = NULL; uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomType == ESD_ATOM) { PV_MP4_FF_NEW(fp->auditCB, ESDAtom, (fp, atomSize, atomType), _pes); if (!_pes->MP4Success()) { _success = false; _mp4ErrorCode = _pes->GetMP4Error(); } else { _pes->setParent(this); } } else { _success = false; _mp4ErrorCode = READ_MPEG_SAMPLE_ENTRY_FAILED; } } else { _mp4ErrorCode = READ_MPEG_SAMPLE_ENTRY_FAILED; } }
void PVA_FF_MediaInformationAtom::init(int32 mediaType) { iMediaType = mediaType; switch (mediaType) { case MEDIA_TYPE_AUDIO: PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SoundMediaHeaderAtom, (), _pmediaInformationHeader); break; case MEDIA_TYPE_VISUAL: PV_MP4_FF_NEW(fp->auditCB, PVA_FF_VideoMediaHeaderAtom, (), _pmediaInformationHeader); break; default: PV_MP4_FF_NEW(fp->auditCB, PVA_FF_Mpeg4MediaHeaderAtom, (mediaType), _pmediaInformationHeader); break; } _pmediaInformationHeader->setParent(this); _pdataInformationAtom->setParent(this); _psampleTableAtom->setParent(this); }
OSCL_EXPORT_REF IMpeg4File *IMpeg4File::readMP4File(OSCL_wString& aFilename, PVMFCPMPluginAccessInterfaceFactory* aCPMAccessFactory, OsclFileHandle* aHandle, uint32 aParsingMode, Oscl_FileServer* aFileServSession) { //optimized mode is not supported if multiple file ptrs are not allowed if (aParsingMode == 1) { #ifndef OPEN_FILE_ONCE_PER_TRACK aParsingMode = 0; #endif } MP4_FF_FILE fileStruct; MP4_FF_FILE *fp = &fileStruct; fp->_fileServSession = aFileServSession; fp->_pvfile.SetCPM(aCPMAccessFactory); fp->_pvfile.SetFileHandle(aHandle); if (AtomUtils::OpenMP4File(aFilename, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, fp) != 0) { return NULL; } uint32 fileSize; AtomUtils::getCurrentFileSize(fp, fileSize); fp->_fileSize = (int32)fileSize; Mpeg4File *mp4 = NULL; PV_MP4_FF_NEW(fp->auditCB, Mpeg4File, (fp, aFilename, aParsingMode), mp4); return mp4; }
ESDAtom::ESDAtom(MP4_FF_FILE *fp, uint32 size, uint32 type) : FullAtom(fp, size, type) { _pdescriptor = NULL; if (_success) { _pparent = NULL; uint8 descr_tag = AtomUtils::peekNextByte(fp); if (descr_tag == ES_DESCRIPTOR_TAG) { PV_MP4_FF_NEW(fp->auditCB, ESDescriptor, (fp), _pdescriptor); if (!_pdescriptor->MP4Success()) { _success = false; _mp4ErrorCode = _pdescriptor->GetMP4Error(); } else { _pdescriptor->setParent(this); } } else { _success = false; _mp4ErrorCode = READ_ESD_ATOM_FAILED; } } else { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED) _mp4ErrorCode = READ_ESD_ATOM_FAILED; } }
// Static method to read in an MP4 file from disk and return the IMpeg4File interface OSCL_EXPORT_REF IMpeg4File* IMpeg4File::readMP4File(OSCL_wString& filename, uint32 parsingMode, Oscl_FileServer* fileServSession) { //optimized mode is not supported if multiple file ptrs are not allowed if (parsingMode == 1) { #ifndef OPEN_FILE_ONCE_PER_TRACK parsingMode = 0; #endif } MP4_FF_FILE fileStruct; MP4_FF_FILE *fp = &fileStruct; fp->_fileServSession = fileServSession; if (AtomUtils::OpenMP4File(filename, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, fp) != 0) { return NULL; } int32 fileSize = 0; int32 filePointer = 0; filePointer = AtomUtils::getCurrentFilePosition(fp); AtomUtils::seekToEnd(fp); fileSize = AtomUtils::getCurrentFilePosition(fp); AtomUtils::seekFromStart(fp, filePointer); fp->_fileSize = fileSize; Mpeg4File *mp4 = NULL; PV_MP4_FF_NEW(fp->auditCB, Mpeg4File, (fp, filename, parsingMode), mp4); return mp4; }
// Constructor PVA_FF_MediaInformationAtom::PVA_FF_MediaInformationAtom(uint32 mediaType, PVA_FF_MP4_CODEC_TYPE codecType, uint32 fileAuthoringFlags, uint32 protocol, uint8 profile, uint8 profileComp, uint8 level) : PVA_FF_Atom(MEDIA_INFORMATION_ATOM) { iMediaType = 0; PV_MP4_FF_NEW(fp->auditCB, PVA_FF_SampleTableAtom, (mediaType, codecType, fileAuthoringFlags, protocol, profile, profileComp, level), _psampleTableAtom); PV_MP4_FF_NEW(fp->auditCB, PVA_FF_DataInformationAtom, (), _pdataInformationAtom); // Create correct PVA_FF_MediaInformationHeaderAtom based on mediaType init(mediaType); recomputeSize(); }
// Stream-in ctor SampleDescriptionAtom::SampleDescriptionAtom(MP4_FF_FILE *fp, uint32 mediaType, uint32 size, uint32 type) : FullAtom(fp, size, type), _pMediaType(mediaType) { _psampleEntryVec = NULL; _pAMRSampleEntryAtom = NULL; _pH263SampleEntryAtom = NULL; _pAVCSampleEntryVec = NULL; _o3GPPAMR = false; _o3GPPH263 = false; _o3GPPWBAMR = false; _oAVC = false; _o3GPPEVRC = false; _o3GPPQCELP = false; _p3GPP2SpeechSampleEntry = NULL; uint32 count = size - DEFAULT_ATOM_SIZE; count -= 4; //for 4-byte handle_type _pProtectionSchemeInformationBox = NULL; if (_success) { if (!AtomUtils::read32(fp, _entryCount)) { _success = false; } count -= 4; int32 tmp = (int32)_entryCount; if (tmp <= 0) { _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } if ((mediaType != MEDIA_TYPE_HINT) && (mediaType != MEDIA_TYPE_TEXT)) { if (tmp > MAX_ALLOWED_MEDIA_SAMPLE_ENTRIES) { _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } if (_success) { PV_MP4_FF_NEW(fp->auditCB, sampleEntryVecType, (), _psampleEntryVec); PV_MP4_FF_NEW(fp->auditCB, AVCSampleEntryVecType, (), _pAVCSampleEntryVec); for (uint32 i = 0; i < _entryCount; i++) { SampleEntry *entry = NULL; uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); count -= atomSize; switch (mediaType) { case MEDIA_TYPE_AUDIO: { if (atomType == ENCRYPTED_AUDIO_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, EcnaBox, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); EcnaBox *ptr = (EcnaBox *)entry; PV_MP4_FF_DELETE(NULL, EcnaBox, ptr); return; } _pProtectionSchemeInformationBox = ((EcnaBox*)entry)->_pProtectionSchemeInformationBox; } else if (atomType == AMR_SAMPLE_ENTRY_ATOM) { if (_o3GPPAMR == false) { PV_MP4_FF_NEW(fp->auditCB, AMRSampleEntry, (fp, atomSize, atomType), _pAMRSampleEntryAtom); if (!_pAMRSampleEntryAtom->MP4Success()) { _success = false; _mp4ErrorCode = _pAMRSampleEntryAtom->GetMP4Error(); PV_MP4_FF_DELETE(NULL, AMRSampleEntry, _pAMRSampleEntryAtom); _pAMRSampleEntryAtom = NULL; return; } else { _pAMRSampleEntryAtom->setParent(this); } _o3GPPAMR = true; } else { // Multiple AMR Sample Entries are illegal _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } else if (atomType == AMRWB_SAMPLE_ENTRY_ATOM) { if (_o3GPPWBAMR == false) { PV_MP4_FF_NEW(fp->auditCB, AMRSampleEntry, (fp, atomSize, atomType), _pAMRSampleEntryAtom); if (!_pAMRSampleEntryAtom->MP4Success()) { _success = false; _mp4ErrorCode = _pAMRSampleEntryAtom->GetMP4Error(); PV_MP4_FF_DELETE(NULL, AMRSampleEntry, _pAMRSampleEntryAtom); _pAMRSampleEntryAtom = NULL; return; } else { _pAMRSampleEntryAtom->setParent(this); } _o3GPPWBAMR = true; } else { // Multiple AMR Sample Entries are illegal _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } else if (atomType == AUDIO_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, AudioSampleEntry, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); AudioSampleEntry *ptr = (AudioSampleEntry *)entry; PV_MP4_FF_DELETE(NULL, AudioSampleEntry, ptr); return; } } else if ((atomType == EVRC_SAMPLE_ENTRY) || (atomType == EVRCB_SAMPLE_ENTRY) || (atomType == EVRCWB_SAMPLE_ENTRY) || (atomType == QCELP_SAMPLE_ENTRY) || (atomType == SMV_SAMPLE_ENTRY) || (atomType == VMR_SAMPLE_ENTRY)) { if (atomType == QCELP_SAMPLE_ENTRY) _o3GPPQCELP = true; else if ((atomType == EVRC_SAMPLE_ENTRY) || (atomType == EVRCB_SAMPLE_ENTRY)) _o3GPPEVRC = true; if (_p3GPP2SpeechSampleEntry == NULL) { PV_MP4_FF_NEW(fp->auditCB, SpeechSampleEntry3GPP2, (fp, atomSize, atomType), _p3GPP2SpeechSampleEntry); if (!_p3GPP2SpeechSampleEntry->MP4Success()) { _success = false; _mp4ErrorCode = _p3GPP2SpeechSampleEntry->GetMP4Error(); PV_MP4_FF_DELETE(NULL, SpeechSampleEntry3GPP2, _p3GPP2SpeechSampleEntry); _p3GPP2SpeechSampleEntry = NULL; return; } else { _p3GPP2SpeechSampleEntry->setParent(this); } } else { // Multiple Sample Entries are illegal _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } else { atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } _handlerType = MEDIA_TYPE_AUDIO; break; } case MEDIA_TYPE_TEXT: { // TIMED_TEXT_SUPPORT start if (atomType == ENCRYPTED_TEXT_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, EnctBox, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); EnctBox *ptr = (EnctBox *)entry; PV_MP4_FF_DELETE(NULL, EnctBox, ptr); return; } _pProtectionSchemeInformationBox = ((EnctBox*)entry)->_pProtectionSchemeInformationBox; } else if (atomType == TEXT_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, TextSampleEntry, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); TextSampleEntry *ptr = (TextSampleEntry *)entry; PV_MP4_FF_DELETE(NULL, TextSampleEntry, ptr); return; } } else // TIMED_TEXT_SUPPORT end { atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } _handlerType = MEDIA_TYPE_TEXT; } break; case MEDIA_TYPE_VISUAL: { if (atomType == ENCRYPTED_VIDEO_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, EcnvBox, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); EcnvBox *ptr = (EcnvBox *)entry; PV_MP4_FF_DELETE(NULL, EcnvBox, ptr); return; } _pProtectionSchemeInformationBox = ((EcnvBox*)entry)->_pProtectionSchemeInformationBox; } else if (atomType == H263_SAMPLE_ENTRY_ATOM) { if (_o3GPPH263 == false) { PV_MP4_FF_NEW(fp->auditCB, H263SampleEntry, (fp, atomSize, atomType), _pH263SampleEntryAtom); if (!_pH263SampleEntryAtom->MP4Success()) { _success = false; _mp4ErrorCode = _pH263SampleEntryAtom->GetMP4Error(); return; } else { _pH263SampleEntryAtom->setParent(this); } _o3GPPH263 = true; } else { // Multiple H263 Sample Entries are illegal _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } else if (atomType == VIDEO_SAMPLE_ENTRY) { PV_MP4_FF_NEW(fp->auditCB, VisualSampleEntry, (fp, atomSize, atomType), entry); if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); VisualSampleEntry *ptr = (VisualSampleEntry *)entry; PV_MP4_FF_DELETE(NULL, VisualSampleEntry, ptr); return; } } else if (atomType == AVC_SAMPLE_ENTRY) { if (_oAVC == false) { AVCSampleEntry* pAVCSampleEntry = NULL; PV_MP4_FF_NEW(fp->auditCB, AVCSampleEntry, (fp, atomSize, atomType), pAVCSampleEntry); if (!pAVCSampleEntry->MP4Success()) { _success = false; _mp4ErrorCode = pAVCSampleEntry->GetMP4Error(); PV_MP4_FF_DELETE(NULL, AVCSampleEntry, pAVCSampleEntry); return; } else { pAVCSampleEntry->setParent(this); } _oAVC = true; if (pAVCSampleEntry != NULL) { (*_pAVCSampleEntryVec).push_back(pAVCSampleEntry); } } else { // Multiple AVC Sample Entries are illegal _success = false; _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED; return; } } else { atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } _handlerType = MEDIA_TYPE_VISUAL; break; } default: { atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } } if (entry != NULL) { if (!entry->MP4Success()) { _success = false; _mp4ErrorCode = entry->GetMP4Error(); break; // Break out of the for loop } else { entry->setParent(this); (*_psampleEntryVec).push_back(entry); } } } // end for loop if (count > 0) { //skip the rest of bytes AtomUtils::seekFromCurrPos(fp, count); } } // end if success } else { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
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; } } }
// Constructor MovieExtendsAtom::MovieExtendsAtom(MP4_FF_FILE *fp, uint32 size, uint32 type) : Atom(fp, size, type) { _pMovieExtendsHeaderAtom = NULL; PV_MP4_FF_NEW(fp->auditCB, trackExtendsAtomVecType, (), _pTrackExtendsAtomVec); uint32 count = size - DEFAULT_ATOM_SIZE; if (_success) { while (count > 0) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomType == MOVIE_EXTENDS_HEADER_ATOM) { if (_pMovieExtendsHeaderAtom == NULL) { PV_MP4_FF_NEW(fp->auditCB, MovieExtendsHeaderAtom, (fp, atomSize, atomType), _pMovieExtendsHeaderAtom); if (!_pMovieExtendsHeaderAtom->MP4Success()) { _success = false; _mp4ErrorCode = READ_MOVIE_EXTENDS_HEADER_FAILED; return; } count -= _pMovieExtendsHeaderAtom->getSize(); } else { //duplicate atom count -= atomSize; atomSize -= DEFAULT_ATOM_SIZE; AtomUtils::seekFromCurrPos(fp, atomSize); } } else if (atomType == TRACK_EXTENDS_ATOM) { TrackExtendsAtom *pTrackExtendsAtom = NULL; PV_MP4_FF_NEW(fp->auditCB, TrackExtendsAtom, (fp, atomSize, atomType), pTrackExtendsAtom); if (!pTrackExtendsAtom->MP4Success()) { _success = false; PV_MP4_FF_DELETE(NULL, TrackExtendsAtom, pTrackExtendsAtom); _mp4ErrorCode = READ_TRACK_EXTENDS_ATOM_FAILED; return; } count -= pTrackExtendsAtom->getSize(); _pTrackExtendsAtomVec->push_back(pTrackExtendsAtom); } } } else { _mp4ErrorCode = READ_MOVIE_EXTENDS_ATOM_FAILED; } }
AVCConfigurationBox::AVCConfigurationBox(MP4_FF_FILE *fp, uint32 size, uint32 type) : Atom(fp, size, type) { _mp4ErrorCode = READ_AVC_CONFIG_BOX_FAILED; _sequenceParameterSetVec = NULL; _pictureParameterSetVec = NULL; _totalSeqParameterSetLength = 0; _totalPicutureParameterSetLength = 0; if (_success) { _success = false; _pparent = NULL; PV_MP4_FF_NEW(fp->auditCB, parameterSetVecType, (), _sequenceParameterSetVec); PV_MP4_FF_NEW(fp->auditCB, parameterSetVecType, (), _pictureParameterSetVec); if (!AtomUtils::read8(fp, _configurationVersion)) { return; } if (!AtomUtils::read8(fp, _avcProfileIndication)) { return; } if (!AtomUtils::read8(fp, _profileCompatibility)) { return; } if (!AtomUtils::read8(fp, _avcLevelIndication)) { return; } _constraint_set0_flag = (uint8)((_profileCompatibility & ~0x7F) >> 7); _constraint_set1_flag = (uint8)((_profileCompatibility & ~0xBF) >> 6); _constraint_set2_flag = (uint8)((_profileCompatibility & ~0xDF) >> 5); _reserved_zero_5bits = 0; if (!AtomUtils::read8(fp, _lengthSizeMinusOne)) { return; } _lengthSizeMinusOne &= LENGTH_SIZE_MINUS_ONE_MASK; if (!AtomUtils::read8(fp, _numSequenceParameterSets)) { return; } _numSequenceParameterSets &= NUM_SEQUENCE_PARAM_SETS_MASK; uint8 i; uint16 parameterSetLen; for (i = 0; i < _numSequenceParameterSets; i++) { if (!AtomUtils::read16(fp, parameterSetLen)) { return; } _totalSeqParameterSetLength += parameterSetLen; ParameterSet *paramSet = NULL; PV_MP4_FF_NEW(fp->auditCB, ParameterSet, (parameterSetLen, fp), paramSet); if (!(paramSet->getSuccess())) { PV_MP4_FF_DELETE(NULL, ParameterSet, paramSet); return; } (*_sequenceParameterSetVec).push_back(paramSet); } if (!AtomUtils::read8(fp, _numPictureParameterSets)) { return; } for (i = 0; i < _numPictureParameterSets; i++) { if (!AtomUtils::read16(fp, parameterSetLen)) { return; } _totalPicutureParameterSetLength += parameterSetLen; ParameterSet *paramSet = NULL; PV_MP4_FF_NEW(fp->auditCB, ParameterSet, (parameterSetLen, fp), paramSet); if (!(paramSet->getSuccess())) { PV_MP4_FF_DELETE(NULL, ParameterSet, paramSet); return; } (*_pictureParameterSetVec).push_back(paramSet); } _success = true; _mp4ErrorCode = EVERYTHING_FINE; } }
EcnaBox::EcnaBox(MP4_FF_FILE *fp, uint32 size, uint32 type) : SampleEntry(fp, size, type) { _pes = NULL; _pparent = NULL; _pProtectionSchemeInformationBox = NULL; _pAMRSpecificAtom = NULL; _pAMRDecSpecInfoArray = NULL; _pAMRWBSpecificAtom = NULL; _pAMRWBDecSpecInfoArray = NULL; int32 count = (_size - DEFAULT_ATOM_SIZE); if (_success) { // Read reserved values if (!AtomUtils::read32read32(fp, _reserved1[0], _reserved1[1])) _success = false; count -= 8; if (!AtomUtils::read16read16(fp, _reserved2, _reserved3)) _success = false; count -= 4; if (!AtomUtils::read32(fp, _reserved4)) _success = false; count -= 4; if (!AtomUtils::read16read16(fp, _timeScale, _reserved5)) _success = false; count -= 4; if (_success) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; while (count > 0) { AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomSize > count) { _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED; break; } count -= atomSize; if (atomType == ESD_ATOM) { PV_MP4_FF_NEW(fp->auditCB, ESDAtom, (fp, atomSize, atomType), _pes); if (!_pes->MP4Success()) { _success = false; _mp4ErrorCode = _pes->GetMP4Error(); break; } else { _pes->setParent(this); } } else if (atomType == AMR_SPECIFIC_ATOM) { PV_MP4_FF_NEW(fp->auditCB, AMRSpecificAtom, (fp, atomSize, atomType), _pAMRSpecificAtom); if (!_pAMRSpecificAtom->MP4Success()) { _success = false; _mp4ErrorCode = READ_AMR_SAMPLE_ENTRY_FAILED; } PV_MP4_FF_NEW(fp->auditCB, decoderSpecificInfoVecType, (), _pAMRDecSpecInfoArray); for (uint32 i = 0; i < 16; i++) { AMRDecoderSpecificInfo *pinfo = NULL; PV_MP4_FF_NEW(fp->auditCB, AMRDecoderSpecificInfo, (fp, true), pinfo); pinfo->_frame_type = (uint8)i; pinfo->_codec_version = _pAMRSpecificAtom->getDecoderVersion(); pinfo->_mode_change_period = _pAMRSpecificAtom->getModeChangePeriod(); pinfo->_mode_set = _pAMRSpecificAtom->getModeSet(); pinfo->_mode_change_neighbour = false; (*_pAMRDecSpecInfoArray).push_back(pinfo); } } else if (atomType == AMRWB_SAMPLE_ENTRY_ATOM) { PV_MP4_FF_NEW(fp->auditCB, AMRSpecificAtom, (fp, atomSize, atomType), _pAMRWBSpecificAtom); if (!_pAMRWBSpecificAtom->MP4Success()) { _success = false; _mp4ErrorCode = READ_AMR_SAMPLE_ENTRY_FAILED; } PV_MP4_FF_NEW(fp->auditCB, decoderSpecificInfoVecType, (), _pAMRWBDecSpecInfoArray); for (uint32 i = 0; i < 16; i++) { AMRDecoderSpecificInfo *pinfo = NULL; PV_MP4_FF_NEW(fp->auditCB, AMRDecoderSpecificInfo, (fp, true), pinfo); pinfo->_frame_type = (uint8)i; pinfo->_codec_version = _pAMRWBSpecificAtom->getDecoderVersion(); pinfo->_mode_change_period = _pAMRWBSpecificAtom->getModeChangePeriod(); pinfo->_mode_set = _pAMRWBSpecificAtom->getModeSet(); pinfo->_mode_change_neighbour = false; (*_pAMRWBDecSpecInfoArray).push_back(pinfo); } } else if (atomType == PROTECTION_SCHEME_INFO_BOX)
ProtectionSchemeInformationBox:: ProtectionSchemeInformationBox(MP4_FF_FILE *fp, uint32 size, uint32 type) : Atom(fp, size, type) { _pSchemeInformationBox = NULL; _pOriginalFormatBox = NULL; if (!_success) { if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED) { _mp4ErrorCode = READ_SCHEME_INFORMATION_BOX_FAILED; } return; } int32 count = (_size - DEFAULT_ATOM_SIZE); while (count > 0) { uint32 atomType = UNKNOWN_ATOM; uint32 atomSize = 0; AtomUtils::getNextAtomType(fp, atomSize, atomType); if (atomType == SCHEME_INFORMATION_BOX) { if (_pSchemeInformationBox == NULL) { PV_MP4_FF_NEW(fp->auditCB, SchemeInformationBox, (fp, atomSize, atomType), _pSchemeInformationBox); if (!_pSchemeInformationBox->MP4Success()) { _success = false; _mp4ErrorCode = _pSchemeInformationBox->GetMP4Error(); break; } _pSchemeInformationBox->setParent(this); } else { //skip over AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE)); } } else if (atomType == ORIGINAL_FORMAT_BOX) { if (_pOriginalFormatBox == NULL) { PV_MP4_FF_NEW(fp->auditCB, OriginalFormatbox, (fp, atomSize, atomType), _pOriginalFormatBox); if (!_pOriginalFormatBox ->MP4Success()) { _success = false; _mp4ErrorCode = _pOriginalFormatBox ->GetMP4Error(); break; } _pOriginalFormatBox ->setParent(this); } else { //skip over AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE)); } } else { //skip over AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE)); } if (atomSize >= DEFAULT_ATOM_SIZE) { //Decrement count count -= atomSize; } else { // Invalid atomSize _success = false; _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE; break; } } if (count < 0) { //count can't be negative. Something went wrong during the read. _success = false; _mp4ErrorCode = READ_SCHEME_INFORMATION_BOX_FAILED; } return; }