• Android MediaPlayer架构 -- 前言小知识点(二)


      本文系作者自己学习之所用,文章内容仅出自作者拙劣之思考,问题之处烦请不吝指教。

      在frameworksavmedialibmediamediaplayer.cpp中会有语句:const sp<IMediaPlayerService>& service(getMediaPlayerService()); 来建立MediaPlayerService的binder接口,那么这个getMediaPlayerService()是如何工作的呢,这篇文章简单看一下。

      本文涉及到的源文件:

      frameworks/av/include/media/mediaplayer.h

      frameworks/av/media/libmedia/mediaplayer.cpp

      frameworks/av/include/media/IMediaDeathNotifier.h

      frameworksav/media/libmedia/IMediaDeathNotifier.cpp

      首先我们要明确的是,getMediaPlayerService() 是IMediaDeathNotifier类的公有静态成员函数,而MediaPlayer继承自IMediaDeathNotifier,所以可以直接引用。

      getMediaPlayerService() 在IMediaDeathNotifier类中的声明:

      

    1 class IMediaDeathNotifier: virtual public RefBase
    2 {
    3 public:
    4     ......
    5     static const sp<IMediaPlayerService>& getMediaPlayerService(); // 静态、公有
    6     ......
    7 };

      

      MediaPlayer继承自IMediaDeathNotifier:

    1 class MediaPlayer : public BnMediaPlayerClient,
    2                     public virtual IMediaDeathNotifier // 注意继承关系
    3 {
    4       .......  
    5 }

      重点看一下getMediaPlayerService()方法的定义:

     1 // establish binder interface to MediaPlayerService
     2 /*static*/const sp<IMediaPlayerService>&
     3 IMediaDeathNotifier::getMediaPlayerService()
     4 {
     5     ALOGV("getMediaPlayerService");
     6     Mutex::Autolock _l(sServiceLock);
     7     if (sMediaPlayerService == 0) {
     8         sp<IServiceManager> sm = defaultServiceManager(); // 首先得到ServiceManager的引用
     9         sp<IBinder> binder;
    10         do {
    11             binder = sm->getService(String16("media.player")); // 向ServiceManager申请服务
    12             if (binder != 0) {
    13                 break;
    14             }
    15             ALOGW("Media player service not published, waiting...");
    16             usleep(500000); // 0.5 s
    17         } while (true);
    18 
    19         if (sDeathNotifier == NULL) {
    20             sDeathNotifier = new DeathNotifier();
    21         }
    22         binder->linkToDeath(sDeathNotifier);
    23         sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); // 类型转换为IMediaPlayerService
    24     }
    25     ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    26     return sMediaPlayerService;
    27 }

      上面这段代码的函数实现就是典型的通过ServiceManager获取binder服务的过程。

      顺便提一下,MediaPlayerService的注册是在 mediaserver (frameworks/av/media/mediaserver/main_mediaserver.cpp)中完成的

    1 int main(int argc __unused, char** argv)
    2 {
    3     ......
    4     MediaPlayerService::instantiate();
    5     ......
    6 }

      MediaPlayerService的instantiate函数:

    1 void MediaPlayerService::instantiate() {
    2     defaultServiceManager()->addService(
    3             String16("media.player"), new MediaPlayerService());
    4 }
  • 相关阅读:
    简单的总结
    /bin/bash: sshpass: command not found
    ubuntu 16.04 忘记root密码
    ubuntu下QtCreator启动无响应问题解决
    TX1 文字界面启动与root用户自动登录设置
    qt线程睡眠
    TX2 默认root用户启动
    linux下使用文件IO监听GPIO中断
    Linux下指定线程的名字
    [Error] ISO C++ forbids comparison between pointer and integer
  • 原文地址:https://www.cnblogs.com/roger-yu/p/8099111.html
Copyright © 2020-2023  润新知