同事写了一个 gstreamer插件,去掉显示之后,整个流不运行。吾视之,看不出问题。猜测是插件类型不对,于是改写了一个sink插件,试之,流运行了。然后,有一个问题没有解决:

  如果是播放文件,文件结束后,无法结束(即使得GstBus收到GST_MESSAGE_EOS消息)。

  虽然有此严重问题,整个系统运行起来了。这个问题以后看看怎么解决。这里把代码共享出来,希望能给朋友们们带来文件。

  • 头文件
#ifndef __GH_GSTSINK_H__
#define __GH_GSTSINK_H__#include <gst/base/gstbasesink.h>
#include <gst/video/video.h>#define GH_GSTSINK_NAME "gh_gstsink"/* Package and library details required for plugin_init */
#define PACKAGE         GH_GSTSINK_NAME
#define VERSION         "1.0"
#define LICENSE         "Proprietary"
#define DESCRIPTION     "wuxi sink"
#define BINARY_PACKAGE  "wuxi sink"
#define URL             "http://wuxi.com/"G_BEGIN_DECLS/* Standard boilerplate stuff */
typedef struct _GhGstSink GhGstSink;
typedef struct _GhGstSinkClass GhGstSinkClass;/* Standard boilerplate stuff */
#define GST_TYPE_GHGSTSINK            (gh_gstsink_get_type())
#define GST_GHGSTSINK(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GHGSTSINK,GhGstSink))
#define GST_GHGSTSINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GHGSTSINK,GhGstSinkClass))
#define GST_GHGSTSINK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_GHGSTSINK, GhGstSinkClass))
#define GST_IS_GHGSTSINK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GHGSTSINK))
#define GST_IS_GHGSTSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GHGSTSINK))
#define GST_GHGSTSINK_CAST(obj)       ((GhGstSink *)(obj))struct _GhGstSink
{GstBaseSink base_trans;//when i received a eos, how to end ? int isEOS;};// Boiler plate stuff
struct _GhGstSinkClass
{GstBaseSinkClass parent_class;//gint (*eos)(GhGstSink *sink);//gint (*signal_action)(GhGstSink *sink);
};GType gh_gst_sink_get_type (void);G_END_DECLS#endif /* __GH_GSTSINK_H__ */
  • 代码

#include <string.h>
#include <string>
#include <fstream>#include "gh_kit.h"
#include "gh_gstsink.h"GST_DEBUG_CATEGORY_STATIC (gh_gstsink_debug);
#define GST_CAT_DEFAULT gh_gstsink_debug/* Enum to identify properties */
enum
{PROP_0,PROP_UNIQUE_ID
};/* Default values for properties */
#define DEFAULT_UNIQUE_ID       15
#define DEFAULT_PROCESSING_WIDTH    640
#define DEFAULT_PROCESSING_HEIGHT   480
#define DEFAULT_PROCESS_FULL_FRAME  TRUE
#define DEFAULT_GPU_ID          0static GstStaticPadTemplate gh_gstsink_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",GST_PAD_SINK,GST_PAD_ALWAYS,GST_STATIC_CAPS ("WUXI"));static GstStaticPadTemplate gh_gstsink_src_template =
GST_STATIC_PAD_TEMPLATE ("src",GST_PAD_SRC,GST_PAD_ALWAYS,GST_STATIC_CAPS ("WUXI"));/* Define our element type. Standard GObject/GStreamer boilerplate stuff */
#define gh_gstsink_parent_class parent_class
G_DEFINE_TYPE (GhGstSink, gh_gstsink, GST_TYPE_BASE_SINK);static void gh_gstsink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
static void gh_gstsink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);static gboolean gh_gstsink_start (   GstBaseSink * basesink);
static gboolean gh_gstsink_stop (    GstBaseSink * basesink);/**
GstEvent *gst_event_new_eos (void);
Create a new EOS event. The eos event can only travel downstream synchronized with the buffer flow. Elements that receive the EOS event on a pad can return GST_FLOW_EOS as a GstFlowReturn when data after the EOS event arrives.The EOS event will travel down to the sink elements in the pipeline which will then post the GST_MESSAGE_EOS on the bus after they have finished playing any buffered data.When all sinks have posted an EOS message, an EOS message is forwarded to the application.The EOS event itself will not cause any state transitions of the pipeline.Events are usually created with gst_event_new_*() which takes event-type specific parameters as arguments. To send an event application will usually use gst_element_send_event() and elements will use gst_pad_send_event() or gst_pad_push_event(). The event should be unreffed with gst_event_unref() if it has not been sent.gst_event_type_get_flags(), GST_EVENT_IS_UPSTREAM, GST_EVENT_IS_DOWNSTREAM, and GST_EVENT_IS_SERIALIZED. gst_collect_pads_event
*///所有sinks发出了EOS消息,EOS就会转发给应用。我这里发出了,为什么还没结束?
//GST_MESSAGE_EOS
static gboolean gh_gstsink_event(GstBaseSink *sink, GstEvent *event)
{GstElement* element = (GstElement*)sink;GhGstSink*  ghsink  = (GhGstSink*) sink;switch(event-> type){case GST_EVENT_EOS://GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;//parent_class->change_state(element, transition);GH_LOG_TEXT("GST_EVENT_EOS");gst_element_set_state(element, GST_STATE_NULL);//gst_event_new_eos();//gst_send_event(ghsink->isEOS = 1;gst_element_send_event(element, event);gst_pad_send_event ((GstPad*)element, event);return TRUE;case GST_EVENT_FLUSH_START:case GST_EVENT_FLUSH_STOP:default:break;}return TRUE;
}static GstFlowReturn gh_gstsink_render(GstBaseSink *sink, GstBuffer *buffer)
{GhGstSink*  ghsink  = (GhGstSink*) sink;return ghsink->isEOS ? GST_FLOW_EOS : GST_FLOW_OK;
}static GstStateChangeReturn gh_gstsink_change_state(GstElement* element, GstStateChange transition)
{GstElementClass *oclass;GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;GhGstSink*  ghsink  = (GhGstSink*) element;g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);oclass = GST_ELEMENT_GET_CLASS (element);if (oclass->set_state && ghsink->isEOS){(oclass->set_state) (element, GST_STATE_NULL);}return result;
}/* Install properties, set sink and src pad capabilities, override the required* functions of the base class, These are common to all instances of the* element.*/
static void gh_gstsink_class_init (GhGstSinkClass * klass)
{GObjectClass     *gobject_class;GstElementClass  *gstelement_class;GstBaseSinkClass *gstbasesink_class;gobject_class     = (GObjectClass *) klass;gstelement_class  = (GstElementClass *) klass;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);//gstelement_class->change_state  = GST_DEBUG_FUNCPTR (gh_gstsink_change_state);//klass->eos                      = gh_gstsink_eos_cb;//guint eossignal_id = 0;//eossignal_id = g_signal_new ("eos", G_TYPE_FROM_CLASS(klass),//        G_SIGNAL_RUN_LAST,//        G_STRUCT_OFFSET (GhGstSinkClass, eos), NULL, NULL, NULL, G_TYPE_INT, 0, G_TYPE_NONE);//klass->signal_action  = gh_gstsink_callback;//eossignal_id = g_signal_new ("act", G_TYPE_FROM_CLASS (klass),//        G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,//        G_STRUCT_OFFSET (GhGstSinkClass, act), NULL, NULL, NULL, G_TYPE_INT, 0, G_TYPE_NONE);/* Install properties */g_object_class_install_property (gobject_class, PROP_UNIQUE_ID,g_param_spec_uint ("unique-id","Unique ID","Unique ID for the element. Can be used to identify output of the element", 0, G_MAXUINT, DEFAULT_UNIQUE_ID, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));/* Set sink and src pad capabilities *///gst_element_class_add_pad_template (gstelement_class,//    gst_static_pad_template_get (&gh_gstsink_src_template));gst_element_class_add_pad_template (gstelement_class,gst_static_pad_template_get (&gh_gstsink_sink_template));/* Set metadata describing the element */gst_element_class_set_details_simple (gstelement_class,"GhGstSink plugin","GhGstSink Plugin","wuxi data sink",URLURL);
}static void gh_gstsink_init (GhGstSink * ghsink)
{ghsink->isEOS = 0;
}/* Function called when a property of the element is set. Standard boilerplate.*/
static void gh_gstsink_set_property (GObject * object, guint prop_id,const GValue * value, GParamSpec * pspec)
{GhGstSink *ghsink = GST_GHGSTSINK (object);switch (prop_id){case PROP_UNIQUE_ID:ghsink->unique_id = g_value_get_uint (value);break;default:G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);break;}
}/* Function called when a property of the element is requested. Standard* boilerplate.*/
static void gh_gstsink_get_property (GObject * object, guint prop_id,GValue * value, GParamSpec * pspec)
{GhGstSink *ghsink = GST_GHGSTSINK (object);switch (prop_id){case PROP_UNIQUE_ID:g_value_set_uint (value, ghsink->unique_id);break;default:G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);break;}
}/*** Initialize all resources and start the output thread*/
static gboolean gh_gstsink_start (GstBaseSink * basesink)
{GH_LOG_HERE();return TRUE;
}/*** Stop the output thread and free up all the resources*/
static gboolean gh_gstsink_stop (GstBaseSink * basesink)
{GH_LOG_HERE();return TRUE;
}/*** Boiler plate for registering a plugin and an element.*/
static gboolean ghsink_plugin_init (GstPlugin * plugin)
{GST_DEBUG_CATEGORY_INIT (gh_gstsink_debug, GH_GSTSINK_NAME, 0,"ghgstsink plugin");return gst_element_register (plugin, GH_GSTSINK_NAME, GST_RANK_PRIMARY,GST_TYPE_GHGSTSINK);
}GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,GST_VERSION_MINOR,ghsink,DESCRIPTION, ghsink_plugin_init, VERSION, LICENSE, BINARY_PACKAGE, URL)

