StreamingSource.cpp revision 5205152968957c51b597ddeabe6a5e17b2a84e38
14e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek/* 24e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * Copyright (C) 2010 The Android Open Source Project 34e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * 44e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * Licensed under the Apache License, Version 2.0 (the "License"); 54e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * you may not use this file except in compliance with the License. 64e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * You may obtain a copy of the License at 74e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * 84e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * http://www.apache.org/licenses/LICENSE-2.0 94e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * 104e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * Unless required by applicable law or agreed to in writing, software 114e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * distributed under the License is distributed on an "AS IS" BASIS, 124e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * See the License for the specific language governing permissions and 144e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek * limitations under the License. 154e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek */ 164e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 174e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek//#define LOG_NDEBUG 0 184e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#define LOG_TAG "StreamingSource" 194e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include <utils/Log.h> 204e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 214e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include "StreamingSource.h" 224e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 234e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include "ATSParser.h" 244e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include "AnotherPacketSource.h" 254e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include "NuPlayerStreamListener.h" 264e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 274e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include <media/stagefright/foundation/ABuffer.h> 284e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include <media/stagefright/foundation/ADebug.h> 294e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include <media/stagefright/foundation/AMessage.h> 304e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#include <media/stagefright/MediaSource.h> 31a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roos#include <media/stagefright/MetaData.h> 324e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 33a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roosnamespace android { 34a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roos 354e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim CinekNuPlayer::StreamingSource::StreamingSource(const sp<IStreamSource> &source) 364e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek : mSource(source), 37a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roos mFinalResult(OK) { 38a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roos} 39a48caee9a717afe80a2210e5db3a4d6dabd952b5Adrian Roos 404e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim CinekNuPlayer::StreamingSource::~StreamingSource() { 414e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek} 424e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 434e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinekvoid NuPlayer::StreamingSource::start() { 444e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mStreamListener = new NuPlayerStreamListener(mSource, 0); 454e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 464e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek uint32_t sourceFlags = mSource->flags(); 474e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 484e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek uint32_t parserFlags = ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE; 494e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (sourceFlags & IStreamSource::kFlagAlignedVideoData) { 504e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek parserFlags |= ATSParser::ALIGNED_VIDEO_DATA; 514e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 524e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 534e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mTSParser = new ATSParser(parserFlags); 544e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 554e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mStreamListener->start(); 564e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek} 574e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 584e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinekstatus_t NuPlayer::StreamingSource::feedMoreTSData() { 594e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (mFinalResult != OK) { 604e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return mFinalResult; 614e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 624e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 634e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek for (int32_t i = 0; i < 50; ++i) { 644e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek char buffer[188]; 654e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek sp<AMessage> extra; 664e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra); 674e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 684e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (n == 0) { 694e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ALOGI("input data EOS reached."); 704e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mTSParser->signalEOS(ERROR_END_OF_STREAM); 714e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mFinalResult = ERROR_END_OF_STREAM; 724e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek break; 734e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } else if (n == INFO_DISCONTINUITY) { 744e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek int32_t type = ATSParser::DISCONTINUITY_SEEK; 754e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 764e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek int32_t mask; 774e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (extra != NULL 784e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek && extra->findInt32( 794e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek IStreamListener::kKeyDiscontinuityMask, &mask)) { 804e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (mask == 0) { 814e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ALOGE("Client specified an illegal discontinuity type."); 824e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return ERROR_UNSUPPORTED; 834e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 844e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 854e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek type = mask; 864e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 874e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 884e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mTSParser->signalDiscontinuity( 894e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek (ATSParser::DiscontinuityType)type, extra); 904e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } else if (n < 0) { 914e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek CHECK_EQ(n, -EWOULDBLOCK); 924e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek break; 934e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } else { 944e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (buffer[0] == 0x00) { 9509eb0337b760c74d73a614edfdc7eaa6e083a29fXiyuan Xia // XXX legacy 9609eb0337b760c74d73a614edfdc7eaa6e083a29fXiyuan Xia mTSParser->signalDiscontinuity( 9709eb0337b760c74d73a614edfdc7eaa6e083a29fXiyuan Xia buffer[1] == 0x00 9809eb0337b760c74d73a614edfdc7eaa6e083a29fXiyuan Xia ? ATSParser::DISCONTINUITY_SEEK 9909eb0337b760c74d73a614edfdc7eaa6e083a29fXiyuan Xia : ATSParser::DISCONTINUITY_FORMATCHANGE, 1004e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek extra); 1014e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } else { 1024e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); 1034e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1044e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (err != OK) { 1054e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ALOGE("TS Parser returned error %d", err); 1064e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1074e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mTSParser->signalEOS(err); 1084e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek mFinalResult = err; 1094e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek break; 1104e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1114e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1124e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1134e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1144e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1154e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return OK; 1164e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek} 1174e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1184e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cineksp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) { 1194e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ATSParser::SourceType type = 1204e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek audio ? ATSParser::AUDIO : ATSParser::VIDEO; 1214e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1224e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek sp<AnotherPacketSource> source = 1234e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); 1244e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1254e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (source == NULL) { 1264e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return NULL; 1274e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1284e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1294e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return source->getFormat(); 1304e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek} 1314e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1324e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinekstatus_t NuPlayer::StreamingSource::dequeueAccessUnit( 1334e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek bool audio, sp<ABuffer> *accessUnit) { 1344e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ATSParser::SourceType type = 1354e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek audio ? ATSParser::AUDIO : ATSParser::VIDEO; 1364e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1374e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek sp<AnotherPacketSource> source = 1384e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); 1394e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1404e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (source == NULL) { 1414e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return -EWOULDBLOCK; 1424e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1434e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1444e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek status_t finalResult; 1454e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (!source->hasBufferAvailable(&finalResult)) { 1464e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek return finalResult == OK ? -EWOULDBLOCK : finalResult; 1474e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1484e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1494e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek status_t err = source->dequeueAccessUnit(accessUnit); 1504e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1514e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0 1524e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek if (err == OK) { 1534e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek int64_t timeUs; 1544e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 1554e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek ALOGV("dequeueAccessUnit timeUs=%lld us", timeUs); 1564e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek } 1574e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek#endif 1584e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek 1596380482d081e557164393417370e0c5da22a5bdaSelim Cinek return err; 1606380482d081e557164393417370e0c5da22a5bdaSelim Cinek} 1616380482d081e557164393417370e0c5da22a5bdaSelim Cinek 1626380482d081e557164393417370e0c5da22a5bdaSelim Cinek} // namespace android 1636380482d081e557164393417370e0c5da22a5bdaSelim Cinek 1644e8b9ed30b67e5449d987e674b2966dc7f3ac224Selim Cinek