美文网首页
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多媒体系统框架

    1.Android MediaPlayer多媒体视频系统框架简介 Mediaplayer是Android系统中最为...

  • ExoPlayer 开发指南

    ExoPlayer 与 MediaPlayer 与Android内置的MediaPlayer相比,ExoPlaye...

  • 2018-07-11

    浅谈Android MediaPlayer 前言 MediaPlayer是Android中多媒体框架中一个重要的组...

  • MediaPlayer

    1.MediaPlayer.java类 (1)Android MediaPlayer类[https://blog....

  • Android MediaPlayer 基础简介

    本文链接: Android MediaPlayer 基础简介 简单介绍MediaPlayer的基本概念,状态,常用...

  • Android MediaPlayer 播放音频

    本文链接: Android MediaPlayer 播放音频 主要介绍使用MediaPlayer播放音频的方式。关...

  • 音乐播放器

    一.MediaPlayer简介Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频...

  • Android开发之MediaPlayer使用

    MediaPlayer MediaPlayer是Android系统自带的,可以用来播放音频、视频和流媒体。Medi...

  • 多媒体工程师必备技能

    1.Android 平台多媒体框架; MediaPlayer 播放器全面剖析(一)MediaPlayer 播放器全...

  • 播放音频

    在 Android 中播放音频文件一般都是使用 MediaPlayer 类来实现的。 MediaPlayer 工作...

网友评论

      本文标题:Android Mediaplayer

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