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 / MediaPlayer.java

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

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 libmedia.so.

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

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

From a procedural point of view the size, libopencoreplayer.so 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, libmedia.so at the core position, provided the upper interface, it is mainly MediaPlayer Class , class libmedia_jni.so by calling the MediaPlayer class provides JAVA interface, and achieve a android.media.MediaPlayer class.
libmediaplayerservice.so is the Media server, it is achieved through inheritance libmedia.so class server functionality, while the other part of libmedia.so through the inter-process communication and libmediaplayerservice.so to communicate. libmediaplayerservice.so 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 libmedia.so library source files directory frameworks / base / media / libmedia / corresponding. The first major document in the following:
IMediaPlayerClient.h
mediaplayer.h
IMediaPlayer.h
IMediaPlayerService.h
MediaPlayerInterface.h

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:



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 libopencoreplayer.so) 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
(
public:
DECLARE_META_INTERFACE (MediaPlayerClient);
virtual void notify (int msg, int ext1, int ext2) = 0;
);

class BnMediaPlayerClient: public BnInterface
(
public:
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
(
public:
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
(
public:
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
(
public:
DECLARE_META_INTERFACE (MediaPlayer);
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
(
public:
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
(
public:
DECLARE_META_INTERFACE (MediaPlayerService);
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
(
public:
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 MediaPlaybackService.java file contains a call to MediaPlayer.
In MediaPlaybackService.java contains a reference to the package:
import android.media.MediaPlayer;
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);
return;
)
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 android.media.MediaPlayer.

3.3 mediaplayer core library libmedia.so
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)
break;
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.
libmedia.so 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
(
public:
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 libmediaservice.so
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) (
case PV_PLAYER:
LOGV ("create PVPlayer");
p = new PVPlayer ();
break;
case SONIVOX_PLAYER:
LOGV ("create MidiFile");
p = new MidiFile ();
break;
case VORBIS_PLAYER:
LOGV ("create VorbisPlayer");
p = new VorbisPlayer ();
break;
)
/ / ... ...
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 libopencoreplayer.so
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.
  • del.icio.us
  • StumbleUpon
  • Digg
  • TwitThis
  • Mixx
  • Technorati
  • Facebook
  • NewsVine
  • Reddit
  • Google
  • LinkedIn
  • YahooMyWeb

Related Posts of The core principle of Android MediaPlayer

  • Hibernate performance tuning (the focus of understanding)

    1. Object Cache: fine-grained, in view of the table Record Level, transparent access, without changing the procedure code can greatly enhance the performance of web applications. ORM object cache is a magic weapon for the victory. 2. The merits of th ...

  • jdbc even ORACLE, SQLServer2000, mysql ways

    According to other people say can make a ride to one of the clear step by step, not as easy to write your own ideas! 1. Even the oracle The direct use of the oracle are provided give a jar package jdbc: oracle alone is installed, and 10g of oracle on ...

  • Top-down design and bottom-up design

    The basic concept Abstract in the importance of software development is self-evident. If a system has the correct abstract, then the system is even more easy to understand and easier to maintain, develop them more efficient, the most important are also mo

  • Software Performance

    1.1 Software Performance In general, the performance is an indicator that the software system or component to its timeliness requirements in line with the level; followed by software performance, are an indicator can be used to measure time. Performa ...

  • lighttpd + fastcgi built a server how to preserve the status of server

    Requirements: server-side has much static files, there is much use of c + + to prepare the operational components necessary to carry out these functions on the external packaging Published Service, server-side state required to preserve the client (simila

  • log4j easy application in java

    JAVA development, frequently used the log output, in a so-called most of the software company will have its own set of configuration style, re-read the configuration file to initialize property of the log, it will be good, but sometimes may not need to fu

  • hibernate using c3p0 connection pooling

    Private http://www.lifevv.com/tenyo/doc/20070605102040991.html c3p0 for open source's JDBC connection pool, with the release hibernate. This article describes how to use the hibernate configuration in c3p0. c3p0 connection pool configuration is v ...

  • JAVA Class naming convention

    1. Entity Layer: Inheritance: All categories inherited from BasicEntity, one of BasicEntity implementation java.io.Serializable interface; Naming rules: Class Name = Object + type suffix, one of type suffix for Bean, such as: SalesOrderBean 2. Form l ...

  • spring + hibernate + oracle9i to read and write CLOB

    Database-driven update classes12-9i.jar Hibernate modify the configuration of the following code <bean/> <bean Lazy-init="true"> <property name="nativeJdbcExtractor"> <ref local="nativejdbcExtractor"/>

  • In the servlet use Bean

    According to Sun's definition, JavaBean is a reusable software components. In fact JavaBean is a Java class, through the package into a property and methods of treatment of a function or a business object, referred to as bean. Because JavaBean is ...

blog comments powered by Disqus
Recent
Recent Entries
Tag Cloud
Random Entries