您的位置:首页 > 移动开发 > Android开发

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

2013-03-29 17:03 363 查看
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 来解压视频和音频压缩包。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: