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 107b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas HuberMP4Source::MP4Source( 108b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber const sp<AMessage> ¬ify, const sp<IStreamSource> &source) 109b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber : Source(notify), 110b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber mSource(source), 111840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mLooper(new ALooper), 112cb1f88c684140ce0eb407049a78f889bc7d51be1Marco Nelissen mParser(new FragmentedMP4Parser), 113840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mEOS(false) { 114840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mLooper->registerHandler(mParser); 115840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 116840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 117840667883fd09d44015716d79bc3ac4d60edc0f0Andreas HuberMP4Source::~MP4Source() { 118840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 119840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid MP4Source::prepareAsync() { 1219575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber notifyVideoSizeChanged(0, 0); 1229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber notifyFlagsChanged(0); 1239575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber notifyPrepared(); 1249575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber} 1259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber 126840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid MP4Source::start() { 127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mLooper->start(false /* runOnCallingThread */); 128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mParser->start(new StreamSource(mSource)); 129840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 130840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 131840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t MP4Source::feedMoreTSData() { 132840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mEOS ? ERROR_END_OF_STREAM : (status_t)OK; 133840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 134840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 135840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<AMessage> MP4Source::getFormat(bool audio) { 136840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mParser->getFormat(audio); 137840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 138840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 139840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huberstatus_t MP4Source::dequeueAccessUnit( 140840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool audio, sp<ABuffer> *accessUnit) { 141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber return mParser->dequeueAccessUnit(audio, accessUnit); 142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} 143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 144840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber} // namespace android 145