From 9b3862a1949c9cc73e5ab0ef79253bb109c6035f Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Sun, 14 Sep 2003 12:21:06 +0000 Subject: Adding GstVideoSink object which will be used for video sink's subclassing. Original commit message from CVS: Adding GstVideoSink object which will be used for video sink's subclassing. --- gst-libs/gst/video/Makefile.am | 4 +- gst-libs/gst/video/gstvideosink.c | 372 ++++++++++++++++++++++++++++++++++++++ gst-libs/gst/video/gstvideosink.h | 102 +++++++++++ gst-libs/gst/video/videosink.h | 102 +++++++++++ 4 files changed, 578 insertions(+), 2 deletions(-) create mode 100644 gst-libs/gst/video/gstvideosink.c create mode 100644 gst-libs/gst/video/gstvideosink.h create mode 100644 gst-libs/gst/video/videosink.h (limited to 'gst-libs') diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index e45c0051..48144ae3 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -2,10 +2,10 @@ librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@ library_LTLIBRARIES = libgstvideo.la -libgstvideo_la_SOURCES = video.c +libgstvideo_la_SOURCES = video.c gstvideosink.c libgstvideoincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video -libgstvideoinclude_HEADERS = video.h +libgstvideoinclude_HEADERS = video.h gstvideosink.h libgstvideo_la_LIBADD = libgstvideo_la_CFLAGS = $(GST_CFLAGS) diff --git a/gst-libs/gst/video/gstvideosink.c b/gst-libs/gst/video/gstvideosink.c new file mode 100644 index 00000000..1fdcce8b --- /dev/null +++ b/gst-libs/gst/video/gstvideosink.c @@ -0,0 +1,372 @@ +/* + * GStreamer Video sink. + * + * Copyright (C) <2003> Julien Moutte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvideosink.h" + +/* VideoSink signals and args */ + +enum { + HAVE_VIDEO_OUT, + HAVE_SIZE, + FRAME_DISPLAYED, + LAST_SIGNAL +}; + + +enum { + ARG_0, + ARG_WIDTH, + ARG_HEIGHT, + ARG_FRAMES_DISPLAYED, + ARG_FRAME_TIME, +}; + +static GstElementClass *parent_class = NULL; +static guint gst_videosink_signals[LAST_SIGNAL] = { 0 }; + +/* Private methods */ + +static void +gst_videosink_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + GstVideoSink *videosink; + + g_return_if_fail (object != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (object)); + + videosink = GST_VIDEOSINK (object); + + switch (prop_id) + { + case ARG_WIDTH: + gst_video_sink_set_geometry (videosink, g_value_get_int (value), + videosink->height); + break; + case ARG_HEIGHT: + gst_video_sink_set_geometry (videosink, videosink->width, + g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_videosink_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GstVideoSink *videosink; + + g_return_if_fail (object != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (object)); + + videosink = GST_VIDEOSINK (object); + + switch (prop_id) + { + case ARG_WIDTH: + g_value_set_int (value, videosink->width); + break; + case ARG_HEIGHT: + g_value_set_int (value, videosink->height); + break; + case ARG_FRAMES_DISPLAYED: + g_value_set_int (value, videosink->frames_displayed); + break; + case ARG_FRAME_TIME: + g_value_set_int64 (value, videosink->frame_time); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_videosink_set_clock (GstElement *element, GstClock *clock) +{ + GstVideoSink *videosink; + + videosink = GST_VIDEOSINK (element); + + videosink->clock = clock; +} + +/* Initing stuff */ + +static void +gst_videosink_init (GstVideoSink *videosink) +{ + videosink->video_out = NULL; + videosink->width = -1; + videosink->height = -1; + videosink->frames_displayed = 0; + videosink->frame_time = 0; + + videosink->clock = NULL; + videosink->formats = NULL; +} + +static void +gst_videosink_class_init (GstVideoSinkClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH, + g_param_spec_int ("width", "Width", "Width of the video output", + G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HEIGHT, + g_param_spec_int ("height", "Height", "Height of the video output", + G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FRAMES_DISPLAYED, + g_param_spec_int ("frames_displayed", "Frames displayed", + "The number of frames displayed so far", + G_MININT,G_MAXINT, 0, G_PARAM_READABLE)); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FRAME_TIME, + g_param_spec_int ("frame_time", "Frame time", "The interval between frames", + G_MININT, G_MAXINT, 0, G_PARAM_READABLE)); + + gobject_class->set_property = gst_videosink_set_property; + gobject_class->get_property = gst_videosink_get_property; + + gst_videosink_signals[FRAME_DISPLAYED] = + g_signal_new ("frame_displayed", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstVideoSinkClass, frame_displayed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + gst_videosink_signals[HAVE_SIZE] = + g_signal_new ("have_size", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstVideoSinkClass, have_size), + NULL, NULL, + gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); + + gst_videosink_signals[HAVE_VIDEO_OUT] = + g_signal_new ("have_video_out", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstVideoSinkClass, have_video_out), + NULL, NULL, + gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, + G_TYPE_POINTER); + + gstelement_class->set_clock = gst_videosink_set_clock; +} + +/* Public virtual methods */ + +/** + * gst_video_sink_set_video_out: + * @videosink: a #GstVideoSink to set the video out on. + * @video_out: the #gpointer linking to video out. + * + * This will call the video sink's set_video_out method. You should use this + * method to tell to a video sink to display video output to a specific + * video out ressource. + */ +void +gst_video_sink_set_video_out (GstVideoSink *videosink, gpointer video_out) +{ + GstVideoSinkClass *class; + + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + class = GST_VIDEOSINK_GET_CLASS (videosink); + + if (class->set_video_out) + class->set_video_out (videosink, video_out); +} + +/** + * gst_video_sink_push_ui_event: + * @videosink: a #GstVideoSink to push the event to. + * @event: the #GstEvent to be pushed. + * + * This will push an event to the video sink. That event is supposed to be + * a user interface event and will be forwarded upstream to provide + * interactivity support. + */ +void +gst_video_sink_push_ui_event (GstVideoSink *videosink, GstEvent *event) +{ + GstVideoSinkClass *class; + + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + class = GST_VIDEOSINK_GET_CLASS (videosink); + + if (class->push_ui_event) + class->push_ui_event (videosink, event); +} + +/** + * gst_video_sink_set_geometry: + * @videosink: a #GstVideoSink which geometry will be set. + * @width: a width as a #gint. + * @height: a height as a #gint. + * + * Set video sink's geometry to @width x @height. If that succeed you should + * get the have_size signal being fired. + */ +void +gst_video_sink_set_geometry (GstVideoSink *videosink, gint width, gint height) +{ + GstVideoSinkClass *class; + + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + class = GST_VIDEOSINK_GET_CLASS (videosink); + + if (class->set_geometry) + class->set_geometry (videosink, width, height); +} + +/* Public methods */ + +/** + * gst_video_sink_got_video_out: + * @videosink: a #GstVideoSink which got a video out ressource. + * @video_out: a #gpointer linking to the video out ressource. + * + * This will fire an have_video_out signal and update the internal object's + * #gpointer. + * + * This function should be used by video sink developpers. + */ +void +gst_video_sink_got_video_out (GstVideoSink *videosink, gpointer video_out) +{ + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + videosink->video_out = video_out; + + g_signal_emit (G_OBJECT (videosink), gst_videosink_signals[HAVE_VIDEO_OUT], + 0, video_out); +} + +/** + * gst_video_sink_got_video_size: + * @videosink: a #GstVideoSink which received video geometry. + * @width: a width as a #gint. + * @height: a height as a #gint. + * + * This will fire an have_size signal and update the internal object's + * geometry. + * + * This function should be used by video sink developpers. + */ +void +gst_video_sink_got_video_size (GstVideoSink *videosink, gint width, gint height) +{ + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + videosink->width = width; + videosink->height = height; + + g_signal_emit (G_OBJECT (videosink), gst_videosink_signals[HAVE_SIZE], + 0, width, height); +} + +/** + * gst_video_sink_frame_displayed: + * @videosink: a #GstVideoSink which displayed a frame. + * + * This will fire an frame_displayed signal and update the internal object's + * counter. + * + * This function should be used by video sink developpers. + */ +void +gst_video_sink_frame_displayed (GstVideoSink *videosink) +{ + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + + videosink->frames_displayed++; + + g_signal_emit (G_OBJECT (videosink), + gst_videosink_signals[FRAME_DISPLAYED], 0); +} + +/** + * gst_video_sink_get_geometry: + * @videosink: a #GstVideoSink which displayed a frame. + * @width: a #gint pointer where the width will be set. + * @height: a #gint pointer where the height will be set. + * + * This will fill set @width and @height with the video sink's current geometry. + */ +void +gst_video_sink_get_geometry (GstVideoSink *videosink, gint *width, gint *height) +{ + g_return_if_fail (videosink != NULL); + g_return_if_fail (GST_IS_VIDEOSINK (videosink)); + *width = videosink->width; + *height = videosink->height; +} + +GType +gst_videosink_get_type (void) +{ + static GType videosink_type = 0; + + if (!videosink_type) + { + static const GTypeInfo videosink_info = { + sizeof (GstVideoSinkClass), + NULL, + NULL, + (GClassInitFunc) gst_videosink_class_init, + NULL, + NULL, + sizeof (GstVideoSink), + 0, + (GInstanceInitFunc) gst_videosink_init, + }; + + videosink_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstVideoSink", + &videosink_info, 0); + } + + return videosink_type; +} diff --git a/gst-libs/gst/video/gstvideosink.h b/gst-libs/gst/video/gstvideosink.h new file mode 100644 index 00000000..9f82bb1f --- /dev/null +++ b/gst-libs/gst/video/gstvideosink.h @@ -0,0 +1,102 @@ +/* + * GStreamer Video sink. + * + * Copyright (C) <2003> Julien Moutte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VIDEOSINK_H__ +#define __GST_VIDEOSINK_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GST_TYPE_VIDEOSINK (gst_videosink_get_type()) +#define GST_VIDEOSINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VIDEOSINK, GstVideoSink)) +#define GST_VIDEOSINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VIDEOSINK, GstVideoSink)) +#define GST_IS_VIDEOSINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VIDEOSINK)) +#define GST_IS_VIDEOSINK_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VIDEOSINK)) +#define GST_VIDEOSINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VIDEOSINK, GstVideoSinkClass)) + +#define GST_VIDEOSINK_PAD(obj) (GST_VIDEOSINK (obj)->sinkpad) +#define GST_VIDEOSINK_WIDTH(obj) (GST_VIDEOSINK (obj)->width) +#define GST_VIDEOSINK_HEIGHT(obj) (GST_VIDEOSINK (obj)->height) +#define GST_VIDEOSINK_CLOCK(obj) (GST_VIDEOSINK (obj)->clock) + +typedef struct _GstVideoSink GstVideoSink; +typedef struct _GstVideoSinkClass GstVideoSinkClass; + +struct _GstVideoSink { + GstElement element; + + GstPad *sinkpad; + + gpointer video_out; + + gint width, height; + gint frames_displayed; + guint64 frame_time; + + GstClock *clock; + + GstCaps *formats; +}; + +struct _GstVideoSinkClass { + GstElementClass parent_class; + + /* public virtual methods */ + void (*set_video_out) (GstVideoSink *videosink, gpointer video_out); + void (*push_ui_event) (GstVideoSink *videosink, GstEvent *event); + void (*set_geometry) (GstVideoSink *videosink, gint width, gint height); + + /* signals */ + void (*have_video_out) (GstVideoSink *element, gpointer video_out); + void (*have_size) (GstVideoSink *element, gint width, gint height); + void (*frame_displayed) (GstVideoSink *element); +}; + +GType gst_videosink_get_type (void); + +/* public virtual methods */ +void gst_video_sink_set_video_out (GstVideoSink *videosink, gpointer video_out); +void gst_video_sink_push_ui_event (GstVideoSink *videosink, GstEvent *event); +void gst_video_sink_set_geometry (GstVideoSink *videosink, gint width, + gint height); + +/* public methods to fire signals */ +void gst_video_sink_got_video_out (GstVideoSink *videosink, gpointer video_out); +void gst_video_sink_got_video_size (GstVideoSink *videosink, + gint width, gint height); +void gst_video_sink_frame_displayed (GstVideoSink *videosink); + +/* public methods */ +void gst_video_sink_get_geometry (GstVideoSink *videosink, + gint *width, gint *height); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_VIDEOSINK_H__ */ diff --git a/gst-libs/gst/video/videosink.h b/gst-libs/gst/video/videosink.h new file mode 100644 index 00000000..9f82bb1f --- /dev/null +++ b/gst-libs/gst/video/videosink.h @@ -0,0 +1,102 @@ +/* + * GStreamer Video sink. + * + * Copyright (C) <2003> Julien Moutte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VIDEOSINK_H__ +#define __GST_VIDEOSINK_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GST_TYPE_VIDEOSINK (gst_videosink_get_type()) +#define GST_VIDEOSINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VIDEOSINK, GstVideoSink)) +#define GST_VIDEOSINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VIDEOSINK, GstVideoSink)) +#define GST_IS_VIDEOSINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VIDEOSINK)) +#define GST_IS_VIDEOSINK_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VIDEOSINK)) +#define GST_VIDEOSINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VIDEOSINK, GstVideoSinkClass)) + +#define GST_VIDEOSINK_PAD(obj) (GST_VIDEOSINK (obj)->sinkpad) +#define GST_VIDEOSINK_WIDTH(obj) (GST_VIDEOSINK (obj)->width) +#define GST_VIDEOSINK_HEIGHT(obj) (GST_VIDEOSINK (obj)->height) +#define GST_VIDEOSINK_CLOCK(obj) (GST_VIDEOSINK (obj)->clock) + +typedef struct _GstVideoSink GstVideoSink; +typedef struct _GstVideoSinkClass GstVideoSinkClass; + +struct _GstVideoSink { + GstElement element; + + GstPad *sinkpad; + + gpointer video_out; + + gint width, height; + gint frames_displayed; + guint64 frame_time; + + GstClock *clock; + + GstCaps *formats; +}; + +struct _GstVideoSinkClass { + GstElementClass parent_class; + + /* public virtual methods */ + void (*set_video_out) (GstVideoSink *videosink, gpointer video_out); + void (*push_ui_event) (GstVideoSink *videosink, GstEvent *event); + void (*set_geometry) (GstVideoSink *videosink, gint width, gint height); + + /* signals */ + void (*have_video_out) (GstVideoSink *element, gpointer video_out); + void (*have_size) (GstVideoSink *element, gint width, gint height); + void (*frame_displayed) (GstVideoSink *element); +}; + +GType gst_videosink_get_type (void); + +/* public virtual methods */ +void gst_video_sink_set_video_out (GstVideoSink *videosink, gpointer video_out); +void gst_video_sink_push_ui_event (GstVideoSink *videosink, GstEvent *event); +void gst_video_sink_set_geometry (GstVideoSink *videosink, gint width, + gint height); + +/* public methods to fire signals */ +void gst_video_sink_got_video_out (GstVideoSink *videosink, gpointer video_out); +void gst_video_sink_got_video_size (GstVideoSink *videosink, + gint width, gint height); +void gst_video_sink_frame_displayed (GstVideoSink *videosink); + +/* public methods */ +void gst_video_sink_get_geometry (GstVideoSink *videosink, + gint *width, gint *height); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_VIDEOSINK_H__ */ -- cgit v1.2.1