[文章]

【HarmonyOS HiSpark AI Camera试用连载】鸿蒙系统之媒体子系统——Recorder(续)

2021-1-27 09:41:59  150 HarmonyOS
分享
0
接上篇继续分析 鸿蒙系统媒体子系统的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
可以看到赋值语句:
    sourceManager_[sourceId].videoSource = new RecorderVideoSource();
在类 RecorderVideoSource 中,主要完成一些共享内存 SuRFace,缓冲区查询、请求、释放等操作。
020.jpg

回到 applications/sample/camera/media/camera_sample.cpp 文件的 StartRecord() 函数中,其调用的 recorder_->Prepare() 和 recorder_->Start() 均可对应到 类 RecorderImpl 中:
在 Prepare() 中,分别 prepare 了 recorderSink_、VideoSource、AudioSource,
012.jpg
在此仍以 video 为例追踪,可以看到其完成 video source 相关工作。
013.jpg

在 Start() 中,分别启动了 recorderSink_、VideoSource、AudioSource,
014.jpg
在此仍以 video 为例追踪,
015.jpg
调用 recorderSink_->Start() 即前文提到的 将数据格式化后输出至录像文件中保存。
调用 StartVideoSource(),在其中:
首先调用 sourceManager_.videoSource->Start() 对数组中对应的 RecorderVideoSource 实例作启动(内部实际仅改变其状态);
接着通过
    sourceManager_.videoProcessThread = std::thread(VideoSourceProcess, &sourceManager_, recorderSink_);
创建一个视频源处理线程,则接下来的工作有该线程去完成。
016.jpg
在线程的执行体函数 VideoSourceProcess 的 while 循环中,
调用
    videoSourceManager->videoSource->AcquireBuffer(buffer, true);
实现请求 buffer(即调用类 RecorderVideoSource 中的函数);
调用
    videoSourceManager->videoSource->AcquireBuffer(buffer, true);
实现写入格式后的数据到录像文件(即调用类 RecorderSink 中的 WriteData()函数)。

至此,Recorder 的底层框架及调用流程已然明了。

评论

您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发文章
快速回复 返回顶部 返回列表