• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
PVA_FF_MediaDataAtom(PVA_FF_UNICODE_STRING_PARAM outputPathString,PVA_FF_UNICODE_STRING_PARAM postfixString,int32 tempFileIndex,int32 type,void * osclFileServerSession,uint32 aCacheSize)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 
PVA_FF_MediaDataAtom(PVA_FF_UNICODE_STRING_PARAM targetFileName,void * osclFileServerSession,uint32 aCacheSize)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 
PVA_FF_MediaDataAtom(MP4_AUTHOR_FF_FILE_HANDLE targetFileHandle,void * osclFileServerSession,uint32 aCacheSize)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
~PVA_FF_MediaDataAtom()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
prepareTempFile(uint32 aCacheSize)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
prepareTargetFile(uint32 mediaStartOffset)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
prepareTargetFileForFragments(uint32 mediaStartOffset)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
closeTargetFile()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*
getTargetFilePtr()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
addRawSample(void * psample,uint32 length)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 
addRawSample(Oscl_Vector<OsclMemoryFragment,OsclMemAllocator> & fragmentList,uint32 length,int32 mediaType,int32 codecType)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
addRenderableSample(PVA_FF_Renderable * psample)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
reserveBuffer(int32 size)519 PVA_FF_MediaDataAtom::reserveBuffer(int32 size)
520 {
521     OSCL_UNUSED_ARG(size);
522 }
523 
524 void
recomputeSize()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
getMediaDataSize()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
renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP * fp)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