1 /* 2 * Copyright (C) 2011 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 ************************************************************************* 19 * @file VideoEditorUtils.cpp 20 * @brief StageFright shell Utilities 21 ************************************************************************* 22 */ 23 #define LOG_NDEBUG 0 24 #define LOG_TAG "SF_utils" 25 #include "utils/Log.h" 26 27 #include "VideoEditorUtils.h" 28 29 #include <media/stagefright/foundation/ADebug.h> 30 #include <media/stagefright/MediaErrors.h> 31 #include <media/stagefright/MediaExtractor.h> 32 #include <media/stagefright/MediaBuffer.h> 33 #include <media/stagefright/MetaData.h> 34 #include <media/stagefright/OMXCodec.h> 35 36 /* Android includes*/ 37 #include <utils/Log.h> 38 #include <memory.h> 39 40 /*---------------------*/ 41 /* DEBUG LEVEL SETUP */ 42 /*---------------------*/ 43 #define LOG1 ALOGE /*ERRORS Logging*/ 44 #define LOG2 ALOGI /*WARNING Logging*/ 45 #define LOG3 //ALOGV /*COMMENTS Logging*/ 46 47 namespace android { 48 49 void displayMetaData(const sp<MetaData> meta) { 50 51 const char* charData; 52 int32_t int32Data; 53 int64_t int64Data; 54 uint32_t type; 55 const void* data; 56 void* ptr; 57 size_t size; 58 59 if (meta->findCString(kKeyMIMEType, &charData)) { 60 LOG1("displayMetaData kKeyMIMEType %s", charData); 61 } 62 if (meta->findInt32(kKeyWidth, &int32Data)) { 63 LOG1("displayMetaData kKeyWidth %d", int32Data); 64 } 65 if (meta->findInt32(kKeyHeight, &int32Data)) { 66 LOG1("displayMetaData kKeyHeight %d", int32Data); 67 } 68 if (meta->findInt32(kKeyIFramesInterval, &int32Data)) { 69 LOG1("displayMetaData kKeyIFramesInterval %d", int32Data); 70 } 71 if (meta->findInt32(kKeyStride, &int32Data)) { 72 LOG1("displayMetaData kKeyStride %d", int32Data); 73 } 74 if (meta->findInt32(kKeySliceHeight, &int32Data)) { 75 LOG1("displayMetaData kKeySliceHeight %d", int32Data); 76 } 77 if (meta->findInt32(kKeyChannelCount, &int32Data)) { 78 LOG1("displayMetaData kKeyChannelCount %d", int32Data); 79 } 80 if (meta->findInt32(kKeySampleRate, &int32Data)) { 81 LOG1("displayMetaData kKeySampleRate %d", int32Data); 82 } 83 if (meta->findInt32(kKeyBitRate, &int32Data)) { 84 LOG1("displayMetaData kKeyBitRate %d", int32Data); 85 } 86 if (meta->findData(kKeyESDS, &type, &data, &size)) { 87 LOG1("displayMetaData kKeyESDS type=%d size=%d", type, size); 88 } 89 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 90 LOG1("displayMetaData kKeyAVCC data=0x%X type=%d size=%d", 91 *((unsigned int*)data), type, size); 92 } 93 if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 94 LOG1("displayMetaData kKeyVorbisInfo type=%d size=%d", type, size); 95 } 96 if (meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 97 LOG1("displayMetaData kKeyVorbisBooks type=%d size=%d", type, size); 98 } 99 if (meta->findInt32(kKeyWantsNALFragments, &int32Data)) { 100 LOG1("displayMetaData kKeyWantsNALFragments %d", int32Data); 101 } 102 if (meta->findInt32(kKeyIsSyncFrame, &int32Data)) { 103 LOG1("displayMetaData kKeyIsSyncFrame %d", int32Data); 104 } 105 if (meta->findInt32(kKeyIsCodecConfig, &int32Data)) { 106 LOG1("displayMetaData kKeyIsCodecConfig %d", int32Data); 107 } 108 if (meta->findInt64(kKeyTime, &int64Data)) { 109 LOG1("displayMetaData kKeyTime %lld", int64Data); 110 } 111 if (meta->findInt32(kKeyDuration, &int32Data)) { 112 LOG1("displayMetaData kKeyDuration %d", int32Data); 113 } 114 if (meta->findInt32(kKeyColorFormat, &int32Data)) { 115 LOG1("displayMetaData kKeyColorFormat %d", int32Data); 116 } 117 if (meta->findPointer(kKeyPlatformPrivate, &ptr)) { 118 LOG1("displayMetaData kKeyPlatformPrivate pointer=0x%x", (int32_t) ptr); 119 } 120 if (meta->findCString(kKeyDecoderComponent, &charData)) { 121 LOG1("displayMetaData kKeyDecoderComponent %s", charData); 122 } 123 if (meta->findInt32(kKeyBufferID, &int32Data)) { 124 LOG1("displayMetaData kKeyBufferID %d", int32Data); 125 } 126 if (meta->findInt32(kKeyMaxInputSize, &int32Data)) { 127 LOG1("displayMetaData kKeyMaxInputSize %d", int32Data); 128 } 129 if (meta->findInt64(kKeyThumbnailTime, &int64Data)) { 130 LOG1("displayMetaData kKeyThumbnailTime %lld", int64Data); 131 } 132 if (meta->findCString(kKeyAlbum, &charData)) { 133 LOG1("displayMetaData kKeyAlbum %s", charData); 134 } 135 if (meta->findCString(kKeyArtist, &charData)) { 136 LOG1("displayMetaData kKeyArtist %s", charData); 137 } 138 if (meta->findCString(kKeyAlbumArtist, &charData)) { 139 LOG1("displayMetaData kKeyAlbumArtist %s", charData); 140 } 141 if (meta->findCString(kKeyComposer, &charData)) { 142 LOG1("displayMetaData kKeyComposer %s", charData); 143 } 144 if (meta->findCString(kKeyGenre, &charData)) { 145 LOG1("displayMetaData kKeyGenre %s", charData); 146 } 147 if (meta->findCString(kKeyTitle, &charData)) { 148 LOG1("displayMetaData kKeyTitle %s", charData); 149 } 150 if (meta->findCString(kKeyYear, &charData)) { 151 LOG1("displayMetaData kKeyYear %s", charData); 152 } 153 if (meta->findData(kKeyAlbumArt, &type, &data, &size)) { 154 LOG1("displayMetaData kKeyAlbumArt type=%d size=%d", type, size); 155 } 156 if (meta->findCString(kKeyAlbumArtMIME, &charData)) { 157 LOG1("displayMetaData kKeyAlbumArtMIME %s", charData); 158 } 159 if (meta->findCString(kKeyAuthor, &charData)) { 160 LOG1("displayMetaData kKeyAuthor %s", charData); 161 } 162 if (meta->findCString(kKeyCDTrackNumber, &charData)) { 163 LOG1("displayMetaData kKeyCDTrackNumber %s", charData); 164 } 165 if (meta->findCString(kKeyDiscNumber, &charData)) { 166 LOG1("displayMetaData kKeyDiscNumber %s", charData); 167 } 168 if (meta->findCString(kKeyDate, &charData)) { 169 LOG1("displayMetaData kKeyDate %s", charData); 170 } 171 if (meta->findCString(kKeyWriter, &charData)) { 172 LOG1("displayMetaData kKeyWriter %s", charData); 173 } 174 if (meta->findInt32(kKeyTimeScale, &int32Data)) { 175 LOG1("displayMetaData kKeyTimeScale %d", int32Data); 176 } 177 if (meta->findInt32(kKeyVideoProfile, &int32Data)) { 178 LOG1("displayMetaData kKeyVideoProfile %d", int32Data); 179 } 180 if (meta->findInt32(kKeyVideoLevel, &int32Data)) { 181 LOG1("displayMetaData kKeyVideoLevel %d", int32Data); 182 } 183 if (meta->findInt32(kKey64BitFileOffset, &int32Data)) { 184 LOG1("displayMetaData kKey64BitFileOffset %d", int32Data); 185 } 186 if (meta->findInt32(kKeyFileType, &int32Data)) { 187 LOG1("displayMetaData kKeyFileType %d", int32Data); 188 } 189 if (meta->findInt64(kKeyTrackTimeStatus, &int64Data)) { 190 LOG1("displayMetaData kKeyTrackTimeStatus %lld", int64Data); 191 } 192 if (meta->findInt32(kKeyRealTimeRecording, &int32Data)) { 193 LOG1("displayMetaData kKeyRealTimeRecording %d", int32Data); 194 } 195 } 196 197 /** 198 * This code was extracted from StageFright MPEG4 writer 199 * Is is used to parse and format the AVC codec specific info received 200 * from StageFright encoders 201 */ 202 static const uint8_t kNalUnitTypeSeqParamSet = 0x07; 203 static const uint8_t kNalUnitTypePicParamSet = 0x08; 204 struct AVCParamSet { 205 AVCParamSet(uint16_t length, const uint8_t *data) 206 : mLength(length), mData(data) {} 207 208 uint16_t mLength; 209 const uint8_t *mData; 210 }; 211 struct AVCCodecSpecificContext { 212 List<AVCParamSet> mSeqParamSets; 213 List<AVCParamSet> mPicParamSets; 214 uint8_t mProfileIdc; 215 uint8_t mProfileCompatible; 216 uint8_t mLevelIdc; 217 }; 218 219 const uint8_t *parseParamSet(AVCCodecSpecificContext* pC, 220 const uint8_t *data, size_t length, int type, size_t *paramSetLen) { 221 CHECK(type == kNalUnitTypeSeqParamSet || 222 type == kNalUnitTypePicParamSet); 223 224 size_t bytesLeft = length; 225 while (bytesLeft > 4 && 226 memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) { 227 --bytesLeft; 228 } 229 if (bytesLeft <= 4) { 230 bytesLeft = 0; // Last parameter set 231 } 232 const uint8_t *nextStartCode = &data[length - bytesLeft]; 233 *paramSetLen = nextStartCode - data; 234 if (*paramSetLen == 0) { 235 ALOGE("Param set is malformed, since its length is 0"); 236 return NULL; 237 } 238 239 AVCParamSet paramSet(*paramSetLen, data); 240 if (type == kNalUnitTypeSeqParamSet) { 241 if (*paramSetLen < 4) { 242 ALOGE("Seq parameter set malformed"); 243 return NULL; 244 } 245 if (pC->mSeqParamSets.empty()) { 246 pC->mProfileIdc = data[1]; 247 pC->mProfileCompatible = data[2]; 248 pC->mLevelIdc = data[3]; 249 } else { 250 if (pC->mProfileIdc != data[1] || 251 pC->mProfileCompatible != data[2] || 252 pC->mLevelIdc != data[3]) { 253 ALOGV("Inconsistent profile/level found in seq parameter sets"); 254 return NULL; 255 } 256 } 257 pC->mSeqParamSets.push_back(paramSet); 258 } else { 259 pC->mPicParamSets.push_back(paramSet); 260 } 261 return nextStartCode; 262 } 263 264 status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize, 265 const uint8_t *data, size_t size, MetaData *param) 266 { 267 //ALOGV("buildAVCCodecSpecificData"); 268 269 if ( (pOutputData == NULL) || (pOutputSize == NULL) ) { 270 ALOGE("output is invalid"); 271 return ERROR_MALFORMED; 272 } 273 274 if (*pOutputData != NULL) { 275 ALOGE("Already have codec specific data"); 276 return ERROR_MALFORMED; 277 } 278 279 if (size < 4) { 280 ALOGE("Codec specific data length too short: %d", size); 281 return ERROR_MALFORMED; 282 } 283 284 // Data is in the form of AVCCodecSpecificData 285 if (memcmp("\x00\x00\x00\x01", data, 4)) { 286 // 2 bytes for each of the parameter set length field 287 // plus the 7 bytes for the header 288 if (size < 4 + 7) { 289 ALOGE("Codec specific data length too short: %d", size); 290 return ERROR_MALFORMED; 291 } 292 293 *pOutputSize = size; 294 *pOutputData = (uint8_t*)malloc(size); 295 memcpy(*pOutputData, data, size); 296 return OK; 297 } 298 299 AVCCodecSpecificContext ctx; 300 uint8_t *outputData = NULL; 301 size_t outputSize = 0; 302 303 // Check if the data is valid 304 uint8_t type = kNalUnitTypeSeqParamSet; 305 bool gotSps = false; 306 bool gotPps = false; 307 const uint8_t *tmp = data; 308 const uint8_t *nextStartCode = data; 309 size_t bytesLeft = size; 310 size_t paramSetLen = 0; 311 outputSize = 0; 312 while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) { 313 type = (*(tmp + 4)) & 0x1F; 314 if (type == kNalUnitTypeSeqParamSet) { 315 if (gotPps) { 316 ALOGE("SPS must come before PPS"); 317 return ERROR_MALFORMED; 318 } 319 if (!gotSps) { 320 gotSps = true; 321 } 322 nextStartCode = parseParamSet(&ctx, tmp + 4, bytesLeft - 4, type, 323 ¶mSetLen); 324 } else if (type == kNalUnitTypePicParamSet) { 325 if (!gotSps) { 326 ALOGE("SPS must come before PPS"); 327 return ERROR_MALFORMED; 328 } 329 if (!gotPps) { 330 gotPps = true; 331 } 332 nextStartCode = parseParamSet(&ctx, tmp + 4, bytesLeft - 4, type, 333 ¶mSetLen); 334 } else { 335 ALOGE("Only SPS and PPS Nal units are expected"); 336 return ERROR_MALFORMED; 337 } 338 339 if (nextStartCode == NULL) { 340 return ERROR_MALFORMED; 341 } 342 343 // Move on to find the next parameter set 344 bytesLeft -= nextStartCode - tmp; 345 tmp = nextStartCode; 346 outputSize += (2 + paramSetLen); 347 } 348 349 { 350 // Check on the number of seq parameter sets 351 size_t nSeqParamSets = ctx.mSeqParamSets.size(); 352 if (nSeqParamSets == 0) { 353 ALOGE("Cound not find sequence parameter set"); 354 return ERROR_MALFORMED; 355 } 356 357 if (nSeqParamSets > 0x1F) { 358 ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets); 359 return ERROR_MALFORMED; 360 } 361 } 362 363 { 364 // Check on the number of pic parameter sets 365 size_t nPicParamSets = ctx.mPicParamSets.size(); 366 if (nPicParamSets == 0) { 367 ALOGE("Cound not find picture parameter set"); 368 return ERROR_MALFORMED; 369 } 370 if (nPicParamSets > 0xFF) { 371 ALOGE("Too many pic parameter sets (%d) found", nPicParamSets); 372 return ERROR_MALFORMED; 373 } 374 } 375 376 // ISO 14496-15: AVC file format 377 outputSize += 7; // 7 more bytes in the header 378 outputData = (uint8_t *)malloc(outputSize); 379 uint8_t *header = outputData; 380 header[0] = 1; // version 381 header[1] = ctx.mProfileIdc; // profile indication 382 header[2] = ctx.mProfileCompatible; // profile compatibility 383 header[3] = ctx.mLevelIdc; 384 385 // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne 386 int32_t use2ByteNalLength = 0; 387 if (param && 388 param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) && 389 use2ByteNalLength) { 390 header[4] = 0xfc | 1; // length size == 2 bytes 391 } else { 392 header[4] = 0xfc | 3; // length size == 4 bytes 393 } 394 395 // 3-bit '111' followed by 5-bit numSequenceParameterSets 396 int nSequenceParamSets = ctx.mSeqParamSets.size(); 397 header[5] = 0xe0 | nSequenceParamSets; 398 header += 6; 399 for (List<AVCParamSet>::iterator it = ctx.mSeqParamSets.begin(); 400 it != ctx.mSeqParamSets.end(); ++it) { 401 // 16-bit sequence parameter set length 402 uint16_t seqParamSetLength = it->mLength; 403 header[0] = seqParamSetLength >> 8; 404 header[1] = seqParamSetLength & 0xff; 405 //ALOGE("### SPS %d %d %d", seqParamSetLength, header[0], header[1]); 406 407 // SPS NAL unit (sequence parameter length bytes) 408 memcpy(&header[2], it->mData, seqParamSetLength); 409 header += (2 + seqParamSetLength); 410 } 411 412 // 8-bit nPictureParameterSets 413 int nPictureParamSets = ctx.mPicParamSets.size(); 414 header[0] = nPictureParamSets; 415 header += 1; 416 for (List<AVCParamSet>::iterator it = ctx.mPicParamSets.begin(); 417 it != ctx.mPicParamSets.end(); ++it) { 418 // 16-bit picture parameter set length 419 uint16_t picParamSetLength = it->mLength; 420 header[0] = picParamSetLength >> 8; 421 header[1] = picParamSetLength & 0xff; 422 //ALOGE("### PPS %d %d %d", picParamSetLength, header[0], header[1]); 423 424 // PPS Nal unit (picture parameter set length bytes) 425 memcpy(&header[2], it->mData, picParamSetLength); 426 header += (2 + picParamSetLength); 427 } 428 429 *pOutputSize = outputSize; 430 *pOutputData = outputData; 431 return OK; 432 } 433 }// namespace android 434