|
【HarmonyOS HiSpark AI Camera试用连载】鸿蒙系统之媒体子系统——Recorder(续), 接上篇继续分析 鸿蒙系统媒体子系统的Recorder部分。
再来分析类 RecorderImpl 的另一个成员,一个数组:
SourceManager sourceManager_[RECORDER_SOURCE_MAX_CNT];
且看结构体 SourceManager:
struct SourceManager {
RecorderVideoSource *videoSource; // 视频缓冲区管理
bool videoSourceStarted; // 视频启动状态
bool videoSourcePaused; // 视频暂停状态
int32_t videoTrackId;
std::thread videoProcessThread; // 视频处理线程
RecorderaudioSource *audioSource; // 音频缓冲区管理
bool audioSourceStarted; // 音频启动状态
bool audioSourcePaused; //音频暂停状态
int32_t audioTrackId;
std::thread audioProcessThread; // 音频处理线程
RecorderVideoSourceConfig videoSourceConfig;
RecorderAudioSourceConfig audioSourceConfig;
};
SourceManager 中包含 RecorderVideoSource 和 RecorderAudioSource,来完成视频和音频的相关的操作,并记录其Recorder状态。
类 RecorderImpl 的成员 sourceManager_ 数组在上层调用以下系列接口时被逐步的初始化:
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为例,在设置 video 相关参数时,可以看到对 sourceManager_ 数组的操作:
011.jpg (232.63 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
可以看到赋值语句:
sourceManager_[sourceId].videoSource = new RecorderVideoSource();
在类 RecorderVideoSource 中,主要完成一些共享内存 SuRFace,缓冲区查询、请求、释放等操作。
020.jpg (121.37 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
回到 applications/sample/camera/media/camera_sample.cpp 文件的 StartRecord() 函数中,其调用的 recorder_->Prepare() 和 recorder_->Start() 均可对应到 类 RecorderImpl 中:
在 Prepare() 中,分别 prepare 了 recorderSink_、VideoSource、AudioSource,
012.jpg (107.83 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
在此仍以 video 为例追踪,可以看到其完成 video source 相关工作。
013.jpg (152.28 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
在 Start() 中,分别启动了 recorderSink_、VideoSource、AudioSource,
014.jpg (146.24 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
在此仍以 video 为例追踪,
015.jpg (105.41 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
调用 recorderSink_->Start() 即前文提到的 将数据格式化后输出至录像文件中保存。
调用 StartVideoSource(),在其中:
首先调 用 sourceManager_.videoSource->Start() 对数组中对应的 RecorderVideoSource 实例作启动(内部实际仅改变其状态);
接着通过
sourceManager_.videoProcessThread = std::thread(VideoSourceProcess, &sourceManager_, recorderSink_);
创建一个视频源处理线程,则接下来的工作有该线程去完成。
016.jpg (227.91 KB, 下载次数: 0)
下载附件 保存到相册
2 小时前 上传
在线程的执行体函数 VideoSourceProcess 的 while 循环中,
调用
videoSourceManager->videoSource->AcquireBuffer(buffer, true);
实现请求 buffer(即调用类 RecorderVideoSource 中的函数);
调用
videoSourceManager->videoSource->AcquireBuffer(buffer, true);
实现写入格式后的数据到录像文件(即调用类 RecorderSink 中的 WriteData()函数)。
至此,Recorder 的底层框架及调用流程已然明了。 |
|