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> ¬ify, 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