日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android的MediaPlayer架構(gòu)介紹 - 狂徒的 - JavaEye技術(shù)網(wǎng)站

 ydyuhu 2010-01-29

Android的MediaPlayer架構(gòu)介紹

關(guān)鍵字: android的mediaplayer架構(gòu)介紹
轉(zhuǎn)載自hanchao3c Android開發(fā)者論壇原創(chuàng))
       本文由中國(guó)的Androidin社區(qū)的hanchao3c原創(chuàng),主要介紹的是Android中很重要也最為復(fù)雜的媒體播放器(MediaPlayer)部分的架構(gòu)。對(duì)于Android這樣一個(gè)完整又相對(duì)復(fù)雜的系統(tǒng),一個(gè)MediaPlayer功能的實(shí)現(xiàn)不在其具體的功能,而是具體功能如何適應(yīng)Android系統(tǒng)Android MediaPlayer的主要具體實(shí)現(xiàn)在OpenCore的Player中,這部分不是本文的關(guān)注點(diǎn)。本文關(guān)注的是MediaPlayer系統(tǒng)的架構(gòu),其他的一些Android的應(yīng)用程序也使用類似的架構(gòu)。

       對(duì)于開源事業(yè)在中國(guó)的發(fā)展,hanchao3c認(rèn)為應(yīng)該共享的不僅僅是代碼,文檔、設(shè)計(jì)思想、理念甚至對(duì)于技術(shù)的理解都應(yīng)該得到充分的共享。Android為中國(guó)人進(jìn)入大規(guī)模的開源項(xiàng)目提供了很好的機(jī)遇,對(duì)于走在技術(shù)前沿的人們,不應(yīng)將技術(shù)視為私有財(cái)產(chǎn),而應(yīng)該將自己理解更好地奉獻(xiàn)給大眾,提高大眾的學(xué)習(xí)速度,從中也可以得到反饋,從而促進(jìn)自己的進(jìn)步。僅以此文奉獻(xiàn)給所有關(guān)系技術(shù)的朋友,希望可以拋磚引玉,促進(jìn)我們共同的技術(shù)進(jìn)步!

第一部分 MediaPlayer概述

        Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video兩個(gè)應(yīng)用程序都是調(diào)用MediaPlayer實(shí)現(xiàn)的。

        MediaPlayer在底層是基于OpenCore(PacketVideo)的庫(kù)實(shí)現(xiàn)的,為了構(gòu)建一個(gè)MediaPlayer程序,上層還包含了進(jìn)程間通訊等內(nèi)容,這種進(jìn)程間通訊的基礎(chǔ)是Android基本庫(kù)中的Binder機(jī)制。

以開源的Android為例MediaPlayer的代碼主要在以下的目錄中:
JAVA程序的路徑:
packages/apps/Music/src/com/android/music/

JAVA本地調(diào)用部分(JNI):
frameworks/base/media/jni/android_media_MediaPlayer.cpp
這部分內(nèi)容編譯成為目標(biāo)是libmedia_jni.so。

主要的頭文件在以下的目錄中:
frameworks/base/include/media/

多媒體底層庫(kù)在以下的目錄中:
frameworks/base/media/libmedia/
這部分的內(nèi)容被編譯成庫(kù)libmedia.so。

多媒體服務(wù)部分:
frameworks/base/media/libmediaplayerservice/
文件為mediaplayerservice.h和mediaplayerservice.cpp
這部分內(nèi)容被編譯成庫(kù)libmediaplayerservice.so。

基于OpenCore的多媒體播放器部分
external/opencore/
這部分內(nèi)容被編譯成庫(kù)libopencoreplayer.so。

        從程序規(guī)模上來(lái)看,libopencoreplayer.so是主要的實(shí)現(xiàn)部分,而其他的庫(kù)基本上都是在其上建立的封裝和為建立進(jìn)程間通訊的機(jī)制。

第二部分 MediaPlayer的接口與架構(gòu)

(hanchao3c Android開發(fā)者論壇原創(chuàng),轉(zhuǎn)載請(qǐng)注明)

