diff options
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r-- | media/libmediaplayerservice/Android.mk | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 217 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 40 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaRecorderClient.cpp | 8 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.h | 7 | ||||
-rw-r--r-- | media/libmediaplayerservice/MidiFile.h | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/VorbisPlayer.h | 2 |
8 files changed, 269 insertions, 18 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index f7f2490..0877142 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -20,6 +20,7 @@ endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ + libbinder \ libvorbisidec \ libsonivox \ libopencore_player \ diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 31eecac..493dc13 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -27,13 +27,21 @@ #include <unistd.h> #include <string.h> + #include <cutils/atomic.h> +#include <cutils/properties.h> + +#include <utils/misc.h> #include <android_runtime/ActivityManager.h> -#include <utils/IPCThreadState.h> -#include <utils/IServiceManager.h> -#include <utils/MemoryHeapBase.h> -#include <utils/MemoryBase.h> + +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> +#include <utils/Errors.h> // for status_t +#include <utils/String8.h> +#include <utils/Vector.h> #include <cutils/properties.h> #include <media/MediaPlayerInterface.h> @@ -41,6 +49,8 @@ #include <media/MediaMetadataRetrieverInterface.h> #include <media/AudioTrack.h> +#include <utils/SortedVector.h> + #include "MediaRecorderClient.h" #include "MediaPlayerService.h" #include "MetadataRetrieverClient.h" @@ -61,6 +71,112 @@ pid_t gettid() { return syscall(__NR_gettid);} #undef __KERNEL__ #endif +namespace { +using android::status_t; +using android::OK; +using android::BAD_VALUE; +using android::NOT_ENOUGH_DATA; +using android::MetadataType; +using android::Parcel; +using android::SortedVector; + +// Max number of entries in the filter. +const int kMaxFilterSize = 64; // I pulled that out of thin air. + +// Keep in sync with ANY in Metadata.java +const int32_t kAny = 0; + + +// Unmarshall a filter from a Parcel. +// Filter format in a parcel: +// +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | number of entries (n) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | metadata type 1 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | metadata type 2 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// .... +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | metadata type n | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// @param p Parcel that should start with a filter. +// @param[out] filter On exit contains the list of metadata type to be +// filtered. +// @param[out] status On exit contains the status code to be returned. +// @return true if the parcel starts with a valid filter. +bool unmarshallFilter(const Parcel& p, + SortedVector<MetadataType> *filter, + status_t *status) +{ + int32_t val; + if (p.readInt32(&val) != OK) + { + LOGE("Failed to read filter's length"); + *status = NOT_ENOUGH_DATA; + return false; + } + + if( val > kMaxFilterSize || val < 0) + { + LOGE("Invalid filter len %d", val); + *status = BAD_VALUE; + return false; + } + + const size_t num = val; + + filter->clear(); + filter->setCapacity(num); + + size_t size = num * sizeof(MetadataType); + + + if (p.dataAvail() < size) + { + LOGE("Filter too short expected %d but got %d", size, p.dataAvail()); + *status = NOT_ENOUGH_DATA; + return false; + } + + const MetadataType *data = static_cast<const MetadataType*>(p.readInplace(size)); + + if (NULL == data) + { + LOGE("Filter had no data"); + *status = BAD_VALUE; + return false; + } + + // TODO: The stl impl of vector would be more efficient here + // because it degenerates into a memcpy on pod types. Try to + // replace later or use stl::set. + for (size_t i = 0; i < num; ++i) + { + filter->add(*data); + ++data; + } + *status = OK; + return true; +} + +// @param filter Of metadata type. +// @param val To be searched. +// @return true if a match was found. +bool findMetadata(const SortedVector<MetadataType>& filter, const int32_t val) +{ + // Deal with empty and ANY right away + if (filter.isEmpty()) return false; + if (filter[0] == kAny) return true; + + return filter.indexOf(val) >= 0; +} + +} // anonymous namespace + namespace android { @@ -105,7 +221,11 @@ MediaPlayerService::~MediaPlayerService() sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid) { +#ifndef NO_OPENCORE sp<MediaRecorderClient> recorder = new MediaRecorderClient(pid); +#else + sp<MediaRecorderClient> recorder = NULL; +#endif LOGV("Create new media recorder client from pid %d", pid); return recorder; } @@ -532,10 +652,12 @@ static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, { sp<MediaPlayerBase> p; switch (playerType) { +#ifndef NO_OPENCORE case PV_PLAYER: LOGV(" create PVPlayer"); p = new PVPlayer(); break; +#endif case SONIVOX_PLAYER: LOGV(" create MidiFile"); p = new MidiFile(); @@ -665,6 +787,55 @@ status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface return p->setVideoSurface(surface); } +status_t MediaPlayerService::Client::invoke(const Parcel& request, + Parcel *reply) +{ + sp<MediaPlayerBase> p = getPlayer(); + if (p == NULL) return UNKNOWN_ERROR; + return p->invoke(request, reply); +} + +// This call doesn't need to access the native player. +status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter) +{ + status_t status; + SortedVector<MetadataType> allow, drop; + + if (unmarshallFilter(filter, &allow, &status) && + unmarshallFilter(filter, &drop, &status)) { + Mutex::Autolock lock(mLock); + + mMetadataAllow = allow; + mMetadataDrop = drop; + } + return status; +} + +status_t MediaPlayerService::Client::getMetadata( + bool update_only, bool apply_filter, Parcel *reply) +{ + status_t status; + reply->writeInt32(-1); // Placeholder for the return code + + SortedVector<MetadataType> updates; + + // We don't block notifications while we fetch the data. We clear + // mMetadataUpdated first so we don't lose notifications happening + // during the rest of this call. + { + Mutex::Autolock lock(mLock); + if (update_only) { + updates = mMetadataUpdated; + } + mMetadataUpdated.clear(); + } + + // FIXME: Implement, query the native player and do the optional filtering, etc... + status = OK; + + return status; +} + status_t MediaPlayerService::Client::prepareAsync() { LOGV("[%d] prepareAsync", mConnId); @@ -784,13 +955,51 @@ status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolu return NO_ERROR; } + void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) { Client* client = static_cast<Client*>(cookie); + + if (MEDIA_INFO == msg && + MEDIA_INFO_METADATA_UPDATE == ext1) { + const MetadataType metadata_type = ext2; + + if(client->shouldDropMetadata(metadata_type)) { + return; + } + + // Update the list of metadata that have changed. getMetadata + // also access mMetadataUpdated and clears it. + client->addNewMetadataUpdate(metadata_type); + } LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); client->mClient->notify(msg, ext1, ext2); } + +bool MediaPlayerService::Client::shouldDropMetadata(MetadataType code) const +{ + Mutex::Autolock lock(mLock); + + if (findMetadata(mMetadataDrop, code)) { + return true; + } + + if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) { + return false; + } else { + return true; + } +} + + +void MediaPlayerService::Client::addNewMetadataUpdate(MetadataType metadata_type) { + Mutex::Autolock lock(mLock); + if (mMetadataUpdated.indexOf(metadata_type) < 0) { + mMetadataUpdated.add(metadata_type); + } +} + #if CALLBACK_ANTAGONIZER const int Antagonizer::interval = 10000; // 10 msecs diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index f138886..db3d5d7 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -18,14 +18,20 @@ #ifndef ANDROID_MEDIAPLAYERSERVICE_H #define ANDROID_MEDIAPLAYERSERVICE_H -#include <utils.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/List.h> +#include <utils/Errors.h> #include <utils/KeyedVector.h> +#include <utils/SortedVector.h> +#include <utils/Vector.h> #include <ui/SurfaceComposerClient.h> #include <media/IMediaPlayerService.h> #include <media/MediaPlayerInterface.h> namespace android { +typedef int32_t MetadataType; class IMediaRecorder; class IMediaMetadataRetriever; @@ -140,7 +146,7 @@ class MediaPlayerService : public BnMediaPlayerService sp<MemoryHeapBase> mHeap; float mMsecsPerFrame; uint16_t mChannelCount; - uint16_t mFormat; + uint16_t mFormat; ssize_t mFrameCount; uint32_t mSampleRate; uint32_t mSize; @@ -165,6 +171,7 @@ public: void removeClient(wp<Client> client); + private: class Client : public BnMediaPlayer { @@ -184,6 +191,11 @@ private: virtual status_t setAudioStreamType(int type); virtual status_t setLooping(int loop); virtual status_t setVolume(float leftVolume, float rightVolume); + virtual status_t invoke(const Parcel& request, Parcel *reply); + virtual status_t setMetadataFilter(const Parcel& filter); + virtual status_t getMetadata(bool update_only, + bool apply_filter, + Parcel *reply); sp<MediaPlayerBase> createPlayer(player_type playerType); status_t setDataSource(const char *url); @@ -206,6 +218,18 @@ private: sp<MediaPlayerBase> getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; } + + + // @param type Of the metadata to be tested. + // @return true if the metadata should be dropped according to + // the filters. + bool shouldDropMetadata(MetadataType type) const; + + // Add a new element to the set of metadata updated. Noop if + // the element exists already. + // @param type Of the metadata to be recorded. + void addNewMetadataUpdate(MetadataType type); + mutable Mutex mLock; sp<MediaPlayerBase> mPlayer; sp<MediaPlayerService> mService; @@ -215,6 +239,17 @@ private: status_t mStatus; bool mLoop; int32_t mConnId; + + // Metadata filters. + SortedVector<int32_t> mMetadataAllow; // protected by mLock + SortedVector<int32_t> mMetadataDrop; // protected by mLock + + // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE + // notification we try to update mMetadataUpdated which is a + // set: no duplicate. + // getMetadata clears this set. + SortedVector<int32_t> mMetadataUpdated; // protected by mLock + #if CALLBACK_ANTAGONIZER Antagonizer* mAntagonizer; #endif @@ -235,4 +270,3 @@ private: }; // namespace android #endif // ANDROID_MEDIAPLAYERSERVICE_H - diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 8bc410c..e54f20d 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -25,10 +25,10 @@ #include <string.h> #include <cutils/atomic.h> #include <android_runtime/ActivityManager.h> -#include <utils/IPCThreadState.h> -#include <utils/IServiceManager.h> -#include <utils/MemoryHeapBase.h> -#include <utils/MemoryBase.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> #include <media/PVMediaRecorder.h> #include <utils/String16.h> diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index a320bd5..ba8d9a8 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -26,10 +26,10 @@ #include <string.h> #include <cutils/atomic.h> -#include <utils/MemoryDealer.h> +#include <binder/MemoryDealer.h> #include <android_runtime/ActivityManager.h> -#include <utils/IPCThreadState.h> -#include <utils/IServiceManager.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> #include <media/MediaMetadataRetrieverInterface.h> #include <media/MediaPlayerInterface.h> #include <media/PVMetadataRetriever.h> @@ -49,7 +49,11 @@ MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid) mThumbnail = NULL; mAlbumArt = NULL; +#ifndef NO_OPENCORE mRetriever = new PVMetadataRetriever(); +#else + mRetriever = NULL; +#endif if (mRetriever == NULL) { LOGE("failed to initialize the retriever"); } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index ce29c98..88d50bf 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -18,9 +18,12 @@ #ifndef ANDROID_MEDIAMETADATARETRIEVERSERVICE_H #define ANDROID_MEDIAMETADATARETRIEVERSERVICE_H -#include <utils.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/List.h> +#include <utils/Errors.h> #include <utils/KeyedVector.h> -#include <utils/IMemory.h> +#include <binder/IMemory.h> #include <media/MediaMetadataRetrieverInterface.h> diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index 302f1cf..83d97fe 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -46,6 +46,7 @@ public: virtual status_t reset(); virtual status_t setLooping(int loop); virtual player_type playerType() { return SONIVOX_PLAYER; } + virtual status_t invoke(const Parcel& request, Parcel *reply) {return INVALID_OPERATION;} private: status_t createOutputTrack(); @@ -74,4 +75,3 @@ private: }; // namespace android #endif // ANDROID_MIDIFILE_H - diff --git a/media/libmediaplayerservice/VorbisPlayer.h b/media/libmediaplayerservice/VorbisPlayer.h index c30dc1b..4024654 100644 --- a/media/libmediaplayerservice/VorbisPlayer.h +++ b/media/libmediaplayerservice/VorbisPlayer.h @@ -53,6 +53,7 @@ public: virtual status_t reset(); virtual status_t setLooping(int loop); virtual player_type playerType() { return VORBIS_PLAYER; } + virtual status_t invoke(const Parcel& request, Parcel *reply) {return INVALID_OPERATION;} private: status_t setdatasource(const char *path, int fd, int64_t offset, int64_t length); @@ -88,4 +89,3 @@ private: }; // namespace android #endif // ANDROID_VORBISPLAYER_H - |