|
【HarmonyOS HiSpark AI Camera试用连载】鸿蒙系统之媒体子系统Record, 之前分析了媒体子系统的主要框架,另外其中涉及的几个辅助类,这些类调用了一些封装的底层接口以帮助应用层开发者快速开发。
在应用层,applications/sample/camera/media/camera_sample.cpp 文件的 main() 函数中,我们以Record为例对其主线进行分析。
001.jpg (109.7 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
- 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;
复制代码
首先看调用 StartRecord(),
002.jpg (156.87 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
在 StartRecord() 中可以看到其所做的工作如下:
1、调用 PrepareRecorder() 即做一些准备工作:其中包括:创建 真正的(狭义的)Recorder,创建录像文件;
2、调用 recorder_->SetOutputFile() 设置(传递)录像文件的文件描述符;
3、调用 recorder_->Prepare() 以完成其内部准备工作;
4、调用 recorder_->Start() 启动录像;
5、初始化共享内存、分辨率等,以实现预览;
PrepareRecorder() 中仅调用 SampleCreateRecorder() 和 SampleGetRecordFd(),
002-2.jpg (90.64 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
其中 SampleGetRecordFd() 所作工作相对简单:创建录像文件以备存储压缩编码后数据流;
重心在 SampleCreateRecorder() 上,
003.jpg (187.27 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
004.jpg (193.09 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
其内部首先 new 一个 Recorder 实例,然后对该实例进行一系列的设置,所调用这些设置接口实际上是由类Recorder 的内部实现类 RecorderImpl 来实现,而稍后所调用实例recorder_的一系列函数,其内均出自RecorderImpl,接下来详细分析该类。
005.jpg (196.24 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
由图中代码可知,类Recorder 的实现类 RecorderImpl 完成了所有工作,该类内部持有两个重要成员:
SourceManager sourceManager_[RECORDER_SOURCE_MAX_CNT];
RecorderSink *recorderSink_;
先看类 RecorderSink:
006.jpg (122.63 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
007.jpg (168.28 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
008.jpg (170 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
类 RecorderSink 完成 底层 muxer 的一系列操作,并将数据混合后输出至录像文件中保存。
再看 结构体 SourceManager:
010.jpg (77.57 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
SourceManager 中包含 RecorderVideoSource 和 RecorderaudioSource,来完成视频和音频的相关的操作,并记录其Recorder状态。以视频Video为例,在设置 video 相关参数时,可以看到对 sourceManager_ 数组的操作:
011.jpg (232.63 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
回到 applications/sample/camera/media/camera_sample.cpp 文件的 StartRecord() 函数中,其调用的 recorder_->Prepare() 和 recorder_->Start() 对应到 类 RecorderImpl 中:
在 Prepare() 中,分别 prepare 了 recorderSink_、VideoSource、AudioSource,在此仍以 video 为例追踪,
012.jpg (107.83 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
013.jpg (152.28 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
在 Start() 中,分别启动了 recorderSink_、VideoSource、AudioSource,在此仍以 video 为例追踪,
014.jpg (146.24 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
015.jpg (105.41 KB, 下载次数: 0)
下载附件 保存到相册
1 小时前 上传
在 StartVideoSource 中,启动视频源并通过std::thread()创建一个视频源处理线程。
最后可以看到,在创建的线程 VideoSourceProcess 中,通过 while () 循环不断的写入格式后的数据到录像文件。
至此,Record 的底层框架及调用流程已然明了。 |
|