2.1 整體框架圖
        MediaPlayer的各個(gè)庫(kù)之間的結(jié)構(gòu)比較復(fù)雜,可以用下圖的表示:

1.png (62.54 KB)

2008-11-22 00:11


    在各個(gè)庫(kù)中,libmedia.so位于核心的位置,它對(duì)上層的提供的接口主要是MediaPlayer類,類libmedia_jni.so通過(guò)調(diào)用MediaPlayer類提供對(duì)JAVA的接口,并且實(shí)現(xiàn)了android.media.MediaPlayer類。
libmediaplayerservice.so是Media的服務(wù)器,它通過(guò)繼承l(wèi)ibmedia.so的類實(shí)現(xiàn)服務(wù)器的功能,而libmedia.so中的另外一部分內(nèi)容則通過(guò)進(jìn)程間通訊和libmediaplayerservice.so進(jìn)行通訊。libmediaplayerservice.so的真正功能通過(guò)調(diào)用OpenCore Player來(lái)完成。

    MediaPlayer部分的頭文件在frameworks/base/include/media/目錄中,這個(gè)目錄是和libmedia.so庫(kù)源文件的目錄frameworks/base/media/libmedia/相對(duì)應(yīng)的。主要的頭文件有以下幾個(gè):


IMediaPlayerClient.h
mediaplayer.h
IMediaPlayer.h
IMediaPlayerService.h
MediaPlayerInterface.h

    在這些頭文件mediaplayer.h提供了對(duì)上層的接口,而其他的幾個(gè)頭文件都是提供一些接口類(即包含了純虛函數(shù)的類),這些接口類必須被實(shí)現(xiàn)類繼承才能夠使用。
    整個(gè)MediaPlayer庫(kù)和調(diào)用的關(guān)系如下圖所示:

2.png (46.74 KB)

2008-11-22 00:11


        整個(gè)MediaPlayer在運(yùn)行的時(shí)候,可以大致上分成Client和Server兩個(gè)部分,它們分別在兩個(gè)進(jìn)程中運(yùn)行,它們之間使用Binder機(jī)制實(shí)現(xiàn)IPC通訊。從框架結(jié)構(gòu)上來(lái)看,IMediaPlayerService.h、IMediaPlayerClient.h和MediaPlayer.h三個(gè)類定義了MeidaPlayer的接口和架構(gòu),MediaPlayerService.cpp和mediaplayer.coo兩個(gè)文件用于MeidaPlayer架構(gòu)的實(shí)現(xiàn),MeidaPlayer的具體功能在PVPlayer(庫(kù)libopencoreplayer.so)中的實(shí)現(xiàn)。

2.2 頭文件IMediaPlayerClient.h  
        IMediaPlayerClient.h用于描述一個(gè)MediaPlayer客戶端的接口,描述如下所示:
class IMediaPlayerClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerClient);
    virtual void notify(int msg, int ext1, int ext2) = 0;
};

class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
{
public:
    virtual status_t  onTransact( uint32_t code,
                                  const Parcel& data,
                                  Parcel* reply,
                                  uint32_t flags = 0);
};
        在定義中,IMediaPlayerClient類繼承IInterface,并定義了一個(gè)MediaPlayer客戶端的接口,BnMediaPlayerClient繼承了BnInterface<IMediaPlayerClient>,這是為基于Android的基礎(chǔ)類Binder機(jī)制實(shí)現(xiàn)在進(jìn)程通訊而構(gòu)建的。事實(shí)上,根據(jù)BnInterface類模版的定義BnInterface<IMediaPlayerClient>類相當(dāng)于雙繼承了BnInterface和ImediaPlayerClient。這是Android一種常用的定義方式。

2.3 頭文件mediaplayer.h
        mediaplayer.h是對(duì)外的接口類,它最主要是定義了一個(gè)MediaPlayer類:
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>& surface);
    status_t    setListener(const sp<MediaPlayerListener>& 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<IMemory>    decode(const char* url, uint32_t *pSampleRate, int* pNumChannels);
    static    sp<IMemory>    decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels);
