StreamingSource.cpp revision d5e56231a598b180a1d898bb7dc61b75580e59a4
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
27ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy * Copyright (C) 2010 The Android Open Source Project
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Licensed under the Apache License, Version 2.0 (the "License");
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * you may not use this file except in compliance with the License.
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * You may obtain a copy of the License at
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *      http://www.apache.org/licenses/LICENSE-2.0
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Unless required by applicable law or agreed to in writing, software
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * distributed under the License is distributed on an "AS IS" BASIS,
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * See the License for the specific language governing permissions and
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * limitations under the License.
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//#define LOG_NDEBUG 0
1883bceaa5d7a1196e05c1ccba443f90f4b032fca6Cristy#define LOG_TAG "StreamingSource"
1983bceaa5d7a1196e05c1ccba443f90f4b032fca6Cristy#include <utils/Log.h>
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
216398ec777e91813b64767e25358b7062a7de56cbcristy#include "StreamingSource.h"
226398ec777e91813b64767e25358b7062a7de56cbcristy
236398ec777e91813b64767e25358b7062a7de56cbcristy#include "ATSParser.h"
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "AnotherPacketSource.h"
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "NuPlayerStreamListener.h"
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <media/stagefright/foundation/ABuffer.h>
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <media/stagefright/foundation/ADebug.h>
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <media/stagefright/foundation/AMessage.h>
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <media/stagefright/MediaSource.h>
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <media/stagefright/MetaData.h>
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristynamespace android {
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyNuPlayer::StreamingSource::StreamingSource(
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const sp<AMessage> &notify,
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const sp<IStreamSource> &source)
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    : Source(notify),
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mSource(source),
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mFinalResult(OK) {
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyNuPlayer::StreamingSource::~StreamingSource() {
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid NuPlayer::StreamingSource::prepareAsync() {
47c9672a94adef17dee351f074e7c9915405ef29e1cristy    notifyVideoSizeChanged(0, 0);
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    notifyFlagsChanged(0);
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    notifyPrepared();
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid NuPlayer::StreamingSource::start() {
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mStreamListener = new NuPlayerStreamListener(mSource, 0);
544c08aed51c5899665ade97263692328eea4af106cristy
554c08aed51c5899665ade97263692328eea4af106cristy    uint32_t sourceFlags = mSource->flags();
564c08aed51c5899665ade97263692328eea4af106cristy
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    uint32_t parserFlags = ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE;
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sourceFlags & IStreamSource::kFlagAlignedVideoData) {
594c08aed51c5899665ade97263692328eea4af106cristy        parserFlags |= ATSParser::ALIGNED_VIDEO_DATA;
604c08aed51c5899665ade97263692328eea4af106cristy    }
614c08aed51c5899665ade97263692328eea4af106cristy
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mTSParser = new ATSParser(parserFlags);
634c08aed51c5899665ade97263692328eea4af106cristy
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mStreamListener->start();
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatus_t NuPlayer::StreamingSource::feedMoreTSData() {
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mFinalResult != OK) {
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return mFinalResult;
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (int32_t i = 0; i < 50; ++i) {
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        char buffer[188];
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        sp<AMessage> extra;
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra);
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
774c08aed51c5899665ade97263692328eea4af106cristy        if (n == 0) {
784c08aed51c5899665ade97263692328eea4af106cristy            ALOGI("input data EOS reached.");
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mTSParser->signalEOS(ERROR_END_OF_STREAM);
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mFinalResult = ERROR_END_OF_STREAM;
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        } else if (n == INFO_DISCONTINUITY) {
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int32_t type = ATSParser::DISCONTINUITY_SEEK;
8482fb921c181c918c50522e199e99c3f8fb8e9de9cristy
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int32_t mask;
86e85007d004da78a4e1dc7738d894a7074cce596dcristy            if (extra != NULL
87e85007d004da78a4e1dc7738d894a7074cce596dcristy                    && extra->findInt32(
88e85007d004da78a4e1dc7738d894a7074cce596dcristy                        IStreamListener::kKeyDiscontinuityMask, &mask)) {
8982fb921c181c918c50522e199e99c3f8fb8e9de9cristy                if (mask == 0) {
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ALOGE("Client specified an illegal discontinuity type.");
9182fb921c181c918c50522e199e99c3f8fb8e9de9cristy                    return ERROR_UNSUPPORTED;
926e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy                }
9382fb921c181c918c50522e199e99c3f8fb8e9de9cristy
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                type = mask;
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mTSParser->signalDiscontinuity(
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (ATSParser::DiscontinuityType)type, extra);
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        } else if (n < 0) {
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CHECK_EQ(n, -EWOULDBLOCK);
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        } else {
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (buffer[0] == 0x00) {
1044cfbb3f7630d4bbc6802b3fcab0cd12d29568b09cristy                // XXX legacy
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (extra == NULL) {
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    extra = new AMessage;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                uint8_t type = buffer[1];
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (type & 2) {
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int64_t mediaTimeUs;
11445410e265b897f36b60119f6058de5b40fd6a43acristy                    memcpy(&mediaTimeUs, &buffer[2], sizeof(mediaTimeUs));
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    extra->setInt64(IStreamListener::kKeyMediaTimeUs, mediaTimeUs);
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
118cd817dbc42df9e03ab07e744d7664b75c6bbd6e7cristy
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mTSParser->signalDiscontinuity(
120cd817dbc42df9e03ab07e744d7664b75c6bbd6e7cristy                        ((type & 1) == 0)
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            ? ATSParser::DISCONTINUITY_SEEK
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            : ATSParser::DISCONTINUITY_FORMATCHANGE,
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        extra);
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            } else {
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer));
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (err != OK) {
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ALOGE("TS Parser returned error %d", err);
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mTSParser->signalEOS(err);
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mFinalResult = err;
132cd817dbc42df9e03ab07e744d7664b75c6bbd6e7cristy                    break;
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
134cd817dbc42df9e03ab07e744d7664b75c6bbd6e7cristy            }
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return OK;
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1408949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy
141435135217c28e58091f120a40d903a7d583ae09acristysp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) {
1428949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy    ATSParser::SourceType type =
1438949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy        audio ? ATSParser::AUDIO : ATSParser::VIDEO;
1448949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy
145435135217c28e58091f120a40d903a7d583ae09acristy    sp<AnotherPacketSource> source =
1468949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
147435135217c28e58091f120a40d903a7d583ae09acristy
1488949e8ebc70d389b6b7b71dae3fec4d9becee2d9cristy    if (source == NULL) {
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return NULL;
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1529d4918ba8d9ac4309651dfca5c74223ab66fd651cristy    return source->getFormat();
1539d4918ba8d9ac4309651dfca5c74223ab66fd651cristy}
1549d4918ba8d9ac4309651dfca5c74223ab66fd651cristy
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatus_t NuPlayer::StreamingSource::dequeueAccessUnit(
156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        bool audio, sp<ABuffer> *accessUnit) {
1579d4918ba8d9ac4309651dfca5c74223ab66fd651cristy    ATSParser::SourceType type =
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        audio ? ATSParser::AUDIO : ATSParser::VIDEO;
159bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp<AnotherPacketSource> source =
161e11d00a2297e64c259caa230157bc19f380e9f84cristy        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
162e11d00a2297e64c259caa230157bc19f380e9f84cristy
163e11d00a2297e64c259caa230157bc19f380e9f84cristy    if (source == NULL) {
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return -EWOULDBLOCK;
1655f766ef8b0cd9906c2c3a56d845828380a251073cristy    }
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status_t finalResult;
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (!source->hasBufferAvailable(&finalResult)) {
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return finalResult == OK ? -EWOULDBLOCK : finalResult;
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17271b27171ca760d049f5d6e9716649e08a9fbe6aecristy    status_t err = source->dequeueAccessUnit(accessUnit);
17305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
17571b27171ca760d049f5d6e9716649e08a9fbe6aecristy    if (err == OK) {
17605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk        int64_t timeUs;
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
178b1253cd7764d10cb086c738ec6dc399ed078a3f3cristy        ALOGV("dequeueAccessUnit timeUs=%lld us", timeUs);
179b1253cd7764d10cb086c738ec6dc399ed078a3f3cristy    }
180b1253cd7764d10cb086c738ec6dc399ed078a3f3cristy#endif
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return err;
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool NuPlayer::StreamingSource::isRealTime() const {
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return mSource->flags() & IStreamSource::kFlagIsRealTimeData;
187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy}
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}  // namespace android
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy