blob: f954789a02b00adc21c766454fe17dc7f0a083e8 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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.
* -------------------------------------------------------------------
*/
/*
This PVA_FF_MovieAtom Class fp the main atom class in the MPEG-4 File that stores
all the meta data about the MPEG-4 presentation.
*/
#define IMPLEMENT_MovieAtom
#include "movieatom.h"
#include "atomutils.h"
#include "a_atomdefs.h"
#define MEDIA_TRACK_ID_OFFSET 3
typedef Oscl_Vector<PVA_FF_TrackAtom*, OsclMemAllocator> PVA_FF_TrackAtomVecType;
// Constructor
PVA_FF_MovieAtom::PVA_FF_MovieAtom(uint32 fileAuthoringFlags)
: PVA_FF_Atom(MOVIE_ATOM)
{
_success = true;
_scalability = -1;
_fileType = 0;
// Initializations
_pAssetInfoCopyRightAtom = NULL;
_pAssetInfoAuthorAtom = NULL;
_pAssetInfoTitleAtom = NULL;
_pAssetInfoDescAtom = NULL;
_pAssetInfoPerformerAtom = NULL;
_pAssetInfoGenreAtom = NULL;
_pAssetInfoRatingAtom = NULL;
_pAssetInfoClassificationAtom = NULL;
_pAssetInfoKeyWordsAtom = NULL;
_pAssetInfoLocationInfoAtom = NULL;
_pAssetInfoKeyAlbumAtom = NULL;
_pAssetInfoKeyRecordingYearAtom = NULL;
_oMovieFragmentEnabled = false;
//Movie Fragment : Enable movie fragment mode and create movie extends atom
if ((fileAuthoringFlags & PVMP4FF_MOVIE_FRAGMENT_MODE) == (PVMP4FF_MOVIE_FRAGMENT_MODE))
{
_oMovieFragmentEnabled = true;
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieExtendsAtom, (), _pMovieExtendsAtom);
}
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieHeaderAtom, ((uint8)0, (uint32)0, fileAuthoringFlags), _pmovieHeaderAtom);
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _pMediaTrackVec);
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _pmpeg4TrackVec);
// Create user data atom
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_UserDataAtom, (), _puserDataAtom);
_puserDataAtom->setParent(this);
setTimeScale(DEFAULT_PRESENTATION_TIMESCALE); // Set default value for timescale
recomputeSize();
_pmovieHeaderAtom->setParent(this);
}
// Destructor - delete the vector(s) of TrackAtoms from the heap
PVA_FF_MovieAtom::~PVA_FF_MovieAtom()
{
uint32 i;
PV_MP4_FF_DELETE(NULL, PVA_FF_MovieHeaderAtom, _pmovieHeaderAtom);
// Delete mpeg4 general tracks
for (i = 0; i < _pmpeg4TrackVec->size(); i++)
{
PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, (*_pmpeg4TrackVec)[i]);
}
PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackAtomVecType, Oscl_Vector, _pmpeg4TrackVec);
// Delete media tracks
for (i = 0; i < _pMediaTrackVec->size(); i++)
{
PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, (*_pMediaTrackVec)[i]);
}
PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackAtomVecType, Oscl_Vector, _pMediaTrackVec);
if (_puserDataAtom != NULL)
{
PV_MP4_FF_DELETE(NULL, PVA_FF_UserDataAtom, _puserDataAtom);
}
//Movie Fragment : delete mvex atom
if (_oMovieFragmentEnabled == true)
{
PV_MP4_FF_DELETE(NULL, PVA_FF_MovieExtendsAtom, _pMovieExtendsAtom);
}
}
// Add a new PVA_FF_TrackAtom to this container
void
PVA_FF_MovieAtom::addTrackAtom(PVA_FF_TrackAtom *a)
{
// Set presentation timescale
a->setTimeScale(getTimeScale());
switch (a->getMediaType())
{
case MEDIA_TYPE_TEXT://added for timed text track
{
_fileType |= FILE_TYPE_TIMED_TEXT;
_pMediaTrackVec->push_back(a);
a->setParent(this);
}
break;
case MEDIA_TYPE_AUDIO:
{
_fileType |= FILE_TYPE_AUDIO;
_pMediaTrackVec->push_back(a);
a->setParent(this);
// add trex atom in movie fragment mode
if (_oMovieFragmentEnabled == true)
{
PVA_FF_TrackExtendsAtom *pTrexAtom;
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackExtendsAtom, (a->getMediaType(), a->getCodecType(), a->getTrackID()), pTrexAtom);
_pMovieExtendsAtom->addTrexAtom(pTrexAtom);
}
}
break;
case MEDIA_TYPE_VISUAL:
{
_fileType |= FILE_TYPE_VIDEO;
_scalability += 1;
_pMediaTrackVec->push_back(a);
a->setParent(this);
// add trex atom in movie fragment mode
if (_oMovieFragmentEnabled == true)
{
PVA_FF_TrackExtendsAtom *pTrexAtom;
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackExtendsAtom, (a->getMediaType(), a->getCodecType(), a->getTrackID()), pTrexAtom);
_pMovieExtendsAtom->addTrexAtom(pTrexAtom);
}
}
break;
default:
PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, a);
break;
}
recomputeSize();
}
void
PVA_FF_MovieAtom::setTargetBitRate(uint32 trackID, uint32 bitrate)
{
PVA_FF_TrackAtom *track = getMediaTrack(trackID);
if (track != NULL)
{
track->setTargetBitrate(bitrate);
}
return;
}
void
PVA_FF_MovieAtom::setTimeScale(uint32 trackID, uint32 rate)
{
PVA_FF_TrackAtom *track = getMediaTrack(trackID);
if (track != NULL)
{
track->setMediaTimeScale(rate);
}
return;
}
PVA_FF_TrackAtom*
PVA_FF_MovieAtom::getMpeg4Track(int32 index)
{
if (index < (int32)_pmpeg4TrackVec->size())
{
return (*_pmpeg4TrackVec)[index];
}
else
{
return NULL;
}
}
// timescale for ENTIRE presentation
void
PVA_FF_MovieAtom::setTimeScale(uint32 ts)
{
// Set timescale in movieheader atom
_pmovieHeaderAtom->setTimeScale(ts);
}
// Get timescale from movieheader atom for ENTIRE presentation
uint32
PVA_FF_MovieAtom::getTimeScale() const
{
return _pmovieHeaderAtom->getTimeScale();
}
// Recomputes the size of the current atom by checking all contained atoms
void
PVA_FF_MovieAtom::recomputeSize()
{
int32 size = getDefaultSize(); // From base class
size += _pmovieHeaderAtom->getSize();
if (_puserDataAtom != NULL)
{
if (_puserDataAtom->getUserDataAtomVecSize() > 0)
{
size += _puserDataAtom->getSize();
}
}
if (_pMediaTrackVec != NULL)
{
for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
{
if ((*_pMediaTrackVec)[i]->getSampleCount() > 0)
{
size += (*_pMediaTrackVec)[i]->getSize();
}
}
}
// in movie fragment mode add size of mvex
if (_oMovieFragmentEnabled == true)
{
size += _pMovieExtendsAtom->getSize();
}
_size = size;
// Update the size of the parent atom since this child atom may have changed
if (_pparent != NULL)
{
_pparent->recomputeSize();
}
}
void
PVA_FF_MovieAtom::prepareToRender()
{
uint32 maxTrackDuration = 0;
uint32 creationTime = _pmovieHeaderAtom->getCreationTime();
uint32 modTime = _pmovieHeaderAtom->getModificationTime();
if (_pMediaTrackVec != NULL)
{
for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
{
PVA_FF_TrackAtom *track = (*_pMediaTrackVec)[i];
PVA_FF_TrackHeaderAtom *tkhdPtr = track->getTrackHeaderAtomPtr();
if (tkhdPtr != NULL)
{
tkhdPtr->setCreationTime(creationTime);
tkhdPtr->setModificationTime(modTime);
}
track->prepareToRender();
uint32 TrackDuration = track->getDuration();
if (TrackDuration > maxTrackDuration)
{
maxTrackDuration = TrackDuration;
}
}
if (maxTrackDuration > 0)
{
_pmovieHeaderAtom->setDuration(maxTrackDuration);
}
}
recomputeSize();
return;
}
// Render this atom to a file stream
bool
PVA_FF_MovieAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp)
{
int32 rendered = 0; // Keep track of number of bytes rendered
// Render PVA_FF_Atom type and size
if (!renderAtomBaseMembers(fp))
{
return false;
}
rendered += getDefaultSize();
// Render rest of atoms in container
// Render the movie header
if (!_pmovieHeaderAtom->renderToFileStream(fp))
{
return false;
}
rendered += _pmovieHeaderAtom->getSize();
{
if (_puserDataAtom != NULL)
{
if (_puserDataAtom->getUserDataAtomVecSize() > 0)
{
if (!_puserDataAtom->renderToFileStream(fp))
{
return false;
}
}
}
}
// Render the object descriptor
if (_pMediaTrackVec != NULL)
{
for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
{
if ((*_pMediaTrackVec)[i]->getSampleCount() > 0)
{
if (!((*_pMediaTrackVec)[i]->renderToFileStream(fp)))
{
return false;
}
rendered += (*_pMediaTrackVec)[i]->getSize();
}
}
}
// render MVEX atom in movie fragment mode
if (_oMovieFragmentEnabled == true)
{
if (_pMovieExtendsAtom->getDuration() == 0)
{
_pMovieExtendsAtom->setMovieFragmentDuration(getDuration());
}
if (!_pMovieExtendsAtom->renderToFileStream(fp))
{
return false;
}
rendered += _pMovieExtendsAtom->getSize();
}
return true;
}
void
PVA_FF_MovieAtom::addDecoderSpecificInfo(PVA_FF_DecoderSpecificInfo *pinfo, int32 trackID)
{
PVA_FF_TrackAtom *mediaTrack = getMediaTrack(trackID);
mediaTrack->addDecoderSpecificInfo(pinfo);
}
//added for timed text
void
PVA_FF_MovieAtom::addTextDecoderSpecificInfo(PVA_FF_TextSampleDescInfo *pinfo, int32 trackID)
{
PVA_FF_TrackAtom *mediaTrack = getMediaTrack(trackID);
mediaTrack->addTextDecoderSpecificInfo(pinfo);
}
int32
PVA_FF_MovieAtom::getCodecType(uint32 trackID)
{
PVA_FF_TrackAtom *track = getMediaTrack(trackID);
if (track != NULL)
{
return (track->getCodecType());
}
else
{
return (-1);
}
}
PVA_FF_TrackAtom*
PVA_FF_MovieAtom::getMediaTrack(uint32 trackID)
{
for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
{
PVA_FF_TrackHeaderAtom *ptkhdr = (*_pMediaTrackVec)[i]->getTrackHeaderAtomPtr();
if (ptkhdr->getTrackID() == trackID)
{
return (*_pMediaTrackVec)[i];
}
}
return NULL;
}
void
PVA_FF_MovieAtom::setMaxBufferSizeDB(uint32 trackID, uint32 max)
{
PVA_FF_TrackAtom *trackAtom = getMediaTrack(trackID);
if (trackAtom != NULL)
{
trackAtom->setMaxBufferSizeDB(max);
}
}
void PVA_FF_MovieAtom::setVideoWidthHeight(uint32 trackID, int16 width, int16 height)
{
PVA_FF_TrackAtom *mediaTrack;
uint32 mediaType = 0;
mediaTrack = getMediaTrack(trackID);
if (mediaTrack != NULL)
{
mediaType = mediaTrack->getMediaType();
if (mediaType == MEDIA_TYPE_VISUAL)
{
mediaTrack->setVideoWidthHeight(width, height);
}
}
}
void
PVA_FF_MovieAtom::addSampleToTrack(uint32 trackID,
uint8 *psample,
uint32 size,
uint32 ts,
uint8 flags,
uint32 baseOffset,
bool oChunkStart)
{
PVA_FF_TrackAtom *mediaTrack;
uint32 mediaType = 0;
mediaTrack = getMediaTrack(trackID);
if (mediaTrack != NULL)
{
mediaType = mediaTrack->getMediaType();
uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
if (mediaTimeScale != 0)
{
uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
// Add sample to movie header so can update its _duration
_pmovieHeaderAtom->addSample(ts_in_milliseconds);
}
}
if (mediaType == MEDIA_TYPE_VISUAL)
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_VISUAL,
psample,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
if (mediaType == MEDIA_TYPE_AUDIO)
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
psample,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
if (mediaType == MEDIA_TYPE_TEXT)
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_TEXT,
psample,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
}
void
PVA_FF_MovieAtom::addTextSampleToTrack(uint32 trackID,
uint8 *psample,
uint32 size,
uint32 ts,
uint8 flags,
int32 index,
uint32 baseOffset,
bool oChunkStart)
{
PVA_FF_TrackAtom *mediaTrack;
uint32 mediaType = 0;
mediaTrack = getMediaTrack(trackID);
if (mediaTrack != NULL)
{
mediaType = mediaTrack->getMediaType();
uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
if (mediaTimeScale != 0)
{
uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
// Add sample to movie header so can update its _duration
_pmovieHeaderAtom->addSample(ts_in_milliseconds);
}
}
if (mediaType == MEDIA_TYPE_TEXT)
{
// Updates the members with the next sample received
mediaTrack->nextTextSample(MEDIA_TYPE_TEXT,
psample,
size,
ts,
flags,
index,
baseOffset,
oChunkStart);
}
}
void
PVA_FF_MovieAtom::addSampleToTrack(uint32 trackID,
Oscl_Vector <OsclMemoryFragment, OsclMemAllocator>& fragmentList,
uint32 size,
uint32 ts,
uint8 flags,
uint32 baseOffset,
bool oChunkStart)
{
PVA_FF_TrackAtom *mediaTrack;
uint32 mediaType = 0;
mediaTrack = getMediaTrack(trackID);
if (mediaTrack != NULL)
{
mediaType = mediaTrack->getMediaType();
uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
if (mediaTimeScale != 0)
{
uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
// Add sample to movie header so can update its _duration
_pmovieHeaderAtom->addSample(ts_in_milliseconds);
}
}
if (mediaType == MEDIA_TYPE_VISUAL)
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_VISUAL,
fragmentList,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
if (mediaType == MEDIA_TYPE_AUDIO)
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
fragmentList,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
if (mediaType == MEDIA_TYPE_TEXT)//added for the support of timed text track
{
// Updates the members with the next sample received
mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
fragmentList,
size,
ts,
flags,
baseOffset,
oChunkStart);
}
}
void
PVA_FF_MovieAtom::addTextSampleToTrack(uint32 trackID,
Oscl_Vector <OsclMemoryFragment, OsclMemAllocator>& fragmentList,
uint32 size,
uint32 ts,
uint8 flags,
int32 index,
uint32 baseOffset,
bool oChunkStart)
{
PVA_FF_TrackAtom *mediaTrack;
uint32 mediaType = 0;
mediaTrack = getMediaTrack(trackID);
if (mediaTrack != NULL)
{
mediaType = mediaTrack->getMediaType();
uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
if (mediaTimeScale != 0)
{
uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
// Add sample to movie header so can update its _duration
_pmovieHeaderAtom->addSample(ts_in_milliseconds);
}
}
if (mediaType == MEDIA_TYPE_TEXT)//added for the support of timed text track
{
// Updates the members with the next sample received
mediaTrack->nextTextSample(MEDIA_TYPE_TEXT,
fragmentList,
size,
ts,
flags,
index,
baseOffset,
oChunkStart);
}
}
bool
PVA_FF_MovieAtom::reAuthorFirstSampleInTrack(uint32 trackID,
uint32 size,
uint32 baseOffset)
{
PVA_FF_TrackAtom *mediaTrack;
mediaTrack = getMediaTrack(trackID);
return (
mediaTrack->reAuthorFirstSample(size,
baseOffset));
}
void
PVA_FF_MovieAtom::populateCommonMetadataAtoms()
{
if (_pAssetInfoCopyRightAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoCopyRightAtom, (), _pAssetInfoCopyRightAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoCopyRightAtom);
}
}
if (_pAssetInfoAuthorAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoAuthorAtom, (), _pAssetInfoAuthorAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoAuthorAtom);
}
}
if (_pAssetInfoTitleAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoTitleAtom, (), _pAssetInfoTitleAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoTitleAtom);
}
}
if (_pAssetInfoDescAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoDescAtom, (), _pAssetInfoDescAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoDescAtom);
}
}
}
void
PVA_FF_MovieAtom::createAssetInfoAtoms()
{
populateCommonMetadataAtoms();
if (_pAssetInfoPerformerAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoPerformerAtom, (), _pAssetInfoPerformerAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoPerformerAtom);
}
}
if (_pAssetInfoGenreAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoGenreAtom, (), _pAssetInfoGenreAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoGenreAtom);
}
}
if (_pAssetInfoRatingAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoRatingAtom, (), _pAssetInfoRatingAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoRatingAtom);
}
}
if (_pAssetInfoClassificationAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoClassificationAtom, (), _pAssetInfoClassificationAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoClassificationAtom);
}
}
if (_pAssetInfoKeyWordsAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoKeyWordsAtom, (), _pAssetInfoKeyWordsAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoKeyWordsAtom);
}
}
if (_pAssetInfoLocationInfoAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoLocationInfoAtom, (), _pAssetInfoLocationInfoAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoLocationInfoAtom);
}
}
if (_pAssetInfoKeyAlbumAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoAlbumAtom, (), _pAssetInfoKeyAlbumAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoKeyAlbumAtom);
}
}
if (_pAssetInfoKeyRecordingYearAtom == NULL)
{
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoRecordingYearAtom, (), _pAssetInfoKeyRecordingYearAtom);
if (_puserDataAtom != NULL)
{
_puserDataAtom->addAtom(_pAssetInfoKeyRecordingYearAtom);
}
}
}
// functions to set and update fragment duration in MVEX atom
void
PVA_FF_MovieAtom::setMovieFragmentDuration()
{
_pMovieExtendsAtom->setMovieFragmentDuration(getDuration());
}
void
PVA_FF_MovieAtom::updateMovieFragmentDuration(uint32 trackID, uint32 ts)
{
PVA_FF_TrackAtom *mediaTrack;
mediaTrack = getMediaTrack(trackID);
uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
if (mediaTimeScale != 0)
{
uint32 ts_moviescale = (uint32)(ts * ((float)getTimeScale() / (float)mediaTimeScale));
_pMovieExtendsAtom->updateMovieFragmentDuration(ts_moviescale);
}
}
void
PVA_FF_MovieAtom::writeMovieFragmentDuration(MP4_AUTHOR_FF_FILE_IO_WRAP* fp)
{
_pMovieExtendsAtom->writeMovieFragmentDuration(fp);
}
void
PVA_FF_MovieAtom::SetMaxSampleSize(uint32 aTrackID, uint32 aSize)
{
PVA_FF_TrackAtom *mediaTrack = NULL;
mediaTrack = getMediaTrack(aTrackID);
if (NULL != mediaTrack)
mediaTrack->SetMaxSampleSize(aSize);
}
void
PVA_FF_MovieAtom::writeMaxSampleSize(MP4_AUTHOR_FF_FILE_IO_WRAP *_afp)
{
for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
{
PVA_FF_TrackHeaderAtom *ptkhdr = NULL;
ptkhdr = (*_pMediaTrackVec)[i]->getTrackHeaderAtomPtr();
if (NULL != ptkhdr)
{
uint32 trackID = ptkhdr->getTrackID();
PVA_FF_TrackAtom *mediaTrack = NULL;
mediaTrack = getMediaTrack(trackID);
if (NULL != mediaTrack)
mediaTrack->writeMaxSampleSize(_afp);
}
}
}