add gstreamer plugin
This commit is contained in:
parent
d77253e058
commit
8fe11a0a07
|
|
@ -0,0 +1,3 @@
|
|||
Language: Cpp
|
||||
ColumnLimit: 180
|
||||
IndentPPDirectives: AfterHash
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
CompileFlags:
|
||||
Add: ['-I/usr/include/gstreamer-1.0', '-I/usr/lib/glib-2.0/include', '-I/usr/include/glib-2.0']
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
#include "gstwestonimagesrc.h"
|
||||
#include "gst/gstinfo.h"
|
||||
#include <string.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC(gst_westonimagesrc_debug);
|
||||
#define GST_CAT_DEFAULT gst_westonimagesrc_debug
|
||||
|
||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS("text/plain; charset=utf-8"));
|
||||
|
||||
enum { PROP_0, PROP_FRAMERATE, N_PROPERTIES };
|
||||
|
||||
static gboolean gst_westonimagesrc_start(GstBaseSrc *basesrc);
|
||||
static gboolean gst_westonimagesrc_stop(GstBaseSrc *basesrc);
|
||||
static GstFlowReturn gst_westonimagesrc_create(GstBaseSrc *basesrc, guint64 offset, guint size, GstBuffer **buf);
|
||||
static gboolean gst_westonimagesrc_unlock(GstBaseSrc *basesrc);
|
||||
static gboolean gst_westonimagesrc_unlock_stop(GstBaseSrc *basesrc);
|
||||
|
||||
static void gst_westonimagesrc_class_init(GstWestonImageSrcClass *klass);
|
||||
static void gst_westonimagesrc_init(GstWestonImageSrc *westonimagesrc);
|
||||
static void gst_westonimagesrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_westonimagesrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
|
||||
G_DEFINE_TYPE(GstWestonImageSrc, gst_westonimagesrc, GST_TYPE_BASE_SRC);
|
||||
|
||||
static void gst_westonimagesrc_class_init(GstWestonImageSrcClass *klass) {
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass);
|
||||
GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS(klass);
|
||||
|
||||
gobject_class->set_property = gst_westonimagesrc_set_property;
|
||||
gobject_class->get_property = gst_westonimagesrc_get_property;
|
||||
|
||||
gstbasesrc_class->start = GST_DEBUG_FUNCPTR(gst_westonimagesrc_start);
|
||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR(gst_westonimagesrc_stop);
|
||||
gstbasesrc_class->create = GST_DEBUG_FUNCPTR(gst_westonimagesrc_create);
|
||||
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR(gst_westonimagesrc_unlock);
|
||||
gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR(gst_westonimagesrc_unlock_stop);
|
||||
|
||||
// Регистрация свойств
|
||||
g_object_class_install_property(
|
||||
gobject_class, PROP_FRAMERATE,
|
||||
g_param_spec_double("framerate", "Frame rate", "Number of hello world messages per second", 0.f, 24.f, 1.f, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_set_static_metadata(gstelement_class, "WestonImageSrc World Source", "Source", "Generates westonimagesrc world messages", "Your Name <your.email@example.com>");
|
||||
gst_element_class_add_static_pad_template(gstelement_class, &src_template);
|
||||
GST_DEBUG_CATEGORY_INIT(gst_westonimagesrc_debug, "westonimagesrc", 0, "WestonImageSrc World Plugin");
|
||||
}
|
||||
|
||||
static void gst_westonimagesrc_init(GstWestonImageSrc *westonimagesrc) {
|
||||
gst_base_src_set_live(GST_BASE_SRC(westonimagesrc), TRUE);
|
||||
gst_base_src_set_format(GST_BASE_SRC(westonimagesrc), GST_FORMAT_TIME);
|
||||
gst_base_src_set_blocksize(GST_BASE_SRC(westonimagesrc), 0);
|
||||
|
||||
westonimagesrc->running = FALSE;
|
||||
westonimagesrc->timeout_id = 0;
|
||||
westonimagesrc->offset = 0;
|
||||
westonimagesrc->framerate = 1.f;
|
||||
|
||||
g_mutex_init(&westonimagesrc->lock);
|
||||
g_cond_init(&westonimagesrc->cond);
|
||||
}
|
||||
|
||||
static void gst_westonimagesrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(object);
|
||||
|
||||
GST_OBJECT_LOCK(westonimagesrc);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FRAMERATE: {
|
||||
gdouble new_framerate = g_value_get_double(value);
|
||||
|
||||
if (new_framerate != westonimagesrc->framerate) {
|
||||
westonimagesrc->framerate = new_framerate;
|
||||
g_object_notify(object, "framerate");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK(westonimagesrc);
|
||||
}
|
||||
|
||||
static void gst_westonimagesrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(object);
|
||||
GST_OBJECT_LOCK(westonimagesrc);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FRAMERATE:
|
||||
g_value_set_double(value, westonimagesrc->framerate);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK(westonimagesrc);
|
||||
}
|
||||
|
||||
static gboolean gst_westonimagesrc_start(GstBaseSrc *basesrc) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(basesrc);
|
||||
|
||||
g_mutex_lock(&westonimagesrc->lock);
|
||||
westonimagesrc->running = TRUE;
|
||||
westonimagesrc->offset = 0;
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
|
||||
GST_DEBUG_OBJECT(westonimagesrc, "started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean gst_westonimagesrc_stop(GstBaseSrc *basesrc) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(basesrc);
|
||||
|
||||
g_mutex_lock(&westonimagesrc->lock);
|
||||
westonimagesrc->running = FALSE;
|
||||
g_cond_signal(&westonimagesrc->cond);
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
|
||||
GST_DEBUG_OBJECT(westonimagesrc, "stopped");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn gst_westonimagesrc_create(GstBaseSrc *basesrc, guint64 offset, guint size, GstBuffer **buf) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(basesrc);
|
||||
GstMapInfo map;
|
||||
gchar *message;
|
||||
gint message_len;
|
||||
GstClockTime timestamp;
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_mutex_lock(&westonimagesrc->lock);
|
||||
|
||||
while (westonimagesrc->running) {
|
||||
GstClockTime wait_until = g_get_monotonic_time() + (1 / westonimagesrc->framerate) * G_TIME_SPAN_SECOND;
|
||||
|
||||
if (g_cond_wait_until(&westonimagesrc->cond, &westonimagesrc->lock, wait_until)) {
|
||||
if (!westonimagesrc->running) {
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
return GST_FLOW_FLUSHING;
|
||||
}
|
||||
}
|
||||
|
||||
if (!westonimagesrc->running) {
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
return GST_FLOW_FLUSHING;
|
||||
}
|
||||
|
||||
message = g_strdup_printf("westonimagesrc world #%lu\n", (gulong)westonimagesrc->offset);
|
||||
message_len = strlen(message);
|
||||
|
||||
buffer = gst_buffer_new_allocate(NULL, message_len, NULL);
|
||||
gst_buffer_map(buffer, &map, GST_MAP_WRITE);
|
||||
memcpy(map.data, message, message_len);
|
||||
gst_buffer_unmap(buffer, &map);
|
||||
g_free(message);
|
||||
|
||||
timestamp = westonimagesrc->offset * GST_SECOND;
|
||||
GST_BUFFER_PTS(buffer) = timestamp;
|
||||
GST_BUFFER_DURATION(buffer) = GST_SECOND;
|
||||
GST_BUFFER_OFFSET(buffer) = westonimagesrc->offset;
|
||||
GST_BUFFER_OFFSET_END(buffer) = westonimagesrc->offset + 1;
|
||||
|
||||
westonimagesrc->offset++;
|
||||
|
||||
*buf = buffer;
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
|
||||
GST_DEBUG_OBJECT(westonimagesrc, "created buffer %" G_GUINT64_FORMAT, westonimagesrc->offset - 1);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
return GST_FLOW_FLUSHING;
|
||||
}
|
||||
|
||||
static gboolean gst_westonimagesrc_unlock(GstBaseSrc *basesrc) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(basesrc);
|
||||
|
||||
GST_DEBUG_OBJECT(westonimagesrc, "unlock");
|
||||
g_mutex_lock(&westonimagesrc->lock);
|
||||
westonimagesrc->running = FALSE;
|
||||
g_cond_signal(&westonimagesrc->cond);
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean gst_westonimagesrc_unlock_stop(GstBaseSrc *basesrc) {
|
||||
GstWestonImageSrc *westonimagesrc = GST_WESTONIMAGESRC(basesrc);
|
||||
|
||||
GST_DEBUG_OBJECT(westonimagesrc, "unlock stop");
|
||||
g_mutex_lock(&westonimagesrc->lock);
|
||||
westonimagesrc->running = TRUE;
|
||||
g_mutex_unlock(&westonimagesrc->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean plugin_init(GstPlugin *plugin) { return gst_element_register(plugin, "westonimagesrc", GST_RANK_NONE, GST_TYPE_WESTONIMAGESRC); }
|
||||
|
||||
#ifndef PACKAGE
|
||||
# define PACKAGE "westonimagesrc"
|
||||
#endif
|
||||
|
||||
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, westonimagesrc, "WestonImageSrc World source plugin", plugin_init, "1.0", "LGPL", "GStreamer", "http://gstreamer.net/")
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef __GST_WESTONIMAGESRC_H__
|
||||
#define __GST_WESTONIMAGESRC_H__
|
||||
|
||||
#include <gst/base/gstbasesrc.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_WESTONIMAGESRC (gst_westonimagesrc_get_type())
|
||||
#define GST_WESTONIMAGESRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_WESTONIMAGESRC, GstWestonImageSrc))
|
||||
#define GST_WESTONIMAGESRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_WESTONIMAGESRC, GstWestonImageSrcClass))
|
||||
#define GST_IS_WESTONIMAGESRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_WESTONIMAGESRC))
|
||||
#define GST_IS_WESTONIMAGESRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_WESTONIMAGESRC))
|
||||
|
||||
typedef struct _GstWestonImageSrc GstWestonImageSrc;
|
||||
typedef struct _GstWestonImageSrcClass GstWestonImageSrcClass;
|
||||
|
||||
struct _GstWestonImageSrc {
|
||||
GstBaseSrc element;
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
gboolean running;
|
||||
guint timeout_id;
|
||||
guint64 offset; // Счетчик отправленных сообщений
|
||||
gdouble framerate;
|
||||
};
|
||||
|
||||
struct _GstWestonImageSrcClass {
|
||||
GstBaseSrcClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_westonimagesrc_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_WESTONIMAGESRC_H__ */
|
||||
Loading…
Reference in New Issue