gstreamer实现sink插件的代码,及无法结束的问题相关推荐

  1. 转载]Linux Gstreamer and GST-OMX插件

    原文地址:Linux Gstreamer and GST-OMX插件 作者:wuqiseu 1. Gstreamer基本介绍 Gstreamer是linux上的多媒体框架.如下所示:         ...

  2. GStreamer appsrc 等插件实现视频音频混流,录制和推流

    参考 使用 GStreamer appsrc 等插件实现视频音频混流,录制和推流 http://t.zoukankan.com/luckbird-p-GStreamer_appsrc.html 目前在 ...

  3. Maven 配置文件 POM 的常用插件配置代码

    Maven 配置文件 POM 的常用插件配置代码 普通 将 Maven 多模块依赖集成打进一个 JAR 包(方法 1) 将 Maven 多模块依赖集成打进一个 JAR 包(方法 2) 生成单入口类 J ...

  4. idea中leetcode提示未登录_IntelliJ IDEA中LeetCode插件配置问题代码解析

    本篇文章小编给大家分享一下IntelliJ IDEA中LeetCode插件配置问题代码解析,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 首先是在In ...

  5. 让数据大白于天下:GCC插件实现代码分析和安全审计

    摘要: 如何利用GCC的插件功能,辅助安全分析人员实现对程序的安全审计.漏洞检测.安全加固等自动化处理能力,提升分析效率和精准度. 本文分享自华为云社区<利用GCC插件实现代码分析和安全审计&g ...

  6. 解决IDEA中使用git插件提交代码乱码问题

    问题描述 在使用idea中git插件commit代码时,中文出现乱码 但是在git bash中提交没有中文乱码的问题,所以一开始以为不是git的配置问题(打脸.jpg) 解决方案 在git的安装路径中 ...

  7. 漂亮实用的jQuery倒计时插件特效代码

    原文:漂亮实用的jQuery倒计时插件特效代码 源代码下载地址:http://www.zuidaima.com/share/1799598875675648.htm

  8. 来客推电商|小程序+h5+app商城|含分销拼团砍价等多种引流插件|前后代码开源

    来客推电商|小程序+h5+app商城|含分销拼团砍价等多种引流插件|前后代码开源 精致电商,来客, [ 微信 + 支付宝 + 百度 + 头条 ] 小程序 + APP + 公众号 + PC + H5,注 ...

  9. Visual Studio中使用Macros插件给代码添加注释、时间和以及自动脚本

    title: Visual Studio中使用Macros插件给代码添加注释.时间和以及自动脚本 date: 2020-09-11 sidebarDepth: 2 tags: 代码 Visual st ...

  10. MDK5插件:代码格式整理、文件注释、函数注释

    文章目录 前言 一.插件使用&&效果演示 1.代码格式整理 2.函数注释 3.文件注释 二.安装插件 1.下载插件 2.导入插件 三.设置快捷键 总结 参考文章和资料 前言 近日,本人 ...

