基于android 4.1.1 源码
【1】mediaserver 启动后会把media相关一些服务添加到servicemanager中,其中就有mediaPlayerService.这样应用启动前,系统就有了mediaPlayerService这个服务程序。
- 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】应用层 mediaPlayer=new MediaPlayer(); 调用SDK中 MediaPlayer.java (frameworks\base\media\java\android\media\MediaPlayer.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));
- }
通过JNI方式调用到framework层 android_media_MediaPlayer.cpp(\frameworks\base\media\jni\android_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);
- }
继而调用mediaplayer.cpp(frameworks\av\media\libmedia\mediaplayer.cpp)
【3】在整个应用程序的进程中,mediaplayer.cpp 中 setDataSource会从service manager中获得mediaPlayerService 服务,然后通过服务来创建player。这个player就是播放器的真实实例。
- 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;
- }
- 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());
- }
在对面的 BnMediaPlayerService中,通过onTransact()来接受这些消息。并把结果返回。
- 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 MAKE_CRYPTO:
- }
- 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) from 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 就得到了一个player的实例,对他来说这个实例和本地的其他类的实例没什么用法上的区别,殊不知其实这个实例是运行在另外一个进程中。实现这种假象的就是binder机制。获得这个实例后继续player->setDataSource().在 MediaPlayerService的进程中他的实际函数中,才会真正的创建Stagefright的具体实例。
- 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("delete 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;
- }
在上面中已经看不到opencore的影子了,creaPlayer 中会根据类型来创建播放器的实例。Stagefright的实例就是在这里创建的。
下一步我们能真正进入到Stagefright里了