電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 1335|回復(fù): 0
收起左側(cè)

【HarmonyOS HiSpark AI Camera試用連載】鴻蒙系統(tǒng)之媒體子系統(tǒng)Record

[復(fù)制鏈接]

2607

主題

2607

帖子

7472

積分

高級(jí)會(huì)員

Rank: 5Rank: 5

積分
7472
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2021-1-26 17:56:29 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
【HarmonyOS HiSpark AI Camera試用連載】鴻蒙系統(tǒng)之媒體子系統(tǒng)Record, 之前分析了媒體子系統(tǒng)的主要框架,另外其中涉及的幾個(gè)輔助類,這些類調(diào)用了一些封裝的底層接口以幫助應(yīng)用層開發(fā)者快速開發(fā)。

在應(yīng)用層,applications/sample/camera/media/camera_sample.cpp 文件的 main() 函數(shù)中,我們以Record為例對(duì)其主線進(jìn)行分析。



001.jpg (109.7 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳



  • int main()
      
  • {
      
  •     cout << “Camera sample begin.“ << endl;
      
  •     SampleHelp();
      
  •     CameraKit *camKit = CameraKit::GetInstance();
      
  •     if (camKit == nullptr) {
      
  •         cout << “Can not get CameraKit instance“ << endl;
      
  •         return 0;
      
  •     }
      
  •     list<string> camList = camKit->GetCameraIds();
      
  •     string camId;
      
  •     for (auto &cam : camList) {
      
  •         cout << “camera name:“ << cam << endl;
      
  •         const CameraAbility *ability = camKit->GetCameraAbility(cam);
      
  •         /* find camera which fits user\“s ability */
      
  •         list<CameraPicSize> sizeList = ability->GetSupportedSizes(0);
      
  •         if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) {
      
  •             camId = cam;
      
  • <!--StartFragment-->            <!--EndFragment--> break;

復(fù)制代碼

首先看調(diào)用 StartRecord(),



002.jpg (156.87 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

在 StartRecord() 中可以看到其所做的工作如下:

1、調(diào)用 PrepareRecorder() 即做一些準(zhǔn)備工作:其中包括:創(chuàng)建 真正的(狹義的)Recorder,創(chuàng)建錄像文件;

2、調(diào)用 recorder_->SetOutputFile() 設(shè)置(傳遞)錄像文件的文件描述符;

3、調(diào)用 recorder_->Prepare() 以完成其內(nèi)部準(zhǔn)備工作;

4、調(diào)用 recorder_->Start() 啟動(dòng)錄像;

5、初始化共享內(nèi)存、分辨率等,以實(shí)現(xiàn)預(yù)覽;



PrepareRecorder() 中僅調(diào)用 SampleCreateRecorder() 和 SampleGetRecordFd(),

002-2.jpg (90.64 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

其中 SampleGetRecordFd() 所作工作相對(duì)簡單:創(chuàng)建錄像文件以備存儲(chǔ)壓縮編碼后數(shù)據(jù)流;

重心在 SampleCreateRecorder() 上,



003.jpg (187.27 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

004.jpg (193.09 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

其內(nèi)部首先 new 一個(gè) Recorder 實(shí)例,然后對(duì)該實(shí)例進(jìn)行一系列的設(shè)置,所調(diào)用這些設(shè)置接口實(shí)際上是由類Recorder 的內(nèi)部實(shí)現(xiàn)類 RecorderImpl 來實(shí)現(xiàn),而稍后所調(diào)用實(shí)例recorder_的一系列函數(shù),其內(nèi)均出自RecorderImpl,接下來詳細(xì)分析該類。



005.jpg (196.24 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

由圖中代碼可知,類Recorder 的實(shí)現(xiàn)類 RecorderImpl 完成了所有工作,該類內(nèi)部持有兩個(gè)重要成員:

     SourceManager sourceManager_[RECORDER_SOURCE_MAX_CNT];

     RecorderSink *recorderSink_;

先看類 RecorderSink:



006.jpg (122.63 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

007.jpg (168.28 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

008.jpg (170 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

類 RecorderSink 完成 底層 muxer 的一系列操作,并將數(shù)據(jù)混合后輸出至錄像文件中保存。



再看 結(jié)構(gòu)體 SourceManager:



010.jpg (77.57 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

SourceManager 中包含 RecorderVideoSource 和 RecorderaudioSource,來完成視頻和音頻的相關(guān)的操作,并記錄其Recorder狀態(tài)。以視頻Video為例,在設(shè)置 video 相關(guān)參數(shù)時(shí),可以看到對(duì) sourceManager_ 數(shù)組的操作:



011.jpg (232.63 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳



回到 applications/sample/camera/media/camera_sample.cpp 文件的 StartRecord() 函數(shù)中,其調(diào)用的 recorder_->Prepare() 和 recorder_->Start() 對(duì)應(yīng)到 類 RecorderImpl 中:

在 Prepare() 中,分別 prepare 了 recorderSink_、VideoSource、AudioSource,在此仍以 video 為例追蹤,   



012.jpg (107.83 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳



013.jpg (152.28 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

在 Start() 中,分別啟動(dòng)了 recorderSink_、VideoSource、AudioSource,在此仍以 video 為例追蹤,



014.jpg (146.24 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳



015.jpg (105.41 KB, 下載次數(shù): 0)

下載附件  保存到相冊(cè)  

1 小時(shí)前 上傳

在 StartVideoSource 中,啟動(dòng)視頻源并通過std::thread()創(chuàng)建一個(gè)視頻源處理線程。



最后可以看到,在創(chuàng)建的線程 VideoSourceProcess 中,通過 while () 循環(huán)不斷的寫入格式后的數(shù)據(jù)到錄像文件。

至此,Record 的底層框架及調(diào)用流程已然明了。

發(fā)表回復(fù)

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表