DSP

Android Audio底层原理(二)

2019-07-13 15:51发布

1. Hal层类关系图

以MediaPlayer功能为例,我们可以根据Android 8.1 (Oreo)源代码绘制出其类图

2. IMediaPlayerService.h

     定义相关API,方便binder进程调用。IMediaPlayerService理论上是MediaPlayerService的接口,故只定义API而把API具体实现都放在class MediaPlayerService中。
class IMediaPlayerService: public IInterface {    public:
      DECLARE_META_INTERFACE(MediaPlayerService);
      ... ...
      virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, audio_session_t audioSessionIdAUDIO_SESSION_ALLOCATE) = 0; virtual sp<IOMX> getOMX() = 0;        virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) = 0;        virtual sp<IMediaCodecList> getCodecList() const = 0; };
class BnMediaPlayerService: public BnInterface<IMediaPlayerService> {    public:        virtual status_t onTransact( uint32_t code,                                                    const Parcel& data,                                                    Parcel* reply,                                                    uint32_t flags = 0); };
     2.1   BnMediaPlayerService       IMediaPlayerService主要有两个子类,一个是BpMediaPlayerServcie类,另一个是BnMediaPlayerService类。       IMediaPlayerService.h中,可以看到BnMediaPlayerService继承模板类BnInterface。在IInterface.h中可看到BnInterface的定义如下:
template<typename INTERFACE>
 
class BnInterface : public INTERFACE, public BBinder
  {
      public:
 
       virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
        
virtual const String16&     getInterfaceDescriptor() const;       protected:
        
virtual IBinder*            onAsBinder();
   };
        根据模板类的概念,BnMediaPlayerService相当于继承IMediaPlayerService和BBinder。         同理,BpMediaPlayerService类相当于继承了IMediaPlayerService和BpRefBase类。
template<typename INTERFACE> class BpInterface : public INTERFACE, public BpRefBase {      public:            explicit     BpInterface(const sp<IBinder>& remote);      protected:             virtual     IBinder* onAsBinder();  };
       2.2  DECLARE_META_INTERFACE( )
          DECLARE_META_INTERFACE( )同样位于IInterface.h,同样是一个模板函数。
#define DECLARE_META_INTERFACE(INTERFACE)
      static const ::
android::String16 descriptor;
      static ::
android::spINTERFACE> asInterface( const ::android::sp<::android::IBinder>& obj);       virtual const ::android::String16& getInterfaceDescriptor() const;
      I##
INTERFACE();
      virtual ~I##INTERFACE();
          则DECLARE_META_INTERFACE( MediaPlayerService)可以翻译为:
      static const ::android::String16 descriptor;
      static ::
android::sp asInterface( const ::android::sp<::android::IBinder>& obj);       virtual const ::android::String16& getInterfaceDescriptor() const;
      IMediaPlayerService();

      virtual ~IMediaPlayerService();                                  //释放IMediaPlayerService对象
         可以总结为IMediaPlayerService主要包含了以下几个虚函数,待子类 class MediaPlayerService实现。          (1) sp<IMediaPlayer> create(...)       //纯虚函数          (2) sp<IOMX> getOMX()                    //纯虚函数          (3) sp<IHDCP> makeHDCP(bool createEncryptionModule)   //纯虚函数       (4) sp<IMediaCodecList> getCodecList() const   //纯虚函数

3. IMediaPlayerService.cpp

    IMediaPlayer.cpp包含了class BpMediaPlayerService和class BnMediaPlayerService。     BpMediaPlayerService的主要设计满足代理模式(proxy),可以视为代理类,隔断客户端(访问对象)和服务端(被访问对象)。客户端对象必须通过代理类才能访问到BnMediaPlayerService中对象。      BpMediaPlayerService代理类的主要代码如下,主要作用是remote->transact( )调用。通知服务端具体调用。
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {    switch (code) {         case CREATE: {             CHECK_INTERFACE(IMediaPlayerService, data, reply);             sp<IMediaPlayerClient> client =interface_cast<IMediaPlayerClient(data.readStrongBinder()); audio_session_t audioSessionId = (audio_session_t) data.readInt32();              sp<IMediaPlayer> player = create(client, audioSessionId);              reply->writeStrongBinder(IInterface::asBinder(player));              return NO_ERROR;     } break;     ... ...     case GET_OMX: {            CHECK_INTERFACE(IMediaPlayerService, data, reply);            sp<IOMX> omx = getOMX();            reply->writeStrongBinder(IInterface::asBinder(omx));            return NO_ERROR;      } break;     case MAKE_HDCP: {            CHECK_INTERFACE(IMediaPlayerService, data, reply);            bool createEncryptionModule = data.readInt32();           sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);           reply->writeStrongBinder(IInterface::asBinder(hdcp));           return NO_ERROR;       } break;       ... ...
     case
LISTEN_FOR_REMOTE_DISPLAY: {           CHECK_INTERFACE(IMediaPlayerService, data, reply);           const String16 opPackageName = data.readString16();           sp<IRemoteDisplayClient> client(interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));           if (client == NULL) {                reply->writeStrongBinder(NULL);                return NO_ERROR;             }            String8 iface(data.readString8());            sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));                             reply->writeStrongBinder(IInterface::asBinder(display));            return NO_ERROR;        } break;        case GET_CODEC_LIST: {             CHECK_INTERFACE(IMediaPlayerService, data, reply);             sp<IMediaCodecList> mcl = getCodecList();             reply->writeStrongBinder(IInterface::asBinder(mcl));             return NO_ERROR;         } break;         default:             return BBinder::onTransact(code, data, reply, flags);         }  }
       BnMediaPlayerService作为实现类,重写onTransact( )函数,处理proxy发来的函数调用。
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {    switch (code) {         case CREATE: {             CHECK_INTERFACE(IMediaPlayerService, data, reply);             sp<IMediaPlayerClient> client =interface_cast<IMediaPlayerClient(data.readStrongBinder()); audio_session_t audioSessionId = (audio_session_t) data.readInt32();              sp<IMediaPlayer> player = create(client, audioSessionId);              reply->writeStrongBinder(IInterface::asBinder(player));              return NO_ERROR;     } break;     ... ...     case GET_OMX: {            CHECK_INTERFACE(IMediaPlayerService, data, reply);            sp<IOMX> omx = getOMX();            reply->writeStrongBinder(IInterface::asBinder(omx));            return NO_ERROR;      } break;     case MAKE_HDCP: {            CHECK_INTERFACE(IMediaPlayerService, data, reply);            bool createEncryptionModule = data.readInt32();           sp<IHDCP> hdcp = makeHDCP(createEncryptionModule);           reply->writeStrongBinder(IInterface::asBinder(hdcp));           return NO_ERROR;       } break;       ... ...
     case
LISTEN_FOR_REMOTE_DISPLAY: {           CHECK_INTERFACE(IMediaPlayerService, data, reply);