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 /*     -------------------------------------------------------------------       */
     20 /*                       MPEG-4 SampleDescriptionAtom Class                      */
     21 /*     -------------------------------------------------------------------       */
     22 /*********************************************************************************/
     23 /*
     24     This SampleDescriptionAtom Class gives detailed information about the codeing
     25     type used, and any initialization information needed for coding.
     26 */
     27 
     28 
     29 #define IMPLEMENT_SampleDescriptionAtom
     30 
     31 #include "sampledescriptionatom.h"
     32 
     33 #include "visualsampleentry.h"
     34 #include "audiosampleentry.h"
     35 #include "mpegsampleentry.h"
     36 
     37 
     38 #include "textsampleentry.h"
     39 
     40 #include "atomutils.h"
     41 #include "atomdefs.h"
     42 #include "objectdescriptor.h"
     43 
     44 #include "amrsampleentry.h"
     45 #include "h263sampleentry.h"
     46 
     47 #include "oma2boxes.h"
     48 
     49 #define MAX_ALLOWED_MEDIA_SAMPLE_ENTRIES 16
     50 
     51 typedef Oscl_Vector<SampleEntry*, OsclMemAllocator> sampleEntryVecType;
     52 typedef Oscl_Vector<AVCSampleEntry*, OsclMemAllocator> AVCSampleEntryVecType;
     53 
     54 // Stream-in ctor
     55 SampleDescriptionAtom::SampleDescriptionAtom(MP4_FF_FILE *fp,
     56         uint32 mediaType,
     57         uint32 size,
     58         uint32 type)
     59         : FullAtom(fp, size, type),
     60         _pMediaType(mediaType)
     61 {
     62     _psampleEntryVec      = NULL;
     63     _pAMRSampleEntryAtom  = NULL;
     64     _pH263SampleEntryAtom = NULL;
     65     _pAVCSampleEntryVec   = NULL;
     66     _o3GPPAMR = false;
     67     _o3GPPH263 = false;
     68     _o3GPPWBAMR = false;
     69     _oAVC = false;
     70 
     71 
     72     uint32 count = size - DEFAULT_ATOM_SIZE;
     73     count -= 4; //for 4-byte handle_type
     74 
     75     _pProtectionSchemeInformationBox = NULL;
     76 
     77     if (_success)
     78     {
     79         if (!AtomUtils::read32(fp, _entryCount))
     80         {
     81             _success = false;
     82         }
     83         count -= 4;
     84         int32 tmp = (int32)_entryCount;
     85 
     86         if (tmp <= 0)
     87         {
     88             _success = false;
     89             _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
     90             return;
     91         }
     92 
     93         if ((mediaType != MEDIA_TYPE_HINT) &&
     94                 (mediaType != MEDIA_TYPE_TEXT))
     95         {
     96             if (tmp > MAX_ALLOWED_MEDIA_SAMPLE_ENTRIES)
     97             {
     98                 _success = false;
     99                 _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    100                 return;
    101             }
    102         }
    103 
    104         if (_success)
    105         {
    106             PV_MP4_FF_NEW(fp->auditCB, sampleEntryVecType, (), _psampleEntryVec);
    107             PV_MP4_FF_NEW(fp->auditCB, AVCSampleEntryVecType, (), _pAVCSampleEntryVec);
    108 
    109 
    110             for (uint32 i = 0; i < _entryCount; i++)
    111             {
    112                 SampleEntry *entry = NULL;
    113 
    114                 uint32 atomType = UNKNOWN_ATOM;
    115                 uint32 atomSize = 0;
    116 
    117                 AtomUtils::getNextAtomType(fp, atomSize, atomType);
    118                 count -= atomSize;
    119 
    120                 switch (mediaType)
    121                 {
    122                     case MEDIA_TYPE_AUDIO:
    123                     {
    124                         if (atomType == ENCRYPTED_AUDIO_SAMPLE_ENTRY)
    125                         {
    126                             PV_MP4_FF_NEW(fp->auditCB, EcnaBox, (fp, atomSize, atomType), entry);
    127                             if (!entry->MP4Success())
    128                             {
    129                                 _success = false;
    130                                 _mp4ErrorCode = entry->GetMP4Error();
    131                                 EcnaBox *ptr = (EcnaBox *)entry;
    132                                 PV_MP4_FF_DELETE(NULL, EcnaBox, ptr);
    133                                 return;
    134                             }
    135                             _pProtectionSchemeInformationBox =
    136                                 ((EcnaBox*)entry)->_pProtectionSchemeInformationBox;
    137                         }
    138                         else if (atomType == AMR_SAMPLE_ENTRY_ATOM)
    139                         {
    140                             if (_o3GPPAMR == false)
    141                             {
    142                                 PV_MP4_FF_NEW(fp->auditCB, AMRSampleEntry, (fp, atomSize, atomType), _pAMRSampleEntryAtom);
    143 
    144                                 if (!_pAMRSampleEntryAtom->MP4Success())
    145                                 {
    146                                     _success = false;
    147                                     _mp4ErrorCode = _pAMRSampleEntryAtom->GetMP4Error();
    148                                     PV_MP4_FF_DELETE(NULL, AMRSampleEntry, _pAMRSampleEntryAtom);
    149                                     _pAMRSampleEntryAtom = NULL;
    150                                     return;
    151                                 }
    152                                 else
    153                                 {
    154                                     _pAMRSampleEntryAtom->setParent(this);
    155                                 }
    156                                 _o3GPPAMR = true;
    157                             }
    158                             else
    159                             {
    160                                 // Multiple AMR Sample Entries are illegal
    161                                 _success = false;
    162                                 _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    163                                 return;
    164                             }
    165                         }
    166                         else if (atomType == AMRWB_SAMPLE_ENTRY_ATOM)
    167                         {
    168                             if (_o3GPPWBAMR == false)
    169                             {
    170                                 PV_MP4_FF_NEW(fp->auditCB, AMRSampleEntry, (fp, atomSize, atomType), _pAMRSampleEntryAtom);
    171 
    172                                 if (!_pAMRSampleEntryAtom->MP4Success())
    173                                 {
    174                                     _success = false;
    175                                     _mp4ErrorCode = _pAMRSampleEntryAtom->GetMP4Error();
    176                                     PV_MP4_FF_DELETE(NULL, AMRSampleEntry, _pAMRSampleEntryAtom);
    177                                     _pAMRSampleEntryAtom = NULL;
    178                                     return;
    179                                 }
    180                                 else
    181                                 {
    182                                     _pAMRSampleEntryAtom->setParent(this);
    183                                 }
    184                                 _o3GPPWBAMR = true;
    185                             }
    186                             else
    187                             {
    188                                 // Multiple AMR Sample Entries are illegal
    189                                 _success = false;
    190                                 _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    191                                 return;
    192                             }
    193                         }
    194                         else if (atomType == AUDIO_SAMPLE_ENTRY)
    195                         {
    196                             PV_MP4_FF_NEW(fp->auditCB, AudioSampleEntry, (fp, atomSize, atomType), entry);
    197                             if (!entry->MP4Success())
    198                             {
    199                                 _success = false;
    200                                 _mp4ErrorCode = entry->GetMP4Error();
    201                                 AudioSampleEntry *ptr = (AudioSampleEntry *)entry;
    202                                 PV_MP4_FF_DELETE(NULL, AudioSampleEntry, ptr);
    203                                 return;
    204                             }
    205                         }
    206 
    207                         else
    208                         {
    209                             atomSize -= DEFAULT_ATOM_SIZE;
    210                             AtomUtils::seekFromCurrPos(fp, atomSize);
    211                         }
    212                         _handlerType = MEDIA_TYPE_AUDIO;
    213                         break;
    214                     }
    215 
    216                     case MEDIA_TYPE_TEXT:
    217                     {
    218 // TIMED_TEXT_SUPPORT start
    219                         if (atomType == ENCRYPTED_TEXT_SAMPLE_ENTRY)
    220                         {
    221                             PV_MP4_FF_NEW(fp->auditCB, EnctBox, (fp, atomSize, atomType), entry);
    222                             if (!entry->MP4Success())
    223                             {
    224                                 _success = false;
    225                                 _mp4ErrorCode = entry->GetMP4Error();
    226                                 EnctBox *ptr = (EnctBox *)entry;
    227                                 PV_MP4_FF_DELETE(NULL, EnctBox, ptr);
    228                                 return;
    229                             }
    230                             _pProtectionSchemeInformationBox =
    231                                 ((EnctBox*)entry)->_pProtectionSchemeInformationBox;
    232 
    233                         }
    234                         else if (atomType == TEXT_SAMPLE_ENTRY)
    235                         {
    236                             PV_MP4_FF_NEW(fp->auditCB, TextSampleEntry, (fp, atomSize, atomType), entry);
    237                             if (!entry->MP4Success())
    238                             {
    239                                 _success = false;
    240                                 _mp4ErrorCode = entry->GetMP4Error();
    241                                 TextSampleEntry *ptr = (TextSampleEntry *)entry;
    242                                 PV_MP4_FF_DELETE(NULL, TextSampleEntry, ptr);
    243                                 return;
    244                             }
    245 
    246                         }
    247                         else
    248 // TIMED_TEXT_SUPPORT end
    249                         {
    250                             atomSize -= DEFAULT_ATOM_SIZE;
    251                             AtomUtils::seekFromCurrPos(fp, atomSize);
    252                         }
    253                         _handlerType = MEDIA_TYPE_TEXT;
    254                     }
    255                     break;
    256 
    257                     case MEDIA_TYPE_VISUAL:
    258                     {
    259                         if (atomType == ENCRYPTED_VIDEO_SAMPLE_ENTRY)
    260                         {
    261                             PV_MP4_FF_NEW(fp->auditCB, EcnvBox, (fp, atomSize, atomType), entry);
    262                             if (!entry->MP4Success())
    263                             {
    264                                 _success = false;
    265                                 _mp4ErrorCode = entry->GetMP4Error();
    266                                 EcnvBox *ptr = (EcnvBox *)entry;
    267                                 PV_MP4_FF_DELETE(NULL, EcnvBox, ptr);
    268                                 return;
    269                             }
    270                             _pProtectionSchemeInformationBox =
    271                                 ((EcnvBox*)entry)->_pProtectionSchemeInformationBox;
    272 
    273                         }
    274                         else if (atomType == H263_SAMPLE_ENTRY_ATOM)
    275                         {
    276                             if (_o3GPPH263 == false)
    277                             {
    278                                 PV_MP4_FF_NEW(fp->auditCB, H263SampleEntry, (fp, atomSize, atomType), _pH263SampleEntryAtom);
    279 
    280                                 if (!_pH263SampleEntryAtom->MP4Success())
    281                                 {
    282                                     _success = false;
    283                                     _mp4ErrorCode = _pH263SampleEntryAtom->GetMP4Error();
    284                                     return;
    285                                 }
    286                                 else
    287                                 {
    288                                     _pH263SampleEntryAtom->setParent(this);
    289                                 }
    290                                 _o3GPPH263 = true;
    291                             }
    292                             else
    293                             {
    294                                 // Multiple H263 Sample Entries are illegal
    295                                 _success = false;
    296                                 _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    297                                 return;
    298                             }
    299                         }
    300                         else if (atomType == VIDEO_SAMPLE_ENTRY)
    301                         {
    302                             PV_MP4_FF_NEW(fp->auditCB, VisualSampleEntry, (fp, atomSize, atomType), entry);
    303                             if (!entry->MP4Success())
    304                             {
    305                                 _success = false;
    306                                 _mp4ErrorCode = entry->GetMP4Error();
    307                                 VisualSampleEntry *ptr = (VisualSampleEntry *)entry;
    308                                 PV_MP4_FF_DELETE(NULL, VisualSampleEntry, ptr);
    309                                 return;
    310                             }
    311                         }
    312                         else if (atomType == AVC_SAMPLE_ENTRY)
    313                         {
    314                             if (_oAVC == false)
    315                             {
    316                                 AVCSampleEntry* pAVCSampleEntry = NULL;
    317                                 PV_MP4_FF_NEW(fp->auditCB, AVCSampleEntry, (fp, atomSize, atomType), pAVCSampleEntry);
    318                                 if (!pAVCSampleEntry->MP4Success())
    319                                 {
    320                                     _success = false;
    321                                     _mp4ErrorCode = pAVCSampleEntry->GetMP4Error();
    322                                     PV_MP4_FF_DELETE(NULL, AVCSampleEntry, pAVCSampleEntry);
    323                                     return;
    324                                 }
    325                                 else
    326                                 {
    327                                     pAVCSampleEntry->setParent(this);
    328                                 }
    329                                 _oAVC = true;
    330 
    331                                 if (pAVCSampleEntry != NULL)
    332                                 {
    333                                     (*_pAVCSampleEntryVec).push_back(pAVCSampleEntry);
    334                                 }
    335                             }
    336                             else
    337                             {
    338                                 // Multiple AVC Sample Entries are illegal
    339                                 _success = false;
    340                                 _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    341                                 return;
    342                             }
    343                         }
    344                         else
    345                         {
    346                             atomSize -= DEFAULT_ATOM_SIZE;
    347                             AtomUtils::seekFromCurrPos(fp, atomSize);
    348                         }
    349                         _handlerType = MEDIA_TYPE_VISUAL;
    350                         break;
    351                     }
    352 
    353                     default:
    354                     {
    355                         atomSize -= DEFAULT_ATOM_SIZE;
    356                         AtomUtils::seekFromCurrPos(fp, atomSize);
    357                     }
    358                 }
    359 
    360                 if (entry != NULL)
    361                 {
    362                     if (!entry->MP4Success())
    363                     {
    364                         _success = false;
    365                         _mp4ErrorCode = entry->GetMP4Error();
    366                         break; // Break out of the for loop
    367                     }
    368                     else
    369                     {
    370                         entry->setParent(this);
    371                         (*_psampleEntryVec).push_back(entry);
    372                     }
    373                 }
    374             } // end for loop
    375             if (count > 0)
    376             {
    377                 //skip the rest of bytes
    378                 AtomUtils::seekFromCurrPos(fp, count);
    379             }
    380 
    381         } // end if success
    382 
    383     }
    384     else
    385     {
    386         if (_mp4ErrorCode != ATOM_VERSION_NOT_SUPPORTED)
    387             _mp4ErrorCode = READ_SAMPLE_DESCRIPTION_ATOM_FAILED;
    388     }
    389 }
    390 
    391 // Destructor
    392 SampleDescriptionAtom::~SampleDescriptionAtom()
    393 {
    394     if (_pAMRSampleEntryAtom != NULL)
    395     {
    396         PV_MP4_FF_DELETE(NULL, AMRSampleEntry, _pAMRSampleEntryAtom);
    397         _pAMRSampleEntryAtom = NULL;
    398     }
    399 
    400     if (_pH263SampleEntryAtom != NULL)
    401     {
    402         PV_MP4_FF_DELETE(NULL, H263SampleEntry, _pH263SampleEntryAtom);
    403     }
    404 
    405     if (_psampleEntryVec != NULL)
    406     {
    407         // CLEAN UP VECTOR!!
    408         for (uint32 i = 0; i < _psampleEntryVec->size(); i++)
    409         {
    410             SampleEntry * pSampleEntryPtr = (SampleEntry*)(*_psampleEntryVec)[i];
    411 
    412             if (pSampleEntryPtr->getType() == AMR_SAMPLE_ENTRY_ATOM)
    413             {
    414                 AMRSampleEntry *ptr = (AMRSampleEntry *)(*_psampleEntryVec)[i];
    415                 PV_MP4_FF_DELETE(NULL, AMRSampleEntry, ptr);
    416             }
    417             else if (pSampleEntryPtr->getType() == AUDIO_SAMPLE_ENTRY)
    418             {
    419                 AudioSampleEntry *ptr = (AudioSampleEntry *)(*_psampleEntryVec)[i];
    420                 PV_MP4_FF_DELETE(NULL, AudioSampleEntry, ptr);
    421             }
    422             else if (pSampleEntryPtr->getType() == TEXT_SAMPLE_ENTRY)
    423             {
    424                 TextSampleEntry *ptr = (TextSampleEntry *)(*_psampleEntryVec)[i];
    425                 PV_MP4_FF_DELETE(NULL, TextSampleEntry, ptr);
    426             }
    427             else if (pSampleEntryPtr->getType() == H263_SAMPLE_ENTRY_ATOM)
    428             {
    429                 H263SampleEntry *ptr = (H263SampleEntry *)(*_psampleEntryVec)[i];
    430                 PV_MP4_FF_DELETE(NULL, H263SampleEntry, ptr);
    431             }
    432             else if (pSampleEntryPtr->getType() == VIDEO_SAMPLE_ENTRY)
    433             {
    434                 VisualSampleEntry *ptr = (VisualSampleEntry *)(*_psampleEntryVec)[i];
    435                 PV_MP4_FF_DELETE(NULL, VisualSampleEntry, ptr);
    436             }
    437             else if (pSampleEntryPtr->getType() == AVC_SAMPLE_ENTRY)
    438             {
    439                 AVCSampleEntry *ptr = (AVCSampleEntry *)(*_psampleEntryVec)[i];
    440                 PV_MP4_FF_DELETE(NULL, AVCSampleEntry, ptr);
    441             }
    442             else if (pSampleEntryPtr->getType() == MPEG_SAMPLE_ENTRY)
    443             {
    444                 MpegSampleEntry *ptr = (MpegSampleEntry *)(*_psampleEntryVec)[i];
    445                 PV_MP4_FF_DELETE(NULL, MpegSampleEntry, ptr);
    446             }
    447 
    448             else
    449             {
    450                 SampleEntry *ptr = (SampleEntry *)(*_psampleEntryVec)[i];
    451                 PV_MP4_FF_DELETE(NULL, SampleEntry, ptr);
    452 
    453             }
    454         }
    455         PV_MP4_FF_TEMPLATED_DELETE(NULL, sampleEntryVecType, Oscl_Vector, _psampleEntryVec);
    456     }
    457 
    458     if (_pAVCSampleEntryVec != NULL)
    459     {
    460         // CLEAN UP VECTOR!!
    461         for (uint32 i = 0; i < _pAVCSampleEntryVec->size(); i++)
    462         {
    463             PV_MP4_FF_DELETE(NULL, AVCSampleEntry, (*_pAVCSampleEntryVec)[i]);
    464         }
    465         PV_MP4_FF_TEMPLATED_DELETE(NULL, AVCSampleEntryVecType, Oscl_Vector, _pAVCSampleEntryVec);
    466     }
    467 }
    468 
    469 // Returns the ESID of the first ESdescriptor of the track - which is the ONLY
    470 // ESID for that track.  Each track has a single unique ESID.
    471 uint32
    472 SampleDescriptionAtom::getESID(uint32 index)
    473 {
    474     switch (_pMediaType)
    475     {
    476         case MEDIA_TYPE_HINT:
    477             return 0; // This is actually an undefined situation
    478         default:
    479             const SampleEntry* entry = getSampleEntryAt(index);
    480             if (!entry)
    481                 return 0;
    482             return entry->getESID();
    483     }
    484 }
    485 
    486 // Return the first ESDescriptor for the track - undefined if a HINT track
    487 const ESDescriptor *
    488 SampleDescriptionAtom::getESDescriptor(uint32 index)
    489 {
    490     switch (_pMediaType)
    491     {
    492         case MEDIA_TYPE_HINT:
    493             return NULL; // This is actually an undefined situation
    494         default:
    495             const SampleEntry* entry = getSampleEntryAt(index);
    496             if (!entry)
    497                 return NULL;
    498             return entry->getESDescriptor();
    499     }
    500 }
    501 
    502 // Getting and setting the Mpeg4 VOL header
    503 DecoderSpecificInfo *
    504 SampleDescriptionAtom::getDecoderSpecificInfo(uint32 index)
    505 {
    506     if (_o3GPPH263)
    507     {
    508         if (_pH263SampleEntryAtom != NULL)
    509         {
    510             return (_pH263SampleEntryAtom->get3GPPH263DecoderSpecificInfo());
    511         }
    512         else
    513         {
    514             return NULL;
    515         }
    516     }
    517 
    518     if ((_o3GPPAMR) || (_o3GPPWBAMR))
    519     {
    520         if (_pAMRSampleEntryAtom != NULL)
    521         {
    522             return (_pAMRSampleEntryAtom->getDecoderSpecificInfo(index));
    523         }
    524         else
    525         {
    526             return NULL;
    527         }
    528     }
    529 
    530     if (_oAVC)
    531     {
    532         return (((*_pAVCSampleEntryVec)[index])->getDecoderSpecificInfo());
    533     }
    534 
    535     const SampleEntry *se = getSampleEntryAt(index);
    536     if ((se != NULL) &&
    537             ((_pMediaType == MEDIA_TYPE_VISUAL) || (_pMediaType == MEDIA_TYPE_AUDIO)))
    538     {
    539         return se->getDecoderSpecificInfo();
    540     }
    541     return NULL;
    542 }
    543 
    544 uint8  SampleDescriptionAtom::getObjectTypeIndication()
    545 {
    546     if (_o3GPPAMR)
    547     {
    548         return (AMR_AUDIO_3GPP);
    549     }
    550 
    551     if (_o3GPPWBAMR)
    552     {
    553         return (AMRWB_AUDIO_3GPP);
    554     }
    555 
    556     if (_o3GPPH263)
    557     {
    558         return (H263_VIDEO);
    559     }
    560 
    561     if (_oAVC)
    562         return (AVC_VIDEO);
    563 
    564     // ok to continue if size()==0, will be
    565     // caught on MEDIA_TYPE_AUDIO and MEDIA_TYPE_VISUAL
    566     // but not on MEDIA_TYPE_TEXT or default case
    567     const SampleEntry  *entry = getSampleEntryAt(0);
    568     if (! entry)
    569         return TYPE_UNKNOWN;
    570     return entry->getObjectTypeIndication();
    571 }
    572 
    573 
    574 int32 SampleDescriptionAtom::getAverageBitrate()
    575 {
    576     uint32 averageBitrate = 0;
    577     uint32 i = 0;
    578 
    579     if (_o3GPPAMR)
    580     {
    581         if (_pAMRSampleEntryAtom != NULL)
    582         {
    583             return (_pAMRSampleEntryAtom->getBitRate());
    584         }
    585         else
    586         {
    587             return 0;
    588         }
    589     }
    590 
    591     if (_o3GPPH263)
    592     {
    593         if (_pH263SampleEntryAtom != NULL)
    594         {
    595             return (_pH263SampleEntryAtom->getAverageBitRate());
    596         }
    597         else
    598         {
    599             return 0;
    600         }
    601     }
    602 
    603     if (_oAVC)
    604     {
    605         if (_pAVCSampleEntryVec->size() > 0)
    606         {
    607             return (*_pAVCSampleEntryVec)[0]->getAvgBitRate();
    608         }
    609         else
    610         {
    611             return 0;
    612         }
    613     }
    614     const SampleEntry* entry = getSampleEntryAt(i);
    615     if (!entry)     // will also pick off size() == 0
    616         return 0;
    617 
    618     averageBitrate = entry->getAverageBitrate();
    619     return (averageBitrate);
    620 
    621 }
    622 
    623 int32 SampleDescriptionAtom::getWidth()
    624 {
    625     uint32 width = 0;
    626     uint32 i = 0;
    627 
    628     if (_o3GPPH263)
    629     {
    630         if (_pH263SampleEntryAtom != NULL)
    631         {
    632             return (_pH263SampleEntryAtom->getWidth());
    633         }
    634         else
    635         {
    636             return 0;
    637         }
    638     }
    639     if (_oAVC)
    640     {
    641         return (((*_pAVCSampleEntryVec)[i])->getWidth());
    642     }
    643 
    644     const SampleEntry* entry = getSampleEntryAt(i);
    645     if (!entry)     // will also pick off size() == 0
    646         return 0;
    647 
    648     width = entry->getWidth();
    649     return (width);
    650 
    651 }
    652 
    653 int32 SampleDescriptionAtom::getHeight()
    654 {
    655 
    656     uint32 i = 0;
    657     if (_o3GPPH263)
    658     {
    659         if (_pH263SampleEntryAtom != NULL)
    660         {
    661             return (_pH263SampleEntryAtom->getHeight());
    662         }
    663         else
    664         {
    665             return 0;
    666         }
    667     }
    668     if (_oAVC)
    669     {
    670         return (((*_pAVCSampleEntryVec)[i])->getHeight());
    671     }
    672 
    673     const SampleEntry* entry = getSampleEntryAt(i);
    674     if (!entry)     // also catch size() == 0
    675         return 0;
    676     return (uint32)entry->getHeight();
    677 }
    678 
    679 
    680 uint32
    681 SampleDescriptionAtom::getMaxBufferSizeDB()
    682 {
    683     uint32 MaxBufSize = 0;
    684 
    685     if (_o3GPPAMR)
    686     {
    687         if (_pAMRSampleEntryAtom != NULL)
    688         {
    689             return 512;
    690         }
    691     }
    692 
    693 
    694     if (_psampleEntryVec->size() == 0)
    695     {
    696         return 0;
    697     }
    698 
    699     for (uint32 i = 0; i < _entryCount; i++)
    700     {
    701         const SampleEntry *entry = getSampleEntryAt(i);
    702         if (!entry)
    703             return 0;
    704         if (entry->getMaxBufferSizeDB() > MaxBufSize)
    705         {
    706             MaxBufSize = entry->getMaxBufferSizeDB();
    707         }
    708     }
    709     return (MaxBufSize);
    710 }
    711 
    712 //PASP box
    713 uint32 SampleDescriptionAtom::getHspacing()
    714 {
    715     uint32 hSpacing = 0;
    716     uint32 i = 0;
    717 
    718     if (_oAVC)
    719     {
    720         return (((*_pAVCSampleEntryVec)[i])->getHspacing());
    721     }
    722 
    723     return (hSpacing);
    724 }
    725 
    726 uint32 SampleDescriptionAtom::getVspacing()
    727 {
    728     uint32 vSpacing = 0;
    729     uint32 i = 0;
    730 
    731     if (_oAVC)
    732     {
    733         return (((*_pAVCSampleEntryVec)[i])->getVspacing());
    734     }
    735 
    736     return (vSpacing);
    737 
    738 }
    739 
    740 uint32
    741 SampleDescriptionAtom::getSampleProtocol(uint32 index)
    742 {
    743 
    744     // Return the atom type of the sampleEntryAtom - for the first one in the vector
    745     const SampleEntry* entry = getSampleEntryAt(index);
    746     if (!entry)     // will also pick off size() == 0
    747         return 0;
    748 
    749     return entry->getType();
    750 }
    751 
    752 
    753 // Watch out:  this can now return NULL, so callers need to
    754 //  check for that before derefencing the return value.
    755 // It will catch the case where _psampleEntryVec->size() == 0,
    756 //  so callers don't have to check for that.  (the check on
    757 //  index < size() will fail if size==0)
    758 const SampleEntry*
    759 SampleDescriptionAtom::getSampleEntryAt(int32 index) const
    760 {
    761     if ((uint32)index < _psampleEntryVec->size())
    762     {
    763         return (SampleEntry*)(*_psampleEntryVec)[index];
    764     }
    765     else
    766     {
    767         return NULL;
    768     }
    769 }
    770 
    771 SampleEntry *
    772 SampleDescriptionAtom::getMutableSampleEntryAt(int32 index)
    773 {
    774     if ((uint32)index < _entryCount)
    775     {
    776         return (SampleEntry*) &(*_psampleEntryVec)[index];
    777     }
    778     else
    779     {
    780         return NULL;
    781     }
    782 }
    783 
    784 // TIMED_TEXT_SUPPORT start
    785 SampleEntry *
    786 SampleDescriptionAtom:: getTextSampleEntryAt(uint32 index)
    787 {
    788     if ((_psampleEntryVec->size() == 0) ||
    789             (index >= (uint32)(_psampleEntryVec->size())))
    790     {
    791         return NULL;
    792     }
    793 
    794     if (_pMediaType == MEDIA_TYPE_TEXT)
    795     {
    796         return (SampleEntry*)(*_psampleEntryVec)[index];
    797     }
    798 
    799     return NULL;
    800 }
    801 // TIMED_TEXT_SUPPORT end
    802 
    803 uint32 SampleDescriptionAtom::getTrackLevelOMA2DRMInfoSize()
    804 {
    805     if (_pProtectionSchemeInformationBox != NULL)
    806     {
    807         return (_pProtectionSchemeInformationBox->getTrackLevelOMA2DRMInfoSize());
    808     }
    809     return 0;
    810 }
    811 
    812 uint8* SampleDescriptionAtom::getTrackLevelOMA2DRMInfo()
    813 {
    814     if (_pProtectionSchemeInformationBox != NULL)
    815     {
    816         return (_pProtectionSchemeInformationBox->getTrackLevelOMA2DRMInfo());
    817     }
    818     return NULL;
    819 }
    820 
    821 
    822 void SampleDescriptionAtom::getMIMEType(OSCL_String& aMimeType)
    823 {
    824     uint8 objectType;
    825     objectType = getObjectTypeIndication();
    826 
    827     OSCL_HeapString<OsclMemAllocator> mimeType;
    828 
    829     mimeType.set(PVMF_MIME_FORMAT_UNKNOWN, oscl_strlen(PVMF_MIME_FORMAT_UNKNOWN));
    830 
    831     if (objectType == AMR_AUDIO)
    832     {
    833         mimeType.set(PVMF_MIME_AMR, oscl_strlen(PVMF_MIME_AMR));
    834     }
    835     else if (objectType == AMR_AUDIO_3GPP)
    836     {
    837         mimeType.set(PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF));
    838     }
    839     else if (objectType == AMRWB_AUDIO_3GPP)
    840     {
    841         mimeType.set(PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF));
    842     }
    843     else if (objectType == MPEG4_AUDIO)
    844     {
    845         mimeType.set(PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO));
    846     }
    847     else if (objectType == MPEG2_AUDIO_LC)
    848     {
    849         mimeType.set(_STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO), oscl_strlen(PVMF_MIME_MPEG4_AUDIO));
    850     }
    851     else if (objectType == MPEG4_VIDEO)
    852     {
    853         mimeType.set(PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V));
    854     }
    855     else if (objectType == H263_VIDEO)
    856     {
    857         mimeType.set(PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000));
    858     }
    859     else if (objectType == AVC_VIDEO)
    860     {
    861         mimeType.set(PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4));
    862     }
    863     else
    864     {
    865         if (_pMediaType == MEDIA_TYPE_TEXT)
    866         {
    867             mimeType.set(PVMF_MIME_3GPP_TIMEDTEXT, oscl_strlen(PVMF_MIME_3GPP_TIMEDTEXT));
    868         }
    869     }
    870 
    871     aMimeType = mimeType;
    872 }
    873 
    874 
    875 
    876