Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4778250a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MediaPlayer2: remove factory"

parents 9fc65009 678c54ce
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -318,9 +318,7 @@ cc_library {

    srcs: [
        "JAudioTrack.cpp",
        "MediaPlayer2Factory.cpp",
        "MediaPlayer2Manager.cpp",
        "TestPlayerStub.cpp",
        "mediaplayer2.cpp",
    ],

+0 −270
Original line number Diff line number Diff line
/*
**
** Copyright 2017, 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 "MediaPlayer2Factory"
#include <utils/Log.h>

#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/MediaPlayer2Engine.h>
#include <media/stagefright/foundation/ADebug.h>
#include <utils/Errors.h>
#include <utils/misc.h>

#include "MediaPlayer2Factory.h"

#include "TestPlayerStub.h"
#include "nuplayer2/NuPlayer2Driver.h"

namespace android {

Mutex MediaPlayer2Factory::sLock;
MediaPlayer2Factory::tFactoryMap *MediaPlayer2Factory::sFactoryMap;
bool MediaPlayer2Factory::sInitComplete = false;

// static
bool MediaPlayer2Factory::ensureInit_l() {
    if (sFactoryMap == NULL) {
        sFactoryMap = new (std::nothrow) tFactoryMap();
    }
    return (sFactoryMap != NULL);
}

status_t MediaPlayer2Factory::registerFactory_l(IFactory* factory,
                                                player2_type type) {
    if (NULL == factory) {
        ALOGE("Failed to register MediaPlayer2Factory of type %d, factory is"
              " NULL.", type);
        return BAD_VALUE;
    }

    if (!ensureInit_l()) {
        return NO_INIT;
    }

    if (sFactoryMap->indexOfKey(type) >= 0) {
        ALOGE("Failed to register MediaPlayer2Factory of type %d, type is"
              " already registered.", type);
        return ALREADY_EXISTS;
    }

    if (sFactoryMap->add(type, factory) < 0) {
        ALOGE("Failed to register MediaPlayer2Factory of type %d, failed to add"
              " to map.", type);
        return UNKNOWN_ERROR;
    }

    return OK;
}

static player2_type getDefaultPlayerType() {
    return PLAYER2_NU_PLAYER2;
}

#define GET_PLAYER_TYPE_IMPL(a...)                      \
    Mutex::Autolock lock_(&sLock);                      \
                                                        \
    player2_type ret = PLAYER2_STAGEFRIGHT_PLAYER;      \
    float bestScore = 0.0;                              \
                                                        \
    if (!ensureInit_l()) {                              \
        return ret;                                     \
    }                                                   \
                                                        \
    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) {                             \
        ret = getDefaultPlayerType();                   \
    }                                                   \
                                                        \
    return ret;

player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
                                               const char* url) {
    GET_PLAYER_TYPE_IMPL(client, url);
}

player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
                                                int fd,
                                                int64_t offset,
                                                int64_t length) {
    GET_PLAYER_TYPE_IMPL(client, fd, offset, length);
}

player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
                                                const sp<IStreamSource> &source) {
    GET_PLAYER_TYPE_IMPL(client, source);
}

player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
                                                const sp<DataSource> &source) {
    GET_PLAYER_TYPE_IMPL(client, source);
}

#undef GET_PLAYER_TYPE_IMPL

sp<MediaPlayer2Base> MediaPlayer2Factory::createPlayer(
        player2_type playerType,
        const wp<MediaPlayer2Engine> &client,
        MediaPlayer2Base::NotifyCallback notifyFunc,
        pid_t pid) {
    sp<MediaPlayer2Base> p;
    IFactory* factory;
    status_t init_result;
    Mutex::Autolock lock_(&sLock);

    if (!ensureInit_l()) {
        return NULL;
    }

    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(pid);

    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(client, 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 NuPlayer2Factory : public MediaPlayer2Factory::IFactory {
  public:
    virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*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)
                || !strncasecmp("file://", url, 7)) {
            size_t len = strlen(url);
            if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
                return kOurScore;
            }

            if (strstr(url,"m3u8")) {
                return kOurScore;
            }

            if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
                return kOurScore;
            }
        }

        if (!strncasecmp("rtsp://", url, 7)) {
            return kOurScore;
        }

        return 0.0;
    }

    virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                               const sp<IStreamSource>& /*source*/,
                               float /*curScore*/) {
        return 1.0;
    }

    virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                               const sp<DataSource>& /*source*/,
                               float /*curScore*/) {
        // Only NuPlayer2 supports setting a DataSource source directly.
        return 1.0;
    }

    virtual sp<MediaPlayer2Base> createPlayer(pid_t pid) {
        ALOGV(" create NuPlayer2");
        return new NuPlayer2Driver(pid);
    }
};

