MP4Source.cpp revision 56997121c5031598fbbba7b7c53980b7fd529c2d
1840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber/*
2840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Copyright (C) 2012 The Android Open Source Project
3840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *
4840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * you may not use this file except in compliance with the License.
6840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * You may obtain a copy of the License at
7840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *
8840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber *
10840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * Unless required by applicable law or agreed to in writing, software
11840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * See the License for the specific language governing permissions and
14840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber * limitations under the License.
15840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber */
16840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
17840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "MP4Source.h"
18840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
19cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen#include "FragmentedMP4Parser.h"
20840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include "../NuPlayerStreamListener.h"
21840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
22840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/IStreamSource.h>
23840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/foundation/AMessage.h>
24840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/MediaErrors.h>
25840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <media/stagefright/MetaData.h>
26840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
27840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubernamespace android {
28840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
29cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissenstruct StreamSource : public FragmentedMP4Parser::Source {
30840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    StreamSource(const sp<IStreamSource> &source)
31840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        : mListener(new NuPlayer::NuPlayerStreamListener(source, 0)),
32840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber          mPosition(0) {
33840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        mListener->start();
34840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
35840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
36840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
37840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        if (offset < mPosition) {
38840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            return -EPIPE;
39840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        }
40840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
41840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        while (offset > mPosition) {
42840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            char buffer[1024];
43840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            off64_t skipBytes = offset - mPosition;
44840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            if (skipBytes > sizeof(buffer)) {
45840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                skipBytes = sizeof(buffer);
46840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            }
47840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
48840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            sp<AMessage> extra;
49840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            ssize_t n;
50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            for (;;) {
51840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                n = mListener->read(buffer, skipBytes, &extra);
52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
53840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                if (n == -EWOULDBLOCK) {
54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                    usleep(10000);
55840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                    continue;
56840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                }
57840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
58840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                break;
59840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            }
60840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
61840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            ALOGV("skipped %ld bytes at offset %lld", n, mPosition);
62840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
63840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            if (n < 0) {
64840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                return n;
65840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            }
66840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
67840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            mPosition += n;
68840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        }
69840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
70840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        sp<AMessage> extra;
71840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        size_t total = 0;
72840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        while (total < size) {
73840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            ssize_t n = mListener->read(
74840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                    (uint8_t *)data + total, size - total, &extra);
75840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
76840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            if (n == -EWOULDBLOCK) {
77840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                usleep(10000);
78840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                continue;
79840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            } else if (n == 0) {
80840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                break;
81840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            } else if (n < 0) {
82840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                mPosition += total;
83840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber                return n;
84840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            }
85840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
86840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber            total += n;
87840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        }
88840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
89840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        ALOGV("read %ld bytes at offset %lld", n, mPosition);
90840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
91840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        mPosition += total;
92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
93840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        return total;
94840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    }
95840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
9656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    bool isSeekable() {
9756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        return false;
9856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
9956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
100840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberprivate:
101840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    sp<NuPlayer::NuPlayerStreamListener> mListener;
102840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    off64_t mPosition;
103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
104840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(StreamSource);
105840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber};
106840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
107840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberMP4Source::MP4Source(const sp<IStreamSource> &source)
108840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    : mSource(source),
109840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber      mLooper(new ALooper),
110cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen      mParser(new FragmentedMP4Parser),
111840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber      mEOS(false) {
112840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    mLooper->registerHandler(mParser);
113840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberMP4Source::~MP4Source() {
116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid MP4Source::start() {
119840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    mLooper->start(false /* runOnCallingThread */);
120840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    mParser->start(new StreamSource(mSource));
121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
122840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
123840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t MP4Source::feedMoreTSData() {
124840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    return mEOS ? ERROR_END_OF_STREAM : (status_t)OK;
125840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
126840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<AMessage> MP4Source::getFormat(bool audio) {
128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    return mParser->getFormat(audio);
129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
130840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t MP4Source::dequeueAccessUnit(
132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber        bool audio, sp<ABuffer> *accessUnit) {
133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    return mParser->dequeueAccessUnit(audio, accessUnit);
134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}
135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
136840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber}  // namespace android
137