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