最新文章

  1. C#进阶之路(一):委托
  2. 实习随记-不定时更新
  3. LeetCode 11 盛最多水的容器
  4. 四十年前的 6502 CPU 指令翻译成 JS 代码会是怎样
  5. S/4HANA业务角色概览之订单到收款篇
  6. 保留小数点后两位小数
  7. RHEL6_yum本地源配置
  8. 定义控制台应用程序的入口点 ConsoleApplication
  9. chm文件转换成单个html
  10. vue项目运行后页面一片空白
  11. %2d、%6d(c语言)
  12. 飞控和飞控固件的讲解
  13. 如何合并视频?教你把多个视频合并成一个视频
  14. 智能制造-主要的国际标准
  15. ionic2 city-picker 报_dur错误
  16. Spring-boot通过redisTemplate使用redis(无须手动序列化)
  17. Oracle11g新特性密码延迟验证的坑
  18. 用7000字长文带你分析深圳二手房市场现况!
  19. Coding git@e.coding.net: Permission denied (publickey)
  20. 京东7亿美元投资兴盛优选,买到了什么?

热门文章

  1. python乱码怎么办_Python爬虫结果是乱码怎么办?带你了解乱码的原因及其解决办法...
  2. 使用fileupload实现文件上传
  3. 一个关于数组数据检查的问题,有没有更好的方法。
  4. redis的持久化(RDBAOF的区别)
  5. 警惕那些产生负价值的开发者
  6. CentOS7 MongoDB安裝
  7. JPDA 架构研究19 - JDI的连接模块
  8. B/S系统间跨域单点登录设计思路
  9. 未来3-4周可能出现大规模病毒或安全***事件
  10. 队列:先进先出的线性表,如何实现增删查?