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