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                &paramSetLen);
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                &paramSetLen);
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