Home | History | Annotate | Download | only in src
      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/MediaErrors.h>
     30 #include <media/stagefright/MediaDebug.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 LOGE    /*ERRORS Logging*/
     44 #define LOG2 LOGI    /*WARNING Logging*/
     45 #define LOG3 //LOGV  /*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(kKeyNotRealTime, &int32Data)) {
    193         LOG1("displayMetaData kKeyNotRealTime %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         LOGE("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             LOGE("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                 LOGV("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     //LOGV("buildAVCCodecSpecificData");
    268 
    269     if ( (pOutputData == NULL) || (pOutputSize == NULL) ) {
    270         LOGE("output is invalid");
    271         return ERROR_MALFORMED;
    272     }
    273 
    274     if (*pOutputData != NULL) {
    275         LOGE("Already have codec specific data");
    276         return ERROR_MALFORMED;
    277     }
    278 
    279     if (size < 4) {
    280         LOGE("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             LOGE("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                 LOGE("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                 &paramSetLen);
    324         } else if (type == kNalUnitTypePicParamSet) {
    325             if (!gotSps) {
    326                 LOGE("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                 &paramSetLen);
    334         } else {
    335             LOGE("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             LOGE("Cound not find sequence parameter set");
    354             return ERROR_MALFORMED;
    355         }
    356 
    357         if (nSeqParamSets > 0x1F) {
    358             LOGE("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             LOGE("Cound not find picture parameter set");
    368             return ERROR_MALFORMED;
    369         }
    370         if (nPicParamSets > 0xFF) {
    371             LOGE("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         //LOGE("### 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 //LOGE("### 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