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>
276a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MediaErrors.h>
286a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MediaDefs.h>
296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <media/stagefright/MetaData.h>
30386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#include <media/stagefright/Utils.h>
316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include "include/avc_utils.h"
336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
34bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber#include <netinet/in.h>
35bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
366a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubernamespace android {
376a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
3857bc23915ecc1d15c293d30463948b68885b3437Andreas HuberElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
3957bc23915ecc1d15c293d30463948b68885b3437Andreas Huber    : mMode(mode),
4057bc23915ecc1d15c293d30463948b68885b3437Andreas Huber      mFlags(flags) {
416a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
426a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
436a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<MetaData> ElementaryStreamQueue::getFormat() {
446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return mFormat;
456a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
466a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
47f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ElementaryStreamQueue::clear(bool clearFormat) {
48e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber    if (mBuffer != NULL) {
49e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber        mBuffer->setRange(0, 0);
50e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber    }
51e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber
52a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    mRangeInfos.clear();
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (clearFormat) {
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFormat.clear();
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
572a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
582a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
59a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) {
60a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (size < 3) {
61a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        // Not enough data to verify header.
62a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
63a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
64a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
65a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
66a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
67a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
68a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
69a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned layer = (ptr[1] >> 1) & 3;
70a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
71a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (layer != 0) {
72a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
73a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
74a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
75a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned ID = (ptr[1] >> 3) & 1;
76a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    unsigned profile_ObjectType = ptr[2] >> 6;
77a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
78a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (ID == 1 && profile_ObjectType == 3) {
79a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        // MPEG-2 profile 3 is reserved.
80a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return false;
81a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
82a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
83a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return true;
84a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
85a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
86386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
87386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < 3) {
88386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        // Not enough data to verify header.
89386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;
90386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
91386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
92386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) {
93386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;
94386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
95386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
96386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned ID = (ptr[1] >> 3) & 3;
97386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
98386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (ID == 1) {
99386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
100386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
101386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
102386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned layer = (ptr[1] >> 1) & 3;
103386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
104386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (layer == 0) {
105386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
106386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
107386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
108386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned bitrateIndex = (ptr[2] >> 4);
109386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
110386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (bitrateIndex == 0x0f) {
111386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
112386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
113386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
114386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned samplingRateIndex = (ptr[2] >> 2) & 3;
115386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
116386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (samplingRateIndex == 3) {
117386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return false;  // reserved
118386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
119386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
120386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return true;
121386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
122386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1236a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberstatus_t ElementaryStreamQueue::appendData(
1246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        const void *data, size_t size, int64_t timeUs) {
1256a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    if (mBuffer == NULL || mBuffer->size() == 0) {
1266a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        switch (mMode) {
1276a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            case H264:
128386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG_VIDEO:
1296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            {
130decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#if 0
1316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
1326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    return ERROR_MALFORMED;
1336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
134decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#else
135decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                uint8_t *ptr = (uint8_t *)data;
136decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
137decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                ssize_t startOffset = -1;
138decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                for (size_t i = 0; i + 3 < size; ++i) {
139decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    if (!memcmp("\x00\x00\x00\x01", &ptr[i], 4)) {
140decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        startOffset = i;
141decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        break;
142decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    }
143decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
144decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
145decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset < 0) {
146decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    return ERROR_MALFORMED;
147decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
148decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
149decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset > 0) {
1508807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                    ALOGI("found something resembling an H.264/MPEG syncword "
1518807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          "at offset %d",
1528807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          startOffset);
153386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
154386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
155386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                data = &ptr[startOffset];
156386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= startOffset;
157386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#endif
158386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
159386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
160386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
161386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG4_VIDEO:
162386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
163386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#if 0
164386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (size < 3 || memcmp("\x00\x00\x01", data, 3)) {
165386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
166386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
167386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber#else
168386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                uint8_t *ptr = (uint8_t *)data;
169386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
170386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                ssize_t startOffset = -1;
171386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                for (size_t i = 0; i + 2 < size; ++i) {
172386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    if (!memcmp("\x00\x00\x01", &ptr[i], 3)) {
173386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        startOffset = i;
174386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        break;
175386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    }
176386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
177386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
178386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset < 0) {
179386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
180386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
181386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
182386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset > 0) {
1838807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                    ALOGI("found something resembling an H.264/MPEG syncword "
1848807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          "at offset %d",
1858807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          startOffset);
186decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
187decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
188decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                data = &ptr[startOffset];
189decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                size -= startOffset;
190decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#endif
1916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                break;
1926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
1936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
1946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            case AAC:
1956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            {
1966a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                uint8_t *ptr = (uint8_t *)data;
1976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
198decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#if 0
1996a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (size < 2 || ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) {
2006a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    return ERROR_MALFORMED;
2016a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
202decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#else
203decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                ssize_t startOffset = -1;
204a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                for (size_t i = 0; i < size; ++i) {
205a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                    if (IsSeeminglyValidADTSHeader(&ptr[i], size - i)) {
206decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        startOffset = i;
207decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                        break;
208decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    }
209decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
210decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
211decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset < 0) {
212decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                    return ERROR_MALFORMED;
213decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
214decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
215decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                if (startOffset > 0) {
2168807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                    ALOGI("found something resembling an AAC syncword at "
2178807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          "offset %d",
2188807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          startOffset);
219decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                }
220decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
221decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                data = &ptr[startOffset];
222decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber                size -= startOffset;
223decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber#endif
2246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                break;
2256a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
2266a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
227386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case MPEG_AUDIO:
228386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
229386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                uint8_t *ptr = (uint8_t *)data;
230386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
231386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                ssize_t startOffset = -1;
232386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                for (size_t i = 0; i < size; ++i) {
233386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) {
234386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        startOffset = i;
235386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        break;
236386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    }
237386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
238386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
239386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset < 0) {
240386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return ERROR_MALFORMED;
241386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
242386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
243386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (startOffset > 0) {
244df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                    ALOGI("found something resembling an MPEG audio "
2458807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          "syncword at offset %d",
2468807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber                          startOffset);
247386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
248386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
249386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                data = &ptr[startOffset];
250386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= startOffset;
251386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
252386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
253386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
254bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            case PCM_AUDIO:
255bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            {
256bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber                break;
257bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            }
258bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
2596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            default:
2606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                TRESPASS();
2616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                break;
2626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
2636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
2646a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2656a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t neededSize = (mBuffer == NULL ? 0 : mBuffer->size()) + size;
2666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
2676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        neededSize = (neededSize + 65535) & ~65535;
2686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("resizing buffer to size %d", neededSize);
2706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2716a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        sp<ABuffer> buffer = new ABuffer(neededSize);
2726a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mBuffer != NULL) {
2736a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            memcpy(buffer->data(), mBuffer->data(), mBuffer->size());
2746a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            buffer->setRange(0, mBuffer->size());
2756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else {
2766a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            buffer->setRange(0, 0);
2776a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
2786a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2796a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        mBuffer = buffer;
2806a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
2816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2826a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    memcpy(mBuffer->data() + mBuffer->size(), data, size);
2836a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    mBuffer->setRange(0, mBuffer->size() + size);
2846a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
285a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    RangeInfo info;
286a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    info.mLength = size;
287a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    info.mTimestampUs = timeUs;
288a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    mRangeInfos.push_back(info);
289a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
290a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber#if 0
291a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    if (mMode == AAC) {
292df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("size = %d, timeUs = %.2f secs", size, timeUs / 1E6);
293a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        hexdump(data, size);
294a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    }
295a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber#endif
2966a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return OK;
2986a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
2996a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
3006a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
30157bc23915ecc1d15c293d30463948b68885b3437Andreas Huber    if ((mFlags & kFlag_AlignedData) && mMode == H264) {
30257bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        if (mRangeInfos.empty()) {
30357bc23915ecc1d15c293d30463948b68885b3437Andreas Huber            return NULL;
30457bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        }
30557bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
30657bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        RangeInfo info = *mRangeInfos.begin();
30757bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        mRangeInfos.erase(mRangeInfos.begin());
30857bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
30957bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        sp<ABuffer> accessUnit = new ABuffer(info.mLength);
31057bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        memcpy(accessUnit->data(), mBuffer->data(), info.mLength);
31157bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        accessUnit->meta()->setInt64("timeUs", info.mTimestampUs);
31257bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
31357bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        memmove(mBuffer->data(),
31457bc23915ecc1d15c293d30463948b68885b3437Andreas Huber                mBuffer->data() + info.mLength,
31557bc23915ecc1d15c293d30463948b68885b3437Andreas Huber                mBuffer->size() - info.mLength);
31657bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
31757bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        mBuffer->setRange(0, mBuffer->size() - info.mLength);
31857bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
31957bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        if (mFormat == NULL) {
32057bc23915ecc1d15c293d30463948b68885b3437Andreas Huber            mFormat = MakeAVCCodecSpecificData(accessUnit);
32157bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        }
32257bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
32357bc23915ecc1d15c293d30463948b68885b3437Andreas Huber        return accessUnit;
32457bc23915ecc1d15c293d30463948b68885b3437Andreas Huber    }
32557bc23915ecc1d15c293d30463948b68885b3437Andreas Huber
326386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (mMode) {
327386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case H264:
328386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitH264();
329386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case AAC:
330386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitAAC();
331386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case MPEG_VIDEO:
332386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEGVideo();
333386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case MPEG4_VIDEO:
334386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEG4Video();
335bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        case PCM_AUDIO:
336bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            return dequeueAccessUnitPCMAudio();
337386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
338386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
339386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return dequeueAccessUnitMPEGAudio();
3406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
3416a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
3426a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
343bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
344bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (mBuffer->size() < 4) {
345bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return NULL;
346bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
347bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
348bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    ABitReader bits(mBuffer->data(), 4);
349bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK_EQ(bits.getBits(8), 0xa0);
350bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    unsigned numAUs = bits.getBits(8);
351bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    bits.skipBits(8);
352bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    unsigned quantization_word_length = bits.getBits(2);
353bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    unsigned audio_sampling_frequency = bits.getBits(3);
354bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    unsigned num_channels = bits.getBits(3);
355bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
356bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK_EQ(audio_sampling_frequency, 2);  // 48kHz
357bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK_EQ(num_channels, 1u);  // stereo!
358bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
359bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (mFormat == NULL) {
360bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        mFormat = new MetaData;
361bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
362bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        mFormat->setInt32(kKeyChannelCount, 2);
363bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        mFormat->setInt32(kKeySampleRate, 48000);
364bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
365bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
366bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    static const size_t kFramesPerAU = 80;
367bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    size_t frameSize = 2 /* numChannels */ * sizeof(int16_t);
368bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
369bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    size_t payloadSize = numAUs * frameSize * kFramesPerAU;
370bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
371bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (mBuffer->size() < 4 + payloadSize) {
372bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return NULL;
373bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
374bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
375bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(payloadSize);
376bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
377bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
378bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    int64_t timeUs = fetchTimestamp(payloadSize + 4);
379bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK_GE(timeUs, 0ll);
380bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
381bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
382bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    int16_t *ptr = (int16_t *)accessUnit->data();
383bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) {
384bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        ptr[i] = ntohs(ptr[i]);
385bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
386bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
387bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    memmove(
388bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            mBuffer->data(),
389bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            mBuffer->data() + 4 + payloadSize,
390bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            mBuffer->size() - 4 - payloadSize);
391bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
392bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize);
393bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
394bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    return accessUnit;
395bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber}
396bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
3976a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
3988807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    if (mBuffer->size() == 0) {
3998807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber        return NULL;
4008807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    }
4018807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber
4028807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    CHECK(!mRangeInfos.empty());
4036a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4048807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    const RangeInfo &info = *mRangeInfos.begin();
4058807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    if (mBuffer->size() < info.mLength) {
4068807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber        return NULL;
4078807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    }
4088807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber
4098807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    CHECK_GE(info.mTimestampUs, 0ll);
4108807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber
4118807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    // The idea here is consume all AAC frames starting at offsets before
4128807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    // info.mLength so we can assign a meaningful timestamp without
4138807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    // having to interpolate.
4148807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    // The final AAC frame may well extend into the next RangeInfo but
4158807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    // that's ok.
4166a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t offset = 0;
4178807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    while (offset < info.mLength) {
4188807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber        if (offset + 7 > mBuffer->size()) {
4198807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber            return NULL;
4208807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber        }
4218807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber
4226a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        ABitReader bits(mBuffer->data() + offset, mBuffer->size() - offset);
4236a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // adts_fixed_header
4256a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4266a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        CHECK_EQ(bits.getBits(12), 0xfffu);
4276a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(3);  // ID, layer
4286a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bool protection_absent = bits.getBits(1) != 0;
4296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4306a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mFormat == NULL) {
4316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned profile = bits.getBits(2);
4326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            CHECK_NE(profile, 3u);
4336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned sampling_freq_index = bits.getBits(4);
4346a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.getBits(1);  // private_bit
4356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            unsigned channel_configuration = bits.getBits(3);
4366a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            CHECK_NE(channel_configuration, 0u);
4376a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.skipBits(2);  // original_copy, home
4386a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4396a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mFormat = MakeAACCodecSpecificData(
4406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    profile, sampling_freq_index, channel_configuration);
4415bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
44256ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber            mFormat->setInt32(kKeyIsADTS, true);
44356ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber
4445bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            int32_t sampleRate;
4455bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            int32_t numChannels;
4465bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate));
4475bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels));
4485bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
449df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("found AAC codec config (%d Hz, %d channels)",
4505bc087c573c70c84c6a39946457590b42d392a33Andreas Huber                 sampleRate, numChannels);
4516a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else {
4526a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // profile_ObjectType, sampling_frequency_index, private_bits,
4536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // channel_configuration, original_copy, home
4546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            bits.skipBits(12);
4556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
4566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // adts_variable_header
4586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        // copyright_identification_bit, copyright_identification_start
4606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(2);
4616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned aac_frame_length = bits.getBits(13);
4636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4646a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bits.skipBits(11);  // adts_buffer_fullness
4656a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2);
4676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (number_of_raw_data_blocks_in_frame != 0) {
4696a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // To be implemented.
4706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            TRESPASS();
4716a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
4726a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4736a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (offset + aac_frame_length > mBuffer->size()) {
4748807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber            return NULL;
4756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
4766a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4776a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        size_t headerSize = protection_absent ? 7 : 9;
4786a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4796a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        offset += aac_frame_length;
4806a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
4816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4828807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber    int64_t timeUs = fetchTimestamp(offset);
4836a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
48456ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(offset);
48556ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    memcpy(accessUnit->data(), mBuffer->data(), offset);
4866a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4876a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    memmove(mBuffer->data(), mBuffer->data() + offset,
4886a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mBuffer->size() - offset);
4896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    mBuffer->setRange(0, mBuffer->size() - offset);
4906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
49156ad61a253a94586d946cc09ed814e7a95a40ca7Andreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
4926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
4936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return accessUnit;
4946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
4956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
496a093f92042cf65060d1474c0fe116c12f8981717Andreas Huberint64_t ElementaryStreamQueue::fetchTimestamp(size_t size) {
497a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    int64_t timeUs = -1;
498a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    bool first = true;
499a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
500a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    while (size > 0) {
501a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        CHECK(!mRangeInfos.empty());
502a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
503a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        RangeInfo *info = &*mRangeInfos.begin();
504a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
505a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        if (first) {
506a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            timeUs = info->mTimestampUs;
507a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        }
508a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
509a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        if (info->mLength > size) {
510a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            info->mLength -= size;
511a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
512a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            if (first) {
513a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber                info->mTimestampUs = -1;
514a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            }
515a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
516a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            size = 0;
517a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        } else {
518a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            size -= info->mLength;
519a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
520a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            mRangeInfos.erase(mRangeInfos.begin());
521a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            info = NULL;
522a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber        }
5238807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber
5248807524fcb3bcfbf87004dbf1df9722b0a977300Andreas Huber        first = false;
525a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    }
526a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
52798a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    if (timeUs == 0ll) {
5283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Returning 0 timestamp");
52998a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    }
53098a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber
531a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber    return timeUs;
532a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber}
533a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber
5346a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberstruct NALPosition {
5356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t nalOffset;
5366a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t nalSize;
5376a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber};
5386a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5396a63a939601645404fd98f58c19cc38ca818d99eAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
5406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    const uint8_t *data = mBuffer->data();
5416a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
54257bc23915ecc1d15c293d30463948b68885b3437Andreas Huber    size_t size = mBuffer->size();
5436a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    Vector<NALPosition> nals;
5446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5456a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t totalSize = 0;
5466a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5476a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    status_t err;
5486a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    const uint8_t *nalStart;
5496a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    size_t nalSize;
5506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    bool foundSlice = false;
5516a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) {
552c9c47e48256fc1b79a77be8226ab9030920c0355Insun Kang        if (nalSize == 0) continue;
5536a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        unsigned nalType = nalStart[0] & 0x1f;
5556a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        bool flush = false;
5566a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5576a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (nalType == 1 || nalType == 5) {
5586a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (foundSlice) {
5596a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                ABitReader br(nalStart + 1, nalSize);
5606a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                unsigned first_mb_in_slice = parseUE(&br);
5616a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (first_mb_in_slice == 0) {
5636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    // This slice starts a new frame.
5646a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5656a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    flush = true;
5666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
5676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
5686a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5696a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            foundSlice = true;
5706a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        } else if ((nalType == 9 || nalType == 7) && foundSlice) {
5716a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // Access unit delimiter and SPS will be associated with the
5726a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // next frame.
5736a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5746a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            flush = true;
5756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
5766a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5776a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (flush) {
5786a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // The access unit will contain all nal units up to, but excluding
5796a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            // the current one, separated by 0x00 0x00 0x00 0x01 startcodes.
5806a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t auSize = 4 * nals.size() + totalSize;
5826a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            sp<ABuffer> accessUnit = new ABuffer(auSize);
5836a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5846a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#if !LOG_NDEBUG
5856a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            AString out;
5866a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#endif
5876a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5886a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t dstOffset = 0;
5896a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            for (size_t i = 0; i < nals.size(); ++i) {
5906a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                const NALPosition &pos = nals.itemAt(i);
5916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;
5936a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
5946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#if !LOG_NDEBUG
5956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                char tmp[128];
5966a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                sprintf(tmp, "0x%02x", nalType);
5976a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                if (i > 0) {
5986a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    out.append(", ");
5996a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                }
6006a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                out.append(tmp);
6016a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#endif
6026a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6036a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4);
6046a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6056a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                memcpy(accessUnit->data() + dstOffset + 4,
6066a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                       mBuffer->data() + pos.nalOffset,
6076a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                       pos.nalSize);
6086a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6096a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                dstOffset += pos.nalSize + 4;
6106a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
6116a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("accessUnit contains nal types %s", out.c_str());
6136a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6146a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            const NALPosition &pos = nals.itemAt(nals.size() - 1);
6156a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            size_t nextScan = pos.nalOffset + pos.nalSize;
6166a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6176a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            memmove(mBuffer->data(),
6186a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    mBuffer->data() + nextScan,
6196a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                    mBuffer->size() - nextScan);
6206a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6216a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mBuffer->setRange(0, mBuffer->size() - nextScan);
6226a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
623a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            int64_t timeUs = fetchTimestamp(nextScan);
624a093f92042cf65060d1474c0fe116c12f8981717Andreas Huber            CHECK_GE(timeUs, 0ll);
6256a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            accessUnit->meta()->setInt64("timeUs", timeUs);
6276a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6286a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (mFormat == NULL) {
6296a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                mFormat = MakeAVCCodecSpecificData(accessUnit);
6306a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            }
6316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            return accessUnit;
6336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        }
6346a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6356a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        NALPosition pos;
6366a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        pos.nalOffset = nalStart - mBuffer->data();
6376a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        pos.nalSize = nalSize;
6386a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6396a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        nals.push(pos);
6406a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6416a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        totalSize += nalSize;
6426a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    }
6436a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    CHECK_EQ(err, (status_t)-EAGAIN);
6446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
6456a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    return NULL;
6466a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}
6476a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
648386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
649386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    const uint8_t *data = mBuffer->data();
650386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
651386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
652386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < 4) {
653386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return NULL;
654386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
655386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
656386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint32_t header = U32_AT(data);
657386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
658386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t frameSize;
659386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int samplingRate, numChannels, bitrate, numSamples;
660386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    CHECK(GetMPEGAudioFrameSize(
661386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                header, &frameSize, &samplingRate, &numChannels,
662386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                &bitrate, &numSamples));
663386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
664386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < frameSize) {
665386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return NULL;
666386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
667386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
6682944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    unsigned layer = 4 - ((header >> 17) & 3);
6692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
670386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(frameSize);
671386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memcpy(accessUnit->data(), data, frameSize);
672386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
673386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memmove(mBuffer->data(),
674386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->data() + frameSize,
675386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->size() - frameSize);
676386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
677386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    mBuffer->setRange(0, mBuffer->size() - frameSize);
678386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
679386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int64_t timeUs = fetchTimestamp(frameSize);
680386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    CHECK_GE(timeUs, 0ll);
681386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
682386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    accessUnit->meta()->setInt64("timeUs", timeUs);
683386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
684386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (mFormat == NULL) {
685386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat = new MetaData;
6862944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
6872944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        switch (layer) {
6882944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 1:
6892944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
6902944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
6912944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
6922944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 2:
6932944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
6942944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
6952944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
6962944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            case 3:
6972944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                mFormat->setCString(
6982944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
6992944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                break;
7002944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            default:
7012944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber                TRESPASS();
7022944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        }
7032944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
704386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat->setInt32(kKeySampleRate, samplingRate);
705386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mFormat->setInt32(kKeyChannelCount, numChannels);
706386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
707386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
708386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return accessUnit;
709386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
710386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
711386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic void EncodeSize14(uint8_t **_ptr, size_t size) {
712386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    CHECK_LE(size, 0x3fff);
713386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
714386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *ptr = *_ptr;
715386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
716386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x80 | (size >> 7);
717386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = size & 0x7f;
718386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
719386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *_ptr = ptr;
720386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
721386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
722386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) {
723386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    sp<ABuffer> esds = new ABuffer(csd->size() + 25);
724386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
725386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *ptr = esds->data();
726386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x03;
727386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, 22 + csd->size());
728386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
729386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;  // ES_ID
730386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;
731386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
732386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
733386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
734386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x04;
735386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, 16 + csd->size());
736386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
737386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x40;  // Audio ISO/IEC 14496-3
738386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
739386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    for (size_t i = 0; i < 12; ++i) {
740386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        *ptr++ = 0x00;
741386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
742386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
743386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    *ptr++ = 0x05;
744386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    EncodeSize14(&ptr, csd->size());
745386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
746386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    memcpy(ptr, csd->data(), csd->size());
747386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
748386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return esds;
749386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
750386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
751386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
752386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    const uint8_t *data = mBuffer->data();
753386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
754386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
755386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    bool sawPictureStart = false;
756386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int pprevStartCode = -1;
757386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int prevStartCode = -1;
758386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int currentStartCode = -1;
759386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
760386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t offset = 0;
761386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while (offset + 3 < size) {
762386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (memcmp(&data[offset], "\x00\x00\x01", 3)) {
763386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            ++offset;
764386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            continue;
765386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
766386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
767386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        pprevStartCode = prevStartCode;
768386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        prevStartCode = currentStartCode;
769386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        currentStartCode = data[offset + 3];
770386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
771386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (currentStartCode == 0xb3 && mFormat == NULL) {
772386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            memmove(mBuffer->data(), mBuffer->data() + offset, size - offset);
773386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            size -= offset;
774386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            (void)fetchTimestamp(offset);
775386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset = 0;
776386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->setRange(0, size);
777386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
778386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
779386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
780386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
781386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            // seqHeader without/with extension
782386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
783386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (mFormat == NULL) {
784386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK_GE(size, 7u);
785386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
786386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                unsigned width =
787386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    (data[4] << 4) | data[5] >> 4;
788386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
789386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                unsigned height =
790386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    ((data[5] & 0x0f) << 8) | data[6];
791386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
792386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat = new MetaData;
793386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
794386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setInt32(kKeyWidth, width);
795386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setInt32(kKeyHeight, height);
796386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
797df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("found MPEG2 video codec config (%d x %d)", width, height);
798386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
799386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> csd = new ABuffer(offset);
800386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memcpy(csd->data(), data, offset);
801386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
802386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memmove(mBuffer->data(),
803386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->data() + offset,
804386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->size() - offset);
805386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
806386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mBuffer->setRange(0, mBuffer->size() - offset);
807386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                size -= offset;
808386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                (void)fetchTimestamp(offset);
809386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                offset = 0;
810386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
811386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                // hexdump(csd->data(), csd->size());
812386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
813386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
814386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mFormat->setData(
815386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        kKeyESDS, kTypeESDS, esds->data(), esds->size());
816386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
817386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return NULL;
818386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
819386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
820386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
821386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (mFormat != NULL && currentStartCode == 0x00) {
822386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            // Picture start
823386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
824386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (!sawPictureStart) {
825386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sawPictureStart = true;
826386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            } else {
827386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                sp<ABuffer> accessUnit = new ABuffer(offset);
828386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memcpy(accessUnit->data(), data, offset);
829386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
830386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                memmove(mBuffer->data(),
831386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->data() + offset,
832386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                        mBuffer->size() - offset);
833386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
834386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mBuffer->setRange(0, mBuffer->size() - offset);
835386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
836386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                int64_t timeUs = fetchTimestamp(offset);
837386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK_GE(timeUs, 0ll);
838386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
839386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                offset = 0;
840386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
841386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                accessUnit->meta()->setInt64("timeUs", timeUs);
842386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
8433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("returning MPEG video access unit at time %lld us",
844386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                      timeUs);
845386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
846386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                // hexdump(accessUnit->data(), accessUnit->size());
847386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
848386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return accessUnit;
849386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
850386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
851386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
852386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        ++offset;
853386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
854386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
855386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return NULL;
856386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
857386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
858386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic ssize_t getNextChunkSize(
859386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        const uint8_t *data, size_t size) {
860386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    static const char kStartCode[] = "\x00\x00\x01";
861386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
862386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (size < 3) {
863386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        return -EAGAIN;
864386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
865386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
866386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (memcmp(kStartCode, data, 3)) {
867386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        TRESPASS();
868386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
869386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
870386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t offset = 3;
871386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while (offset + 2 < size) {
872386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (!memcmp(&data[offset], kStartCode, 3)) {
873386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            return offset;
874386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
875386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
876386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        ++offset;
877386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
878386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
879386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return -EAGAIN;
880386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
881386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
882386d609dc513e838c7e7c4c46c604493ccd560beAndreas Hubersp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
883386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    uint8_t *data = mBuffer->data();
884386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t size = mBuffer->size();
885386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
886386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    enum {
887386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        SKIP_TO_VISUAL_OBJECT_SEQ_START,
888386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VISUAL_OBJECT_START,
889386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VO_START,
890386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        EXPECT_VOL_START,
891386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        WAIT_FOR_VOP_START,
892386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        SKIP_TO_VOP_START,
893386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
894386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } state;
895386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
896386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (mFormat == NULL) {
897386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        state = SKIP_TO_VISUAL_OBJECT_SEQ_START;
898386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else {
899386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        state = SKIP_TO_VOP_START;
900386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
901386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
902386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    int32_t width = -1, height = -1;
903386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
904386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    size_t offset = 0;
905386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    ssize_t chunkSize;
906386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while ((chunkSize = getNextChunkSize(
907386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    &data[offset], size - offset)) > 0) {
908386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        bool discard = false;
909386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
910386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        unsigned chunkType = data[offset + 3];
911386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
912386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        switch (state) {
913386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case SKIP_TO_VISUAL_OBJECT_SEQ_START:
914386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
915386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb0) {
916386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // Discard anything before this marker.
917386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
918386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    state = EXPECT_VISUAL_OBJECT_START;
919386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                } else {
920386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
921386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
922386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
923386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
924386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
925386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VISUAL_OBJECT_START:
926386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
927386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK_EQ(chunkType, 0xb5);
928386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = EXPECT_VO_START;
929386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
930386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
931386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
932386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VO_START:
933386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
934386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK_LE(chunkType, 0x1f);
935386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = EXPECT_VOL_START;
936386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
937386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
938386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
939386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case EXPECT_VOL_START:
940386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
941386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK((chunkType & 0xf0) == 0x20);
942386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
943386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                CHECK(ExtractDimensionsFromVOLHeader(
944386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            &data[offset], chunkSize,
945386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            &width, &height));
946386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
947386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                state = WAIT_FOR_VOP_START;
948386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
949386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
950386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
951386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case WAIT_FOR_VOP_START:
952386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
953386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb3 || chunkType == 0xb6) {
954386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // group of VOP or VOP start.
955386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
956386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat = new MetaData;
957386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setCString(
958386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
959386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
960386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setInt32(kKeyWidth, width);
961386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setInt32(kKeyHeight, height);
962386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
963df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                    ALOGI("found MPEG4 video codec config (%d x %d)",
964386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                         width, height);
965386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
966386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> csd = new ABuffer(offset);
967386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memcpy(csd->data(), data, offset);
968386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
969386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // hexdump(csd->data(), csd->size());
970386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
971386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
972386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mFormat->setData(
973386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            kKeyESDS, kTypeESDS,
974386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                            esds->data(), esds->size());
975386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
976386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
977386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    state = SKIP_TO_VOP_START;
978386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
979386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
980386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
981386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
982386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
983386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            case SKIP_TO_VOP_START:
984386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            {
985386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (chunkType == 0xb6) {
986386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset += chunkSize;
987386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
988386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    sp<ABuffer> accessUnit = new ABuffer(offset);
989386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memcpy(accessUnit->data(), data, offset);
990386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
991386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    memmove(data, &data[offset], size - offset);
992386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    size -= offset;
993386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    mBuffer->setRange(0, size);
994386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
995386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    int64_t timeUs = fetchTimestamp(offset);
996386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    CHECK_GE(timeUs, 0ll);
997386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
998386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset = 0;
999386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1000386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    accessUnit->meta()->setInt64("timeUs", timeUs);
1001386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
10023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("returning MPEG4 video access unit at time %lld us",
1003386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                         timeUs);
1004386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1005386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    // hexdump(accessUnit->data(), accessUnit->size());
1006386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1007386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    return accessUnit;
1008386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                } else if (chunkType != 0xb3) {
1009386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    offset += chunkSize;
1010386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    discard = true;
1011386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1012386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1013386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                break;
1014386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1015386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1016386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            default:
1017386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                TRESPASS();
1018386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1019386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1020386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        if (discard) {
1021386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            (void)fetchTimestamp(offset);
1022386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            memmove(data, &data[offset], size - offset);
1023386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            size -= offset;
1024386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset = 0;
1025386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            mBuffer->setRange(0, size);
1026386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        } else {
1027386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            offset += chunkSize;
1028386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1029386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1030386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1031386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    return NULL;
1032386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber}
1033386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
10346a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber}  // namespace android
1035