MPEG4Extractor.cpp revision ba529e486dde15fe75ea1b48570f9d60a4cf3c48
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor"
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h"
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h"
2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h>
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
32ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#include "include/ESDS.h"
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h>
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
3518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h>
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h>
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource {
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic:
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Caller retains ownership of both "dataSource" and "sampleTable".
46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    MPEG4Source(const sp<MetaData> &format,
47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                const sp<DataSource> &dataSource,
4848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                int32_t timeScale,
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber                const sp<SampleTable> &sampleTable);
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t start(MetaData *params = NULL);
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t stop();
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual sp<MetaData> getFormat();
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    virtual status_t read(
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~MPEG4Source();
61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex mLock;
647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> mFormat;
66693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<DataSource> mDataSource;
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t mTimescale;
68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<SampleTable> mSampleTable;
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t mCurrentSampleIndex;
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mIsAVC;
726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t mNALLengthSize;
736064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool mStarted;
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBufferGroup *mGroup;
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *mBuffer;
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool mWantsNALFragments;
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
820024245e134467d120b40099da16c467dc365e76Andreas Huber    uint8_t *mSrcBuffer;
830024245e134467d120b40099da16c467dc365e76Andreas Huber
846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    size_t parseNALSize(const uint8_t *data) const;
856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source(const MPEG4Source &);
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MPEG4Source &operator=(const MPEG4Source &);
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This custom data source wraps an existing one and satisfies requests
9150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// falling entirely within a cached range from the cache while forwarding
9250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// all remaining requests to the wrapped datasource.
9350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// This is used to cache the full sampletable metadata for a single track,
9450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// possibly wrapping multiple times to cover all tracks, i.e.
9550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track.
9650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
9750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstruct MPEG4DataSource : public DataSource {
9850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource(const sp<DataSource> &source);
9950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
10050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual status_t initCheck() const;
10150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual ssize_t readAt(off_t offset, void *data, size_t size);
10250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual status_t getSize(off_t *size);
10350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual uint32_t flags();
10450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
10550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    status_t setCachedRange(off_t offset, size_t size);
10650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
10750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprotected:
10850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    virtual ~MPEG4DataSource();
10950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
11050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberprivate:
11150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex mLock;
11250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
11350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    sp<DataSource> mSource;
11450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    off_t mCachedOffset;
11550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    size_t mCachedSize;
11650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    uint8_t *mCache;
11750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
11850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    void clearCache();
11950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
12050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource(const MPEG4DataSource &);
12150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    MPEG4DataSource &operator=(const MPEG4DataSource &);
12250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber};
12350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
12450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
12550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    : mSource(source),
12650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedOffset(0),
12750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCachedSize(0),
12850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber      mCache(NULL) {
12950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
13050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
13150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas HuberMPEG4DataSource::~MPEG4DataSource() {
13250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
13350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
13450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
13550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Hubervoid MPEG4DataSource::clearCache() {
13650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache) {
13750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        free(mCache);
13850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        mCache = NULL;
13950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
14050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
14150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = 0;
14250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = 0;
14350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
14450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
14550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::initCheck() const {
14650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->initCheck();
14750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
14850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
14950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) {
15050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
15150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
15250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (offset >= mCachedOffset
15350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            && offset + size <= mCachedOffset + mCachedSize) {
15450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        memcpy(data, &mCache[offset - mCachedOffset], size);
15550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return size;
15650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
15750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
15850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->readAt(offset, data, size);
15950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
16050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
16150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) {
16250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->getSize(size);
16350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
16450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
16550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberuint32_t MPEG4DataSource::flags() {
16650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return mSource->flags();
16750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
16850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
16950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) {
17050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    Mutex::Autolock autoLock(mLock);
17150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
17250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    clearCache();
17350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
17450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCache = (uint8_t *)malloc(size);
17550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
17650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (mCache == NULL) {
17750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return -ENOMEM;
17850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
17950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedOffset = offset;
18150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    mCachedSize = size;
18250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
18450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    if (err < (ssize_t)size) {
18650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        clearCache();
18750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
18850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber        return ERROR_IO;
18950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    }
19050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber    return OK;
19250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber}
19350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19450a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber////////////////////////////////////////////////////////////////////////////////
19550a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const uint8_t *data = (const uint8_t *)_data;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t offset = 0;
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (offset < size) {
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("0x%04x  ", offset);
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t n = size - offset;
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (n > 16) {
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            n = 16;
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < 16; ++i) {
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (i == 8) {
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(" ");
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (offset + i < size) {
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%02x ", data[offset + i]);
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("   ");
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf(" ");
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (size_t i = 0; i < n; ++i) {
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (isprint(data[offset + i])) {
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf("%c", data[offset + i]);
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                printf(".");
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("\n");
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        offset += 16;
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) {
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch (fourcc) {
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
23818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AAC;
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
24118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
243371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
24418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
245371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
24718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_MPEG4;
24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
25018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_H263;
25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
25318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            return MEDIA_MIMETYPE_VIDEO_AVC;
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
256dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            CHECK(!"should not be here.");
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
261693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mHaveMetadata(false),
2647be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber      mHasVideo(false),
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mFirstTrack(NULL),
26672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber      mLastTrack(NULL),
267dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFileMetaData(new MetaData),
268dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mFirstSINF(NULL),
269dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang      mIsDrm(false) {
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() {
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        Track *next = track->next;
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete track;
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = next;
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mFirstTrack = mLastTrack = NULL;
281dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
282dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
283dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf) {
284dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *next = sinf->next;
285dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete sinf->IPMPData;
286dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        delete sinf;
287dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = next;
288dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
289dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mFirstSINF = NULL;
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() {
2937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    status_t err;
2947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if ((err = readMetaData()) != OK) {
29572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return new MetaData;
2967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
2977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
29872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return mFileMetaData;
2997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
3007be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() {
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
304693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return 0;
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
307693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t n = 0;
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (track) {
310693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        ++n;
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
314693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return n;
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(
3187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t index, uint32_t flags) {
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return NULL;
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return NULL;
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
334371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
335371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
336371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
337371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
3387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if ((flags & kIncludeExtensiveMetaData)
3397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            && !track->includes_expensive_metadata) {
3407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        track->includes_expensive_metadata = true;
3417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
3427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        const char *mime;
3437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
3447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (!strncasecmp("video/", mime, 6)) {
3457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            uint32_t sampleIndex;
3467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            uint32_t sampleTime;
3477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
348c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    && track->sampleTable->getMetaDataForSample(
349c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        sampleIndex, NULL /* offset */, NULL /* size */,
350c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &sampleTime) == OK) {
3517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber                track->meta->setInt64(
3527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber                        kKeyThumbnailTime,
3537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber                        ((int64_t)sampleTime * 1000000) / track->timescale);
3547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            }
3557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
3567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
3577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return track->meta;
35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() {
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mHaveMetadata) {
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    off_t offset = 0;
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while ((err = parseChunk(&offset, 0)) == OK) {
36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
3707be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mHaveMetadata) {
37272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (mHasVideo) {
37372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
37672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
37772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return err;
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangvoid MPEG4Extractor::setDrmFlag(bool flag) {
385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    mIsDrm = flag;
386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangchar* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mFirstSINF == NULL) {
390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
391dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
392dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
393dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    SINF *sinf = mFirstSINF;
394dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (sinf && (trackID != sinf->trackID)) {
395dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf = sinf->next;
396dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
397dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
398dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (sinf == NULL) {
399dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return NULL;
400dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
401dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
402dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *len = sinf->len;
403dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return sinf->IPMPData;
404dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
405dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
406dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang// Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
407dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangint32_t readSize(off_t offset,
408dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        const sp<DataSource> DataSource, uint8_t *numOfBytes) {
409dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint32_t size = 0;
410dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t data;
411dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    bool moreData = true;
412dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    *numOfBytes = 0;
413dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
414dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (moreData) {
415dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (DataSource->readAt(offset, &data, 1) < 1) {
416dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return -1;
417dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
418dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        offset ++;
419dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        moreData = (data >= 128) ? true : false;
420dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size = (size << 7) | (data & 0x7f); // Take last 7 bits
421dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        (*numOfBytes) ++;
422dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
423dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
424dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return size;
425dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
426dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
427dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wangstatus_t MPEG4Extractor::parseDrmSINF(off_t *offset, off_t data_offset) {
428dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t updateIdTag;
429dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
430dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
431dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
432dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
433dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
434dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
435dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
436dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
437dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
438dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    uint8_t numOfBytes;
439dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
440dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
441dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
442dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
443dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    int32_t classSize = size;
444dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
445dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
446dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while(size >= 11 ) {
447dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t descriptorTag;
448dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
449dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
450dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
451dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
452dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
453dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
454dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
455dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
456dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
457dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t buffer[8];
458dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        //ObjectDescriptorID and ObjectDescriptor url flag
459dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
460dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
461dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
462dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 2;
463dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
464dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((buffer[1] >> 5) & 0x0001) { //url flag is set
465dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
466dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
467dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
468dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
469dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
470dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
471dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset += 8;
472dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
473dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
474dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
475dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_MALFORMED;
476dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
477dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
478dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        SINF *sinf = new SINF;
479dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->trackID = U16_AT(&buffer[3]);
480dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->IPMPDescriptorID = buffer[7];
481dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        sinf->next = mFirstSINF;
482dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mFirstSINF = sinf;
483dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
484dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        size -= (8 + 2 + 1);
485dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
486dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
487dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
488dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
489dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
490dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
491dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
492dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
493dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
494dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset ++;
495dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
496dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
497dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
498dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
499dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
500dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    size = readSize(data_offset, mDataSource, &numOfBytes);
501dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size < 0) {
502dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_IO;
503dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
504dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    classSize = size;
505dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    data_offset += numOfBytes;
506dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
507dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    while (size > 0) {
508dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        uint8_t tag;
509dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t dataLen;
510dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
511dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return ERROR_IO;
512dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
513dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        data_offset ++;
514dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
515dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
516dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t id;
517dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            dataLen = readSize(data_offset, mDataSource, &numOfBytes);
518dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (dataLen < 0) {
519dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
520dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            } else if (dataLen < 4) {
521dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
522dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
523dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += numOfBytes;
524dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
525dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (mDataSource->readAt(data_offset, &id, 1) < 1) {
526dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
527dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
528dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset ++;
529dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
530dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            SINF *sinf = mFirstSINF;
531dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (sinf && (sinf->IPMPDescriptorID != id)) {
532dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                sinf = sinf->next;
533dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
534dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (sinf == NULL) {
535dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
536dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
537dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            sinf->len = dataLen - 3;
538dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            sinf->IPMPData = new char[sinf->len];
539dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
540dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
541dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_IO;
542dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
543dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            data_offset += sinf->len;
544dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
545dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size -= (dataLen + numOfBytes + 1);
546dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
547dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
548dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
549dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (size != 0) {
550dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        return ERROR_MALFORMED;
551dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
552dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
553dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    return UNKNOWN_ERROR;  // Return a dummy error.
554dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang}
555dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) {
55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    s[0] = x >> 24;
55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    s[1] = (x >> 16) & 0xff;
55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    s[2] = (x >> 8) & 0xff;
56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    s[3] = x & 0xff;
56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    s[4] = '\0';
56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder {
56572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
56672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        : mPath(path) {
56772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->push(chunkType);
56872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
56972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
57072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    ~PathAdder() {
57172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        mPath->pop();
57272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
57372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
57472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate:
57572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    Vector<uint32_t> *mPath;
57672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
57772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder(const PathAdder &);
57872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder &operator=(const PathAdder &);
57972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber};
58072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
58172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) {
58272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return path.size() >= 5
58372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[0] == FOURCC('m', 'o', 'o', 'v')
58472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[1] == FOURCC('u', 'd', 't', 'a')
58572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[2] == FOURCC('m', 'e', 't', 'a')
58672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        && path[3] == FOURCC('i', 'l', 's', 't');
58772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
58872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
58972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string.
59072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) {
59172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
59272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
59372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    char tmp[32];
59472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
59572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
59672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    s->setTo(tmp);
59772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
59872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t hdr[2];
60134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint64_t chunk_size = ntohl(hdr[0]);
60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t chunk_type = ntohl(hdr[1]);
60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    off_t data_offset = *offset + 8;
60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (chunk_size == 1) {
60934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_IO;
61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        chunk_size = ntoh64(chunk_size);
61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        data_offset += 8;
61471b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber
61571b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        if (chunk_size < 16) {
61671b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            // The smallest valid chunk is 16 bytes long in this case.
61771b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber            return ERROR_MALFORMED;
61871b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        }
61971b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber    } else if (chunk_size < 8) {
62071b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        // The smallest valid chunk is 8 bytes long.
62171b1a4e975dfb65660a0119b9d6bf6db77eca09eAndreas Huber        return ERROR_MALFORMED;
62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    char chunk[5];
62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MakeFourCCString(chunk_type, chunk);
62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0
62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    static const char kWhitespace[] = "                                        ";
62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    char buffer[256];
633ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber    size_t n = chunk_size;
634ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber    if (n > sizeof(buffer)) {
635ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        n = sizeof(buffer);
636ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber    }
637ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber    if (mDataSource->readAt(*offset, buffer, n)
638ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber            < (ssize_t)n) {
639ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        return ERROR_IO;
64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
641ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
642ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber    hexdump(buffer, n);
64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif
64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
64572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    PathAdder autoAdder(&mPath, chunk_type);
64672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    off_t chunk_data_size = *offset + chunk_size - data_offset;
64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
64972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (chunk_type != FOURCC('c', 'p', 'r', 't')
65072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            && mPath.size() == 5 && underMetaDataPath(mPath)) {
65172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        off_t stop_offset = *offset + chunk_size;
65272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        *offset = data_offset;
65372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        while (*offset < stop_offset) {
65472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            status_t err = parseChunk(offset, depth + 1);
65572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (err != OK) {
65672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return err;
65772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
65872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
659bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
660bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (*offset != stop_offset) {
661bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
662bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
66372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
66472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return OK;
66572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
66672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    switch(chunk_type) {
66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'v'):
66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'k'):
67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'i', 'a'):
67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'i', 'n', 'f'):
67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('d', 'i', 'n', 'f'):
67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'b', 'l'):
67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'v', 'e', 'x'):
67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'o', 'o', 'f'):
67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'r', 'a', 'f'):
67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'f', 'r', 'a'):
67872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('u', 'd', 't', 'a'):
67972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('i', 'l', 's', 't'):
68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
68150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
68250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
68350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
684b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                if (mDataSource->flags()
685b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                        & (DataSource::kWantsPrefetching
686b9d3038ec950665639e26acd51329ebc800e780dAndreas Huber                            | DataSource::kIsCachingDataSource)) {
68750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    sp<MPEG4DataSource> cachedSource =
68850a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        new MPEG4DataSource(mDataSource);
68950a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
69050a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
69150a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                        mDataSource = cachedSource;
69250a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                    }
69350a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber                }
6941edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber
6951edbcb2bb9988cc7cb54a865aaea4613bdd53a9dAndreas Huber                mLastTrack->sampleTable = new SampleTable(mDataSource);
69650a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber            }
69750a9976892316c033cd90d522ecbfcc8e3c0eb9bAndreas Huber
6986f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            bool isTrack = false;
699bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
7006f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                isTrack = true;
7016f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
702bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                Track *track = new Track;
703bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->next = NULL;
704bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (mLastTrack) {
705bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mLastTrack->next = track;
706bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                } else {
707bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    mFirstTrack = track;
708bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
709bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                mLastTrack = track;
710bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
711bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta = new MetaData;
712bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->includes_expensive_metadata = false;
7136f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                track->skipTrack = false;
714bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->timescale = 0;
715bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
716bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
717bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            off_t stop_offset = *offset + chunk_size;
71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset;
72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
727bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
728bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
729bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
730bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
7316f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber            if (isTrack) {
7326f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                if (mLastTrack->skipTrack) {
7336f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    Track *cur = mFirstTrack;
7346f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
7356f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    if (cur == mLastTrack) {
7366f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete cur;
7376f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mFirstTrack = mLastTrack = NULL;
7386f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    } else {
7396f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        while (cur && cur->next != mLastTrack) {
7406f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                            cur = cur->next;
7416f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        }
7426f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        cur->next = NULL;
7436f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        delete mLastTrack;
7446f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                        mLastTrack = cur;
7456f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    }
7466f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
7476f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                    return OK;
7486f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                }
7496f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
750bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                status_t err = verifyTrack(mLastTrack);
751bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
752bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                if (err != OK) {
753bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                    return err;
754bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                }
755bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mHaveMetadata = true;
75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
758dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (!mIsDrm) {
759dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return UNKNOWN_ERROR;  // Return a dummy error.
760dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                } else {
761dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return OK;
762dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('t', 'k', 'h', 'd'):
76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
769ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            status_t err;
770ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
771ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                return err;
77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 4) {
78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t version;
78534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, &version, sizeof(version))
78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(version)) {
78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            off_t timescale_offset;
79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 16;
79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else if (version == 0) {
79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                timescale_offset = data_offset + 4 + 8;
79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t timescale;
80234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    < (ssize_t)sizeof(timescale)) {
80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->timescale = ntohl(timescale);
80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            int64_t duration;
81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (version == 1) {
81234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration)) {
81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                duration = ntoh64(duration);
81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            } else {
81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                int32_t duration32;
82034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                if (mDataSource->readAt(
82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        < (ssize_t)sizeof(duration32)) {
82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return ERROR_IO;
82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                duration = ntohl(duration32);
82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
82748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            mLastTrack->meta->setInt64(
82848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'd'):
83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 8) {
83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8];
841bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (chunk_data_size < (off_t)sizeof(buffer)) {
842bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
843bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
844bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
84534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, 8) < 8) {
84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (entry_count > 1) {
85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // For now we only support a single type of media per track.
8596f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber
8606f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                mLastTrack->skipTrack = true;
8616f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                *offset += chunk_size;
8626f3a0c2dcb8d37d34e29e6a02acf1e3f8596088cAndreas Huber                break;
86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
86520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            off_t stop_offset = *offset + chunk_size;
86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + 8;
86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
873bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
874bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
875bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
876bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
882371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        case FOURCC('s', 'a', 'w', 'b'):
88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[8 + 20];
88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic AudioSampleEntry size.
88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
88920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
89034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
89620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t num_channels = U16_AT(&buffer[16]);
89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
89881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
89981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
90081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
90118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
90281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                            FourCC2MIME(chunk_type))) {
90381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                // AMR NB audio is always mono, 8kHz
90481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                num_channels = 1;
90581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                sample_rate = 8000;
90681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
90718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber                               FourCC2MIME(chunk_type))) {
90881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                // AMR WB audio is always mono, 16kHz
90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                num_channels = 1;
91081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                sample_rate = 16000;
91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
91381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#if 0
91481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber            printf("*** coding='%s' %d channels, size %d, rate %d\n",
91581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber                   chunk, num_channels, sample_size, sample_rate);
91681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber#endif
91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            off_t stop_offset = *offset + chunk_size;
92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
930bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
931bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
932bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
933bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', '2', '6', '3'):
93920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
94020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
9417be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber            mHasVideo = true;
9427be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
94320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[78];
94420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
94520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Basic VideoSampleEntry size.
94620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
94720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
94934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
95320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
958134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
959134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber            //        chunk, width, height);
96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            off_t stop_offset = *offset + chunk_size;
96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset = data_offset + sizeof(buffer);
96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            while (*offset < stop_offset) {
96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                status_t err = parseChunk(offset, depth + 1);
96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (err != OK) {
97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    return err;
97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
973bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
974bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
975bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
976bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('c', 'o', '6', '4'):
98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'c'):
99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 'z'):
101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 'z', '2'):
101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        chunk_type, data_offset, chunk_data_size);
101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1020738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            size_t max_size;
102149110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
102249110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber
102349110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            if (err != OK) {
102449110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber                return err;
102549110ce0ed95918c85eebe6e09e900b905b37e23Andreas Huber            }
1026738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
1027738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            // Assume that a given buffer only contains at most 10 fragments,
1028738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            // each fragment originally prefixed with a 2 byte length will
1029738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
1030738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            // and thus will grow by 2 bytes per fragment.
1031738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
1032738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber
103320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
103420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
103520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
103620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 't', 's'):
103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
103920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
104020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
104320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
104620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('s', 't', 's', 's'):
105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            status_t err =
105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, chunk_data_size);
105620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return err;
105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
106020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('e', 's', 'd', 's'):
106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size < 4) {
106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            uint8_t buffer[256];
107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
107634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
107820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
108020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (U32_AT(buffer) != 0) {
108220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                // Should be version 0, flags 0.
108320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_MALFORMED;
108420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
108520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
108620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
108720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1089ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            if (mPath.size() >= 2
1090ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1091ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // Information from the ESDS must be relied on for proper
1092ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // setup of sample rate and channel count for MPEG4 Audio.
1093ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // The generic header appears to only contain generic
1094ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                // information...
1095ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1096ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1097ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        &buffer[4], chunk_data_size - 4);
1098ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1099ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                if (err != OK) {
1100ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                    return err;
1101ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                }
1102ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            }
1103ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
110420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
110820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
110920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            char buffer[256];
111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
111534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber            if (mDataSource->readAt(
111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
111720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                return ERROR_IO;
111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mLastTrack->meta->setData(
112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
112772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'e', 't', 'a'):
112872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
112972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            uint8_t buffer[4];
1130bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (chunk_data_size < (off_t)sizeof(buffer)) {
1131bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1132bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
1133bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
113472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mDataSource->readAt(
113572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        data_offset, buffer, 4) < 4) {
113672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_IO;
113772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
113872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
113972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (U32_AT(buffer) != 0) {
114072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                // Should be version 0, flags 0.
1141ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber
1142ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                // If it's not, let's assume this is one of those
1143ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                // apparently malformed chunks that don't have flags
1144ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                // and completely different semantics than what's
1145ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                // in the MPEG4 specs and skip it.
1146ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                *offset += chunk_size;
1147ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber                return OK;
114872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
114972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
115072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            off_t stop_offset = *offset + chunk_size;
115172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            *offset = data_offset + sizeof(buffer);
115272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            while (*offset < stop_offset) {
115372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                status_t err = parseChunk(offset, depth + 1);
115472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
115572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
115672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
115772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
1158bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1159bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            if (*offset != stop_offset) {
1160bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
1161bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            }
116272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
116372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
116472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
116572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('d', 'a', 't', 'a'):
116672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
116772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
116872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                status_t err = parseMetaData(data_offset, chunk_data_size);
116972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
117072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                if (err != OK) {
117172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    return err;
117272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                }
117372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
117472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
117572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            *offset += chunk_size;
117672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
117772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
117872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
117972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('m', 'v', 'h', 'd'):
118072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
118172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (chunk_data_size < 12) {
118272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_MALFORMED;
118372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
118472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
118572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            uint8_t header[12];
118672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (mDataSource->readAt(
118772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        data_offset, header, sizeof(header))
118872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    < (ssize_t)sizeof(header)) {
118972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                return ERROR_IO;
119072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
119172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
119272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            int64_t creationTime;
119372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (header[0] == 1) {
119472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U64_AT(&header[4]);
1195bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            } else if (header[0] != 0) {
1196bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                return ERROR_MALFORMED;
119772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            } else {
119872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                creationTime = U32_AT(&header[4]);
119972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
120072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
120172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            String8 s;
120272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            convertTimeToDate(creationTime, &s);
120372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
120472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(kKeyDate, s.string());
120572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
120672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            *offset += chunk_size;
120772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
120872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
120972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
1210dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        case FOURCC('m', 'd', 'a', 't'):
1211dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        {
1212dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (!mIsDrm) {
1213dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                *offset += chunk_size;
1214dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                break;
1215dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
1216dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1217dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            if (chunk_size < 8) {
1218dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                return ERROR_MALFORMED;
1219dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
1220dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1221dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            return parseDrmSINF(offset, data_offset);
1222dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
1223dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
122420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        default:
122520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
122620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *offset += chunk_size;
122720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
122820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
122920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
123020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
123120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
123320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1234ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huberstatus_t MPEG4Extractor::parseTrackHeader(
1235ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        off_t data_offset, off_t data_size) {
1236ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (data_size < 4) {
1237ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
1238ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1239ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1240ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t version;
1241ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(data_offset, &version, 1) < 1) {
1242ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
1243ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1244ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1245ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t dynSize = (version == 1) ? 36 : 24;
1246ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1247ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint8_t buffer[36 + 60];
1248ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1249ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (data_size != (off_t)dynSize + 60) {
1250ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_MALFORMED;
1251ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1252ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1253ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (mDataSource->readAt(
1254ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                data_offset, buffer, data_size) < (ssize_t)data_size) {
1255ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        return ERROR_IO;
1256ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1257ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1258ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint64_t ctime, mtime, duration;
1259ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t id;
1260ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1261ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (version == 1) {
1262ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U64_AT(&buffer[4]);
1263ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U64_AT(&buffer[12]);
1264ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[20]);
1265ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U64_AT(&buffer[28]);
1266ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
1267ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((unsigned)version, 0u);
1268ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1269ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        ctime = U32_AT(&buffer[4]);
1270ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mtime = U32_AT(&buffer[8]);
1271ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        id = U32_AT(&buffer[12]);
1272ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        duration = U32_AT(&buffer[20]);
1273ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1274ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1275ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    mLastTrack->meta->setInt32(kKeyTrackID, id);
1276ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1277ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    size_t matrixOffset = dynSize + 16;
1278ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a00 = U32_AT(&buffer[matrixOffset]);
1279ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
1280ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
1281ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
1282ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
1283ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
1284ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1285ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0
1286ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    LOGI("x' = %.2f * x + %.2f * y + %.2f",
1287ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
1288ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    LOGI("y' = %.2f * x + %.2f * y + %.2f",
1289ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber         a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
1290ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif
1291ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1292ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t rotationDegrees;
1293ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1294ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    static const int32_t kFixedOne = 0x10000;
1295ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
1296ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        // Identity, no rotation
1297ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1298ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
1299ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 90;
1300ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
1301ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 270;
1302ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
1303ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 180;
1304ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
1305ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        LOGW("We only support 0,90,180,270 degree rotation matrices");
1306ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1307ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1308ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1309ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees != 0) {
1310ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
1311ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1312ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1313ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#if 0
1314ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t width = U32_AT(&buffer[dynSize + 52]);
1315ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t height = U32_AT(&buffer[dynSize + 56]);
1316ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber#endif
1317ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1318ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    return OK;
1319ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber}
1320ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
132172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) {
132272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (size < 4) {
132372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_MALFORMED;
132472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
132572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
132672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint8_t *buffer = new uint8_t[size + 1];
132772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (mDataSource->readAt(
132872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                offset, buffer, size) != (ssize_t)size) {
132972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        delete[] buffer;
133072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        buffer = NULL;
133172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
133272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        return ERROR_IO;
133372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
133472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
133572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t flags = U32_AT(buffer);
133672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
133772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    uint32_t metadataKey = 0;
133872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    switch (mPath[4]) {
133972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'a', 'l', 'b'):
134072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
134172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbum;
134272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
134372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
134472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'A', 'R', 'T'):
134572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
134672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyArtist;
134772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
134872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
134966ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        case FOURCC('a', 'A', 'R', 'T'):
135066ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        {
135166ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            metadataKey = kKeyAlbumArtist;
135266ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen            break;
135366ac4df65516ebfd0e500bfca75dc4b5ef8d674eMarco Nelissen        }
135472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'd', 'a', 'y'):
135572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
135672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyYear;
135772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
135872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
135972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'n', 'a', 'm'):
136072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
136172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyTitle;
136272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
136372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
136472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC(0xa9, 'w', 'r', 't'):
136572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
136672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyWriter;
136772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
136872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
136972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('c', 'o', 'v', 'r'):
137072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
137172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyAlbumArt;
137272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
137372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
137472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('g', 'n', 'r', 'e'):
137572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
137672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            metadataKey = kKeyGenre;
137772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
137872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
137926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC(0xa9, 'g', 'e', 'n'):
138026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
138126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            metadataKey = kKeyGenre;
138226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
138326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
138472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        case FOURCC('t', 'r', 'k', 'n'):
138572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        {
138672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (size == 16 && flags == 0) {
138772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char tmp[16];
138872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                sprintf(tmp, "%d/%d",
138972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                        (int)buffer[size - 5], (int)buffer[size - 3]);
139072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
139172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
139272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
139372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
139472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
139526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        case FOURCC('d', 'i', 's', 'k'):
139626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        {
139726bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            if (size == 14 && flags == 0) {
139826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                char tmp[16];
139926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                sprintf(tmp, "%d/%d",
140026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                        (int)buffer[size - 3], (int)buffer[size - 1]);
140126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
140226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(kKeyDiscNumber, tmp);
140326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            }
140426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            break;
140526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen        }
140626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
140772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        default:
140872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            break;
140972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
141072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
141172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    if (size >= 8 && metadataKey) {
141272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        if (metadataKey == kKeyAlbumArt) {
141372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setData(
141472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    kKeyAlbumArt, MetaData::TYPE_NONE,
141572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    buffer + 8, size - 8);
141672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else if (metadataKey == kKeyGenre) {
141772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            if (flags == 0) {
141826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // uint8_t genre code, iTunes genre codes are
141926bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // the standard id3 codes, except they start
142026bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // at 1 instead of 0 (e.g. Pop is 14, not 13)
142126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // We use standard id3 numbering, so subtract 1.
142226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                int genrecode = (int)buffer[size - 1];
142326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                genrecode--;
142426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                if (genrecode < 0) {
142526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                    genrecode = 255; // reserved for 'unknown genre'
142626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                }
142772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                char genre[10];
142826bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                sprintf(genre, "%d", genrecode);
142972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
143072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                mFileMetaData->setCString(metadataKey, genre);
143126bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen            } else if (flags == 1) {
143226bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                // custom genre string
143326bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                buffer[size] = '\0';
143426bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen
143526bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                mFileMetaData->setCString(
143626bae54d7a3d04215eba34c62c349f1be6ab1493Marco Nelissen                        metadataKey, (const char *)buffer + 8);
143772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            }
143872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        } else {
143972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            buffer[size] = '\0';
144072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
144172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber            mFileMetaData->setCString(
144272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber                    metadataKey, (const char *)buffer + 8);
144372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber        }
144472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    }
144572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
144672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    delete[] buffer;
144772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    buffer = NULL;
144872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
144972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber    return OK;
145072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}
145172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber
1452693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
145320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    status_t err;
145420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if ((err = readMetaData()) != OK) {
1455693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return NULL;
145620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
145720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
145820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Track *track = mFirstTrack;
145920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (index > 0) {
146020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (track == NULL) {
1461693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            return NULL;
146220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
146320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
146420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        track = track->next;
146520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        --index;
146620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
146720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1468371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    if (track == NULL) {
1469371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber        return NULL;
1470371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber    }
1471371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber
1472693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return new MPEG4Source(
147348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            track->meta, mDataSource, track->timescale, track->sampleTable);
147420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
147520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1476bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber// static
1477bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) {
1478bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const char *mime;
1479bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
1480bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1481bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    uint32_t type;
1482bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    const void *data;
1483bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    size_t size;
1484bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1485bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
1486bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeAVCC) {
1487bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
1488bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
1489bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
1490bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1491bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
1492bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber                || type != kTypeESDS) {
1493bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber            return ERROR_MALFORMED;
1494bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber        }
1495bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    }
1496bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1497bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber    return OK;
1498bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber}
1499bd5d93f21e6f79c6d9ebe9d77542c3090d4a7ff4Andreas Huber
1500ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
1501ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        const void *esds_data, size_t esds_size) {
1502ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    ESDS esds(esds_data, esds_size);
150381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
150481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    uint8_t objectTypeIndication;
150581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
150681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return ERROR_MALFORMED;
150781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
150881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
150981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    if (objectTypeIndication == 0xe1) {
151081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // This isn't MPEG4 audio at all, it's QCELP 14k...
151181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
151281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
151381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
151481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber
1515ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    const uint8_t *csd;
1516ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    size_t csd_size;
1517ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (esds.getCodecSpecificInfo(
1518ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                (const void **)&csd, &csd_size) != OK) {
1519ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
1520ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1521ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1522ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#if 0
1523ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    printf("ESD of size %d\n", csd_size);
1524ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    hexdump(csd, csd_size);
1525ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber#endif
1526ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1527a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    if (csd_size == 0) {
1528a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // There's no further information, i.e. no codec specific data
1529a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // Let's assume that the information provided in the mpeg4 headers
1530a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        // is accurate and hope for the best.
1531a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
1532a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber        return OK;
1533a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber    }
1534a65ccbff6e8eb301c0d325b2ec080aeda8df2024Andreas Huber
1535ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (csd_size < 2) {
1536ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_MALFORMED;
1537ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1538ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1539ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    uint32_t objectType = csd[0] >> 3;
1540ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1541ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (objectType == 31) {
1542ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_UNSUPPORTED;
1543ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1544ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1545ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
1546ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t sampleRate = 0;
1547ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t numChannels = 0;
1548ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (freqIndex == 15) {
1549ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        if (csd_size < 5) {
1550ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            return ERROR_MALFORMED;
1551ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        }
1552ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1553ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        sampleRate = (csd[1] & 0x7f) << 17
1554ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        | csd[2] << 9
1555ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        | csd[3] << 1
1556ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber                        | (csd[4] >> 7);
1557ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1558ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        numChannels = (csd[4] >> 3) & 15;
1559ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    } else {
15603c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber        static uint32_t kSamplingRate[] = {
15613c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber            96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
15623c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber            16000, 12000, 11025, 8000, 7350
15633c3ddfa39635a2d39f4ee7c966fb9403fe1ec9d8Andreas Huber        };
1564ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1565ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        if (freqIndex == 13 || freqIndex == 14) {
1566ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber            return ERROR_MALFORMED;
1567ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        }
1568ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1569ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        sampleRate = kSamplingRate[freqIndex];
1570ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        numChannels = (csd[1] >> 3) & 15;
1571ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1572ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1573ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (numChannels == 0) {
1574ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber        return ERROR_UNSUPPORTED;
1575ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1576ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1577ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevSampleRate;
1578ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
1579ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1580ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevSampleRate != sampleRate) {
1581ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber        LOGV("mpeg4 audio sample rate different from previous setting. "
1582ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevSampleRate, sampleRate);
1583ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1584ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1585ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
1586ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1587ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    int32_t prevChannelCount;
1588ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
1589ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1590ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    if (prevChannelCount != numChannels) {
1591ec9dd59902c8beea4ba6a842f3a843d46150d949Andreas Huber        LOGV("mpeg4 audio channel count different from previous setting. "
1592ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber             "was: %d, now: %d", prevChannelCount, numChannels);
1593ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    }
1594ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1595ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
1596ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
1597ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber    return OK;
1598ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber}
1599ba7c7eeca462614251aec3d27f0f7ff3a83cefa1Andreas Huber
160020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
160120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
160220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source(
160320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const sp<MetaData> &format,
1604693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &dataSource,
160548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        int32_t timeScale,
1606693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<SampleTable> &sampleTable)
160720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mFormat(format),
160820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDataSource(dataSource),
160948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber      mTimescale(timeScale),
161020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleTable(sampleTable),
161120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mCurrentSampleIndex(0),
161220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mIsAVC(false),
16136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber      mNALLengthSize(0),
161420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
161520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mGroup(NULL),
161620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mBuffer(NULL),
1617dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber      mWantsNALFragments(false),
16180024245e134467d120b40099da16c467dc365e76Andreas Huber      mSrcBuffer(NULL) {
161920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
162020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
1621dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(success);
162220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
162318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
16246064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
16256064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    if (mIsAVC) {
16266064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        uint32_t type;
16276064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const void *data;
16286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t size;
16296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
16306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
16316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
16326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
16336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(size >= 7);
1634ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
16356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
16366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        // The number of bytes used to encode the length of a NAL unit.
16376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
16386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
163920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
164020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
164120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() {
164220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        stop();
164420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
164520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
164620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
16487b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
16497b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
1650dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(!mStarted);
165120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
165220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int32_t val;
1653dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
165420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        && val != 0) {
1655dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = true;
165620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
1657dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mWantsNALFragments = false;
165820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
165920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
166020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mGroup = new MediaBufferGroup;
166120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1662738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    int32_t max_size;
1663738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
166420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1665738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber    mGroup->add_buffer(new MediaBuffer(max_size));
16660024245e134467d120b40099da16c467dc365e76Andreas Huber
16670024245e134467d120b40099da16c467dc365e76Andreas Huber    mSrcBuffer = new uint8_t[max_size];
166820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
167120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
167220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
167320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
167420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() {
16757b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
16767b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
1677dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
167820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
167920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mBuffer != NULL) {
168020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->release();
168120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
168220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
168320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16840024245e134467d120b40099da16c467dc365e76Andreas Huber    delete[] mSrcBuffer;
16850024245e134467d120b40099da16c467dc365e76Andreas Huber    mSrcBuffer = NULL;
16860024245e134467d120b40099da16c467dc365e76Andreas Huber
168720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete mGroup;
168820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mGroup = NULL;
168920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
169020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
169120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCurrentSampleIndex = 0;
169220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
169320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
169420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
169520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
169620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
16977b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
16987b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
169920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mFormat;
170020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
170120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
17036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    switch (mNALLengthSize) {
17046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 1:
17056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return *data;
17066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 2:
17076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U16_AT(data);
17086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 3:
17096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
17106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        case 4:
17116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber            return U32_AT(data);
17126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    }
17136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
17146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
17156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    // a 2-bit integer.
17166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    CHECK(!"Should not be here.");
17176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
17186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber    return 0;
17196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber}
17206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
172120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read(
172220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
17237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    Mutex::Autolock autoLock(mLock);
17247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
1725dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    CHECK(mStarted);
172620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
172720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *out = NULL;
172820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1729abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    int64_t targetSampleTimeUs = -1;
1730abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
173120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
1732abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
1733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
1734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t findFlags = 0;
1735abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        switch (mode) {
1736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_PREVIOUS_SYNC:
1737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagBefore;
1738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
1739abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_NEXT_SYNC:
1740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagAfter;
1741abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
1742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST_SYNC:
1743abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            case ReadOptions::SEEK_CLOSEST:
1744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                findFlags = SampleTable::kFlagClosest;
1745abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
1746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            default:
1747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(!"Should not be here.");
1748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                break;
1749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
1750abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
175120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t sampleIndex;
1752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleTable->findSampleAtTime(
175320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                seekTimeUs * mTimescale / 1000000,
1754abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                &sampleIndex, findFlags);
1755abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1756abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
1757abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // We found the closest sample already, now we want the sync
1758abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // sample preceding it (or the sample itself of course), even
1759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // if the subsequent sync sample is closer.
1760abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            findFlags = SampleTable::kFlagBefore;
1761abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
1762abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1763abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleIndex;
1764abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err == OK) {
1765abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            err = mSampleTable->findSyncSampleNear(
1766abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    sampleIndex, &syncSampleIndex, findFlags);
1767abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
176820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
176920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
17705295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            if (err == ERROR_OUT_OF_RANGE) {
17715295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // An attempt to seek past the end of the stream would
17725295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
17735295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // this all the way to the MediaPlayer would cause abnormal
17745295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // termination. Legacy behaviour appears to be to behave as if
17755295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                // we had seeked to the end of stream, ending normally.
17765295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                err = ERROR_END_OF_STREAM;
17775295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber            }
177820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
177920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
178020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1781abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t sampleTime;
1782ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample(
1783abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    sampleIndex, NULL, NULL, &sampleTime));
1784abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1785abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mode == ReadOptions::SEEK_CLOSEST) {
1786abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
1787abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
1788abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1789abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#if 0
1790abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t syncSampleTime;
1791abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
1792abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    syncSampleIndex, NULL, NULL, &syncSampleTime));
1793abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1794abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        LOGI("seek to time %lld us => sample at time %lld us, "
1795abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             "sync sample at time %lld us",
1796abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             seekTimeUs,
1797abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             sampleTime * 1000000ll / mTimescale,
1798abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber             syncSampleTime * 1000000ll / mTimescale);
1799abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber#endif
1800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        mCurrentSampleIndex = syncSampleIndex;
180220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mBuffer != NULL) {
180320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
180420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
180520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
180620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
180720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // fall through
180820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
180920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18100024245e134467d120b40099da16c467dc365e76Andreas Huber    off_t offset;
18110024245e134467d120b40099da16c467dc365e76Andreas Huber    size_t size;
1812dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    uint32_t dts;
18138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    bool isSyncSample;
1814dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    bool newBuffer = false;
1815dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (mBuffer == NULL) {
1816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        newBuffer = true;
181720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1818c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err =
1819c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mSampleTable->getMetaDataForSample(
18208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample);
182120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1822dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
1823dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
1824dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
1825dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1826dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        err = mGroup->acquire_buffer(&mBuffer);
1827c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
1828dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (err != OK) {
1829ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK(mBuffer == NULL);
1830dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return err;
1831dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
18320024245e134467d120b40099da16c467dc365e76Andreas Huber    }
183320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1834dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    if (!mIsAVC || mWantsNALFragments) {
1835dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (newBuffer) {
1836dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ssize_t num_bytes_read =
183734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
1838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1839dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            if (num_bytes_read < (ssize_t)size) {
1840dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer->release();
1841dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                mBuffer = NULL;
1842dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber                return ERROR_IO;
1844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            }
1845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
18467b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber            CHECK(mBuffer != NULL);
1847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->set_range(0, size);
1848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->meta_data()->clear();
184948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            mBuffer->meta_data()->setInt64(
185048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1851abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1852abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (targetSampleTimeUs >= 0) {
1853abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mBuffer->meta_data()->setInt64(
1854abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        kKeyTargetTime, targetSampleTimeUs);
1855abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
1856abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
18578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (isSyncSample) {
18588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
18598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
18608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
1861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            ++mCurrentSampleIndex;
1862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
1863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (!mIsAVC) {
1865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            *out = mBuffer;
1866dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
1867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1868dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return OK;
1869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
1870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1871dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Each NAL unit is split up into its constituent fragments and
1872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // each one of them returned in its own buffer.
1873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
18746064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
1875dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        const uint8_t *src =
1877dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
1878dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
18796064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        size_t nal_size = parseNALSize(src);
1880e8a084958c27327b0aca749f69095605d2a21309Andreas Huber        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
1881e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            LOGE("incomplete NAL unit.");
1882e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
1883e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer->release();
1884e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            mBuffer = NULL;
1885e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
1886e8a084958c27327b0aca749f69095605d2a21309Andreas Huber            return ERROR_MALFORMED;
1887e8a084958c27327b0aca749f69095605d2a21309Andreas Huber        }
1888dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        MediaBuffer *clone = mBuffer->clone();
18907b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(clone != NULL);
18916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
1892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
18937b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        CHECK(mBuffer != NULL);
1894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        mBuffer->set_range(
18956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
18966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
1897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        if (mBuffer->range_length() == 0) {
1899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer->release();
1900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            mBuffer = NULL;
1901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
1902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        *out = clone;
1904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        return OK;
1906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber    } else {
1907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // Whole NAL units are returned but each fragment is prefixed by
1908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        // the start code (0x00 00 00 01).
1909dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        ssize_t num_bytes_read = 0;
1910dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        int32_t drm = 0;
1911dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
1912dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
1913dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read =
1914dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
1915dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
1916dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
1917dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
191820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
191920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (num_bytes_read < (ssize_t)size) {
192020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer->release();
192120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mBuffer = NULL;
192220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber            return ERROR_IO;
192420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
192520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1926dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (usesDRM) {
1927dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
1928dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, size);
19296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber
1930dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        } else {
1931dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            uint8_t *dstData = (uint8_t *)mBuffer->data();
1932dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t srcOffset = 0;
1933dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            size_t dstOffset = 0;
1934e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
1935dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            while (srcOffset < size) {
1936dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                CHECK(srcOffset + mNALLengthSize <= size);
1937dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1938dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                srcOffset += mNALLengthSize;
1939e8a084958c27327b0aca749f69095605d2a21309Andreas Huber
1940dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (srcOffset + nalLength > size) {
1941dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer->release();
1942dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    mBuffer = NULL;
1943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1944dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    return ERROR_MALFORMED;
1945dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
1946dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1947dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                if (nalLength == 0) {
1948dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    continue;
1949dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                }
1950dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1951dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                CHECK(dstOffset + 4 <= mBuffer->size());
1952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
1953dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
1954dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
1955dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 0;
1956dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstData[dstOffset++] = 1;
1957dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
1958dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                srcOffset += nalLength;
1959dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                dstOffset += nalLength;
1960dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            }
1961dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK_EQ(srcOffset, size);
1962dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            CHECK(mBuffer != NULL);
1963dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mBuffer->set_range(0, dstOffset);
1964dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber        }
1965dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber
196620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer->meta_data()->clear();
196748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        mBuffer->meta_data()->setInt64(
196848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1969abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
1970abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (targetSampleTimeUs >= 0) {
1971abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            mBuffer->meta_data()->setInt64(
1972abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    kKeyTargetTime, targetSampleTimeUs);
1973abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
1974abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
19758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (isSyncSample) {
19768bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
19778bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
19788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
197920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        ++mCurrentSampleIndex;
198020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
198120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *out = mBuffer;
198220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mBuffer = NULL;
198320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
198420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
198520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
198620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
198720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool LegacySniffMPEG4(
1989693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
199020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
199120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
199234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
199320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (n < (ssize_t)sizeof(header)) {
199420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
199520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
199620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
199720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
1998b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
1999b9dbba9285fb406bc6eb87779c8bfc405269b6f2James Dong        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
20000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
2001ea5ea10a036f79c86bf5f204cb81804bf2bacdc7Andreas Huber        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
2002983b449a27b5fa91eca82ede5204b4341899be62Andreas Huber        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
200318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
20045a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        *confidence = 0.4;
200520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
200620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return true;
200720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
200820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
200920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return false;
201020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
201120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20121b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool isCompatibleBrand(uint32_t fourcc) {
20131b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    static const uint32_t kCompatibleBrands[] = {
20141b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', 'm'),
20151b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('i', 's', 'o', '2'),
20161b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('a', 'v', 'c', '1'),
20171b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('3', 'g', 'p', '4'),
20181b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '1'),
20191b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        FOURCC('m', 'p', '4', '2'),
20201b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    };
20211b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20221b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    for (size_t i = 0;
20231b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
20241b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber         ++i) {
20251b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        if (kCompatibleBrands[i] == fourcc) {
20261b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            return true;
20271b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
20281b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20291b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20301b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
20311b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
20321b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20331b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// Attempt to actually parse the 'ftyp' atom and determine if a suitable
20341b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber// compatible brand is present.
20351b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberstatic bool BetterSniffMPEG4(
20361b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
20371b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    uint8_t header[12];
20381b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (source->readAt(0, header, 12) != 12
20391b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            || memcmp("ftyp", &header[4], 4)) {
20401b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
20411b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20421b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20431b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    size_t atomSize = U32_AT(&header[0]);
20441b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (atomSize < 16 || (atomSize % 4) != 0) {
20451b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
20461b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20471b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20481b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    bool success = false;
20491b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (isCompatibleBrand(U32_AT(&header[8]))) {
20501b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        success = true;
20511b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    } else {
20521b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        size_t numCompatibleBrands = (atomSize - 16) / 4;
20531b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        for (size_t i = 0; i < numCompatibleBrands; ++i) {
20541b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            uint8_t tmp[4];
20551b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
20561b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                return false;
20571b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
20581b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20591b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
20601b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                success = true;
20611b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber                break;
20621b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber            }
20631b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        }
20641b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20651b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20661b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (!success) {
20671b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return false;
20681b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20691b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20701b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
20715a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    *confidence = 0.4f;
20721b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20731b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return true;
20741b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
20751b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20761b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huberbool SniffMPEG4(
20775a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
20785a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
20791b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (BetterSniffMPEG4(source, mimeType, confidence)) {
20801b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
20811b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20821b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20831b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    if (LegacySniffMPEG4(source, mimeType, confidence)) {
20841b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        LOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
20851b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber        return true;
20861b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    }
20871b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
20881b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber    return false;
20891b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber}
20901b52bd2874aef6c9cbc141f1cff5205830515f7dAndreas Huber
209120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
209220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2093