美文网首页
Android Mediaplayer

Android Mediaplayer

作者: gbmaotai | 来源:发表于2018-09-11 15:22 被阅读0次

    JAVA类的路径:
    frameworks/base/media/java/android/media/MediaPlayer.java

    JAVA本地调用部分(JNI):
    frameworks/base/media/jni/android_media_MediaPlayer.cpp 这部分内容编译成为目标是libmedia_jni.so。

    主要的头文件在以下的目录中:frameworks/base/include/media/

    多媒体底层库在以下的目录中:frameworks/av/media/libmedia/
    这部分的内容被编译成库libmedia.so。

    多媒体服务部分:
    frameworks/av/media/libmediaplayerservice/
    文件为mediaplayerservice.h和mediaplayerservice.cpp
    这部分内容被编译成库libmediaplayerservice.so。

    int main(int argc __unused, char** argv)
    {
        ...
        InitializeIcuOrDie();  
        //获得ProcessState实例对象
        sp<ProcessState> proc(ProcessState::self());
        //获取ServiceManager实例对象 
        sp<IServiceManager> sm = defaultServiceManager();
        AudioFlinger::instantiate();
    
        MediaPlayerService::instantiate();
        ResourceManagerService::instantiate();
        CameraService::instantiate();
        AudioPolicyService::instantiate();
        SoundTriggerHwService::instantiate();
        RadioService::instantiate();
        registerExtensions();
    
        ProcessState::self()->startThreadPool();
    
        IPCThreadState::self()->joinThreadPool();
     }
    
    void MediaPlayerService::instantiate() {
        defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
    }
    

    defaultServiceManager

    获取Service Manager远程接口的函数是defaultServiceManager.
    gDefaultServiceManager是单例模式,调用defaultServiceManager函数时,如果gDefaultServiceManager已经创建,
    则直接返回,否则通过interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))来创建一个,
    并保存在gDefaultServiceManager全局变量中.

    getService接口来获得.Service Manager远程接口是一个特殊的Binder引用,它的引用句柄一定是0。

    ProcessState::ProcessState()
        : mDriverFD(open_driver()) 
        , mVMStart(MAP_FAILED)
        , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
        , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
        , mExecutingThreadsCount(0)
        , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
        , mManagesContexts(false)
        , mBinderContextCheckFunc(NULL)
        , mBinderContextUserData(NULL)
        , mThreadPoolStarted(false)
        , mThreadPoolSeq(1)
    {
        if (mDriverFD >= 0) {
            //采用内存映射函数mmap,给binder分配一块虚拟地址空间,用来接收事务
            mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
            if (mVMStart == MAP_FAILED) {
                close(mDriverFD); //没有足够空间分配给/dev/binder,则关闭驱动
                mDriverFD = -1;
            }
        }
    }
    

    ProcessState的单例模式的惟一性,因此一个进程只打开binder设备一次,其中ProcessState的成员变量mDriverFD记录binder驱动的fd,用于访问binder设备。

    BINDER_VM_SIZE = (110241024) - (4096 *2), binder分配的默认内存大小为1M-8k。

    DEFAULT_MAX_BINDER_THREADS = 15,binder默认的最大可并发访问的线程数为16。

    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    {
        //获取handle=0的IBinder
        return getStrongProxyForHandle(0);  
    }
    
    

    interface_cast

    template<typename INTERFACE>
    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
    {
        return INTERFACE::asInterface(obj);
    }
    

    对于asInterface()函数,也是通过模板函数来定义的,通过下面两个代码完成的:

    //位于IServiceManager.h文件
    DECLARE_META_INTERFACE(IServiceManager)
    //位于IServiceManager.cpp文件
    IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager")
    

    IServiceManager::asInterface() 等价于 new BpServiceManager()

    交互

    如果我们要使用MediaPlayerService服务,那么MediaPlayerService客户端就需要与MediaPlayerService
    (即BnMediaPlayerService)交互。交互的过程需要建立一个循环,然后读写Binder设备。注意,
    在BnMediaPlayerService中并没有打开Binder设备和建立一个循环监听,这里实际上是借用ProcessState来完成了MediaPlayerService的一些功能.

    IPCThreadState::self()->joinThreadPool,也就是说,主线程和工作线程都会执行joinThreadPool;
    在该函数中通过talkWithDriver函数操作Binder驱动程序,executeCommand函数来执行命令。
    查看executeCommand的代码可以得知,实际上会根据不同的命令进行不同的解析,
    但是最终的解析还是调用BBinder::transact函数,而transact又调用了自己的BBinder::onTransact函数。
    这里的BnMediaPlayerService继承自BBinder,所以会调用到它自己的BnMediaPlayerService::onTransact函数。

    客户端

    libs/media/mediaplayer.cpp

    class MediaPlayer : public BnMediaPlayerClient,
                        public virtual IMediaDeathNotifier
    
    const sp<IMediaPlayerService>& service(getMediaPlayerService());  
            if (service != 0) {  
                sp<IMediaPlayer> player(service->create(getpid(), this, url));  
                err = setDataSource(player);  
    

    相关文章

      网友评论

          本文标题:Android Mediaplayer

          本文链接:https://www.haomeiwen.com/subject/qreugftx.html