summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-11-23 11:41:34 -0800
committerAndreas Huber <andih@google.com>2010-11-23 14:46:13 -0800
commite2b1028852120bcfded33b8f06f66b780437fe92 (patch)
treea524b579935df0a8773e780299e31b590d1bdb44 /media/libmedia
parent31d7235c79667f88002d9ad87207099ed438a197 (diff)
downloadframeworks_av-e2b1028852120bcfded33b8f06f66b780437fe92.zip
frameworks_av-e2b1028852120bcfded33b8f06f66b780437fe92.tar.gz
frameworks_av-e2b1028852120bcfded33b8f06f66b780437fe92.tar.bz2
Support streaming data across binder boundaries.
Change-Id: Ifbac61406dcb81343765f99ccba08bd90f9274cc
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/Android.mk1
-rw-r--r--media/libmedia/IMediaPlayerService.cpp38
-rw-r--r--media/libmedia/IStreamSource.cpp168
3 files changed, 207 insertions, 0 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 2e5cbe3..731c09d 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -15,6 +15,7 @@ LOCAL_SRC_FILES:= \
IMediaRecorderClient.cpp \
IMediaPlayer.cpp \
IMediaRecorder.cpp \
+ IStreamSource.cpp \
Metadata.cpp \
mediarecorder.cpp \
IMediaMetadataRetriever.cpp \
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 4abfa75..77199e1 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -23,6 +23,7 @@
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/IOMX.h>
+#include <media/IStreamSource.h>
#include <utils/Errors.h> // for status_t
@@ -31,6 +32,7 @@ namespace android {
enum {
CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
CREATE_FD,
+ CREATE_STREAM,
DECODE_URL,
DECODE_FD,
CREATE_MEDIA_RECORDER,
@@ -107,6 +109,21 @@ public:
return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
}
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient> &client,
+ const sp<IStreamSource> &source, int audioSessionId) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(pid));
+ data.writeStrongBinder(client->asBinder());
+ data.writeStrongBinder(source->asBinder());
+ data.writeInt32(static_cast<int32_t>(audioSessionId));
+
+ remote()->transact(CREATE_STREAM, data, &reply);
+
+ return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
+ }
+
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
{
Parcel data, reply;
@@ -184,6 +201,27 @@ status_t BnMediaPlayerService::onTransact(
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
+ case CREATE_STREAM:
+ {
+ CHECK_INTERFACE(IMediaPlayerService, data, reply);
+
+ pid_t pid = static_cast<pid_t>(data.readInt32());
+
+ sp<IMediaPlayerClient> client =
+ interface_cast<IMediaPlayerClient>(data.readStrongBinder());
+
+ sp<IStreamSource> source =
+ interface_cast<IStreamSource>(data.readStrongBinder());
+
+ int audioSessionId = static_cast<int>(data.readInt32());
+
+ sp<IMediaPlayer> player =
+ create(pid, client, source, audioSessionId);
+
+ reply->writeStrongBinder(player->asBinder());
+ return OK;
+ break;
+ }
case DECODE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const char* url = data.readCString();
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
new file mode 100644
index 0000000..89f2b44
--- /dev/null
+++ b/media/libmedia/IStreamSource.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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 "IStreamSource"
+#include <utils/Log.h>
+
+#include <media/IStreamSource.h>
+
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+ // IStreamSource
+ SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
+ SET_BUFFERS,
+ ON_BUFFER_AVAILABLE,
+
+ // IStreamListener
+ QUEUE_BUFFER,
+ QUEUE_COMMAND,
+};
+
+struct BpStreamSource : public BpInterface<IStreamSource> {
+ BpStreamSource(const sp<IBinder> &impl)
+ : BpInterface<IStreamSource>(impl) {
+ }
+
+ virtual void setListener(const sp<IStreamListener> &listener) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+ remote()->transact(SET_LISTENER, data, &reply);
+ }
+
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(buffers.size()));
+ for (size_t i = 0; i < buffers.size(); ++i) {
+ data.writeStrongBinder(buffers.itemAt(i)->asBinder());
+ }
+ remote()->transact(SET_BUFFERS, data, &reply);
+ }
+
+ virtual void onBufferAvailable(size_t index) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(index));
+ remote()->transact(
+ ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource");
+
+status_t BnStreamSource::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case SET_LISTENER:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ setListener(
+ interface_cast<IStreamListener>(data.readStrongBinder()));
+ break;
+ }
+
+ case SET_BUFFERS:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ size_t n = static_cast<size_t>(data.readInt32());
+ Vector<sp<IMemory> > buffers;
+ for (size_t i = 0; i < n; ++i) {
+ sp<IMemory> mem =
+ interface_cast<IMemory>(data.readStrongBinder());
+
+ buffers.push(mem);
+ }
+ setBuffers(buffers);
+ break;
+ }
+
+ case ON_BUFFER_AVAILABLE:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ onBufferAvailable(static_cast<size_t>(data.readInt32()));
+ break;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+
+ return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct BpStreamListener : public BpInterface<IStreamListener> {
+ BpStreamListener(const sp<IBinder> &impl)
+ : BpInterface<IStreamListener>(impl) {
+ }
+
+ virtual void queueBuffer(size_t index, size_t size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(index));
+ data.writeInt32(static_cast<int32_t>(size));
+
+ remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual void queueCommand(Command cmd) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(cmd));
+
+ remote()->transact(QUEUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener");
+
+status_t BnStreamListener::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case QUEUE_BUFFER:
+ {
+ CHECK_INTERFACE(IStreamListener, data, reply);
+ size_t index = static_cast<size_t>(data.readInt32());
+ size_t size = static_cast<size_t>(data.readInt32());
+
+ queueBuffer(index, size);
+ break;
+ }
+
+ case QUEUE_COMMAND:
+ {
+ CHECK_INTERFACE(IStreamListener, data, reply);
+ Command cmd = static_cast<Command>(data.readInt32());
+
+ queueCommand(cmd);
+ break;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+
+ return OK;
+}
+
+} // namespace android