1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "StreamingSource" 19 #include <utils/Log.h> 20 21 #include "StreamingSource.h" 22 23 #include "ATSParser.h" 24 #include "AnotherPacketSource.h" 25 #include "NuPlayerStreamListener.h" 26 27 #include <media/stagefright/foundation/ABuffer.h> 28 #include <media/stagefright/foundation/ADebug.h> 29 #include <media/stagefright/foundation/AMessage.h> 30 #include <media/stagefright/MediaSource.h> 31 #include <media/stagefright/MetaData.h> 32 33 namespace android { 34 35 NuPlayer::StreamingSource::StreamingSource(const sp<IStreamSource> &source) 36 : mSource(source), 37 mFinalResult(OK) { 38 } 39 40 NuPlayer::StreamingSource::~StreamingSource() { 41 } 42 43 void NuPlayer::StreamingSource::start() { 44 mStreamListener = new NuPlayerStreamListener(mSource, 0); 45 mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE); 46 47 mStreamListener->start(); 48 } 49 50 status_t NuPlayer::StreamingSource::feedMoreTSData() { 51 if (mFinalResult != OK) { 52 return mFinalResult; 53 } 54 55 for (int32_t i = 0; i < 50; ++i) { 56 char buffer[188]; 57 sp<AMessage> extra; 58 ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra); 59 60 if (n == 0) { 61 LOGI("input data EOS reached."); 62 mTSParser->signalEOS(ERROR_END_OF_STREAM); 63 mFinalResult = ERROR_END_OF_STREAM; 64 break; 65 } else if (n == INFO_DISCONTINUITY) { 66 int32_t type = ATSParser::DISCONTINUITY_SEEK; 67 68 int32_t mask; 69 if (extra != NULL 70 && extra->findInt32( 71 IStreamListener::kKeyDiscontinuityMask, &mask)) { 72 if (mask == 0) { 73 LOGE("Client specified an illegal discontinuity type."); 74 return ERROR_UNSUPPORTED; 75 } 76 77 type = mask; 78 } 79 80 mTSParser->signalDiscontinuity( 81 (ATSParser::DiscontinuityType)type, extra); 82 } else if (n < 0) { 83 CHECK_EQ(n, -EWOULDBLOCK); 84 break; 85 } else { 86 if (buffer[0] == 0x00) { 87 // XXX legacy 88 mTSParser->signalDiscontinuity( 89 buffer[1] == 0x00 90 ? ATSParser::DISCONTINUITY_SEEK 91 : ATSParser::DISCONTINUITY_FORMATCHANGE, 92 extra); 93 } else { 94 status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); 95 96 if (err != OK) { 97 LOGE("TS Parser returned error %d", err); 98 99 mTSParser->signalEOS(err); 100 mFinalResult = err; 101 break; 102 } 103 } 104 } 105 } 106 107 return OK; 108 } 109 110 sp<MetaData> NuPlayer::StreamingSource::getFormat(bool audio) { 111 ATSParser::SourceType type = 112 audio ? ATSParser::AUDIO : ATSParser::VIDEO; 113 114 sp<AnotherPacketSource> source = 115 static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); 116 117 if (source == NULL) { 118 return NULL; 119 } 120 121 return source->getFormat(); 122 } 123 124 status_t NuPlayer::StreamingSource::dequeueAccessUnit( 125 bool audio, sp<ABuffer> *accessUnit) { 126 ATSParser::SourceType type = 127 audio ? ATSParser::AUDIO : ATSParser::VIDEO; 128 129 sp<AnotherPacketSource> source = 130 static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); 131 132 if (source == NULL) { 133 return -EWOULDBLOCK; 134 } 135 136 status_t finalResult; 137 if (!source->hasBufferAvailable(&finalResult)) { 138 return finalResult == OK ? -EWOULDBLOCK : finalResult; 139 } 140 141 return source->dequeueAccessUnit(accessUnit); 142 } 143 144 } // namespace android 145 146