一、 简介
多媒体播放框架主要的实现在PlayerServer服务中,这个服务提供了媒体播放框架所需要的实现环境,继续跟踪代码分析发现,PlayerServer主要通过gstreamer适配层,对gstreamer进行调用。gstreamer属于更加具体的实现,所以本篇文章主要是分析PlayerServer通过适配层调用到gstreamer的过程。
本篇主要分析了多媒体gstreamer的调用,涉及到从PlayerServer到gstreamer的整体流程。
二、 目录
gstreamer
├── BUILD.gn
├── common
│ ├── BUILD.gn
│ ├── playbin_adapter
│ │ ├── i_playbin_ctrler.h
│ │ ├── playbin2_ctrler.cpp
│ │ ├── playbin2_ctrler.h
│ │ ├── playbin_ctrler_base.cpp
│ │ ├── playbin_ctrler_base.h
│ │ ├── playbin_msg_define.h
│ │ ├── playbin_sink_provider.h
│ │ ├── playbin_state.cpp
│ │ ├── playbin_state.h
│ │ ├── playbin_task_mgr.cpp
│ │ └── playbin_task_mgr.h
│ ├── state_machine
│ │ ├── state_machine.cpp
│ │ └── state_machine.h
├── factory
│ ├── BUILD.gn
│ └── engine_factory.cpp
└── player
├── BUILD.gn
├── player_codec_ctrl.cpp
├── player_codec_ctrl.h
├── player_engine_gst_impl.cpp
├── player_engine_gst_impl.h
├── player_sinkprovider.cpp
├── player_sinkprovider.h
├── player_track_parse.cpp
└── player_track_parse.h
目录主要是多媒体子系统中的engine部分,涉及到了gstreamer的适配层,gstreamer具体的实现是在third_party/gstreamer目录中。
三 、Gstreamer介绍
1. 简介
Gstreamer是一个跨平台的多媒体框架,应用程序可以通过管道(Pipeline)的方式,将多媒体处理的各个步骤串联起来,达到预期的效果。每个步骤通过元素(Element)基于GObject对象系统通过插件(plugins)的方式实现,方便了各项功能的扩展。

2.Gstreamer几个重要的概念
Element
Element是Gstreamer中最重要的对象类型之一。一个element实现一个功能(读取文件,解码,输出等),程序需要创建多个element,并按顺序将其串联起来,构成一个完整的Pipeline。
Pad
Pad是一个element的输入/输出接口,分为src pad(生产数据)和sink pad(消费数据)两种。
两个element必须通过pad才能连接起来,pad拥有当前element能处理数据类型的能力(capabilities),会在连接时通过比较src pad和sink pad中所支持的能力,来选择最恰当的数据类型用于传输,如果element不支持,程序会直接退出。在element通过pad连接成功后,数据会从上一个element的src pad传到下一个element的sink pad然后进行处理。
Bin和Pipeline
Bin是一个容器,用于管理多个element,改变bin的状态时,bin会自动去修改所包含的element的状态,也会转发所收到的消息。如果没有bin,我们需要依次操作我们所使用的element。通过bin降低了应用的复杂度。
Pipeline继承自bin,为程序提供一个bus用于传输消息,并且对所有子element进行同步。当将Pipeline的状态设置为PLAYING时,Pipeline会在一个/多个新的线程中通过element处理数据。
四、调用流程

五、源码分析
1. PrepareAsync分析
首先,在PlayerServer的PrepareAsync中会调用OnPrepare(false),具体是在OnPrepare(false)中实现,参数传入false,表明调用的是异步方法。
int32_t PlayerServer::PrepareAsync()
{
std::lock_guard<std::mutex> lock(mutex_);
MEDIA_LOGW("KPI-TRACE: PlayerServer PrepareAsync in");
if (lastOpStatus_ == PLAYER_INITIALIZED || lastOpStatus_ == PLAYER_STOPPED) {
return OnPrepare(false);
} else {
MEDIA_LOGE("Can not Prepare, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
return MSERR_INVALID_OPERATION;
}
}
OnPrepare方法中,先通过playerEngine_调用SerVideoSurface的方法,将surface_设置到PlayerEngineGstImpl中(producerSurface_),接着启动一个任务,调用目前状态的Prepare()方法。
int32_t PlayerServer::OnPrepare(bool sync)
{
CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
int32_t ret = MSERR_OK;
#ifdef SUPPORT_VIDEO
if (surface_ != nullptr) {
ret = playerEngine_->SetVideoSurface(surface_);
CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine SetVideoSurface Failed!");
}
#endif
lastOpStatus_ = PLAYER_PREPARED;
auto preparedTask = std::make_shared<TaskHandler<int32_t>>([this]() {
MediaTrace::TraceBegin("PlayerServer::PrepareAsync", FAKE_POINTER(this));
auto c
OpenHarmonyPlayerServer中gstreamer调用深度解析

最低0.47元/天 解锁文章
1146

被折叠的 条评论
为什么被折叠?



