了解與友情的關(guān)系好似調(diào)情之于愛(ài)情——高興,但卻又不滿足。基于android 4.1.1 源碼
科學(xué)家必須在錯(cuò)雜的經(jīng)驗(yàn)事實(shí)中抓住某些可用緊密公式來(lái)默示的廣泛特點(diǎn),由此尋找天然界的廣泛道理。
【1】mediaserver 啟動(dòng)后會(huì)把media相干一些辦事添加到servicemanager中,此中就有mediaPlayerService.如許應(yīng)用啟動(dòng)前,體系就有了mediaPlayerService這個(gè)辦事法度。
int main(int argc, 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(); }
void MediaPlayerService::instantiate() { defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); }
【2】應(yīng)用層 mediaPlayer=new MediaPlayer(); 調(diào)用SDK中 MediaPlayer.java (frameworksasemediajavaandroidmediaMediaPlayer.java)
public MediaPlayer() { Looper looper; if ((looper = Looper.myLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else if ((looper = Looper.getMainLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else { mEventHandler = null; } /* Native setup requires a weak reference to our object. * It""s easier to create it here than in C++. */ native_setup(new WeakReference<MediaPlayer>(this)); }
經(jīng)由過(guò)程JNI體式格式調(diào)用到framework層 android_media_MediaPlayer.cpp(frameworksasemediajniandroid_media_MediaPlayer.cpp)
static void android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) { ALOGV("native_setup"); sp<MediaPlayer> mp = new MediaPlayer(); if (mp == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; } // create new listener and give it to MediaPlayer sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this); mp->setListener(listener); // Stow our new C++ MediaPlayer in an opaque field in the Java object. setMediaPlayer(env, thiz, mp); }
繼而調(diào)用mediaplayer.cpp(frameworksavmedialibmediamediaplayer.cpp)
【3】在全部應(yīng)用法度的過(guò)程中,mediaplayer.cpp 中 setDataSource會(huì)從service manager中獲得mediaPlayerService 辦事,然后經(jīng)由過(guò)程辦事來(lái)創(chuàng)建player。這個(gè)player就是播放器的真實(shí)實(shí)例。
status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source) { ALOGV("setDataSource"); status_t err = UNKNOWN_ERROR; const sp<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); } return err; }【4】經(jīng)由過(guò)程 getMediaPlayerService 獲得的service其實(shí)是 BpMediaPlayerService,這是和mediaPlayerService過(guò)程中的BnMediaPlayerService 相對(duì)應(yīng)負(fù)責(zé)binder通信。BpMediaPlayerService中的create其實(shí)經(jīng)由過(guò)程binder機(jī)制將CREATE消息發(fā)送出去。
virtual sp<IMediaPlayer> create( pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); data.writeInt32(pid); data.writeStrongBinder(client->asBinder()); data.writeInt32(audioSessionId); remote()->transact(CREATE, data, &reply); return interface_cast<IMediaPlayer>(reply.readStrongBinder()); }
在對(duì)面的BnMediaPlayerService中,經(jīng)由過(guò)程onTransact()來(lái)接管這些消息。并把成果返回。
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case CREATE: { CHECK_INTERFACE(IMediaPlayerService, data, reply); pid_t pid = data.readInt32(); sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder()); int audioSessionId = data.readInt32(); sp<IMediaPlayer> player = create(pid, client, audioSessionId); reply->writeStrongBinder(player->asBinder()); return NO_ERROR; } break; case DECODE_URL: { CHECK_INTERFACE(IMediaPlayerService, data, reply); const char* url = data.readCString(); uint32_t sampleRate; int numChannels; audio_format_t format; sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format); reply->writeInt32(sampleRate); reply->writeInt32(numChannels); reply->writeInt32((int32_t) format); reply->writeStrongBinder(player->asBinder()); return NO_ERROR; } break; case DECODE_FD: { CHECK_INTERFACE(IMediaPlayerService, data, reply); int fd = dup(data.readFileDescriptor()); int64_t offset = data.readInt64(); int64_t length = data.readInt64(); uint32_t sampleRate; int numChannels; audio_format_t format; sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format); reply->writeInt32(sampleRate); reply->writeInt32(numChannels); reply->writeInt32((int32_t) format); reply->writeStrongBinder(player->asBinder()); return NO_ERROR; } break; case CREATE_MEDIA_RECORDER: { CHECK_INTERFACE(IMediaPlayerService, data, reply); pid_t pid = data.readInt32(); sp<IMediaRecorder> recorder = createMediaRecorder(pid); reply->writeStrongBinder(recorder->asBinder()); return NO_ERROR; } break; case CREATE_METADATA_RETRIEVER: { CHECK_INTERFACE(IMediaPlayerService, data, reply); pid_t pid = data.readInt32(); sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid); reply->writeStrongBinder(retriever->asBinder()); return NO_ERROR; } break; case GET_OMX: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IOMX> omx = getOMX(); reply->writeStrongBinder(omx->asBinder()); return NO_ERROR; } break; case MAKE_CRYPTO: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<ICrypto> crypto = makeCrypto(); reply->writeStrongBinder(crypto->asBinder()); return NO_ERROR; } break; case ADD_BATTERY_DATA: { CHECK_INTERFACE(IMediaPlayerService, data, reply); uint32_t params = data.readInt32(); addBatteryData(params); return NO_ERROR; } break; case PULL_BATTERY_DATA: { CHECK_INTERFACE(IMediaPlayerService, data, reply); pullBatteryData(reply); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }當(dāng)發(fā)明是CREATE才真正調(diào)用了MediaPlayerService 中的create函數(shù)。在create函數(shù)中其實(shí)是創(chuàng)建了一個(gè)MediaPlayerService::Client的實(shí)例,也就是 說(shuō)MediaPlayerService會(huì)為每個(gè)client應(yīng)用過(guò)程創(chuàng)建一個(gè)響應(yīng)的MediaPlayerService::Client的實(shí)例,來(lái)供給辦事。
sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) { int32_t connId = android_atomic_inc(&mNextConnId); sp<Client> c = new Client( this, pid, connId, client, audioSessionId, IPCThreadState::self()->getCallingUid()); ALOGV("Create new client(%d) pid %d, uid %d, ", connId, pid, IPCThreadState::self()->getCallingUid()); wp<Client> w = c; { Mutex::Autolock lock(mLock); mClients.add(w); } return c; }
【5】如許mediaplayer.cpp就獲得了一個(gè)player的實(shí)例,對(duì)他來(lái)說(shuō)這個(gè)實(shí)例和本地的其他類的實(shí)例沒(méi)什么用法上的差別,殊不知其實(shí)這個(gè)實(shí)例是運(yùn)行在別的一個(gè)過(guò)程中。實(shí)現(xiàn)這種假象的就是binder機(jī)制。獲得這個(gè)實(shí)例后持續(xù)player->setDataSource().在MediaPlayerService的過(guò)程中他的實(shí)際函數(shù)中,才會(huì)真正的創(chuàng)建Stagefright的具體實(shí)例。
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) { ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); struct stat sb; int ret = fstat(fd, &sb); if (ret != 0) { ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); return UNKNOWN_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("offset error"); ::close(fd); return UNKNOWN_ERROR; } if (offset + length > sb.st_size) { length = sb.st_size - offset; ALOGV("calculated length = %lld", length); } // Until re-transmit functionality is added to the existing core android // players, we use the special AAH TX player whenever we were configured for // retransmission. player_type playerType = getPlayerType(fd, offset, length); sp<MediaPlayerBase> p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; } // now set data source setDataSource_post(p, p->setDataSource(fd, offset, length)); return mStatus; }
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre( player_type playerType) { ALOGV("player type = %d", playerType); // create the right type of player sp<MediaPlayerBase> p = createPlayer(playerType); if (p == NULL) { return p; } if (!p->hardwareOutput()) { mAudioOutput = new AudioOutput(mAudioSessionId); static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); } return p; }
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) { // determine if we have the right player type sp<MediaPlayerBase> p = mPlayer; if ((p != NULL) && (p->playerType() != playerType)) { ALOGV(" player"); p.clear(); } if (p == NULL) { p = android::createPlayer(playerType, this, notify); } if (p != NULL) { p->setUID(mUID); } return p; }
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, notify_callback_f notifyFunc) { sp<MediaPlayerBase> p; switch (playerType) { case SONIVOX_PLAYER: ALOGV(" create MidiFile"); p = new MidiFile(); break; case STAGEFRIGHT_PLAYER: ALOGV(" create StagefrightPlayer"); p = new StagefrightPlayer; break; case NU_PLAYER: ALOGV(" create NuPlayer"); p = new NuPlayerDriver; break; case TEST_PLAYER: ALOGV("Create Test Player stub"); p = new TestPlayerStub(); break; case AAH_RX_PLAYER: ALOGV(" create A@H RX Player"); p = createAAH_RXPlayer(); break; case AAH_TX_PLAYER: ALOGV(" create A@H TX Player"); p = createAAH_TXPlayer(); break; default: ALOGE("Unknown player type: %d", playerType); return NULL; } if (p != NULL) { if (p->initCheck() == NO_ERROR) { p->setNotifyCallback(cookie, notifyFunc); } else { p.clear(); } } if (p == NULL) { ALOGE("Failed to create player object"); } return p; }
在上方中已經(jīng)看不到opencore的影子了,creaPlayer 中會(huì)按照類型來(lái)創(chuàng)建播放器的實(shí)例。Stagefright的實(shí)例就是在這里創(chuàng)建的。
下一步我們能真正進(jìn)入到Stagefright里了