android mediaplayer client与server的交互流程

来源:互联网 发布:java小游戏源代码下载 编辑:程序博客网 时间:2024/05/26 20:20

一、  mediplayer 的架构的类图表示:


图1


二、  mediplayer Server端流程:

1、启动mediaserver进程(mips-ics\frameworks\base\media\mediaserver\main_mediaserver.cpp)

int main(int argc, char** argv)

{

   sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm =defaultServiceManager();\*获取servicemanager*\

    MediaPlayerService::instantiate(); /*初始化MediaplayerSevice*/

    ProcessState::self()->startThreadPool();/*open /dev/binder, //启动进程的线程池*/

   IPCThreadState::self()->joinThreadPool();//将自己加入到线程池

}

/*向servicemanager 注册名称为”media.player”的service,实例化MediaplayerSevice(是IBinder的子类)并传给addService函数,*/

void MediaPlayerService::instantiate() {

   defaultServiceManager()->addService(

           String16("media.player"), new MediaPlayerService());

}

addService( constString16& name, const sp<IBinder>& service)



图2: mediaplayerService的注册流程



图3:media client 获取media service 的流程图


三、  mediplayer Client端流程:


1. Client code

 

1、 Java 代码

   mMediaPlayer = newMediaPlayer();  /*调用native_setup()*/

   mMediaPlayer .setDataSource(uri)

 

 

2.Mediaplayer JavaAPI: (MediaPlayer.java)

public class MediaPlayer

{

    static {

        System.loadLibrary("media_jni");  /*load media_jni.so 库*/

        native_init();}

public MediaPlayer() {

                                native_setup(newWeakReference<MediaPlayer>(this));

}

}

 

2、 C++ 代码

1. jni code.   (frameworks\base\media\jni\android_media_MediaPlayer.cpp)

 

android_media_MediaPlayer_native_setup()  /*native JNI code*/

{

sp<MediaPlayer> mp = new MediaPlayer();

    // create new listener and give it toMediaPlayer

   sp<JNIMediaPlayerListener> listener = newJNIMediaPlayerListener(env, thiz, weak_this);

    mp->setListener(listener);

}

 

2. Client C++ code

 

libMedia_Jni (android_media_MediaPlayer.cpp)

 

static JNINativeMethod gMethods[]= {

   {"native_init",        "()V",                              (void*)android_media_MediaPlayer_native_init},

   {"native_setup",       "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},

{"setDataSource",       "(Ljava/lang/String;)V",      (void*)android_media_MediaPlayer_setDataSource},

{"prepare",             "()V",   (void*)android_media_MediaPlayer_prepare},

{"_start",              "()V",     (void *)android_media_MediaPlayer_start},

{"_stop",               "()V",     (void *)android_media_MediaPlayer_stop},};

 

 

android_media_MediaPlayer_setDataSource()  /*native JNI code*/

{

sp<MediaPlayer> mp =getMediaPlayer(env, thiz);

mp->setDataSource();

}

 

frameworks\base\media\libmedia \mediaplayer.cpp

MediaPlayer::setDataSource()       

{

      constsp<IMediaPlayerService>& service(getMediaPlayerService());/create BpMediaplayerServices*/

    /*createbpMediaplayer*/

       sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));

       player->setDataSource(url,headers)) ;

       attachNewPlayer(player);

}

 

mediaplyer client获取服务:

const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()

{

       sp<IServiceManager> sm = defaultServiceManager(); /*获取servicemanager*/

       sp<IBinder> binder;

         binder =sm->getService(String16("media.player"));/*获取名称为”media.player”的服务,并返回指向基类binder的指针(对象为MediaplayerSevice)*/

       sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

    将基类binder指向MediaplayerService的对外接口IMediaPlayerService

}

 

 

BpMediaPlayerService:: create()

{

       remote()->transact(CREATE, data, &reply);  /*IPC通知server create service*/

        /*create BpMediaPlayer实例, 参数为指向BnMediaplayer的Ibinder*/

        returninterface_cast<IMediaPlayer>(reply.readStrongBinder());

}

 

BpMediaPlayer:: setDataSource()

{

      /*向server 发送SET_DATA_SOURCE_URL命令*/

       remote()->transact(SET_DATA_SOURCE_URL, data, &reply);

}

 

3. Server C++ code.

BnMediaPlayerService::onTransact()

{

        caseCREATE_FD: {

 /*在server端创建一个与client 对应的client,建立一个server àclient 的notify通道*/

           sp<IMediaPlayerClient> client =interface_cast<IMediaPlayerClient>(data.readStrongBinder());

/*将该client传给BnMeidaplayer*/

           sp<IMediaPlayer> player = create(pid, client,fd, offset, length, audioSessionId);

/*将BnMediaPlayer的实例返回给BpMediaplayer*/

           reply->writeStrongBinder(player->asBinder());

}

 

sp<IMediaPlayer>MediaPlayerService::create()

{

/*创建一个BnMediaplayer的派生类client的实例*/
    sp<Client> c = new MediaPlayerService::Client();

    Return c;

}

 

MediaPlayerService::Client::setDataSource()

{

        player_typeplayerType = getPlayerType(url);

       sp<MediaPlayerBase> p = createPlayer(playerType);

        mStatus =p->setDataSource(url, headers);

}

createPlayer(player_type playerType)

{

new StagefrightPlayer();

}


四、 多个service 在同一个进程中


frameworks\base\media\mediaserver\main_mediaserver.cpp

int main(int argc, char** argv)

{

   sp<ProcessState> proc(ProcessState::self());

   sp<IServiceManager> sm = defaultServiceManager();

   LOGI("ServiceManager: %p", sm.get());

   AudioFlinger::instantiate();

   MediaPlayerService::instantiate();

   CameraService::instantiate();

   AudioPolicyService::instantiate();

   ProcessState::self()->startThreadPool();

   IPCThreadState::self()->joinThreadPool();

}

 

AudioFinger,MeidaPlayer,Camera,AudioPolicy 这些server 的实例的作用域都是在本进程内有效,而且这些server的binder的uid都是指向本进程。



原创粉丝点击