1840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber/* 2840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Copyright (C) 2012 The Android Open Source Project 3840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 4840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * you may not use this file except in compliance with the License. 6840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * You may obtain a copy of the License at 7840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 8840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * 10840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Unless required by applicable law or agreed to in writing, software 11840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * See the License for the specific language governing permissions and 14840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * limitations under the License. 15840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber */ 16840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 17840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber//#define LOG_NDEBUG 0 18cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen#define LOG_TAG "FragmentedMP4Parser" 19840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <utils/Log.h> 20840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 218c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen#include "include/avc_utils.h" 22cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen#include "include/ESDS.h" 2356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/FragmentedMP4Parser.h" 24840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "TrackFragment.h" 25840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 26840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 27840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 28840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/ADebug.h> 29840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/AMessage.h> 30840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/hexdump.h> 31840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/MediaDefs.h> 32840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/MediaErrors.h> 33840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/Utils.h> 34840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 3556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 36840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubernamespace android { 37840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 38840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic const char *Fourcc2String(uint32_t fourcc) { 39840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static char buffer[5]; 40840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber buffer[4] = '\0'; 41840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber buffer[0] = fourcc >> 24; 42840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber buffer[1] = (fourcc >> 16) & 0xff; 43840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber buffer[2] = (fourcc >> 8) & 0xff; 44840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber buffer[3] = fourcc & 0xff; 45840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 46840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return buffer; 47840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 48840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 49840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic const char *IndentString(size_t n) { 50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static const char kSpace[] = " "; 51840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return kSpace + sizeof(kSpace) - 2 * n - 1; 52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 53840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber// static 55cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenconst FragmentedMP4Parser::DispatchEntry FragmentedMP4Parser::kDispatchTable[] = { 56840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'o', 'o', 'v'), 0, NULL }, 57840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'r', 'a', 'k'), FOURCC('m', 'o', 'o', 'v'), NULL }, 58840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('u', 'd', 't', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL }, 59840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('u', 'd', 't', 'a'), FOURCC('m', 'o', 'o', 'v'), NULL }, 60840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'e', 't', 'a'), FOURCC('u', 'd', 't', 'a'), NULL }, 61840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('i', 'l', 's', 't'), FOURCC('m', 'e', 't', 'a'), NULL }, 62840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 63840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'k', 'h', 'd'), FOURCC('t', 'r', 'a', 'k'), 64cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseTrackHeader 65840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 66840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 67840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'v', 'e', 'x'), FOURCC('m', 'o', 'o', 'v'), NULL }, 68840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 69840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'r', 'e', 'x'), FOURCC('m', 'v', 'e', 'x'), 70cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseTrackExtends 71840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 72840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 73840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('e', 'd', 't', 's'), FOURCC('t', 'r', 'a', 'k'), NULL }, 74840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'd', 'i', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL }, 75840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 76840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'd', 'h', 'd'), FOURCC('m', 'd', 'i', 'a'), 77cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseMediaHeader 78840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 79840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 80840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('h', 'd', 'l', 'r'), FOURCC('m', 'd', 'i', 'a'), 81cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseMediaHandler 82840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 83840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 84840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'i', 'n', 'f'), FOURCC('m', 'd', 'i', 'a'), NULL }, 85840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('d', 'i', 'n', 'f'), FOURCC('m', 'i', 'n', 'f'), NULL }, 86840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 'b', 'l'), FOURCC('m', 'i', 'n', 'f'), NULL }, 87840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 's', 'd'), FOURCC('s', 't', 'b', 'l'), NULL }, 88840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 89840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 's', 'z'), FOURCC('s', 't', 'b', 'l'), 90cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseSampleSizes }, 91840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 'z', '2'), FOURCC('s', 't', 'b', 'l'), 93cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseCompactSampleSizes }, 94840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 95840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 's', 'c'), FOURCC('s', 't', 'b', 'l'), 96cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseSampleToChunk }, 97840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 98840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('s', 't', 'c', 'o'), FOURCC('s', 't', 'b', 'l'), 99cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseChunkOffsets }, 100840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 101840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('c', 'o', '6', '4'), FOURCC('s', 't', 'b', 'l'), 102cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseChunkOffsets64 }, 103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 104840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('a', 'v', 'c', 'C'), FOURCC('a', 'v', 'c', '1'), 105cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseAVCCodecSpecificData }, 106840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 107840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'a'), 108cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseESDSCodecSpecificData }, 109840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 110840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'v'), 111cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseESDSCodecSpecificData }, 112840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 113cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen { FOURCC('m', 'd', 'a', 't'), 0, &FragmentedMP4Parser::parseMediaData }, 114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'o', 'o', 'f'), 0, NULL }, 116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'r', 'a', 'f'), FOURCC('m', 'o', 'o', 'f'), NULL }, 117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'f', 'h', 'd'), FOURCC('t', 'r', 'a', 'f'), 119cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseTrackFragmentHeader 120840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('t', 'r', 'u', 'n'), FOURCC('t', 'r', 'a', 'f'), 122cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen &FragmentedMP4Parser::parseTrackFragmentRun 123840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }, 124840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 125840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { FOURCC('m', 'f', 'r', 'a'), 0, NULL }, 12656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 12756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen { FOURCC('s', 'i', 'd', 'x'), 0, &FragmentedMP4Parser::parseSegmentIndex }, 128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}; 129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 130cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstruct FileSource : public FragmentedMP4Parser::Source { 131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber FileSource(const char *filename) 132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mFile(fopen(filename, "rb")) { 133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(mFile != NULL); 134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 136442d83cfb731bc0a8d1bb2d41ecd242ec498893fYou Kim virtual ~FileSource() { 137442d83cfb731bc0a8d1bb2d41ecd242ec498893fYou Kim fclose(mFile); 138442d83cfb731bc0a8d1bb2d41ecd242ec498893fYou Kim } 139442d83cfb731bc0a8d1bb2d41ecd242ec498893fYou Kim 140840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber fseek(mFile, offset, SEEK_SET); 142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return fread(data, 1, size, mFile); 143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 144840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 14556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen virtual bool isSeekable() { 14656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return true; 14756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 14856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 149840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber private: 150840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber FILE *mFile; 151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 152840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(FileSource); 153840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}; 154840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 15556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstruct ReadTracker : public RefBase { 15656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ReadTracker(off64_t size) { 15756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen allocSize = 1 + size / 8192; // 1 bit per kilobyte 15856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bitmap = (char*) calloc(1, allocSize); 15956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 16056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen virtual ~ReadTracker() { 16156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen dumpToLog(); 16256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen free(bitmap); 16356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 16456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen void mark(off64_t offset, size_t size) { 16556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int firstbit = offset / 1024; 16656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int lastbit = (offset + size - 1) / 1024; 16756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int i = firstbit; i <= lastbit; i++) { 16856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bitmap[i/8] |= (0x80 >> (i & 7)); 16956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 17056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 17156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 17256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen private: 17356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen void dumpToLog() { 17456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // 96 chars per line, each char represents one kilobyte, 1 kb per bit 17556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numlines = allocSize / 12; 17656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char buf[97]; 17756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char *cur = bitmap; 17856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int i = 0; i < numlines; i++ && cur) { 17956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int j = 0; j < 12; j++) { 18056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int k = 0; k < 8; k++) { 18156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen buf[(j * 8) + k] = (*cur & (0x80 >> k)) ? 'X' : '.'; 18256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 18356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen cur++; 18456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 18556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen buf[96] = '\0'; 18656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGI("%5dk: %s", i * 96, buf); 18756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 18856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 18956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 19056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t allocSize; 19156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char *bitmap; 19256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}; 19356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 19456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstruct DataSourceSource : public FragmentedMP4Parser::Source { 19556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen DataSourceSource(sp<DataSource> &source) 19656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen : mDataSource(source) { 19756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(mDataSource != NULL); 19856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0 19956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen off64_t size; 20056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (source->getSize(&size) == OK) { 20156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mReadTracker = new ReadTracker(size); 20256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 20356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGE("couldn't get data source size"); 20456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 20556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif 20656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 20756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 20856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 20956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mReadTracker != NULL) { 21056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mReadTracker->mark(offset, size); 21156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 21256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return mDataSource->readAt(offset, data, size); 21356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 21456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 21556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen virtual bool isSeekable() { 21656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return true; 21756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 21856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 21956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen private: 22056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<DataSource> mDataSource; 22156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ReadTracker> mReadTracker; 22256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 22356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen DISALLOW_EVIL_CONSTRUCTORS(DataSourceSource); 22456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}; 22556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 226cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::FragmentedMP4Parser() 227840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : mBufferPos(0), 228c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber mSuspended(false), 22956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mDoneWithMoov(false), 23056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mFirstMoofOffset(0), 231c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber mFinalResult(OK) { 232840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 233840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 234cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::~FragmentedMP4Parser() { 235840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 236840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 237cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::start(const char *filename) { 238840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> msg = new AMessage(kWhatStart, id()); 239840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->setObject("source", new FileSource(filename)); 240840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->post(); 24156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("Parser::start(%s)", filename); 242840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 243840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 244cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::start(const sp<Source> &source) { 245840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> msg = new AMessage(kWhatStart, id()); 246840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->setObject("source", source); 247840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->post(); 24856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("Parser::start(Source)"); 24956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 25056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 25156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid FragmentedMP4Parser::start(sp<DataSource> &source) { 25256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> msg = new AMessage(kWhatStart, id()); 25356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->setObject("source", new DataSourceSource(source)); 25456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->post(); 25556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("Parser::start(DataSource)"); 256840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 257840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 25856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissensp<AMessage> FragmentedMP4Parser::getFormat(bool audio, bool synchronous) { 259840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 26056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen while (true) { 26156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bool moovDone = mDoneWithMoov; 26256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> msg = new AMessage(kWhatGetFormat, id()); 26356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->setInt32("audio", audio); 264840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 26556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> response; 26656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen status_t err = msg->postAndAwaitResponse(&response); 267840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 26856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (err != OK) { 26956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("getFormat post failed: %d", err); 27056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return NULL; 27156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 27256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 27356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (response->findInt32("err", &err) && err != OK) { 27456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (synchronous && err == -EWOULDBLOCK && !moovDone) { 27556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen resumeIfNecessary(); 27656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("@getFormat parser not ready yet, retrying"); 27756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen usleep(10000); 27856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen continue; 27956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 28056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("getFormat failed: %d", err); 28156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return NULL; 28256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 283840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 28456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> format; 28556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(response->findMessage("format", &format)); 286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 28756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("returning format %s", format->debugString().c_str()); 28856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return format; 28956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 290840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 291840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 29256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatus_t FragmentedMP4Parser::seekTo(bool wantAudio, int64_t timeUs) { 29356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> msg = new AMessage(kWhatSeekTo, id()); 29456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->setInt32("audio", wantAudio); 29556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->setInt64("position", timeUs); 296840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 297840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> response; 298840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 29956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return err; 30056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 301840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 30256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenbool FragmentedMP4Parser::isSeekable() const { 30356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen while (mFirstMoofOffset == 0 && mFinalResult == OK) { 30456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen usleep(10000); 30556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 30656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bool seekable = mSource->isSeekable(); 30756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (size_t i = 0; seekable && i < mTracks.size(); i++) { 30856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen const TrackInfo *info = &mTracks.valueAt(i); 30956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen seekable &= !info->mSidx.empty(); 310840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 31156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return seekable; 31256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 313840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 31456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatus_t FragmentedMP4Parser::onSeekTo(bool wantAudio, int64_t position) { 31556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen status_t err = -EINVAL; 31656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ssize_t trackIndex = findTrack(wantAudio); 31756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (trackIndex < 0) { 31856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen err = trackIndex; 31956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 32056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen TrackInfo *info = &mTracks.editValueAt(trackIndex); 32156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 32256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numSidxEntries = info->mSidx.size(); 32356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int64_t totalTime = 0; 32456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen off_t totalOffset = mFirstMoofOffset; 32556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int i = 0; i < numSidxEntries; i++) { 32656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen const SidxEntry *se = &info->mSidx[i]; 32786355f5b1ef6c6434d8717c71428e3165b0fe7b5Marco Nelissen if (totalTime + se->mDurationUs > position) { 32856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mBuffer->setRange(0,0); 32956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mBufferPos = totalOffset; 33056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mFinalResult == ERROR_END_OF_STREAM) { 33156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mFinalResult = OK; 33256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mSuspended = true; // force resume 33356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen resumeIfNecessary(); 33456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 33556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen info->mFragments.clear(); 33686355f5b1ef6c6434d8717c71428e3165b0fe7b5Marco Nelissen info->mDecodingTime = totalTime * info->mMediaTimeScale / 1000000ll; 33756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return OK; 33856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 33986355f5b1ef6c6434d8717c71428e3165b0fe7b5Marco Nelissen totalTime += se->mDurationUs; 34056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen totalOffset += se->mSize; 34156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 342840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 34356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("seekTo out of range"); 34456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return err; 34556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 346840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 34756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatus_t FragmentedMP4Parser::dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit, 34856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bool synchronous) { 349840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 35056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen while (true) { 35156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> msg = new AMessage(kWhatDequeueAccessUnit, id()); 35256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen msg->setInt32("audio", audio); 35356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 35456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> response; 35556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen status_t err = msg->postAndAwaitResponse(&response); 35656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 35756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (err != OK) { 35856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("dequeue fail 1: %d", err); 35956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return err; 36056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 36156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 36256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (response->findInt32("err", &err) && err != OK) { 36356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (synchronous && err == -EWOULDBLOCK) { 36456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen resumeIfNecessary(); 36556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("Parser not ready yet, retrying"); 36656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen usleep(10000); 36756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen continue; 36856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 36956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("dequeue fail 2: %d, %d", err, synchronous); 37056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return err; 37156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 37256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 37356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(response->findBuffer("accessUnit", accessUnit)); 37456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 37556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return OK; 37656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 377840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 378840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 379cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenssize_t FragmentedMP4Parser::findTrack(bool wantAudio) const { 380840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 381840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const TrackInfo *info = &mTracks.valueAt(i); 382840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 383840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool isAudio = 384840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mMediaHandlerType == FOURCC('s', 'o', 'u', 'n'); 385840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 386840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool isVideo = 387840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mMediaHandlerType == FOURCC('v', 'i', 'd', 'e'); 388840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 389840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((wantAudio && isAudio) || (!wantAudio && !isAudio)) { 390840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (info->mSampleDescs.empty()) { 391840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 392840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 393840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 394840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return i; 395840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 396840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 397840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 398840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EWOULDBLOCK; 399840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 400840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 401cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::onMessageReceived(const sp<AMessage> &msg) { 402840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (msg->what()) { 403840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case kWhatStart: 404840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 405840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<RefBase> obj; 406840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->findObject("source", &obj)); 407840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 408840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSource = static_cast<Source *>(obj.get()); 409840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 410840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer = new ABuffer(512 * 1024); 411840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->setRange(0, 0); 412840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 413bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber enter(0ll, 0, 0); 414840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 415840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (new AMessage(kWhatProceed, id()))->post(); 416840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 417840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 418840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 419840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case kWhatProceed: 420840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 421840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(!mSuspended); 422840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 423840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = onProceed(); 424840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 425840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err == OK) { 426840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!mSuspended) { 427840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->post(); 428840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 429840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (err != -EAGAIN) { 430840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGE("onProceed returned error %d", err); 431840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 432840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 433840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 434840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 435840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 436840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case kWhatReadMore: 437840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 438840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t needed; 439840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->findSize("needed", &needed)); 440840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 441840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memmove(mBuffer->base(), mBuffer->data(), mBuffer->size()); 442840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBufferPos += mBuffer->offset(); 443840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->setRange(0, mBuffer->size()); 444840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 445840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size(); 446b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 447b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber if (maxBytesToRead < needed) { 44856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("resizing buffer."); 449b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 450b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber sp<ABuffer> newBuffer = 451b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber new ABuffer((mBuffer->size() + needed + 1023) & ~1023); 452b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 453b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber newBuffer->setRange(0, mBuffer->size()); 454b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 455b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber mBuffer = newBuffer; 456b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber maxBytesToRead = mBuffer->capacity() - mBuffer->size(); 457b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber } 458b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 459840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_GE(maxBytesToRead, needed); 460840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 461840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ssize_t n = mSource->readAt( 462840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBufferPos + mBuffer->size(), 463840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->data() + mBuffer->size(), needed); 464840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 465840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (n < (ssize_t)needed) { 46656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("Reached EOF when reading %d @ %d + %d", needed, mBufferPos, mBuffer->size()); 467c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber if (n < 0) { 468c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber mFinalResult = n; 469c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber } else if (n == 0) { 470c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber mFinalResult = ERROR_END_OF_STREAM; 471c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber } else { 472c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber mFinalResult = ERROR_IO; 473c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber } 474840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 475840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->setRange(0, mBuffer->size() + n); 476840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (new AMessage(kWhatProceed, id()))->post(); 477840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 478840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 479840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 480840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 481840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 482840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case kWhatGetFormat: 483840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 484840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int32_t wantAudio; 485840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->findInt32("audio", &wantAudio)); 486840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 487840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = -EWOULDBLOCK; 488840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> response = new AMessage; 489840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 490840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ssize_t trackIndex = findTrack(wantAudio); 491840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 492840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (trackIndex < 0) { 493840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = trackIndex; 494840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 495840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = &mTracks.editValueAt(trackIndex); 496840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 49756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> format = info->mSampleDescs.itemAt(0).mFormat; 49856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (info->mSidxDuration) { 49956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen format->setInt64("durationUs", info->mSidxDuration); 50056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 50156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // this is probably going to be zero. Oh well... 50256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen format->setInt64("durationUs", 50356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 1000000ll * info->mDuration / info->mMediaTimeScale); 50456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 505840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->setMessage( 50656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen "format", format); 507840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 508840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = OK; 509840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 510840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 511840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->setInt32("err", err); 512840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 513840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t replyID; 514840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 515840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 516840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->postReply(replyID); 517840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 518840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 519840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 520840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case kWhatDequeueAccessUnit: 521840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 522840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int32_t wantAudio; 523840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->findInt32("audio", &wantAudio)); 524840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 525840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = -EWOULDBLOCK; 526840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> response = new AMessage; 527840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 528840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ssize_t trackIndex = findTrack(wantAudio); 529840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 530840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (trackIndex < 0) { 531840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = trackIndex; 532840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 533840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<ABuffer> accessUnit; 534840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = onDequeueAccessUnit(trackIndex, &accessUnit); 535840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 536840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err == OK) { 537840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->setBuffer("accessUnit", accessUnit); 538840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 539840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 540840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 541840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->setInt32("err", err); 542840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 543840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t replyID; 544840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 545840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 546840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber response->postReply(replyID); 547840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 548840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 549840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 55056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen case kWhatSeekTo: 55156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen { 55256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("kWhatSeekTo"); 55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t wantAudio; 55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(msg->findInt32("audio", &wantAudio)); 55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int64_t position; 55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(msg->findInt64("position", &position)); 55756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen status_t err = -EWOULDBLOCK; 55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<AMessage> response = new AMessage; 56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ssize_t trackIndex = findTrack(wantAudio); 56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 56356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (trackIndex < 0) { 56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen err = trackIndex; 56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen err = onSeekTo(wantAudio, position); 56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen response->setInt32("err", err); 56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t replyID; 57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(msg->senderAwaitsResponse(&replyID)); 57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen response->postReply(replyID); 57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen break; 57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 574840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 575840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TRESPASS(); 576840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 577840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 578840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 579cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::onProceed() { 580840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err; 581840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 582840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(8)) != OK) { 583840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 584840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 585840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 586840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint64_t size = readU32(0); 587840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type = readU32(4); 588840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 589840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t offset = 8; 590840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 591840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size == 1) { 592840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(16)) != OK) { 593840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 594840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 595840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 596840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size = readU64(offset); 597840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 8; 598840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 599840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 600840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint8_t userType[16]; 601840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 602840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (type == FOURCC('u', 'u', 'i', 'd')) { 603840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(offset + 16)) != OK) { 604840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 605840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 606840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 607840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy(userType, mBuffer->data() + offset, 16); 608840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 16; 609840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 610840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 611840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(!mStack.isEmpty()); 612840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t ptype = mStack.itemAt(mStack.size() - 1).mType; 613840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 614840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static const size_t kNumDispatchers = 615840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sizeof(kDispatchTable) / sizeof(kDispatchTable[0]); 616840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 617840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t i; 618840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (i = 0; i < kNumDispatchers; ++i) { 619840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (kDispatchTable[i].mType == type 620840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber && kDispatchTable[i].mParentType == ptype) { 621840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 622840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 623840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 624840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 625840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // SampleEntry boxes are container boxes that start with a variable 626840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // amount of data depending on the media handler type. 627840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // We don't look inside 'hint' type SampleEntry boxes. 628840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 629840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool isSampleEntryBox = 630840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (ptype == FOURCC('s', 't', 's', 'd')) 631840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber && editTrack(mCurrentTrackID)->mMediaHandlerType 632840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber != FOURCC('h', 'i', 'n', 't'); 633840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 634840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((i < kNumDispatchers && kDispatchTable[i].mHandler == 0) 635840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber || isSampleEntryBox || ptype == FOURCC('i', 'l', 's', 't')) { 636840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // This is a container box. 63756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (type == FOURCC('m', 'o', 'o', 'f')) { 63856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mFirstMoofOffset == 0) { 63956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("first moof @ %08x", mBufferPos + offset); 64056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mFirstMoofOffset = mBufferPos + offset - 8; // point at the size 64156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 64256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 643840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (type == FOURCC('m', 'e', 't', 'a')) { 644840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(offset + 4)) < OK) { 645840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 646840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 647840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 648840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (readU32(offset) != 0) { 649840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 650840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 651840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 652840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 653840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (type == FOURCC('s', 't', 's', 'd')) { 654840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(offset + 8)) < OK) { 655840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 656840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 657840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 658840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (readU32(offset) != 0) { 659840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 660840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 661840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 662840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (readU32(offset + 4) == 0) { 663840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // We need at least some entries. 664840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 665840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 666840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 667840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 8; 668840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (isSampleEntryBox) { 669840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t headerSize; 670840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 671840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (editTrack(mCurrentTrackID)->mMediaHandlerType) { 672840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('v', 'i', 'd', 'e'): 673840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 674840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // 8 bytes SampleEntry + 70 bytes VisualSampleEntry 675840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber headerSize = 78; 676840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 677840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 678840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 679840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('s', 'o', 'u', 'n'): 680840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 681840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // 8 bytes SampleEntry + 20 bytes AudioSampleEntry 682840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber headerSize = 28; 683840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 684840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 685840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 686840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('m', 'e', 't', 'a'): 687840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 688840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber headerSize = 8; // 8 bytes SampleEntry 689840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 690840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 691840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 692840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 693840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TRESPASS(); 694840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 695840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 696840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + headerSize > size) { 697840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 698840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 699840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 700840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(offset + headerSize)) != OK) { 701840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 702840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 703840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 704840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (editTrack(mCurrentTrackID)->mMediaHandlerType) { 705840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('v', 'i', 'd', 'e'): 706840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 707840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = parseVisualSampleEntry( 708840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber type, offset, offset + headerSize); 709840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 710840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 711840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 712840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('s', 'o', 'u', 'n'): 713840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 714840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = parseAudioSampleEntry( 715840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber type, offset, offset + headerSize); 716840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 717840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 718840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 719840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('m', 'e', 't', 'a'): 720840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber { 721840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = OK; 722840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 723840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 724840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 725840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 726840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TRESPASS(); 727840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 728840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 729840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err != OK) { 730840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 731840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 732840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 733840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += headerSize; 734840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 735840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 736840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber skip(offset); 737840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 738840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("%sentering box of type '%s'", 739840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber IndentString(mStack.size()), Fourcc2String(type)); 740840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 741bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber enter(mBufferPos - offset, type, size - offset); 742840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 743840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!fitsContainer(size)) { 744840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 745840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 746840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 747840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (i < kNumDispatchers && kDispatchTable[i].mHandler != 0) { 748840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // We have a handler for this box type. 749840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 750840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = need(size)) != OK) { 751840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 752840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 753840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 754840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("%sparsing box of type '%s'", 755840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber IndentString(mStack.size()), Fourcc2String(type)); 756840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 757840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((err = (this->*kDispatchTable[i].mHandler)( 758840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber type, offset, size)) != OK) { 759840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 760840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 761840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 762840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // Unknown box type 763840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 764840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("%sskipping box of type '%s', size %llu", 765840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber IndentString(mStack.size()), 766840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Fourcc2String(type), size); 767840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 768840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 769840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 770840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber skip(size); 771840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 772840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 773840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 774840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 775840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 776840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber// static 777cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenint FragmentedMP4Parser::CompareSampleLocation( 778840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const SampleInfo &sample, const MediaDataInfo &mdatInfo) { 779840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sample.mOffset + sample.mSize < mdatInfo.mOffset) { 780840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -1; 781840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 782840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 783840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sample.mOffset >= mdatInfo.mOffset + mdatInfo.mBuffer->size()) { 784840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return 1; 785840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 786840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 787840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // Otherwise make sure the sample is completely contained within this 788840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // media data block. 789840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 790840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_GE(sample.mOffset, mdatInfo.mOffset); 791840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 792840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_LE(sample.mOffset + sample.mSize, 793840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mdatInfo.mOffset + mdatInfo.mBuffer->size()); 794840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 795840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return 0; 796840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 797840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 798cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::resumeIfNecessary() { 799840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!mSuspended) { 800840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 801840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 802840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 80356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("resuming."); 804840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 805840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSuspended = false; 806840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (new AMessage(kWhatProceed, id()))->post(); 807840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 808840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 809cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::getSample( 810840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info, sp<TrackFragment> *fragment, SampleInfo *sampleInfo) { 811840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (;;) { 812840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (info->mFragments.empty()) { 813c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber if (mFinalResult != OK) { 814c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber return mFinalResult; 815c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber } 816c7708555ea7511aea684e00a55fb5309281540ceAndreas Huber 817840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber resumeIfNecessary(); 818840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EWOULDBLOCK; 819840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 820840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 821840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *fragment = *info->mFragments.begin(); 822840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 823840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = (*fragment)->getSample(sampleInfo); 824840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 825840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err == OK) { 826840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 827840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (err != ERROR_END_OF_STREAM) { 828840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 829840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 830840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 831840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // Really, end of this fragment... 832840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 833840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mFragments.erase(info->mFragments.begin()); 834840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 835840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 836840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 837cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::onDequeueAccessUnit( 838840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t trackIndex, sp<ABuffer> *accessUnit) { 839840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = &mTracks.editValueAt(trackIndex); 840840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 841840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<TrackFragment> fragment; 842840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleInfo sampleInfo; 843840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber status_t err = getSample(info, &fragment, &sampleInfo); 844840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 845840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err == -EWOULDBLOCK) { 846840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber resumeIfNecessary(); 847840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 848840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (err != OK) { 849840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 850840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 851840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 852840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = -EWOULDBLOCK; 853840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 854840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool checkDroppable = false; 855840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 856840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; i < mMediaData.size(); ++i) { 857840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const MediaDataInfo &mdatInfo = mMediaData.itemAt(i); 858840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 859840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int cmp = CompareSampleLocation(sampleInfo, mdatInfo); 860840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 86156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (cmp < 0 && !mSource->isSeekable()) { 862840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EPIPE; 863840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (cmp == 0) { 864840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (i > 0) { 865840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber checkDroppable = true; 866840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 867840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 868840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = makeAccessUnit(info, sampleInfo, mdatInfo, accessUnit); 869840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 870840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 871840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 872840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 873840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err != OK) { 874840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 875840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 876840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 877840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber fragment->advance(); 878840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 879840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!mMediaData.empty() && checkDroppable) { 880840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t numDroppable = 0; 881840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool done = false; 882840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 88356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // XXX FIXME: if one of the tracks is not advanced (e.g. if you play an audio+video 88456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // file with sf2), then mMediaData will not be pruned and keeps growing 885840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; !done && i < mMediaData.size(); ++i) { 886840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const MediaDataInfo &mdatInfo = mMediaData.itemAt(i); 887840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 888840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t j = 0; j < mTracks.size(); ++j) { 889840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = &mTracks.editValueAt(j); 890840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 891840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<TrackFragment> fragment; 892840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleInfo sampleInfo; 893840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber err = getSample(info, &fragment, &sampleInfo); 894840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 895840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (err != OK) { 896840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber done = true; 897840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 898840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 899840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 900840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int cmp = CompareSampleLocation(sampleInfo, mdatInfo); 901840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 902840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (cmp <= 0) { 903840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber done = true; 904840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 905840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 906840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 907840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 908840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!done) { 909840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++numDroppable; 910840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 911840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 912840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 913840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (numDroppable > 0) { 914840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mMediaData.removeItemsAt(0, numDroppable); 915840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 916840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mMediaData.size() < 5) { 917840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber resumeIfNecessary(); 918840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 919840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 920840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 921840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 922840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return err; 923840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 924840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 925840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic size_t parseNALSize(size_t nalLengthSize, const uint8_t *data) { 926840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (nalLengthSize) { 927840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 1: 928840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return *data; 929840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 2: 930840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return U16_AT(data); 931840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 3: 932840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 933840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case 4: 934840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return U32_AT(data); 935840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 936840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 937840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 938840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // a 2-bit integer. 939840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TRESPASS(); 940840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 941840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return 0; 942840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 943840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 944cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::makeAccessUnit( 945840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info, 946840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const SampleInfo &sample, 947840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const MediaDataInfo &mdatInfo, 948840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<ABuffer> *accessUnit) { 949840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sample.mSampleDescIndex < 1 950840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber || sample.mSampleDescIndex > info->mSampleDescs.size()) { 951840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 952840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 953840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 954840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int64_t presentationTimeUs = 955840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1000000ll * sample.mPresentationTime / info->mMediaTimeScale; 956840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 957840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const SampleDescription &sampleDesc = 958840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mSampleDescs.itemAt(sample.mSampleDescIndex - 1); 959840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 960840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t nalLengthSize; 961840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!sampleDesc.mFormat->findSize("nal-length-size", &nalLengthSize)) { 962840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *accessUnit = new ABuffer(sample.mSize); 963840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 964840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy((*accessUnit)->data(), 965840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset), 966840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sample.mSize); 967840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 968840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs); 9698c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (IsIDR(*accessUnit)) { 9708c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen (*accessUnit)->meta()->setInt32("is-sync-frame", 1); 9718c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 9728c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 973840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 974840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 975840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 976840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *srcPtr = 977840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset); 978840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 979840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (int i = 0; i < 2 ; ++i) { 980840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t srcOffset = 0; 981840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t dstOffset = 0; 982840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 983840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber while (srcOffset < sample.mSize) { 984840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (srcOffset + nalLengthSize > sample.mSize) { 985840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 986840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 987840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 988840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t nalSize = parseNALSize(nalLengthSize, &srcPtr[srcOffset]); 989840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber srcOffset += nalLengthSize; 990840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 991840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (srcOffset + nalSize > sample.mSize) { 992840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 993840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 994840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 995840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (i == 1) { 996840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy((*accessUnit)->data() + dstOffset, 997840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber "\x00\x00\x00\x01", 998840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 4); 999840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1000840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy((*accessUnit)->data() + dstOffset + 4, 1001840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber srcPtr + srcOffset, 1002840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber nalSize); 1003840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1004840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1005840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber srcOffset += nalSize; 1006840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber dstOffset += nalSize + 4; 1007840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1008840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1009840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (i == 0) { 1010840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (*accessUnit) = new ABuffer(dstOffset); 1011840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (*accessUnit)->meta()->setInt64( 1012840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber "timeUs", presentationTimeUs); 1013840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1014840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 10158c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (IsIDR(*accessUnit)) { 10168c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen (*accessUnit)->meta()->setInt32("is-sync-frame", 1); 10178c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 1018840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1019840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1020840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1021840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1022cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::need(size_t size) { 1023840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!fitsContainer(size)) { 1024840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1025840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1026840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1027840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size <= mBuffer->size()) { 1028840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1029840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1030840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1031840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> msg = new AMessage(kWhatReadMore, id()); 1032840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->setSize("needed", size - mBuffer->size()); 1033840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber msg->post(); 1034840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1035840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // ALOGV("need(%d) returning -EAGAIN, only have %d", size, mBuffer->size()); 1036840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1037840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EAGAIN; 1038840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1039840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1040cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::enter(off64_t offset, uint32_t type, uint64_t size) { 1041840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Container container; 1042bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber container.mOffset = offset; 1043840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber container.mType = type; 1044840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber container.mExtendsToEOF = (size == 0); 1045840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber container.mBytesRemaining = size; 1046840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1047840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mStack.push(container); 1048840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1049840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1050cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenbool FragmentedMP4Parser::fitsContainer(uint64_t size) const { 1051840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(!mStack.isEmpty()); 1052840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const Container &container = mStack.itemAt(mStack.size() - 1); 1053840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1054840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return container.mExtendsToEOF || size <= container.mBytesRemaining; 1055840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1056840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1057cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenuint16_t FragmentedMP4Parser::readU16(size_t offset) { 1058840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_LE(offset + 2, mBuffer->size()); 1059840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1060840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *ptr = mBuffer->data() + offset; 1061840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return (ptr[0] << 8) | ptr[1]; 1062840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1063840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1064cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenuint32_t FragmentedMP4Parser::readU32(size_t offset) { 1065840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_LE(offset + 4, mBuffer->size()); 1066840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1067840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *ptr = mBuffer->data() + offset; 1068840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; 1069840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1070840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1071cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenuint64_t FragmentedMP4Parser::readU64(size_t offset) { 1072840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return (((uint64_t)readU32(offset)) << 32) | readU32(offset + 4); 1073840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1074840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1075cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::skip(off_t distance) { 1076840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(!mStack.isEmpty()); 1077840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = mStack.size(); i-- > 0;) { 1078840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Container *container = &mStack.editItemAt(i); 1079840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!container->mExtendsToEOF) { 1080840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK_LE(distance, (off_t)container->mBytesRemaining); 1081840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1082840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber container->mBytesRemaining -= distance; 1083840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1084840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (container->mBytesRemaining == 0) { 1085840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("%sleaving box of type '%s'", 1086840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber IndentString(mStack.size() - 1), 1087840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber Fourcc2String(container->mType)); 1088840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1089840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#if 0 1090840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (container->mType == FOURCC('s', 't', 's', 'd')) { 1091840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1092840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; 1093840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber i < trackInfo->mSampleDescs.size(); ++i) { 1094840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGI("format #%d: %s", 1095840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber i, 1096840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.itemAt(i) 1097840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber .mFormat->debugString().c_str()); 1098840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1099840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1100840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#endif 1101840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1102840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (container->mType == FOURCC('s', 't', 'b', 'l')) { 1103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1104840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1105840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mStaticFragment->signalCompletion(); 1106840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1107840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(trackInfo->mFragments.empty()); 1108840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mFragments.push_back(trackInfo->mStaticFragment); 1109840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mStaticFragment.clear(); 1110840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (container->mType == FOURCC('t', 'r', 'a', 'f')) { 1111840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = 1112840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber editTrack(mTrackFragmentHeaderInfo.mTrackID); 1113840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const sp<TrackFragment> &fragment = 1115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *--trackInfo->mFragments.end(); 1116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static_cast<DynamicTrackFragment *>( 1118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber fragment.get())->signalCompletion(); 111956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else if (container->mType == FOURCC('m', 'o', 'o', 'v')) { 112056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen mDoneWithMoov = true; 1121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1122840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1123840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber container = NULL; 1124840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mStack.removeItemsAt(i); 1125840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1126840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (distance < (off_t)mBuffer->size()) { 1130840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->setRange(mBuffer->offset() + distance, mBuffer->size() - distance); 1131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBufferPos += distance; 1132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return; 1133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBuffer->setRange(0, 0); 1136840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBufferPos += distance; 1137840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1138840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1139cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseTrackHeader( 1140840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1144840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1145840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t flags = readU32(offset); 1146840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1147840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t version = flags >> 24; 1148840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber flags &= 0xffffff; 1149840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1150840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t trackID; 1151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint64_t duration; 1152840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1153840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (version == 1) { 1154840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 36 > size) { 1155840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1156840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1157840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1158840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackID = readU32(offset + 20); 1159840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber duration = readU64(offset + 28); 1160840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1161840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 36; 1162840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (version == 0) { 1163840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 24 > size) { 1164840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1165840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1166840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1167840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackID = readU32(offset + 12); 1168840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber duration = readU32(offset + 20); 1169840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1170840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 24; 1171840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1172840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1173840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1174840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1175840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = editTrack(trackID, true /* createIfNecessary */); 1176840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mFlags = flags; 1177840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDuration = duration; 117856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (info->mDuration == 0xffffffff) { 117956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // ffmpeg sets this to -1, which is incorrect. 118056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen info->mDuration = 0; 118156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 1182840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1183840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mStaticFragment = new StaticTrackFragment; 1184840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1185840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mCurrentTrackID = trackID; 1186840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1187840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1188840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1189840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1190cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseMediaHeader( 1191840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1192840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1193840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1194840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1195840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1196840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t versionAndFlags = readU32(offset); 1197840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1198840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (versionAndFlags & 0xffffff) { 1199840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1200840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1201840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1202840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t version = versionAndFlags >> 24; 1203840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1204840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = editTrack(mCurrentTrackID); 1205840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1206840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (version == 1) { 1207840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 + 32 > size) { 1208840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1209840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1210840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 20); 1211840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (version == 0) { 1212840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 + 20 > size) { 1213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1214840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1215840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 12); 1216840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1217840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1218840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1219840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1220840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1221840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1222840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1223cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseMediaHandler( 1224840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1225840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 12 > size) { 1226840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1227840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1228840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1229840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (readU32(offset) != 0) { 1230840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1231840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1232840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1233840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t handlerType = readU32(offset + 8); 1234840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1235840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (handlerType) { 1236840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('v', 'i', 'd', 'e'): 1237840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('s', 'o', 'u', 'n'): 1238840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('h', 'i', 'n', 't'): 1239840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('m', 'e', 't', 'a'): 1240840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1241840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1242840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 1243840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1244840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1245840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1246840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber editTrack(mCurrentTrackID)->mMediaHandlerType = handlerType; 1247840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1248840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1249840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1250840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1251cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseVisualSampleEntry( 1252840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1253840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 78 > size) { 1254840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1255840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1256840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1257840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1258840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1259840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.push(); 1260840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleDescription *sampleDesc = 1261840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber &trackInfo->mSampleDescs.editItemAt( 1262840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.size() - 1); 1263840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1264840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mType = type; 1265840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mDataRefIndex = readU16(offset + 6); 1266840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1267840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> format = new AMessage; 1268840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1269840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (type) { 1270840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('a', 'v', 'c', '1'): 1271840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 1272840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1273840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('m', 'p', '4', 'v'): 1274840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); 1275840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1276b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber case FOURCC('s', '2', '6', '3'): 1277b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber case FOURCC('h', '2', '6', '3'): 1278b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber case FOURCC('H', '2', '6', '3'): 1279b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); 1280b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber break; 1281840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 1282840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", "application/octet-stream"); 1283840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1284840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1285840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("width", readU16(offset + 8 + 16)); 1287840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("height", readU16(offset + 8 + 18)); 1288840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1289840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat = format; 1290840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1291840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1292840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1293840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1294cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseAudioSampleEntry( 1295840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1296840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 28 > size) { 1297840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1298840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1299840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1300840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1301840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1302840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.push(); 1303840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleDescription *sampleDesc = 1304840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber &trackInfo->mSampleDescs.editItemAt( 1305840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.size() - 1); 1306840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1307840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mType = type; 1308840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mDataRefIndex = readU16(offset + 6); 1309840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1310840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<AMessage> format = new AMessage; 1311840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1312840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("channel-count", readU16(offset + 8 + 8)); 1313840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("sample-size", readU16(offset + 8 + 10)); 1314840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("sample-rate", readU32(offset + 8 + 16) / 65536.0f); 1315840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1316840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber switch (type) { 1317840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('m', 'p', '4', 'a'): 1318840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 1319840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1320b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 1321840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 1322840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 1323840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("channel-count", 1); 1324840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("sample-rate", 8000); 1325840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1326b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber 1327840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 1328840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 1329840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("channel-count", 1); 1330840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setInt32("sample-rate", 16000); 1331840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1332840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber default: 1333840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setString("mime", "application/octet-stream"); 1334840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 1335840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1336840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1337840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat = format; 1338840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1339840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1340840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1341840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1342840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatic void addCodecSpecificData( 1343840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const sp<AMessage> &format, int32_t index, 1344840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const void *data, size_t size, 1345840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool insertStartCode = false) { 1346840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<ABuffer> csd = new ABuffer(insertStartCode ? size + 4 : size); 1347840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1348840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy(csd->data() + (insertStartCode ? 4 : 0), data, size); 1349840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1350840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (insertStartCode) { 1351840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 1352840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1353840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1354840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber csd->meta()->setInt32("csd", true); 1355840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber csd->meta()->setInt64("timeUs", 0ll); 1356840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1357840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber format->setBuffer(StringPrintf("csd-%d", index).c_str(), csd); 1358840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1359840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1360cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseSampleSizes( 1361840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1362840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleSizes( 1363840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber this, type, offset, size); 1364840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1365840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1366cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseCompactSampleSizes( 1367840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1368840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return editTrack(mCurrentTrackID)->mStaticFragment->parseCompactSampleSizes( 1369840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber this, type, offset, size); 1370840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1371840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1372cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseSampleToChunk( 1373840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1374840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleToChunk( 1375840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber this, type, offset, size); 1376840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1377840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1378cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseChunkOffsets( 1379840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1380840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets( 1381840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber this, type, offset, size); 1382840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1383840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1384cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseChunkOffsets64( 1385840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1386840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets64( 1387840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber this, type, offset, size); 1388840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1389840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1390cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseAVCCodecSpecificData( 1391840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1392840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1393840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1394840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleDescription *sampleDesc = 1395840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber &trackInfo->mSampleDescs.editItemAt( 1396840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.size() - 1); 1397840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1398840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sampleDesc->mType != FOURCC('a', 'v', 'c', '1')) { 1399840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1400840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1401840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1402840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *ptr = mBuffer->data() + offset; 1403840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1404840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= offset; 1405840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset = 0; 1406840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1407840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < 7 || ptr[0] != 0x01) { 1408840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1409840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1410840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1411840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat->setSize("nal-length-size", 1 + (ptr[4] & 3)); 1412840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1413840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t numSPS = ptr[5] & 31; 1414840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1415840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += 6; 1416840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= 6; 1417840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1418840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; i < numSPS; ++i) { 1419840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < 2) { 1420840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1421840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1422840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1423840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t length = U16_AT(ptr); 1424840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1425840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += 2; 1426840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= 2; 1427840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1428840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < length) { 1429840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1430840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1431840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1432840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber addCodecSpecificData( 1433840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat, i, ptr, length, 1434840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber true /* insertStartCode */); 1435840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1436840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += length; 1437840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= length; 1438840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1439840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1440840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < 1) { 1441840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1442840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1443840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1444840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t numPPS = *ptr; 1445840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ++ptr; 1446840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber --size; 1447840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1448840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0; i < numPPS; ++i) { 1449840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < 2) { 1450840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1451840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1452840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1453840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t length = U16_AT(ptr); 1454840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1455840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += 2; 1456840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= 2; 1457840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1458840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < length) { 1459840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1460840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1461840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1462840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber addCodecSpecificData( 1463840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat, numSPS + i, ptr, length, 1464840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber true /* insertStartCode */); 1465840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1466840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += length; 1467840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= length; 1468840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1469840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1470840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1471840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1472840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1473cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseESDSCodecSpecificData( 1474840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1475840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mCurrentTrackID); 1476840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1477840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber SampleDescription *sampleDesc = 1478840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber &trackInfo->mSampleDescs.editItemAt( 1479840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mSampleDescs.size() - 1); 1480840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1481840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a') 1482840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber && sampleDesc->mType != FOURCC('m', 'p', '4', 'v')) { 1483840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1484840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1485840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1486840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *ptr = mBuffer->data() + offset; 1487840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1488840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -= offset; 1489840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset = 0; 1490840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1491840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (size < 4) { 1492840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1493840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1494840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1495840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (U32_AT(ptr) != 0) { 1496840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1497840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1498840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1499840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ptr += 4; 1500840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size -=4; 1501840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1502840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ESDS esds(ptr, size); 1503840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1504840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint8_t objectTypeIndication; 1505840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1506840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1507840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1508840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1509840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const uint8_t *csd; 1510840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t csd_size; 1511840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (esds.getCodecSpecificInfo( 1512840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (const void **)&csd, &csd_size) != OK) { 1513840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1514840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1515840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1516840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber addCodecSpecificData(sampleDesc->mFormat, 0, csd, csd_size); 1517840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1518840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')) { 1519840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1520840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1521840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1522840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (csd_size == 0) { 1523840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // There's no further information, i.e. no codec specific data 1524840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // Let's assume that the information provided in the mpeg4 headers 1525840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // is accurate and hope for the best. 1526840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1527840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1528840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1529840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1530840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (csd_size < 2) { 1531840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1532840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1533840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1534840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t objectType = csd[0] >> 3; 1535840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1536840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (objectType == 31) { 1537840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_UNSUPPORTED; 1538840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1539840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1540840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1541840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int32_t sampleRate = 0; 1542840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int32_t numChannels = 0; 1543840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (freqIndex == 15) { 1544840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (csd_size < 5) { 1545840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1546840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1547840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1548840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleRate = (csd[1] & 0x7f) << 17 1549840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber | csd[2] << 9 1550840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber | csd[3] << 1 1551840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber | (csd[4] >> 7); 1552840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1553840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber numChannels = (csd[4] >> 3) & 15; 1554840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1555840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static uint32_t kSamplingRate[] = { 1556840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1557840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 16000, 12000, 11025, 8000, 7350 1558840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }; 1559840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1560840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (freqIndex == 13 || freqIndex == 14) { 1561840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_MALFORMED; 1562840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1563840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1564840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleRate = kSamplingRate[freqIndex]; 1565840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber numChannels = (csd[1] >> 3) & 15; 1566840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1567840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1568840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (numChannels == 0) { 1569840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return ERROR_UNSUPPORTED; 1570840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1571840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1572840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat->setInt32("sample-rate", sampleRate); 1573840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDesc->mFormat->setInt32("channel-count", numChannels); 1574840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1575840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1576840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1577840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1578cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseMediaData( 1579840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1580840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("skipping 'mdat' chunk at offsets 0x%08lx-0x%08llx.", 1581840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mBufferPos + offset, mBufferPos + size); 1582840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1583840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<ABuffer> buffer = new ABuffer(size - offset); 1584840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy(buffer->data(), mBuffer->data() + offset, size - offset); 1585840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1586840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mMediaData.push(); 1587840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber MediaDataInfo *info = &mMediaData.editItemAt(mMediaData.size() - 1); 1588840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mBuffer = buffer; 1589840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mOffset = mBufferPos + offset; 1590840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1591840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (mMediaData.size() > 10) { 159256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("suspending for now."); 1593840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mSuspended = true; 1594840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1595840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1596840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1597840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1598840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 159956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatus_t FragmentedMP4Parser::parseSegmentIndex( 160056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t type, size_t offset, uint64_t size) { 160156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("sidx box type %d, offset %d, size %d", type, int(offset), int(size)); 160256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen// AString sidxstr; 160356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen// hexdump(mBuffer->data() + offset, size, 0 /* indent */, &sidxstr); 160456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen// ALOGV("raw sidx:"); 160556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen// ALOGV("%s", sidxstr.c_str()); 160656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (offset + 12 > size) { 160756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 160856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 160956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 161056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t flags = readU32(offset); 161156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 161256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t version = flags >> 24; 161356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen flags &= 0xffffff; 161456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 161556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("sidx version %d", version); 161656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 161756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t referenceId = readU32(offset + 4); 161856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t timeScale = readU32(offset + 8); 161956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 162056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 162156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint64_t earliestPresentationTime; 162256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint64_t firstOffset; 162356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 162456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen offset += 12; 162556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 162656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (version == 0) { 162756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (offset + 8 > size) { 162856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 162956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 163056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen earliestPresentationTime = readU32(offset); 163156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen firstOffset = readU32(offset + 4); 163256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen offset += 8; 163356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 163456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (offset + 16 > size) { 163556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 163656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 163756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen earliestPresentationTime = readU64(offset); 163856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen firstOffset = readU64(offset + 8); 163956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen offset += 16; 164056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 164156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset); 164256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 164356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (offset + 4 > size) { 164456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 164556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 164656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (readU16(offset) != 0) { // reserved 164756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 164856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 164956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t referenceCount = readU16(offset + 2); 165056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen offset += 4; 165156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("refcount: %d", referenceCount); 165256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 165356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (offset + referenceCount * 12 > size) { 165456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return -EINVAL; 165556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 165656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 165756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen TrackInfo *info = editTrack(mCurrentTrackID); 165856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint64_t total_duration = 0; 165956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen for (int i = 0; i < referenceCount; i++) { 166056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t d1 = readU32(offset); 166156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t d2 = readU32(offset + 4); 166256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen uint32_t d3 = readU32(offset + 8); 166356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 166456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (d1 & 0x80000000) { 166556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("sub-sidx boxes not supported yet"); 166656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 166756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bool sap = d3 & 0x80000000; 166856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen bool saptype = d3 >> 28; 166956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (!sap || saptype > 2) { 167056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("not a stream access point, or unsupported type"); 167156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 167256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen total_duration += d2; 167356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen offset += 12; 167456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 167556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen SidxEntry se; 167656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen se.mSize = d1 & 0x7fffffff; 167756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen se.mDurationUs = 1000000LL * d2 / timeScale; 167856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen info->mSidx.add(se); 167956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 168056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 168156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen info->mSidxDuration = total_duration * 1000000 / timeScale; 168256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("duration: %lld", info->mSidxDuration); 168356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return OK; 168456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 168556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 1686cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseTrackExtends( 1687840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1688840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 24 > size) { 1689840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1690840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1691840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1692840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (readU32(offset) != 0) { 1693840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1694840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1695840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1696840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t trackID = readU32(offset + 4); 1697840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1698840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = editTrack(trackID, true /* createIfNecessary */); 1699840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDefaultSampleDescriptionIndex = readU32(offset + 8); 1700840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDefaultSampleDuration = readU32(offset + 12); 1701840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDefaultSampleSize = readU32(offset + 16); 1702840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDefaultSampleFlags = readU32(offset + 20); 1703840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1704840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1705840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1706840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1707cb1f88c684140ce0eb407049a78f889bc7d51be1Marco NelissenFragmentedMP4Parser::TrackInfo *FragmentedMP4Parser::editTrack( 1708840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t trackID, bool createIfNecessary) { 1709840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ssize_t i = mTracks.indexOfKey(trackID); 1710840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1711840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (i >= 0) { 1712840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return &mTracks.editValueAt(i); 1713840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1714840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1715840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!createIfNecessary) { 1716840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return NULL; 1717840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1718840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1719840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo info; 1720840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mTrackID = trackID; 1721840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mFlags = 0; 1722840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDuration = 0xffffffff; 172356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen info.mSidxDuration = 0; 1724840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mMediaTimeScale = 0; 1725840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mMediaHandlerType = 0; 1726840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDefaultSampleDescriptionIndex = 0; 1727840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDefaultSampleDuration = 0; 1728840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDefaultSampleSize = 0; 1729840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDefaultSampleFlags = 0; 1730840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1731840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info.mDecodingTime = 0; 1732840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1733840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTracks.add(trackID, info); 1734840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return &mTracks.editValueAt(mTracks.indexOfKey(trackID)); 1735840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1736840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1737cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseTrackFragmentHeader( 1738840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1739840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 1740840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1741840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1742840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1743840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t flags = readU32(offset); 1744840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1745840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & 0xff000000) { 1746840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1747840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1748840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1749840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mFlags = flags; 1750840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1751840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mTrackID = readU32(offset + 4); 1752840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 8; 1753840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1754840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 1755840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 1756840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1757840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1758840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1759840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mBaseDataOffset = readU64(offset); 1760840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 8; 1761840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1762840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1763840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 1764840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1765840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1766840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1767840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1768840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mSampleDescriptionIndex = readU32(offset); 1769840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1770840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1771840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1772840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 1773840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1774840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1775840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1776840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1777840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mDefaultSampleDuration = readU32(offset); 1778840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1779840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1780840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1781840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 1782840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1783840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1784840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1785840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1786840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mDefaultSampleSize = readU32(offset); 1787840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1788840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1789840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1790840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 1791840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1792840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1793840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1794840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1795840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mDefaultSampleFlags = readU32(offset); 1796840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1797840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1798840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1799840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 1800bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // This should point to the position of the first byte of the 1801bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // enclosing 'moof' container for the first track and 1802bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // the end of the data of the preceding fragment for subsequent 1803bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // tracks. 1804840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1805bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber CHECK_GE(mStack.size(), 2u); 1806840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1807840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mBaseDataOffset = 1808bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber mStack.itemAt(mStack.size() - 2).mOffset; 1809bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber 1810bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // XXX TODO: This does not do the right thing for the 2nd and 1811bd828233d3eda966bf7145108dde74616abd97fbAndreas Huber // subsequent tracks yet. 1812840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1813840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1814840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mDataOffset = 1815840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mBaseDataOffset; 1816840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1817840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *trackInfo = editTrack(mTrackFragmentHeaderInfo.mTrackID); 1818840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1819840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (trackInfo->mFragments.empty() 1820840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber || (*trackInfo->mFragments.begin())->complete()) { 1821840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber trackInfo->mFragments.push_back(new DynamicTrackFragment); 1822840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1823840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1824840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1825840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1826840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1827cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstatus_t FragmentedMP4Parser::parseTrackFragmentRun( 1828840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t type, size_t offset, uint64_t size) { 1829840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 8 > size) { 1830840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1831840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1832840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1833840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber enum { 1834840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kDataOffsetPresent = 0x01, 1835840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kFirstSampleFlagsPresent = 0x04, 1836840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kSampleDurationPresent = 0x100, 1837840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kSampleSizePresent = 0x200, 1838840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kSampleFlagsPresent = 0x400, 1839840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber kSampleCompositionTimeOffsetPresent = 0x800, 1840840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber }; 1841840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1842840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t flags = readU32(offset); 1843840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1844840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & 0xff000000) { 1845840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1846840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1847840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1848840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 1849840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber // These two shall not be used together. 1850840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1851840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1852840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1853840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleCount = readU32(offset + 4); 1854840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 8; 1855840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1856840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 1857840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1858840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t firstSampleFlags = 0; 1859840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1860840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kDataOffsetPresent) { 1861840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1862840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1863840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1864840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1865840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber int32_t dataOffsetDelta = (int32_t)readU32(offset); 1866840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1867840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 1868840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1869840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1870840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1871840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1872840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kFirstSampleFlagsPresent) { 1873840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + 4 > size) { 1874840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1875840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1876840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1877840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber firstSampleFlags = readU32(offset); 1878840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1879840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1880840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1881840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber TrackInfo *info = editTrack(mTrackFragmentHeaderInfo.mTrackID); 1882840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1883840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (info == NULL) { 1884840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1885840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1886840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1887840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 1888840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleCtsOffset = 0; 1889840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1890840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber size_t bytesPerSample = 0; 1891840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleDurationPresent) { 1892840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bytesPerSample += 4; 1893840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (mTrackFragmentHeaderInfo.mFlags 1894840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 1895840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 1896840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1897840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDuration = info->mDefaultSampleDuration; 1898840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1899840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1900840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleSizePresent) { 1901840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bytesPerSample += 4; 1902840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (mTrackFragmentHeaderInfo.mFlags 1903840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 1904840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 1905840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1906840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleSize = info->mDefaultSampleSize; 1907840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1908840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1909840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleFlagsPresent) { 1910840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bytesPerSample += 4; 1911840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else if (mTrackFragmentHeaderInfo.mFlags 1912840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 1913840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 1914840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1915840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleFlags = info->mDefaultSampleFlags; 1916840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1917840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1918840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleCompositionTimeOffsetPresent) { 1919840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bytesPerSample += 4; 1920840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } else { 1921840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleCtsOffset = 0; 1922840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1923840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1924840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (offset + sampleCount * bytesPerSample > size) { 1925840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return -EINVAL; 1926840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1927840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1928840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t sampleDescIndex = 1929840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (mTrackFragmentHeaderInfo.mFlags 1930840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) 1931840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ? mTrackFragmentHeaderInfo.mSampleDescriptionIndex 1932840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber : info->mDefaultSampleDescriptionIndex; 1933840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1934840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (uint32_t i = 0; i < sampleCount; ++i) { 1935840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleDurationPresent) { 1936840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDuration = readU32(offset); 1937840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1938840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1939840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1940840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleSizePresent) { 1941840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleSize = readU32(offset); 1942840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1943840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1944840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1945840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleFlagsPresent) { 1946840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleFlags = readU32(offset); 1947840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1948840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1949840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1950840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (flags & kSampleCompositionTimeOffsetPresent) { 1951840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleCtsOffset = readU32(offset); 1952840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber offset += 4; 1953840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1954840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1955840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ALOGV("adding sample at offset 0x%08llx, size %u, duration %u, " 1956840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber "sampleDescIndex=%u, flags 0x%08x", 1957840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber dataOffset, sampleSize, sampleDuration, 1958840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDescIndex, 1959840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (flags & kFirstSampleFlagsPresent) && i == 0 1960840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ? firstSampleFlags : sampleFlags); 1961840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1962840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber const sp<TrackFragment> &fragment = *--info->mFragments.end(); 1963840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1964840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t decodingTime = info->mDecodingTime; 1965840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber info->mDecodingTime += sampleDuration; 1966840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber uint32_t presentationTime = decodingTime + sampleCtsOffset; 1967840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1968840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber static_cast<DynamicTrackFragment *>( 1969840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber fragment.get())->addSample( 1970840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber dataOffset, 1971840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleSize, 1972840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber presentationTime, 1973840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sampleDescIndex, 1974840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ((flags & kFirstSampleFlagsPresent) && i == 0) 1975840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber ? firstSampleFlags : sampleFlags); 1976840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1977840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber dataOffset += sampleSize; 1978840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1979840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1980840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 1981840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1982840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return OK; 1983840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1984840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1985cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenvoid FragmentedMP4Parser::copyBuffer( 19862e136686cd60556b681480079142142ab4a7e07cJames Dong sp<ABuffer> *dst, size_t offset, uint64_t size) const { 19872e136686cd60556b681480079142142ab4a7e07cJames Dong sp<ABuffer> buf = new ABuffer(size); 1988840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber memcpy(buf->data(), mBuffer->data() + offset, size); 1989840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1990840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *dst = buf; 1991840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 1992840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1993840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} // namespace android 1994