免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      Android音視頻開發(fā)-Media FrameWork框架與源碼解析

      Android音視頻開發(fā)-Media FrameWork框架與源碼解析

      一、Media FrameWork背景

      Media Framework (媒體函數(shù)庫):此函數(shù)庫讓Android 可以播放與錄制許多常見的音頻與視頻文件,支持的文件類型包括MPEG4、H.264、MP3、AAC、AMR、JPG 與PNG 等。 Surface Manager (外觀管理函數(shù)庫):管理圖形界面的操作與2D、3D 圖層的顯示。

      二、Media Framework“路線圖”

      我們可以看到用紅色框框圈起來的地方。一個(gè)是app應(yīng)用Gallery(也可以為第三方player);另外一個(gè)是Media Framework。對(duì),沒錯(cuò),講了這么多,我們的主角“Media Framework”登場(chǎng)了。讓我們來看看它的廬山真面目, 如圖所示:

      接下來,給大家簡單介紹下它??吹捻樞蚴? (腫么都覺得是在打表情符號(hào):-D)

      2.1 代理端

      這一端做的事情只是將下面復(fù)雜的邏輯進(jìn)行封裝(java),然后透過jni調(diào)用底下的native層方法來實(shí)現(xiàn)具體功能。并且,這些個(gè)具體的功能是在服務(wù)端實(shí)現(xiàn)的,他們分屬不同的進(jìn)程,通過Binder來通信,最終通過調(diào)用服務(wù)端的方法實(shí)現(xiàn)具體的邏輯處理。(有童鞋問:Binder是個(gè)什么東東呢? 小弟有時(shí)間會(huì)講解的,現(xiàn)在就理解它是一個(gè)進(jìn)程間通信的一種方式就好,求甚解的朋友們可以百度下_)

      2.2 服務(wù)端

      這邊的主要任務(wù)就是在MediaPlayerFactory中,創(chuàng)建出NuplayerDriver(這個(gè)不是底層驅(qū)動(dòng)啦,我們理解為一個(gè)抽象出來的NuPlayer的基類就好啦)。 然后Nuplayer中,我們可以看到有三大模塊。

      2.2.1 Source

      這里是為咱們的播放器提供數(shù)據(jù)源的(解協(xié)議,解封裝在這里)。

      2.2.2 Decoder

      這里是解碼數(shù)據(jù)的地方(解碼在這里)

      2.2.3 Renderer

      這里是用來做Display的,里面涉及到A/V同步的問題。

      2.2.4 Foundation

      這個(gè)部分是基礎(chǔ)類。在后面的分析當(dāng)中,我們會(huì)知道在NuPlayer中會(huì)啟動(dòng)相當(dāng)多的線程,這些線程如何異步/同步的通信,需要依靠AMessage/ALooper/AHandler來支持

      之后, 通過接口類IOMX來通過Binder進(jìn)程間通信,遠(yuǎn)程調(diào)用具體的decoder來實(shí)現(xiàn)解碼。

      2.3 OMX端

      這一端就比較靠近底層了,里面會(huì)有各種各樣的插件注冊(cè)其中。它還鏈接這Codec Driver,這里面就是放的各種具體的解碼器啦。

      2.4 Kernel端

      最后, OMX的具體解碼器在啟動(dòng)Kernel層的A/V Codec Driver完成解碼操作。

      三、media播放的流程

      在framework中涉及media播放的流程頭文件如下:IMediaPlayer.h mediaplayer.h IMediaPlayerClient.h

      其中IMediaPlayer.h 定義了binder通信相關(guān)的接口。 定義了:

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

      IMediaPlayer.cpp 是binder通信接口的實(shí)現(xiàn)。

      class BpMediaPlayer: public BpInterface; status_t BnMediaPlayer::onTransact();

      mediaplayer.h 是定義binder通信的客戶端。在mediaplayer.cpp中如下代碼獲取BpMediaPlayer:

      status_t MediaPlayer::setDataSource( const char *url, const KeyedVector *headers){ LOGV(“setDataSource(%s)”, url); status_t err = BAD_VALUE; if (url != NULL) { const sp& service(getMediaPlayerService()); if (service != 0) { sp player( service->create(getpid(), this, url, headers)); err = setDataSource(player); } } return err;}

      服務(wù)端在MediaPlayerService中。在MediaPlayerService.h中如下定義:

      class Client : public BnMediaPlayer 在MediaPlayerService.cpp中,create函數(shù)創(chuàng)建了BnMediaPlayer:

      sp MediaPlayerService::create( pid_t pid, const sp& client, const char* url, const KeyedVector *headers){ int32_t connId = android_atomic_inc(&mNextConnId); sp c = new Client(this, pid, connId, client); LOGV(“Create new client(%d) from pid %d, url=%s, connId=%d”, connId, pid, url, connId); if (NO_ERROR != c->setDataSource(url, headers)) { c.clear(); return c; } wp w = c; Mutex::Autolock lock(mLock); mClients.add(w); return c;}

      再來看一下MediaPlayer這個(gè)類的定義:

      class MediaPlayer : public BnMediaPlayerClient, public virtual IMediaDeathNotifier{} 很奇怪:在binder通信的客戶端又有了一個(gè)binder通信的服務(wù)端: BnMediaPlayerClient 在IMediaPlayerClient.h 中這個(gè)binder通信只有一個(gè)接口:

      class IMediaPlayerClient: public IInterface{public: DECLARE_META_INTERFACE(MediaPlayerClient); virtual void notify(int msg, int ext1, int ext2) = 0;};

      這個(gè)binder通信服務(wù)為誰提供呢?在回來看一下MediaPlayerServer中的create函數(shù):

      sp MediaPlayerService::create( pid_t pid, const sp& client, const char* url, const KeyedVector *headers)

      客戶端就在這里。這個(gè)binder通信的實(shí)質(zhì)是一個(gè)消息回調(diào)函數(shù)。framework的media框架式一個(gè)雙向binder通信框架。

      以seek接口為例分析一下:

      在mediaplayer.cpp 中調(diào)用seek 接口:

      MediaPlayer (seek)->IMediaPlayer.cpp(bpMediaPlayer.cpp )->IMediaPlayer.cpp(bnMediaPlayer.cpp ) 在這里其實(shí)已經(jīng)達(dá)到了MediaPlayerServer中的client類。當(dāng)?shù)讓拥膍edia 完成seek 以后會(huì)拋出來一消息,這個(gè)消息通過 const sp& client 通知給MediaPlayer。

      在media相關(guān)的頭文件中還有一個(gè)MediaPlayerInterface.h 。這個(gè)頭文件定義了底層播放器的接口。

      四、Media FrameWork源碼分析

      首先,針對(duì)android.media.MediaPlayer進(jìn)行分析。

      里面有很多native代碼,我們找到native_setup這個(gè)jni調(diào)用,就可以找到整個(gè)框架的入口。

      我們查看

      android_media_MediaPlayer_native_setup@framworks/base/media/jni/android_media_MediaPlayer.cpp

      `static` `void` `android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)“{“ “LOGV(“”native_setup”“);“ “sp mp = “new` `MediaPlayer();“ “if` `(mp == NULL) {“ “jniThrowException(env, “”java/lang/RuntimeException”“, “”Out of memory”“);“ “return“;“ “}` ` “// create new listener and give it to MediaPlayer“ “sp listener = “new` `JNIMediaPlayerListener(env, thiz, weak_this);“ “mp->setListener(listener);` ` “// Stow our new C++ MediaPlayer in an opaque field in the Java object.“ “setMediaPlayer(env, thiz, mp);“}`

      從這里的這段代碼我們可以看到,android在這里實(shí)例化了一個(gè)變量mp:MediaPlayer。

      并且為其設(shè)置了一個(gè)listener:JNIMediaPlayerListener

      在后面我們會(huì)看到對(duì)mp的調(diào)用,現(xiàn)在讓我們先看看MediaPlayer是什么東東。

      MediaPlayer@framworks/base/include/media/mediaplayer.h MediaPlayer@framworks/base/media/libmedia/mediaplayer.cpp

      在這里我們終于找到了MediaPlayer:BnMediaPlayerClient:IMediaPlayerClient

      原來他也是對(duì)Bind Native的一個(gè)封裝,而他本身提供了很多方法用于訪問,包括start等。下面是start的cpp代碼:

      status_t MediaPlayer::start(){ LOGV(“start”); Mutex::Autolock _l(mLock); if (mCurrentState & MEDIA_PLAYER_STARTED) return NO_ERROR; if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { mPlayer->setLooping(mLoop); mPlayer->setVolume(mLeftVolume, mRightVolume); mCurrentState = MEDIA_PLAYER_STARTED; status_t ret = mPlayer->start(); if (ret != NO_ERROR) { mCurrentState = MEDIA_PLAYER_STATE_ERROR; } else { if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { LOGV(“playback completed immediately following start()”); } } return ret; } LOGE(“start called in state %d”, mCurrentState); return INVALID_OPERATION;}

      原來這里又調(diào)用了mPlayer:sp

      從這里我們發(fā)現(xiàn)最終的服務(wù),還是由IMediaPlayer這個(gè)東西提供的,而IMediaPlayer@framworks/base/include/media/IMediaPlayer.h

      實(shí)際上是如下定義的一個(gè)類,它繼承了IInterface@framworks/base/include/binder/IInterface.h這個(gè)類(注意雖然名字是Interface,但是它確實(shí)是個(gè)類!:-))

      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 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; virtual status_t invoke(const Parcel& request, Parcel *reply) = 0; virtual status_t setMetadataFilter(const Parcel& filter) = 0; virtual status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata) = 0;};

      為了弄清楚,在什么地方產(chǎn)生的mPlayer,我轉(zhuǎn)而分析MediaPlayerService@framworks/base/media/libmediaplayerservice/MediaPlayerService.h

      其中有如下代碼

      virtual sp createMediaRecorder(pid_t pid);void removeMediaRecorderClient(wp client);virtual sp createMetadataRetriever(pid_t pid); // House keeping for media player clientsvirtual sp create(pid_t pid, const sp& client, const char* url);virtual sp create(pid_t pid, const sp& client, int fd, int64_t offset, int64_t length);

      原來在這個(gè)地方會(huì)創(chuàng)建你sp對(duì)象。

      五、文末

      在本篇中,我們知道了Media Framework在整個(gè)Android框架中的位置, 也了解了Media Framework自己是個(gè)什么樣框架,以及它和各部分的聯(lián)系。 以及他的源碼分析。這也是音視頻學(xué)習(xí)的重要部分。音視頻進(jìn)階入門,請(qǐng)私信發(fā)送“核心筆記”或“手冊(cè)”,即可獲取音視頻資料!

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年6月25日 21:22
      下一篇 2022年6月25日 21:22

      相關(guān)推薦

      • 短視頻策劃內(nèi)容的3個(gè)要點(diǎn)(短視頻策劃內(nèi)容怎么做)

        短視頻在制作時(shí),內(nèi)容框架非常重要。如果直奔主題,然后結(jié)束,聚卓告訴你,這樣的短視頻已經(jīng)過時(shí)了?,F(xiàn)在的短視頻需要框架的,但不是任何框架,它需要一種易于理解和消化的框架。而且,現(xiàn)在大多…

        2022年11月27日
      • 存儲(chǔ)過程語法(sql server存儲(chǔ)過程語法)

        今天小編給各位分享存儲(chǔ)過程語法的知識(shí),其中也會(huì)對(duì)sql server存儲(chǔ)過程語法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲(chǔ)過程基本語法…

        2022年11月26日
      • 成都健康碼打不開顯示接口請(qǐng)求未知異常怎么辦(成都健康碼打不開顯示接口請(qǐng)求未知異常)

        成都這幾天的疫情也是備受關(guān)注,疫情期間各地出行都是需要查看健康碼的,不過今天卻有成都的小伙伴反饋健康碼無法打開的情況。成都健康碼打不開顯示接口請(qǐng)求未知異常怎么辦?由于健康碼無法打開…

        2022年11月24日
      • 1千克等于多少磅

        克,此定義在1958年被美國以及其他英聯(lián)邦會(huì)員國承認(rèn)換算回來,一千克等于262磅,一磅等于037千克英國在1963年開始,依據(jù)度量衡法案的規(guī);1 磅=16 盎司=04536 千克 …

        2022年11月24日
      • 神舟戰(zhàn)神S7-DA5NS電腦預(yù)售 到手價(jià)僅需5399元

        神舟戰(zhàn)神S7-DA5NS正在京東商城預(yù)售搶購,預(yù)售到手價(jià)僅需5399元。其搭載了全新12代i5-12450H處理器,擁有2.0GHz八核十二線程效能,RTX3050 4G GDDR…

        2022年11月23日
      • 馬斯克凌晨一點(diǎn)半曬“代碼審查”現(xiàn)場(chǎng),編排他的段子比瘋狂星期四還多

        夢(mèng)晨 Pine 發(fā)自 凹非寺 量子位 | 公眾號(hào) QbitAI 每一個(gè)真正會(huì)寫代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 每一個(gè)真正會(huì)寫代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 馬斯…

        2022年11月21日
      • win11任務(wù)管理器在哪(任務(wù)管理器怎么打開)

        在win10電腦中,我們可以在任務(wù)管理器里查看系統(tǒng)各項(xiàng)資源使用情況,也可以通過這個(gè)地方強(qiáng)行結(jié)束卡死的進(jìn)程。不過很多人不知道如何打開電腦上的任務(wù)管理器,下面就和大家講解一下方法吧。 …

        2022年11月18日
      • 手淘搜索是自然流量嗎(手淘搜索流量怎么提高)

        作為一個(gè)賣家,我們都應(yīng)該知道,現(xiàn)在店鋪的流量大部分來自移動(dòng)端,也就是我們說的手機(jī)端流量。隨著智能手機(jī)的發(fā)展及網(wǎng)速的提升,手機(jī)購物已成為常態(tài)。而淘寶也一直嘗試著從一個(gè)購物平臺(tái)往社交平…

        2022年11月18日
      • 英特爾NUC迷你主機(jī)僅需749元 搭載賽揚(yáng)J4005處理器

        作為資深NUC用戶,小編對(duì)迷你臺(tái)式機(jī)可謂是情有獨(dú)鐘,畢竟迷你臺(tái)式機(jī)可以大量的節(jié)省空間?,F(xiàn)在,這款英特爾NUC迷你主機(jī)僅需749元。 這款英特爾NUC迷你主機(jī)搭載了intel賽揚(yáng)J4…

        2022年11月17日
      • 優(yōu)派和aoc顯示器哪個(gè)好(優(yōu)派顯示器怎么樣)

        這兩年便攜式顯示器的崛起并不是一個(gè)偶然,對(duì)于很多人包括筆者在內(nèi),對(duì)家庭第二塊顯示器的需求的確是越來越大。一方面單獨(dú)買個(gè)筆記本在家使用并不劃算,反而是搭配雙屏顯示更符合自己的需求;另…

        2022年11月13日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息