AnotherPacketSource.cpp revision f69e53033f23f9f70fcdb28a3c2e650de0147459
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#include "AnotherPacketSource.h" 18 19#include <media/stagefright/foundation/ABuffer.h> 20#include <media/stagefright/foundation/ADebug.h> 21#include <media/stagefright/foundation/AMessage.h> 22#include <media/stagefright/foundation/AString.h> 23#include <media/stagefright/foundation/hexdump.h> 24#include <media/stagefright/MediaBuffer.h> 25#include <media/stagefright/MediaDefs.h> 26#include <media/stagefright/MetaData.h> 27#include <utils/Vector.h> 28 29namespace android { 30 31AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta) 32 : mIsAudio(false), 33 mFormat(meta), 34 mEOSResult(OK) { 35 const char *mime; 36 CHECK(meta->findCString(kKeyMIMEType, &mime)); 37 38 if (!strncasecmp("audio/", mime, 6)) { 39 mIsAudio = true; 40 } else { 41 CHECK(!strncasecmp("video/", mime, 6)); 42 } 43} 44 45void AnotherPacketSource::setFormat(const sp<MetaData> &meta) { 46 CHECK(mFormat == NULL); 47 mFormat = meta; 48} 49 50AnotherPacketSource::~AnotherPacketSource() { 51} 52 53status_t AnotherPacketSource::start(MetaData *params) { 54 return OK; 55} 56 57status_t AnotherPacketSource::stop() { 58 return OK; 59} 60 61sp<MetaData> AnotherPacketSource::getFormat() { 62 return mFormat; 63} 64 65status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) { 66 buffer->clear(); 67 68 Mutex::Autolock autoLock(mLock); 69 while (mEOSResult == OK && mBuffers.empty()) { 70 mCondition.wait(mLock); 71 } 72 73 if (!mBuffers.empty()) { 74 *buffer = *mBuffers.begin(); 75 mBuffers.erase(mBuffers.begin()); 76 77 int32_t discontinuity; 78 if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) { 79 if (wasFormatChange(discontinuity)) { 80 mFormat.clear(); 81 } 82 83 return INFO_DISCONTINUITY; 84 } 85 86 return OK; 87 } 88 89 return mEOSResult; 90} 91 92status_t AnotherPacketSource::read( 93 MediaBuffer **out, const ReadOptions *) { 94 *out = NULL; 95 96 Mutex::Autolock autoLock(mLock); 97 while (mEOSResult == OK && mBuffers.empty()) { 98 mCondition.wait(mLock); 99 } 100 101 if (!mBuffers.empty()) { 102 const sp<ABuffer> buffer = *mBuffers.begin(); 103 mBuffers.erase(mBuffers.begin()); 104 105 int32_t discontinuity; 106 if (buffer->meta()->findInt32("discontinuity", &discontinuity)) { 107 if (wasFormatChange(discontinuity)) { 108 mFormat.clear(); 109 } 110 111 return INFO_DISCONTINUITY; 112 } else { 113 int64_t timeUs; 114 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 115 116 MediaBuffer *mediaBuffer = new MediaBuffer(buffer); 117 118 mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs); 119 120 *out = mediaBuffer; 121 return OK; 122 } 123 } 124 125 return mEOSResult; 126} 127 128bool AnotherPacketSource::wasFormatChange( 129 int32_t discontinuityType) const { 130 if (mIsAudio) { 131 return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; 132 } 133 134 return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0; 135} 136 137void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { 138 int32_t damaged; 139 if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { 140 // LOG(VERBOSE) << "discarding damaged AU"; 141 return; 142 } 143 144 int64_t timeUs; 145 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 146 ALOGV("queueAccessUnit timeUs=%lld us (%.2f secs)", timeUs, timeUs / 1E6); 147 148 Mutex::Autolock autoLock(mLock); 149 mBuffers.push_back(buffer); 150 mCondition.signal(); 151} 152 153void AnotherPacketSource::queueDiscontinuity( 154 ATSParser::DiscontinuityType type, 155 const sp<AMessage> &extra) { 156 Mutex::Autolock autoLock(mLock); 157 158 // Leave only discontinuities in the queue. 159 List<sp<ABuffer> >::iterator it = mBuffers.begin(); 160 while (it != mBuffers.end()) { 161 sp<ABuffer> oldBuffer = *it; 162 163 int32_t oldDiscontinuityType; 164 if (!oldBuffer->meta()->findInt32( 165 "discontinuity", &oldDiscontinuityType)) { 166 it = mBuffers.erase(it); 167 continue; 168 } 169 170 ++it; 171 } 172 173 mEOSResult = OK; 174 175 sp<ABuffer> buffer = new ABuffer(0); 176 buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type)); 177 buffer->meta()->setMessage("extra", extra); 178 179 mBuffers.push_back(buffer); 180 mCondition.signal(); 181} 182 183void AnotherPacketSource::signalEOS(status_t result) { 184 CHECK(result != OK); 185 186 Mutex::Autolock autoLock(mLock); 187 mEOSResult = result; 188 mCondition.signal(); 189} 190 191bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) { 192 Mutex::Autolock autoLock(mLock); 193 if (!mBuffers.empty()) { 194 return true; 195 } 196 197 *finalResult = mEOSResult; 198 return false; 199} 200 201status_t AnotherPacketSource::nextBufferTime(int64_t *timeUs) { 202 *timeUs = 0; 203 204 Mutex::Autolock autoLock(mLock); 205 206 if (mBuffers.empty()) { 207 return mEOSResult != OK ? mEOSResult : -EWOULDBLOCK; 208 } 209 210 sp<ABuffer> buffer = *mBuffers.begin(); 211 CHECK(buffer->meta()->findInt64("timeUs", timeUs)); 212 213 return OK; 214} 215 216} // namespace android 217