深入了解mediaserver-3

6. MediaPlayer如何与MediaPlayerService交互

6.1    MeidaPlayerService根据MediaPlayer的请求,创建对应的MeidaPlayer

//MediaPlayerService.cpp
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
        notify_callback_f notifyFunc)
{
    sp<MediaPlayerBase> p;
    switch (playerType) {
        case XX_PLAYER:
            LOGV("Create XXPlayer");
            p = new XXPlayerService();
            break;
#ifndef NO_OPENCORE
        case PV_PLAYER:
            LOGV(" create PVPlayer");
            p = new PVPlayer();
            break;
#endif
        case SONIVOX_PLAYER:
            LOGV(" create MidiFile");
            p = new MidiFile();
            break;
        case VORBIS_PLAYER:
            LOGV(" create VorbisPlayer");
            p = new VorbisPlayer();
            break;
#if BUILD_WITH_FULL_STAGEFRIGHT
        case STAGEFRIGHT_PLAYER:
            LOGV(" create StagefrightPlayer");
            p = new StagefrightPlayer;
            break;
#endif
        case TEST_PLAYER:
            LOGV("Create Test Player stub");
            p = new TestPlayerStub();
            break;
    }
    if (p != NULL) {
        if (p->initCheck() == NO_ERROR) {
            p->setNotifyCallback(cookie, notifyFunc);
        } else {
            p.clear();
        }
    }
    if (p == NULL) {
        LOGE("Failed to create player object");
    }
    return p;
}
class MediaPlayer : public BnMediaPlayerClient,
                    public virtual IMediaDeathNotifier

=============================================================
class IMediaPlayerClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerClient);

    virtual void notify(int msg, int ext1, int ext2) = 0;
};

class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};
=============================================================
class IMediaDeathNotifier: virtual public RefBase
{
public:
    IMediaDeathNotifier() { addObitRecipient(this); }
    virtual ~IMediaDeathNotifier() { removeObitRecipient(this); }

    virtual void died() = 0;
    //establish binder interface to MediaPlayerService
    static const sp<IMediaPlayerService>& getMediaPlayerService();

private:
    IMediaDeathNotifier &operator=(const IMediaDeathNotifier &);
    IMediaDeathNotifier(const IMediaDeathNotifier &);

    static void addObitRecipient(const wp<IMediaDeathNotifier>& recipient);
    static void removeObitRecipient(const wp<IMediaDeathNotifier>& recipient);

    class DeathNotifier: public IBinder::DeathRecipient
    {
    public:
                DeathNotifier() {}
        virtual ~DeathNotifier();

        virtual void binderDied(const wp<IBinder>& who);
    };

    friend class DeathNotifier;

    static  Mutex                                   sServiceLock;
    static  sp<IMediaPlayerService>                 sMediaPlayerService;
    static  sp<DeathNotifier>                       sDeathNotifier;
    static  SortedVector< wp<IMediaDeathNotifier> > sObitRecipients;
}

6.2 通过ServiceManager获取BpMediaPlayerService

const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
{
    LOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
             }
             LOGW("Media player service not published, waiting...");
             usleep(500000); // 0.5 s
        } while(true);

        if (sDeathNotifier == NULL) {
        sDeathNotifier = new DeathNotifier();
    }
    binder->linkToDeath(sDeathNotifier);

    // sMediaPlayerService中保存的为BpMediaPlayerService

    sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

6.3 获取mPlayer(IMediaPlayer,实质为BpMediaPlayer) 

status_t MediaPlayer::setDataSource(
        const char *url, const KeyedVector<String8, String8> *headers)
{
    LOGV("setDataSource(%s)", url);
    status_t err = BAD_VALUE;
    if (url != NULL) {
        //service实质上是BpMediaPlayerService
        const sp<IMediaPlayerService>& service(getMediaPlayerService());

        if (service != 0) {
            // Player实质上是BpMediaPlayer
            sp<IMediaPlayer> player(service->create(getpid(), this, url, headers));
            //把BpMediaPlayer赋值给成员变量mPlayer,如果以前的mPlayer有效,则Disconnect以前的Player
            err = setDataSource(player);
        }
    }
    return err;
}

BpMediaPlayerService::create (Client端)

class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
{
public:
    BpMediaPlayerService(const sp<IBinder>& impl)
        : BpInterface<IMediaPlayerService>(impl)
    {
    }

    virtual sp<IMediaPlayer> create(
            pid_t pid, const sp<IMediaPlayerClient>& client,
            const char* url, const KeyedVector<String8, String8> *headers) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeInt32(pid);
        data.writeStrongBinder(client->asBinder());
        data.writeCString(url);

        if (headers == NULL) {
            data.writeInt32(0);
        } else {
            // serialize the headers
            data.writeInt32(headers->size());
            for (size_t i = 0; i < headers->size(); ++i) {
                data.writeString8(headers->keyAt(i));
                data.writeString8(headers->valueAt(i));
            }
        }

        remote()->transact(CREATE_URL, data, &reply);  //传递到BnMediaPlayerSerivce执行
        return interface_cast<IMediaPlayer>(reply.readStrongBinder()); //返回BpMediaPlayer
    }
}

