The core principle of Android MediaPlayer

In this paper, is a very important Android is also the most complex media player (MediaPlayer) part of the structure. For a complete Android and relatively complex system, a function of the realization of MediaPlayer is not their specific function, but the specific function of the system adapting to Android Android MediaPlayer concrete realization of the main OpenCore the Player, this part is not a concern of this article. This concern is MediaPlayer system architecture, a number of other Android applications also use a similar structure.

For the open source enterprise in China, hanchao3c that should be shared not just code, documentation, design, concept or understanding of the technology should be widely shared. Android for the Chinese to enter the large-scale open source projects provide a good opportunity for people to go forward in technology, technology should not be treated as private property, but should devote themselves to the public to better understand and improve the public learning speed, which is also a feedback, thereby contributing to their progress. Only article dedicated to the relationship between technology, all friends, hope to initiate the promotion of our mutual technological progress!

The first part of the MediaPlayer Overview
Android's MediaPlayer include Audio and video playback capabilities, the interface in Android, Music and Video are two applications called MediaPlayer achieve.

MediaPlayer at the bottom is based on the OpenCore (PacketVideo) library to achieve, to build a MediaPlayer program, the upper also includes inter-process communication and other content, such inter-process communication is based on the basic library Android Binder mechanism.

The Android open source code example MediaPlayer mainly in the following directory:
JAVA program path: packages / apps / Music / src / com / android / music /
JAVA class path: frameworks / base / media / java / android / media /

JAVA local access to some (JNI): frameworks / base / media / jni / android_media_MediaPlayer.cpp
This part of the goal is to build a

The main header file in the following directory: frameworks / base / include / media /

Multimedia underlying database in the following directory: frameworks / base / media / libmedia /
This part of the content is compiled into a library

Multimedia services section: frameworks / base / media / libmediaplayerservice /
Documents mediaplayerservice.h and mediaplayerservice.cpp
This section is compiled into a library

OpenCore multimedia player based on some external / opencore /
This section is compiled into a library

From a procedural point of view the size, is the main part of implementation, while other libraries are basically the establishment of its packaging and for the establishment of inter-process communication mechanism.

The second part of the MediaPlayer interface and architecture

The overall framework of Figure 2.1

MediaPlayer structure between the various library complex, can be expressed under the map

The core principle of Android MediaPlayer

MediaPlayer structure between the various libraries

In each library, at the core position, provided the upper interface, it is mainly MediaPlayer Class , class by calling the MediaPlayer class provides JAVA interface, and achieve a class. is the Media server, it is achieved through inheritance class server functionality, while the other part of through the inter-process communication and to communicate. the real function to be completed by calling OpenCore Player.

MediaPlayer part of the header files in the frameworks / base / include / media / directory, this directory is and library source files directory frameworks / base / media / libmedia / corresponding. The first major document in the following:

In these header files mediaplayer.h provides upper interface, while the other are several header files to provide interface classes (which contains the pure virtual function of class), these interfaces inherited class must be able to use the implementation class.
MediaPlayer library and call the whole relationship as shown below:

The core principle of Android MediaPlayer

MediaPlayer library and calls the relationship between

