Android——Mediaplay 框架调用

基于android 4.1.1 源码


【1】mediaserver 启动后会把media相关一些服务添加到servicemanager中,其中就有mediaPlayerService.这样应用启动前,系统就有了mediaPlayerService这个服务程序。   

[java]   view plain copy
  1. int main(int argc, char** argv)  
  2. {  
  3.     sp proc(ProcessState::self());  
  4.     sp sm = defaultServiceManager();  
  5.     ALOGI("ServiceManager: %p", sm.get());  
  6.     AudioFlinger::instantiate();  
  7.     MediaPlayerService::instantiate();  
  8.     CameraService::instantiate();  
  9.     AudioPolicyService::instantiate();  
  10.     ProcessState::self()->startThreadPool();  
  11.     IPCThreadState::self()->joinThreadPool();  
  12. }  
[cpp]   view plain copy
  1. void MediaPlayerService::instantiate() {  
  2.     defaultServiceManager()->addService(  
  3.             String16("media.player"), new MediaPlayerService());  
  4. }  

【2】应用层 mediaPlayer=new MediaPlayer();  调用SDK中 MediaPlayer.java (frameworks\base\media\java\android\media\MediaPlayer.java)

[java]   view plain copy
  1. public MediaPlayer() {  
  2.   
  3.       Looper looper;  
  4.       if ((looper = Looper.myLooper()) != null) {  
  5.           mEventHandler = new EventHandler(this, looper);  
  6.       } else if ((looper = Looper.getMainLooper()) != null) {  
  7.           mEventHandler = new EventHandler(this, looper);  
  8.       } else {  
  9.           mEventHandler = null;  
  10.       }  
  11.   
  12.       /* Native setup requires a weak reference to our object. 
  13.        * It's easier to create it here than in C++. 
  14.        */  
  15.       native_setup(new WeakReference(this));  
  16.   }  

通过JNI方式调用到framework层 android_media_MediaPlayer.cpp(\frameworks\base\media\jni\android_media_MediaPlayer.cpp)

[cpp]   view plain copy
  1. static void  
  2. android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)  
  3. {  
  4.     ALOGV("native_setup");  
  5.     sp mp = new MediaPlayer();  
  6.     if (mp == NULL) {  
  7.         jniThrowException(env, "java/lang/RuntimeException""Out of memory");  
  8.         return;  
  9.     }  
  10.   
  11.     // create new listener and give it to MediaPlayer  
  12.     sp listener = new JNIMediaPlayerListener(env, thiz, weak_this);  
  13.     mp->setListener(listener);  
  14.   
  15.     // Stow our new C++ MediaPlayer in an opaque field in the Java object.  
  16.     setMediaPlayer(env, thiz, mp);  
  17. }  

继而调用mediaplayer.cpp(frameworks\av\media\libmedia\mediaplayer.cpp)

【3】在整个应用程序的进程中,mediaplayer.cpp 中 setDataSource会从service manager中获得mediaPlayerService 服务,然后通过服务来创建player。这个player就是播放器的真实实例。

[cpp]   view plain copy
  1. status_t MediaPlayer::setDataSource(const sp &source)  
  2. {  
  3.     ALOGV("setDataSource");  
  4.     status_t err = UNKNOWN_ERROR;  
  5.     const sp& service(getMediaPlayerService());  
  6.     if (service != 0) {  
  7.         sp player(service->create(getpid(), this, mAudioSessionId));  
  8.         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||  
  9.             (NO_ERROR != player->setDataSource(source))) {  
  10.             player.clear();  
  11.         }  
  12.         err = attachNewPlayer(player);  
  13.     }  
  14.     return err;  
  15. }  
【4】通过 getMediaPlayerService 得到的service其实是 BpMediaPlayerService,这是和 mediaPlayerService 进程中的BnMediaPlayerService 相对应负责binder通讯。BpMediaPlayerService中的create其实通过binder机制将CREATE消息发送出去。

[cpp]   view plain copy
  1. virtual sp create(  
  2.            pid_t pid, const sp& client, int audioSessionId) {  
  3.        Parcel data, reply;  
  4.        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());  
  5.        data.writeInt32(pid);  
  6.        data.writeStrongBinder(client->asBinder());  
  7.        data.writeInt32(audioSessionId);  
  8.   
  9.        remote()->transact(CREATE, data, &reply);  
  10.        return interface_cast(reply.readStrongBinder());  
  11.    }  

在对面的 BnMediaPlayerService中,通过onTransact()来接受这些消息。并把结果返回。

[cpp]   view plain copy
  1. status_t BnMediaPlayerService::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch (code) {  
  5.         case CREATE: {  
  6.             CHECK_INTERFACE(IMediaPlayerService, data, reply);  
  7.             pid_t pid = data.readInt32();  
  8.             sp client =  
  9.                 interface_cast(data.readStrongBinder());  
  10.             int audioSessionId = data.readInt32();  
  11.             sp player = create(pid, client, audioSessionId);  
  12.             reply->writeStrongBinder(player->asBinder());  
  13.             return NO_ERROR;  
  14.         } break;  
  15.         case MAKE_CRYPTO:  
  16. }  
当发现是CREATE才真正调用了MediaPlayerService 中的create函数。在create函数中其实是创建了一个MediaPlayerService::Client的实例,也就是 说 MediaPlayerService会为每个client应用进程创建一个相应的MediaPlayerService::Client的实例,来提供服务。

