/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ #define IMPLEMENT_TrackFragmentAtom #include "trackfragmentatom.h" #include "trackfragmentrunatom.h" typedef Oscl_Vector uint32VecType; typedef Oscl_Vector uint8VecType; typedef Oscl_Vector PVA_FF_TrackFragmentRunAtomVecType; // 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(); } //destructor PVA_FF_TrackFragmentAtom::~PVA_FF_TrackFragmentAtom() { // delete track fragment header PV_MP4_FF_DELETE(NULL, PVA_FF_TrackFragmentHeaderAtom, _pTfhdAtom); // Delete trum atom list for (uint32 ii = 0; ii < _pTrunList->size(); ii++) { PV_MP4_FF_DELETE(NULL, PVA_FF_TrackFragmentRunAtom, (*_pTrunList)[ii]); } PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackFragmentRunAtomVecType, Oscl_Vector, _pTrunList); } // add new TRUN in the list PVA_FF_TrackFragmentRunAtom* PVA_FF_TrackFragmentAtom::addTrackRun() { PVA_FF_TrackFragmentRunAtom *pTrunAtom; PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackFragmentRunAtom, (), pTrunAtom); _pTrunList->push_back(pTrunAtom); pTrunAtom->setParent(this); recomputeSize(); return pTrunAtom; } // add new sample into track fragment inturn into TRUN void PVA_FF_TrackFragmentAtom::addSampleToFragment(uint32 size, uint32 ts, uint8 flags, uint32 baseOffset, bool otrunStart) { if (otrunStart == false) { // add sample to current Trun PVA_FF_TrackFragmentRunAtom* pTrunAtom; pTrunAtom = _pTrunList->back(); pTrunAtom->addSample(size, ts, flags); } else { // make new trun PVA_FF_TrackFragmentRunAtom* pTrunAtom = addTrackRun(); if (_ofirstTrun) { _ofirstTrun = false; setTrackFragmentBaseDataOffset(baseOffset); pTrunAtom->setDataOffset(0); } else { uint32 offset = _pTfhdAtom->getBaseDataOffset(); pTrunAtom->setDataOffset(baseOffset - offset); } pTrunAtom->addSample(size, ts, flags); } // update track fragment duration if (_firstEntry) { _firstEntry = false; _prevTS = ts; } else { uint32 delta = ts - _prevTS; _prevTS = ts; _fragmentDuration = _fragmentDuration + (uint32)((1000.0f / _timescale) * delta + 0.5f); } } void PVA_FF_TrackFragmentAtom::setTrackFragmentHeaderData(uint32 flags) { // currently default headers are there, this function arguments will be defined later OSCL_UNUSED_ARG(flags); _pTfhdAtom->setHeaderData(); } // set base data offset of track fragment void PVA_FF_TrackFragmentAtom::setTrackFragmentBaseDataOffset(uint64 offset) { _pTfhdAtom->setBaseDataOffset(offset); } // recompute size of atom void PVA_FF_TrackFragmentAtom::recomputeSize() { int32 size = getDefaultSize(); // add size of tfhd atom size += _pTfhdAtom->getSize(); // add size of Track run atoms if (_pTrunList->size() != 0) { for (uint32 ii = 0; ii < _pTrunList->size(); ii++) { size += ((*_pTrunList)[ii])->getSize(); } } _size = size; // Update the parent atom size if (_pparent != NULL) { _pparent->recomputeSize(); } } // get functions uint32 PVA_FF_TrackFragmentAtom::getTrackId() { return _pTfhdAtom->getTrackId(); } uint32 PVA_FF_TrackFragmentAtom::getFragmentDuration() { return _fragmentDuration; } uint32 PVA_FF_TrackFragmentAtom::getTrunNumber() { return _pTrunList->size(); } // updates the duration of last sample in TRUN void PVA_FF_TrackFragmentAtom::updateLastTSEntry(uint32 ts) { int32 size = _pTrunList->size(); if (size > 0) { (*_pTrunList)[size -1]->updateLastTSEntry(ts); } return; } // write atom to target file bool PVA_FF_TrackFragmentAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP* fp) { uint32 rendered = 0; if (!renderAtomBaseMembers(fp)) { return false; } rendered += getDefaultSize(); // Render the movie fragment header atom if (!_pTfhdAtom->renderToFileStream(fp)) { return false; } rendered += _pTfhdAtom->getSize(); // render track extend atoms if (_pTrunList->size() != 0) { for (uint32 ii = 0; ii < _pTrunList->size(); ii++) { if (!((*_pTrunList)[ii])->renderToFileStream(fp)) { return false; } rendered += ((*_pTrunList)[ii])->getSize(); } } return true; }