Android平台下多媒体设计.docx

上传人:b****6 文档编号:6423583 上传时间:2023-01-06 格式:DOCX 页数:36 大小:1.06MB
下载 相关 举报
Android平台下多媒体设计.docx_第1页
第1页 / 共36页
Android平台下多媒体设计.docx_第2页
第2页 / 共36页
Android平台下多媒体设计.docx_第3页
第3页 / 共36页
Android平台下多媒体设计.docx_第4页
第4页 / 共36页
Android平台下多媒体设计.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

Android平台下多媒体设计.docx

《Android平台下多媒体设计.docx》由会员分享,可在线阅读,更多相关《Android平台下多媒体设计.docx(36页珍藏版)》请在冰豆网上搜索。

Android平台下多媒体设计.docx

Android平台下多媒体设计

智能平台开发部

Android平台多媒体设计

版本号

V0.1

修订内容

修订日期

拟制

文件性质

密级

审核

文件编号

批准

生效日期

发放号

修改记录

1>V0.1

完成时间:

2009-7-8

修改人:

修改内容:

初始版本

11、编写目的

本文档描述在Android平台中多媒体的框架设计。

在Android中,多媒体部分包括MediaPlayerr应用、mediarecorder应用(videorecorder/voicerecorder),imagecenter(imagecapture/view)、opencore等。

此文档仅仅包含MediaPlayer与opencore的架构。

12、编写背景

总结前段时间的学习,为后续工作开展打下基础

13、参考资料

N/A

14、Android总体架构图

15、Android多媒体的架构

5.1、多媒体架构概览

多媒体应用基于Android的多媒体架构。

MediaPlayer包含了Audio和Video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的。

MediaPlayer在底层是基于Opencore(PacketVideo)的库实现的,为了构建一个MediaPlayer程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制。

5.2、多媒体总体架构图

5.3、MediaPlayer的各个库之间的结构如下图的表示:

在各个库中,libmedia.so与libmediaplayerservice.so位于核心的位置。

libmedia.so对上层的提供的接口主要是MediaPlayer类,类libmedia_jni.so通过调用MediaPlayer类提供对JAVA的接口,并且实现了android.media.MediaPlayer类。

libmediaplayerservice.so是Media的服务器,它通过继承libmedia.so的类实现服务器的功能,而libmedia.so中的另外一部分内容则通过进程间通讯和libmediaplayerservice.so进行通讯。

libmediaplayerservice.so的真正功能通过调用OpenCorePlayer(库libopencoreplayer.so)来完成。

5.4、整个MediaPlayer库和调用的关系图

从框架结构上来看,IMediaPlayerService.h、IMediaPlayerClient.h和MediaPlayer.h三个类定义了MeidaPlayer的接口和架构,MediaPlayerService.cpp和mediaplayer.coo两个文件用于MeidaPlayer架构的实现,MeidaPlayer的具体功能在PVPlayer(库libopencoreplayer.so)中的实现。

6、应用层架构分析

6.1、JAVA程序部分

在packages/apps/Music/src/com/android/music/目录的MediaPlaybackService.java文件中,包含了对MediaPlayer的调用。

在MediaPlaybackService.java中包含对包的引用:

importandroid.media.MediaPlayer;

在MediaPlaybackService类的内部,定义了MultiPlayer类:

privateclassMultiPlayer{

privateMediaPlayermMediaPlayer=newMediaPlayer();

}

MultiPlayer类中使用了MediaPlayer类,其中有一些对这个MediaPlayer的调用,调用的过程如下所示:

mMediaPlayer.reset();

mMediaPlayer.setDataSource(path);

mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

reset、setDataSource和setAudioStreamType等接口就是通过JAVA本地调用(JNI)来实现的。

6.2、MediaPlayer的JAVA本地调用部分

MediaPlayer的JAVA本地调用部分在目录frameworks/base/media/jni/的android_media_MediaPlayer.cpp中的文件中实现。

android_media_MediaPlayer.cpp之中定义了一个JNINativeMethod(JAVA本地调用方法)类型的数组gMethods,如下所示:

