|
【HarmonyOS HiSpark AI Camera試用連載】鴻蒙系統(tǒng)之媒體子系統(tǒng)——Recorder(續(xù)), 接上篇繼續(xù)分析 鴻蒙系統(tǒng)媒體子系統(tǒng)的Recorder部分。
再來分析類 RecorderImpl 的另一個成員,一個數(shù)組:
SourceManager sourceManager_[RECORDER_SOURCE_MAX_CNT];
且看結(jié)構(gòu)體 SourceManager:
struct SourceManager {
RecorderVideoSource *videoSource; // 視頻緩沖區(qū)管理
bool videoSourceStarted; // 視頻啟動狀態(tài)
bool videoSourcePaused; // 視頻暫停狀態(tài)
int32_t videoTrackId;
std::thread videoProcessThread; // 視頻處理線程
RecorderaudioSource *audioSource; // 音頻緩沖區(qū)管理
bool audioSourceStarted; // 音頻啟動狀態(tài)
bool audioSourcePaused; //音頻暫停狀態(tài)
int32_t audioTrackId;
std::thread audioProcessThread; // 音頻處理線程
RecorderVideoSourceConfig videoSourceConfig;
RecorderAudioSourceConfig audioSourceConfig;
};
SourceManager 中包含 RecorderVideoSource 和 RecorderAudioSource,來完成視頻和音頻的相關(guān)的操作,并記錄其Recorder狀態(tài)。
類 RecorderImpl 的成員 sourceManager_ 數(shù)組在上層調(diào)用以下系列接口時被逐步的初始化:
int32_t Recorder::RecorderImpl::SetVideoSource(VideoSourceType source, int32_t &sourceId);
int32_t Recorder::RecorderImpl::SetVideoEncoder(int32_t sourceId, VideoCodecFormat encoder);
int32_t Recorder::RecorderImpl::SetAudioSource(AudioSourceType source, int32_t &sourceId);
...
以視頻Video為例,在設(shè)置 video 相關(guān)參數(shù)時,可以看到對 sourceManager_ 數(shù)組的操作:
011.jpg (232.63 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
可以看到賦值語句:
sourceManager_[sourceId].videoSource = new RecorderVideoSource();
在類 RecorderVideoSource 中,主要完成一些共享內(nèi)存 SuRFace,緩沖區(qū)查詢、請求、釋放等操作。
020.jpg (121.37 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
回到 applications/sample/camera/media/camera_sample.cpp 文件的 StartRecord() 函數(shù)中,其調(diào)用的 recorder_->Prepare() 和 recorder_->Start() 均可對應(yīng)到 類 RecorderImpl 中:
在 Prepare() 中,分別 prepare 了 recorderSink_、VideoSource、AudioSource,
012.jpg (107.83 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
在此仍以 video 為例追蹤,可以看到其完成 video source 相關(guān)工作。
013.jpg (152.28 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
在 Start() 中,分別啟動了 recorderSink_、VideoSource、AudioSource,
014.jpg (146.24 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
在此仍以 video 為例追蹤,
015.jpg (105.41 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
調(diào)用 recorderSink_->Start() 即前文提到的 將數(shù)據(jù)格式化后輸出至錄像文件中保存。
調(diào)用 StartVideoSource(),在其中:
首先調(diào) 用 sourceManager_.videoSource->Start() 對數(shù)組中對應(yīng)的 RecorderVideoSource 實(shí)例作啟動(內(nèi)部實(shí)際僅改變其狀態(tài));
接著通過
sourceManager_.videoProcessThread = std::thread(VideoSourceProcess, &sourceManager_, recorderSink_);
創(chuàng)建一個視頻源處理線程,則接下來的工作有該線程去完成。
016.jpg (227.91 KB, 下載次數(shù): 0)
下載附件 保存到相冊
2 小時前 上傳
在線程的執(zhí)行體函數(shù) VideoSourceProcess 的 while 循環(huán)中,
調(diào)用
videoSourceManager->videoSource->AcquireBuffer(buffer, true);
實(shí)現(xiàn)請求 buffer(即調(diào)用類 RecorderVideoSource 中的函數(shù));
調(diào)用
videoSourceManager->videoSource->AcquireBuffer(buffer, true);
實(shí)現(xiàn)寫入格式后的數(shù)據(jù)到錄像文件(即調(diào)用類 RecorderSink 中的 WriteData()函數(shù))。
至此,Recorder 的底層框架及調(diào)用流程已然明了。 |
|