gstreamer插件特别要注意事件处理(含代码范例)

  因为工作需要,同事写了一个Transform插件,吾写了一个 Sink插件。结果吾在测试的时候,发现数据流结束了,流程一直无法正常结束。再网上反复搜索,连蒙带猜的折腾了一番,还是不行。

  昨天发现显存无法正常释放,今天在查找原因。先将两个插件从流程中删除,发现可以正常结束。加上Transform就不能正常结束了。原来问题出在这个插件上这里……于是又开始连蒙带猜……

  老兄,咱玩编程,好歹也算是搞科研了,汝这样天天连蒙带猜的,这不是事啊,这能靠谱吗?

  吾亦知道有点那个(哪个?),那汝可有好办法?实际上搞科研,开始的时候不都是这样嘛。

  所以每次解决问题,吾都喜欢公布解决办法,希望其他人能够顺利一些。

 

SINK插件的事件处理代码:

static gboolean gh_gstsink_event(GstBaseSink *sink, GstEvent *event)
{
    GstElement* element = (GstElement*)sink;
    GhGstSink*  ghsink  = (GhGstSink*) sink;

    switch(event-> type)
    {
        case GST_EVENT_EOS:
            break;

        case GST_EVENT_FLUSH_START:
        case GST_EVENT_FLUSH_STOP:
        default:
            break;
    }

    //关键代码。最关键的就是遇到GST_EVENT_EOS要如此调用。
    return GST_BASE_SINK_CLASS(parent_class)->event(sink, event);
}

static void gh_gstsink_class_init (GhGstSinkClass * klass)
{
  GObjectClass     *gobject_class    = (GObjectClass     *) klass;
  GstElementClass  *gstelement_class = (GstElementClass  *) klass;
  GstBaseSinkClass *gstbasesink_class= (GstBaseSinkClass *) klass;

  /* Overide base class functions */
 //代码对齐,看起来很漂亮专业吧。
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gh_gstsink_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gh_gstsink_get_property);

  gstbasesink_class->render   = GST_DEBUG_FUNCPTR (gh_gstsink_render);
  gstbasesink_class->start    = GST_DEBUG_FUNCPTR (gh_gstsink_start);
  gstbasesink_class->stop     = GST_DEBUG_FUNCPTR (gh_gstsink_stop);
  gstbasesink_class->event    = GST_DEBUG_FUNCPTR (gh_gstsink_event);
……
}

 

对于Transform插件(相当于 Filter),事件代码如下:

static gboolean gst_rfcnplugin_sink_event(GstBaseTransform *trans, GstEvent *event)
{
    //关键代码。最关键的就是遇到GST_EVENT_EOS要如此调用。
    return GST_BASE_TRANSFORM_CLASS(parent_class)->sink_event(trans, event);
}

static gboolean gst_rfcnplugin_src_event(GstBaseTransform *trans, GstEvent *event)
{
    //关键代码。最关键的就是遇到GST_EVENT_EOS要如此调用。
    return GST_BASE_TRANSFORM_CLASS(parent_class)->src_event(trans, event);
}


static void gst_rfcnplugin_class_init(GstRfcnPluginClass* klass)
{
    GObjectClass* gobject_class                   = (GObjectClass*) klass;
    GstElementClass* gstelement_class             = (GstElementClass*) klass;
    GstBaseTransformClass* gstbasetransform_class = (GstBaseTransformClass*) klass;

    /* Overide base class functions */
    gobject_class->set_property          = GST_DEBUG_FUNCPTR(gst_rfcn_set_property);
    gobject_class->get_property          = GST_DEBUG_FUNCPTR(gst_rfcnplugin_get_property);

    gstbasetransform_class->set_caps     = GST_DEBUG_FUNCPTR(gst_rfcnplugin_set_caps);
    gstbasetransform_class->start        = GST_DEBUG_FUNCPTR(gst_rfcnplugin_start);
    gstbasetransform_class->stop         = GST_DEBUG_FUNCPTR(gst_rfcnplugin_stop);

    gstbasetransform_class->transform_ip = GST_DEBUG_FUNCPTR(gst_rfcnplugin_transform_ip);

    gstbasetransform_class->sink_event   = GST_DEBUG_FUNCPTR(gst_rfcnplugin_sink_event);
    gstbasetransform_class->src_event    = GST_DEBUG_FUNCPTR(gst_rfcnplugin_src_event);
……
}

start/stop的正确写法!

static gboolean gh_gstsink_start (GstBaseSink * basesink)
{
    //do pre work.

    //这样调用会崩溃。
    //return GST_BASE_SINK_CLASS(parent_class)->start(basesink);
    return TRUE;
}

static gboolean gh_gstsink_stop (GstBaseSink * basesink)
{
    //release something.

    //这样调用会崩溃。
    //return GST_BASE_SINK_CLASS(parent_class)->stop(basesink);
    return TRUE;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳鲲鹏

能给阁下一点帮助,非常荣幸

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值