//……
}
    從接口中可以看出MediaPlayer類剛好實(shí)現(xiàn)了一個(gè)MediaPlayer的基本操作,例如播放(start)、停止(stop)、暫停(pause)等。
    另外的一個(gè)類DeathNotifier在MediaPlayer類中定義,它繼承了IBinder類中的DeathRecipient類:
class DeathNotifier: public IBinder:: DeathRecipient
{
public:
    DeathNotifier() {}
    virtual ~DeathNotifier();
    virtual void binderDied(const wp<IBinder>& who);
};
        事實(shí)上,MediaPlayer類正是間接地繼承了IBinder,而MediaPlayer:: DeathNotifier類繼承了IBinder:: DeathRecipient,這都是為了實(shí)現(xiàn)進(jìn)程間通訊而構(gòu)建的。

2.4 頭文件IMediaPlayer.h
        IMediaPlayer.h主要的的內(nèi)容是一個(gè)實(shí)現(xiàn)MediaPlayer功能的接口,它的主要定義如下所示:
class IMediaPlayer: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayer);
    virtual void    disconnect() = 0;
    virtual status_t    setVideoSurface(const sp<ISurface>& 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<IMediaPlayer>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,  
                                    Parcel* reply,
                                    uint32_t flags = 0);
};
        在IMediaPlayer類中,主要定義MediaPlayer的功能接口,這個(gè)類必須被繼承才能夠使用。值得注意的是,這些接口和MediaPlayer類的接口有些類似,但是它們并沒(méi)有直接的關(guān)系。事實(shí)上,在MediaPlayer類的各種實(shí)現(xiàn)中,一般都會(huì)通過(guò)調(diào)用IMediaPlayer類的實(shí)現(xiàn)類來(lái)完成。


2.5 頭文件IMediaPlayerService.h
        IMediaPlayerService.h用于描述一個(gè)MediaPlayer的服務(wù),定義方式如下所示:
class IMediaPlayerService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerService);
    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0;
    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
    virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels) = 0;
    virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels) = 0;
};
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

    由于具有純虛函數(shù),IMediaPlayerService 以及BnMediaPlayerService必須被繼承實(shí)現(xiàn)才能夠使用,在IMediaPlayerService定義的create和decode等接口,事實(shí)上是必須被繼承者實(shí)現(xiàn)的內(nèi)容。注意,create的返回值的類型是sp<IMediaPlayer>,這個(gè)IMediaPlayer正是提供實(shí)現(xiàn)功能的接口。

第三部分 MediaPlayer的主要實(shí)現(xiàn)分析

(hanchao3c Android開發(fā)者論壇原創(chuàng),轉(zhuǎn)載請(qǐng)注明)


3.1 JAVA程序部分
    在packages/apps/Music/src/com/android/music/目錄的MediaPlaybackService.java文件中,包含了對(duì)MediaPlayer的調(diào)用。
    在MediaPlaybackService.java中包含對(duì)包的引用:
import android.media.MediaPlayer;
    在MediaPlaybackService類的內(nèi)部,定義了MultiPlayer類:
private class MultiPlayer {
    private MediaPlayer mMediaPlayer = new MediaPlayer();
}

    MultiPlayer類中使用了MediaPlayer類,其中有一些對(duì)這個(gè)MediaPlayer的調(diào)用,調(diào)用的過(guò)程如下所示:
    mMediaPlayer.reset();
    mMediaPlayer.setDataSource(path);
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    reset、setDataSource和setAudioStreamType等接口就是通過(guò)JAVA本地調(diào)用(JNI)來(lái)實(shí)現(xiàn)的。

3.2 MediaPlayer的JAVA本地調(diào)用部分
    MediaPlayer的JAVA本地調(diào)用部分在目錄frameworks/base/media/jni/的android_media_MediaPlayer.cpp中的文件中實(shí)現(xiàn)。
    android_media_MediaPlayer.cpp之中定義了一個(gè)JNINativeMethod(JAVA本地調(diào)用方法)類型的數(shù)組gMethods,如下所示:
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的第一個(gè)成員是一個(gè)字符串,表示了JAVA本地調(diào)用方法的名稱,這個(gè)名稱是在JAVA程序中調(diào)用的名稱;第二個(gè)成員也是一個(gè)字符串,表示JAVA本地調(diào)用方法的參數(shù)和返回值;第三個(gè)成員是JAVA本地調(diào)用方法對(duì)應(yīng)的C語(yǔ)言函數(shù)。
    其中android_media_MediaPlayer_reset函數(shù)的實(shí)現(xiàn)如下所示:
