您的位置:首页 > 移动开发 > Android开发

Android多媒体开发【4】-- 上层mediaPlayer 是如何调到Stagefright的【2】【图解】

2014-06-23 10:19 351 查看
http://blog.csdn.net/tx3344/article/details/8024489

基于android 4.1.1 源码



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

[java] view
plaincopy

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();

}

[cpp] view
plaincopy

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)

[java] view
plaincopy

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)

[cpp] view
plaincopy

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就是播放器的真实实例。

[cpp] view
plaincopy

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】通过 getMediaPlayerService 得到的service其实是 BpMediaPlayerService,这是和mediaPlayerService进程中的BnMediaPlayerService
相对应负责binder通讯。BpMediaPlayerService中的create其实通过binder机制将CREATE消息发送出去。

[cpp] view
plaincopy

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()来接受这些消息。并把结果返回。

[cpp] view
plaincopy

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:

}

当发现是CREATE才真正调用了MediaPlayerService 中的create函数。在create函数中其实是创建了一个MediaPlayerService::Client的实例,也就是 说MediaPlayerService会为每个client应用进程创建一个相应的MediaPlayerService::Client的实例,来提供服务。

[cpp] view
plaincopy

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的具体实例。

[cpp] view
plaincopy

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;

}

[cpp] view
plaincopy

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;

}

[cpp] view
plaincopy

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;

}

[cpp] view
plaincopy

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里了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: