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 #ifndef OMA2BOXES_H_INCLUDED
19 #include "oma2boxes.h"
20 #endif
21
22 #include "h263decoderspecificinfo.h"
23 #include "boxrecord.h"
24 #include "fontrecord.h"
25 #include "stylerecord.h"
26 #include "fonttableatom.h"
27 #include "amrdecoderspecificinfo.h"
28 #include "h263decoderspecificinfo.h"
29
30 typedef Oscl_Vector<DecoderSpecificInfo*, OsclMemAllocator> decoderSpecificInfoVecType;
31
OMADRMKMSBox(MP4_FF_FILE * fp,uint32 size,uint32 type)32 OMADRMKMSBox:: OMADRMKMSBox(MP4_FF_FILE *fp,
33 uint32 size,
34 uint32 type)
35 : FullAtom(fp, size, type)
36 {
37 _pODKMData = NULL;
38
39 if (!_success)
40 {
41 if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
42 {
43 _mp4ErrorCode = READ_OMADRM_KMS_BOX_FAILED;
44 }
45 return;
46 }
47
48 /* Seek back to atom start */
49 AtomUtils::rewindFilePointerByN(fp, DEFAULT_FULL_ATOM_SIZE);
50
51 /* Read the entire contents of the atom into memory */
52 _pODKMData = (uint8*)(oscl_malloc(sizeof(uint8) * (_size)));
53
54 if (!AtomUtils::readByteData(fp, _size, _pODKMData))
55 {
56 _success = false;
57 _mp4ErrorCode = READ_OMADRM_KMS_BOX_FAILED;
58 return;
59 }
60 return;
61 }
62
~OMADRMKMSBox()63 OMADRMKMSBox::~OMADRMKMSBox()
64 {
65 if (_pODKMData != NULL)
66 {
67 oscl_free(_pODKMData);
68 }
69 };
70
MutableDRMInformationBox(MP4_FF_FILE * fp,uint32 size,uint32 type)71 MutableDRMInformationBox:: MutableDRMInformationBox(MP4_FF_FILE *fp,
72 uint32 size,
73 uint32 type)
74 : Atom(fp, size, type)
75 {
76 }
77
SchemeInformationBox(MP4_FF_FILE * fp,uint32 size,uint32 type)78 SchemeInformationBox:: SchemeInformationBox(MP4_FF_FILE *fp,
79 uint32 size,
80 uint32 type)
81 : Atom(fp, size, type)
82 {
83 _pOMADRMKMSBox = NULL;
84
85 if (!_success)
86 {
87 if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
88 {
89 _mp4ErrorCode = READ_SCHEME_INFORMATION_BOX_FAILED;
90 }
91 return;
92 }
93 uint32 count = (_size - DEFAULT_ATOM_SIZE);
94
95 while (count > 0)
96 {
97 uint32 atomType = UNKNOWN_ATOM;
98 uint32 atomSize = 0;
99 AtomUtils::getNextAtomType(fp, atomSize, atomType);
100 if (atomType == OMADRM_KMS_BOX)
101 {
102 if (_pOMADRMKMSBox == NULL)
103 {
104 PV_MP4_FF_NEW(fp->auditCB, OMADRMKMSBox, (fp, atomSize, atomType), _pOMADRMKMSBox);
105
106 if (!_pOMADRMKMSBox->MP4Success())
107 {
108 _success = false;
109 _mp4ErrorCode = _pOMADRMKMSBox->GetMP4Error();
110 break;
111 }
112 _pOMADRMKMSBox->setParent(this);
113 }
114 else
115 {
116 _success = false;
117 _mp4ErrorCode = DUPLICATE_OMADRM_KMS_BOX;
118 break;
119 }
120 }
121 else
122 {
123 //skip over
124 atomSize -= DEFAULT_ATOM_SIZE;
125 AtomUtils::seekFromCurrPos(fp, atomSize);
126 }
127 count -= atomSize;
128 }
129 return;
130 }
131
~SchemeInformationBox()132 SchemeInformationBox::~SchemeInformationBox()
133 {
134 if (_pOMADRMKMSBox != NULL)
135 {
136 PV_MP4_FF_DELETE(NULL, OMADRMKMSBox, _pOMADRMKMSBox);
137 }
138 }
139
ProtectionSchemeInformationBox(MP4_FF_FILE * fp,uint32 size,uint32 type)140 ProtectionSchemeInformationBox:: ProtectionSchemeInformationBox(MP4_FF_FILE *fp,
141 uint32 size,
142 uint32 type)
143 : Atom(fp, size, type)
144 {
145 _pSchemeInformationBox = NULL;
146 _pOriginalFormatBox = NULL;
147
148 if (!_success)
149 {
150 if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
151 {
152 _mp4ErrorCode = READ_SCHEME_INFORMATION_BOX_FAILED;
153 }
154 return;
155 }
156 uint32 count = (_size - DEFAULT_ATOM_SIZE);
157
158 while (count > 0)
159 {
160 uint32 atomType = UNKNOWN_ATOM;
161 uint32 atomSize = 0;
162 AtomUtils::getNextAtomType(fp, atomSize, atomType);
163 if (atomType == SCHEME_INFORMATION_BOX)
164 {
165 if (_pSchemeInformationBox == NULL)
166 {
167 PV_MP4_FF_NEW(fp->auditCB,
168 SchemeInformationBox,
169 (fp, atomSize, atomType),
170 _pSchemeInformationBox);
171
172 if (!_pSchemeInformationBox->MP4Success())
173 {
174 _success = false;
175 _mp4ErrorCode = _pSchemeInformationBox->GetMP4Error();
176 break;
177 }
178 _pSchemeInformationBox->setParent(this);
179 }
180 else
181 {
182 //skip over
183 AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE));
184 }
185 }
186
187 else if (atomType == ORIGINAL_FORMAT_BOX)
188 {
189 if (_pOriginalFormatBox == NULL)
190 {
191 PV_MP4_FF_NEW(fp->auditCB,
192 OriginalFormatbox,
193 (fp, atomSize, atomType),
194 _pOriginalFormatBox);
195
196 if (!_pOriginalFormatBox ->MP4Success())
197 {
198 _success = false;
199 _mp4ErrorCode = _pOriginalFormatBox ->GetMP4Error();
200 break;
201 }
202 _pOriginalFormatBox ->setParent(this);
203 }
204 else
205 {
206 //skip over
207 AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE));
208 }
209 }
210
211 else
212 {
213 //skip over
214 AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE));
215 }
216 count -= atomSize;
217 }
218 return;
219 }
220
~ProtectionSchemeInformationBox()221 ProtectionSchemeInformationBox::~ProtectionSchemeInformationBox()
222 {
223 if (_pSchemeInformationBox != NULL)
224 {
225 PV_MP4_FF_DELETE(NULL, SchemeInformationBox, _pSchemeInformationBox);
226 }
227 if (_pOriginalFormatBox != NULL)
228 {
229 PV_MP4_FF_DELETE(NULL, OriginalFormatBox, _pOriginalFormatBox);
230 }
231 }
232
OriginalFormatbox(MP4_FF_FILE * fp,uint32 size,uint32 type)233 OriginalFormatbox::OriginalFormatbox(MP4_FF_FILE *fp, uint32 size, uint32 type)
234 : Atom(fp, size, type)
235 {
236 if (!AtomUtils::read32(fp, _data_format))
237 _success = false;
238 }
239
~OriginalFormatbox()240 OriginalFormatbox::~OriginalFormatbox()
241 {
242 }
243
EcnaBox(MP4_FF_FILE * fp,uint32 size,uint32 type)244 EcnaBox::EcnaBox(MP4_FF_FILE *fp, uint32 size, uint32 type)
245 : SampleEntry(fp, size, type)
246 {
247 _pes = NULL;
248 _pparent = NULL;
249 _pProtectionSchemeInformationBox = NULL;
250 _pAMRSpecificAtom = NULL;
251 _pAMRDecSpecInfoArray = NULL;
252 _pAMRWBSpecificAtom = NULL;
253 _pAMRWBDecSpecInfoArray = NULL;
254
255 uint32 count = (_size - DEFAULT_ATOM_SIZE);
256
257 if (_success)
258 {
259 // Read reserved values
260 if (!AtomUtils::read32read32(fp, _reserved1[0], _reserved1[1]))
261 _success = false;
262 count -= 8;
263
264 if (!AtomUtils::read16read16(fp, _reserved2, _reserved3))
265 _success = false;
266 count -= 4;
267
268 if (!AtomUtils::read32(fp, _reserved4))
269 _success = false;
270 count -= 4;
271
272 if (!AtomUtils::read16read16(fp, _timeScale, _reserved5))
273 _success = false;
274 count -= 4;
275
276 if (_success)
277 {
278 uint32 atomType = UNKNOWN_ATOM;
279 uint32 atomSize = 0;
280
281 while (count > 0)
282 {
283 AtomUtils::getNextAtomType(fp, atomSize, atomType);
284 if (atomSize > count)
285 {
286 _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED;
287 break;
288 }
289 count -= atomSize;
290
291 if (atomType == ESD_ATOM)
292 {
293 PV_MP4_FF_NEW(fp->auditCB, ESDAtom, (fp, atomSize, atomType), _pes);
294
295 if (!_pes->MP4Success())
296 {
297 _success = false;
298 _mp4ErrorCode = _pes->GetMP4Error();
299 break;
300 }
301 else
302 {
303 _pes->setParent(this);
304 }
305 }
306 else if (atomType == AMR_SPECIFIC_ATOM)
307 {
308 PV_MP4_FF_NEW(fp->auditCB, AMRSpecificAtom, (fp, atomSize, atomType), _pAMRSpecificAtom);
309
310 if (!_pAMRSpecificAtom->MP4Success())
311 {
312 _success = false;
313 _mp4ErrorCode = READ_AMR_SAMPLE_ENTRY_FAILED;
314 }
315
316 PV_MP4_FF_NEW(fp->auditCB, decoderSpecificInfoVecType, (), _pAMRDecSpecInfoArray);
317
318 for (uint32 i = 0; i < 16; i++)
319 {
320 AMRDecoderSpecificInfo *pinfo = NULL;
321 PV_MP4_FF_NEW(fp->auditCB, AMRDecoderSpecificInfo, (fp, true), pinfo);
322
323 pinfo->_frame_type = (uint8)i;
324 pinfo->_codec_version = _pAMRSpecificAtom->getDecoderVersion();
325 pinfo->_mode_change_period = _pAMRSpecificAtom->getModeChangePeriod();
326 pinfo->_mode_set = _pAMRSpecificAtom->getModeSet();
327 pinfo->_mode_change_neighbour = false;
328
329 (*_pAMRDecSpecInfoArray).push_back(pinfo);
330 }
331 }
332 else if (atomType == AMRWB_SAMPLE_ENTRY_ATOM)
333 {
334 PV_MP4_FF_NEW(fp->auditCB, AMRSpecificAtom, (fp, atomSize, atomType), _pAMRWBSpecificAtom);
335
336 if (!_pAMRWBSpecificAtom->MP4Success())
337 {
338 _success = false;
339 _mp4ErrorCode = READ_AMR_SAMPLE_ENTRY_FAILED;
340 }
341
342 PV_MP4_FF_NEW(fp->auditCB, decoderSpecificInfoVecType, (), _pAMRWBDecSpecInfoArray);
343
344 for (uint32 i = 0; i < 16; i++)
345 {
346 AMRDecoderSpecificInfo *pinfo = NULL;
347 PV_MP4_FF_NEW(fp->auditCB, AMRDecoderSpecificInfo, (fp, true), pinfo);
348
349 pinfo->_frame_type = (uint8)i;
350 pinfo->_codec_version = _pAMRWBSpecificAtom->getDecoderVersion();
351 pinfo->_mode_change_period = _pAMRWBSpecificAtom->getModeChangePeriod();
352 pinfo->_mode_set = _pAMRWBSpecificAtom->getModeSet();
353 pinfo->_mode_change_neighbour = false;
354
355 (*_pAMRWBDecSpecInfoArray).push_back(pinfo);
356 }
357 }
358 else if (atomType == PROTECTION_SCHEME_INFO_BOX)
359 {
360 if (_pProtectionSchemeInformationBox == NULL)
361 {
362 PV_MP4_FF_NEW(fp->auditCB,
363 ProtectionSchemeInformationBox,
364 (fp, atomSize, atomType),
365 _pProtectionSchemeInformationBox);
366
367 if (!_pProtectionSchemeInformationBox->MP4Success())
368 {
369 _success = false;
370 _mp4ErrorCode = _pProtectionSchemeInformationBox->GetMP4Error();
371 break;
372 }
373 _pProtectionSchemeInformationBox->setParent(this);
374 }
375 }
376 else
377 {
378 AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE));
379 }
380 }
381 if (count > 0)
382 {
383 AtomUtils::seekFromCurrPos(fp, (count));
384 }
385 }
386 else
387 {
388 _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED;
389 }
390 }
391 else
392 {
393 _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED;
394 }
395
396 }
397
getESID() const398 uint32 EcnaBox::getESID() const
399 {
400 if (_pes != NULL)
401 {
402 if (_pes->getESDescriptorPtr() != NULL)
403 {
404 return _pes->getESDescriptorPtr()->getESID();
405 }
406 else
407 {
408 return 0;
409 }
410 }
411 else
412 {
413 return 0;
414 }
415 }
416
getESDescriptor() const417 const ESDescriptor* EcnaBox::getESDescriptor() const
418 {
419 if (_pes != NULL)
420 {
421 return _pes->getESDescriptorPtr();
422 }
423 else
424 {
425 return NULL;
426 }
427 }
428
getObjectTypeIndication() const429 uint8 EcnaBox::getObjectTypeIndication() const
430 {
431 if (_pes != NULL)
432 {
433 return _pes->getObjectTypeIndication();
434 }
435 else if (_pAMRSpecificAtom != NULL)
436 {
437 return (AMR_AUDIO_3GPP);
438 }
439 else if (_pAMRWBSpecificAtom != NULL)
440 {
441 return (AMRWB_AUDIO_3GPP);
442 }
443 else
444 {
445 return 0xFF;
446 }
447 }
448
getDecoderSpecificInfo() const449 DecoderSpecificInfo* EcnaBox::getDecoderSpecificInfo() const
450 {
451 uint32 index = 0;
452 if (_pes != NULL)
453 {
454 return _pes->getDecoderSpecificInfo();
455 }
456 else if (_pAMRSpecificAtom != NULL)
457 {
458 if ((_pAMRDecSpecInfoArray->size() == 0) ||
459 (index >= (uint32)(_pAMRDecSpecInfoArray->size())))
460 {
461 return NULL;
462 }
463 else
464 {
465 return ((*_pAMRDecSpecInfoArray)[index]);
466 }
467 }
468 else if (_pAMRWBSpecificAtom != NULL)
469 {
470 if ((_pAMRWBDecSpecInfoArray->size() == 0) ||
471 (index >= (uint32)(_pAMRWBDecSpecInfoArray->size())))
472 {
473 return NULL;
474 }
475 else
476 {
477 return ((*_pAMRWBDecSpecInfoArray)[index]);
478 }
479 }
480 else
481 {
482 return NULL;
483 }
484 }
485
getAverageBitrate() const486 uint32 EcnaBox::getAverageBitrate() const
487 {
488 if (_pes != NULL)
489 {
490 return _pes->getAverageBitrate();
491 }
492 else if (_pAMRSpecificAtom != NULL)
493 {
494 return (_pAMRSpecificAtom->getBitRate());
495 }
496 else
497 {
498 return 0;
499 }
500 }
501
getMaxBitrate() const502 uint32 EcnaBox::getMaxBitrate() const
503 {
504 if (_pes != NULL)
505 {
506 return _pes->getMaxBitrate();
507 }
508 else
509 {
510 return 0;
511 }
512 }
513
514 // Get the max size buffer needed to retrieve the media samples
getMaxBufferSizeDB() const515 uint32 EcnaBox::getMaxBufferSizeDB() const
516 {
517 if (_pes != NULL)
518 {
519 return _pes->getMaxBufferSizeDB();
520 }
521 else
522 {
523 return 0;
524 }
525 }
526
527 // Destructor
~EcnaBox()528 EcnaBox::~EcnaBox()
529 {
530 if (_pes != NULL)
531 {
532 // Cleanup ESDAtom
533 PV_MP4_FF_DELETE(NULL, ESDAtom, _pes);
534 }
535 if (_pProtectionSchemeInformationBox != NULL)
536 {
537 PV_MP4_FF_DELETE(NULL, ProtectionSchemeInformationBox, _pProtectionSchemeInformationBox);
538 }
539 if (_pAMRSpecificAtom != NULL)
540 {
541 // Cleanup ESDAtom
542 PV_MP4_FF_DELETE(NULL, AMRSpecificAtom, _pAMRSpecificAtom);
543 }
544 if (_pAMRDecSpecInfoArray != NULL)
545 {
546 for (uint32 i = 0; i < _pAMRDecSpecInfoArray->size(); i++)
547 {
548 PV_MP4_FF_DELETE(NULL, DecoderSpecificInfo, (*_pAMRDecSpecInfoArray)[i]);
549 }
550 }
551
552 if (_pAMRDecSpecInfoArray != NULL)
553 {
554 PV_MP4_FF_TEMPLATED_DELETE(NULL, decoderSpecificInfoVecType, Oscl_Vector, _pAMRDecSpecInfoArray);
555 _pAMRDecSpecInfoArray = NULL;
556 }
557 }
558
EcnvBox(MP4_FF_FILE * fp,uint32 size,uint32 type)559 EcnvBox::EcnvBox(MP4_FF_FILE *fp, uint32 size, uint32 type)
560 : SampleEntry(fp, size, type)
561 {
562 _pes = NULL;
563 _pProtectionSchemeInformationBox = NULL;
564 _pH263SpecificAtom = NULL;
565 _pH263decSpecificInfo = NULL;
566 _pAVCConfigurationBox = NULL;
567 _pMPEG4BitRateBox = NULL;
568 _decoderSpecificInfo = NULL;
569
570 uint32 count = (_size - DEFAULT_ATOM_SIZE);
571
572 if (_success)
573 {
574 _pparent = NULL;
575
576 // Read in all reserved members
577 for (int32 i = 0; i < 4; i++)
578 {
579 if (!AtomUtils::read32(fp, _reserved1[i]))
580 {
581 _success = false;
582 break;
583 }
584 count -= 4;
585 }
586
587 if (_success)
588 {
589 if (!AtomUtils::read32read32(fp, _reserved2, _reserved3))
590 _success = false;
591 count -= 8;
592
593 if (!AtomUtils::read32read32(fp, _reserved4, _reserved5))
594 _success = false;
595 count -= 8;
596
597 if (!AtomUtils::read16(fp, _reserved6))
598 _success = false;
599 count -= 2;
600
601 for (int32 i = 0; i < 32; i++)
602 {
603 if (!AtomUtils::read8(fp, _reserved7[i]))
604 {
605 _success = false;
606 break;
607 }
608 count -= 1;
609 }
610
611 if (!AtomUtils::read16read16(fp, _reserved8, _reserved9))
612 _success = false;
613 count -= 4;
614 }
615
616 if (_success)
617 {
618 bool avcPresent = false;
619 while (count > 0)
620 {
621 uint32 atomType = UNKNOWN_ATOM;
622 uint32 atomSize = 0;
623
624 AtomUtils::getNextAtomType(fp, atomSize, atomType);
625
626 if (atomSize > count)
627 {
628 _mp4ErrorCode = READ_VISUAL_SAMPLE_ENTRY_FAILED;
629 break;
630 }
631
632 count -= atomSize;
633
634 if (atomType == ESD_ATOM)
635 {
636
637 PV_MP4_FF_NEW(fp->auditCB, ESDAtom, (fp, atomSize, atomType), _pes);
638 if (!_pes->MP4Success())
639 {
640 _mp4ErrorCode = _pes->GetMP4Error();
641 _success = false;
642 }
643 else
644 {
645 if (_pes->getObjectTypeIndication() == H263_VIDEO)
646 {
647 const ESDescriptor *_pdescriptor = _pes->getESDescriptorPtr();
648 if (NULL != _pdescriptor)
649 {
650 H263DecoderSpecificInfo *_pH263decSpecificInfo =
651 (H263DecoderSpecificInfo *)(_pdescriptor->getDecoderSpecificInfo());
652 if (NULL != _pH263decSpecificInfo)
653 {
654 if (_pH263decSpecificInfo->_max_height <= 0)
655 _pH263decSpecificInfo->_max_height = (uint16)((_reserved2 << 16) >> 16);
656 if (_pH263decSpecificInfo->_max_width <= 0)
657 _pH263decSpecificInfo->_max_width = (uint16)(_reserved2 >> 16);
658 }
659 }
660 }
661 }
662 }
663 else if (atomType == H263_SPECIFIC_ATOM)
664 {
665 PV_MP4_FF_NEW(fp->auditCB, H263SpecficAtom, (fp, atomSize, atomType), _pH263SpecificAtom);
666
667 if (_pH263SpecificAtom->MP4Success())
668 {
669 PV_MP4_FF_NEW(fp->auditCB, H263DecoderSpecificInfo, (fp, true), _pH263decSpecificInfo);
670
671 _pH263decSpecificInfo->_VendorCode = _pH263SpecificAtom->getVendorCode();
672 _pH263decSpecificInfo->_codec_version = _pH263SpecificAtom->getDecoderVersion();
673 _pH263decSpecificInfo->_codec_level = _pH263SpecificAtom->getCodecLevel();
674 _pH263decSpecificInfo->_codec_profile = _pH263SpecificAtom->getCodecProfile();
675
676 uint32 width = _reserved2 & 0xFFFF0000;
677 _pH263decSpecificInfo->_max_width = width >> 16;
678 _pH263decSpecificInfo->_max_height = _reserved2 & 0x0000FFFF;
679 }
680
681 }
682 else if (atomType == AVC_CONFIGURATION_BOX)
683 {
684 avcPresent = true;
685 PV_MP4_FF_NEW(fp->auditCB, AVCConfigurationBox, (fp, atomSize, atomType), _pAVCConfigurationBox);
686
687 if (!_pAVCConfigurationBox->MP4Success())
688 {
689 _mp4ErrorCode = READ_AVC_CONFIG_BOX_FAILED;
690 return;
691 }
692 }
693 else if (atomType == MPEG4_BITRATE_BOX)
694 {
695 PV_MP4_FF_NEW(fp->auditCB, MPEG4BitRateBox, (fp, atomSize, atomType), _pMPEG4BitRateBox);
696
697 if (!_pMPEG4BitRateBox->MP4Success())
698 {
699 _mp4ErrorCode = READ_MPEG4_BITRATE_BOX_FAILED;
700 return;
701 }
702 }
703 else if (atomType == PROTECTION_SCHEME_INFO_BOX)
704 {
705 if (_pProtectionSchemeInformationBox == NULL)
706 {
707 PV_MP4_FF_NEW(fp->auditCB,
708 ProtectionSchemeInformationBox,
709 (fp, atomSize, atomType),
710 _pProtectionSchemeInformationBox);
711
712 if (!_pProtectionSchemeInformationBox->MP4Success())
713 {
714 _success = false;
715 _mp4ErrorCode = _pProtectionSchemeInformationBox->GetMP4Error();
716 break;
717 }
718 _pProtectionSchemeInformationBox->setParent(this);
719 }
720 }
721
722 else
723 {
724 _success = false;
725 _mp4ErrorCode = READ_VISUAL_SAMPLE_ENTRY_FAILED;
726 }
727
728 if (avcPresent)
729 {
730 avcPresent = false;
731 if (createAVCDecoderSpecificInfo(fp))
732 {
733 _success = true;
734 _mp4ErrorCode = EVERYTHING_FINE;
735 }
736 }
737 }
738 if (count > 0)
739 {
740 AtomUtils::seekFromCurrPos(fp, (count));
741 }
742
743 }
744 else
745 {
746 _mp4ErrorCode = READ_VISUAL_SAMPLE_ENTRY_FAILED;
747 }
748 }
749 else
750 {
751 _mp4ErrorCode = READ_VISUAL_SAMPLE_ENTRY_FAILED;
752 }
753
754 }
755
756 bool
createAVCDecoderSpecificInfo(MP4_FF_FILE * fp)757 EcnvBox::createAVCDecoderSpecificInfo(MP4_FF_FILE *fp)
758 {
759 if (_pAVCConfigurationBox == NULL)
760 return false;
761
762 uint32 numSPS = _pAVCConfigurationBox->getNumSequenceParamSets();
763 uint32 numPPS = _pAVCConfigurationBox->getNumPictureParamSets();
764 uint32 totalSPSLen = _pAVCConfigurationBox->getTotalSeqParameterSetLength();
765 uint32 totalPPSLen = _pAVCConfigurationBox->getTotalPictureParameterSetLength();
766 uint32 len = (numSPS * 2) + (numPPS * 2) + totalSPSLen + totalPPSLen;
767
768 if ((int32)len > 0)
769 {
770
771 PV_MP4_FF_NEW(fp->auditCB, DecoderSpecificInfo, (fp, true), _decoderSpecificInfo);
772
773 uint8* info = (uint8*)(oscl_malloc(sizeof(uint8) * len));
774 if (!info)
775 return false; // malloc failed (unlikely)
776 uint8* destPtr = info;
777 if (numSPS > 0)
778 {
779 for (uint32 i = 0; i < numSPS; i++)
780 {
781 uint16 len = 0;
782 uint8* ptr = NULL;
783 if (_pAVCConfigurationBox->getSequenceParamSet(i, len, ptr) == false)
784 {
785 OSCL_FREE(info);
786 return false;
787 }
788 oscl_memcpy(destPtr, &len, sizeof(uint16));
789 destPtr += sizeof(uint16);
790 oscl_memcpy(destPtr, ptr, len);
791 destPtr += len;
792 }
793 }
794 if (numPPS > 0)
795 {
796 for (uint32 i = 0; i < numPPS; i++)
797 {
798 uint16 len = 0;
799 uint8* ptr = NULL;
800 if (_pAVCConfigurationBox->getPictureParamSet(i, len, ptr) == false)
801 {
802 OSCL_FREE(info);
803 return false;
804 }
805 oscl_memcpy(destPtr, &len, sizeof(uint16));
806 destPtr += sizeof(uint16);
807 oscl_memcpy(destPtr, ptr, len);
808 destPtr += len;
809 }
810 }
811 _decoderSpecificInfo->setInfoSize(len);
812 _decoderSpecificInfo->setInfo(info);
813 }
814 return true;
815 }
816
getESID() const817 uint32 EcnvBox::getESID() const
818 {
819 if (_pes != NULL)
820 {
821 if (_pes->getESDescriptorPtr() != NULL)
822 {
823 return _pes->getESDescriptorPtr()->getESID();
824 }
825 else
826 {
827 return 0;
828 }
829 }
830 else
831 {
832 return 0;
833 }
834 }
835
getESDescriptor() const836 const ESDescriptor* EcnvBox::getESDescriptor() const
837 {
838 if (_pes != NULL)
839 {
840 return _pes->getESDescriptorPtr();
841 }
842 else
843 {
844 return NULL;
845 }
846 }
847
848 // Getting and setting the Mpeg4 VOL header
getDecoderSpecificInfo() const849 DecoderSpecificInfo* EcnvBox::getDecoderSpecificInfo() const
850 {
851 if (_pes != NULL)
852 {
853 return _pes->getDecoderSpecificInfo();
854 }
855 else if (_pH263decSpecificInfo != NULL)
856 {
857 return _pH263decSpecificInfo;
858 }
859 else if (_pAVCConfigurationBox != NULL)
860 {
861 if (_decoderSpecificInfo != NULL)
862 return _decoderSpecificInfo;
863 else
864 return NULL;
865 }
866 else
867 {
868 return NULL;
869 }
870 }
871
getObjectTypeIndication() const872 uint8 EcnvBox::getObjectTypeIndication() const
873 {
874 if (_pes != NULL)
875 {
876 return _pes->getObjectTypeIndication();
877 }
878 else
879 {
880 if (_pH263SpecificAtom != NULL)
881 return (H263_VIDEO);
882 else if (_pAVCConfigurationBox != NULL)
883 return (AVC_VIDEO);
884 else
885 return 0xFF;
886 }
887 }
888
889
890 // Get the max size buffer needed to retrieve the media samples
getMaxBufferSizeDB() const891 uint32 EcnvBox::getMaxBufferSizeDB() const
892 {
893 if (_pes != NULL)
894 {
895 return _pes->getMaxBufferSizeDB();
896 }
897 else if (_pMPEG4BitRateBox != NULL)
898 {
899 return _pMPEG4BitRateBox->getBufferSizeDB();
900 }
901 else
902 {
903 return 0;
904 }
905 }
906
getAverageBitrate() const907 uint32 EcnvBox::getAverageBitrate() const
908 {
909 if (_pes != NULL)
910 {
911 return _pes->getAverageBitrate();
912 }
913 else if (_pH263SpecificAtom != NULL)
914 {
915 return (_pH263SpecificAtom->getAverageBitRate());
916 }
917 else if (_pMPEG4BitRateBox != NULL)
918 {
919 return _pMPEG4BitRateBox->getAvgBitRate();
920 }
921 else
922 {
923 return 0;
924 }
925 }
926
getMaxBitrate() const927 uint32 EcnvBox::getMaxBitrate() const
928 {
929 if (_pes != NULL)
930 {
931 return _pes->getMaxBitrate();
932 }
933 else if (_pH263SpecificAtom != NULL)
934 {
935 return (_pH263SpecificAtom->getMaxBitRate());
936 }
937 else if (_pMPEG4BitRateBox != NULL)
938 {
939 return _pMPEG4BitRateBox->getMaxBitRate();
940 }
941 else
942 {
943 return 0;
944 }
945 }
946
getWidth() const947 uint16 EcnvBox::getWidth() const
948 {
949 uint32 width = _reserved2 & 0xFFFF0000;
950 uint32 ret = width >> 16;
951 return (uint16)ret;
952
953 }
954
getHeight() const955 uint16 EcnvBox::getHeight() const
956 {
957 return (uint16)(_reserved2 & 0x0000FFFF);
958 }
959
960
961 // Destructor
~EcnvBox()962 EcnvBox::~EcnvBox()
963 {
964 if (_pes != NULL)
965 {
966 // Cleanup ESDAtom
967 PV_MP4_FF_DELETE(NULL, ESDAtom, _pes);
968 }
969 if (_pH263SpecificAtom != NULL)
970 {
971 PV_MP4_FF_DELETE(NULL, H263SpecficAtom, _pH263SpecificAtom);
972 }
973
974 if (_pH263decSpecificInfo != NULL)
975 {
976 PV_MP4_FF_DELETE(NULL, H263DecoderSpecificInfo, _pH263decSpecificInfo);
977 }
978 if (_pAVCConfigurationBox != NULL)
979 {
980 PV_MP4_FF_DELETE(NULL, AVCConfigurationBox, _pAVCConfigurationBox);
981 }
982 if (_pMPEG4BitRateBox != NULL)
983 {
984 PV_MP4_FF_DELETE(NULL, MPEG4BitRateBox, _pMPEG4BitRateBox);
985 }
986 if (_decoderSpecificInfo != NULL)
987 {
988 PV_MP4_FF_DELETE(NULL, DecoderSpecificInfo, _decoderSpecificInfo);
989 }
990 if (_decoderSpecificInfo != NULL)
991 {
992 PV_MP4_FF_DELETE(NULL, DecoderSpecificInfo, _decoderSpecificInfo);
993 }
994 if (_pProtectionSchemeInformationBox != NULL)
995 {
996 PV_MP4_FF_DELETE(NULL, ProtectionSchemeInformationBox, _pProtectionSchemeInformationBox);
997 }
998 }
999
1000
EnctBox(MP4_FF_FILE * fp,uint32 size,uint32 type)1001 OSCL_EXPORT_REF EnctBox:: EnctBox(MP4_FF_FILE *fp, uint32 size, uint32 type)
1002 : SampleEntry(fp, size, type)
1003 {
1004 _pparent = NULL;
1005
1006 _pBackgroundRGBA = NULL;
1007 _pBoxRecord = NULL;
1008 _pStyleRecord = NULL;
1009 _pFontTableAtom = NULL;
1010 _pProtectionSchemeInformationBox = NULL;
1011
1012 uint32 count = (_size - DEFAULT_ATOM_SIZE);
1013
1014 if (_success)
1015 {
1016
1017 AtomUtils::read32(fp, _displayFlags);
1018 count -= 4;
1019
1020 uint8 horz = 0;
1021 AtomUtils::read8(fp, horz);
1022 count -= 1;
1023
1024 _horzJustification = (int8)horz;
1025
1026 uint8 vert = 0;
1027 AtomUtils::read8(fp, vert);
1028 count -= 1;
1029 _vertJustification = (int8)vert;
1030
1031 PV_MP4_FF_ARRAY_NEW(NULL, uint8, (4), _pBackgroundRGBA);
1032
1033 AtomUtils::readByteData(fp, 4, _pBackgroundRGBA);
1034 count -= 4;
1035
1036 uint32 fpos1 = AtomUtils::getCurrentFilePosition(fp);
1037 PV_MP4_FF_NEW(fp->auditCB, BoxRecord, (fp), _pBoxRecord);
1038 if (!_pBoxRecord->MP4Success())
1039 {
1040 _success = false;
1041 _mp4ErrorCode = _pBoxRecord->GetMP4Error();
1042 return;
1043 }
1044 uint32 fpos2 = AtomUtils::getCurrentFilePosition(fp);
1045 count -= (fpos2 - fpos1);
1046
1047
1048 fpos1 = AtomUtils::getCurrentFilePosition(fp);
1049 PV_MP4_FF_NEW(fp->auditCB, StyleRecord, (fp), _pStyleRecord);
1050 if (!_pStyleRecord->MP4Success())
1051 {
1052 _success = false;
1053 _mp4ErrorCode = _pStyleRecord->GetMP4Error();
1054 return;
1055 }
1056 fpos2 = AtomUtils::getCurrentFilePosition(fp);
1057 count -= (fpos2 - fpos1);
1058
1059 PV_MP4_FF_NEW(fp->auditCB, FontTableAtom, (fp), _pFontTableAtom);
1060 if (!_pFontTableAtom->MP4Success())
1061 {
1062 _success = false;
1063 _mp4ErrorCode = _pFontTableAtom->GetMP4Error();
1064 return;
1065 }
1066 count -= _pFontTableAtom->getSize();
1067
1068 uint32 atomType = UNKNOWN_ATOM;
1069 uint32 atomSize = 0;
1070
1071 while (count > 0)
1072 {
1073 AtomUtils::getNextAtomType(fp, atomSize, atomType);
1074 if (atomSize > count)
1075 {
1076 _mp4ErrorCode = READ_AUDIO_SAMPLE_ENTRY_FAILED;
1077 break;
1078 }
1079 count -= atomSize;
1080
1081 if (atomType == PROTECTION_SCHEME_INFO_BOX)
1082 {
1083 if (_pProtectionSchemeInformationBox == NULL)
1084 {
1085 PV_MP4_FF_NEW(fp->auditCB,
1086 ProtectionSchemeInformationBox,
1087 (fp, atomSize, atomType),
1088 _pProtectionSchemeInformationBox);
1089
1090 if (!_pProtectionSchemeInformationBox->MP4Success())
1091 {
1092 _success = false;
1093 _mp4ErrorCode = _pProtectionSchemeInformationBox->GetMP4Error();
1094 break;
1095 }
1096 _pProtectionSchemeInformationBox->setParent(this);
1097 }
1098 }
1099 else
1100 {
1101 AtomUtils::seekFromCurrPos(fp, (atomSize - DEFAULT_ATOM_SIZE));
1102 }
1103 }
1104 if (count > 0)
1105 {
1106 AtomUtils::seekFromCurrPos(fp, (count));
1107 }
1108
1109 }
1110 }
1111
1112 // Destructor
~EnctBox()1113 OSCL_EXPORT_REF EnctBox::~EnctBox()
1114 {
1115 if (_pBackgroundRGBA != NULL)
1116 {
1117 PV_MP4_ARRAY_DELETE(NULL, _pBackgroundRGBA);
1118 }
1119 if (_pBoxRecord != NULL)
1120 {
1121 PV_MP4_FF_DELETE(NULL, BoxRecord, _pBoxRecord);
1122 }
1123 if (_pStyleRecord != NULL)
1124 {
1125 PV_MP4_FF_DELETE(NULL, StyleRecord, _pStyleRecord);
1126 }
1127 if (_pFontTableAtom != NULL)
1128 {
1129 PV_MP4_FF_DELETE(NULL, FontTableAtom, _pFontTableAtom);
1130 }
1131 if (_pProtectionSchemeInformationBox != NULL)
1132 {
1133 PV_MP4_FF_DELETE(NULL, ProtectionSchemeInformationBox, _pProtectionSchemeInformationBox);
1134 }
1135
1136 }
1137
getBoxTop()1138 OSCL_EXPORT_REF int16 EnctBox::getBoxTop()
1139 {
1140 if (_pBoxRecord != NULL)
1141 {
1142 return (_pBoxRecord->getBoxTop());
1143 }
1144 else
1145 {
1146 return -1;
1147 }
1148 }
1149
getBoxLeft()1150 OSCL_EXPORT_REF int16 EnctBox::getBoxLeft()
1151 {
1152 if (_pBoxRecord != NULL)
1153 {
1154 return (_pBoxRecord->getBoxLeft());
1155 }
1156 else
1157 {
1158 return -1;
1159 }
1160 }
1161
getBoxBottom()1162 OSCL_EXPORT_REF int16 EnctBox::getBoxBottom()
1163 {
1164 if (_pBoxRecord != NULL)
1165 {
1166 return (_pBoxRecord->getBoxBottom());
1167 }
1168 else
1169 {
1170 return -1;
1171 }
1172 }
1173
getBoxRight()1174 OSCL_EXPORT_REF int16 EnctBox::getBoxRight()
1175 {
1176 if (_pBoxRecord != NULL)
1177 {
1178 return (_pBoxRecord->getBoxRight());
1179 }
1180 else
1181 {
1182 return -1;
1183 }
1184 }
getFontID()1185 OSCL_EXPORT_REF uint16 EnctBox::getFontID()
1186 {
1187 if (_pStyleRecord != NULL)
1188 {
1189 return _pStyleRecord-> getFontID();
1190 }
1191 else
1192 {
1193 return 0;
1194 }
1195 }
1196
getStartChar()1197 OSCL_EXPORT_REF uint16 EnctBox::getStartChar()
1198 {
1199 if (_pStyleRecord != NULL)
1200 {
1201 return _pStyleRecord-> getStartChar();
1202 }
1203 else
1204 {
1205 return 0;
1206 }
1207 }
1208
getEndChar()1209 OSCL_EXPORT_REF uint16 EnctBox::getEndChar()
1210 {
1211 if (_pStyleRecord != NULL)
1212 {
1213 return _pStyleRecord-> getEndChar();
1214 }
1215 else
1216 {
1217 return 0;
1218 }
1219 }
1220
getFontStyleFlags()1221 OSCL_EXPORT_REF uint8 EnctBox::getFontStyleFlags()
1222 {
1223 if (_pStyleRecord != NULL)
1224 {
1225 return _pStyleRecord-> getFontStyleFlags();
1226 }
1227 else
1228 {
1229 return 0;
1230 }
1231 }
1232
getfontSize()1233 OSCL_EXPORT_REF uint8 EnctBox::getfontSize()
1234 {
1235 if (_pStyleRecord != NULL)
1236 {
1237 return _pStyleRecord->getfontSize();
1238 }
1239 else
1240 {
1241 return 0;
1242 }
1243 }
1244
getTextColourRGBA()1245 OSCL_EXPORT_REF uint8* EnctBox::getTextColourRGBA()
1246 {
1247 if (_pStyleRecord != NULL)
1248 {
1249 return _pStyleRecord-> getTextColourRGBA();
1250 }
1251 else
1252 {
1253 return NULL;
1254 }
1255 }
1256
getFontListSize()1257 OSCL_EXPORT_REF uint16 EnctBox:: getFontListSize()
1258 {
1259 if (_pFontTableAtom != NULL)
1260 {
1261 return _pFontTableAtom-> getFontListSize();
1262 }
1263 else
1264 {
1265 return 0;
1266 }
1267 }
1268
getFontRecordAt(uint16 index)1269 OSCL_EXPORT_REF FontRecord* EnctBox::getFontRecordAt(uint16 index)
1270 {
1271 if (_pFontTableAtom != NULL)
1272 {
1273 return _pFontTableAtom->getFontRecordAt(index);
1274 }
1275 else
1276 {
1277 return NULL;
1278 }
1279 }
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289