diff options
-rw-r--r-- | include/media/IMediaPlayer.h | 1 | ||||
-rw-r--r-- | include/media/MediaPlayerInterface.h | 7 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 34 | ||||
-rw-r--r-- | media/libmediaplayerservice/Android.mk | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerFactory.cpp | 404 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerFactory.h | 84 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 241 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 6 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.cpp | 22 |
9 files changed, 583 insertions, 217 deletions
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 00facc5..4ed1863 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -64,6 +64,7 @@ public: virtual status_t setParameter(int key, const Parcel& request) = 0; virtual status_t getParameter(int key, Parcel* reply) = 0; virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) = 0; + virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) = 0; virtual status_t setNextPlayer(const sp<IMediaPlayer>& next) = 0; // Invoke a generic method on the player by using opaque parcels diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index a70fe8c..0498ed1 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -154,12 +154,15 @@ public: virtual status_t getParameter(int key, Parcel *reply) = 0; // Right now, only the AAX TX player supports this functionality. For now, - // provide a default implementation which indicates a lack of support for - // this functionality to make life easier for all of the other media player + // provide default implementations which indicate a lack of support for this + // functionality to make life easier for all of the other media player // maintainers out there. virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) { return INVALID_OPERATION; } + virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) { + return INVALID_OPERATION; + } // Invoke a generic method on the player by using opaque parcels // for the request and reply. diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 0bb237d..cb07766 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -55,6 +55,7 @@ enum { SET_PARAMETER, GET_PARAMETER, SET_RETRANSMIT_ENDPOINT, + GET_RETRANSMIT_ENDPOINT, SET_NEXT_PLAYER, }; @@ -292,7 +293,8 @@ public: return remote()->transact(GET_PARAMETER, data, reply); } - status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) { + status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) + { Parcel data, reply; status_t err; @@ -319,6 +321,23 @@ public: remote()->transact(SET_NEXT_PLAYER, data, &reply); return reply.readInt32(); } + + status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) + { + Parcel data, reply; + status_t err; + + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + err = remote()->transact(GET_RETRANSMIT_ENDPOINT, data, &reply); + + if ((OK != err) || (OK != (err = reply.readInt32()))) { + return err; + } + + data.read(endpoint, sizeof(*endpoint)); + + return err; + } }; IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); @@ -498,11 +517,24 @@ status_t BnMediaPlayer::onTransact( } else { reply->writeInt32(setRetransmitEndpoint(NULL)); } + + return NO_ERROR; + } break; + case GET_RETRANSMIT_ENDPOINT: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + + struct sockaddr_in endpoint; + status_t res = getRetransmitEndpoint(&endpoint); + + reply->writeInt32(res); + reply->write(&endpoint, sizeof(endpoint)); + return NO_ERROR; } break; case SET_NEXT_PLAYER: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder()))); + return NO_ERROR; } break; default: diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index f173e2e..e3134d1 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \ ActivityManager.cpp \ Crypto.cpp \ MediaRecorderClient.cpp \ + MediaPlayerFactory.cpp \ MediaPlayerService.cpp \ MetadataRetrieverClient.cpp \ TestPlayerStub.cpp \ diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp new file mode 100644 index 0000000..dcb347f --- /dev/null +++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp @@ -0,0 +1,404 @@ +/* +** +** Copyright 2012, 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_TAG "MediaPlayerFactory" +#include <utils/Log.h> + +#include <cutils/properties.h> +#include <media/IMediaPlayer.h> +#include <media/stagefright/foundation/ADebug.h> +#include <utils/Errors.h> +#include <utils/misc.h> + +#include "MediaPlayerFactory.h" + +#include "MidiFile.h" +#include "TestPlayerStub.h" +#include "StagefrightPlayer.h" +#include "nuplayer/NuPlayerDriver.h" + +namespace android { + +extern sp<MediaPlayerBase> createAAH_TXPlayer(); +extern sp<MediaPlayerBase> createAAH_RXPlayer(); + +Mutex MediaPlayerFactory::sLock; +MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap; +bool MediaPlayerFactory::sInitComplete = false; + +status_t MediaPlayerFactory::registerFactory_l(IFactory* factory, + player_type type) { + if (NULL == factory) { + ALOGE("Failed to register MediaPlayerFactory of type %d, factory is" + " NULL.", type); + return BAD_VALUE; + } + + if (sFactoryMap.indexOfKey(type) >= 0) { + ALOGE("Failed to register MediaPlayerFactory of type %d, type is" + " already registered.", type); + return ALREADY_EXISTS; + } + + if (sFactoryMap.add(type, factory) < 0) { + ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add" + " to map.", type); + return UNKNOWN_ERROR; + } + + return OK; +} + +player_type MediaPlayerFactory::getDefaultPlayerType() { + char value[PROPERTY_VALUE_MAX]; + if (property_get("media.stagefright.use-nuplayer", value, NULL) + && (!strcmp("1", value) || !strcasecmp("true", value))) { + return NU_PLAYER; + } + + return STAGEFRIGHT_PLAYER; +} + +status_t MediaPlayerFactory::registerFactory(IFactory* factory, + player_type type) { + Mutex::Autolock lock_(&sLock); + return registerFactory_l(factory, type); +} + +void MediaPlayerFactory::unregisterFactory(player_type type) { + Mutex::Autolock lock_(&sLock); + sFactoryMap.removeItem(type); +} + +#define GET_PLAYER_TYPE_IMPL(a...) \ + Mutex::Autolock lock_(&sLock); \ + \ + player_type ret = STAGEFRIGHT_PLAYER; \ + float bestScore = 0.0; \ + \ + for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ + \ + IFactory* v = sFactoryMap.valueAt(i); \ + float thisScore; \ + CHECK(v != NULL); \ + thisScore = v->scoreFactory(a, bestScore); \ + if (thisScore > bestScore) { \ + ret = sFactoryMap.keyAt(i); \ + bestScore = thisScore; \ + } \ + } \ + \ + if (0.0 == bestScore) { \ + bestScore = getDefaultPlayerType(); \ + } \ + \ + return ret; + +player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, + const char* url) { + GET_PLAYER_TYPE_IMPL(client, url); +} + +player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length) { + GET_PLAYER_TYPE_IMPL(client, fd, offset, length); +} + +player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, + const sp<IStreamSource> &source) { + GET_PLAYER_TYPE_IMPL(client, source); +} + +#undef GET_PLAYER_TYPE_IMPL + +sp<MediaPlayerBase> MediaPlayerFactory::createPlayer( + player_type playerType, + void* cookie, + notify_callback_f notifyFunc) { + sp<MediaPlayerBase> p; + IFactory* factory; + status_t init_result; + Mutex::Autolock lock_(&sLock); + + if (sFactoryMap.indexOfKey(playerType) < 0) { + ALOGE("Failed to create player object of type %d, no registered" + " factory", playerType); + return p; + } + + factory = sFactoryMap.valueFor(playerType); + CHECK(NULL != factory); + p = factory->createPlayer(); + + if (p == NULL) { + ALOGE("Failed to create player object of type %d, create failed", + playerType); + return p; + } + + init_result = p->initCheck(); + if (init_result == NO_ERROR) { + p->setNotifyCallback(cookie, notifyFunc); + } else { + ALOGE("Failed to create player object of type %d, initCheck failed" + " (res = %d)", playerType, init_result); + p.clear(); + } + + return p; +} + +/***************************************************************************** + * * + * Built-In Factory Implementations * + * * + *****************************************************************************/ + +class StagefrightPlayerFactory : + public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length, + float curScore) { + char buf[20]; + lseek(fd, offset, SEEK_SET); + read(fd, buf, sizeof(buf)); + lseek(fd, offset, SEEK_SET); + + long ident = *((long*)buf); + + // Ogg vorbis? + if (ident == 0x5367674f) // 'OggS' + return 1.0; + + return 0.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV(" create StagefrightPlayer"); + return new StagefrightPlayer(); + } +}; + +class NuPlayerFactory : public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { + static const float kOurScore = 0.8; + + if (kOurScore <= curScore) + return 0.0; + + if (!strncasecmp("http://", url, 7) + || !strncasecmp("https://", url, 8)) { + size_t len = strlen(url); + if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { + return kOurScore; + } + + if (strstr(url,"m3u8")) { + return kOurScore; + } + } + + if (!strncasecmp("rtsp://", url, 7)) { + return kOurScore; + } + + return 0.0; + } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const sp<IStreamSource> &source, + float curScore) { + return 1.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV(" create NuPlayer"); + return new NuPlayerDriver; + } +}; + +class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { + static const float kOurScore = 0.4; + static const char* const FILE_EXTS[] = { ".mid", + ".midi", + ".smf", + ".xmf", + ".imy", + ".rtttl", + ".rtx", + ".ota" }; + if (kOurScore <= curScore) + return 0.0; + + // use MidiFile for MIDI extensions + int lenURL = strlen(url); + for (int i = 0; i < NELEM(FILE_EXTS); ++i) { + int len = strlen(FILE_EXTS[i]); + int start = lenURL - len; + if (start > 0) { + if (!strncasecmp(url + start, FILE_EXTS[i], len)) { + return kOurScore; + } + } + } + + return 0.0; + } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length, + float curScore) { + static const float kOurScore = 0.8; + + if (kOurScore <= curScore) + return 0.0; + + // Some kind of MIDI? + EAS_DATA_HANDLE easdata; + if (EAS_Init(&easdata) == EAS_SUCCESS) { + EAS_FILE locator; + locator.path = NULL; + locator.fd = fd; + locator.offset = offset; + locator.length = length; + EAS_HANDLE eashandle; + if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { + EAS_CloseFile(easdata, eashandle); + EAS_Shutdown(easdata); + return kOurScore; + } + EAS_Shutdown(easdata); + } + + return 0.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV(" create MidiFile"); + return new MidiFile(); + } +}; + +class TestPlayerFactory : public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { + if (TestPlayerStub::canBeUsed(url)) { + return 1.0; + } + + return 0.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV("Create Test Player stub"); + return new TestPlayerStub(); + } +}; + +class AAH_RX_PlayerFactory : public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { + static const float kOurScore = 0.6; + + if (kOurScore <= curScore) + return 0.0; + + if (!strncasecmp("aahRX://", url, 8)) { + return kOurScore; + } + + return 0.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV(" create A@H RX Player"); + return createAAH_RXPlayer(); + } +}; + +class AAH_TX_PlayerFactory : public MediaPlayerFactory::IFactory { + public: + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { + return checkRetransmitEndpoint(client) ? 1.1 : 0.0; + } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length, + float curScore) { + return checkRetransmitEndpoint(client) ? 1.1 : 0.0; + } + + virtual sp<MediaPlayerBase> createPlayer() { + ALOGV(" create A@H TX Player"); + return createAAH_TXPlayer(); + } + + private: + bool checkRetransmitEndpoint(const sp<IMediaPlayer>& client) { + if (client == NULL) + return false; + + struct sockaddr_in junk; + if (OK != client->getRetransmitEndpoint(&junk)) + return false; + + return true; + } +}; + +void MediaPlayerFactory::registerBuiltinFactories() { + Mutex::Autolock lock_(&sLock); + + if (sInitComplete) + return; + + registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER); + registerFactory_l(new NuPlayerFactory(), NU_PLAYER); + registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER); + registerFactory_l(new TestPlayerFactory(), TEST_PLAYER); + + // TODO: remove this once AAH players have been relocated from + // framework/base and into vendor/google_devices/phantasm + registerFactory_l(new AAH_RX_PlayerFactory(), AAH_RX_PLAYER); + registerFactory_l(new AAH_TX_PlayerFactory(), AAH_TX_PLAYER); + + sInitComplete = true; +} + +} // namespace android diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h new file mode 100644 index 0000000..fe8972b --- /dev/null +++ b/media/libmediaplayerservice/MediaPlayerFactory.h @@ -0,0 +1,84 @@ +/* +** +** Copyright 2012, 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_MEDIAPLAYERFACTORY_H +#define ANDROID_MEDIAPLAYERFACTORY_H + +#include <media/MediaPlayerInterface.h> +#include <media/stagefright/foundation/ABase.h> + +namespace android { + +class MediaPlayerFactory { + public: + class IFactory { + public: + virtual ~IFactory() { } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const char* url, + float curScore) { return 0.0; } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length, + float curScore) { return 0.0; } + + virtual float scoreFactory(const sp<IMediaPlayer>& client, + const sp<IStreamSource> &source, + float curScore) { return 0.0; } + + virtual sp<MediaPlayerBase> createPlayer() = 0; + }; + + static status_t registerFactory(IFactory* factory, + player_type type); + static void unregisterFactory(player_type type); + static player_type getPlayerType(const sp<IMediaPlayer>& client, + const char* url); + static player_type getPlayerType(const sp<IMediaPlayer>& client, + int fd, + int64_t offset, + int64_t length); + static player_type getPlayerType(const sp<IMediaPlayer>& client, + const sp<IStreamSource> &source); + + static sp<MediaPlayerBase> createPlayer(player_type playerType, + void* cookie, + notify_callback_f notifyFunc); + + static void registerBuiltinFactories(); + + private: + typedef KeyedVector<player_type, IFactory*> tFactoryMap; + + MediaPlayerFactory() { } + + static status_t registerFactory_l(IFactory* factory, + player_type type); + static player_type getDefaultPlayerType(); + + static Mutex sLock; + static tFactoryMap sFactoryMap; + static bool sInitComplete; + + DISALLOW_EVIL_CONSTRUCTORS(MediaPlayerFactory); +}; + +} // namespace android +#endif // ANDROID_MEDIAPLAYERFACTORY_H diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index c47fbd6..8620856 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -43,7 +43,6 @@ #include <utils/String8.h> #include <utils/SystemClock.h> #include <utils/Vector.h> -#include <cutils/properties.h> #include <media/MediaPlayerInterface.h> #include <media/mediarecorder.h> @@ -61,6 +60,7 @@ #include "MediaRecorderClient.h" #include "MediaPlayerService.h" #include "MetadataRetrieverClient.h" +#include "MediaPlayerFactory.h" #include "MidiFile.h" #include "TestPlayerStub.h" @@ -71,11 +71,6 @@ #include "Crypto.h" -namespace android { -sp<MediaPlayerBase> createAAH_TXPlayer(); -sp<MediaPlayerBase> createAAH_RXPlayer(); -} - namespace { using android::media::Metadata; using android::status_t; @@ -194,22 +189,6 @@ static bool checkPermission(const char* permissionString) { return ok; } -// TODO: Temp hack until we can register players -typedef struct { - const char *extension; - const player_type playertype; -} extmap; -extmap FILE_EXTS [] = { - {".mid", SONIVOX_PLAYER}, - {".midi", SONIVOX_PLAYER}, - {".smf", SONIVOX_PLAYER}, - {".xmf", SONIVOX_PLAYER}, - {".imy", SONIVOX_PLAYER}, - {".rtttl", SONIVOX_PLAYER}, - {".rtx", SONIVOX_PLAYER}, - {".ota", SONIVOX_PLAYER}, -}; - // TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround /* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4; /* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false; @@ -232,6 +211,8 @@ MediaPlayerService::MediaPlayerService() } // speaker is on by default mBatteryAudio.deviceOn[SPEAKER] = 1; + + MediaPlayerFactory::registerBuiltinFactories(); } MediaPlayerService::~MediaPlayerService() @@ -545,174 +526,6 @@ void MediaPlayerService::Client::disconnect() IPCThreadState::self()->flushCommands(); } -static player_type getDefaultPlayerType() { - char value[PROPERTY_VALUE_MAX]; - if (property_get("media.stagefright.use-nuplayer", value, NULL) - && (!strcmp("1", value) || !strcasecmp("true", value))) { - return NU_PLAYER; - } - - return STAGEFRIGHT_PLAYER; -} - -player_type getPlayerType(int fd, int64_t offset, int64_t length) -{ - char buf[20]; - lseek(fd, offset, SEEK_SET); - read(fd, buf, sizeof(buf)); - lseek(fd, offset, SEEK_SET); - - long ident = *((long*)buf); - - // Ogg vorbis? - if (ident == 0x5367674f) // 'OggS' - return STAGEFRIGHT_PLAYER; - - // Some kind of MIDI? - EAS_DATA_HANDLE easdata; - if (EAS_Init(&easdata) == EAS_SUCCESS) { - EAS_FILE locator; - locator.path = NULL; - locator.fd = fd; - locator.offset = offset; - locator.length = length; - EAS_HANDLE eashandle; - if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { - EAS_CloseFile(easdata, eashandle); - EAS_Shutdown(easdata); - return SONIVOX_PLAYER; - } - EAS_Shutdown(easdata); - } - - return getDefaultPlayerType(); -} - -player_type getPlayerType(const char* url) -{ - if (TestPlayerStub::canBeUsed(url)) { - return TEST_PLAYER; - } - - if (!strncasecmp("http://", url, 7) - || !strncasecmp("https://", url, 8)) { - size_t len = strlen(url); - if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { - return NU_PLAYER; - } - - if (strstr(url,"m3u8")) { - return NU_PLAYER; - } - } - - if (!strncasecmp("rtsp://", url, 7)) { - return NU_PLAYER; - } - - if (!strncasecmp("aahRX://", url, 8)) { - return AAH_RX_PLAYER; - } - - // use MidiFile for MIDI extensions - int lenURL = strlen(url); - for (int i = 0; i < NELEM(FILE_EXTS); ++i) { - int len = strlen(FILE_EXTS[i].extension); - int start = lenURL - len; - if (start > 0) { - if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { - return FILE_EXTS[i].playertype; - } - } - } - - return getDefaultPlayerType(); -} - -player_type MediaPlayerService::Client::getPlayerType(int fd, - int64_t offset, - int64_t length) -{ - // Until re-transmit functionality is added to the existing core android - // players, we use the special AAH TX player whenever we were configured - // for retransmission. - if (mRetransmitEndpointValid) { - return AAH_TX_PLAYER; - } - - return android::getPlayerType(fd, offset, length); -} - -player_type MediaPlayerService::Client::getPlayerType(const char* url) -{ - // Until re-transmit functionality is added to the existing core android - // players, we use the special AAH TX player whenever we were configured - // for retransmission. - if (mRetransmitEndpointValid) { - return AAH_TX_PLAYER; - } - - return android::getPlayerType(url); -} - -player_type MediaPlayerService::Client::getPlayerType( - const sp<IStreamSource> &source) { - // Until re-transmit functionality is added to the existing core android - // players, we use the special AAH TX player whenever we were configured - // for retransmission. - if (mRetransmitEndpointValid) { - return AAH_TX_PLAYER; - } - - return NU_PLAYER; -} - -static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, - notify_callback_f notifyFunc) -{ - sp<MediaPlayerBase> p; - switch (playerType) { - case SONIVOX_PLAYER: - ALOGV(" create MidiFile"); - p = new MidiFile(); - break; - case STAGEFRIGHT_PLAYER: - ALOGV(" create StagefrightPlayer"); - p = new StagefrightPlayer; - break; - case NU_PLAYER: - ALOGV(" create NuPlayer"); - p = new NuPlayerDriver; - break; - case TEST_PLAYER: - ALOGV("Create Test Player stub"); - p = new TestPlayerStub(); - break; - case AAH_RX_PLAYER: - ALOGV(" create A@H RX Player"); - p = createAAH_RXPlayer(); - break; - case AAH_TX_PLAYER: - ALOGV(" create A@H TX Player"); - p = createAAH_TXPlayer(); - break; - default: - ALOGE("Unknown player type: %d", playerType); - return NULL; - } - if (p != NULL) { - if (p->initCheck() == NO_ERROR) { - p->setNotifyCallback(cookie, notifyFunc); - } else { - p.clear(); - } - } - if (p == NULL) { - ALOGE("Failed to create player object"); - } - return p; -} - sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) { // determine if we have the right player type @@ -722,7 +535,7 @@ sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerT p.clear(); } if (p == NULL) { - p = android::createPlayer(playerType, this, notify); + p = MediaPlayerFactory::createPlayer(playerType, this, notify); } if (p != NULL) { @@ -805,7 +618,7 @@ status_t MediaPlayerService::Client::setDataSource( close(fd); return mStatus; } else { - player_type playerType = getPlayerType(url); + player_type playerType = MediaPlayerFactory::getPlayerType(this, url); sp<MediaPlayerBase> p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; @@ -842,10 +655,10 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64 ALOGV("calculated length = %lld", length); } - // Until re-transmit functionality is added to the existing core android - // players, we use the special AAH TX player whenever we were configured for - // retransmission. - player_type playerType = getPlayerType(fd, offset, length); + player_type playerType = MediaPlayerFactory::getPlayerType(this, + fd, + offset, + length); sp<MediaPlayerBase> p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; @@ -859,10 +672,7 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64 status_t MediaPlayerService::Client::setDataSource( const sp<IStreamSource> &source) { // create the right type of player - // Until re-transmit functionality is added to the existing core android - // players, we use the special AAH TX player whenever we were configured for - // retransmission. - player_type playerType = getPlayerType(source); + player_type playerType = MediaPlayerFactory::getPlayerType(this, source); sp<MediaPlayerBase> p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; @@ -1209,6 +1019,25 @@ status_t MediaPlayerService::Client::setRetransmitEndpoint( return NO_ERROR; } +status_t MediaPlayerService::Client::getRetransmitEndpoint( + struct sockaddr_in* endpoint) +{ + if (NULL == endpoint) + return BAD_VALUE; + + sp<MediaPlayerBase> p = getPlayer(); + + if (p != NULL) + return p->getRetransmitEndpoint(endpoint); + + if (!mRetransmitEndpointValid) + return NO_INIT; + + *endpoint = mRetransmitEndpoint; + + return NO_ERROR; +} + void MediaPlayerService::Client::notify( void* cookie, int msg, int ext1, int ext2, const Parcel *obj) { @@ -1315,12 +1144,13 @@ sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, i return mem; } - player_type playerType = getPlayerType(url); + player_type playerType = + MediaPlayerFactory::getPlayerType(NULL /* client */, url); ALOGV("player type = %d", playerType); // create the right type of player sp<AudioCache> cache = new AudioCache(url); - player = android::createPlayer(playerType, cache.get(), cache->notify); + player = MediaPlayerFactory::createPlayer(playerType, cache.get(), cache->notify); if (player == NULL) goto Exit; if (player->hardwareOutput()) goto Exit; @@ -1362,12 +1192,15 @@ sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, u sp<MemoryBase> mem; sp<MediaPlayerBase> player; - player_type playerType = getPlayerType(fd, offset, length); + player_type playerType = MediaPlayerFactory::getPlayerType(NULL /* client */, + fd, + offset, + length); ALOGV("player type = %d", playerType); // create the right type of player sp<AudioCache> cache = new AudioCache("decode_fd"); - player = android::createPlayer(playerType, cache.get(), cache->notify); + player = MediaPlayerFactory::createPlayer(playerType, cache.get(), cache->notify); if (player == NULL) goto Exit; if (player->hardwareOutput()) goto Exit; diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 95b1b05..6ede9a4 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -299,7 +299,6 @@ public: private: class Client : public BnMediaPlayer { - // IMediaPlayer interface virtual void disconnect(); virtual status_t setVideoSurfaceTexture( @@ -326,6 +325,7 @@ private: virtual status_t setParameter(int key, const Parcel &request); virtual status_t getParameter(int key, Parcel *reply); virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint); + virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint); virtual status_t setNextPlayer(const sp<IMediaPlayer>& player); sp<MediaPlayerBase> createPlayer(player_type playerType); @@ -342,10 +342,6 @@ private: void setDataSource_post(const sp<MediaPlayerBase>& p, status_t status); - player_type getPlayerType(int fd, int64_t offset, int64_t length); - player_type getPlayerType(const char* url); - player_type getPlayerType(const sp<IStreamSource> &source); - static void notify(void* cookie, int msg, int ext1, int ext2, const Parcel *obj); diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index e44031e..348957f 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -37,12 +37,10 @@ #include "MidiMetadataRetriever.h" #include "MetadataRetrieverClient.h" #include "StagefrightMetadataRetriever.h" +#include "MediaPlayerFactory.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) { ALOGV("MetadataRetrieverClient constructor pid(%d)", pid); @@ -115,7 +113,17 @@ status_t MetadataRetrieverClient::setDataSource( if (url == NULL) { return UNKNOWN_ERROR; } - player_type playerType = getPlayerType(url); + + // When asking the MediaPlayerFactory subsystem to choose a media player for + // a given URL, a pointer to an outer IMediaPlayer can be passed to the + // factory system to be taken into consideration along with the URL. In the + // case of choosing an instance of a MediaPlayerBase for a + // MetadataRetrieverClient, there is no outer IMediaPlayer which will + // eventually encapsulate the result of this selection. In this case, just + // pass NULL to getPlayerType to indicate that there is no outer + // IMediaPlayer to consider during selection. + player_type playerType = + MediaPlayerFactory::getPlayerType(NULL /* client */, url); ALOGV("player type = %d", playerType); sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); if (p == NULL) return NO_INIT; @@ -150,7 +158,11 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t ALOGV("calculated length = %lld", length); } - player_type playerType = getPlayerType(fd, offset, length); + player_type playerType = + MediaPlayerFactory::getPlayerType(NULL /* client */, + fd, + offset, + length); ALOGV("player type = %d", playerType); sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); if (p == NULL) { |