static void android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
{
    sp<MediaPlayer> mp = 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的調(diào)用中,得到一個(gè)MediaPlayer指針,通過(guò)對(duì)它的調(diào)用實(shí)現(xiàn)實(shí)際的功能。
        register_android_media_MediaPlayer用于將gMethods注冊(cè)為的類"android/media/MediaPlayer",其實(shí)現(xiàn)如下所示。
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"對(duì)應(yīng)JAVA的類android.media.MediaPlayer。

(hanchao3c Android開發(fā)者論壇原創(chuàng),轉(zhuǎn)載請(qǐng)注明)

3.3 mediaplayer的核心庫(kù)libmedia.so
    libs/media/mediaplayer.cpp文件用于實(shí)現(xiàn)mediaplayer.h提供的接口,其中一個(gè)重要的片段如下所示:
const sp<IMediaPlayerService>& MediaPlayer::getMediaPlayerService()
{
    Mutex::Autolock _l(mServiceLock);
    if (mMediaPlayerService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> 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<IMediaPlayerService>(binder);
    }
    LOGE_IF(mMediaPlayerService==0, "no MediaPlayerService!?");
    return mMediaPlayerService;
}
      其中最重要的一點(diǎn)是binder = sm->getService(String16("media.player"));這個(gè)調(diào)用用來(lái)得到一個(gè)名稱為"media.player"的服務(wù),這個(gè)調(diào)用返回值的類型為IBinder,根據(jù)實(shí)現(xiàn)將其轉(zhuǎn)換成類型IMediaPlayerService使用。
       一個(gè)具體的函數(shù)setDataSource如下所示:
status_t MediaPlayer::setDataSource(const char *url)
{
    LOGV("setDataSource(%s)", url);
    status_t err = UNKNOWN_ERROR;
    if (url != NULL) {
        const sp<IMediaPlayerService>& service(getMediaPlayerService());
        if (service != 0) {
            sp<IMediaPlayer> player(service->create(getpid(), this, url));
            err = setDataSource(player);
        }
    }
    return err;
}
    在函數(shù)setDataSource函數(shù)中,調(diào)用getMediaPlayerService得到了一個(gè)IMediaPlayerService,又從IMediaPlayerService中得到了IMediaPlayer類型的指針,通過(guò)這個(gè)指針進(jìn)行著具體的操作。
    其他一些函數(shù)的實(shí)現(xiàn)也與setDataSource類似。
        libmedia.so中的其他一些文件與頭文件的名稱相同,它們是:
libs/media/IMediaPlayerClient.cpp
libs/media/IMediaPlayer.cpp
libs/media/IMediaPlayerService.cpp
     為了實(shí)現(xiàn)Binder的具體功能,在這些類中還需要實(shí)現(xiàn)一個(gè)BpXXX的類,例如IMediaPlayerClient.cpp的實(shí)現(xiàn)如下所示:l
class BpMediaPlayerClient: public BpInterface<IMediaPlayerClient>
{
public:
    BpMediaPlayerClient(const sp<IBinder>& impl)
    : BpInterface<IMediaPlayerClient>(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);
    }
};
        還需要實(shí)現(xiàn)定義宏IMPLEMENT_META_INTERFACE,這個(gè)宏將被展開,生成幾個(gè)函數(shù):
IMPLEMENT_META_INTERFACE(MediaPlayerClient, "android.hardware.IMediaPlayerClient");
        以上的實(shí)現(xiàn)都是基于Binder框架的實(shí)現(xiàn)方式,只需要按照模版實(shí)現(xiàn)即可。其中BpXXX的類為代理類(proxy),BnXXX的類為本地類(native)。代理類的transact函數(shù)和本地類的onTransact函數(shù)實(shí)現(xiàn)對(duì)應(yīng)的通訊。

