(Base on Android Q)
主要是為了梳理MediaRecorder模塊代碼,熟悉流程
本文的簡化圖由draw.io繪制,詳細(xì)時(shí)序圖由plantUml繪制
繪制原材料在百度云盤中 鏈接: https://pan.baidu.com/s/1IJ7Qo2Jl3o6GthPtAiD95Q 提取碼: qu4w
,可以自行down下來修改添加
一.MediaRecorder整體架構(gòu)
主要簡單梳理數(shù)據(jù)流向,方便復(fù)習(xí)記憶
1.1 MediaRecorder簡單錄制視頻框架:
在這里插入圖片描述
簡單過程:
1.Camera應(yīng)用中至少有兩個(gè)Surface,一個(gè)使用于preview的,另一個(gè)使用來record的,record的surface是PersistentSurface類型,PersistentSurface中的GraphicBufferSource類型的成員變量mBufferSource最終由編碼器創(chuàng)建引用;
2.CameraServer中持有Record Surface的producer引用和Preview Surface的producer引用,因此預(yù)覽和錄制CameraServer都充當(dāng)著生產(chǎn)者的角色;
3.在向CameraProvider發(fā)request的時(shí)候先dequeueBuffer送至HAL去填充,填充完HAL發(fā)回result這時(shí)queueBuffer將數(shù)據(jù)填充至BufferQueue中,由BufferQueue的原理,可知這時(shí)候BufferQueue的Consumer將回調(diào)onFrameAvailable函數(shù)去收到數(shù)據(jù)準(zhǔn)備完成通知,接下來Consumer使用acquireBuffer去消費(fèi)即可,消費(fèi)完即releaseBuffer去釋放Buffer;
4.對(duì)于preview,消費(fèi)者就是Surfaceflinger了,合成消費(fèi)后拿去顯示,對(duì)于record,消費(fèi)者就是編碼器了,舉例OMX一種,編碼器獲取到數(shù)據(jù)消費(fèi)用于編碼;
5.編碼器編完碼之后將調(diào)用Framework中MediaServer的回調(diào),將編碼后的數(shù)據(jù)傳遞至MediaRecorder;
6.MediaRecorder在start之后將啟動(dòng)一個(gè)WriteThread,兩個(gè)TrackThread(分別是Video和Audio),當(dāng)TrackThread跟蹤到有相應(yīng)數(shù)據(jù)后將video或audio的數(shù)據(jù)分裝成Chunk數(shù)據(jù)結(jié)構(gòu),保存在MPEG4Writer成員變量mChunks中.這時(shí)WriteThread發(fā)現(xiàn)有數(shù)據(jù)可寫會(huì)將mChunks中的chunk寫到文件中.
1.2 PersistentSurface及GraphicBufferSource實(shí)現(xiàn)的BufferQueue框架
1.CameraApp使用的Java層PersistentSurface繼承Java層的Surface,因此它首先是個(gè)Surface,其次他一個(gè)成員變量指向Native層的 PersistentSurface 實(shí)例對(duì)象,也指向Natvie層創(chuàng)建的Surface對(duì)象;
2.Surface一般用來作為生產(chǎn)者的容器,這里一樣,Java PersistentSurface的 natvie Surface給到CameraServer用于生產(chǎn)數(shù)據(jù)容器,Producer是CameraServer;
3.Native PersistentSurface的兩個(gè)參數(shù)mBufferProducer和mBufferSource最終是由編碼器創(chuàng)建,其mBufferProducer指向CameraServer中的Record Surface,mBufferSource作為消費(fèi)者引用在編碼器內(nèi)部實(shí)現(xiàn),mBufferSource是GraphicBufferSource類型,在其走在構(gòu)造函數(shù)時(shí)會(huì)創(chuàng)建BufferQueue;
4.mBufferSource應(yīng)是指向引用編碼器內(nèi)部的數(shù)據(jù)結(jié)構(gòu)或?qū)嵗?Acodec可以通過GraphicBufferSource類型的成員變量(由PersistentSurface的mBufferSource賦值來)對(duì)編碼器進(jìn)行一些參數(shù)設(shè)置.
1.3 寫文件的過程及重要類
二.MediaRecorder init,prepare,start,stop簡單過程
上面已經(jīng)將重要過程過基本講述了完了,下面是簡單地梳理MediaRecorder的代碼過程,文末將附上詳細(xì)的代碼跟進(jìn)過程,簡化圖為了方便記憶主要過程,都基于詳細(xì)代碼跟進(jìn)之后歸納重點(diǎn)的地方.
2.1 MediaRecorder init
詳細(xì)過程見附件,其中附上PersistentSurface的創(chuàng)建及設(shè)置詳細(xì)過程
2.2 MediaRecorder prepare
MediaCodecSource 即對(duì)應(yīng)videoEncoder和audioEncoder的初始化:
prepare的詳細(xì)過程見附件.
2.3 MediaRecorder start
MediaRecord Start 與編碼器數(shù)據(jù)傳遞至recorder的詳細(xì)過程見附件