天天看點

MediaPlayerService流程簡要分析

涉及相關檔案:

\frameworks\av\media\mediaserver\mediaserver.rc

\frameworks\av\media\mediaserver\main_mediaserver.cpp

\frameworks\av\media\libmediaplayerservice\MediaPlayerService.h

\frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

\frameworks\av\media\libmediaplayerservice\MediaPlayerFactory.h

\frameworks\av\media\libmediaplayerservice\MediaPlayerFactory.cpp

\frameworks\av\include\media\IMediaPlayerService.h

\frameworks\av\media\libmedia\include\media\IMediaPlayer.h

MediaPlayerService服務相關類關系圖如下:

MediaPlayerService流程簡要分析

在\frameworks\av\media\mediaserver\中,mediaserver.rc檔案内容如下,啟動/system/bin/mediaserver作為media服務

service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

           

main_mediaserver.cpp中main函數内容如下,擷取IServiceManager服務管理對象,然後初始化MediaPlayerService、ResourceManagerService并且将這兩個服務加入到ServiceManager中管理。

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm(defaultServiceManager());
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    MediaPlayerService::instantiate();
    ResourceManagerService::instantiate();
    registerExtensions();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}
           

MediaPlayerService中的初始化方法如下:

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());  //将該服務加入到ServiceManager中
}

MediaPlayerService::MediaPlayerService()
{
    ALOGV("MediaPlayerService created");
    mNextConnId = 1;

  MediaPlayerFactory::registerBuiltinFactories();  //完成player工廠的注冊
}
           

在MediaPlayerFactory.cpp注冊了兩個工廠類:NuPlayerFactory和TestPlayerFactory(一般debug版本才會用到),注冊完成會将兩個Ifactory對象加入到容器tFactoryMap中

void MediaPlayerFactory::registerBuiltinFactories() {
    Mutex::Autolock lock_(&sLock);

    if (sInitComplete)
        return;

    IFactory* factory = new NuPlayerFactory();
    if (registerFactory_l(factory, NU_PLAYER) != OK) //注冊将其加入到容器中
        delete factory;
    factory = new TestPlayerFactory();
    if (registerFactory_l(factory, TEST_PLAYER) != OK)
        delete factory;

    sInitComplete = true;
}

typedef KeyedVector<player_type, IFactory*> tFactoryMap;
           

NuPlayerFactory實作如下:

class NuPlayerFactory : public MediaPlayerFactory::IFactory {
  public:
    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
                               const char* url,
                               float curScore) {
        static const float kOurScore = 0.8;

        if (kOurScore <= curScore)
            return 0.0;

        if (!strncasecmp("http://", url, 7)
                || !strncasecmp("https://", url, 8)
                || !strncasecmp("file://", url, 7)) {
            size_t len = strlen(url);
            if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
                return kOurScore;
            }

            if (strstr(url,"m3u8")) {
                return kOurScore;
            }

            if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
                return kOurScore;
            }
        }

        if (!strncasecmp("rtsp://", url, 7)) {
            return kOurScore;
        }

        return 0.0;
    }

    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
                               const sp<IStreamSource>& /*source*/,
                               float /*curScore*/) {
        return 1.0;
    }

    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
                               const sp<DataSource>& /*source*/,
                               float /*curScore*/) {
        // Only NuPlayer supports setting a DataSource source directly.
        return 1.0;
    }

    virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
        ALOGV(" create NuPlayer");
        return new NuPlayerDriver(pid);
    }
};
           

MediaPlayerService中Client對象建立過程如下:

sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
        audio_session_t audioSessionId)
{
    pid_t pid = IPCThreadState::self()->getCallingPid();
    int32_t connId = android_atomic_inc(&mNextConnId);
    //建立client對象
    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);    //将新建立的client對象加入到容器mClient中
    }
    return c;
}

           

client類定義如下,包含了所有針對音視訊播放所需要的操作,與native層的MediaPlayer類方法正好對應

class Client : public BnMediaPlayer {
        // IMediaPlayer interface
        virtual void            disconnect();
        virtual status_t        setVideoSurfaceTexture(
                                        const sp<IGraphicBufferProducer>& bufferProducer);
        virtual status_t        setBufferingSettings(const BufferingSettings& buffering) override;
        virtual status_t        getBufferingSettings(
                                        BufferingSettings* buffering /* nonnull */) override;
        virtual status_t        prepareAsync();
        virtual status_t        start();
        virtual status_t        stop();
        virtual status_t        pause();
        virtual status_t        isPlaying(bool* state);
        //......省略
           

其中父類定義如下

class BnMediaPlayer: public BnInterface<IMediaPlayer>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

class IMediaPlayer: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayer);

    virtual void            disconnect() = 0;

    virtual status_t        setDataSource(
            const sp<IMediaHTTPService> &httpService,
            const char *url,
            const KeyedVector<String8, String8>* headers) = 0;

    virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
    virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0;
    virtual status_t        setDataSource(const sp<IDataSource>& source) = 0;
    virtual status_t        setVideoSurfaceTexture(
                                    const sp<IGraphicBufferProducer>& bufferProducer) = 0;
    virtual status_t        getBufferingSettings(
                                    BufferingSettings* buffering /* nonnull */) = 0;
    virtual status_t        setBufferingSettings(const BufferingSettings& buffering) = 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        setPlaybackSettings(const AudioPlaybackRate& rate) = 0;
    virtual status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) = 0;
    //......省略
           

MediaPlayerService本身不負責音視訊的具體操作,通過管理client接口與工廠類,将具體播放工作通過binder交由其他程序負責完成,而MediaPlayer又是通過binder擷取到MediaPlayerService服務,通過發送和接收指令來完成音視訊的播放和狀态的更新擷取等。

繼續閱讀