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