Android 里从“media.player ” 服务里获取 IOMX 的智能指针

来源:互联网 发布:无水印视频剪辑软件 编辑:程序博客网 时间:2024/05/21 16:23

Android里原生媒体播放器是通过 media.player 这个服务来实现的。定义这个服务的接口是 IMediaPlayerService,它委身在/system/bin/mediaserver 这个进程里,该进程还有收纳camera audio等服务。在main_mediaserver.cpp 里有这一句 MediaPlayerService::instantiate(); 来启动这个服务。

IMediaPlayerService里定义了一个虚方法:virtual sp<IOMX>            getOMX() = 0;

有关这个类的派生关系如下图:

它就是用来给本进程和其他进程取得IOMX智能指针的方法。IOMX其实是一个用来初始化 OMXIL component 的 OMXIL client 。

这个方法的具体实现在 MediaPlayerService.cpp 里:

sp<IOMX> MediaPlayerService::getOMX() {
    Mutex::Autolock autoLock(mLock);
    LOGW(  " getOMX  mOMX=%d    1" , mOMX.get() ) ;
    if (mOMX.get() == NULL) {
  LOGW(  "mOMX=%d    2" , mOMX.get() ) ;
        mOMX = new OMX;
 LOGW(  "mOMX=%d    3" , mOMX.get() ) ; 
    }
    return mOMX;
}

 

对于本进程,也就是 media.player 这个服务里,也有通过这个方法取得 IOMX指针的调用。AwesomePlayer 里有一个 OMXClient 类的实例变量mClient 。

class OMXClient {
public:
    OMXClient();

    status_t connect();
    void disconnect();

    sp<IOMX> interface() {
  
        return mOMX;
    }

private:
    sp<IOMX> mOMX;

    OMXClient(const OMXClient &);
    OMXClient &operator=(const OMXClient &);
};

AwesomePlayer要使用 OMXIL component 时都是通过 mClinet.interface() 获得 IOMX的智能指针。

OMXClient::mOMX 的初始化就是通过这段代码来得到的

status_t OMXClient::connect() {
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->getService(String16("media.player"));
    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);

    CHECK(service.get() != NULL);
   LOGW(  " getOMX  OMXClient()  1  %d" , mOMX.get() ) ;

    mOMX = service->getOMX();
    LOGW(  " getOMX  OMXClient()  2  %d" , mOMX.get() ) ;
    CHECK(mOMX.get() != NULL);

    return OK;
}

看一个 AwesomePlayer里调用 mClient.interface() 的地方:

status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {

......

    LOGW(  "mOMX=%x    4" , mClient.interface().get() ) ;
    LOGW(  "mOMX=%d    4" , mClient.interface().get() ) ;
    mVideoSource = OMXCodec::Create(
            mClient.interface(), mVideoTrack->getFormat(),
            false, // createEncoder
            mVideoTrack,
            NULL, flags);
....

}

在这里AwesomePlayer 和 MediaPlayerService::instantiate() 是同一个进程,上面OMXClient::connect()函数里的mOMX = service->getOMX();会直接调用MediaPlayerService::getOMX()。 MediaPlayerService::mOMX 是在第一次MediaPlayerService::getOMX()被调用时初始化的。

这些可以在这段log里得到验证:

[ 03-28 12:06:08.369    97:0x61 W/OMXClient ] getOMX  OMXClient()  1  0
[ 03-28 12:06:08.369    97:0x61 W/MediaPlayerService ] getOMX  mOMX=64968    1
[ 03-28 12:06:08.369    97:0x61 W/OMXClient ]getOMX  OMXClient()  2  64968
 
[ 03-28 12:06:08.399    97:0x351 W/AwesomePlayer ]mOMX=fdc8    4
[ 03-28 12:06:08.399    97:0x351 W/AwesomePlayer ]mOMX=64968    4

别的进程也可以获得 media.player 里的 IOMX 智能指针,这个就要复杂一些。以OMXHarness.cpp所创建的测试进程为例, 请看下图和源码和log:

status_t Harness::initOMX() {
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->getService(String16("media.player"));
    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);

    LOGW(  " getOMX  Harness::initOMX() 1  %d" , mOMX.get() ) ;
   
    mOMX = service->getOMX();

    LOGW(  " getOMX  Harness::initOMX() 2  %d" , mOMX.get() ) ;
    return mOMX != 0 ? OK : NO_INIT;
}

 

class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
{

....
    virtual sp<IOMX> getOMX() {
        Parcel data, reply;
   LOGE(  "getOMX in BpMediaPlayerService " ) ;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        remote()->transact(GET_OMX, data, &reply);
        return interface_cast<IOMX>(reply.readStrongBinder());
    }

.....

}

 

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

........

        case GET_OMX: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
       LOGE(  "GET_OMX in BnMediaPlayerService::onTransact to getOMX " ) ; 
            sp<IOMX> omx = getOMX();
        LOGE(  "GET_OMX in BnMediaPlayerService::onTransact to getOMX is %d " ,omx.get() ) ;  
            reply->writeStrongBinder(omx->asBinder());
            return NO_ERROR;
        } break;
........

}


[ 03-28 12:39:22.779   991:0x3df W/OMXHarness ] getOMX  Harness::initOMX() 1  0
[ 03-28 12:39:22.779   991:0x3df E/         ] getOMX in BpMediaPlayerService
[ 03-28 12:39:22.789    97:0x61 E/         ] GET_OMX in BnMediaPlayerService::onTransact to getOMX
[ 03-28 12:39:22.789    97:0x61 W/MediaPlayerService ]  getOMX  mOMX=64968    1
[ 03-28 12:39:22.789    97:0x61 E/         ] GET_OMX in BnMediaPlayerService::onTransact to getOMX is 64968
[ 03-28 12:39:22.789   991:0x3df W/OMXHarness ]   getOMX  Harness::initOMX() 2  76760

 

 

 可以看出别的进程通过获得 media.player 服务里得 IOMX 智能指针,可以使用 OMXIL component 来解压视频和音频压缩包。

 

 

 

 

 


 

 

 

 

 

原创粉丝点击