因为工作需要,同事写了一个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; }