MediaPlayer is running the whole time, Client and Server can be generally divided into two parts, which were run in two processes, among them the use Binder to achieve IPC communication mechanism. Point of view from the frame structure, IMediaPlayerService.h, IMediaPlayerClient.h and MediaPlayer.h defines three classes MeidaPlayer interface and framework, MediaPlayerService.cpp and mediaplayer.coo two files for MeidaPlayer framework to achieve, MeidaPlayer specific function PVPlayer (Library in the implementation.

2.2 File IMediaPlayerClient.h
IMediaPlayerClient.h MediaPlayer is used to describe a client interface, described as follows:
class IMediaPlayerClient: public IInterface
virtual void notify (int msg, int ext1, int ext2) = 0;

class BnMediaPlayerClient: public BnInterface
virtual status_t onTransact (uint32_t code,
const Parcel & data,
Parcel * reply,
uint32_t flags = 0);
In the definition, IMediaPlayerClient class inheritance IInterface, and defines a client interface MediaPlayer, BnMediaPlayerClient inherited BnInterface, which is the basis of class-based Android Binder mechanism to achieve communication and constructed in the process. In fact, according BnInterface class template definition is equivalent to double BnInterface class inherits BnInterface and ImediaPlayerClient. This is the Android way of a common definition.

2.3 File mediaplayer.h
mediaplayer.h is the external interface class, which is mainly defined a MediaPlayer class:
class MediaPlayer: public BnMediaPlayerClient
MediaPlayer ();
~ MediaPlayer ();
void onFirstRef ();
void disconnect ();
status_t setDataSource (const char * url);
status_t setDataSource (int fd, int64_t offset, int64_t length);
status_t setVideoSurface (const sp & surface);
status_t setListener (const sp & listener);
status_t prepare ();
status_t prepareAsync ();
status_t start ();
status_t stop ();
status_t pause ();
bool isPlaying ();
status_t getVideoWidth (int * w);
status_t getVideoHeight (int * h);
status_t seekTo (int msec);
status_t getCurrentPosition (int * msec);
status_t getDuration (int * msec);
status_t reset ();
status_t setAudioStreamType (int type);
status_t setLooping (int loop);
status_t setVolume (float leftVolume, float rightVolume);
void notify (int msg, int ext1, int ext2);
static sp decode (const char * url, uint32_t * pSampleRate, int * pNumChannels);
static sp decode (int fd, int64_t offset, int64_t length, uint32_t * pSampleRate, int * pNumChannels);
/ / ... ...
As can be seen from the interface MediaPlayer MediaPlayer class just implements a basic operations such as Play (start), stop (stop), pause (pause) and so on.
Another class DeathNotifier in MediaPlayer class definition, it inherits IBinder class DeathRecipient categories:
class DeathNotifier: public IBinder:: DeathRecipient
DeathNotifier () ()
virtual ~ DeathNotifier ();
virtual void binderDied (const wp & who);
In fact, MediaPlayer class is indirectly inherited IBinder, while the MediaPlayer:: DeathNotifier class inherits IBinder:: DeathRecipient, this is to achieve inter-process communications and built.

2.4 file IMediaPlayer.h
IMediaPlayer.h the content is a key feature to achieve MediaPlayer interface, its main definitions are as follows:
class IMediaPlayer: public IInterface
virtual void disconnect () = 0;
virtual status_t setVideoSurface (const sp & surface) = 0;
virtual status_t prepareAsync () = 0;
virtual status_t start () = 0;
virtual status_t stop () = 0;
virtual status_t pause () = 0;
virtual status_t isPlaying (bool * state) = 0;
virtual status_t getVideoSize (int * w, int * h) = 0;
virtual status_t seekTo (int msec) = 0;
virtual status_t getCurrentPosition (int * msec) = 0;
virtual status_t getDuration (int * msec) = 0;
virtual status_t reset () = 0;
virtual status_t setAudioStreamType (int type) = 0;
virtual status_t setLooping (int loop) = 0;
virtual status_t setVolume (float leftVolume, float rightVolume) = 0;
class BnMediaPlayer: public BnInterface
virtual status_t onTransact (uint32_t code,
const Parcel & data,
Parcel * reply,
uint32_t flags = 0);
In IMediaPlayer class, the main function of the definition of MediaPlayer interface, this class must be inherited can use. It is noteworthy that these interfaces and the MediaPlayer class interface somewhat similar, but they are not directly related. In fact, the various implementations MediaPlayer class, usually by calling IMediaPlayer class implementation class to complete.

2.5 File IMediaPlayerService.h
IMediaPlayerService.h MediaPlayer used to describe a service means the definition as follows:
class IMediaPlayerService: public IInterface
virtual sp create (pid_t pid, const sp & client, const char * url) = 0;
virtual sp create (pid_t pid, const sp & client, int fd, int64_t offset, int64_t length) = 0;
virtual sp decode (const char * url, uint32_t * pSampleRate, int * pNumChannels) = 0;
virtual sp decode (int fd, int64_t offset, int64_t length, uint32_t * pSampleRate, int * pNumChannels) = 0;
class BnMediaPlayerService: public BnInterface
virtual status_t onTransact (uint32_t code,
const Parcel & data,
Parcel * reply,
uint32_t flags = 0);

As a pure virtual function, IMediaPlayerService and BnMediaPlayerService must be able to use inheritance to achieve, as defined in IMediaPlayerService create and decode the interface is in fact to be successor to achieve. Note that, create the return value type is sp, the IMediaPlayer is to provide the interface to achieve functionality.

The third part of the MediaPlayer the main part of the implementation of 3.1 JAVA program

In packages / apps / Music / src / com / android / music / directory file contains a call to MediaPlayer.
In contains a reference to the package:
Within the class in MediaPlaybackService defined MultiPlayer categories:
private class MultiPlayer (
private MediaPlayer mMediaPlayer = new MediaPlayer ();

MultiPlayer class using MediaPlayer class, some of which call on the MediaPlayer, call the procedure as follows:
mMediaPlayer.reset ();
mMediaPlayer.setDataSource (path);
mMediaPlayer.setAudioStreamType (AudioManager.STREAM_MUSIC);
reset, setDataSource and setAudioStreamType the interface that is called by the local JAVA (JNI) to achieve.

JAVA 3.2 MediaPlayer for some local calls
MediaPlayer in JAVA some local calls in the directory frameworks / base / media / jni /'s android_media_MediaPlayer.cpp achieved in the paper.
android_media_MediaPlayer.cpp being defined a JNINativeMethod (JAVA local call method) type array gMethods, as follows:
static JNINativeMethod gMethods [] = (

("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 the first member is a string that the JAVA local calling method name, this name is invoked in the name of the JAVA program; second member is a string that JAVA local call method arguments and return values; The third member is a local call JAVA C language functions corresponding to the method.
One android_media_MediaPlayer_reset function is implemented as follows:
static void android_media_MediaPlayer_reset (JNIEnv * env, jobject thiz)
sp mp = getMediaPlayer (env, thiz);
if (mp == NULL) (
jniThrowException (env, "java / lang / IllegalStateException", NULL);
process_media_player_call (env, thiz, mp-> reset (), NULL, NULL);
In android_media_MediaPlayer_reset the call, get a MediaPlayer pointer, by its call to implement the actual functionality.
register_android_media_MediaPlayer used to gMethods registered as a Class "android / media / MediaPlayer", its realization as follows.
static int register_android_media_MediaPlayer (JNIEnv * env)
jclass clazz;
clazz = env-> FindClass ("android / media / MediaPlayer");
/ / ......
return AndroidRuntime:: registerNativeMethods (env, "android / media / MediaPlayer", gMethods, NELEM (gMethods));

"Android / media / MediaPlayer" corresponding JAVA class

3.3 mediaplayer core library
libs / media / mediaplayer.cpp files provide the interface for achieve mediaplayer.h, one of the important fragment of the following:
const sp & MediaPlayer:: getMediaPlayerService ()
Mutex:: Autolock _l (mServiceLock);
if (mMediaPlayerService.get () == 0) (
sp sm = defaultServiceManager ();
sp binder;
do (
binder = sm-> getService (String16 ("media.player"));
if (binder! = 0)
LOGW ("MediaPlayerService not published, waiting ...");
usleep (500000); / / 0.5 s
) While (true);
if (mDeathNotifier == NULL) (
mDeathNotifier = new DeathNotifier ();
binder-> linkToDeath (mDeathNotifier);
mMediaPlayerService = interface_cast (binder);
LOGE_IF (mMediaPlayerService == 0, "no MediaPlayerService !?");
return mMediaPlayerService;
One of the most important point is that binder = sm-> getService (String16 ("media.player")); this call to get a name for the "media.player" service, this call returns the value of the type IBinder, according to realize convert it into a type IMediaPlayerService use.
SetDataSource a specific function as follows:
status_t MediaPlayer:: setDataSource (const char * url)
LOGV ("setDataSource (% s)", url);
status_t err = UNKNOWN_ERROR;
if (url! = NULL) (
const sp & service (getMediaPlayerService ());
if (service! = 0) (
sp player (service-> create (getpid (), this, url));
err = setDataSource (player);
return err;
SetDataSource function in the function, called getMediaPlayerService get a IMediaPlayerService, and from IMediaPlayerService been a IMediaPlayer type pointer, through this pointer to a specific operation.
The realization of some other function setDataSource also similar. some of the other documents with the header files of the same name, they are:
libs / media / IMediaPlayerClient.cpp
libs / media / IMediaPlayer.cpp
libs / media / IMediaPlayerService.cpp
Binder in order to achieve specific functions in these classes need to implement a BpXXX class, such as IMediaPlayerClient.cpp is implemented as follows: l
class BpMediaPlayerClient: public BpInterface
BpMediaPlayerClient (const sp & impl)
: BpInterface (impl) ()
virtual void notify (int msg, int ext1, int ext2)
Parcel data, reply;
data.writeInterfaceToken (IMediaPlayerClient:: getInterfaceDescriptor ());
data.writeInt32 (msg);
data.writeInt32 (ext1);
data.writeInt32 (ext2);
remote () -> transact (NOTIFY, data, & reply, IBinder:: FLAG_ONEWAY);
Also need to realize the definition of macro IMPLEMENT_META_INTERFACE, this macro will be launched, generating several functions:
IMPLEMENT_META_INTERFACE (MediaPlayerClient, "android.hardware.IMediaPlayerClient");
The realization of the above are based on Binder framework for implementation, only in accordance with the template can be achieved. One BpXXX class for the proxy class (proxy), BnXXX class for the local class (native). Agent class transact functions and local functions to achieve the corresponding class onTransact communications.

3.4 media services
frameworks / base / media \ libmediaplayerservice directory MediaPlayerService.h and MediaPlayerService.cpp used to achieve an
servers / media / services, MediaPlayerService inherited BnMediaPlayerService implementation, in this class is defined inside another class Client, MediaPlayerService:: Client inherited BnMediaPlayer.
class MediaPlayerService: public BnMediaPlayerService
class Client: public BnMediaPlayer
In MediaPlayerService in a static function with the following instantiate:
void MediaPlayerService:: instantiate () (
defaultServiceManager () -> addService (
String16 ("media.player"), new MediaPlayerService ());
In the instantiate function, a function call IServiceManager addService, to which the addition of a known "media.player" service.
Entitled "media.player" service and call the getService mediaplayer.cpp obtained using the same name. So, here called addService mediaplayer.cpp can increase the service by name "media.player" to use. Binder to achieve this is to use inter-process communication (IPC) role, a matter of fact this MediaPlayerService run in the service category, while the function call mediaplayer.cpp applications running in the two is not a process. However, in a process called mediaplayer.cpp are like the same function call MediaPlayerService.
The createPlayer function in MediaPlayerService.cpp as follows:
static sp createPlayer (player_type playerType, void * cookie,
notify_callback_f notifyFunc)
sp p;
switch (playerType) (
LOGV ("create PVPlayer");
p = new PVPlayer ();
LOGV ("create MidiFile");
p = new MidiFile ();
LOGV ("create VorbisPlayer");
p = new VorbisPlayer ();
/ / ... ...
return p;
The type here under playerType create different players: for most cases, the type will be PV_PLAYER, then will call the new PVPlayer () to establish a PVPlayer, and then to use the pointer into MediaPlayerBase; the case file for Mini , type SONIVOX_PLAYER, will create a MidiFile; Ogg Vorbis format for the situation, will establish a VorbisPlayer.
(OGG Vobis is an audio compression format, and MP3 and other music format is similar, it is completely free, open and without the characteristics of patent restrictions.)
It is worth noting PVPlayer, MidiFile and VorbisPlayer inherited MediaPlayerInterface three classes are obtained, which is inherited MediaPlayerBase MediaPlayerInterface get, so all three have the same interface type. Only by establishing their own when the constructor is called, in the established, will only be through MediaPlayerBase interface MediaPlayerBase control them.
In the frameworks / base / media / libmediaplayerservice directory, MidiFile.h and MidiFile.cpp realization MidiFile, VorbisPlayer.h and VorbisPlayer.cpp implement a VorbisPlayer.

3.5 OpenCorePlayer realization
OpenCore Player in the external / opencore / implement, this realization is a realization based on OpenCore of the Player. Realization of the document playerdriver.cpp. Which implements two classes: PlayerDriver and PVPlayer. PVPlayer PlayerDriver by calling the function to achieve specific functions.

分类:Mobile 时间:2010-06-25 人气:637
blog comments powered by Disqus


iOS 开发

Android 开发

Python 开发



PHP 开发

Ruby 开发






Javascript 开发

.NET 开发



Copyright (C), All Rights Reserved. 版权所有 闽ICP备15018612号

processed in 0.040 (s). 13 q(s)