Gstreamer 学习笔记(10):Gstvideodecoder

一、简介

GstVideoDecoder是gstreamer提供的视频解码元件的父类(基类)元件,以方便开发者封装自己的video decoder为gstreamer的插件。当然,它也是继承自gstreamer元件的基类GstElement。

注:这里同样是以gstreamer 1.14.0为蓝本

二、结构体GstVideoDecoder

结构体GstVideoDecoder是video decoder元件“类”的属性部分,其定义如下:

**
* GstVideoDecoder:
*
* The opaque #GstVideoDecoder data structure.
*/
struct _GstVideoDecoder
{
	/*< private >*/
	GstElement     element; /** 基类 */
	
	/*< protected >*/
	GstPad  *sinkpad;  /** video decoder元件的输入衬垫 */
	GstPad  *srcpad;   /**  video 元件的输出衬垫 */
	
	/* protects all data processing, i.e. is locked
	* in the chain function, finish_frame and when
	* processing serialized events */
	GRecMutex stream_lock; /** 数据处理流程的 互斥锁 */
	
	/* MT-protected (with STREAM_LOCK) */
	GstSegment      input_segment; /** */
	GstSegment      output_segment;
	
	GstVideoDecoderPrivate *priv; /** video decoder基类的私有结构体 */
	
	/*< private >*/
	void             *padding[GST_PADDING_LARGE];
};

上面代码中的GstSegment的资料可见官方文档:

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstSegment.html

以下是文中对其的描述:

This helper structure holds the relevant values for tracking the region of interest in a media file, called a segment.

The structure can be used for two purposes:

  • performing seeks (handling seek events)
  • tracking playback regions (handling newsegment events)

基本上就是处理seek 事件和追踪播放区域的,按我的理解,就是表示一个媒体文件的片段(不保证理解正确)

三、结构体GstVideoDecoderClass

这个结构体就是video decoder“基”类的 成员方法部分,其定义如下:

struct _GstVideoDecoderClass
{
	/*< private >*/
	GstElementClass element_class;
	
	/*< public >*/
	gboolean      (*open) (GstVideoDecoder *decoder);
	
	gboolean      (*close) (GstVideoDecoder *decoder);
	
	gboolean      (*start) (GstVideoDecoder *decoder);
	
	gboolean      (*stop) (GstVideoDecoder *decoder);
	
	GstFlowReturn (*parse)(GstVideoDecoder *decoder,
							GstVideoCodecFrame *frame,
							GstAdapter *adapter,
							gboolean at_eos);
	
	gboolean   (*set_format) (GstVideoDecoder *decoder, GstVideoCodecState * state);
	
	gboolean   (*reset)  (GstVideoDecoder *decoder, gboolean hard);
	
	GstFlowReturn (*finish)  (GstVideoDecoder *decoder);
	
	GstFlowReturn (*handle_frame)(GstVideoDecoder *decoder, GstVideoCodecFrame *frame);
	
	gboolean   (*sink_event) (GstVideoDecoder *decoder, GstEvent *event);
	
	gboolean    (*src_event) (GstVideoDecoder *decoder, GstEvent *event);
	
	gboolean    (*negotiate)(GstVideoDecoder *decoder);
	
	gboolean (*decide_allocation)  (GstVideoDecoder *decoder, GstQuery *query);
	
	gboolean (*propose_allocation) (GstVideoDecoder *decoder, GstQuery * query);
	
	gboolean (*flush)  (GstVideoDecoder *decoder);
	
	gboolean (*sink_query) (GstVideoDecoder *decoder, GstQuery *query);
	
	gboolean  (*src_query) (GstVideoDecoder *decoder, GstQuery *query);
	
	GstCaps*  (*getcaps) (GstVideoDecoder *decoder, GstCaps *filter);
	
	GstFlowReturn (*drain)  (GstVideoDecoder *decoder);
	
	gboolean(*transform_meta) (GstVideoDecoder *decoder, GstVideoCodecFrame *frame, GstMeta * meta);
	
	/*< private >*/
	void         *padding[GST_PADDING_LARGE-6];
};

成员方法的数量还是比较多的,具体的用途可以查看源码或者官方的参考手册,和GstVideoDecoder结构体一样,GstVideoDecoderClass也是继承自gstreamer中element基类,这里是成员方法结构体,所以它继承自GstElementClass。

GstVideoDecoderClass结构体中提供的都是public类型的“虚函数”(函数指针),在实现自己的video decoder element 时,可以根据实际需要部分或全部的 继承或覆盖这些虚函数。

四、video decoder element的工作流程

video decoder element仍然是基于gstreamer最基本的GstElement,所以在上层行为与运行流程还是表现为正常的element的行为。前面已经说到过元件的状态以及状态之间的转变行为了,那么这里就基于前面提到的东西进一步论述。

4.1 GstVideoDecoder的基本结构

说到底GstVideoDecoder就是一个GstElement,所以它的结果和GstElement一样,就一般来说Decoder会有一个输入和一个输出,也就是说GstVideoDecoder类似一个filter。

在这里插入图片描述

如图所示,蓝色部分是decoder元件的主体,绿色部分是decoder的输入输出衬垫(pad)

4.2 video decoder element的接口说明

