接上一篇继续探究分析鸿蒙系统的媒体子系统,上回说到 CameraDevice类,现在继续。
先把上篇做的那张类图贴出来以便我们分析。
类 CameraDevice中有一个初始化方法 Initialize(), 该方法是在 CameraService::Initialize() 中(通过调用 CameraService::InitCameraDevices())被调用,
而 CameraService::Initialize() 是在 CameraManagerImpl(即 CameraManager 的实现类)的构造函数中被调用的。
那么何时创建 CameraManager 实例的呢?找到创建该实例的地方,也就了解了何时进行的一系列的初始化动作。
回到 applications/sample/camera/media/camera_sample.cpp 文件的 main() 中:
跳转到 CameraKit::GetInstance()中,可以看到该函数最终触发了 CameraKit 类的构造函数的调用并在其中调用了 CameraManager::GetInstance(),至此形成闭环——即:类 CameraManager 的实例通过其内部聚合的CameraDevice 实例 device_ 来操作HAL层或底层接口。
PS. 结合类图分析更清晰。
接下来回看 CameraDevice::Initialize() :
可以看到,其内部调用了hal层的一些封装接口,重要的是还初始化了底层的音频与视频 Codec。
最后把三个“助手”的状态赋值为了 LOOP_READY,即就绪态。
接下分析一下这三个“助手”。
进入到类 CameraDevice 的声明中,其中有三个成员:
RecordAssistant recordAssistant_;
PreviewAssistant previewAssistant_;
CaptureAssistant captureAssistant_;
xxxAssistant,即 xxx 助手,分别实现录像、预览、拍照功能。
由继承关系可以,这三个“助手”均继承自类 DeviceAssistant —— 这是很简单的基类,只有三个函数需要子类按需实现:
virtual int32_t SetFrameConfig(FrameConfig &fc, std::vector<HalProcessorHdl> &hdls, std::vector<HalVideoProcessorAttr> &attrs);
virtual int32_t Start();
virtual int32_t Stop();
以CaptureAssistant为例来分析:
这些函数均是完成一些底层硬件的配置与启停操作以及相应的状态改变,另外涉及共享内存 Surface 方面的操作。
分析到这里,会发现CameraDevice类的内部还剩余为数不多的几个函数,这些函数同样涉及一些底层硬件的配置等,现在问题变得简单起来了,我们只需要找到其调用主线就一目了然了。
对于TriggerLoopingCapture() ,是不是似曾相识?是的,就在 applications/sample/camera/media/camera_sample.cpp 文件的 main() 中,
当调用 StartRecord() 或 StartPreview() 时,其内部就是调用了 TriggerLoopingCapture()。
在 TriggerLoopingCapture() 中,会根据不同的 FrameConfig 来使用不同的 Assistant 来做出 capture 动作。
至此,媒体子体系的框架主线分析完毕,但其中涉及的多个小的辅助类,同样值得我们深入去探究。