staticJNINativeMethodgMethods[]={

{"setDataSource","(Ljava/lang/String;)V",(void*)android_media_MediaPlayer_setDataSource},

{"setDataSource","(Ljava/io/FileDescriptor;JJ)V",(void*)android_media_MediaPlayer_setDataSourceFD},

{"prepare","()V",(void*)android_media_MediaPlayer_prepare},

{"prepareAsync","()V",(void*)android_media_MediaPlayer_prepareAsync},

{"_start","()V",(void*)android_media_MediaPlayer_start},

{"_stop","()V",(void*)android_media_MediaPlayer_stop},

{"getVideoWidth","()I",(void*)android_media_MediaPlayer_getVideoWidth},

{"getVideoHeight","()I",(void*)android_media_MediaPlayer_getVideoHeight},

{"seekTo","(I)V",(void*)android_media_MediaPlayer_seekTo},

{"_pause","()V",(void*)android_media_MediaPlayer_pause},

{"isPlaying","()Z",(void*)android_media_MediaPlayer_isPlaying},

{"getCurrentPosition","()I",(void*)android_media_MediaPlayer_getCurrentPosition},

{"getDuration","()I",(void*)android_media_MediaPlayer_getDuration},

{"_release","()V",(void*)android_media_MediaPlayer_release},

{"_reset","()V",(void*)android_media_MediaPlayer_reset},

{"setAudioStreamType","(I)V",(void*)android_media_MediaPlayer_setAudioStreamType},

{"setLooping","(Z)V",(void*)android_media_MediaPlayer_setLooping},

{"setVolume","(FF)V",(void*)android_media_MediaPlayer_setVolume},

{"getFrameAt","(I)Landroid/graphics/Bitmap;",(void*)android_media_MediaPlayer_getFrameAt},

{"native_setup","(Ljava/lang/Object;)V",(void*)android_media_MediaPlayer_native_setup},

{"native_finalize","()V",(void*)android_media_MediaPlayer_native_finalize},

JNINativeMethod的第一个成员是一个字符串,表示了JAVA本地调用方法的名称,这个名称是在JAVA程序中调用的名称;第二个成员也是一个字符串,表示JAVA本地调用方法的参数和返回值;第三个成员是JAVA本地调用方法对应的C语言函数。

其中android_media_MediaPlayer_reset函数的实现如下所示:

staticvoid

android_media_MediaPlayer_reset(JNIEnv*env,jobjectthiz)

{

spmp=getMediaPlayer(env,thiz);

if(mp==NULL){

jniThrowException(env,"java/lang/IllegalStateException",NULL);

return;

}

process_media_player_call(env,thiz,mp->reset(),NULL,NULL);

}

在android_media_MediaPlayer_reset的调用中,得到一个MediaPlayer指针,通过对它的调用实现实际的功能。

register_android_media_MediaPlayer用于将gMethods注册为的类"android/media/MediaPlayer",其实现如下所示。

staticintregister_android_media_MediaPlayer(JNIEnv*env)

{

jclassclazz;

clazz=env->FindClass("android/media/MediaPlayer");

//......

returnAndroidRuntime:

:

registerNativeMethods(env,"android/media/MediaPlayer",gMethods,NELEM(gMethods));

}

"android/media/MediaPlayer"对应JAVA的类android.media.MediaPlayer

6.3、mediaplayer本地库libmedia.so

libs/media/mediaplayer.cpp文件用于实现mediaplayer.h提供的接口,其中一个重要的片段如下所示:

constsp&MediaPlayer:

:

getMediaPlayerService()

{

Mutex:

:

Autolock_l(mServiceLock);

if(mMediaPlayerService.get()==0){

spsm=defaultServiceManager();

spbinder;

do{

binder=sm->getService(String16("media.player"));

if(binder!

=0)

break;

LOGW("MediaPlayerServicenotpublished,waiting...");

usleep(500000);//0.5s

}while(true);

if(mDeathNotifier==NULL){

mDeathNotifier=newDeathNotifier();

}

binder->linkToDeath(mDeathNotifier);

mMediaPlayerService=interface_cast(binder);

}

LOGE_IF(mMediaPlayerService==0,"noMediaPlayerService!

?

");

returnmMediaPlayerService;

}

其中最重要的一点是binder=sm->getService(String16("media.player"));这个调用用来得到一个名称为"media.player"的服务,这个调用返回值的类型为IBinder,根据实现将其转换成类型IMediaPlayerService使用。

一个具体的函数setDataSource如下所示:

status_tMediaPlayer:

:

setDataSource(constchar*url)

{

LOGV("setDataSource(%s)",url);

status_terr=UNKNOWN_ERROR;

if(url!

=NULL){

constsp&service(getMediaPlayerService());

if(service!

=0){

spplayer(service->create(getpid(),this,url));

err=setDataSource(player);

}

}

returnerr;

}

在函数setDataSource函数中,调用getMediaPlayerService得到了一个IMediaPlayerService,又从IMediaPlayerService中得到了IMediaPlayer类型的指针,通过这个指针进行着具体的操作。

其他一些函数的实现也与setDataSource类似。

libmedia.so中的其他一些文件与头文件的名称相同,它们是:

libs/media/IMediaPlayerClient.cpp

libs/media/IMediaPlayer.cpp

libs/media/IMediaPlayerService.cpp

为了实现Binder的具体功能,在这些类中还需要实现一个BpXXX的类,例如IMediaPlayerClient.cpp的实现如下所示:

l

classBpMediaPlayerClient:

publicBpInterface

{

public:

BpMediaPlayerClient(constsp&impl)

:

BpInterface(impl)

{

}

virtualvoidnotify(intmsg,intext1,intext2)

{

Parceldata,reply;

data.writeInterfaceToken(IMediaPlayerClient:

:

getInterfaceDescriptor());

data.writeInt32(msg);

data.writeInt32(ext1);

data.writeInt32(ext2);

remote()->transact(NOTIFY,data,&reply,IBinder:

:

FLAG_ONEWAY);

}

};

还需要实现定义宏IMPLEMENT_META_INTERFACE,这个宏将被展开,生成几个函数:

IMPLEMENT_META_INTERFACE(MediaPlayerClient,"android.hardware.IMediaPlayerClient");

以上的实现都是基于Binder框架的实现方式,只需要按照模版实现即可。

其中BpXXX的类为代理类(proxy),BnXXX的类为本地类(native)。

代理类的transact函数和本地类的onTransact函数实现对应的通讯。

6.4、media服务libmediaservice.so

frameworks/base/media\libmediaplayerservice目录中的MediaPlayerService.h和MediaPlayerService.cpp用于实现一个

servers/media/的服务,MediaPlayerService是继承BnMediaPlayerService的实现,在这个类的内部又定义了类Client,MediaPlayerService:

:

Client继承了BnMediaPlayer。

classMediaPlayerService:

publicBnMediaPlayerService

{

classClient:

publicBnMediaPlayer

}

在MediaPlayerService中具有如下一个静态函数instantiate:

voidMediaPlayerService:

:

instantiate(){

defaultServiceManager()->addService(

String16("media.player"),newMediaPlayerService());

}

在instantiate函数中,调用IServiceManager的一个函数addService,向其中增加了一个名为"media.player"的服务。

这个名为"media.player"的服务和mediaplayer.cpp中调用getService中得到的使用一样名称。

因此,在这里调用addService增加服务在mediaplayer.cpp中可以按照名称"media.player"来使用。

这就是使用Binder实现进程间通讯的(IPC)的作用,事实上这个MediaPlayerService类是在服务中运行的,而mediaplayer.cpp调用的功能在应用中运行,二者并不是一个进程。

但是在mediaplayer.cpp却像一个进程的调用一样调用MediaPlayerService的功能。

在MediaPlayerService.cpp中的createPlayer函数如下所示:

staticspcreatePlayer(player_typeplayerType,void*cookie,

notify_callback_fnotifyFunc)

{

spp;

switch(playerType){

casePV_PLAYER:

LOGV("createPVPlayer");

p=newPVPlayer();

break;

caseSONIVOX_PLAYER:

LOGV("createMidiFile");

p=newMidiFile();

break;

caseVORBIS_PLAYER:

LOGV("createVorbisPlayer");

p=newVorbisPlayer();

break;

}

//……

returnp;

}

在这里根据playerType的类型建立不同的播放器:

对于大多数情况,类型将是PV_PLAYER,这时会调用了newPVPlayer()建立一个PVPlayer,然后将其指针转换成MediaPlayerBase来使用;对于Mini文件的情况,类型为SONIVOX_PLAYER,将会建立一个MidiFile;对于OggVorbis格式的情况,将会建立一个VorbisPlayer。

值得注意的是PVPlayer、MidiFile和VorbisPlayer三个类都是继承MediaPlayerInterface得到的,而MediaPlayerInterface又是继承MediaPlayerBase得到的,因此三者具有相同接口类型。

只有建立的时候会调用各自的构造函数,在建立之后,将只通过MediaPlayerBase接口来MediaPlayerBase控制它们。

在frameworks/base/media/libmediaplayerservice目录中,MidiFile.h和MidiFile.cpp的实现

MidiFile,VorbisPlayer.h和VorbisPlayer.cpp实现一个VorbisPlayer

6.5、头文件IMediaPlayerClient.h

IMediaPlayerClient.h用于描述一个MediaPlayer客户端的接口,描述如下所示:

classIMediaPlayerClient:

publicIInterface

{

public:

DECLARE_META_INTERFACE(MediaPlayerClient);

virtualvoidnotify(intmsg,intext1,intext2)=0;

};

classBnMediaPlayerClient:

publicBnInterface

{

public:

virtualstatus_tonTransact(uint32_tcode,

constParcel&data,

Parcel*reply,

uint32_tflags=0);

};

在定义中,IMediaPlayerClient类继承IInterface,并定义了一个MediaPlayer客户端的接口,BnMediaPlayerClient继承了BnInterface,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。

事实上,根据BnInterface类模版的定义BnInterface类相当于双继承了BnInterface和ImediaPlayerClient。

这是Android一种常用的定义方式

6.6、头文件mediaplayer.h

mediaplayer.h是对外的接口类,它最主要是定义了一个MediaPlayer类:

classMediaPlayer:

publicBnMediaPlayerClient

{

public:

MediaPlayer();

~MediaPlayer();

voidonFirstRef()

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1