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