[cpp]   view plain copy
  1. sp MediaPlayerService::create(pid_t pid, const sp& client,  
  2.         int audioSessionId)  
  3. {  
  4.     int32_t connId = android_atomic_inc(&mNextConnId);  
  5.   
  6.     sp c = new Client(  
  7.             this, pid, connId, client, audioSessionId,  
  8.             IPCThreadState::self()->getCallingUid());  
  9.   
  10.     ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,  
  11.          IPCThreadState::self()->getCallingUid());  
  12.   
  13.     wp w = c;  
  14.     {  
  15.         Mutex::Autolock lock(mLock);  
  16.         mClients.add(w);  
  17.     }  
  18.     return c;  
  19. }  

【5】这样 mediaplayer.cpp 就得到了一个player的实例,对他来说这个实例和本地的其他类的实例没什么用法上的区别,殊不知其实这个实例是运行在另外一个进程中。实现这种假象的就是binder机制。获得这个实例后继续player->setDataSource().在 MediaPlayerService的进程中他的实际函数中,才会真正的创建Stagefright的具体实例。
[cpp]   view plain copy
  1. status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)  
  2. {  
  3.     ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);  
  4.     struct stat sb;  
  5.     int ret = fstat(fd, &sb);  
  6.     if (ret != 0) {  
  7.         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));  
  8.         return UNKNOWN_ERROR;  
  9.     }  
  10.   
  11.     ALOGV("st_dev  = %llu", sb.st_dev);  
  12.     ALOGV("st_mode = %u", sb.st_mode);  
  13.     ALOGV("st_uid  = %lu", sb.st_uid);  
  14.     ALOGV("st_gid  = %lu", sb.st_gid);  
  15.     ALOGV("st_size = %llu", sb.st_size);  
  16.   
  17.     if (offset >= sb.st_size) {  
  18.         ALOGE("offset error");  
  19.         ::close(fd);  
  20.         return UNKNOWN_ERROR;  
  21.     }  
  22.     if (offset + length > sb.st_size) {  
  23.         length = sb.st_size - offset;  
  24.         ALOGV("calculated length = %lld", length);  
  25.     }  
  26.   
  27.     // Until re-transmit functionality is added to the existing core android  
  28.     // players, we use the special AAH TX player whenever we were configured for  
  29.     // retransmission.  
  30.     player_type playerType = getPlayerType(fd, offset, length);  
  31.     sp p = setDataSource_pre(playerType);  
  32.     if (p == NULL) {  
  33.         return NO_INIT;  
  34.     }  
  35.   
  36.     // now set data source  
  37.     setDataSource_post(p, p->setDataSource(fd, offset, length));  
  38.     return mStatus;  
  39. }  
[cpp]   view plain copy
  1. sp MediaPlayerService::Client::setDataSource_pre(  
  2.         player_type playerType)  
  3. {  
  4.     ALOGV("player type = %d", playerType);  
  5.   
  6.     // create the right type of player  
  7.     sp p = createPlayer(playerType);  
  8.     if (p == NULL) {  
  9.         return p;  
  10.     }  
  11.   
  12.     if (!p->hardwareOutput()) {  
  13.         mAudioOutput = new AudioOutput(mAudioSessionId);  
  14.         static_cast(p.get())->setAudioSink(mAudioOutput);  
  15.     }  
  16.   
  17.     return p;  
  18. }  
[cpp]   view plain copy
  1. sp MediaPlayerService::Client::createPlayer(player_type playerType)  
  2. {  
  3.     // determine if we have the right player type  
  4.     sp p = mPlayer;  
  5.     if ((p != NULL) && (p->playerType() != playerType)) {  
  6.         ALOGV("delete player");  
  7.         p.clear();  
  8.     }  
  9.     if (p == NULL) {  
  10.         p = android::createPlayer(playerType, this, notify);  
  11.     }  
  12.   
  13.     if (p != NULL) {  
  14.         p->setUID(mUID);  
  15.     }  
  16.   
  17.     return p;  
  18. }  
[cpp]   view plain copy
  1. static sp createPlayer(player_type playerType, void* cookie,  
  2.         notify_callback_f notifyFunc)  
  3. {  
  4.     sp p;  
  5.     switch (playerType) {  
  6.         case SONIVOX_PLAYER:  
  7.             ALOGV(" create MidiFile");  
  8.             p = new MidiFile();  
  9.             break;  
  10.         case STAGEFRIGHT_PLAYER:  
  11.             ALOGV(" create StagefrightPlayer");  
  12.             p = new StagefrightPlayer;  
  13.             break;  
  14.         case NU_PLAYER:  
  15.             ALOGV(" create NuPlayer");  
  16.             p = new NuPlayerDriver;  
  17.             break;  
  18.         case TEST_PLAYER:  
  19.             ALOGV("Create Test Player stub");  
  20.             p = new TestPlayerStub();  
  21.             break;  
  22.         case AAH_RX_PLAYER:  
  23.             ALOGV(" create A@H RX Player");  
  24.             p = createAAH_RXPlayer();  
  25.             break;  
  26.         case AAH_TX_PLAYER:  
  27.             ALOGV(" create A@H TX Player");  
  28.             p = createAAH_TXPlayer();  
  29.             break;  
  30.         default:  
  31.             ALOGE("Unknown player type: %d", playerType);  
  32.             return NULL;  
  33.     }  
  34.     if (p != NULL) {  
  35.         if (p->initCheck() == NO_ERROR) {  
  36.             p->setNotifyCallback(cookie, notifyFunc);  
  37.         } else {  
  38.             p.clear();  
  39.         }  
  40.     }  
  41.     if (p == NULL) {  
  42.         ALOGE("Failed to create player object");  
  43.     }  
  44.     return p;  
  45. }  

在上面中已经看不到opencore的影子了,creaPlayer 中会根据类型来创建播放器的实例。Stagefright的实例就是在这里创建的。

下一步我们能真正进入到Stagefright里了

你可能感兴趣的:(【Android,—,框架】,android,mediaplay,binder,server)