[经验分享] OpenHarmony4.0源码解析之媒体框架 原创

深开鸿_王奎 显示全部楼层 发表于 2024-1-3 14:15:11

OpenHarmony4.0 源码解析之媒体框架

作者:王奎

媒体框架简介

媒体框架 multimedia_player_framework主要提供音视频的录制与播放功能。

框架简介

catalogs.png

architecture.png

从框架图中可以看出,媒体框架的主要工作模式为通过Gstreamer的插件自动化注册及插件组合功能,将其余媒体播放相关的框架功能插件化,配合Gstreamer自身丰富的插件,共同来对外提供音视频的录制与播放功能。如通过audio-sink及audio-source插件调用音频框架的播放及采集功能来实现音频的播放与录制;通过surface-sink调用图形框架,video-decoder调用解码驱动模块实现视频的硬解播放等。

Gstreamer基本概念

Gstreamer是媒体框架中的重要组成部分,采用基于插件(plugin)和管道(pipeline)的体系结构,框架中的所有的功能模块都被实现成可以插拔的组件(plugin),能够很方便地安装到任意管道上。插件架构是GStreamer的核心,几乎所有的媒体处理功能都可以抽象成为插件的一部分。

gstreamer1.png

以一个图中完整的ogg播放流程为例: GStreamer内部使用pipeline(管线)机制来做信令控制,元素组件管理和数据传输,一个pipeline内部存在多个element(元素),每个元素内部存在输入和输出的端口(pad);<br />解码流程具体为 ogg文件源source经过解封装器demuxer产生vorbis编码的数据流,之后经过解码器decoder解码为浮点float格式的raw数据,浮点raw数据通过转换器转换为整形raw数据,最后通过输出sink完成音频信号输出。虚线下面的标注为经过每个pad的输入格式和输出格式。<br />GStreamer定义了以下元素概念:

gstreamer2.png

Source:可以理解为数据源,也就是数据流的起始地。例如文件,网络源,摄像机麦克风的输入。

gstreamer3.png

Filter: 过滤器, 也可理解为中间处理单元,将 sink pad传入的数据经过内部处理通过src pad传出。编解码器,封装/解封装都可以认为是Filter。有人可能会与Ffmpeg的filter相混淆,Ffmpeg中Filter定义为处理原始数据(解码后数据的)的功能单元。提供音视频后处理功能。Gstreamer中Filter更强调同时存在输入和输出的概念,功能的范围更大一些。

gstreamer4.png

Sink:数据接受者,source产生的数据流最终要流向的地方。例如输出文件,屏幕显示,扬声器输出。

gstreamer5.png

Bin: 与pipeline类似,它们的区别为pipeline肯定是一个bin,但bin不一定是pipeline,它就像一个盒子,存放了多个元素,实现了部分甚至完整的由source到sink的流程。Bin提供了软总线Bus用于处理内部产生的信号(这些消息包括:错误消息(error messages),卷标消息(tag messages),EOS消息(EOS messages))。PipeLine: pipeline是高级的Bin。当你设定管道的暂停或者播放状态的时候,数据流将开始流动,并且媒体数据处理也开始处理。一旦开始,管道将在一个单独的线程中运行,直到被停止或者数据流播放完毕。

音视频播放流程

1.视频播放流程如下:

player_workflow.jpg

2.视频播放的接口调用时序图如下:播放器在设置播放源时,完成Gstreamer engine的加载,在prepare时 完成对于gsreamer playbin的初始化,后续的播放,暂停等接口都是通过控制Gstreamer playbin的状态来控制播放流。

player_calls.png

音视频录制流程

1.音视频录制流程如下:

recorder_workflow.jpg

2.音视频录制接口调用时序图如下:以音频录制为例,用户在调用prepare接口时,会依次设置音频源,音频输出格式,以及音频配置参数和音频输出路径,在基本配置完成后,才会形成音频录制的pipeline,与播放器不同,该pipeline为框架自定义。在音频录制的pipeline形成后,即可通过recorderPipeline的状态来控制录制流。

recorder_calls.png

媒体框架4.0新增能力

1 ScreenCapture

ScreenCapture为屏幕采集模块,提供屏幕画面采集及音频采集功能。主要提供如下接口:

class ScreenCapture {
public:
    virtual ~ScreenCapture() = default;
    virtual int32_t Init(AVScreenCaptureConfig config) = 0;
    virtual int32_t SetMicrophoneEnabled(bool isMicrophone) = 0;
    virtual int32_t StartScreenCapture() = 0;
    virtual int32_t StopScreenCapture() = 0;
    virtual int32_t AcquireAudioBuffer(std::shared_ptr<AudioBuffer> &audiobuffer, AudioCaptureSourceType type) = 0;
    virtual sptr<OHOS::SurfaceBuffer> AcquireVideoBuffer(int32_t &fence, int64_t &timestamp, Rect &damage) = 0;
    virtual int32_t ReleaseAudioBuffer(AudioCaptureSourceType type) = 0;
    virtual int32_t ReleaseVideoBuffer() = 0;
    virtual int32_t Release() = 0;
    virtual int32_t SetScreenCaptureCallback(const std::shared_ptr<ScreenCaptureCallBack> &callback) = 0;
};

从提供的结构体AVScreenCaptureConfig来看,主要采集类型如下:CaptureMode : 采集模式包括了主屏幕、特定屏幕(暂不支持)、特定窗口(暂不支持)采集;DataType : 数据类型包括原始流,编码流(暂不支持)和文件(暂不支持);AudioInfo : 音频信息包括对采样率,采样格式以及音频源的设置。音频源支持麦克风以及系统内部音源;VideoInfo : 视频信息主要包括分辨率以及视频源类型,视频源类型主要为yuv(暂不支持),es流(暂不支持),rgba;

struct AVScreenCaptureConfig {
    CaptureMode captureMode;
    DataType dataType;
    AudioInfo audioInfo;
    VideoInfo videoInfo;
    RecorderInfo recorderInfo;
};

音视频数据的流转如下图,分别存在音频和视频数据的缓存队列,通过bufferavailable来通知用户可用buffer,用户可通过acquireBuffer和releaseBuffer来获取和删除音视频数据

screen_capture.png

2 SoundPool

SoundPool为音频池管理模块,提供集中管理多个音频资源的功能。该框架实际并未经过媒体框架的IPC,而是在client端直接调用了音频解码器和音频渲染器。

SoundPool通过SoundIdManager来管理SoundParser获取音频流解码数据,通过StreamIdManager来管理CacheBuffer控制音频流的播放,加载资源及播放的调用流程如下:

sound_pool_calls.png

3 Monitor

媒体框架的播放及录制client 与 stub分别通过继承MonitorClientObject,MonitorServerObject来实现对于媒体播放录制运行状态的监控。client在开始播放或者录制后每隔1s向server端发送click指令,Server端每隔1.5s检查对应的client是否过长时间未发送指令,若出现异常,则调用暂停命令,否则调用恢复播放指令。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部