首先来看一下GstVideoDecoder的成员方法的功能,被调用的位置以及什么时候被调用(调用时机)

  • open【可选】

    • 功能:允许子类打开外部资源(如第三方library)
    • 被调用位置:gst_video_decoder_change_state
    • 调用时机:GST_STATE_CHANGE_NULL_TO_READY
  • close【可选】

    • 功能:允许子类关闭外部资源(如第三方library)
    • 被调用位置:gst_video_decoder_change_state
    • 调用时机:GST_STATE_CHANGE_READY_TO_NULL
  • start【可选】

    • 功能:允许子类打开外部资源(如第三方library)
    • 被调用位置:gst_video_decoder_change_state
    • 调用时机: GST_STATE_CHANGE_READY_TO_PAUSED
  • stop【可选】

    • 功能:允许子类关闭外部资源(如第三方library)
    • 被调用位置:gst_video_decoder_change_state
    • 调用时机: GST_STATE_CHANGE_PAUSED_TO_READY
  • parse【当需要支持输入流为非完整帧时需要】

    • 功能:将输入流重组或拆分为完整帧
    • 被调用位置: gst_video_decoder_parse_available
    • 调用时机: 如果使用gst_video_decoder_set_packetized方法将decoder的priv的成员packetized设置为FALSE(默认值为TRUE)之后,当有数据流过decoder元件时,gst_video_decoder_parse_available将会被调用。
    • 注意:子类在将packetized设置为FALSE之后,需要实现decoder基类的parse方法,并且在parse方法中,当已经parse到一个完整帧之后,需要手动调用gst_video_decoder_have_frame接口驱动GstVideoDecoder进行解码。
  • set_format 【必须】

    • 功能: 告诉子类输入流数据格式
    • 被调用位置: gst_video_decoder_setcaps
    • 调用时机: 当上游element发出了GST_EVENT_CAPS 事件时被调用
  • reset 【可选】【Deprecated】

    • 功能: 允许子类在seek时复位decoder
    • 被调用位置: gst_video_decoder_flush
    • 调用时机: 收到事件GST_EVENT_FLUSH_STOPGST_EVENT_STREAM_START逆向播放
  • finish 【可选】

    • 功能: 请求子类处理decoder中的剩余数据,当本操作执行之后子类可以拒绝解码新数据
    • 被调用位置: gst_video_decoder_drain_out、gst_video_decoder_flush_parse
    • 调用时机:收到事件 GST_EVENT_SEGMENT_DONE,GST_EVENT_EOS或逆向播放时
  • drain 【可选】【Since : 1.6(version)】

    • 功能: 请求之类将其内部的数据解码完,在这之后可能会有更多的新数据到来,子类需要做好准备。
    • 被调用位置: gst_video_decoder_drain_outgst_video_decoder_flush_parse
    • 调用时机: 收到事件GST_EVENT_STREAM_STARTGST_EVENT_GAPGST_EVENT_CUSTOM_DOWNSTREAM逆向播放
  • sink_event 【可选】

    • 功能: 处理sink pad收到的事件,如果decoder元件能够处理该事件,那就需要返回TRUE并丢弃当前事件,子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_sink_event
    • 调用时机: 当收到上游事件
  • src_event 【可选】

    • 功能: 处理source pad收到的事件,如果decoder元件能够处理该事件,那就需要返回TRUE并丢弃当前事件,子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_src_event
    • 调用时机: 当收到下游事件
  • handle_frame 【必须】

    • 功能: 提供输入的帧数据到子类(子类可以在这个实现中进行具体的解码动作)
    • 被调用位置: gst_video_decoder_decode_frame
    • 调用时机: 当有数据需要解码时(顺播,flush等)
  • negotiate 【可选】

    • 功能: 与下游元件协助和配置buffer pool等等,子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_negotiategst_video_decoder_negotiate_unlocked
    • 调用时机: 与下游元件协商当前的配置或者当某些信息发生变化需要重配置
  • decide_allocation 【可选】

    • 功能: 设置分配输出buffer的分配器的参数,传入的query参数包含有对下游元件的分配器的信息。子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_negotiate_pool
    • 调用时机: 在negotiate接口被调用
  • propose_allocation 【可选】

    • 功能: 为上游元件提供分配器的建议参数。子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_sink_query_default
    • 调用时机: 当收到上游元件的GST_QUERY_ALLOCATION查询命令时
  • flush 【可选】【Since: 1.2(version)】

    • 功能:清掉decoder中剩余的数据,但不会推送到下游元件
    • 被调用位置: gst_video_decoder_flush
    • 调用时机: 收到事件GST_EVENT_FLUSH_STOPGST_EVENT_STREAM_START逆向播放
  • sink_query 【可选】【Since: 1.4(version)】

    • 功能:处理sink pad收到的查询命令,当元件能够处理这个查询命令时需要返回TRUE,子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_sink_query
    • 调用时机: 当sink pad收到查询命令
  • src_query 【可选】【Since: 1.4(version)】

    • 功能:处理src pad收到的查询命令,当元件能够处理这个查询命令时需要返回TRUE,子类实现中需要调用父类的默认实现
    • 被调用位置: gst_video_decoder_src_query
    • 调用时机: 当src pad收到查询命令
  • getcaps 【可选】

    • 功能:允许自定义sink的getcaps实现,如果子类没实现将会调用gst_video_decoder_proxy_getcaps接口
    • 被调用位置: gst_video_decoder_sink_getcaps
    • 调用时机: 当收到上游的GST_QUERY_CAPS查询命令时
  • transform_meta 【可选】【Since 1.6(version)】

    • 功能:将输入buffer中的元数据转换到输出buffer当中,默认情况下这个方法只会复制输入buffer中所有的元数据(不会复制标签),转换到输出buffer当中变成唯一的标签“video”
    • 被调用位置: gstvideodecoder.c中的foreach_metadata
    • 调用时机: 当有一个解码后的视频帧需要推入下游元件时(gst_video_decoder_finish_frame

4.3 GstVideoDecoder运行时序

在这里插入图片描述

因为有不少事件或者接口调用会发生在不同的运行情况上(如元件的实现,具体码流或者下播放流程控制等因素),所以上图只是GstVideoDecoder简要的运行时序。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值