diff options
author | James Dong <jdong@google.com> | 2009-09-06 14:29:45 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2009-09-08 11:04:53 -0700 |
commit | 392ff3b5296e0cee8d5db386d2ef72e2719890c8 (patch) | |
tree | 5d533efc93f3d87e62beb4eea7a5d0eff66dc338 /media | |
parent | 0b98c944c6bac98d95c93916cde31f841b44d9aa (diff) | |
download | frameworks_base-392ff3b5296e0cee8d5db386d2ef72e2719890c8.zip frameworks_base-392ff3b5296e0cee8d5db386d2ef72e2719890c8.tar.gz frameworks_base-392ff3b5296e0cee8d5db386d2ef72e2719890c8.tar.bz2 |
Add basic metadata retrieval support for midi, ogg, etc.
Bug 2050320
Diffstat (limited to 'media')
7 files changed, 334 insertions, 13 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index 84f858c..59ecde6 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -13,6 +13,8 @@ LOCAL_SRC_FILES:= \ StagefrightPlayer.cpp \ TestPlayerStub.cpp \ VorbisPlayer.cpp \ + VorbisMetadataRetriever.cpp \ + MidiMetadataRetriever.cpp \ MidiFile.cpp ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index eeb4e49..8998f10 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -611,7 +611,7 @@ static player_type getDefaultPlayerType() { return PV_PLAYER; } -static player_type getPlayerType(int fd, int64_t offset, int64_t length) +player_type getPlayerType(int fd, int64_t offset, int64_t length) { char buf[20]; lseek(fd, offset, SEEK_SET); @@ -644,7 +644,7 @@ static player_type getPlayerType(int fd, int64_t offset, int64_t length) return getDefaultPlayerType(); } -static player_type getPlayerType(const char* url) +player_type getPlayerType(const char* url) { if (TestPlayerStub::canBeUsed(url)) { return TEST_PLAYER; diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index ba8d9a8..b34421d 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -34,12 +34,15 @@ #include <media/MediaPlayerInterface.h> #include <media/PVMetadataRetriever.h> #include <private/media/VideoFrame.h> - +#include "VorbisMetadataRetriever.h" +#include "MidiMetadataRetriever.h" #include "MetadataRetrieverClient.h" - namespace android { +extern player_type getPlayerType(const char* url); +extern player_type getPlayerType(int fd, int64_t offset, int64_t length); + MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid) { LOGV("MetadataRetrieverClient constructor pid(%d)", pid); @@ -90,6 +93,36 @@ void MetadataRetrieverClient::disconnect() IPCThreadState::self()->flushCommands(); } +static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType) +{ + sp<MediaMetadataRetrieverBase> p; + switch (playerType) { +#ifndef NO_OPENCORE + case PV_PLAYER: + LOGV("create pv metadata retriever"); + p = new PVMetadataRetriever(); + break; +#endif + case VORBIS_PLAYER: + LOGV("create vorbis metadata retriever"); + p = new VorbisMetadataRetriever(); + break; + case SONIVOX_PLAYER: + LOGV("create midi metadata retriever"); + p = new MidiMetadataRetriever(); + break; + default: + // TODO: + // support for STAGEFRIGHT_PLAYER and TEST_PLAYER + LOGE("player type %d is not supported", playerType); + break; + } + if (p == NULL) { + LOGE("failed to create a retriever object"); + } + return p; +} + status_t MetadataRetrieverClient::setDataSource(const char *url) { LOGV("setDataSource(%s)", url); @@ -97,11 +130,13 @@ status_t MetadataRetrieverClient::setDataSource(const char *url) if (url == NULL) { return UNKNOWN_ERROR; } - if (mRetriever == NULL) { - LOGE("retriever is not initialized"); - return NO_INIT; - } - return mRetriever->setDataSource(url); + player_type playerType = getPlayerType(url); + LOGV("player type = %d", playerType); + sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); + if (p == NULL) return NO_INIT; + status_t ret = p->setDataSource(url); + if (ret == NO_ERROR) mRetriever = p; + return ret; } status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length) @@ -118,7 +153,7 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t int ret = fstat(fd, &sb); if (ret != 0) { LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); - return UNKNOWN_ERROR; + return BAD_VALUE; } LOGV("st_dev = %llu", sb.st_dev); LOGV("st_mode = %u", sb.st_mode); @@ -129,13 +164,22 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t if (offset >= sb.st_size) { LOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size); ::close(fd); - return UNKNOWN_ERROR; + return BAD_VALUE; } if (offset + length > sb.st_size) { length = sb.st_size - offset; - LOGE("calculated length = %lld", length); + LOGV("calculated length = %lld", length); + } + + player_type playerType = getPlayerType(fd, offset, length); + LOGV("player type = %d", playerType); + sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); + if (p == NULL) { + ::close(fd); + return NO_INIT; } - status_t status = mRetriever->setDataSource(fd, offset, length); + status_t status = p->setDataSource(fd, offset, length); + if (status == NO_ERROR) mRetriever = p; ::close(fd); return status; } diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp new file mode 100644 index 0000000..3795b7b --- /dev/null +++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp @@ -0,0 +1,91 @@ +/* +** +** Copyright 2009, 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 "MidiMetadataRetriever" +#include <utils/Log.h> + +#include "MidiMetadataRetriever.h" +#include <media/mediametadataretriever.h> + +namespace android { + +static status_t ERROR_NOT_OPEN = -1; +static status_t ERROR_OPEN_FAILED = -2; +static status_t ERROR_EAS_FAILURE = -3; +static status_t ERROR_ALLOCATE_FAILED = -4; + +void MidiMetadataRetriever::clearMetadataValues() +{ + LOGV("clearMetadataValues"); + mMetadataValues[0][0] = '\0'; +} + +status_t MidiMetadataRetriever::setDataSource(const char *url) +{ + LOGV("setDataSource: %s", url? url: "NULL pointer"); + Mutex::Autolock lock(mLock); + clearMetadataValues(); + if (mMidiPlayer == 0) { + mMidiPlayer = new MidiFile(); + } + return mMidiPlayer->setDataSource(url); +} + +status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) +{ + LOGV("setDataSource: fd(%d), offset(%lld), and length(%lld)", fd, offset, length); + Mutex::Autolock lock(mLock); + clearMetadataValues(); + if (mMidiPlayer == 0) { + mMidiPlayer = new MidiFile(); + } + return mMidiPlayer->setDataSource(fd, offset, length);; +} + +const char* MidiMetadataRetriever::extractMetadata(int keyCode) +{ + LOGV("extractMetdata: key(%d)", keyCode); + Mutex::Autolock lock(mLock); + if (mMidiPlayer == 0 || mMidiPlayer->initCheck() != NO_ERROR) { + LOGE("Midi player is not initialized yet"); + return NULL; + } + switch (keyCode) { + case METADATA_KEY_DURATION: + { + if (mMetadataValues[0][0] == '\0') { + int duration = -1; + if (mMidiPlayer->getDuration(&duration) != NO_ERROR) { + LOGE("failed to get duration"); + return NULL; + } + snprintf(mMetadataValues[0], MAX_METADATA_STRING_LENGTH, "%d", duration); + } + + LOGV("duration: %s ms", mMetadataValues[0]); + return mMetadataValues[0]; + } + default: + LOGE("Unsupported key code (%d)", keyCode); + return NULL; + } + return NULL; +} + +}; + diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h new file mode 100644 index 0000000..73ff347 --- /dev/null +++ b/media/libmediaplayerservice/MidiMetadataRetriever.h @@ -0,0 +1,49 @@ +/* +** +** Copyright 2009, 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. +*/ + +#ifndef ANDROID_MIDIMETADATARETRIEVER_H +#define ANDROID_MIDIMETADATARETRIEVER_H + +#include <utils/threads.h> +#include <utils/Errors.h> +#include <media/MediaMetadataRetrieverInterface.h> + +#include "MidiFile.h" + +namespace android { + +class MidiMetadataRetriever : public MediaMetadataRetrieverInterface { +public: + MidiMetadataRetriever() {} + ~MidiMetadataRetriever() {} + + virtual status_t setDataSource(const char *url); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); + virtual const char* extractMetadata(int keyCode); + +private: + static const uint32_t MAX_METADATA_STRING_LENGTH = 128; + void clearMetadataValues(); + + Mutex mLock; + sp<MidiFile> mMidiPlayer; + char mMetadataValues[1][MAX_METADATA_STRING_LENGTH]; +}; + +}; // namespace android + +#endif // ANDROID_MIDIMETADATARETRIEVER_H diff --git a/media/libmediaplayerservice/VorbisMetadataRetriever.cpp b/media/libmediaplayerservice/VorbisMetadataRetriever.cpp new file mode 100644 index 0000000..e981678 --- /dev/null +++ b/media/libmediaplayerservice/VorbisMetadataRetriever.cpp @@ -0,0 +1,86 @@ +/* +** +** Copyright 2009, 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 "VorbisMetadataRetriever" +#include <utils/Log.h> + +#include "VorbisMetadataRetriever.h" +#include <media/mediametadataretriever.h> +# + +namespace android { + +void VorbisMetadataRetriever::clearMetadataValues() +{ + LOGV("cleearMetadataValues"); + mMetadataValues[0][0] = '\0'; +} + +status_t VorbisMetadataRetriever::setDataSource(const char *url) +{ + LOGV("setDataSource: url(%s)", url? url: "NULL pointer"); + Mutex::Autolock lock(mLock); + clearMetadataValues(); + if (mVorbisPlayer == 0) { + mVorbisPlayer = new VorbisPlayer(); + } + return mVorbisPlayer->setDataSource(url); +} + +status_t VorbisMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) +{ + LOGV("setDataSource: fd(%d), offset(%lld), and length(%lld)", fd, offset, length); + Mutex::Autolock lock(mLock); + clearMetadataValues(); + if (mVorbisPlayer == 0) { + mVorbisPlayer = new VorbisPlayer(); + } + return mVorbisPlayer->setDataSource(fd, offset, length); +} + +const char* VorbisMetadataRetriever::extractMetadata(int keyCode) +{ + LOGV("extractMetadata: key(%d)", keyCode); + Mutex::Autolock lock(mLock); + if (mVorbisPlayer == 0 || mVorbisPlayer->initCheck() != NO_ERROR) { + LOGE("no vorbis player is initialized yet"); + return NULL; + } + switch (keyCode) { + case METADATA_KEY_DURATION: + { + if (mMetadataValues[0][0] == '\0') { + int duration = -1; + if (mVorbisPlayer->getDuration(&duration) != NO_ERROR) { + LOGE("failed to get duration"); + return NULL; + } + snprintf(mMetadataValues[0], MAX_METADATA_STRING_LENGTH, "%d", duration); + } + LOGV("duration: %s ms", mMetadataValues[0]); + return mMetadataValues[0]; + } + default: + LOGE("Unsupported key code (%d)", keyCode); + return NULL; + } + return NULL; +} + +}; + diff --git a/media/libmediaplayerservice/VorbisMetadataRetriever.h b/media/libmediaplayerservice/VorbisMetadataRetriever.h new file mode 100644 index 0000000..1c57fe3 --- /dev/null +++ b/media/libmediaplayerservice/VorbisMetadataRetriever.h @@ -0,0 +1,49 @@ +/* +** +** Copyright 2009, 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. +*/ + +#ifndef ANDROID_VORBISMETADATARETRIEVER_H +#define ANDROID_VORBISMETADATARETRIEVER_H + +#include <utils/threads.h> +#include <utils/Errors.h> +#include <media/MediaMetadataRetrieverInterface.h> + +#include "VorbisPlayer.h" + +namespace android { + +class VorbisMetadataRetriever : public MediaMetadataRetrieverInterface { +public: + VorbisMetadataRetriever() {} + ~VorbisMetadataRetriever() {} + + virtual status_t setDataSource(const char *url); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); + virtual const char* extractMetadata(int keyCode); + +private: + static const uint32_t MAX_METADATA_STRING_LENGTH = 128; + void clearMetadataValues(); + + Mutex mLock; + sp<VorbisPlayer> mVorbisPlayer; + char mMetadataValues[1][MAX_METADATA_STRING_LENGTH]; +}; + +}; // namespace android + +#endif // ANDROID_VORBISMETADATARETRIEVER_H |