OpenHarmony 3.2 Beta多媒体系列——音视频播放gstreamer

一、 简介

多媒体播放框架主要的实现在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值