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