summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-12-15 15:17:42 -0800
committerAndreas Huber <andih@google.com>2010-12-15 15:18:26 -0800
commitf933441648ef6a71dee783d733aac17b9508b452 (patch)
tree240f8068edb362cbea579659a963bbb029a2bac0 /media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
parent60c5b57edd3c8f4bdf6b38cf5b8a193ba770bb72 (diff)
downloadframeworks_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.cpp151
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