在BnMediaPlayerService处理CREATE_URL(Server端)

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case CREATE_URL: { //收到上面的CREATE_URL并进行处理
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            pid_t pid = data.readInt32();
            sp<IMediaPlayerClient> client = //实质保存的为BpMediaPlayerClient,用于向MediaPlayer发通知消息,它为Client,MediaPlayer为Sever
                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
            const char* url = data.readCString();

            KeyedVector<String8, String8> headers;
            int32_t numHeaders = data.readInt32();
            for (int i = 0; i < numHeaders; ++i) {
                String8 key = data.readString8();
                String8 value = data.readString8();
                headers.add(key, value);
            }
            //在BnMediaPlayerService的派生类MediaPlayerService中实现,创建一个Client对象(Client:public BnMediaPlayer)
            sp<IMediaPlayer> player = create(
                    pid, client, url, numHeaders > 0 ? &headers : NULL);

            reply->writeStrongBinder(player->asBinder());
            return NO_ERROR;
        } break;
}

MediaPlayerService::create才是真正的实现创建IMediaPlayer

sp<IMediaPlayer> MediaPlayerService::create(         pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,         const KeyedVector<String8, String8> *headers) {     int32_t connId = android_atomic_inc(&mNextConnId);

     //创建一个Clinet,class Client : public BnMediaPlayer,真正实现start, stop, pause, resume...     sp<Client> c = new Client(this, pid, connId, client);     LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);

    //分析url,并创建真正的player(demuxer,decoder)     if (NO_ERROR != c->setDataSource(url, headers))     {         c.clear();         return c;     }     wp<Client> w = c;     Mutex::Autolock lock(mLock);     mClients.add(w);     return c;//返回此BnMediaPlayer派生类的对象 }

MediaPlayerService::Client::setDataSource分析URL类型,然后创建对应的Player

status_t MediaPlayerService::Client::setDataSource(
        const char *url, const KeyedVector<String8, String8> *headers)
{
    LOGV("setDataSource(%s)", url);
    if (url == NULL)
        return UNKNOWN_ERROR;

    if (strncmp(url, "content://", 10) == 0) {
        // get a filedescriptor for the content Uri and
        // pass it to the setDataSource(fd) method

        String16 url16(url);
        int fd = android::openContentProviderFile(url16);
        if (fd < 0)
        {
            LOGE("Couldn't open fd for %s", url);
            return UNKNOWN_ERROR;
        }
        setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
        close(fd);
        return mStatus;
    } else {
        //根据url返回对应的player_type,如: PV_PLAYER,STAGEFRIGHT_PLAYER, XX_PLAYER
        player_type playerType = getPlayerType(url);
        LOGV("player type = %d", playerType);

        // create the right type of player,建立真正的AVPlayer
        sp<MediaPlayerBase> p = createPlayer(playerType);
        if (p == NULL) return NO_INIT;

        if (!p->hardwareOutput()) {
            mAudioOutput = new AudioOutput();
            static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
        }

        // now set data source,把URL传递给真正的AVPlayer
        LOGV(" setDataSource");
        mStatus = p->setDataSource(url, headers);
        p->setOutRange( mService->getLeft(), mService->getTop(), mService->getWidth(), mService->getHeight()); 
        if (mStatus == NO_ERROR) {
            mPlayer = p;
        } else {
            LOGE("  error: %d", mStatus);
        }
        return mStatus;
    }
}

创建真正的AVPlayer

sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
    // determine if we have the right player type
    sp<MediaPlayerBase> p = mPlayer;
    LOGV("Enter MediaPlayerService::Client::createPlayer: playerType is %d", playerType);
    if ((p != NULL) && (p->playerType() != playerType)) {
        LOGV("p->playerType() is: %d, , delete player", p->playerType());
        p.clear();
    }
    if (p == NULL) {
        LOGV("Create new player");
        p = android::createPlayer(playerType, this, notify);
    }
    return p;
}
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
        notify_callback_f notifyFunc)
{
    sp<MediaPlayerBase> p;
    switch (playerType) {
        case XX_PLAYER:
            LOGV("Create XXPlayer");
            p = new XXPlayerService();
            break;
#ifndef NO_OPENCORE
        case PV_PLAYER:
            LOGV(" create PVPlayer");
            p = new PVPlayer();
            break;
#endif
        case SONIVOX_PLAYER:
            LOGV(" create MidiFile");
            p = new MidiFile();
            break;
        case VORBIS_PLAYER:
            LOGV(" create VorbisPlayer");
            p = new VorbisPlayer();
            break;
#if BUILD_WITH_FULL_STAGEFRIGHT
        case STAGEFRIGHT_PLAYER:
            LOGV(" create StagefrightPlayer");
            p = new StagefrightPlayer;
            break;
#endif
        case TEST_PLAYER:
            LOGV("Create Test Player stub");
            p = new TestPlayerStub();
            break;
    }
    if (p != NULL) {
        if (p->initCheck() == NO_ERROR) {
            p->setNotifyCallback(cookie, notifyFunc);
        } else {
            p.clear();
        }
    }
    if (p == NULL) {
        LOGE("Failed to create player object");
    }
    return p;
}

6.4 开始播放MediaPlayer::start

MediaPlayer::mPlayer实质为BpMediaPlayer

MediaPlayerService::Client::mPlayer实质为真正的AVPlayer,如:PVPlayer, XXPlayer

class PVPlayer: public MediaPlayerInterface

class MediaPlayerInterface : public MediaPlayerBase

 

MediaPlayer::start()  -->  mPlayer->start(BpMediaPlayer::start) --> remote()->transact(START, data, &reply)--> BpBinder::transact--> IPCThreadState::self()->transact--> ioctl(写) --> ioctl(读,在IPCThreadState::joinThreadPool中调用) --> BBinder::transact --> BnMediaPlayer::onTransact --> MediaPlayerService::Client::start -->MediaPlayerService::Client::mPlayer->start(PVPlayer->start)

 



 


 




 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值