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