class TestPlayerFactory : public MediaPlayer2Factory::IFactory {
  public:
    virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                               const char* url,
                               float /*curScore*/) {
        if (TestPlayerStub::canBeUsed(url)) {
            return 1.0;
        }

        return 0.0;
    }

    virtual sp<MediaPlayer2Base> createPlayer(pid_t /* pid */) {
        ALOGV("Create Test Player stub");
        return new TestPlayerStub();
    }
};

void MediaPlayer2Factory::registerBuiltinFactories() {
    Mutex::Autolock lock_(&sLock);

    if (sInitComplete) {
        return;
    }

    IFactory* factory = new NuPlayer2Factory();
    if (registerFactory_l(factory, PLAYER2_NU_PLAYER2) != OK) {
        delete factory;
    }
    factory = new TestPlayerFactory();
    if (registerFactory_l(factory, PLAYER2_TEST_PLAYER) != OK) {
        delete factory;
    }

    sInitComplete = true;
}

}  // namespace android
+0 −89
Original line number Diff line number Diff line
/*
**
** Copyright 2017, 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_MEDIAPLAYER2FACTORY_H
#define ANDROID_MEDIAPLAYER2FACTORY_H

#include <media/MediaPlayer2Interface.h>
#include <media/stagefright/foundation/ABase.h>

namespace android {

class MediaPlayer2Factory {
  public:
    class IFactory {
      public:
        virtual ~IFactory() { }

        virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                                   const char* /*url*/,
                                   float /*curScore*/) { return 0.0; }

        virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                                   int /*fd*/,
                                   int64_t /*offset*/,
                                   int64_t /*length*/,
                                   float /*curScore*/) { return 0.0; }

        virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                                   const sp<IStreamSource> &/*source*/,
                                   float /*curScore*/) { return 0.0; }

        virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
                                   const sp<DataSource> &/*source*/,
                                   float /*curScore*/) { return 0.0; }

        virtual sp<MediaPlayer2Base> createPlayer(pid_t pid) = 0;
    };

    static player2_type getPlayerType(const sp<MediaPlayer2Engine>& client,
                                      const char* url);
    static player2_type getPlayerType(const sp<MediaPlayer2Engine>& client,
                                      int fd,
                                      int64_t offset,
                                      int64_t length);
    static player2_type getPlayerType(const sp<MediaPlayer2Engine>& client,
                                      const sp<IStreamSource> &source);
    static player2_type getPlayerType(const sp<MediaPlayer2Engine>& client,
                                      const sp<DataSource> &source);

    static sp<MediaPlayer2Base> createPlayer(player2_type playerType,
                                             const wp<MediaPlayer2Engine> &client,
                                             MediaPlayer2Base::NotifyCallback notifyFunc,
                                             pid_t pid);

    static void registerBuiltinFactories();

  private:
    typedef KeyedVector<player2_type, IFactory*> tFactoryMap;

    MediaPlayer2Factory() { }

    static bool ensureInit_l();

    static status_t registerFactory_l(IFactory* factory,
                                      player2_type type);

    static Mutex       sLock;
    static tFactoryMap *sFactoryMap;
    static bool        sInitComplete;

    DISALLOW_EVIL_CONSTRUCTORS(MediaPlayer2Factory);
};

}  // namespace android
#endif  // ANDROID_MEDIAPLAYER2FACTORY_H
+16 −30
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@

#include <private/android_filesystem_config.h>

#include <nuplayer2/NuPlayer2Driver.h>
#include "MediaPlayer2Manager.h"
#include "MediaPlayer2Factory.h"

static const int kDumpLockRetries = 50;
static const int kDumpLockSleepUs = 20000;
@@ -269,8 +269,6 @@ MediaPlayer2Manager::MediaPlayer2Manager() {
    mPid = IPCThreadState::self()->getCallingPid();
    mUid = IPCThreadState::self()->getCallingUid();
    mNextConnId = 1;

    MediaPlayer2Factory::registerBuiltinFactories();
}

