ESQueue.cpp revision b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81
1/*
2 * Copyright (C) 2010 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//#define LOG_NDEBUG 0
18#define LOG_TAG "ESQueue"
19#include <media/stagefright/foundation/ADebug.h>
20
21#include "ESQueue.h"
22
23#include <media/stagefright/foundation/hexdump.h>
24#include <media/stagefright/foundation/ABitReader.h>
25#include <media/stagefright/foundation/ABuffer.h>
26#include <media/stagefright/foundation/AMessage.h>
27#include <media/stagefright/MediaErrors.h>
28#include <media/stagefright/MediaDefs.h>
29#include <media/stagefright/MetaData.h>
30#include <media/stagefright/Utils.h>
31
32#include "include/avc_utils.h"
33
34#include <inttypes.h>
35#include <netinet/in.h>
36
37namespace android {
38
39ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
40    : mMode(mode),
41      mFlags(flags) {
42}
43
44sp<MetaData> ElementaryStreamQueue::getFormat() {
45    return mFormat;
46}
47
48void ElementaryStreamQueue::clear(bool clearFormat) {
49    if (mBuffer != NULL) {
50        mBuffer->setRange(0, 0);
51    }
52
53    mRangeInfos.clear();
54
55    if (clearFormat) {
56        mFormat.clear();
57    }
58}
59
60// Parse AC3 header assuming the current ptr is start position of syncframe,
61// update metadata only applicable, and return the payload size
62static unsigned parseAC3SyncFrame(
63        const uint8_t *ptr, size_t size, sp<MetaData> *metaData) {
64    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
65    static const unsigned samplingRateTable[] = {48000, 44100, 32000};
66    static const unsigned rates[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256,
67            320, 384, 448, 512, 576, 640};
68
69    static const unsigned frameSizeTable[19][3] = {
70        { 64, 69, 96 },
71        { 80, 87, 120 },
72        { 96, 104, 144 },
73        { 112, 121, 168 },
74        { 128, 139, 192 },
75        { 160, 174, 240 },
76        { 192, 208, 288 },
77        { 224, 243, 336 },
78        { 256, 278, 384 },
79        { 320, 348, 480 },
80        { 384, 417, 576 },
81        { 448, 487, 672 },
82        { 512, 557, 768 },
83        { 640, 696, 960 },
84        { 768, 835, 1152 },
85        { 896, 975, 1344 },
86        { 1024, 1114, 1536 },
87        { 1152, 1253, 1728 },
88        { 1280, 1393, 1920 },
89    };
90
91    ABitReader bits(ptr, size);
92    unsigned syncStartPos = 0;  // in bytes
93    if (bits.numBitsLeft() < 16) {
94        return 0;
95    }
96    if (bits.getBits(16) != 0x0B77) {
97        return 0;
98    }
99
100    if (bits.numBitsLeft() < 16 + 2 + 6 + 5 + 3 + 3) {
101        ALOGV("Not enough bits left for further parsing");
102        return 0;
103    }
104    bits.skipBits(16);  // crc1
105
106    unsigned fscod = bits.getBits(2);
107    if (fscod == 3) {
108        ALOGW("Incorrect fscod in AC3 header");
109        return 0;
110    }
111
112    unsigned frmsizecod = bits.getBits(6);
113    if (frmsizecod > 37) {
114        ALOGW("Incorrect frmsizecod in AC3 header");
115        return 0;
116    }
117
118    unsigned bsid = bits.getBits(5);
119    if (bsid > 8) {
120        ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
121        return 0;
122    }
123
124    unsigned bsmod = bits.getBits(3);
125    unsigned acmod = bits.getBits(3);
126    unsigned cmixlev = 0;
127    unsigned surmixlev = 0;
128    unsigned dsurmod = 0;
129
130    if ((acmod & 1) > 0 && acmod != 1) {
131        if (bits.numBitsLeft() < 2) {
132            return 0;
133        }
134        cmixlev = bits.getBits(2);
135    }
136    if ((acmod & 4) > 0) {
137        if (bits.numBitsLeft() < 2) {
138            return 0;
139        }
140        surmixlev = bits.getBits(2);
141    }
142    if (acmod == 2) {
143        if (bits.numBitsLeft() < 2) {
144            return 0;
145        }
146        dsurmod = bits.getBits(2);
147    }
148
149    if (bits.numBitsLeft() < 1) {
150        return 0;
151    }
152    unsigned lfeon = bits.getBits(1);
153
154    unsigned samplingRate = samplingRateTable[fscod];
155    unsigned payloadSize = frameSizeTable[frmsizecod >> 1][fscod];
156    if (fscod == 1) {
157        payloadSize += frmsizecod & 1;
158    }
159    payloadSize <<= 1;  // convert from 16-bit words to bytes
160
161    unsigned channelCount = channelCountTable[acmod] + lfeon;
162
163    if (metaData != NULL) {
164        (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
165        (*metaData)->setInt32(kKeyChannelCount, channelCount);
166        (*metaData)->setInt32(kKeySampleRate, samplingRate);
167    }
168
169    return payloadSize;
170}
171
172static bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) {
173    return parseAC3SyncFrame(ptr, size, NULL) > 0;
174}
175
176static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) {
177    if (size < 3) {
178        // Not enough data to verify header.
179        return false;
180    }
181
182    if (ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
183        return false;
184    }
185
186    unsigned layer = (ptr[1] >> 1) & 3;
187
188    if (layer != 0) {
189        return false;
190    }
191
192    unsigned ID = (ptr[1] >> 3) & 1;
193    unsigned profile_ObjectType = ptr[2] >> 6;
194
195    if (ID == 1 && profile_ObjectType == 3) {
196        // MPEG-2 profile 3 is reserved.
197        return false;
198    }
199
200    return true;
201}
202
203static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
204    if (size < 3) {
205        // Not enough data to verify header.
206        return false;
207    }
208
209    if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) {
210        return false;
211    }
212
213    unsigned ID = (ptr[1] >> 3) & 3;
214
215    if (ID == 1) {
216        return false;  // reserved
217    }
218
219    unsigned layer = (ptr[1] >> 1) & 3;
220
221    if (layer == 0) {
222        return false;  // reserved
223    }
224
225    unsigned bitrateIndex = (ptr[2] >> 4);
226
227    if (bitrateIndex == 0x0f) {
228        return false;  // reserved
229    }
230
231    unsigned samplingRateIndex = (ptr[2] >> 2) & 3;
232
233    if (samplingRateIndex == 3) {
234        return false;  // reserved
235    }
236
237    return true;
238}
239
240status_t ElementaryStreamQueue::appendData(
241        const void *data, size_t size, int64_t timeUs) {
242    if (mBuffer == NULL || mBuffer->size() == 0) {
243        switch (mMode) {
244            case H264:
245            case MPEG_VIDEO:
246            {
247#if 0
248                if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
249                    return ERROR_MALFORMED;
250                }
251#else
252                uint8_t *ptr = (uint8_t *)data;
253
254                ssize_t startOffset = -1;
255                for (size_t i = 0; i + 3 < size; ++i) {
256                    if (!memcmp("\x00\x00\x00\x01", &ptr[i], 4)) {
257                        startOffset = i;
258                        break;
259                    }
260                }
261
262                if (startOffset < 0) {
263                    return ERROR_MALFORMED;
264                }
265
266                if (startOffset > 0) {
267                    ALOGI("found something resembling an H.264/MPEG syncword "
268                          "at offset %zd",
269                          startOffset);
270                }
271
272                data = &ptr[startOffset];
273                size -= startOffset;
274#endif
275                break;
276            }
277
278            case MPEG4_VIDEO:
279            {
280#if 0
281                if (size < 3 || memcmp("\x00\x00\x01", data, 3)) {
282                    return ERROR_MALFORMED;
283                }
284#else
285                uint8_t *ptr = (uint8_t *)data;
286
287                ssize_t startOffset = -1;
288                for (size_t i = 0; i + 2 < size; ++i) {
289                    if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
290                        startOffset = i;
291                        break;
292                    }
293                }
294
295                if (startOffset < 0) {
296                    return ERROR_MALFORMED;
297                }
298
299                if (startOffset > 0) {
300                    ALOGI("found something resembling an H.264/MPEG syncword "
301                          "at offset %zd",
302                          startOffset);
303                }
304
305                data = &ptr[startOffset];
306                size -= startOffset;
307#endif
308                break;
309            }
310
311            case AAC:
312            {
313                uint8_t *ptr = (uint8_t *)data;
314
315#if 0
316                if (size < 2 || ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
317                    return ERROR_MALFORMED;
318                }
319#else
320                ssize_t startOffset = -1;
321                for (size_t i = 0; i < size; ++i) {
322                    if (IsSeeminglyValidADTSHeader(&ptr[i], size - i)) {
323                        startOffset = i;
324                        break;
325                    }
326                }
327
328                if (startOffset < 0) {
329                    return ERROR_MALFORMED;
330                }
331
332                if (startOffset > 0) {
333                    ALOGI("found something resembling an AAC syncword at "
334                          "offset %zd",
335                          startOffset);
336                }
337
338                data = &ptr[startOffset];
339                size -= startOffset;
340#endif
341                break;
342            }
343
344            case AC3:
345            {
346                uint8_t *ptr = (uint8_t *)data;
347
348                ssize_t startOffset = -1;
349                for (size_t i = 0; i < size; ++i) {
350                    if (IsSeeminglyValidAC3Header(&ptr[i], size - i)) {
351                        startOffset = i;
352                        break;
353                    }
354                }
355
356                if (startOffset < 0) {
357                    return ERROR_MALFORMED;
358                }
359
360                if (startOffset > 0) {
361                    ALOGI("found something resembling an AC3 syncword at "
362                          "offset %zd",
363                          startOffset);
364                }
365
366                data = &ptr[startOffset];
367                size -= startOffset;
368                break;
369            }
370
371            case MPEG_AUDIO:
372            {
373                uint8_t *ptr = (uint8_t *)data;
374
375                ssize_t startOffset = -1;
376                for (size_t i = 0; i < size; ++i) {
377                    if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) {
378                        startOffset = i;
379                        break;
380                    }
381                }
382
383                if (startOffset < 0) {
384                    return ERROR_MALFORMED;
385                }
386
387                if (startOffset > 0) {
388                    ALOGI("found something resembling an MPEG audio "
389                          "syncword at offset %zd",
390                          startOffset);
391                }
392
393                data = &ptr[startOffset];
394                size -= startOffset;
395                break;
396            }
397
398            case PCM_AUDIO:
399            {
400                break;
401            }
402
403            default:
404                TRESPASS();
405                break;
406        }
407    }
408
409    size_t neededSize = (mBuffer == NULL ? 0 : mBuffer->size()) + size;
410    if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
411        neededSize = (neededSize + 65535) & ~65535;
412
413        ALOGV("resizing buffer to size %zu", neededSize);
414
415        sp<ABuffer> buffer = new ABuffer(neededSize);
416        if (mBuffer != NULL) {
417            memcpy(buffer->data(), mBuffer->data(), mBuffer->size());
418            buffer->setRange(0, mBuffer->size());
419        } else {
420            buffer->setRange(0, 0);
421        }
422
423        mBuffer = buffer;
424    }
425
426    memcpy(mBuffer->data() + mBuffer->size(), data, size);
427    mBuffer->setRange(0, mBuffer->size() + size);
428
429    RangeInfo info;
430    info.mLength = size;
431    info.mTimestampUs = timeUs;
432    mRangeInfos.push_back(info);
433
434#if 0
435    if (mMode == AAC) {
436        ALOGI("size = %zu, timeUs = %.2f secs", size, timeUs / 1E6);
437        hexdump(data, size);
438    }
439#endif
440
441    return OK;
442}
443
444sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
445    if ((mFlags & kFlag_AlignedData) && mMode == H264) {
446        if (mRangeInfos.empty()) {
447            return NULL;
448        }
449
450        RangeInfo info = *mRangeInfos.begin();
451        mRangeInfos.erase(mRangeInfos.begin());
452
453        sp<ABuffer> accessUnit = new ABuffer(info.mLength);
454        memcpy(accessUnit->data(), mBuffer->data(), info.mLength);
455        accessUnit->meta()->setInt64("timeUs", info.mTimestampUs);
456
457        memmove(mBuffer->data(),
458                mBuffer->data() + info.mLength,
459                mBuffer->size() - info.mLength);
460
461        mBuffer->setRange(0, mBuffer->size() - info.mLength);
462
463        if (mFormat == NULL) {
464            mFormat = MakeAVCCodecSpecificData(accessUnit);
465        }
466
467        return accessUnit;
468    }
469
470    switch (mMode) {
471        case H264:
472            return dequeueAccessUnitH264();
473        case AAC:
474            return dequeueAccessUnitAAC();
475        case AC3:
476            return dequeueAccessUnitAC3();
477        case MPEG_VIDEO:
478            return dequeueAccessUnitMPEGVideo();
479        case MPEG4_VIDEO:
480            return dequeueAccessUnitMPEG4Video();
481        case PCM_AUDIO:
482            return dequeueAccessUnitPCMAudio();
483        default:
484            CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
485            return dequeueAccessUnitMPEGAudio();
486    }
487}
488
489sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() {
490    unsigned syncStartPos = 0;  // in bytes
491    unsigned payloadSize = 0;
492    sp<MetaData> format = new MetaData;
493    while (true) {
494        if (syncStartPos + 2 >= mBuffer->size()) {
495            return NULL;
496        }
497
498        payloadSize = parseAC3SyncFrame(
499                mBuffer->data() + syncStartPos,
500                mBuffer->size() - syncStartPos,
501                &format);
502        if (payloadSize > 0) {
503            break;
504        }
505        ++syncStartPos;
506    }
507
508    if (mBuffer->size() < syncStartPos + payloadSize) {
509        ALOGV("Not enough buffer size for AC3");
510        return NULL;
511    }
512
513    if (mFormat == NULL) {
514        mFormat = format;
515    }
516
517    sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
518    memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
519
520    int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
521    CHECK_GE(timeUs, 0ll);
522    accessUnit->meta()->setInt64("timeUs", timeUs);
523
524    memmove(
525            mBuffer->data(),
526            mBuffer->data() + syncStartPos + payloadSize,
527            mBuffer->size() - syncStartPos - payloadSize);
528
529    mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
530
531    return accessUnit;
532}
533
534sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
535    if (mBuffer->size() < 4) {
536        return NULL;
537    }
538
539    ABitReader bits(mBuffer->data(), 4);
540    CHECK_EQ(bits.getBits(8), 0xa0);
541    unsigned numAUs = bits.getBits(8);
542    bits.skipBits(8);
543    unsigned quantization_word_length = bits.getBits(2);
544    unsigned audio_sampling_frequency = bits.getBits(3);
545    unsigned num_channels = bits.getBits(3);
546
547    CHECK_EQ(audio_sampling_frequency, 2);  // 48kHz
548    CHECK_EQ(num_channels, 1u);  // stereo!
549
550    if (mFormat == NULL) {
551        mFormat = new MetaData;
552        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
553        mFormat->setInt32(kKeyChannelCount, 2);
554        mFormat->setInt32(kKeySampleRate, 48000);
555    }
556
557    static const size_t kFramesPerAU = 80;
558    size_t frameSize = 2 /* numChannels */ * sizeof(int16_t);
559
560    size_t payloadSize = numAUs * frameSize * kFramesPerAU;
561
562    if (mBuffer->size() < 4 + payloadSize) {
563        return NULL;
564    }
565
566    sp<ABuffer> accessUnit = new ABuffer(payloadSize);
567    memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
568
569    int64_t timeUs = fetchTimestamp(payloadSize + 4);
570    CHECK_GE(timeUs, 0ll);
571    accessUnit->meta()->setInt64("timeUs", timeUs);
572
573    int16_t *ptr = (int16_t *)accessUnit->data();
574    for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) {
575        ptr[i] = ntohs(ptr[i]);
576    }
577
578    memmove(
579            mBuffer->data(),
580            mBuffer->data() + 4 + payloadSize,
581            mBuffer->size() - 4 - payloadSize);
582
583    mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize);
584
585    return accessUnit;
586}
587
588sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
589    if (mBuffer->size() == 0) {
590        return NULL;
591    }
592
593    CHECK(!mRangeInfos.empty());
594
595    const RangeInfo &info = *mRangeInfos.begin();
596    if (mBuffer->size() < info.mLength) {
597        return NULL;
598    }
599
600    CHECK_GE(info.mTimestampUs, 0ll);
601
602    // The idea here is consume all AAC frames starting at offsets before
603    // info.mLength so we can assign a meaningful timestamp without
604    // having to interpolate.
605    // The final AAC frame may well extend into the next RangeInfo but
606    // that's ok.
607    size_t offset = 0;
608    while (offset < info.mLength) {
609        if (offset + 7 > mBuffer->size()) {
610            return NULL;
611        }
612
613        ABitReader bits(mBuffer->data() + offset, mBuffer->size() - offset);
614
615        // adts_fixed_header
616
617        CHECK_EQ(bits.getBits(12), 0xfffu);
618        bits.skipBits(3);  // ID, layer
619        bool protection_absent = bits.getBits(1) != 0;
620
621        if (mFormat == NULL) {
622            unsigned profile = bits.getBits(2);
623            CHECK_NE(profile, 3u);
624            unsigned sampling_freq_index = bits.getBits(4);
625            bits.getBits(1);  // private_bit
626            unsigned channel_configuration = bits.getBits(3);
627            CHECK_NE(channel_configuration, 0u);
628            bits.skipBits(2);  // original_copy, home
629
630            mFormat = MakeAACCodecSpecificData(
631                    profile, sampling_freq_index, channel_configuration);
632
633            mFormat->setInt32(kKeyIsADTS, true);
634
635            int32_t sampleRate;
636            int32_t numChannels;
637            CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate));
638            CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels));
639
640            ALOGI("found AAC codec config (%d Hz, %d channels)",
641                 sampleRate, numChannels);
642        } else {
643            // profile_ObjectType, sampling_frequency_index, private_bits,
644            // channel_configuration, original_copy, home
645            bits.skipBits(12);
646        }
647
648        // adts_variable_header
649
650        // copyright_identification_bit, copyright_identification_start
651        bits.skipBits(2);
652
653        unsigned aac_frame_length = bits.getBits(13);
654
655        bits.skipBits(11);  // adts_buffer_fullness
656
657        unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2);
658
659        if (number_of_raw_data_blocks_in_frame != 0) {
660            // To be implemented.
661            TRESPASS();
662        }
663
664        if (offset + aac_frame_length > mBuffer->size()) {
665            return NULL;
666        }
667
668        size_t headerSize = protection_absent ? 7 : 9;
669
670        offset += aac_frame_length;
671    }
672
673    int64_t timeUs = fetchTimestamp(offset);
674
675    sp<ABuffer> accessUnit = new ABuffer(offset);
676    memcpy(accessUnit->data(), mBuffer->data(), offset);
677
678    memmove(mBuffer->data(), mBuffer->data() + offset,
679            mBuffer->size() - offset);
680    mBuffer->setRange(0, mBuffer->size() - offset);
681
682    accessUnit->meta()->setInt64("timeUs", timeUs);
683
684    return accessUnit;
685}
686
687int64_t ElementaryStreamQueue::fetchTimestamp(size_t size) {
688    int64_t timeUs = -1;
689    bool first = true;
690
691    while (size > 0) {
692        CHECK(!mRangeInfos.empty());
693
694        RangeInfo *info = &*mRangeInfos.begin();
695
696        if (first) {
697            timeUs = info->mTimestampUs;
698            first = false;
699        }
700
701        if (info->mLength > size) {
702            info->mLength -= size;
703            size = 0;
704        } else {
705            size -= info->mLength;
706
707            mRangeInfos.erase(mRangeInfos.begin());
708            info = NULL;
709        }
710
711    }
712
713    if (timeUs == 0ll) {
714        ALOGV("Returning 0 timestamp");
715    }
716
717    return timeUs;
718}
719
720struct NALPosition {
721    size_t nalOffset;
722    size_t nalSize;
723};
724
725sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
726    const uint8_t *data = mBuffer->data();
727
728    size_t size = mBuffer->size();
729    Vector<NALPosition> nals;
730
731    size_t totalSize = 0;
732
733    status_t err;
734    const uint8_t *nalStart;
735    size_t nalSize;
736    bool foundSlice = false;
737    while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) {
738        if (nalSize == 0) continue;
739
740        unsigned nalType = nalStart[0] & 0x1f;
741        bool flush = false;
742
743        if (nalType == 1 || nalType == 5) {
744            if (foundSlice) {
745                ABitReader br(nalStart + 1, nalSize);
746                unsigned first_mb_in_slice = parseUE(&br);
747
748                if (first_mb_in_slice == 0) {
749                    // This slice starts a new frame.
750
751                    flush = true;
752                }
753            }
754
755            foundSlice = true;
756        } else if ((nalType == 9 || nalType == 7) && foundSlice) {
757            // Access unit delimiter and SPS will be associated with the
758            // next frame.
759
760            flush = true;
761        }
762
763        if (flush) {
764            // The access unit will contain all nal units up to, but excluding
765            // the current one, separated by 0x00 0x00 0x00 0x01 startcodes.
766
767            size_t auSize = 4 * nals.size() + totalSize;
768            sp<ABuffer> accessUnit = new ABuffer(auSize);
769
770#if !LOG_NDEBUG
771            AString out;
772#endif
773
774            size_t dstOffset = 0;
775            for (size_t i = 0; i < nals.size(); ++i) {
776                const NALPosition &pos = nals.itemAt(i);
777
778                unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;
779
780#if !LOG_NDEBUG
781                char tmp[128];
782                sprintf(tmp, "0x%02x", nalType);
783                if (i > 0) {
784                    out.append(", ");
785                }
786                out.append(tmp);
787#endif
788
789                memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4);
790
791                memcpy(accessUnit->data() + dstOffset + 4,
792                       mBuffer->data() + pos.nalOffset,
793                       pos.nalSize);
794
795                dstOffset += pos.nalSize + 4;
796            }
797
798#if !LOG_NDEBUG
799            ALOGV("accessUnit contains nal types %s", out.c_str());
800#endif
801
802            const NALPosition &pos = nals.itemAt(nals.size() - 1);
803            size_t nextScan = pos.nalOffset + pos.nalSize;
804
805            memmove(mBuffer->data(),
806                    mBuffer->data() + nextScan,
807                    mBuffer->size() - nextScan);
808
809            mBuffer->setRange(0, mBuffer->size() - nextScan);
810
811            int64_t timeUs = fetchTimestamp(nextScan);
812            CHECK_GE(timeUs, 0ll);
813
814            accessUnit->meta()->setInt64("timeUs", timeUs);
815
816            if (mFormat == NULL) {
817                mFormat = MakeAVCCodecSpecificData(accessUnit);
818            }
819
820            return accessUnit;
821        }
822
823        NALPosition pos;
824        pos.nalOffset = nalStart - mBuffer->data();
825        pos.nalSize = nalSize;
826
827        nals.push(pos);
828
829        totalSize += nalSize;
830    }
831    CHECK_EQ(err, (status_t)-EAGAIN);
832
833    return NULL;
834}
835
836sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
837    const uint8_t *data = mBuffer->data();
838    size_t size = mBuffer->size();
839
840    if (size < 4) {
841        return NULL;
842    }
843
844    uint32_t header = U32_AT(data);
845
846    size_t frameSize;
847    int samplingRate, numChannels, bitrate, numSamples;
848    CHECK(GetMPEGAudioFrameSize(
849                header, &frameSize, &samplingRate, &numChannels,
850                &bitrate, &numSamples));
851
852    if (size < frameSize) {
853        return NULL;
854    }
855
856    unsigned layer = 4 - ((header >> 17) & 3);
857
858    sp<ABuffer> accessUnit = new ABuffer(frameSize);
859    memcpy(accessUnit->data(), data, frameSize);
860
861    memmove(mBuffer->data(),
862            mBuffer->data() + frameSize,
863            mBuffer->size() - frameSize);
864
865    mBuffer->setRange(0, mBuffer->size() - frameSize);
866
867    int64_t timeUs = fetchTimestamp(frameSize);
868    CHECK_GE(timeUs, 0ll);
869
870    accessUnit->meta()->setInt64("timeUs", timeUs);
871
872    if (mFormat == NULL) {
873        mFormat = new MetaData;
874
875        switch (layer) {
876            case 1:
877                mFormat->setCString(
878                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
879                break;
880            case 2:
881                mFormat->setCString(
882                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
883                break;
884            case 3:
885                mFormat->setCString(
886                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
887                break;
888            default:
889                TRESPASS();
890        }
891
892        mFormat->setInt32(kKeySampleRate, samplingRate);
893        mFormat->setInt32(kKeyChannelCount, numChannels);
894    }
895
896    return accessUnit;
897}
898
899static void EncodeSize14(uint8_t **_ptr, size_t size) {
900    CHECK_LE(size, 0x3fff);
901
902    uint8_t *ptr = *_ptr;
903
904    *ptr++ = 0x80 | (size >> 7);
905    *ptr++ = size & 0x7f;
906
907    *_ptr = ptr;
908}
909
910static sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) {
911    sp<ABuffer> esds = new ABuffer(csd->size() + 25);
912
913    uint8_t *ptr = esds->data();
914    *ptr++ = 0x03;
915    EncodeSize14(&ptr, 22 + csd->size());
916
917    *ptr++ = 0x00;  // ES_ID
918    *ptr++ = 0x00;
919
920    *ptr++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
921
922    *ptr++ = 0x04;
923    EncodeSize14(&ptr, 16 + csd->size());
924
925    *ptr++ = 0x40;  // Audio ISO/IEC 14496-3
926
927    for (size_t i = 0; i < 12; ++i) {
928        *ptr++ = 0x00;
929    }
930
931    *ptr++ = 0x05;
932    EncodeSize14(&ptr, csd->size());
933
934    memcpy(ptr, csd->data(), csd->size());
935
936    return esds;
937}
938
939sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
940    const uint8_t *data = mBuffer->data();
941    size_t size = mBuffer->size();
942
943    bool sawPictureStart = false;
944    int pprevStartCode = -1;
945    int prevStartCode = -1;
946    int currentStartCode = -1;
947
948    size_t offset = 0;
949    while (offset + 3 < size) {
950        if (memcmp(&data[offset], "\x00\x00\x01", 3)) {
951            ++offset;
952            continue;
953        }
954
955        pprevStartCode = prevStartCode;
956        prevStartCode = currentStartCode;
957        currentStartCode = data[offset + 3];
958
959        if (currentStartCode == 0xb3 && mFormat == NULL) {
960            memmove(mBuffer->data(), mBuffer->data() + offset, size - offset);
961            size -= offset;
962            (void)fetchTimestamp(offset);
963            offset = 0;
964            mBuffer->setRange(0, size);
965        }
966
967        if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
968                || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
969            // seqHeader without/with extension
970
971            if (mFormat == NULL) {
972                CHECK_GE(size, 7u);
973
974                unsigned width =
975                    (data[4] << 4) | data[5] >> 4;
976
977                unsigned height =
978                    ((data[5] & 0x0f) << 8) | data[6];
979
980                mFormat = new MetaData;
981                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
982                mFormat->setInt32(kKeyWidth, width);
983                mFormat->setInt32(kKeyHeight, height);
984
985                ALOGI("found MPEG2 video codec config (%d x %d)", width, height);
986
987                sp<ABuffer> csd = new ABuffer(offset);
988                memcpy(csd->data(), data, offset);
989
990                memmove(mBuffer->data(),
991                        mBuffer->data() + offset,
992                        mBuffer->size() - offset);
993
994                mBuffer->setRange(0, mBuffer->size() - offset);
995                size -= offset;
996                (void)fetchTimestamp(offset);
997                offset = 0;
998
999                // hexdump(csd->data(), csd->size());
1000
1001                sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
1002                mFormat->setData(
1003                        kKeyESDS, kTypeESDS, esds->data(), esds->size());
1004
1005                return NULL;
1006            }
1007        }
1008
1009        if (mFormat != NULL && currentStartCode == 0x00) {
1010            // Picture start
1011
1012            if (!sawPictureStart) {
1013                sawPictureStart = true;
1014            } else {
1015                sp<ABuffer> accessUnit = new ABuffer(offset);
1016                memcpy(accessUnit->data(), data, offset);
1017
1018                memmove(mBuffer->data(),
1019                        mBuffer->data() + offset,
1020                        mBuffer->size() - offset);
1021
1022                mBuffer->setRange(0, mBuffer->size() - offset);
1023
1024                int64_t timeUs = fetchTimestamp(offset);
1025                CHECK_GE(timeUs, 0ll);
1026
1027                offset = 0;
1028
1029                accessUnit->meta()->setInt64("timeUs", timeUs);
1030
1031                ALOGV("returning MPEG video access unit at time %" PRId64 " us",
1032                      timeUs);
1033
1034                // hexdump(accessUnit->data(), accessUnit->size());
1035
1036                return accessUnit;
1037            }
1038        }
1039
1040        ++offset;
1041    }
1042
1043    return NULL;
1044}
1045
1046static ssize_t getNextChunkSize(
1047        const uint8_t *data, size_t size) {
1048    static const char kStartCode[] = "\x00\x00\x01";
1049
1050    if (size < 3) {
1051        return -EAGAIN;
1052    }
1053
1054    if (memcmp(kStartCode, data, 3)) {
1055        TRESPASS();
1056    }
1057
1058    size_t offset = 3;
1059    while (offset + 2 < size) {
1060        if (!memcmp(&data[offset], kStartCode, 3)) {
1061            return offset;
1062        }
1063
1064        ++offset;
1065    }
1066
1067    return -EAGAIN;
1068}
1069
1070sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
1071    uint8_t *data = mBuffer->data();
1072    size_t size = mBuffer->size();
1073
1074    enum {
1075        SKIP_TO_VISUAL_OBJECT_SEQ_START,
1076        EXPECT_VISUAL_OBJECT_START,
1077        EXPECT_VO_START,
1078        EXPECT_VOL_START,
1079        WAIT_FOR_VOP_START,
1080        SKIP_TO_VOP_START,
1081
1082    } state;
1083
1084    if (mFormat == NULL) {
1085        state = SKIP_TO_VISUAL_OBJECT_SEQ_START;
1086    } else {
1087        state = SKIP_TO_VOP_START;
1088    }
1089
1090    int32_t width = -1, height = -1;
1091
1092    size_t offset = 0;
1093    ssize_t chunkSize;
1094    while ((chunkSize = getNextChunkSize(
1095                    &data[offset], size - offset)) > 0) {
1096        bool discard = false;
1097
1098        unsigned chunkType = data[offset + 3];
1099
1100        switch (state) {
1101            case SKIP_TO_VISUAL_OBJECT_SEQ_START:
1102            {
1103                if (chunkType == 0xb0) {
1104                    // Discard anything before this marker.
1105
1106                    state = EXPECT_VISUAL_OBJECT_START;
1107                } else {
1108                    discard = true;
1109                }
1110                break;
1111            }
1112
1113            case EXPECT_VISUAL_OBJECT_START:
1114            {
1115                CHECK_EQ(chunkType, 0xb5);
1116                state = EXPECT_VO_START;
1117                break;
1118            }
1119
1120            case EXPECT_VO_START:
1121            {
1122                CHECK_LE(chunkType, 0x1f);
1123                state = EXPECT_VOL_START;
1124                break;
1125            }
1126
1127            case EXPECT_VOL_START:
1128            {
1129                CHECK((chunkType & 0xf0) == 0x20);
1130
1131                CHECK(ExtractDimensionsFromVOLHeader(
1132                            &data[offset], chunkSize,
1133                            &width, &height));
1134
1135                state = WAIT_FOR_VOP_START;
1136                break;
1137            }
1138
1139            case WAIT_FOR_VOP_START:
1140            {
1141                if (chunkType == 0xb3 || chunkType == 0xb6) {
1142                    // group of VOP or VOP start.
1143
1144                    mFormat = new MetaData;
1145                    mFormat->setCString(
1146                            kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
1147
1148                    mFormat->setInt32(kKeyWidth, width);
1149                    mFormat->setInt32(kKeyHeight, height);
1150
1151                    ALOGI("found MPEG4 video codec config (%d x %d)",
1152                         width, height);
1153
1154                    sp<ABuffer> csd = new ABuffer(offset);
1155                    memcpy(csd->data(), data, offset);
1156
1157                    // hexdump(csd->data(), csd->size());
1158
1159                    sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
1160                    mFormat->setData(
1161                            kKeyESDS, kTypeESDS,
1162                            esds->data(), esds->size());
1163
1164                    discard = true;
1165                    state = SKIP_TO_VOP_START;
1166                }
1167
1168                break;
1169            }
1170
1171            case SKIP_TO_VOP_START:
1172            {
1173                if (chunkType == 0xb6) {
1174                    offset += chunkSize;
1175
1176                    sp<ABuffer> accessUnit = new ABuffer(offset);
1177                    memcpy(accessUnit->data(), data, offset);
1178
1179                    memmove(data, &data[offset], size - offset);
1180                    size -= offset;
1181                    mBuffer->setRange(0, size);
1182
1183                    int64_t timeUs = fetchTimestamp(offset);
1184                    CHECK_GE(timeUs, 0ll);
1185
1186                    offset = 0;
1187
1188                    accessUnit->meta()->setInt64("timeUs", timeUs);
1189
1190                    ALOGV("returning MPEG4 video access unit at time %" PRId64 " us",
1191                         timeUs);
1192
1193                    // hexdump(accessUnit->data(), accessUnit->size());
1194
1195                    return accessUnit;
1196                } else if (chunkType != 0xb3) {
1197                    offset += chunkSize;
1198                    discard = true;
1199                }
1200
1201                break;
1202            }
1203
1204            default:
1205                TRESPASS();
1206        }
1207
1208        if (discard) {
1209            (void)fetchTimestamp(offset);
1210            memmove(data, &data[offset], size - offset);
1211            size -= offset;
1212            offset = 0;
1213            mBuffer->setRange(0, size);
1214        } else {
1215            offset += chunkSize;
1216        }
1217    }
1218
1219    return NULL;
1220}
1221
1222}  // namespace android
1223