Home | History | Annotate | Download | only in src
      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     This PVA_FF_MediaDataAtom Class contains the media data.  This class can operate in
     20     either one of two ways - 1. it can store all it's data in memory (such as
     21     during the creation of PVA_FF_ObjectDescriptor streams), or 2. it can maintain all
     22     it's data on disk (such as during the creation ofmedia streams - i.e. audio
     23     and video).
     24 
     25     Note that during reading in this atom from a file stream, the type fp forced
     26     to MEDIA_DATA_ON_DISK thereby keeping all the object data in the physical
     27     file.
     28 */
     29 
     30 #define IMPLEMENT_MediaDataAtom
     31 
     32 #include "mediadataatom.h"
     33 #include "atomutils.h"
     34 #include "a_atomdefs.h"
     35 #include "oscl_byte_order.h"
     36 #include "oscl_bin_stream.h"
     37 
     38 #define TEMP_TO_TARGET_FILE_COPY_BLOCK_SIZE 1024
     39 
     40 typedef Oscl_Vector<PVA_FF_Renderable*, OsclMemAllocator> PVA_FF_RenderableVecType;
     41 typedef Oscl_Vector<PVA_FF_TrackAtom*, OsclMemAllocator> PVA_FF_TrackAtomVecType;
     42 
     43 // Constructor
     44 PVA_FF_MediaDataAtom::PVA_FF_MediaDataAtom(PVA_FF_UNICODE_STRING_PARAM outputPathString,
     45         PVA_FF_UNICODE_STRING_PARAM postfixString,
     46         int32 tempFileIndex,
     47         int32 type,
     48         void  *osclFileServerSession,
     49         uint32 aCacheSize)
     50         : PVA_FF_Atom(MEDIA_DATA_ATOM)
     51 {
     52     _osclFileServerSession = osclFileServerSession;
     53 
     54     _success = true;
     55     _prenderables = NULL;
     56     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_RenderableVecType, (), _prenderables);
     57     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _ptrackReferencePtrVec);
     58 
     59     // ADDED TO CHECK FOR ANY FILE WRITE FAILURES
     60     _fileWriteError = false;
     61     _targetFileWriteError = false;
     62     _directRender = false;
     63     _oIsFileOpen = false;
     64 
     65     _fileSize = 0;
     66     _fileOffsetForChunkStart = 0;
     67     _fileOffsetForAtomStart = 0;
     68     _type = type;
     69 
     70     _pofstream._filePtr = NULL;
     71     _ptrackReferencePtr = NULL;
     72     _targetFileMediaStartOffset = 0;
     73     _totalDataRenderedToTargetFile = 0;
     74 
     75     _tempFilePostfix = postfixString;
     76 
     77     _tempFilename = outputPathString;
     78 
     79     _tempFileIndex = tempFileIndex;
     80 
     81     recomputeSize();
     82 
     83     // Preparing the temp output file for rendering the atom data
     84     if (_type == MEDIA_DATA_ON_DISK)
     85     {
     86         prepareTempFile(aCacheSize);
     87     }
     88 }
     89 
     90 PVA_FF_MediaDataAtom::PVA_FF_MediaDataAtom(PVA_FF_UNICODE_STRING_PARAM targetFileName,
     91         void  *osclFileServerSession, uint32 aCacheSize)
     92         : PVA_FF_Atom(MEDIA_DATA_ATOM)
     93 {
     94     _type = MEDIA_DATA_ON_DISK;
     95 
     96     _osclFileServerSession = osclFileServerSession;
     97     _targetFileMediaStartOffset = 0;
     98     _totalDataRenderedToTargetFile = 0;
     99     _prenderables = NULL;
    100     _success = true;
    101     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_RenderableVecType, (), _prenderables);
    102     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _ptrackReferencePtrVec);
    103 
    104 
    105     // ADDED TO CHECK FOR ANY FILE WRITE FAILURES
    106     _fileWriteError = false;
    107     _targetFileWriteError = false;
    108     _fileSize = 0;
    109     _fileOffsetForChunkStart = 0;
    110     _fileOffsetForAtomStart = 0;
    111 
    112     _directRender = true;
    113 
    114     _ptrackReferencePtr = NULL;
    115 
    116     recomputeSize();
    117 
    118     _pofstream._filePtr = NULL;
    119     _pofstream._osclFileServerSession = OSCL_STATIC_CAST(Oscl_FileServer*, _osclFileServerSession);
    120 
    121 
    122     int retVal = PVA_FF_AtomUtils::openFile(&_pofstream, targetFileName, Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, aCacheSize);
    123     _oIsFileOpen = true;
    124 
    125     if (_pofstream._filePtr == NULL)
    126     {
    127         _fileWriteError = true;
    128     }
    129     else if (retVal == 0)
    130     {
    131         _targetFileWriteError = true;
    132         if (_pofstream._filePtr != NULL)
    133         {
    134             PVA_FF_AtomUtils::closeFile(&_pofstream);
    135             _pofstream._filePtr = NULL;
    136         }
    137     }
    138 }
    139 
    140 PVA_FF_MediaDataAtom::PVA_FF_MediaDataAtom(MP4_AUTHOR_FF_FILE_HANDLE targetFileHandle,
    141         void  *osclFileServerSession, uint32 aCacheSize)
    142         : PVA_FF_Atom(MEDIA_DATA_ATOM)
    143 {
    144     OSCL_UNUSED_ARG(aCacheSize);
    145     _type = MEDIA_DATA_ON_DISK;
    146 
    147     _osclFileServerSession = osclFileServerSession;
    148     _targetFileMediaStartOffset = 0;
    149     _totalDataRenderedToTargetFile = 0;
    150     _prenderables = NULL;
    151 
    152     _success = true;
    153     // _ptrackReferencePtrVec = new Oscl_Vector<PVA_FF_TrackAtom*,OsclMemAllocator>();
    154     // _prenderables = new Oscl_Vector<PVA_FF_Renderable*,OsclMemAllocator>();
    155 
    156     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_RenderableVecType, (), _prenderables);
    157     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _ptrackReferencePtrVec);
    158 
    159 
    160 
    161     // ADDED TO CHECK FOR ANY FILE WRITE FAILURES
    162     _fileWriteError = false;
    163     _targetFileWriteError = false;
    164 
    165     _fileSize = 0;
    166     _fileOffsetForChunkStart = 0;
    167     _fileOffsetForAtomStart = 0;
    168     _oIsFileOpen = false;
    169     _directRender = true;
    170 
    171     _ptrackReferencePtr = NULL;
    172 
    173     recomputeSize();
    174 
    175     _pofstream._filePtr = targetFileHandle;
    176 
    177     if (_pofstream._filePtr == NULL)
    178     {
    179         _fileWriteError = true;
    180     }
    181 }
    182 
    183 // Destructor
    184 PVA_FF_MediaDataAtom::~PVA_FF_MediaDataAtom()
    185 {
    186     if (_pofstream._filePtr != NULL && true == _oIsFileOpen)
    187     {
    188         PVA_FF_AtomUtils::closeFile(&_pofstream);
    189         _pofstream._filePtr = NULL;
    190     }
    191 
    192     // PVA_FF_TrackAtom *_ptrackReferencePtr - is taken care of by the movie atom
    193     // Delete vector<PVA_FF_Renderable*> *_prenderables
    194     if (_prenderables != NULL)
    195     {
    196         for (uint32 i = 0; i < _prenderables->size(); i++)
    197         {
    198             if ((*_prenderables)[i] != NULL)
    199             {
    200                 OSCL_DELETE((*_prenderables)[i]);
    201                 //PV_MP4_FF_DELETE(NULL,PVA_FF_Renderable,(*_prenderables)[i]);
    202                 (*_prenderables)[i] = NULL;
    203             }
    204         }
    205         PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_RenderableVecType, Oscl_Vector, _prenderables);
    206         _prenderables = NULL;
    207     }
    208 
    209     //Contents of this array are deleted in movie atom
    210     //OSCL_DELETE(_ptrackReferencePtrVec);
    211 
    212     PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackAtomVecType, Oscl_Vector, _ptrackReferencePtrVec);
    213 
    214     Oscl_FileServer fileServ;
    215     fileServ.Connect();
    216     fileServ.Oscl_DeleteFile(_tempFilename.get_cstr());
    217     fileServ.Close();
    218 }
    219 
    220 // Create the atom temp file and the corresponding ofstream
    221 void
    222 PVA_FF_MediaDataAtom::prepareTempFile(uint32 aCacheSize)
    223 {
    224     if (_pofstream._filePtr == NULL && !_fileWriteError)
    225     {
    226         // 05/31/01 Generate temporary files into output path (the actual mp4 location)
    227         // _tempFilename already contains the output path ("drive:\\...\\...\\")
    228         //
    229         _tempFilename += _STRLIT("temp");
    230         // Assign the rest of the temp filename - index plus suffix
    231         _tempFilename += (uint16)(_tempFileIndex++);
    232 
    233         // 03/21/01 Multiple instances support
    234         _tempFilename += _STRLIT("_");
    235         _tempFilename += _tempFilePostfix;
    236         //
    237 
    238         _tempFilename += _STRLIT(".mdat");
    239 
    240         _pofstream._osclFileServerSession = OSCL_STATIC_CAST(Oscl_FileServer*, _osclFileServerSession);
    241 
    242         PVA_FF_AtomUtils::openFile(&_pofstream, _tempFilename, Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, aCacheSize);
    243 
    244         if (_pofstream._filePtr == NULL)
    245         {
    246             _fileWriteError = true;
    247         }
    248         else
    249         {
    250             _oIsFileOpen = true;
    251         }
    252 
    253         // Render the atoms base members to the media data atom file
    254         renderAtomBaseMembers(&_pofstream);
    255 
    256         _fileOffsetForChunkStart = getDefaultSize();
    257         _fileSize = getDefaultSize();
    258     }
    259 }
    260 
    261 bool
    262 PVA_FF_MediaDataAtom::prepareTargetFile(uint32 mediaStartOffset)
    263 {
    264     if (_directRender)
    265     {
    266         if ((_pofstream._filePtr != NULL) && (_fileWriteError != true))
    267         {
    268             if (mediaStartOffset > 0)
    269             {
    270                 // Write zeros to accomodate the user data upfront
    271                 uint8* tempBuffer = NULL;
    272                 PV_MP4_FF_ARRAY_NEW(NULL, uint8, mediaStartOffset, tempBuffer);
    273 
    274                 oscl_memset(tempBuffer, 0, mediaStartOffset);
    275 
    276                 if (!(PVA_FF_AtomUtils::renderByteData(&_pofstream, mediaStartOffset, tempBuffer)))
    277                 {
    278                     PV_MP4_ARRAY_DELETE(NULL, tempBuffer);
    279                     return false;
    280                 }
    281                 PV_MP4_ARRAY_DELETE(NULL, tempBuffer);
    282             }
    283 
    284             // Render the atoms base members to the media data atom file
    285             renderAtomBaseMembers(&_pofstream);
    286 
    287             _fileOffsetForChunkStart = getDefaultSize();
    288             _fileSize = getDefaultSize();
    289 
    290             _targetFileMediaStartOffset = mediaStartOffset;
    291 
    292             return true;
    293         }
    294     }
    295     return false;
    296 }
    297 
    298 
    299 uint32
    300 PVA_FF_MediaDataAtom::prepareTargetFileForFragments(uint32 mediaStartOffset)
    301 {
    302     if (_directRender)
    303     {
    304         _targetFileMediaStartOffset = mediaStartOffset;
    305         PVA_FF_AtomUtils::seekFromStart(&_pofstream, _targetFileMediaStartOffset);
    306 
    307         renderAtomBaseMembers(&_pofstream);
    308         _fileOffsetForChunkStart = getDefaultSize();
    309 
    310         _fileSize = getDefaultSize();
    311 
    312         return _fileOffsetForChunkStart;
    313     }
    314 
    315     return 0;
    316 }
    317 
    318 bool
    319 PVA_FF_MediaDataAtom::closeTargetFile()
    320 {
    321     if (_directRender)
    322     {
    323         if ((_pofstream._filePtr != NULL) && (_fileWriteError != true))
    324         {
    325             // Get current position of put pointer
    326             _totalDataRenderedToTargetFile =
    327                 PVA_FF_AtomUtils::getCurrentFilePosition(&_pofstream);
    328 
    329             // Go to the beginning of the media data
    330             PVA_FF_AtomUtils::seekFromStart(&_pofstream, _targetFileMediaStartOffset);
    331 
    332             // Update size field
    333             if (!PVA_FF_AtomUtils::render32(&_pofstream, getSize()))
    334             {
    335                 return false;
    336             }
    337 
    338             // Return the _pofstream's pointer to start
    339             PVA_FF_AtomUtils::seekFromStart(&_pofstream, 0);
    340 
    341             _fileOffsetForChunkStart =
    342                 _targetFileMediaStartOffset + getDefaultSize();
    343 
    344             return true;
    345         }
    346     }
    347     return false;
    348 }
    349 
    350 Oscl_File*
    351 PVA_FF_MediaDataAtom::getTargetFilePtr()
    352 {
    353     return (_pofstream._filePtr);
    354 }
    355 
    356 // Adds more data to the atom then update the atom size field (first 4 bytes)
    357 bool
    358 PVA_FF_MediaDataAtom::addRawSample(void *psample, uint32 length)
    359 {
    360     bool retVal = true;
    361 
    362     if (_type == MEDIA_DATA_ON_DISK)
    363     {
    364         if (!_fileWriteError)
    365         {
    366             if (_pofstream._filePtr == NULL)
    367             {
    368                 if (!_directRender)
    369                 {
    370                     // If initial file fp not opened
    371                     prepareTempFile();
    372                 }
    373                 else
    374                 {
    375                     //File must have been prepared for direct render
    376                     return false;
    377                 }
    378             }
    379 
    380             bool ret = PVA_FF_AtomUtils::renderByteData(&_pofstream, length, (uint8 *)psample);
    381 
    382             if (ret == false)
    383             {
    384                 _fileWriteError = true;
    385                 retVal = false;
    386             }
    387 
    388             _fileSize += length; // Update the size of the atom
    389 
    390             // Update the size of the atom
    391             recomputeSize();
    392         }
    393         else
    394         {
    395             retVal = false;
    396         }
    397     }
    398     else
    399     {
    400         retVal = false;
    401     }
    402 
    403     return (retVal);
    404 }
    405 
    406 bool PVA_FF_MediaDataAtom::addRawSample(Oscl_Vector <OsclMemoryFragment, OsclMemAllocator>& fragmentList,
    407                                         uint32 length, int32 mediaType, int32 codecType)
    408 {
    409     bool retVal = true;
    410     bool ret = true;
    411     uint32 ii = 0;
    412     OsclBinIStreamBigEndian stream;
    413 
    414     if (_type == MEDIA_DATA_ON_DISK)
    415     {
    416         if (!_fileWriteError)
    417         {
    418             if (_pofstream._filePtr == NULL)
    419             {
    420                 if (!_directRender)
    421                 {
    422                     // If initial file fp not opened
    423                     prepareTempFile();
    424                 }
    425                 else
    426                 {
    427                     //File must have been prepared for direct render
    428                     return false;
    429                 }
    430             }
    431 
    432             uint32 nalLength = 0;
    433             if (mediaType == (int32)MEDIA_TYPE_VISUAL && codecType == CODEC_TYPE_AVC_VIDEO)
    434             {
    435                 for (ii = 0; ii < fragmentList.size(); ii++)
    436                 {
    437                     // read NAL length in Big Endian format
    438                     stream.Attach((OsclAny*) &(fragmentList[ii].len), 4);
    439                     stream >> nalLength;
    440 
    441                     // compose nal length in two bytes
    442                     ret = PVA_FF_AtomUtils::renderByteData(&_pofstream, 4, (uint8 *) & nalLength);
    443                     if (ret == false)
    444                     {
    445                         _fileWriteError = true;
    446                         retVal = false;
    447                     }
    448 
    449                     // write NAL uint
    450                     ret = PVA_FF_AtomUtils::renderByteData(&_pofstream, fragmentList[ii].len, (uint8 *)fragmentList[ii].ptr);
    451                     if (ret == false)
    452                     {
    453                         _fileWriteError = true;
    454                         retVal = false;
    455                     }
    456                 }
    457             }
    458             else
    459             {
    460                 for (ii = 0; ii < fragmentList.size(); ii++)
    461                 {
    462                     ret = PVA_FF_AtomUtils::renderByteData(&_pofstream, fragmentList[ii].len, (uint8 *)fragmentList[ii].ptr);
    463                 }
    464 
    465             }
    466 
    467             if (ret == false)
    468             {
    469                 _fileWriteError = true;
    470                 retVal = false;
    471             }
    472 
    473             _fileSize += length; // Update the size of the atom
    474 
    475             // Update the size of the atom
    476             recomputeSize();
    477         }
    478         else
    479         {
    480             retVal = false;
    481         }
    482     }
    483     else
    484     {
    485         retVal = false;
    486     }
    487 
    488     return (retVal);
    489 }
    490 
    491 int32
    492 PVA_FF_MediaDataAtom::addRenderableSample(PVA_FF_Renderable *psample)
    493 {
    494     if (_type == MEDIA_DATA_ON_DISK)
    495     {
    496         // Force renderables to
    497         // be written to disk
    498         uint32 length = psample->getSize();
    499         psample->renderToFileStream(&_pofstream);
    500         _fileSize += length;
    501 
    502         recomputeSize();
    503         return length;
    504     }
    505     else
    506     {
    507         // MEDIA_DATA_IN_MEMORY
    508         PVA_FF_Renderable *prenderable = (PVA_FF_Renderable*) psample;
    509         _prenderables->push_back(prenderable);
    510 
    511         recomputeSize();
    512         return prenderable->getSize();
    513     }
    514 }
    515 
    516 
    517 // Allocates in-memory space for the media data
    518 void
    519 PVA_FF_MediaDataAtom::reserveBuffer(int32 size)
    520 {
    521     OSCL_UNUSED_ARG(size);
    522 }
    523 
    524 void
    525 PVA_FF_MediaDataAtom::recomputeSize()
    526 {
    527     if (_type == MEDIA_DATA_ON_DISK)
    528     {
    529         // Entire atom size fp same as atom file size
    530         if (_fileSize == 0)
    531         {
    532             _size = getDefaultSize();
    533         }
    534         else
    535         {
    536             _size = _fileSize;
    537         }
    538     }
    539     else
    540     { // MEDIA_DATA_IN_MEMORY
    541 
    542         uint32 size = getDefaultSize();
    543 
    544         // Include size from actual data payload
    545 
    546         // From renderable data
    547         for (uint32 i = 0; i < _prenderables->size(); i++)
    548         {
    549             size += (*_prenderables)[i]->getSize();
    550         }
    551 
    552         _size = size;
    553     }
    554 }
    555 
    556 uint32
    557 PVA_FF_MediaDataAtom::getMediaDataSize()
    558 {
    559     recomputeSize();
    560 
    561     uint32 size = getSize();
    562 
    563     return (size);
    564 }
    565 
    566 // Rendering the PVA_FF_Atom in proper format (bitlengths, etc.) to an ostream
    567 bool
    568 PVA_FF_MediaDataAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp)
    569 {
    570 
    571     int32 rendered = 0; // Keep track of number of bytes rendered
    572 
    573     // Render the data
    574     if (_type == MEDIA_DATA_IN_MEMORY)
    575     {
    576 
    577         // Render in-memory data directoy to disk
    578         // From renderable data
    579 
    580         // Render PVA_FF_Atom type and size
    581         if (!renderAtomBaseMembers(fp))
    582         {
    583             return false;
    584         }
    585         rendered += getDefaultSize();
    586 
    587         // BREAKING CONST RULES!!!
    588 
    589         // Need to set the actual file offset where the actual chunk data begins
    590         // so before rendering the ChunkOffetAtom, we can shift the PVA_FF_ChunkOffsetAtom
    591         // table elements by this offset - the table elements are actual file offsets
    592         // and NOT just offsets from the first chunk (i.e. zero) and we don't really
    593         // know this offset until now.
    594         PVA_FF_MediaDataAtom *This = const_cast<PVA_FF_MediaDataAtom*>(this);
    595         This->setFileOffsetForChunkStart(PVA_FF_AtomUtils::getCurrentFilePosition(fp));
    596 
    597         for (uint32 i = 0; i < _prenderables->size(); i++)
    598         {
    599             if (!(*_prenderables)[i]->renderToFileStream(fp))
    600             {
    601                 return false;
    602             }
    603             rendered += (*_prenderables)[i]->getSize();
    604         }
    605     }
    606     else
    607     {
    608         // MEDIA_DATA_ON_DISK
    609         // 05/30/01 CPU problem when the file fp big.
    610         // We update the size at the end not for every sample.
    611         // Need to update the atoms size field on disk
    612         int32 currentPos = PVA_FF_AtomUtils::getCurrentFilePosition(&_pofstream);    // Get current position of put pointer
    613         PVA_FF_AtomUtils::seekFromStart(&_pofstream, 0);          // Go to the beginning of the file
    614         if (!PVA_FF_AtomUtils::render32(&_pofstream, getSize()))
    615         {
    616             return false;
    617         }
    618         // Update size field
    619         PVA_FF_AtomUtils::seekFromStart(&_pofstream, currentPos); // Return the ostream's put pointer
    620 
    621         // Cleanup and close temp data output file
    622         if (_pofstream._filePtr != NULL)
    623         {
    624             PVA_FF_AtomUtils::closeFile(&_pofstream);
    625             _pofstream._filePtr = NULL;
    626         }
    627 
    628         // Open the file in which this mdat atom was stored
    629         MP4_AUTHOR_FF_FILE_IO_WRAP mdatFilePtr;
    630         mdatFilePtr._filePtr = NULL;
    631         mdatFilePtr._osclFileServerSession = OSCL_STATIC_CAST(Oscl_FileServer*, _osclFileServerSession);
    632         PVA_FF_AtomUtils::openFile(&mdatFilePtr, _tempFilename, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY);
    633 
    634         // Seek to the offset in the file where the ATOM starts
    635         PVA_FF_AtomUtils::seekFromStart(&mdatFilePtr, _fileOffsetForAtomStart);
    636 
    637         // In the case where the mdat atom fp stored on disk file,
    638         // the atom just gets directly copied - i.e. there fp no atom-specific
    639         // rendering.  We need to adjust the fileOffset by the size of the
    640         // atom header (based on what the header "should" be).
    641 
    642         // BREAKING CONST RULES!!!
    643 
    644         // Need to set the actual file offset where the actual chunk data begins
    645         // so before rendering the ChunkOffetAtom, we can shift the PVA_FF_ChunkOffsetAtom
    646         // table elements by this offset - the table elements are actual file offsets
    647         // and NOT just offsets from the first chunk (i.e. zero) and we don't really
    648         // know this offset until now (during rendering).
    649         PVA_FF_MediaDataAtom *This = const_cast<PVA_FF_MediaDataAtom*>(this);
    650         This->setFileOffsetForChunkStart((uint32)(PVA_FF_AtomUtils::getCurrentFilePosition(fp)) +
    651                                          (uint32)getDefaultSize());
    652 
    653         // Read in atom from separate file and copy byte-by-byte to new ofstream
    654         // (including the mediaDataAtom header - 4 byte size ad 4 byte type)
    655 
    656         uint32 readBlockSize = 0;
    657         uint32 tempFileSize  = getSize();
    658 
    659         uint8 *dataBuf = NULL;
    660 
    661         PV_MP4_FF_ARRAY_NEW(NULL, uint8, TEMP_TO_TARGET_FILE_COPY_BLOCK_SIZE, dataBuf);
    662 
    663         while (tempFileSize > 0)
    664         {
    665             if (tempFileSize < TEMP_TO_TARGET_FILE_COPY_BLOCK_SIZE)
    666             {
    667                 readBlockSize = tempFileSize;
    668             }
    669             else
    670             {
    671                 readBlockSize = TEMP_TO_TARGET_FILE_COPY_BLOCK_SIZE;
    672             }
    673 
    674             if (!(PVA_FF_AtomUtils::readByteData(&mdatFilePtr, readBlockSize, dataBuf)))
    675             {
    676                 _targetFileWriteError = true;
    677                 return false;
    678             }
    679 
    680             if (!(PVA_FF_AtomUtils::renderByteData(fp, readBlockSize, dataBuf)))
    681             {
    682                 _targetFileWriteError = true;
    683                 return false;
    684             }
    685             tempFileSize -= readBlockSize;
    686         }
    687 
    688         PV_MP4_FF_DELETE(NULL, uint8, dataBuf);
    689 
    690         rendered += _fileSize;
    691 
    692         PVA_FF_AtomUtils::closeFile(&mdatFilePtr);
    693 
    694     }
    695 
    696     return true;
    697 }
    698 
    699