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 #define IMPLEMENT_AVCSampleEntry
     19 
     20 #include "avcsampleentry.h"
     21 #include "atomutils.h"
     22 #include "atomdefs.h"
     23 
     24 
     25 AVCSampleEntry::AVCSampleEntry(MP4_FF_FILE *fp, uint32 size, uint32 type)
     26         : Atom(fp, size, type)
     27 {
     28     _mp4ErrorCode = READ_AVC_SAMPLE_ENTRY_FAILED;
     29 
     30     uint32 count = _size - DEFAULT_ATOM_SIZE;
     31 
     32     _pAVCConfigurationBox = NULL;
     33     _pMPEG4BitRateBox     = NULL;
     34     _decoderSpecificInfo  = NULL;
     35     _pPASPBox             = NULL ; //PASP box
     36     if (_success)
     37     {
     38         _success = false;
     39 
     40         uint16 data16;
     41         uint32 data32;
     42 
     43         _pparent = NULL;
     44         // Read reserved values
     45         if (!AtomUtils::readByteData(fp, 6, _reserved))
     46         {
     47             return;
     48         }
     49         count -= 6;
     50 
     51         if (!AtomUtils::read16(fp, _dataReferenceIndex))
     52         {
     53             return;
     54         }
     55         count -= 2;
     56 
     57         if (!AtomUtils::read16(fp, data16))
     58         {
     59             return;
     60         }
     61         _preDefined1 = (int16)data16;
     62         count -= 2;
     63 
     64         if (!AtomUtils::read16(fp, data16))
     65         {
     66             return;
     67         }
     68         _reserved1 = (int16)data16;
     69         count -= 2;
     70 
     71         // Read in all reserved members
     72         for (int32 i = 0; i < 3; i++)
     73         {
     74             if (!AtomUtils::read32(fp, data32))
     75             {
     76                 return;
     77             }
     78             _predefined2[i] = (int32)data32;
     79             count -= 4;
     80         }
     81 
     82         if (!AtomUtils::read16(fp, data16))
     83         {
     84             return;
     85         }
     86         _width = (int16)data16;
     87         count -= 2;
     88 
     89         if (!AtomUtils::read16(fp, data16))
     90         {
     91             return;
     92         }
     93         _height = (int16)data16;
     94         count -= 2;
     95 
     96         if (!AtomUtils::read32(fp, data32))
     97         {
     98             return;
     99         }
    100         _horizResolution = (int32)data32;
    101         count -= 4;
    102 
    103         if (!AtomUtils::read32(fp, data32))
    104         {
    105             return;
    106         }
    107         _vertResolution = (int32)data32;
    108         count -= 4;
    109 
    110         if (!AtomUtils::read32(fp, data32))
    111         {
    112             return;
    113         }
    114         _reserved2 = (int32)data32;
    115         count -= 4;
    116 
    117         if (!AtomUtils::read16(fp, data16))
    118         {
    119             return;
    120         }
    121         _preDefined2 = (int16)data16;
    122         count -= 2;
    123 
    124         if (!AtomUtils::readByteData(fp, 32, _compressorName))
    125         {
    126             return;
    127         }
    128         count -= 32;
    129 
    130         if (!AtomUtils::read16(fp, data16))
    131         {
    132             return;
    133         }
    134         _depth = (int16)data16;
    135         count -= 2;
    136 
    137         if (!AtomUtils::read16(fp, data16))
    138         {
    139             return;
    140         }
    141         _predefined3 = (int16)data16;
    142         count -= 2;
    143 
    144         while (count >= DEFAULT_ATOM_SIZE)
    145         {
    146             uint32 atomType = UNKNOWN_ATOM;
    147             uint32 atomSize = 0;
    148 
    149             AtomUtils::getNextAtomType(fp, atomSize, atomType);
    150 
    151             if (atomType == AVC_CONFIGURATION_BOX)
    152             {
    153                 PV_MP4_FF_NEW(fp->auditCB, AVCConfigurationBox, (fp, atomSize, atomType), _pAVCConfigurationBox);
    154 
    155                 if (!_pAVCConfigurationBox->MP4Success())
    156                 {
    157                     _mp4ErrorCode = READ_AVC_CONFIG_BOX_FAILED;
    158                     return;
    159                 }
    160                 count -= atomSize;
    161             }
    162             else if (atomType == MPEG4_BITRATE_BOX)
    163             {
    164                 PV_MP4_FF_NEW(fp->auditCB, MPEG4BitRateBox, (fp, atomSize, atomType), _pMPEG4BitRateBox);
    165 
    166                 if (!_pMPEG4BitRateBox->MP4Success())
    167                 {
    168                     _mp4ErrorCode = READ_MPEG4_BITRATE_BOX_FAILED;
    169                     return;
    170                 }
    171                 count -= atomSize;
    172             }
    173             else if (atomType == PIXELASPECTRATIO_BOX) //PASP Box
    174             {
    175                 PV_MP4_FF_NEW(fp->auditCB, PASPBox, (fp, atomSize, atomType), _pPASPBox);
    176 
    177                 if (!_pPASPBox->MP4Success())
    178                 {
    179                     _mp4ErrorCode = READ_PIXELASPECTRATIO_BOX_FAILED;
    180                     return;
    181                 }
    182                 count -= atomSize;
    183             }
    184             else
    185             {
    186                 if (atomSize < DEFAULT_ATOM_SIZE)
    187                 {
    188                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
    189                     return;
    190                 }
    191                 if (count < (uint32)atomSize)
    192                 {
    193                     _mp4ErrorCode = READ_FAILED;
    194                     break;
    195                 }
    196                 count -= atomSize;
    197                 atomSize -= DEFAULT_ATOM_SIZE;
    198                 AtomUtils::seekFromCurrPos(fp, atomSize);
    199             }
    200 
    201         }
    202         if (count > 0)
    203         {
    204             //skip over any left over bytes
    205             AtomUtils::seekFromCurrPos(fp, count);
    206             count = 0;
    207         }
    208         if (createDecoderSpecificInfo(fp))
    209         {
    210             _success = true;
    211             _mp4ErrorCode = EVERYTHING_FINE;
    212         }
    213     }
    214 }
    215 
    216 // Destructor
    217 AVCSampleEntry::~AVCSampleEntry()
    218 {
    219     if (_pAVCConfigurationBox != NULL)
    220     {
    221         PV_MP4_FF_DELETE(NULL, AVCConfigurationBox, _pAVCConfigurationBox);
    222     }
    223     if (_pMPEG4BitRateBox != NULL)
    224     {
    225         PV_MP4_FF_DELETE(NULL, MPEG4BitRateBox, _pMPEG4BitRateBox);
    226     }
    227     if (_pPASPBox != NULL)
    228     {
    229         PV_MP4_FF_DELETE(NULL, PASPBox, _pPASPBox);
    230     }
    231     if (_decoderSpecificInfo != NULL)
    232     {
    233         PV_MP4_FF_DELETE(NULL, DecoderSpecificInfo, _decoderSpecificInfo);
    234     }
    235 }
    236 
    237 bool
    238 AVCSampleEntry::createDecoderSpecificInfo(MP4_FF_FILE *fp)
    239 {
    240     uint32 numSPS = getNumSequenceParamSets();
    241     uint32 numPPS = getNumPictureParamSets();
    242     uint32 totalSPSLen = getTotalSeqParameterSetLength();
    243     uint32 totalPPSLen = getTotalPictureParameterSetLength();
    244     uint32 len = (numSPS * 2) + (numPPS * 2) + totalSPSLen + totalPPSLen;
    245 
    246     if ((int32)len > 0)
    247     {
    248         PV_MP4_FF_NEW(fp->auditCB, DecoderSpecificInfo, (fp, true), _decoderSpecificInfo);
    249 
    250         uint8* info = (uint8*)(oscl_malloc(sizeof(uint8) * len));
    251         if (!info)
    252             return false;   // malloc failed (unlikely)
    253         uint8* destPtr = info;
    254         if (numSPS > 0)
    255         {
    256             for (uint32 i = 0; i < numSPS; i++)
    257             {
    258                 uint16 len = 0;
    259                 uint8* ptr = NULL;
    260                 if (getSequenceParamSet(i, len, ptr) == false)
    261                 {
    262                     OSCL_FREE(info);
    263                     return false;
    264                 }
    265                 oscl_memcpy(destPtr, &len, sizeof(uint16));
    266                 destPtr += sizeof(uint16);
    267                 oscl_memcpy(destPtr, ptr, len);
    268                 destPtr += len;
    269             }
    270         }
    271         if (numPPS > 0)
    272         {
    273             for (uint32 i = 0; i < numPPS; i++)
    274             {
    275                 uint16 len = 0;
    276                 uint8* ptr = NULL;
    277                 if (getPictureParamSet(i, len, ptr) == false)
    278                 {
    279                     OSCL_FREE(info);
    280                     return false;
    281                 }
    282                 oscl_memcpy(destPtr, &len, sizeof(uint16));
    283                 destPtr += sizeof(uint16);
    284                 oscl_memcpy(destPtr, ptr, len);
    285                 destPtr += len;
    286             }
    287         }
    288         _decoderSpecificInfo->setInfoSize(len);
    289         _decoderSpecificInfo->setInfo(info);
    290     }
    291     return true;
    292 }
    293