Android——Mediaplay 框架调用
16lz
2021-01-26
基于android 4.1.1 源码
【1】mediaserver启动后会把media相关一些服务添加到servicemanager中,其中就有mediaPlayerService.这样应用启动前,系统就有了mediaPlayerService这个服务程序。
[java] view plain copy
- intmain(intargc,char**argv)
- {
- sp<ProcessState>proc(ProcessState::self());
- sp<IServiceManager>sm=defaultServiceManager();
- ALOGI("ServiceManager:%p",sm.get());
- AudioFlinger::instantiate();
- MediaPlayerService::instantiate();
- CameraService::instantiate();
- AudioPolicyService::instantiate();
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- }
- voidMediaPlayerService::instantiate(){
- defaultServiceManager()->addService(
- String16("media.player"),newMediaPlayerService());
- }
【2】应用层mediaPlayer=newMediaPlayer(); 调用SDK中MediaPlayer.java (frameworks\base\media\java\android\media\MediaPlayer.java)
[java] view plain copy
- publicMediaPlayer(){
- Looperlooper;
- if((looper=Looper.myLooper())!=null){
- mEventHandler=newEventHandler(this,looper);
- }elseif((looper=Looper.getMainLooper())!=null){
- mEventHandler=newEventHandler(this,looper);
- }else{
- mEventHandler=null;
- }
- /*Nativesetuprequiresaweakreferencetoourobject.
- *It'seasiertocreateitherethaninC++.
- */
- native_setup(newWeakReference<MediaPlayer>(this));
- }
通过JNI方式调用到framework层android_media_MediaPlayer.cpp(\frameworks\base\media\jni\android_media_MediaPlayer.cpp)
[cpp] view plain copy- staticvoid
- android_media_MediaPlayer_native_setup(JNIEnv*env,jobjectthiz,jobjectweak_this)
- {
- ALOGV("native_setup");
- sp<MediaPlayer>mp=newMediaPlayer();
- if(mp==NULL){
- jniThrowException(env,"java/lang/RuntimeException","Outofmemory");
- return;
- }
- //createnewlistenerandgiveittoMediaPlayer
- sp<JNIMediaPlayerListener>listener=newJNIMediaPlayerListener(env,thiz,weak_this);
- mp->setListener(listener);
- //StowournewC++MediaPlayerinanopaquefieldintheJavaobject.
- setMediaPlayer(env,thiz,mp);
- }
继而调用mediaplayer.cpp(frameworks\av\media\libmedia\mediaplayer.cpp)
【3】在整个应用程序的进程中,mediaplayer.cpp 中setDataSource会从service manager中获得mediaPlayerService服务,然后通过服务来创建player。这个player就是播放器的真实实例。
[cpp] view plain copy
- status_tMediaPlayer::setDataSource(constsp<IStreamSource>&source)
- {
- ALOGV("setDataSource");
- status_terr=UNKNOWN_ERROR;
- constsp<IMediaPlayerService>&service(getMediaPlayerService());
- if(service!=0){
- sp<IMediaPlayer>player(service->create(getpid(),this,mAudioSessionId));
- if((NO_ERROR!=doSetRetransmitEndpoint(player))||
- (NO_ERROR!=player->setDataSource(source))){
- player.clear();
- }
- err=attachNewPlayer(player);
- }
- returnerr;
- }
[cpp] view plain copy
- virtualsp<IMediaPlayer>create(
- pid_tpid,constsp<IMediaPlayerClient>&client,intaudioSessionId){
- Parceldata,reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- data.writeInt32(pid);
- data.writeStrongBinder(client->asBinder());
- data.writeInt32(audioSessionId);
- remote()->transact(CREATE,data,&reply);
- returninterface_cast<IMediaPlayer>(reply.readStrongBinder());
- }
在对面的 BnMediaPlayerService中,通过onTransact()来接受这些消息。并把结果返回。
[cpp] view plain copy
- status_tBnMediaPlayerService::onTransact(
- uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
- {
- switch(code){
- caseCREATE:{
- CHECK_INTERFACE(IMediaPlayerService,data,reply);
- pid_tpid=data.readInt32();
- sp<IMediaPlayerClient>client=
- interface_cast<IMediaPlayerClient>(data.readStrongBinder());
- intaudioSessionId=data.readInt32();
- sp<IMediaPlayer>player=create(pid,client,audioSessionId);
- reply->writeStrongBinder(player->asBinder());
- returnNO_ERROR;
- }break;
- caseMAKE_CRYPTO:
- }
[cpp] view plain copy
- sp<IMediaPlayer>MediaPlayerService::create(pid_tpid,constsp<IMediaPlayerClient>&client,
- intaudioSessionId)
- {
- int32_tconnId=android_atomic_inc(&mNextConnId);
- sp<Client>c=newClient(
- this,pid,connId,client,audioSessionId,
- IPCThreadState::self()->getCallingUid());
- ALOGV("Createnewclient(%d)frompid%d,uid%d,",connId,pid,
- IPCThreadState::self()->getCallingUid());
- wp<Client>w=c;
- {
- Mutex::Autolocklock(mLock);
- mClients.add(w);
- }
- returnc;
- }
【5】这样 mediaplayer.cpp 就得到了一个player的实例,对他来说这个实例和本地的其他类的实例没什么用法上的区别,殊不知其实这个实例是运行在另外一个进程中。实现这种假象的就是binder机制。获得这个实例后继续player->setDataSource().在 MediaPlayerService的进程中他的实际函数中,才会真正的创建Stagefright的具体实例。 [cpp] view plain copy
- status_tMediaPlayerService::Client::setDataSource(intfd,int64_toffset,int64_tlength)
- {
- ALOGV("setDataSourcefd=%d,offset=%lld,length=%lld",fd,offset,length);
- structstatsb;
- intret=fstat(fd,&sb);
- if(ret!=0){
- ALOGE("fstat(%d)failed:%d,%s",fd,ret,strerror(errno));
- returnUNKNOWN_ERROR;
- }
- ALOGV("st_dev=%llu",sb.st_dev);
- ALOGV("st_mode=%u",sb.st_mode);
- ALOGV("st_uid=%lu",sb.st_uid);
- ALOGV("st_gid=%lu",sb.st_gid);
- ALOGV("st_size=%llu",sb.st_size);
- if(offset>=sb.st_size){
- ALOGE("offseterror");
- ::close(fd);
- returnUNKNOWN_ERROR;
- }
- if(offset+length>sb.st_size){
- length=sb.st_size-offset;
- ALOGV("calculatedlength=%lld",length);
- }
- //Untilre-transmitfunctionalityisaddedtotheexistingcoreandroid
- //players,weusethespecialAAHTXplayerwheneverwewereconfiguredfor
- //retransmission.
- player_typeplayerType=getPlayerType(fd,offset,length);
- sp<MediaPlayerBase>p=setDataSource_pre(playerType);
- if(p==NULL){
- returnNO_INIT;
- }
- //nowsetdatasource
- setDataSource_post(p,p->setDataSource(fd,offset,length));
- returnmStatus;
- }
- sp<MediaPlayerBase>MediaPlayerService::Client::setDataSource_pre(
- player_typeplayerType)
- {
- ALOGV("playertype=%d",playerType);
- //createtherighttypeofplayer
- sp<MediaPlayerBase>p=createPlayer(playerType);
- if(p==NULL){
- returnp;
- }
- if(!p->hardwareOutput()){
- mAudioOutput=newAudioOutput(mAudioSessionId);
- static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
- }
- returnp;
- }
- sp<MediaPlayerBase>MediaPlayerService::Client::createPlayer(player_typeplayerType)
- {
- //determineifwehavetherightplayertype
- sp<MediaPlayerBase>p=mPlayer;
- if((p!=NULL)&&(p->playerType()!=playerType)){
- ALOGV("deleteplayer");
- p.clear();
- }
- if(p==NULL){
- p=android::createPlayer(playerType,this,notify);
- }
- if(p!=NULL){
- p->setUID(mUID);
- }
- returnp;
- }
- staticsp<MediaPlayerBase>createPlayer(player_typeplayerType,void*cookie,
- notify_callback_fnotifyFunc)
- {
- sp<MediaPlayerBase>p;
- switch(playerType){
- caseSONIVOX_PLAYER:
- ALOGV("createMidiFile");
- p=newMidiFile();
- break;
- caseSTAGEFRIGHT_PLAYER:
- ALOGV("createStagefrightPlayer");
- p=newStagefrightPlayer;
- break;
- caseNU_PLAYER:
- ALOGV("createNuPlayer");
- p=newNuPlayerDriver;
- break;
- caseTEST_PLAYER:
- ALOGV("CreateTestPlayerstub");
- p=newTestPlayerStub();
- break;
- caseAAH_RX_PLAYER:
- ALOGV("create[email protected]RXPlayer");
- p=createAAH_RXPlayer();
- break;
- caseAAH_TX_PLAYER:
- ALOGV("create[email protected]TXPlayer");
- p=createAAH_TXPlayer();
- break;
- default:
- ALOGE("Unknownplayertype:%d",playerType);
- returnNULL;
- }
- if(p!=NULL){
- if(p->initCheck()==NO_ERROR){
- p->setNotifyCallback(cookie,notifyFunc);
- }else{
- p.clear();
- }
- }
- if(p==NULL){
- ALOGE("Failedtocreateplayerobject");
- }
- returnp;
- }
在上面中已经看不到opencore的影子了,creaPlayer 中会根据类型来创建播放器的实例。Stagefright的实例就是在这里创建的。
下一步我们能真正进入到Stagefright里了
更多相关文章
- Android之TabLayout常见问题解决+TabLayout+ViewPager实现标签页
- SystemUI编译遇到的问题
- Android(安卓)RIL 架构学习总结
- Android(安卓)studio添加按钮点击进入下一页
- android pagerView
- Android(安卓)SystemServer 启动流程
- Android(安卓)RIL 架构学习总结 .
- Android(安卓)Activity 四种启动模式
- Fresco源码解析 - 创建一个ImagePipeline(一)