diff options
author | Andreas Huber <andih@google.com> | 2010-12-15 15:17:42 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-12-15 15:18:26 -0800 |
commit | f933441648ef6a71dee783d733aac17b9508b452 (patch) | |
tree | 240f8068edb362cbea579659a963bbb029a2bac0 /media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp | |
parent | 60c5b57edd3c8f4bdf6b38cf5b8a193ba770bb72 (diff) | |
download | frameworks_av-f933441648ef6a71dee783d733aac17b9508b452.zip frameworks_av-f933441648ef6a71dee783d733aac17b9508b452.tar.gz frameworks_av-f933441648ef6a71dee783d733aac17b9508b452.tar.bz2 |
Initial support for a true streaming player for mpeg2 transport streams.
Change-Id: I153eec439d260a5524b21270e16d36940ec3161a
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp new file mode 100644 index 0000000..92642a8 --- /dev/null +++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "NuPlayerStreamListener" +#include <utils/Log.h> + +#include "NuPlayerStreamListener.h" + +#include <binder/MemoryDealer.h> +#include <media/stagefright/foundation/ADebug.h> + +namespace android { + +NuPlayer::NuPlayerStreamListener::NuPlayerStreamListener( + const sp<IStreamSource> &source, + ALooper::handler_id id) + : mSource(source), + mTargetID(id), + mEOS(false), + mSendDataNotification(true) { + mSource->setListener(this); + + mMemoryDealer = new MemoryDealer(kNumBuffers * kBufferSize); + for (size_t i = 0; i < kNumBuffers; ++i) { + sp<IMemory> mem = mMemoryDealer->allocate(kBufferSize); + CHECK(mem != NULL); + + mBuffers.push(mem); + } + mSource->setBuffers(mBuffers); +} + +void NuPlayer::NuPlayerStreamListener::start() { + for (size_t i = 0; i < kNumBuffers; ++i) { + mSource->onBufferAvailable(i); + } +} + +void NuPlayer::NuPlayerStreamListener::queueBuffer(size_t index, size_t size) { + QueueEntry entry; + entry.mIsCommand = false; + entry.mIndex = index; + entry.mSize = size; + entry.mOffset = 0; + + Mutex::Autolock autoLock(mLock); + mQueue.push_back(entry); + + if (mSendDataNotification) { + mSendDataNotification = false; + (new AMessage(kWhatMoreDataQueued, mTargetID))->post(); + } +} + +void NuPlayer::NuPlayerStreamListener::issueCommand( + Command cmd, bool synchronous, const sp<AMessage> &extra) { + CHECK(!synchronous); + + QueueEntry entry; + entry.mIsCommand = true; + entry.mCommand = cmd; + entry.mExtra = extra; + + Mutex::Autolock autoLock(mLock); + mQueue.push_back(entry); + + if (mSendDataNotification) { + mSendDataNotification = false; + (new AMessage(kWhatMoreDataQueued, mTargetID))->post(); + } +} + +ssize_t NuPlayer::NuPlayerStreamListener::read(void *data, size_t size) { + CHECK_GT(size, 0u); + + Mutex::Autolock autoLock(mLock); + + if (mEOS) { + return 0; + } + + if (mQueue.empty()) { + mSendDataNotification = true; + + return -EWOULDBLOCK; + } + + QueueEntry *entry = &*mQueue.begin(); + + if (entry->mIsCommand) { + switch (entry->mCommand) { + case EOS: + { + mQueue.erase(mQueue.begin()); + entry = NULL; + + mEOS = true; + return 0; + } + + case DISCONTINUITY: + { + mQueue.erase(mQueue.begin()); + entry = NULL; + + return INFO_DISCONTINUITY; + } + + default: + TRESPASS(); + break; + } + } + + size_t copy = entry->mSize; + if (copy > size) { + copy = size; + } + + memcpy(data, + (const uint8_t *)mBuffers.editItemAt(entry->mIndex)->pointer() + + entry->mOffset, + copy); + + entry->mOffset += copy; + entry->mSize -= copy; + + if (entry->mSize == 0) { + mSource->onBufferAvailable(entry->mIndex); + mQueue.erase(mQueue.begin()); + entry = NULL; + } + + return copy; +} + +} // namespace android |