16a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber/*
26a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * Copyright (C) 2010 The Android Open Source Project
36a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber *
46a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
56a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * you may not use this file except in compliance with the License.
66a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * You may obtain a copy of the License at
76a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber *
86a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
96a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber *
106a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * Unless required by applicable law or agreed to in writing, software
116a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
126a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * See the License for the specific language governing permissions and
146a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber * limitations under the License.
156a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber */
166a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
176a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber//#define LOG_NDEBUG 0
186a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#define LOG_TAG "ESQueue"
196a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/foundation/ADebug.h>
206a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
216a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include "ESQueue.h"
226a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
236a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/foundation/hexdump.h>
246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
256a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
266a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/foundation/AMessage.h>
27607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h>
28d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/stagefright/foundation/avc_utils.h>
296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MediaErrors.h>
306a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MediaDefs.h>
316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MetaData.h>
327dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/MetaDataUtils.h>
333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include <media/cas/DescramblerAPI.h>
343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include <media/hardware/CryptoAPI.h>
356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
36b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h>
3790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <netinet/in.h>
3890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
396a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubernamespace android {
406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
41f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas HuberElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
42f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber    : mMode(mode),
43be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen      mFlags(flags),
44bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang      mEOSReached(false),
453a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania      mCASystemId(0),
463a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania      mAUIndex(0) {
473a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
483a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("ElementaryStreamQueue(%p) mode %x  flags %x  isScrambled %d  isSampleEncrypted %d",
493a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            this, mode, flags, isScrambled(), isSampleEncrypted());
503a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
513a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // Create the decryptor anyway since we don't know the use-case unless key is provided
523a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // Won't decrypt if key info not available (e.g., scanner/extractor just parsing ts files)
533a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleDecryptor = isSampleEncrypted() ? new HlsSampleDecryptor : NULL;
546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
566a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<MetaData> ElementaryStreamQueue::getFormat() {
576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return mFormat;
586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ElementaryStreamQueue::clear(bool clearFormat) {
61e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber    if (mBuffer != NULL) {
62e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber        mBuffer->setRange(0, 0);
63e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber    }
64e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber
65a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    mRangeInfos.clear();
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambledBuffer != NULL) {
683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mScrambledBuffer->setRange(0, 0);
693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mScrambledRangeInfos.clear();
713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (clearFormat) {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFormat.clear();
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
75aabbdc7401ae24a4199f12a283985deb648673c0Robert Shih
76aabbdc7401ae24a4199f12a283985deb648673c0Robert Shih    mEOSReached = false;
772a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
782a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
79bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhangbool ElementaryStreamQueue::isScrambled() const {
80bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang    return (mFlags & kFlag_ScrambledData) != 0;
81bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang}
82bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang
83bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhangvoid ElementaryStreamQueue::setCasInfo(
84bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        int32_t systemId, const std::vector<uint8_t> &sessionId) {
85bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang    mCASystemId = systemId;
86bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang    mCasSessionId = sessionId;
87bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang}
88bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang
89dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu// Parse AC3 header assuming the current ptr is start position of syncframe,
90dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu// update metadata only applicable, and return the payload size
91dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryustatic unsigned parseAC3SyncFrame(
92dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        const uint8_t *ptr, size_t size, sp<MetaData> *metaData) {
930105027f2a385ecb29a64b055f3046fb01ca2803Dongwon Kang    static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
94dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    static const unsigned samplingRateTable[] = {48000, 44100, 32000};
95dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
96dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    static const unsigned frameSizeTable[19][3] = {
97dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 64, 69, 96 },
98dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 80, 87, 120 },
99dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 96, 104, 144 },
100dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 112, 121, 168 },
101dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 128, 139, 192 },
102dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 160, 174, 240 },
103dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 192, 208, 288 },
104dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 224, 243, 336 },
105dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 256, 278, 384 },
106dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 320, 348, 480 },
107dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 384, 417, 576 },
108dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 448, 487, 672 },
109dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 512, 557, 768 },
110dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 640, 696, 960 },
111dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 768, 835, 1152 },
112dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 896, 975, 1344 },
113dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 1024, 1114, 1536 },
114dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 1152, 1253, 1728 },
115dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        { 1280, 1393, 1920 },
116dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    };
117dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
118dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    ABitReader bits(ptr, size);
119dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (bits.numBitsLeft() < 16) {
120dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
121dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
122dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (bits.getBits(16) != 0x0B77) {
123dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
124dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
125dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
126dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (bits.numBitsLeft() < 16 + 2 + 6 + 5 + 3 + 3) {
127dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ALOGV("Not enough bits left for further parsing");
128dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
129dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
130dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    bits.skipBits(16);  // crc1
131dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
132dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned fscod = bits.getBits(2);
133dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (fscod == 3) {
134dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ALOGW("Incorrect fscod in AC3 header");
135dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
136dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
137dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
138dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned frmsizecod = bits.getBits(6);
139dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (frmsizecod > 37) {
140dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ALOGW("Incorrect frmsizecod in AC3 header");
141dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
142dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
143dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
144dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned bsid = bits.getBits(5);
145dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (bsid > 8) {
146dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
147dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
148dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
149dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
150b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    unsigned bsmod __unused = bits.getBits(3);
151dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned acmod = bits.getBits(3);
152b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    unsigned cmixlev __unused = 0;
153b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    unsigned surmixlev __unused = 0;
154b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    unsigned dsurmod __unused = 0;
155dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
156dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if ((acmod & 1) > 0 && acmod != 1) {
157dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        if (bits.numBitsLeft() < 2) {
158dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            return 0;
159dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        }
160dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        cmixlev = bits.getBits(2);
161dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
162dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if ((acmod & 4) > 0) {
163dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        if (bits.numBitsLeft() < 2) {
164dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            return 0;
165dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        }
166dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        surmixlev = bits.getBits(2);
167dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
168dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (acmod == 2) {
169dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        if (bits.numBitsLeft() < 2) {
170dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            return 0;
171dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        }
172dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        dsurmod = bits.getBits(2);
173dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
174dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
175dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (bits.numBitsLeft() < 1) {
176dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return 0;
177dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
178dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned lfeon = bits.getBits(1);
179dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
180dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned samplingRate = samplingRateTable[fscod];
181dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned payloadSize = frameSizeTable[frmsizecod >> 1][fscod];
182dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (fscod == 1) {
183dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        payloadSize += frmsizecod & 1;
184dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
185dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    payloadSize <<= 1;  // convert from 16-bit words to bytes
186dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
187dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned channelCount = channelCountTable[acmod] + lfeon;
188dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
189dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (metaData != NULL) {
190dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
191dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        (*metaData)->setInt32(kKeyChannelCount, channelCount);
192dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        (*metaData)->setInt32(kKeySampleRate, samplingRate);
193dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
194dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
195dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    return payloadSize;
196dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu}
197dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
198dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryustatic bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) {
199dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    return parseAC3SyncFrame(ptr, size, NULL) > 0;
200dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu}
201dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
2024d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jiastatic bool IsSeeminglyValidADTSHeader(
2034d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia        const uint8_t *ptr, size_t size, size_t *frameLength) {
2044d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia    if (size < 7) {
205a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        // Not enough data to verify header.
206a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
207a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
208a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
209a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
210a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
211a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
212a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
213a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned layer = (ptr[1] >> 1) & 3;
214a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
215a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (layer != 0) {
216a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
217a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
218a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
219a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned ID = (ptr[1] >> 3) & 1;
220a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned profile_ObjectType = ptr[2] >> 6;
221a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
222a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (ID == 1 && profile_ObjectType == 3) {
223a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        // MPEG-2 profile 3 is reserved.
224a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
225a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
226a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
2274d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia    size_t frameLengthInHeader =
2284d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia            ((ptr[3] & 3) << 11) + (ptr[4] << 3) + ((ptr[5] >> 5) & 7);
2294d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia    if (frameLengthInHeader > size) {
2304d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia        return false;
2314d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia    }
2324d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia
2334d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia    *frameLength = frameLengthInHeader;
234a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return true;
235a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
236a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
237386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
238386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < 3) {
239386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        // Not enough data to verify header.
240386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;
241386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
242386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
243386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) {
244386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;
245386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
246386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
247386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned ID = (ptr[1] >> 3) & 3;
248386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
249386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (ID == 1) {
250386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
251386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
252386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
253386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned layer = (ptr[1] >> 1) & 3;
254386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
255386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (layer == 0) {
256386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
257386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
258386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
259386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned bitrateIndex = (ptr[2] >> 4);
260386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
261386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (bitrateIndex == 0x0f) {
262386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
263386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
264386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
265386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned samplingRateIndex = (ptr[2] >> 2) & 3;
266386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
267386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (samplingRateIndex == 3) {
268386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
269386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
270386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
271386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return true;
272386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
273386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
2746a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberstatus_t ElementaryStreamQueue::appendData(
2753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const void *data, size_t size, int64_t timeUs,
2763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t payloadOffset, uint32_t pesScramblingControl) {
277be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen
278be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    if (mEOSReached) {
279be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        ALOGE("appending data after EOS");
280be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        return ERROR_MALFORMED;
281be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    }
2826a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    if (mBuffer == NULL || mBuffer->size() == 0) {
2836a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        switch (mMode) {
2846a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            case H264:
285386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG_VIDEO:
2866a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            {
287decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#if 0
2886a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
2896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    return ERROR_MALFORMED;
2906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
291decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#else
292decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                uint8_t *ptr = (uint8_t *)data;
293decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
294decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                ssize_t startOffset = -1;
29513561c89d6d8f6980625192bd75f9fd6cfb102a3Robert Shih                for (size_t i = 0; i + 2 < size; ++i) {
29613561c89d6d8f6980625192bd75f9fd6cfb102a3Robert Shih                    if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
297decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        startOffset = i;
298decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        break;
299decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    }
300decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
301decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
302decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset < 0) {
303decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    return ERROR_MALFORMED;
304decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
305decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
3063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                if (mFormat == NULL && startOffset > 0) {
307a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                    ALOGI("found something resembling an H.264/MPEG syncword "
308b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                          "at offset %zd",
309a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                          startOffset);
310386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
311386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
312386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                data = &ptr[startOffset];
313386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= startOffset;
314386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#endif
315386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
316386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
317386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
318386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG4_VIDEO:
319386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
320386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#if 0
321386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (size < 3 || memcmp("\x00\x00\x01", data, 3)) {
322386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
323386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
324386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#else
325386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                uint8_t *ptr = (uint8_t *)data;
326386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
327386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                ssize_t startOffset = -1;
328386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                for (size_t i = 0; i + 2 < size; ++i) {
329386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
330386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        startOffset = i;
331386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        break;
332386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    }
333386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
334386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
335386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset < 0) {
336386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
337386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
338386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
339386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset > 0) {
340a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                    ALOGI("found something resembling an H.264/MPEG syncword "
341b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                          "at offset %zd",
342a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                          startOffset);
343decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
344decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
345decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                data = &ptr[startOffset];
346decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                size -= startOffset;
347decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#endif
3486a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                break;
3496a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
3506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
3516a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            case AAC:
3526a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            {
3536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                uint8_t *ptr = (uint8_t *)data;
3546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
355decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#if 0
3566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (size < 2 || ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
3576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    return ERROR_MALFORMED;
3586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
359decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#else
360decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                ssize_t startOffset = -1;
3614d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                size_t frameLength;
362a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                for (size_t i = 0; i < size; ++i) {
3634d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                    if (IsSeeminglyValidADTSHeader(
3644d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                            &ptr[i], size - i, &frameLength)) {
365decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        startOffset = i;
366decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        break;
367decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    }
368decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
369decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
370decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset < 0) {
371decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    return ERROR_MALFORMED;
372decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
373decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
374decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset > 0) {
375a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                    ALOGI("found something resembling an AAC syncword at "
376b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                          "offset %zd",
377a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                          startOffset);
378decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
379decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
3804d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                if (frameLength != size - startOffset) {
381f247eef54c58ee1b7c13a3f6888b6374e9bea66fWei Jia                    ALOGV("First ADTS AAC frame length is %zd bytes, "
38215ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia                          "while the buffer size is %zd bytes.",
3834d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                          frameLength, size - startOffset);
3844d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia                }
3854d23645c8d3d93c91967a5494473b4a8b5d10d9cWei Jia
386decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                data = &ptr[startOffset];
38715ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia                size -= startOffset;
388decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#endif
3896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                break;
3906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
3916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
392dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            case AC3:
393dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            {
394dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                uint8_t *ptr = (uint8_t *)data;
395dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
396dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                ssize_t startOffset = -1;
397dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                for (size_t i = 0; i < size; ++i) {
398dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                    if (IsSeeminglyValidAC3Header(&ptr[i], size - i)) {
399dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                        startOffset = i;
400dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                        break;
401dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                    }
402dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                }
403dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
404dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                if (startOffset < 0) {
405dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                    return ERROR_MALFORMED;
406dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                }
407dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
408dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                if (startOffset > 0) {
409dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                    ALOGI("found something resembling an AC3 syncword at "
410b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                          "offset %zd",
411dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                          startOffset);
412dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                }
413dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
414dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                data = &ptr[startOffset];
415dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                size -= startOffset;
416dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                break;
417dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            }
418dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
419386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG_AUDIO:
420386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
421386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                uint8_t *ptr = (uint8_t *)data;
422386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
423386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                ssize_t startOffset = -1;
424386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                for (size_t i = 0; i < size; ++i) {
425386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) {
426386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        startOffset = i;
427386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        break;
428386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    }
429386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
430386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
431386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset < 0) {
432386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
433386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
434386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
435386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset > 0) {
436df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                    ALOGI("found something resembling an MPEG audio "
437b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                          "syncword at offset %zd",
438a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber                          startOffset);
439386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
440386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
441386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                data = &ptr[startOffset];
442386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= startOffset;
443386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
444386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
445386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
44690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case PCM_AUDIO:
4470852843d304006e3ab333081fddda13b07193de8Robert Shih            case METADATA:
44890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            {
44990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
45090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
45190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
4526a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            default:
453e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("Unknown mode: %d", mMode);
454e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
4556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
4566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
4576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t neededSize = (mBuffer == NULL ? 0 : mBuffer->size()) + size;
4596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
4606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        neededSize = (neededSize + 65535) & ~65535;
4616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
462b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        ALOGV("resizing buffer to size %zu", neededSize);
4636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4646a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        sp<ABuffer> buffer = new ABuffer(neededSize);
4656a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mBuffer != NULL) {
4666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            memcpy(buffer->data(), mBuffer->data(), mBuffer->size());
4676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            buffer->setRange(0, mBuffer->size());
4686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else {
4696a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            buffer->setRange(0, 0);
4706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
4716a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4726a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        mBuffer = buffer;
4736a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
4746a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    memcpy(mBuffer->data() + mBuffer->size(), data, size);
4766a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    mBuffer->setRange(0, mBuffer->size() + size);
4776a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
478a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    RangeInfo info;
479a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    info.mLength = size;
480a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    info.mTimestampUs = timeUs;
4813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    info.mPesOffset = payloadOffset;
4823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    info.mPesScramblingControl = pesScramblingControl;
483a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    mRangeInfos.push_back(info);
484a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
485a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber#if 0
486a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    if (mMode == AAC) {
487b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        ALOGI("size = %zu, timeUs = %.2f secs", size, timeUs / 1E6);
488a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        hexdump(data, size);
489a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    }
490a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber#endif
4916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return OK;
4936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
4946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangvoid ElementaryStreamQueue::appendScrambledData(
4963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const void *data, size_t size,
4973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t keyId, bool isSync,
4983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> clearSizes, sp<ABuffer> encSizes) {
4993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (!isScrambled()) {
5003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return;
5013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    size_t neededSize = (mScrambledBuffer == NULL ? 0 : mScrambledBuffer->size()) + size;
5043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambledBuffer == NULL || neededSize > mScrambledBuffer->capacity()) {
5053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + 65535) & ~65535;
5063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGI("resizing scrambled buffer to size %zu", neededSize);
5083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> buffer = new ABuffer(neededSize);
5103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mScrambledBuffer != NULL) {
5113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            memcpy(buffer->data(), mScrambledBuffer->data(), mScrambledBuffer->size());
5123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            buffer->setRange(0, mScrambledBuffer->size());
5133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
5143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            buffer->setRange(0, 0);
5153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
5163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mScrambledBuffer = buffer;
5183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    memcpy(mScrambledBuffer->data() + mScrambledBuffer->size(), data, size);
5203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mScrambledBuffer->setRange(0, mScrambledBuffer->size() + size);
5213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ScrambledRangeInfo scrambledInfo;
5233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledInfo.mLength = size;
5243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledInfo.mKeyId = keyId;
5253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledInfo.mIsSync = isSync;
5263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledInfo.mClearSizes = clearSizes;
5273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledInfo.mEncSizes = encSizes;
5283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("[stream %d] appending scrambled range: size=%zu", mMode, size);
5303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mScrambledRangeInfos.push_back(scrambledInfo);
5323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
5333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangsp<ABuffer> ElementaryStreamQueue::dequeueScrambledAccessUnit() {
5353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    size_t nextScan = mBuffer->size();
5363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mBuffer->setRange(0, 0);
5373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t pesOffset = 0, pesScramblingControl = 0;
5383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int64_t timeUs = fetchTimestamp(nextScan, &pesOffset, &pesScramblingControl);
5393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (timeUs < 0ll) {
5403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("Negative timeUs");
5413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return NULL;
5423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // return scrambled unit
5453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t keyId = pesScramblingControl, isSync = 0, scrambledLength = 0;
5463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> clearSizes, encSizes;
5473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    while (mScrambledRangeInfos.size() > mRangeInfos.size()) {
5483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        auto it = mScrambledRangeInfos.begin();
5493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("[stream %d] fetching scrambled range: size=%zu", mMode, it->mLength);
5503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (scrambledLength > 0) {
5523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // This shouldn't happen since we always dequeue the entire PES.
5533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGW("Discarding srambled length %d", scrambledLength);
5543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
5553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        scrambledLength = it->mLength;
5563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // TODO: handle key id change, use first non-zero keyId for now
5583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (keyId == 0) {
5593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            keyId = it->mKeyId;
5603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
5613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        clearSizes = it->mClearSizes;
5623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        encSizes = it->mEncSizes;
5633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        isSync = it->mIsSync;
5643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mScrambledRangeInfos.erase(it);
5653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (scrambledLength == 0) {
5673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("[stream %d] empty scrambled unit!", mMode);
5683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return NULL;
5693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // skip the PES header, and copy the rest into scrambled access unit
5723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> scrambledAccessUnit = ABuffer::CreateAsCopy(
5733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mScrambledBuffer->data() + pesOffset,
5743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            scrambledLength - pesOffset);
5753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // fix up first sample size after skipping the PES header
5773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (pesOffset > 0) {
5783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t &firstClearSize = *(int32_t*)clearSizes->data();
5793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t &firstEncSize = *(int32_t*)encSizes->data();
5803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Cut away the PES header
5813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (firstClearSize >= pesOffset) {
5823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // This is for TS-level scrambling, we descrambled the first
5833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // (or it was clear to begin with)
5843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            firstClearSize -= pesOffset;
5853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else if (firstEncSize >= pesOffset) {
5863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // This can only be PES-level scrambling
5873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            firstEncSize -= pesOffset;
5883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
5893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledAccessUnit->meta()->setInt64("timeUs", timeUs);
5923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (isSync) {
5933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        scrambledAccessUnit->meta()->setInt32("isSync", 1);
5943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
5953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
5963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // fill in CryptoInfo fields for AnotherPacketSource::read()
5973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // MediaCas doesn't use cryptoMode, but set to non-zero value here.
5983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledAccessUnit->meta()->setInt32(
599b01fb48fcc755d6bfad9bc94d8c227349155e1b5Chong Zhang            "cryptoMode", CryptoPlugin::kMode_AES_CTR);
6003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledAccessUnit->meta()->setInt32("cryptoKey", keyId);
6013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledAccessUnit->meta()->setBuffer("clearBytes", clearSizes);
6023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    scrambledAccessUnit->meta()->setBuffer("encBytes", encSizes);
6033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
6043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    memmove(mScrambledBuffer->data(),
6053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mScrambledBuffer->data() + scrambledLength,
6063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mScrambledBuffer->size() - scrambledLength);
6073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
6083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mScrambledBuffer->setRange(0, mScrambledBuffer->size() - scrambledLength);
6093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
6103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("[stream %d] dequeued scrambled AU: timeUs=%lld, size=%zu",
6113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mMode, (long long)timeUs, scrambledAccessUnit->size());
6123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
6133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return scrambledAccessUnit;
6143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
6153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
6166a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
6173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if ((mFlags & kFlag_AlignedData) && mMode == H264 && !isScrambled()) {
618f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        if (mRangeInfos.empty()) {
619f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber            return NULL;
620f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        }
621f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
622f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        RangeInfo info = *mRangeInfos.begin();
623f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        mRangeInfos.erase(mRangeInfos.begin());
624f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
625f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        sp<ABuffer> accessUnit = new ABuffer(info.mLength);
626f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        memcpy(accessUnit->data(), mBuffer->data(), info.mLength);
627f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        accessUnit->meta()->setInt64("timeUs", info.mTimestampUs);
628f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
629f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        memmove(mBuffer->data(),
630f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber                mBuffer->data() + info.mLength,
631f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber                mBuffer->size() - info.mLength);
632f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
633f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        mBuffer->setRange(0, mBuffer->size() - info.mLength);
634f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
635f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        if (mFormat == NULL) {
6363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            mFormat = new MetaData;
637a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen            if (!MakeAVCCodecSpecificData(*mFormat, accessUnit->data(), accessUnit->size())) {
6383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                mFormat.clear();
6393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
640f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        }
641f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
642f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber        return accessUnit;
643f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber    }
644f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber
645386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (mMode) {
646386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case H264:
647386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitH264();
648386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case AAC:
649386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitAAC();
650dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        case AC3:
651dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            return dequeueAccessUnitAC3();
652386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case MPEG_VIDEO:
653386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEGVideo();
654386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case MPEG4_VIDEO:
655386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEG4Video();
65690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case PCM_AUDIO:
65790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return dequeueAccessUnitPCMAudio();
6580852843d304006e3ab333081fddda13b07193de8Robert Shih        case METADATA:
6590852843d304006e3ab333081fddda13b07193de8Robert Shih            return dequeueAccessUnitMetadata();
660386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
661e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (mMode != MPEG_AUDIO) {
662e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("Unknown mode");
663e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
664e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
665386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEGAudio();
6666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
6676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
6686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
669dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryusp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() {
670dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned syncStartPos = 0;  // in bytes
671dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    unsigned payloadSize = 0;
672dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    sp<MetaData> format = new MetaData;
6733a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
6743a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("dequeueAccessUnit_AC3[%d]: mBuffer %p(%zu)", mAUIndex, mBuffer->data(), mBuffer->size());
6753a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
676dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    while (true) {
677dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        if (syncStartPos + 2 >= mBuffer->size()) {
678dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            return NULL;
679dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        }
680dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
681dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        payloadSize = parseAC3SyncFrame(
682dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                mBuffer->data() + syncStartPos,
683dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                mBuffer->size() - syncStartPos,
684dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu                &format);
685dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        if (payloadSize > 0) {
686dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            break;
687dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        }
6883a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
6893a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        ALOGV("dequeueAccessUnit_AC3[%d]: syncStartPos %u payloadSize %u",
6903a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                mAUIndex, syncStartPos, payloadSize);
6913a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
692dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ++syncStartPos;
693dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
694dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
695dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (mBuffer->size() < syncStartPos + payloadSize) {
696dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        ALOGV("Not enough buffer size for AC3");
697dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        return NULL;
698dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
699dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
700dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    if (mFormat == NULL) {
701dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        mFormat = format;
702dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    }
703dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
704dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
705dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
706e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (timeUs < 0ll) {
707e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("negative timeUs");
708e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
709e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
7103a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7113a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // Not decrypting if key info not available (e.g., scanner/extractor parsing ts files)
7123a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    if (mSampleDecryptor != NULL) {
7133a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        mSampleDecryptor->processAC3(mBuffer->data() + syncStartPos, payloadSize);
7143a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
7153a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mAUIndex++;
7163a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7173a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
7183a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
7193a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
720dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    accessUnit->meta()->setInt64("timeUs", timeUs);
72137746afe186ce04f0f6252900b79726040d89a0dTerry Heo    accessUnit->meta()->setInt32("isSync", 1);
722dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
723dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    memmove(
724dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            mBuffer->data(),
725dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            mBuffer->data() + syncStartPos + payloadSize,
726dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu            mBuffer->size() - syncStartPos - payloadSize);
727dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
728dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
729dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
730dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu    return accessUnit;
731dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu}
732dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
73390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
73490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mBuffer->size() < 4) {
73590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return NULL;
73690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
73790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
73890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ABitReader bits(mBuffer->data(), 4);
739e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (bits.getBits(8) != 0xa0) {
740e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Unexpected bit values");
741e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
742e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
74390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    unsigned numAUs = bits.getBits(8);
74490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bits.skipBits(8);
745b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe    unsigned quantization_word_length __unused = bits.getBits(2);
74690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    unsigned audio_sampling_frequency = bits.getBits(3);
74790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    unsigned num_channels = bits.getBits(3);
74890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
749e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (audio_sampling_frequency != 2) {
750e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong sampling freq");
751e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
752e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
753e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (num_channels != 1u) {
754e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong channel #");
755e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
756e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
75790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
75890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mFormat == NULL) {
75990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFormat = new MetaData;
76090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
76190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFormat->setInt32(kKeyChannelCount, 2);
76290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFormat->setInt32(kKeySampleRate, 48000);
76378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        mFormat->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
76490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
76590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
76690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    static const size_t kFramesPerAU = 80;
76790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t frameSize = 2 /* numChannels */ * sizeof(int16_t);
76890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
76990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t payloadSize = numAUs * frameSize * kFramesPerAU;
77090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
77190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mBuffer->size() < 4 + payloadSize) {
77290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return NULL;
77390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
77490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
77590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(payloadSize);
77690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
77790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
77890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t timeUs = fetchTimestamp(payloadSize + 4);
779e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (timeUs < 0ll) {
780e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Negative timeUs");
781e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
782e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
78390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
78437746afe186ce04f0f6252900b79726040d89a0dTerry Heo    accessUnit->meta()->setInt32("isSync", 1);
78590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
78690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int16_t *ptr = (int16_t *)accessUnit->data();
78790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) {
78890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ptr[i] = ntohs(ptr[i]);
78990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
79090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    memmove(
79290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mBuffer->data(),
79390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mBuffer->data() + 4 + payloadSize,
79490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mBuffer->size() - 4 - payloadSize);
79590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize);
79790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return accessUnit;
79990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
80090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
8016a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
802a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    if (mBuffer->size() == 0) {
803a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber        return NULL;
804a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    }
805a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber
806e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (mRangeInfos.empty()) {
807e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
808e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
8096a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
810a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    const RangeInfo &info = *mRangeInfos.begin();
811a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    if (mBuffer->size() < info.mLength) {
812a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber        return NULL;
813a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    }
814a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber
815e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (info.mTimestampUs < 0ll) {
816e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Negative info.mTimestampUs");
817e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
818e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
819a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber
8203a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("dequeueAccessUnit_AAC[%d]: mBuffer %zu info.mLength %zu",
8213a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mAUIndex, mBuffer->size(), info.mLength);
8223a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
8233a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    struct ADTSPosition {
8243a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        size_t offset;
8253a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        size_t headerSize;
8263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        size_t length;
8273a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    };
8283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
8293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    Vector<ADTSPosition> frames;
8303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
831a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    // The idea here is consume all AAC frames starting at offsets before
832a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    // info.mLength so we can assign a meaningful timestamp without
833a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    // having to interpolate.
834a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    // The final AAC frame may well extend into the next RangeInfo but
835a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    // that's ok.
8366a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t offset = 0;
837a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    while (offset < info.mLength) {
838a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber        if (offset + 7 > mBuffer->size()) {
839a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber            return NULL;
840a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber        }
841a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber
8426a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        ABitReader bits(mBuffer->data() + offset, mBuffer->size() - offset);
8436a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
8446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // adts_fixed_header
8456a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
846e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (bits.getBits(12) != 0xfffu) {
847e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("Wrong atds_fixed_header");
848e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return NULL;
849e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
8506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(3);  // ID, layer
8513a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        bool protection_absent = bits.getBits(1) != 0;
8526a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
8536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mFormat == NULL) {
8546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned profile = bits.getBits(2);
855e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (profile == 3u) {
856e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("profile should not be 3");
857e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
858e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
8596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned sampling_freq_index = bits.getBits(4);
8606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.getBits(1);  // private_bit
8616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned channel_configuration = bits.getBits(3);
862e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (channel_configuration == 0u) {
863e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("channel_config should not be 0");
864e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
865e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
8666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.skipBits(2);  // original_copy, home
8676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
868b25c03c27d58820ba0b87d3d4e86e4b92047e2c3Dongwon Kang            mFormat = new MetaData;
8693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            MakeAACCodecSpecificData(*mFormat,
8706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    profile, sampling_freq_index, channel_configuration);
8715bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
87256ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber            mFormat->setInt32(kKeyIsADTS, true);
87356ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber
8745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            int32_t sampleRate;
8755bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            int32_t numChannels;
876e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (!mFormat->findInt32(kKeySampleRate, &sampleRate)) {
877e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("SampleRate not found");
878e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
879e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
880e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (!mFormat->findInt32(kKeyChannelCount, &numChannels)) {
881e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("ChannelCount not found");
882e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
883e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
8845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
885df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("found AAC codec config (%d Hz, %d channels)",
8865bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                 sampleRate, numChannels);
8876a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else {
8886a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // profile_ObjectType, sampling_frequency_index, private_bits,
8896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // channel_configuration, original_copy, home
8906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.skipBits(12);
8916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
8926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
8936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // adts_variable_header
8946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
8956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // copyright_identification_bit, copyright_identification_start
8966a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(2);
8976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
8986a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned aac_frame_length = bits.getBits(13);
8996e2bcf40e4083be3a0fbb13d03293a78301e66efChong Zhang        if (aac_frame_length == 0){
9006e2bcf40e4083be3a0fbb13d03293a78301e66efChong Zhang            ALOGE("b/62673179, Invalid AAC frame length!");
9016e2bcf40e4083be3a0fbb13d03293a78301e66efChong Zhang            android_errorWriteLog(0x534e4554, "62673179");
9026e2bcf40e4083be3a0fbb13d03293a78301e66efChong Zhang            return NULL;
9036e2bcf40e4083be3a0fbb13d03293a78301e66efChong Zhang        }
9046a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9056a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(11);  // adts_buffer_fullness
9066a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9076a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2);
9086a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9096a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (number_of_raw_data_blocks_in_frame != 0) {
9106a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // To be implemented.
911e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("Should not reach here.");
912e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return NULL;
9136a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
9146a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9156a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (offset + aac_frame_length > mBuffer->size()) {
916a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber            return NULL;
9176a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
9186a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9193a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        size_t headerSize = protection_absent ? 7 : 9;
9203a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
9213a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        // tracking the frame positions first then decrypt only if an accessUnit to be generated
9223a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        if (mSampleDecryptor != NULL) {
9233a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            ADTSPosition frame = {
9243a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                .offset     = offset,
9253a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                .headerSize = headerSize,
9263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                .length     = aac_frame_length
9273a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            };
9283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
9293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            frames.push(frame);
9303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        }
9316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        offset += aac_frame_length;
9336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
9346a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9353a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // Decrypting only if the loop didn't exit early and an accessUnit is about to be generated
9363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // Not decrypting if key info not available (e.g., scanner/extractor parsing ts files)
9373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    if (mSampleDecryptor != NULL) {
9383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        for (size_t frameId = 0; frameId < frames.size(); frameId++) {
9393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            const ADTSPosition &frame = frames.itemAt(frameId);
9403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
9413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mSampleDecryptor->processAAC(frame.headerSize,
9423a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    mBuffer->data() + frame.offset, frame.length);
9433a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania//            ALOGV("dequeueAccessUnitAAC[%zu]: while offset %zu headerSize %zu frame_len %zu",
9443a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania//                    frameId, frame.offset, frame.headerSize, frame.length);
9453a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        }
9463a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
9473a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mAUIndex++;
9483a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
949a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber    int64_t timeUs = fetchTimestamp(offset);
9506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
95156ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(offset);
95256ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    memcpy(accessUnit->data(), mBuffer->data(), offset);
9536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    memmove(mBuffer->data(), mBuffer->data() + offset,
9556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mBuffer->size() - offset);
9566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    mBuffer->setRange(0, mBuffer->size() - offset);
9576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
95856ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
95937746afe186ce04f0f6252900b79726040d89a0dTerry Heo    accessUnit->meta()->setInt32("isSync", 1);
9606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return accessUnit;
9626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
9636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
9643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangint64_t ElementaryStreamQueue::fetchTimestamp(
9653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        size_t size, int32_t *pesOffset, int32_t *pesScramblingControl) {
966a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    int64_t timeUs = -1;
967a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    bool first = true;
968a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
969a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    while (size > 0) {
970e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (mRangeInfos.empty()) {
971e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return timeUs;
972e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
973a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
974a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        RangeInfo *info = &*mRangeInfos.begin();
975a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
976a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        if (first) {
977a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            timeUs = info->mTimestampUs;
9783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (pesOffset != NULL) {
9793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                *pesOffset = info->mPesOffset;
9803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
9813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (pesScramblingControl != NULL) {
9823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                *pesScramblingControl = info->mPesScramblingControl;
9833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
984fa51e09b30e884fed20b141783a7447599a6563eRachad            first = false;
985a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        }
986a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
987a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        if (info->mLength > size) {
988a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            info->mLength -= size;
989a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            size = 0;
990a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        } else {
991a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            size -= info->mLength;
992a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
993a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            mRangeInfos.erase(mRangeInfos.begin());
994a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            info = NULL;
995a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        }
996a1cc7d579888554a59f35c6cdfae3e7f85645ae2Andreas Huber
997a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    }
998a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
99998a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    if (timeUs == 0ll) {
10003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Returning 0 timestamp");
100198a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    }
100298a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber
1003a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    return timeUs;
1004a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber}
1005a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
10066a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
10073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (isScrambled()) {
10083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mBuffer == NULL || mBuffer->size() == 0) {
10093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return NULL;
10103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
10113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mFormat == NULL) {
10123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            mFormat = new MetaData;
1013a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen            if (!MakeAVCCodecSpecificData(*mFormat, mBuffer->data(), mBuffer->size())) {
10143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                ALOGW("Creating dummy AVC format for scrambled content");
10153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mFormat = new MetaData;
10163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
10173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mFormat->setInt32(kKeyWidth, 1280);
10183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mFormat->setInt32(kKeyHeight, 720);
10193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
1020bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            // for MediaExtractor.CasInfo
1021bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mFormat->setInt32(kKeyCASystemID, mCASystemId);
1022bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mFormat->setData(kKeyCASessionID, 0,
1023bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang                    mCasSessionId.data(), mCasSessionId.size());
10243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
10253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return dequeueScrambledAccessUnit();
10263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
10273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
10286a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    const uint8_t *data = mBuffer->data();
10296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
1030f56afa4878694803a44d1b0e9a54762d1d5ab652Andreas Huber    size_t size = mBuffer->size();
10316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    Vector<NALPosition> nals;
10326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t totalSize = 0;
103478acc89eae9789366b6384707861f4563addf2d3Chong Zhang    size_t seiCount = 0;
10356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10366a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    status_t err;
10376a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    const uint8_t *nalStart;
10386a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t nalSize;
10396a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    bool foundSlice = false;
104037746afe186ce04f0f6252900b79726040d89a0dTerry Heo    bool foundIDR = false;
10413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
10423a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("dequeueAccessUnit_H264[%d] %p/%zu", mAUIndex, data, size);
10433a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
10446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) {
10452b56065a51c49a6235ac974c033c5751e8055869Insun Kang        if (nalSize == 0) continue;
10466a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10476a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned nalType = nalStart[0] & 0x1f;
10486a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bool flush = false;
10496a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (nalType == 1 || nalType == 5) {
105137746afe186ce04f0f6252900b79726040d89a0dTerry Heo            if (nalType == 5) {
105237746afe186ce04f0f6252900b79726040d89a0dTerry Heo                foundIDR = true;
105337746afe186ce04f0f6252900b79726040d89a0dTerry Heo            }
10546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (foundSlice) {
10553a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                //TODO: Shouldn't this have been called with nalSize-1?
10566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                ABitReader br(nalStart + 1, nalSize);
10576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                unsigned first_mb_in_slice = parseUE(&br);
10586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (first_mb_in_slice == 0) {
10606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    // This slice starts a new frame.
10616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    flush = true;
10636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
10646a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
10656a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            foundSlice = true;
10676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else if ((nalType == 9 || nalType == 7) && foundSlice) {
10686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // Access unit delimiter and SPS will be associated with the
10696a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // next frame.
10706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10716a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            flush = true;
107278acc89eae9789366b6384707861f4563addf2d3Chong Zhang        } else if (nalType == 6 && nalSize > 0) {
107378acc89eae9789366b6384707861f4563addf2d3Chong Zhang            // found non-zero sized SEI
107478acc89eae9789366b6384707861f4563addf2d3Chong Zhang            ++seiCount;
10756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
10766a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10776a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (flush) {
10786a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // The access unit will contain all nal units up to, but excluding
10796a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // the current one, separated by 0x00 0x00 0x00 0x01 startcodes.
10806a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t auSize = 4 * nals.size() + totalSize;
10826a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            sp<ABuffer> accessUnit = new ABuffer(auSize);
108378acc89eae9789366b6384707861f4563addf2d3Chong Zhang            sp<ABuffer> sei;
108478acc89eae9789366b6384707861f4563addf2d3Chong Zhang
108578acc89eae9789366b6384707861f4563addf2d3Chong Zhang            if (seiCount > 0) {
108678acc89eae9789366b6384707861f4563addf2d3Chong Zhang                sei = new ABuffer(seiCount * sizeof(NALPosition));
108778acc89eae9789366b6384707861f4563addf2d3Chong Zhang                accessUnit->meta()->setBuffer("sei", sei);
108878acc89eae9789366b6384707861f4563addf2d3Chong Zhang            }
10896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#if !LOG_NDEBUG
10916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            AString out;
10926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#endif
10936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
10946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t dstOffset = 0;
109578acc89eae9789366b6384707861f4563addf2d3Chong Zhang            size_t seiIndex = 0;
10963a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            size_t shrunkBytes = 0;
10976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            for (size_t i = 0; i < nals.size(); ++i) {
10986a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                const NALPosition &pos = nals.itemAt(i);
10996a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11006a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;
11016a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
110278acc89eae9789366b6384707861f4563addf2d3Chong Zhang                if (nalType == 6 && pos.nalSize > 0) {
1103e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    if (seiIndex >= sei->size() / sizeof(NALPosition)) {
1104e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                        ALOGE("Wrong seiIndex");
1105e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                        return NULL;
1106e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    }
110778acc89eae9789366b6384707861f4563addf2d3Chong Zhang                    NALPosition &seiPos = ((NALPosition *)sei->data())[seiIndex++];
110878acc89eae9789366b6384707861f4563addf2d3Chong Zhang                    seiPos.nalOffset = dstOffset + 4;
110978acc89eae9789366b6384707861f4563addf2d3Chong Zhang                    seiPos.nalSize = pos.nalSize;
1110a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang                }
1111a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang
11126a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#if !LOG_NDEBUG
11136a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                char tmp[128];
11146a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                sprintf(tmp, "0x%02x", nalType);
11156a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (i > 0) {
11166a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    out.append(", ");
11176a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
11186a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                out.append(tmp);
11196a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#endif
11206a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11216a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4);
11226a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11233a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                if (mSampleDecryptor != NULL && (nalType == 1 || nalType == 5)) {
11243a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    uint8_t *nalData = mBuffer->data() + pos.nalOffset;
11253a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    size_t newSize = mSampleDecryptor->processNal(nalData, pos.nalSize);
11263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    // Note: the data can shrink due to unescaping
11273a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    memcpy(accessUnit->data() + dstOffset + 4,
11283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                            nalData,
11293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                            newSize);
11303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    dstOffset += newSize + 4;
11313a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
11323a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    size_t thisShrunkBytes = pos.nalSize - newSize;
11333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    //ALOGV("dequeueAccessUnitH264[%d]: nalType: %d -> %zu (%zu)",
11343a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    //        nalType, (int)pos.nalSize, newSize, thisShrunkBytes);
11356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    shrunkBytes += thisShrunkBytes;
11373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                }
11383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                else {
11393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    memcpy(accessUnit->data() + dstOffset + 4,
11403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                            mBuffer->data() + pos.nalOffset,
11413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                            pos.nalSize);
11423a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
11433a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    dstOffset += pos.nalSize + 4;
11443a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    //ALOGV("dequeueAccessUnitH264 [%d] %d @%d",
11453a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    //        nalType, (int)pos.nalSize, (int)pos.nalOffset);
11463a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                }
11476a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
11486a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
114994dcc94b16cc6c2a7aa02df2d0d6b8743d738d78Colin Cross#if !LOG_NDEBUG
11503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("accessUnit contains nal types %s", out.c_str());
115194dcc94b16cc6c2a7aa02df2d0d6b8743d738d78Colin Cross#endif
11526a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            const NALPosition &pos = nals.itemAt(nals.size() - 1);
11546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t nextScan = pos.nalOffset + pos.nalSize;
11556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            memmove(mBuffer->data(),
11576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    mBuffer->data() + nextScan,
11586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    mBuffer->size() - nextScan);
11596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mBuffer->setRange(0, mBuffer->size() - nextScan);
11616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
1162a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            int64_t timeUs = fetchTimestamp(nextScan);
1163e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (timeUs < 0ll) {
1164e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("Negative timeUs");
1165e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
1166e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
11676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            accessUnit->meta()->setInt64("timeUs", timeUs);
116937746afe186ce04f0f6252900b79726040d89a0dTerry Heo            if (foundIDR) {
117037746afe186ce04f0f6252900b79726040d89a0dTerry Heo                accessUnit->meta()->setInt32("isSync", 1);
117137746afe186ce04f0f6252900b79726040d89a0dTerry Heo            }
11726a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11736a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (mFormat == NULL) {
11743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                mFormat = new MetaData;
1175a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen                if (!MakeAVCCodecSpecificData(*mFormat,
1176a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen                        accessUnit->data(),
1177a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen                        accessUnit->size())) {
11783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                    mFormat.clear();
11793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                }
11806a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
11816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11823a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            if (mSampleDecryptor != NULL && shrunkBytes > 0) {
11833a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                size_t adjustedSize = accessUnit->size() - shrunkBytes;
11843a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                ALOGV("dequeueAccessUnitH264[%d]: AU size adjusted %zu -> %zu",
11853a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                        mAUIndex, accessUnit->size(), adjustedSize);
11863a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                accessUnit->setRange(0, adjustedSize);
11873a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            }
11883a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
11893a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            ALOGV("dequeueAccessUnitH264[%d]: AU %p(%zu) dstOffset:%zu, nals:%zu, totalSize:%zu ",
11903a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    mAUIndex, accessUnit->data(), accessUnit->size(),
11913a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    dstOffset, nals.size(), totalSize);
11923a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mAUIndex++;
11933a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
11946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            return accessUnit;
11956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
11966a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
11976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        NALPosition pos;
11986a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        pos.nalOffset = nalStart - mBuffer->data();
11996a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        pos.nalSize = nalSize;
12006a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
12016a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        nals.push(pos);
12026a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
12036a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        totalSize += nalSize;
12046a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
1205e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (err != (status_t)-EAGAIN) {
1206e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Unexpeted err");
1207e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
1208e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
12096a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
12106a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return NULL;
12116a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
12126a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
1213386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
1214386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    const uint8_t *data = mBuffer->data();
1215386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
1216386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1217386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < 4) {
1218386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return NULL;
1219386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1220386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1221386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint32_t header = U32_AT(data);
1222386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1223386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t frameSize;
1224386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int samplingRate, numChannels, bitrate, numSamples;
1225e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (!GetMPEGAudioFrameSize(
1226386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                header, &frameSize, &samplingRate, &numChannels,
1227e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                &bitrate, &numSamples)) {
1228e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Failed to get audio frame size");
1229e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
1230e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1231386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1232386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < frameSize) {
1233386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return NULL;
1234386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1235386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
12362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    unsigned layer = 4 - ((header >> 17) & 3);
12372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
1238386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(frameSize);
1239386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memcpy(accessUnit->data(), data, frameSize);
1240386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1241386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memmove(mBuffer->data(),
1242386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->data() + frameSize,
1243386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->size() - frameSize);
1244386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1245386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    mBuffer->setRange(0, mBuffer->size() - frameSize);
1246386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1247386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int64_t timeUs = fetchTimestamp(frameSize);
1248e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (timeUs < 0ll) {
1249e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Negative timeUs");
1250e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return NULL;
1251e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1252386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1253386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
125437746afe186ce04f0f6252900b79726040d89a0dTerry Heo    accessUnit->meta()->setInt32("isSync", 1);
1255386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1256386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (mFormat == NULL) {
1257386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat = new MetaData;
12582944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
12592944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        switch (layer) {
12602944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 1:
12612944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
12622944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
12632944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
12642944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 2:
12652944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
12662944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
12672944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
12682944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 3:
12692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
12702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
12712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
12722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            default:
1273e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
12742944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        }
12752944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
1276386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat->setInt32(kKeySampleRate, samplingRate);
1277386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
1278386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1279386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1280386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return accessUnit;
1281386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1282386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1283386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic void EncodeSize14(uint8_t **_ptr, size_t size) {
1284e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (size > 0x3fff) {
1285e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong size");
1286e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return;
1287e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1288386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1289386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *ptr = *_ptr;
1290386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1291386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x80 | (size >> 7);
1292386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = size & 0x7f;
1293386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1294386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *_ptr = ptr;
1295386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1296386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1297386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) {
1298386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    sp<ABuffer> esds = new ABuffer(csd->size() + 25);
1299386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1300386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *ptr = esds->data();
1301386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x03;
1302386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, 22 + csd->size());
1303386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1304386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;  // ES_ID
1305386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;
1306386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1307386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
1308386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1309386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x04;
1310386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, 16 + csd->size());
1311386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1312386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x40;  // Audio ISO/IEC 14496-3
1313386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1314386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    for (size_t i = 0; i < 12; ++i) {
1315386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        *ptr++ = 0x00;
1316386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1317386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1318386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x05;
1319386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, csd->size());
1320386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1321386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memcpy(ptr, csd->data(), csd->size());
1322386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1323386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return esds;
1324386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1325386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1326386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
13273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (isScrambled()) {
13283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mBuffer == NULL || mBuffer->size() == 0) {
13293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return NULL;
13303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mFormat == NULL) {
13323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGI("Creating dummy MPEG format for scrambled content");
13333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mFormat = new MetaData;
13343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
13353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mFormat->setInt32(kKeyWidth, 1280);
13363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mFormat->setInt32(kKeyHeight, 720);
13373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1338bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            // for MediaExtractor.CasInfo
1339bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mFormat->setInt32(kKeyCASystemID, mCASystemId);
1340bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mFormat->setData(kKeyCASessionID, 0,
1341bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang                    mCasSessionId.data(), mCasSessionId.size());
13423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return dequeueScrambledAccessUnit();
13443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1346386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    const uint8_t *data = mBuffer->data();
1347386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
1348386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
13493694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung    Vector<size_t> userDataPositions;
13503694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung
1351386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    bool sawPictureStart = false;
1352386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int pprevStartCode = -1;
1353386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int prevStartCode = -1;
1354386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int currentStartCode = -1;
135537746afe186ce04f0f6252900b79726040d89a0dTerry Heo    bool gopFound = false;
135637746afe186ce04f0f6252900b79726040d89a0dTerry Heo    bool isClosedGop = false;
135737746afe186ce04f0f6252900b79726040d89a0dTerry Heo    bool brokenLink = false;
1358386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1359386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t offset = 0;
1360386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while (offset + 3 < size) {
1361386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (memcmp(&data[offset], "\x00\x00\x01", 3)) {
1362386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            ++offset;
1363386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            continue;
1364386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1365386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1366386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        pprevStartCode = prevStartCode;
1367386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        prevStartCode = currentStartCode;
1368386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        currentStartCode = data[offset + 3];
1369386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1370386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (currentStartCode == 0xb3 && mFormat == NULL) {
1371386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            memmove(mBuffer->data(), mBuffer->data() + offset, size - offset);
1372386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            size -= offset;
1373386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            (void)fetchTimestamp(offset);
1374386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset = 0;
1375386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->setRange(0, size);
1376386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1377386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1378386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
1379386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
1380386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            // seqHeader without/with extension
1381386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1382386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (mFormat == NULL) {
1383e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (size < 7u) {
1384e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Size too small");
1385e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1386e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1387386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1388386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                unsigned width =
1389386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    (data[4] << 4) | data[5] >> 4;
1390386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1391386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                unsigned height =
1392386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    ((data[5] & 0x0f) << 8) | data[6];
1393386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1394386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat = new MetaData;
1395386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
1396386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setInt32(kKeyWidth, width);
1397386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setInt32(kKeyHeight, height);
1398386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1399df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("found MPEG2 video codec config (%d x %d)", width, height);
1400386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1401386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> csd = new ABuffer(offset);
1402386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memcpy(csd->data(), data, offset);
1403386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1404386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memmove(mBuffer->data(),
1405386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->data() + offset,
1406386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->size() - offset);
1407386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1408386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mBuffer->setRange(0, mBuffer->size() - offset);
1409386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= offset;
1410386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                (void)fetchTimestamp(offset);
1411386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                offset = 0;
1412386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1413386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                // hexdump(csd->data(), csd->size());
1414386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1415386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
1416386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setData(
1417386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        kKeyESDS, kTypeESDS, esds->data(), esds->size());
1418386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1419386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return NULL;
1420386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1421386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1422386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
142337746afe186ce04f0f6252900b79726040d89a0dTerry Heo        if (mFormat != NULL && currentStartCode == 0xb8) {
142437746afe186ce04f0f6252900b79726040d89a0dTerry Heo            // GOP layer
142530cfe1d70876034cd341fa62ec5abe7a6758d4e4Neel Mehta            if (offset + 7 >= size) {
142630cfe1d70876034cd341fa62ec5abe7a6758d4e4Neel Mehta                ALOGE("Size too small");
142730cfe1d70876034cd341fa62ec5abe7a6758d4e4Neel Mehta                return NULL;
142830cfe1d70876034cd341fa62ec5abe7a6758d4e4Neel Mehta            }
142937746afe186ce04f0f6252900b79726040d89a0dTerry Heo            gopFound = true;
143037746afe186ce04f0f6252900b79726040d89a0dTerry Heo            isClosedGop = (data[offset + 7] & 0x40) != 0;
143137746afe186ce04f0f6252900b79726040d89a0dTerry Heo            brokenLink = (data[offset + 7] & 0x20) != 0;
143237746afe186ce04f0f6252900b79726040d89a0dTerry Heo        }
143337746afe186ce04f0f6252900b79726040d89a0dTerry Heo
14343694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung        if (mFormat != NULL && currentStartCode == 0xb2) {
14353694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung            userDataPositions.add(offset);
14363694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung        }
14373694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung
1438386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (mFormat != NULL && currentStartCode == 0x00) {
1439386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            // Picture start
1440386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1441386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (!sawPictureStart) {
1442386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sawPictureStart = true;
1443386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            } else {
1444386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> accessUnit = new ABuffer(offset);
1445386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memcpy(accessUnit->data(), data, offset);
1446386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1447386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memmove(mBuffer->data(),
1448386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->data() + offset,
1449386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->size() - offset);
1450386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1451386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mBuffer->setRange(0, mBuffer->size() - offset);
1452386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1453386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                int64_t timeUs = fetchTimestamp(offset);
1454e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (timeUs < 0ll) {
1455e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Negative timeUs");
1456e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1457e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1458386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1459386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                offset = 0;
1460386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1461386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                accessUnit->meta()->setInt64("timeUs", timeUs);
146237746afe186ce04f0f6252900b79726040d89a0dTerry Heo                if (gopFound && (!brokenLink || isClosedGop)) {
146337746afe186ce04f0f6252900b79726040d89a0dTerry Heo                    accessUnit->meta()->setInt32("isSync", 1);
146437746afe186ce04f0f6252900b79726040d89a0dTerry Heo                }
1465386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1466b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                ALOGV("returning MPEG video access unit at time %" PRId64 " us",
1467386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                      timeUs);
1468386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1469386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                // hexdump(accessUnit->data(), accessUnit->size());
1470386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
14713694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                if (userDataPositions.size() > 0) {
14723694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                    sp<ABuffer> mpegUserData =
14733694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                        new ABuffer(userDataPositions.size() * sizeof(size_t));
14743694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                    if (mpegUserData != NULL && mpegUserData->data() != NULL) {
14753694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                        for (size_t i = 0; i < userDataPositions.size(); ++i) {
14763694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                            memcpy(
14773694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                                    mpegUserData->data() + i * sizeof(size_t),
14783694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                                    &userDataPositions[i], sizeof(size_t));
14793694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                        }
1480d83d4f4a43616f38217591ba2d3f10d77fd4e748Robert Shih                        accessUnit->meta()->setBuffer("mpeg-user-data", mpegUserData);
14813694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                    }
14823694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung                }
14833694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung
1484386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return accessUnit;
1485386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1486386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1487386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1488386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        ++offset;
1489386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1490386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1491386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return NULL;
1492386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1493386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1494386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic ssize_t getNextChunkSize(
1495386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        const uint8_t *data, size_t size) {
1496386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    static const char kStartCode[] = "\x00\x00\x01";
1497386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1498371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick    // per ISO/IEC 14496-2 6.2.1, a chunk has a 3-byte prefix + 1-byte start code
1499371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick    // we need at least <prefix><start><next prefix> to successfully scan
1500371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick    if (size < 3 + 1 + 3) {
1501386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return -EAGAIN;
1502386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1503386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1504386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (memcmp(kStartCode, data, 3)) {
1505e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return -EAGAIN;
1506386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1507386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1508371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick    size_t offset = 4;
1509386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while (offset + 2 < size) {
1510386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (!memcmp(&data[offset], kStartCode, 3)) {
1511386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return offset;
1512386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1513386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1514386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        ++offset;
1515386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1516386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1517386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return -EAGAIN;
1518386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1519386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1520386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
1521386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *data = mBuffer->data();
1522386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
1523386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1524386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    enum {
1525386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        SKIP_TO_VISUAL_OBJECT_SEQ_START,
1526386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VISUAL_OBJECT_START,
1527386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VO_START,
1528386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VOL_START,
1529386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        WAIT_FOR_VOP_START,
1530386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        SKIP_TO_VOP_START,
1531386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1532386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } state;
1533386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1534386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (mFormat == NULL) {
1535386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        state = SKIP_TO_VISUAL_OBJECT_SEQ_START;
1536386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else {
1537386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        state = SKIP_TO_VOP_START;
1538386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1539386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1540386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int32_t width = -1, height = -1;
1541386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1542386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t offset = 0;
1543386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    ssize_t chunkSize;
1544386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while ((chunkSize = getNextChunkSize(
1545386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    &data[offset], size - offset)) > 0) {
1546386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        bool discard = false;
1547386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1548386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        unsigned chunkType = data[offset + 3];
1549386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1550386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        switch (state) {
1551386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case SKIP_TO_VISUAL_OBJECT_SEQ_START:
1552386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1553386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb0) {
1554386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // Discard anything before this marker.
1555386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1556386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    state = EXPECT_VISUAL_OBJECT_START;
1557386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                } else {
1558386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
1559371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick                    offset += chunkSize;
1560371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick                    ALOGW("b/74114680, advance to next chunk");
1561371066d073c5db289b0f38b9d2bfd3e326c78c66Ray Essick                    android_errorWriteLog(0x534e4554, "74114680");
1562386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1563386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1564386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1565386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1566386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VISUAL_OBJECT_START:
1567386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1568e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (chunkType != 0xb5) {
1569e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Unexpected chunkType");
1570e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1571e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1572386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = EXPECT_VO_START;
1573386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1574386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1575386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1576386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VO_START:
1577386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1578e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (chunkType > 0x1f) {
1579e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Unexpected chunkType");
1580e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1581e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1582386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = EXPECT_VOL_START;
1583386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1584386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1585386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1586386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VOL_START:
1587386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1588e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if ((chunkType & 0xf0) != 0x20) {
1589e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Wrong chunkType");
1590e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1591e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1592386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1593e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (!ExtractDimensionsFromVOLHeader(
1594386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            &data[offset], chunkSize,
1595e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                            &width, &height)) {
1596e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    ALOGE("Failed to get dimension");
1597e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return NULL;
1598e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1599386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1600386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = WAIT_FOR_VOP_START;
1601386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1602386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1603386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1604386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case WAIT_FOR_VOP_START:
1605386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1606386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb3 || chunkType == 0xb6) {
1607386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // group of VOP or VOP start.
1608386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1609386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat = new MetaData;
1610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setCString(
1611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
1612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1613386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setInt32(kKeyWidth, width);
1614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setInt32(kKeyHeight, height);
1615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1616df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                    ALOGI("found MPEG4 video codec config (%d x %d)",
1617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                         width, height);
1618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> csd = new ABuffer(offset);
1620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memcpy(csd->data(), data, offset);
1621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // hexdump(csd->data(), csd->size());
1623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
1625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setData(
1626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            kKeyESDS, kTypeESDS,
1627386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            esds->data(), esds->size());
1628386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1629386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
1630386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    state = SKIP_TO_VOP_START;
1631386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1632386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1633386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1634386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1635386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1636386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case SKIP_TO_VOP_START:
1637386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
1638386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb6) {
163937746afe186ce04f0f6252900b79726040d89a0dTerry Heo                    int vopCodingType = (data[offset + 4] & 0xc0) >> 6;
164037746afe186ce04f0f6252900b79726040d89a0dTerry Heo
1641386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset += chunkSize;
1642386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1643386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> accessUnit = new ABuffer(offset);
1644386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memcpy(accessUnit->data(), data, offset);
1645386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1646386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memmove(data, &data[offset], size - offset);
1647386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    size -= offset;
1648386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mBuffer->setRange(0, size);
1649386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1650386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    int64_t timeUs = fetchTimestamp(offset);
1651e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    if (timeUs < 0ll) {
1652e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                        ALOGE("Negative timeus");
1653e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                        return NULL;
1654e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    }
1655386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1656386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset = 0;
1657386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1658386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    accessUnit->meta()->setInt64("timeUs", timeUs);
165937746afe186ce04f0f6252900b79726040d89a0dTerry Heo                    if (vopCodingType == 0) {  // intra-coded VOP
166037746afe186ce04f0f6252900b79726040d89a0dTerry Heo                        accessUnit->meta()->setInt32("isSync", 1);
166137746afe186ce04f0f6252900b79726040d89a0dTerry Heo                    }
1662386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1663b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                    ALOGV("returning MPEG4 video access unit at time %" PRId64 " us",
1664386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                         timeUs);
1665386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1666386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // hexdump(accessUnit->data(), accessUnit->size());
1667386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1668386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return accessUnit;
1669386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                } else if (chunkType != 0xb3) {
1670386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset += chunkSize;
1671386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
1672386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1673386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1674386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1675386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1676386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1677386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            default:
1678e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                ALOGE("Unknown state: %d", state);
1679e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return NULL;
1680386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1681386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1682386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (discard) {
1683386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            (void)fetchTimestamp(offset);
1684386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            memmove(data, &data[offset], size - offset);
1685386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            size -= offset;
1686386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset = 0;
1687386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->setRange(0, size);
1688386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        } else {
1689386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset += chunkSize;
1690386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1691386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1692386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1693386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return NULL;
1694386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1695386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1696be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissenvoid ElementaryStreamQueue::signalEOS() {
1697be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    if (!mEOSReached) {
1698be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        if (mMode == MPEG_VIDEO) {
1699be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen            const char *theEnd = "\x00\x00\x01\x00";
1700be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen            appendData(theEnd, 4, 0);
1701be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        }
1702be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        mEOSReached = true;
1703be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    } else {
1704be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        ALOGW("EOS already signaled");
1705be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    }
1706be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen}
1707be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen
17080852843d304006e3ab333081fddda13b07193de8Robert Shihsp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMetadata() {
17090852843d304006e3ab333081fddda13b07193de8Robert Shih    size_t size = mBuffer->size();
17100852843d304006e3ab333081fddda13b07193de8Robert Shih    if (!size) {
17110852843d304006e3ab333081fddda13b07193de8Robert Shih        return NULL;
17120852843d304006e3ab333081fddda13b07193de8Robert Shih    }
17130852843d304006e3ab333081fddda13b07193de8Robert Shih
17140852843d304006e3ab333081fddda13b07193de8Robert Shih    sp<ABuffer> accessUnit = new ABuffer(size);
17150852843d304006e3ab333081fddda13b07193de8Robert Shih    int64_t timeUs = fetchTimestamp(size);
17160852843d304006e3ab333081fddda13b07193de8Robert Shih    accessUnit->meta()->setInt64("timeUs", timeUs);
17170852843d304006e3ab333081fddda13b07193de8Robert Shih
17180852843d304006e3ab333081fddda13b07193de8Robert Shih    memcpy(accessUnit->data(), mBuffer->data(), size);
17190852843d304006e3ab333081fddda13b07193de8Robert Shih    mBuffer->setRange(0, 0);
17200852843d304006e3ab333081fddda13b07193de8Robert Shih
17210852843d304006e3ab333081fddda13b07193de8Robert Shih    if (mFormat == NULL) {
17220852843d304006e3ab333081fddda13b07193de8Robert Shih        mFormat = new MetaData;
17236f9c5e26c710dbee50e57316f1c460dda4850fa5Robert Shih        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_DATA_TIMED_ID3);
17240852843d304006e3ab333081fddda13b07193de8Robert Shih    }
17250852843d304006e3ab333081fddda13b07193de8Robert Shih
17260852843d304006e3ab333081fddda13b07193de8Robert Shih    return accessUnit;
17270852843d304006e3ab333081fddda13b07193de8Robert Shih}
1728be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen
17293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ElementaryStreamQueue::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
17303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    if (mSampleDecryptor == NULL) {
17313a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        ALOGE("signalNewSampleAesKey: Stream %x is not encrypted; keyItem: %p",
17323a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                mMode, keyItem.get());
17333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        return;
17343a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
17353a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
17363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleDecryptor->signalNewSampleAesKey(keyItem);
17373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
17383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
17393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
17406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}  // namespace android
1741