3.4 media服務(wù)libmediaservice.so
    frameworks/base/media\libmediaplayerservice目錄中的MediaPlayerService.h和MediaPlayerService.cpp用于實(shí)現(xiàn)一個(gè)
servers/media/的服務(wù),MediaPlayerService是繼承BnMediaPlayerService的實(shí)現(xiàn),在這個(gè)類的內(nèi)部又定義了類Client,MediaPlayerService::Client繼承了BnMediaPlayer。
class MediaPlayerService : public BnMediaPlayerService
{
    class Client : public BnMediaPlayer
}
    在MediaPlayerService中具有如下一個(gè)靜態(tài)函數(shù)instantiate:
void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
    String16("media.player"), new MediaPlayerService());
}
    在instantiate函數(shù)中,調(diào)用IServiceManager的一個(gè)函數(shù)addService,向其中增加了一個(gè)名為"media.player"的服務(wù)。
    這個(gè)名為"media.player"的服務(wù)和mediaplayer.cpp中調(diào)用getService中得到的使用一樣名稱。因此,在這里調(diào)用addService增加服務(wù)在mediaplayer.cpp中可以按照名稱"media.player"來(lái)使用。這就是使用Binder實(shí)現(xiàn)進(jìn)程間通訊的(IPC)的作用,事實(shí)上這個(gè)MediaPlayerService類是在服務(wù)中運(yùn)行的,而mediaplayer.cpp調(diào)用的功能在應(yīng)用中運(yùn)行,二者并不是一個(gè)進(jìn)程。但是在mediaplayer.cpp卻像一個(gè)進(jìn)程的調(diào)用一樣調(diào)用MediaPlayerService的功能。
    在MediaPlayerService.cpp中的createPlayer函數(shù)如下所示:
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
    notify_callback_f notifyFunc)
{
    sp<MediaPlayerBase> 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;
}
    在這里根據(jù)playerType的類型建立不同的播放器:對(duì)于大多數(shù)情況,類型將是PV_PLAYER,這時(shí)會(huì)調(diào)用了new PVPlayer()建立一個(gè)PVPlayer,然后將其指針轉(zhuǎn)換成MediaPlayerBase來(lái)使用;對(duì)于Mini文件的情況,類型為SONIVOX_PLAYER,將會(huì)建立一個(gè)MidiFile;對(duì)于Ogg Vorbis格式的情況,將會(huì)建立一個(gè)VorbisPlayer。
     (OGG Vobis是一種音頻壓縮格式,與MP3等的音樂(lè)格式類似,它具有完全免費(fèi)、開放和沒(méi)有專利限制的特點(diǎn)。)
    值得注意的是PVPlayer、MidiFile和VorbisPlayer三個(gè)類都是繼承MediaPlayerInterface得到的,而MediaPlayerInterface又是繼承MediaPlayerBase得到的,因此三者具有相同接口類型。只有建立的時(shí)候會(huì)調(diào)用各自的構(gòu)造函數(shù),在建立之后,將只通過(guò)MediaPlayerBase接口來(lái)MediaPlayerBase控制它們。
    在frameworks/base/media/libmediaplayerservice目錄中,MidiFile.h和MidiFile.cpp的實(shí)現(xiàn)MidiFile,VorbisPlayer.h和VorbisPlayer.cpp實(shí)現(xiàn)一個(gè)VorbisPlayer。

3.5 OpenCorePlayer的實(shí)現(xiàn)libopencoreplayer.so
       OpenCore Player在external/opencore/中實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)是一個(gè)基于OpenCore的Player的實(shí)現(xiàn)。具體實(shí)現(xiàn)的文件為playerdriver.cpp。其中實(shí)現(xiàn)了兩個(gè)類:PlayerDriver和PVPlayer。PVPlayer通過(guò)調(diào)用PlayerDriver的函數(shù)實(shí)現(xiàn)具體的功能。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多