Android音频流程二(Binder部分)

2libmedia MediaPlayer至MediaPlayerService binder


clientservice之间的通信通过android binder机制,只是对于用户而言是透明的。

继续按照上面play调用流程,上面已经调用到了frameworksmediaplayer.cpp方法start

status_t MediaPlayer::start()
{
    LOGV("start");
    Mutex::Autolock _l(mLock);
    if (mCurrentState & MEDIA_PLAYER_STARTED)
        return NO_ERROR;
    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
        mPlayer->setLooping(mLoop);
        mPlayer->setVolume(mLeftVolume, mRightVolume);
        mPlayer->setAuxEffectSendLevel(mSendLevel);
        mCurrentState = MEDIA_PLAYER_STARTED;
        status_t ret = mPlayer->start();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
        } else {
            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
                LOGV("playback completed immediately following start()");
            }
        }
        return ret;
    }
    LOGE("start called in state %d", mCurrentState);
    return INVALID_OPERATION;
}

其中mPlayersetDataSource时候创建的播放器的实例,调用到的方法setLooping setVolume等都是在frameworks/base/include/mediaIMediaPlayer.h中声明

Ixx开头的头文件是binder机制的接口文件,每个这种接口文件同级目录下都会有对应一个.cpp文件,这里对应的是IMediaPlayer.cpp

这个C++文件定义binder的本地和代理函数,本地的是以Bn开头,native的意思,BnMediaPlyaer;代理的是以Bp开头,proxy的意思,BpMediaPlayer

这两个类之间调用是通过在kernel驱动的、在dev/下生成的一个binder程序来通信!代理端使用remote()->transact(),本地端响应请求onTransact()

代码如下:

class BpMediaPlayer: public BpInterface<IMediaPlayer>
{
public:
//...
    status_t start()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(START, data, &reply);
        return reply.readInt32();
}
//...
}
status_t BnMediaPlayer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
//...
        case START: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            reply->writeInt32(start());
            return NO_ERROR;
        } break;
//...
}
//...
}

播放器实例获得是通过setDataSource函数创建的,而这个函数会调用MediaPlayerService

const sp<IMediaPlayerService>& service(getMediaPlayerService());


再调用MediaPlayerServicecreatsetDataSource

总结下上面流程应该是:

======================================================================

|Applications                                      Music.apk                                      

|                                                                |                                          

|                                                                |                                          

|Framework                                   MediaPlayer API

======================================================================

--JNI----------------------------------------IMediaPlayer--------------------------------------------------

|                                                                |

|                                                                |

|libmedia                                          MediaPlayer

|                                                                |

--Binder---------------------------------------BpXXX-------------------------------------------------------

-------------------------------------------------BnXXX-------------------------------------------------------

|                                                                |

|                                                                |

|MediaServer                              MediaPlayerService

======================================================================


Binder在直观上看到是直接函数对应调用,实际上是有透过kernel空间的


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值