diff options
author | Nicolas Catania <niko@google.com> | 2009-05-12 23:25:55 -0700 |
---|---|---|
committer | niko <niko@google.com> | 2009-06-24 08:22:52 -0700 |
commit | 20cb94eeb5b9672573fc86bf51e09bd66a774581 (patch) | |
tree | 138919c0c2fd32e1c0185e726be3d6b5debee065 /media/libmedia | |
parent | 5a12373277f6ce14101f08580bc4f08f9a3d7c50 (diff) | |
download | frameworks_base-20cb94eeb5b9672573fc86bf51e09bd66a774581.zip frameworks_base-20cb94eeb5b9672573fc86bf51e09bd66a774581.tar.gz frameworks_base-20cb94eeb5b9672573fc86bf51e09bd66a774581.tar.bz2 |
Direct api to the native media player.
MediaPlayer.java has 3 new methods:
* newRequest creates a Parcel that can be used to send data to the
native player using invoke.
* invoke issues synchronous calls to the native player using opaque
parcels for the request and reply.
IMediaPlayer.h has 1 new abstract method:
* invoke
The Midi and Vorbis players have a stub for these. So far only PV
makes use of that new feature.
To avoid any copy overhead, the JNI interface uses Parcel as a java
object (no serialization/copy happens at the JNI layer).
The remote interface token is inserted when the Parcel is constructed
in java. That way the parcel is already routable when it reaches
IMediaPlayer.cpp (proxy). No extra copy is needed there.
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 15 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayerService.cpp | 1 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 14 |
3 files changed, 29 insertions, 1 deletions
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index fa2d81d..3f278f4 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -39,7 +39,8 @@ enum { RESET, SET_AUDIO_STREAM_TYPE, SET_LOOPING, - SET_VOLUME + SET_VOLUME, + INVOKE, }; class BpMediaPlayer: public BpInterface<IMediaPlayer> @@ -170,6 +171,13 @@ public: remote()->transact(SET_VOLUME, data, &reply); return reply.readInt32(); } + + status_t invoke(const Parcel& request, Parcel *reply) + { // Avoid doing any extra copy. The interface descriptor should + // have been set by MediaPlayer.java. + status_t retcode = remote()->transact(INVOKE, request, reply); + return retcode; + } }; IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); @@ -260,6 +268,11 @@ status_t BnMediaPlayer::onTransact( reply->writeInt32(setVolume(data.readFloat(), data.readFloat())); return NO_ERROR; } break; + case INVOKE: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + invoke(data, reply); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index 33b3e22..0f64259 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -20,6 +20,7 @@ #include <binder/Parcel.h> #include <binder/IMemory.h> +#include <utils/Errors.h> // for status_t #include <media/IMediaPlayerService.h> #include <media/IMediaRecorder.h> diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 220c998..4683166 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -196,6 +196,20 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) return err; } +status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) +{ + Mutex::Autolock _l(mLock); + if ((mPlayer != NULL) && ( mCurrentState & MEDIA_PLAYER_INITIALIZED )) + { + LOGV("invoke %d", request.dataSize()); + return mPlayer->invoke(request, reply); + } + LOGE("invoke failed: wrong state %X", mCurrentState); + return INVALID_OPERATION; +} + + + status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface) { LOGV("setVideoSurface"); |