MediaPlayer2Manager::~MediaPlayer2Manager() {
@@ -562,16 +560,17 @@ void MediaPlayer2Manager::Client::disconnect()
    IPCThreadState::self()->flushCommands();
}

sp<MediaPlayer2Base> MediaPlayer2Manager::Client::createPlayer(player2_type playerType)
{
    // determine if we have the right player type
sp<MediaPlayer2Base> MediaPlayer2Manager::Client::createPlayer() {
    sp<MediaPlayer2Base> p = getPlayer();
    if ((p != NULL) && (p->playerType() != playerType)) {
        ALOGV("delete player");
    if (p == NULL) {
        p = new NuPlayer2Driver(mPid);
        status_t init_result = p->initCheck();
        if (init_result == NO_ERROR) {
            p->setNotifyCallback(this, notify);
        } else {
            ALOGE("Failed to create player, initCheck failed(res = %d)", init_result);
            p.clear();
        }
    if (p == NULL) {
        p = MediaPlayer2Factory::createPlayer(playerType, this, notify, mPid);
    }

    if (p != NULL) {
@@ -592,13 +591,8 @@ void MediaPlayer2Manager::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdat
    }
}

sp<MediaPlayer2Base> MediaPlayer2Manager::Client::setDataSource_pre(
        player2_type playerType)
{
    ALOGV("player type = %d", playerType);

    // create the right type of player
    sp<MediaPlayer2Base> p = createPlayer(playerType);
sp<MediaPlayer2Base> MediaPlayer2Manager::Client::setDataSource_pre() {
    sp<MediaPlayer2Base> p = createPlayer();
    if (p == NULL) {
        return p;
    }
@@ -663,8 +657,7 @@ status_t MediaPlayer2Manager::Client::setDataSource(
        mStatus = UNKNOWN_ERROR;
        return mStatus;
    } else {
        player2_type playerType = MediaPlayer2Factory::getPlayerType(this, url);
        sp<MediaPlayer2Base> p = setDataSource_pre(playerType);
        sp<MediaPlayer2Base> p = setDataSource_pre();
        if (p == NULL) {
            return NO_INIT;
        }
@@ -701,11 +694,7 @@ status_t MediaPlayer2Manager::Client::setDataSource(int fd, int64_t offset, int6
        ALOGV("calculated length = %lld", (long long)length);
    }

    player2_type playerType = MediaPlayer2Factory::getPlayerType(this,
                                                               fd,
                                                               offset,
                                                               length);
    sp<MediaPlayer2Base> p = setDataSource_pre(playerType);
    sp<MediaPlayer2Base> p = setDataSource_pre();
    if (p == NULL) {
        return NO_INIT;
    }
@@ -716,9 +705,7 @@ status_t MediaPlayer2Manager::Client::setDataSource(int fd, int64_t offset, int6

status_t MediaPlayer2Manager::Client::setDataSource(
        const sp<IStreamSource> &source) {
    // create the right type of player
    player2_type playerType = MediaPlayer2Factory::getPlayerType(this, source);
    sp<MediaPlayer2Base> p = setDataSource_pre(playerType);
    sp<MediaPlayer2Base> p = setDataSource_pre();
    if (p == NULL) {
        return NO_INIT;
    }
@@ -729,8 +716,7 @@ status_t MediaPlayer2Manager::Client::setDataSource(

status_t MediaPlayer2Manager::Client::setDataSource(
        const sp<DataSource> &source) {
    player2_type playerType = MediaPlayer2Factory::getPlayerType(this, source);
    sp<MediaPlayer2Base> p = setDataSource_pre(playerType);
    sp<MediaPlayer2Base> p = setDataSource_pre();
    if (p == NULL) {
        return NO_INIT;
    }
+2 −2
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ private:
                                        const sp<media::VolumeShaper::Operation>& operation) override;
        virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;

        sp<MediaPlayer2Base>    createPlayer(player2_type playerType);
        sp<MediaPlayer2Base>    createPlayer();

        virtual status_t        setDataSource(
                        const sp<MediaHTTPService> &httpService,
@@ -300,7 +300,7 @@ private:
        virtual status_t        setDataSource(const sp<DataSource> &source);


        sp<MediaPlayer2Base>    setDataSource_pre(player2_type playerType);
        sp<MediaPlayer2Base>    setDataSource_pre();
        status_t                setDataSource_post(const sp<MediaPlayer2Base>& p,
                                                   status_t status);

Loading