mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 23:18:52 +00:00
newly added files
Original commit message from CVS: newly added files
This commit is contained in:
parent
3ffce00efc
commit
65285e1acf
9 changed files with 1577 additions and 0 deletions
311
gst/gstbus.c
Normal file
311
gst/gstbus.c
Normal file
|
@ -0,0 +1,311 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstbus.c: GstBus subsystem
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "gst_private.h"
|
||||||
|
#include "gstinfo.h"
|
||||||
|
|
||||||
|
#include "gstbus.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ARG_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gst_bus_class_init (GstBusClass * klass);
|
||||||
|
static void gst_bus_init (GstBus * bus);
|
||||||
|
static void gst_bus_dispose (GObject * object);
|
||||||
|
|
||||||
|
static void gst_bus_set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
static void gst_bus_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
static GstObjectClass *parent_class = NULL;
|
||||||
|
|
||||||
|
/* static guint gst_bus_signals[LAST_SIGNAL] = { 0 }; */
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_bus_get_type (void)
|
||||||
|
{
|
||||||
|
static GType bus_type = 0;
|
||||||
|
|
||||||
|
if (!bus_type) {
|
||||||
|
static const GTypeInfo bus_info = {
|
||||||
|
sizeof (GstBusClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_bus_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstBus),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_bus_init,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
bus_type = g_type_register_static (GST_TYPE_OBJECT, "GstBus", &bus_info, 0);
|
||||||
|
}
|
||||||
|
return bus_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bus_class_init (GstBusClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class;
|
||||||
|
GstObjectClass *gstobject_class;
|
||||||
|
|
||||||
|
gobject_class = (GObjectClass *) klass;
|
||||||
|
gstobject_class = (GstObjectClass *) klass;
|
||||||
|
|
||||||
|
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
|
||||||
|
|
||||||
|
if (!g_thread_supported ())
|
||||||
|
g_thread_init (NULL);
|
||||||
|
|
||||||
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bus_dispose);
|
||||||
|
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bus_set_property);
|
||||||
|
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bus_get_property);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bus_init (GstBus * bus)
|
||||||
|
{
|
||||||
|
bus->queue = g_async_queue_new ();
|
||||||
|
|
||||||
|
if (socketpair (PF_UNIX, SOCK_STREAM, 0, bus->control_socket) < 0) {
|
||||||
|
g_warning ("cannot create io channel");
|
||||||
|
} else {
|
||||||
|
bus->io_channel = g_io_channel_unix_new (bus->control_socket[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bus_dispose (GObject * object)
|
||||||
|
{
|
||||||
|
GstBus *bus;
|
||||||
|
|
||||||
|
bus = GST_BUS (object);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bus_set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBus *bus;
|
||||||
|
|
||||||
|
bus = GST_BUS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bus_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBus *bus;
|
||||||
|
|
||||||
|
bus = GST_BUS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_bus_post (GstBus * bus, GstMessage * message)
|
||||||
|
{
|
||||||
|
gchar c;
|
||||||
|
GstBusSyncReply reply = GST_BUS_PASS;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
|
||||||
|
g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
|
||||||
|
|
||||||
|
if (bus->sync_handler) {
|
||||||
|
reply = bus->sync_handler (bus, message, bus->sync_handler_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (reply) {
|
||||||
|
case GST_BUS_DROP:
|
||||||
|
break;
|
||||||
|
case GST_BUS_PASS:
|
||||||
|
g_async_queue_push (bus->queue, message);
|
||||||
|
c = 'p';
|
||||||
|
write (bus->control_socket[1], &c, 1);
|
||||||
|
break;
|
||||||
|
case GST_BUS_ASYNC:
|
||||||
|
{
|
||||||
|
GMutex *lock = g_mutex_new ();
|
||||||
|
GCond *cond = g_cond_new ();
|
||||||
|
|
||||||
|
message->cond = cond;
|
||||||
|
message->lock = lock;
|
||||||
|
|
||||||
|
GST_DEBUG ("waiting for async delivery of message %p", message);
|
||||||
|
|
||||||
|
g_mutex_lock (lock);
|
||||||
|
g_async_queue_push (bus->queue, message);
|
||||||
|
c = 'p';
|
||||||
|
write (bus->control_socket[1], &c, 1);
|
||||||
|
g_cond_wait (cond, lock);
|
||||||
|
g_mutex_unlock (lock);
|
||||||
|
|
||||||
|
GST_DEBUG ("message %p delivered asynchronously", message);
|
||||||
|
|
||||||
|
g_mutex_free (lock);
|
||||||
|
g_cond_free (cond);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_bus_have_pending (GstBus * bus)
|
||||||
|
{
|
||||||
|
gint length;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
|
||||||
|
|
||||||
|
length = g_async_queue_length (bus->queue);
|
||||||
|
|
||||||
|
return (length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GstMessage *
|
||||||
|
gst_bus_pop (GstBus * bus)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
gchar c;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
|
||||||
|
|
||||||
|
message = g_async_queue_pop (bus->queue);
|
||||||
|
read (bus->control_socket[0], &c, 1);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func, gpointer data)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GST_IS_BUS (bus));
|
||||||
|
|
||||||
|
bus->sync_handler = func;
|
||||||
|
bus->sync_handler_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSource *
|
||||||
|
gst_bus_create_watch (GstBus * bus)
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
|
||||||
|
|
||||||
|
source = g_io_create_watch (bus->io_channel, G_IO_IN);
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GSource *source;
|
||||||
|
GstBus *bus;
|
||||||
|
gint priority;
|
||||||
|
GstBusHandler handler;
|
||||||
|
gpointer user_data;
|
||||||
|
GDestroyNotify notify;
|
||||||
|
} GstBusWatch;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
bus_callback (GIOChannel * channel, GIOCondition cond, GstBusWatch * watch)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (watch->bus), FALSE);
|
||||||
|
|
||||||
|
message = gst_bus_pop (watch->bus);
|
||||||
|
|
||||||
|
if (watch->handler)
|
||||||
|
watch->handler (watch->bus, message, watch->user_data);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bus_destroy (GstBusWatch * watch)
|
||||||
|
{
|
||||||
|
g_print ("destroy\n");
|
||||||
|
if (watch->notify) {
|
||||||
|
watch->notify (watch->user_data);
|
||||||
|
}
|
||||||
|
g_free (watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
gst_bus_add_watch_full (GstBus * bus, gint priority,
|
||||||
|
GstBusHandler handler, gpointer user_data, GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
guint id;
|
||||||
|
GstBusWatch *watch;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUS (bus), 0);
|
||||||
|
|
||||||
|
watch = g_new (GstBusWatch, 1);
|
||||||
|
|
||||||
|
watch->source = gst_bus_create_watch (bus);
|
||||||
|
watch->bus = bus;
|
||||||
|
watch->priority = priority;
|
||||||
|
watch->handler = handler;
|
||||||
|
watch->user_data = user_data;
|
||||||
|
watch->notify = notify;
|
||||||
|
|
||||||
|
if (priority != G_PRIORITY_DEFAULT)
|
||||||
|
g_source_set_priority (watch->source, priority);
|
||||||
|
|
||||||
|
g_source_set_callback (watch->source, (GSourceFunc) bus_callback, watch,
|
||||||
|
(GDestroyNotify) bus_destroy);
|
||||||
|
|
||||||
|
id = g_source_attach (watch->source, NULL);
|
||||||
|
g_source_unref (watch->source);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
gst_bus_add_watch (GstBus * bus, GstBusHandler handler, gpointer user_data)
|
||||||
|
{
|
||||||
|
return gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, handler, user_data,
|
||||||
|
NULL);
|
||||||
|
}
|
94
gst/gstbus.h
Normal file
94
gst/gstbus.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstbus.h: Header for GstBus subsystem
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_BUS_H__
|
||||||
|
#define __GST_BUS_H__
|
||||||
|
|
||||||
|
#include <gst/gsttypes.h>
|
||||||
|
#include <gst/gstmessage.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* --- standard type macros --- */
|
||||||
|
#define GST_TYPE_BUS (gst_bus_get_type ())
|
||||||
|
#define GST_BUS(bus) (G_TYPE_CHECK_INSTANCE_CAST ((bus), GST_TYPE_BUS, GstBus))
|
||||||
|
#define GST_IS_BUS(bus) (G_TYPE_CHECK_INSTANCE_TYPE ((bus), GST_TYPE_BUS))
|
||||||
|
#define GST_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_CAST ((bclass), GST_TYPE_BUS, GstBusClass))
|
||||||
|
#define GST_IS_BUS_CLASS(bclass) (G_TYPE_CHECK_CLASS_TYPE ((bclass), GST_TYPE_BUS))
|
||||||
|
#define GST_BUS_GET_CLASS(bus) (G_TYPE_INSTANCE_GET_CLASS ((bus), GST_TYPE_BUS, GstBusClass))
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_BUS_DROP = 0, /* drop message */
|
||||||
|
GST_BUS_PASS = 1, /* pass message to async queue */
|
||||||
|
GST_BUS_ASYNC = 2, /* pass message to async queue, continue if message is handled */
|
||||||
|
} GstBusSyncReply;
|
||||||
|
|
||||||
|
typedef struct _GstBus GstBus;
|
||||||
|
typedef struct _GstBusClass GstBusClass;
|
||||||
|
|
||||||
|
typedef GstBusSyncReply (*GstBusSyncHandler) (GstBus *bus, GstMessage *message, gpointer data);
|
||||||
|
typedef gboolean (*GstBusHandler) (GstBus *bus, GstMessage *message, gpointer data);
|
||||||
|
|
||||||
|
struct _GstBus {
|
||||||
|
GstObject object;
|
||||||
|
|
||||||
|
GAsyncQueue *queue;
|
||||||
|
|
||||||
|
GstBusSyncHandler sync_handler;
|
||||||
|
gpointer sync_handler_data;
|
||||||
|
|
||||||
|
gint control_socket[2];
|
||||||
|
GIOChannel *io_channel;
|
||||||
|
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstBusClass {
|
||||||
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gst_bus_get_type (void);
|
||||||
|
|
||||||
|
gboolean gst_bus_post (GstBus *bus, GstMessage *message);
|
||||||
|
|
||||||
|
gboolean gst_bus_have_pending (GstBus *bus);
|
||||||
|
const GstMessage* gst_bus_peek (GstBus *bus);
|
||||||
|
GstMessage* gst_bus_pop (GstBus *bus);
|
||||||
|
|
||||||
|
void gst_bus_set_sync_handler (GstBus *bus, GstBusSyncHandler func,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
GSource* gst_bus_create_watch (GstBus *bus);
|
||||||
|
guint gst_bus_add_watch_full (GstBus *bus,
|
||||||
|
gint priority,
|
||||||
|
GstBusHandler handler,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
guint gst_bus_add_watch (GstBus *bus,
|
||||||
|
GstBusHandler handler,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_BUS_H__ */
|
261
gst/gstiterator.c
Normal file
261
gst/gstiterator.c
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstiterator.h: Base class for iterating lists.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gst_private.h"
|
||||||
|
#include <gst/gstiterator.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_iterator_init (GstIterator * it,
|
||||||
|
GMutex * lock,
|
||||||
|
guint32 * master_cookie,
|
||||||
|
GstIteratorNextFunction next,
|
||||||
|
GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
|
||||||
|
{
|
||||||
|
it->lock = lock;
|
||||||
|
it->master_cookie = master_cookie;
|
||||||
|
it->cookie = *master_cookie;
|
||||||
|
it->next = next;
|
||||||
|
it->resync = resync;
|
||||||
|
it->free = free;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstIterator *
|
||||||
|
gst_iterator_new (guint size,
|
||||||
|
GMutex * lock,
|
||||||
|
guint32 * master_cookie,
|
||||||
|
GstIteratorNextFunction next,
|
||||||
|
GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
|
||||||
|
{
|
||||||
|
GstIterator *result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (size >= sizeof (GstIterator), NULL);
|
||||||
|
g_return_val_if_fail (master_cookie != NULL, NULL);
|
||||||
|
g_return_val_if_fail (next != NULL, NULL);
|
||||||
|
g_return_val_if_fail (resync != NULL, NULL);
|
||||||
|
g_return_val_if_fail (free != NULL, NULL);
|
||||||
|
|
||||||
|
result = g_malloc (size);
|
||||||
|
gst_iterator_init (result, lock, master_cookie, next, resync, free);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstIteratorResult
|
||||||
|
gst_iterator_next (GstIterator * it, gpointer * elem)
|
||||||
|
{
|
||||||
|
GstIteratorResult result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR);
|
||||||
|
g_return_val_if_fail (elem != NULL, GST_ITERATOR_ERROR);
|
||||||
|
|
||||||
|
if (it->lock)
|
||||||
|
g_mutex_lock (it->lock);
|
||||||
|
if (*it->master_cookie != it->cookie) {
|
||||||
|
result = GST_ITERATOR_RESYNC;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = it->next (it, elem);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (it->lock)
|
||||||
|
g_mutex_unlock (it->lock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_iterator_resync (GstIterator * it)
|
||||||
|
{
|
||||||
|
g_return_if_fail (it != NULL);
|
||||||
|
|
||||||
|
if (it->lock)
|
||||||
|
g_mutex_lock (it->lock);
|
||||||
|
it->resync (it);
|
||||||
|
it->cookie = *it->master_cookie;
|
||||||
|
if (it->lock)
|
||||||
|
g_mutex_unlock (it->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_iterator_free (GstIterator * it)
|
||||||
|
{
|
||||||
|
g_return_if_fail (it != NULL);
|
||||||
|
|
||||||
|
it->free (it);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _GstIteratorFilter
|
||||||
|
{
|
||||||
|
GstIterator iterator;
|
||||||
|
GstIterator *slave;
|
||||||
|
|
||||||
|
GCompareFunc func;
|
||||||
|
gpointer user_data;
|
||||||
|
|
||||||
|
gboolean compare;
|
||||||
|
gboolean first;
|
||||||
|
gboolean found;
|
||||||
|
|
||||||
|
} GstIteratorFilter;
|
||||||
|
|
||||||
|
static GstIteratorResult
|
||||||
|
filter_next (GstIteratorFilter * it, gpointer * elem)
|
||||||
|
{
|
||||||
|
GstIteratorResult result;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
|
||||||
|
*elem = NULL;
|
||||||
|
|
||||||
|
if (it->found)
|
||||||
|
return GST_ITERATOR_DONE;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
gpointer item;
|
||||||
|
|
||||||
|
result = gst_iterator_next (it->slave, &item);
|
||||||
|
switch (result) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
if (GST_ITERATOR (it)->lock)
|
||||||
|
g_mutex_unlock (GST_ITERATOR (it)->lock);
|
||||||
|
if (it->compare) {
|
||||||
|
if (it->func (item, it->user_data) == 0) {
|
||||||
|
*elem = item;
|
||||||
|
done = TRUE;
|
||||||
|
if (it->first)
|
||||||
|
it->found = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it->func (item, it->user_data);
|
||||||
|
}
|
||||||
|
if (GST_ITERATOR (it)->lock)
|
||||||
|
g_mutex_lock (GST_ITERATOR (it)->lock);
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_RESYNC:
|
||||||
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_resync (GstIteratorFilter * it)
|
||||||
|
{
|
||||||
|
gst_iterator_resync (it->slave);
|
||||||
|
it->found = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_uninit (GstIteratorFilter * it)
|
||||||
|
{
|
||||||
|
it->slave->lock = GST_ITERATOR (it)->lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_free (GstIteratorFilter * it)
|
||||||
|
{
|
||||||
|
filter_uninit (it);
|
||||||
|
gst_iterator_free (it->slave);
|
||||||
|
g_free (it);
|
||||||
|
}
|
||||||
|
|
||||||
|
GstIterator *
|
||||||
|
gst_iterator_filter (GstIterator * it, gpointer user_data, GCompareFunc func)
|
||||||
|
{
|
||||||
|
GstIteratorFilter *result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (it != NULL, NULL);
|
||||||
|
g_return_val_if_fail (func != NULL, NULL);
|
||||||
|
|
||||||
|
result = (GstIteratorFilter *) gst_iterator_new (sizeof (GstIteratorFilter),
|
||||||
|
it->lock, it->master_cookie,
|
||||||
|
(GstIteratorNextFunction) filter_next,
|
||||||
|
(GstIteratorResyncFunction) filter_resync,
|
||||||
|
(GstIteratorFreeFunction) filter_free);
|
||||||
|
it->lock = NULL;
|
||||||
|
result->func = func;
|
||||||
|
result->user_data = user_data;
|
||||||
|
result->slave = it;
|
||||||
|
result->compare = TRUE;
|
||||||
|
result->first = FALSE;
|
||||||
|
result->found = FALSE;
|
||||||
|
|
||||||
|
return GST_ITERATOR (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_iterator_foreach (GstIterator * it, GFunc function, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstIteratorFilter filter;
|
||||||
|
gpointer dummy;
|
||||||
|
|
||||||
|
g_return_if_fail (it != NULL);
|
||||||
|
g_return_if_fail (function != NULL);
|
||||||
|
|
||||||
|
gst_iterator_init (GST_ITERATOR (&filter),
|
||||||
|
it->lock, it->master_cookie,
|
||||||
|
(GstIteratorNextFunction) filter_next,
|
||||||
|
(GstIteratorResyncFunction) filter_resync,
|
||||||
|
(GstIteratorFreeFunction) filter_uninit);
|
||||||
|
it->lock = NULL;
|
||||||
|
filter.func = (GCompareFunc) function;
|
||||||
|
filter.user_data = user_data;
|
||||||
|
filter.slave = it;
|
||||||
|
filter.compare = FALSE;
|
||||||
|
filter.first = FALSE;
|
||||||
|
filter.found = FALSE;
|
||||||
|
gst_iterator_next (GST_ITERATOR (&filter), &dummy);
|
||||||
|
gst_iterator_free (GST_ITERATOR (&filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
gpointer
|
||||||
|
gst_iterator_find_custom (GstIterator * it, gpointer user_data,
|
||||||
|
GCompareFunc func)
|
||||||
|
{
|
||||||
|
GstIteratorFilter filter;
|
||||||
|
gpointer result = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (it != NULL, NULL);
|
||||||
|
g_return_val_if_fail (func != NULL, NULL);
|
||||||
|
|
||||||
|
gst_iterator_init (GST_ITERATOR (&filter),
|
||||||
|
it->lock, it->master_cookie,
|
||||||
|
(GstIteratorNextFunction) filter_next,
|
||||||
|
(GstIteratorResyncFunction) filter_resync,
|
||||||
|
(GstIteratorFreeFunction) filter_uninit);
|
||||||
|
it->lock = NULL;
|
||||||
|
filter.func = func;
|
||||||
|
filter.user_data = user_data;
|
||||||
|
filter.slave = it;
|
||||||
|
filter.compare = TRUE;
|
||||||
|
filter.first = TRUE;
|
||||||
|
filter.found = FALSE;
|
||||||
|
|
||||||
|
gst_iterator_next (GST_ITERATOR (&filter), &result);
|
||||||
|
gst_iterator_free (GST_ITERATOR (&filter));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
78
gst/gstiterator.h
Normal file
78
gst/gstiterator.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstiterator.h: Header for GstIterator
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_ITERATOR_H__
|
||||||
|
#define __GST_ITERATOR_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_ITERATOR_DONE = 0,
|
||||||
|
GST_ITERATOR_OK = 1,
|
||||||
|
GST_ITERATOR_RESYNC = 2,
|
||||||
|
GST_ITERATOR_ERROR = 3,
|
||||||
|
} GstIteratorResult;
|
||||||
|
|
||||||
|
typedef struct _GstIterator GstIterator;
|
||||||
|
|
||||||
|
typedef GstIteratorResult (*GstIteratorNextFunction) (GstIterator *it, gpointer *result);
|
||||||
|
typedef void (*GstIteratorResyncFunction) (GstIterator *it);
|
||||||
|
typedef void (*GstIteratorFreeFunction) (GstIterator *it);
|
||||||
|
|
||||||
|
#define GST_ITERATOR(it) ((GstIterator*)(it))
|
||||||
|
#define GST_ITERATOR_LOCK(it) (GST_ITERATOR(it)->lock)
|
||||||
|
#define GST_ITERATOR_COOKIE(it) (GST_ITERATOR(it)->cookie)
|
||||||
|
#define GST_ITERATOR_ORIG_COOKIE(it) (GST_ITERATOR(it)->master_cookie)
|
||||||
|
|
||||||
|
struct _GstIterator {
|
||||||
|
GstIteratorNextFunction next;
|
||||||
|
GstIteratorResyncFunction resync;
|
||||||
|
GstIteratorFreeFunction free;
|
||||||
|
|
||||||
|
GMutex *lock;
|
||||||
|
guint32 cookie; /* cookie of the iterator */
|
||||||
|
guint32 *master_cookie; /* pointer to guint32 holding the cookie when this
|
||||||
|
iterator was created */
|
||||||
|
};
|
||||||
|
|
||||||
|
GstIterator* gst_iterator_new (guint size,
|
||||||
|
GMutex *lock,
|
||||||
|
guint32 *master_cookie,
|
||||||
|
GstIteratorNextFunction next,
|
||||||
|
GstIteratorResyncFunction resync,
|
||||||
|
GstIteratorFreeFunction free);
|
||||||
|
|
||||||
|
GstIteratorResult gst_iterator_next (GstIterator *it, gpointer *result);
|
||||||
|
void gst_iterator_resync (GstIterator *it);
|
||||||
|
void gst_iterator_free (GstIterator *it);
|
||||||
|
|
||||||
|
void gst_iterator_foreach (GstIterator *it, GFunc function,
|
||||||
|
gpointer user_data);
|
||||||
|
gpointer gst_iterator_find_custom (GstIterator *it, gpointer user_data,
|
||||||
|
GCompareFunc func);
|
||||||
|
GstIterator* gst_iterator_filter (GstIterator *it, gpointer user_data,
|
||||||
|
GCompareFunc func);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_ITERATOR_H__ */
|
214
gst/gstmessage.c
Normal file
214
gst/gstmessage.c
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstmessage.c: GstMessage subsystem
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h> /* memcpy */
|
||||||
|
|
||||||
|
#include "gst_private.h"
|
||||||
|
#include "gstdata_private.h"
|
||||||
|
#include "gstinfo.h"
|
||||||
|
#include "gstmemchunk.h"
|
||||||
|
#include "gstmessage.h"
|
||||||
|
#include "gsttag.h"
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_TRACE
|
||||||
|
/* #define GST_WITH_ALLOC_TRACE */
|
||||||
|
#include "gsttrace.h"
|
||||||
|
static GstAllocTrace *_message_trace;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static GstMemChunk *chunk;
|
||||||
|
|
||||||
|
/* #define MEMPROF */
|
||||||
|
|
||||||
|
GType _gst_message_type;
|
||||||
|
|
||||||
|
void
|
||||||
|
_gst_message_initialize (void)
|
||||||
|
{
|
||||||
|
/* register the type */
|
||||||
|
_gst_message_type = g_boxed_type_register_static ("GstMessage",
|
||||||
|
(GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref);
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_TRACE
|
||||||
|
_message_trace = gst_alloc_trace_register (GST_MESSAGE_TRACE_NAME);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
chunk = gst_mem_chunk_new ("GstMessageChunk", sizeof (GstMessage),
|
||||||
|
sizeof (GstMessage) * 50, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstMessage *
|
||||||
|
_gst_message_copy (GstMessage * message)
|
||||||
|
{
|
||||||
|
GstMessage *copy;
|
||||||
|
|
||||||
|
copy = gst_mem_chunk_alloc (chunk);
|
||||||
|
#ifndef GST_DISABLE_TRACE
|
||||||
|
gst_alloc_trace_new (_message_trace, copy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memcpy (copy, message, sizeof (GstMessage));
|
||||||
|
|
||||||
|
/* FIXME copy/ref additional fields */
|
||||||
|
switch (GST_MESSAGE_TYPE (message)) {
|
||||||
|
case GST_MESSAGE_TAG:
|
||||||
|
copy->message_data.structure.structure =
|
||||||
|
gst_tag_list_copy ((GstTagList *) message->message_data.structure.
|
||||||
|
structure);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gst_message_free (GstMessage * message)
|
||||||
|
{
|
||||||
|
GST_CAT_INFO (GST_CAT_MESSAGE, "freeing message %p", message);
|
||||||
|
|
||||||
|
if (GST_MESSAGE_SRC (message)) {
|
||||||
|
gst_object_unref (GST_MESSAGE_SRC (message));
|
||||||
|
}
|
||||||
|
if (message->lock) {
|
||||||
|
g_mutex_lock (message->lock);
|
||||||
|
g_cond_signal (message->cond);
|
||||||
|
g_mutex_unlock (message->lock);
|
||||||
|
}
|
||||||
|
switch (GST_MESSAGE_TYPE (message)) {
|
||||||
|
case GST_MESSAGE_ERROR:
|
||||||
|
g_error_free (GST_MESSAGE_ERROR_ERROR (message));
|
||||||
|
g_free (GST_MESSAGE_ERROR_DEBUG (message));
|
||||||
|
break;
|
||||||
|
case GST_MESSAGE_TAG:
|
||||||
|
if (GST_IS_TAG_LIST (message->message_data.tag.list)) {
|
||||||
|
gst_tag_list_free (message->message_data.tag.list);
|
||||||
|
} else {
|
||||||
|
g_warning ("tag message %p didn't contain a valid tag list!", message);
|
||||||
|
GST_ERROR ("tag message %p didn't contain a valid tag list!", message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_GST_DATA_DISPOSE (GST_DATA (message));
|
||||||
|
#ifndef GST_DISABLE_TRACE
|
||||||
|
gst_alloc_trace_free (_message_trace, message);
|
||||||
|
#endif
|
||||||
|
gst_mem_chunk_free (chunk, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_message_get_type (void)
|
||||||
|
{
|
||||||
|
return _gst_message_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_message_new:
|
||||||
|
* @type: The type of the new message
|
||||||
|
*
|
||||||
|
* Allocate a new message of the given type.
|
||||||
|
*
|
||||||
|
* Returns: A new message.
|
||||||
|
*/
|
||||||
|
GstMessage *
|
||||||
|
gst_message_new (GstMessageType type, GstObject * src)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
|
||||||
|
message = gst_mem_chunk_alloc0 (chunk);
|
||||||
|
#ifndef GST_DISABLE_TRACE
|
||||||
|
gst_alloc_trace_new (_message_trace, message);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GST_CAT_INFO (GST_CAT_MESSAGE, "creating new message %p %d", message, type);
|
||||||
|
|
||||||
|
_GST_DATA_INIT (GST_DATA (message),
|
||||||
|
_gst_message_type,
|
||||||
|
0,
|
||||||
|
(GstDataFreeFunction) _gst_message_free,
|
||||||
|
(GstDataCopyFunction) _gst_message_copy);
|
||||||
|
|
||||||
|
GST_MESSAGE_TYPE (message) = type;
|
||||||
|
GST_MESSAGE_TIMESTAMP (message) = G_GINT64_CONSTANT (0);
|
||||||
|
gst_object_ref (src);
|
||||||
|
GST_MESSAGE_SRC (message) = src;
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_message_new_eos:
|
||||||
|
*
|
||||||
|
* Create a new eos message.
|
||||||
|
*
|
||||||
|
* Returns: The new eos message.
|
||||||
|
*/
|
||||||
|
GstMessage *
|
||||||
|
gst_message_new_eos (GstObject * src)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
|
||||||
|
message = gst_message_new (GST_MESSAGE_EOS, src);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_message_new_error:
|
||||||
|
*
|
||||||
|
* Create a new error message.
|
||||||
|
*
|
||||||
|
* Returns: The new error message.
|
||||||
|
*/
|
||||||
|
GstMessage *
|
||||||
|
gst_message_new_error (GstObject * src, GError * error, gchar * debug)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
|
||||||
|
message = gst_message_new (GST_MESSAGE_ERROR, src);
|
||||||
|
GST_MESSAGE_ERROR_ERROR (message) = error;
|
||||||
|
GST_MESSAGE_ERROR_DEBUG (message) = debug;
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_message_new_tag:
|
||||||
|
*
|
||||||
|
* Create a new tag message.
|
||||||
|
*
|
||||||
|
* Returns: The new tag message.
|
||||||
|
*/
|
||||||
|
GstMessage *
|
||||||
|
gst_message_new_tag (GstObject * src, GstTagList * tag_list)
|
||||||
|
{
|
||||||
|
GstMessage *message;
|
||||||
|
|
||||||
|
message = gst_message_new (GST_MESSAGE_TAG, src);
|
||||||
|
GST_MESSAGE_TAG_LIST (message) = tag_list;
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
106
gst/gstmessage.h
Normal file
106
gst/gstmessage.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* gstmessage.h: Header for GstMessage subsystem
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_MESSAGE_H__
|
||||||
|
#define __GST_MESSAGE_H__
|
||||||
|
|
||||||
|
#include <gst/gsttypes.h>
|
||||||
|
#include <gst/gstdata.h>
|
||||||
|
#include <gst/gstobject.h>
|
||||||
|
#include <gst/gsttag.h>
|
||||||
|
#include <gst/gststructure.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GST_EXPORT GType _gst_message_type;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_MESSAGE_UNKNOWN = 0,
|
||||||
|
GST_MESSAGE_EOS = 1,
|
||||||
|
GST_MESSAGE_ERROR = 2,
|
||||||
|
GST_MESSAGE_WARNING = 3,
|
||||||
|
GST_MESSAGE_INFO = 4,
|
||||||
|
GST_MESSAGE_TAG = 5,
|
||||||
|
GST_MESSAGE_BUFFERING = 6,
|
||||||
|
GST_MESSAGE_STATE_CHANGED = 7,
|
||||||
|
GST_MESSAGE_STEP_DONE = 8,
|
||||||
|
} GstMessageType;
|
||||||
|
|
||||||
|
#define GST_MESSAGE_TRACE_NAME "GstMessage"
|
||||||
|
|
||||||
|
#define GST_TYPE_MESSAGE (_gst_message_type)
|
||||||
|
#define GST_MESSAGE(message) ((GstMessage*)(message))
|
||||||
|
#define GST_IS_MESSAGE(message) (GST_DATA_TYPE(message) == GST_TYPE_MESSAGE)
|
||||||
|
|
||||||
|
#define GST_MESSAGE_TYPE(message) (GST_MESSAGE(message)->type)
|
||||||
|
#define GST_MESSAGE_TIMESTAMP(message) (GST_MESSAGE(message)->timestamp)
|
||||||
|
#define GST_MESSAGE_SRC(message) (GST_MESSAGE(message)->src)
|
||||||
|
|
||||||
|
#define GST_MESSAGE_TAG_LIST(message) (GST_MESSAGE(message)->message_data.tag.list)
|
||||||
|
|
||||||
|
#define GST_MESSAGE_ERROR_ERROR(message) (GST_MESSAGE(message)->message_data.error.error)
|
||||||
|
#define GST_MESSAGE_ERROR_DEBUG(message) (GST_MESSAGE(message)->message_data.error.debug)
|
||||||
|
|
||||||
|
struct _GstMessage {
|
||||||
|
GstData data;
|
||||||
|
|
||||||
|
GstMessageType type;
|
||||||
|
guint64 timestamp;
|
||||||
|
GstObject *src;
|
||||||
|
|
||||||
|
GMutex *lock; /* lock and cond for async delivery */
|
||||||
|
GCond *cond;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
GError *error;
|
||||||
|
gchar *debug;
|
||||||
|
} error;
|
||||||
|
struct {
|
||||||
|
GstStructure *structure;
|
||||||
|
} structure;
|
||||||
|
struct {
|
||||||
|
GstTagList *list;
|
||||||
|
} tag;
|
||||||
|
} message_data;
|
||||||
|
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
};
|
||||||
|
|
||||||
|
void _gst_message_initialize (void);
|
||||||
|
|
||||||
|
GType gst_message_get_type (void);
|
||||||
|
GstMessage* gst_message_new (GstMessageType type, GstObject *src);
|
||||||
|
|
||||||
|
/* refcounting */
|
||||||
|
#define gst_message_ref(ev) GST_MESSAGE (gst_data_ref (GST_DATA (ev)))
|
||||||
|
#define gst_message_ref_by_count(ev,c) GST_MESSAGE (gst_data_ref_by_count (GST_DATA (ev), c))
|
||||||
|
#define gst_message_unref(ev) gst_data_unref (GST_DATA (ev))
|
||||||
|
/* copy message */
|
||||||
|
#define gst_message_copy(ev) GST_MESSAGE (gst_data_copy (GST_DATA (ev)))
|
||||||
|
|
||||||
|
GstMessage* gst_message_new_eos (GstObject *src);
|
||||||
|
GstMessage* gst_message_new_error (GstObject *src, GError *error, gchar *debug);
|
||||||
|
GstMessage* gst_message_new_tag (GstObject *src, GstTagList *tag_list);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_MESSAGE_H__ */
|
118
gst/gsttask.c
Normal file
118
gst/gsttask.c
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
|
||||||
|
* 2000 Wim Taymans <wim.taymans@chello.be>
|
||||||
|
*
|
||||||
|
* gsttask.c: Streaming tasks
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gst_private.h"
|
||||||
|
|
||||||
|
#include "gstinfo.h"
|
||||||
|
#include "gsttask.h"
|
||||||
|
|
||||||
|
static void gst_task_class_init (GstTaskClass * klass);
|
||||||
|
static void gst_task_init (GstTask * sched);
|
||||||
|
static void gst_task_dispose (GObject * object);
|
||||||
|
|
||||||
|
static GstObjectClass *parent_class = NULL;
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_task_get_type (void)
|
||||||
|
{
|
||||||
|
static GType _gst_task_type = 0;
|
||||||
|
|
||||||
|
if (!_gst_task_type) {
|
||||||
|
static const GTypeInfo task_info = {
|
||||||
|
sizeof (GstTaskClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_task_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstTask),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_task_init,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
_gst_task_type =
|
||||||
|
g_type_register_static (GST_TYPE_OBJECT, "GstTask",
|
||||||
|
&task_info, G_TYPE_FLAG_ABSTRACT);
|
||||||
|
}
|
||||||
|
return _gst_task_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_task_class_init (GstTaskClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class;
|
||||||
|
|
||||||
|
gobject_class = (GObjectClass *) klass;
|
||||||
|
|
||||||
|
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
|
||||||
|
|
||||||
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_task_dispose);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_task_init (GstTask * sched)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_task_dispose (GObject * object)
|
||||||
|
{
|
||||||
|
GstTask *task = GST_TASK (object);
|
||||||
|
|
||||||
|
/* thse lists should all be NULL */
|
||||||
|
GST_DEBUG ("task %p dispose", task);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_task_start (GstTask * task)
|
||||||
|
{
|
||||||
|
GstTaskClass *tclass;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_TASK (task), result);
|
||||||
|
|
||||||
|
tclass = GST_TASK_GET_CLASS (task);
|
||||||
|
|
||||||
|
if (tclass->start)
|
||||||
|
result = tclass->start (task);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_task_stop (GstTask * task)
|
||||||
|
{
|
||||||
|
GstTaskClass *tclass;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_TASK (task), result);
|
||||||
|
|
||||||
|
tclass = GST_TASK_GET_CLASS (task);
|
||||||
|
|
||||||
|
if (tclass->stop)
|
||||||
|
result = tclass->stop (task);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
64
gst/gsttask.h
Normal file
64
gst/gsttask.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||||
|
* <2004> Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_TASK_H__
|
||||||
|
#define __GST_TASK_H__
|
||||||
|
|
||||||
|
#include <gst/gstobject.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef void (*GstTaskFunction) (void *data);
|
||||||
|
|
||||||
|
/* --- standard type macros --- */
|
||||||
|
#define GST_TYPE_TASK (gst_task_get_type ())
|
||||||
|
#define GST_TASK(task) (G_TYPE_CHECK_INSTANCE_CAST ((task), GST_TYPE_TASK, GstTask))
|
||||||
|
#define GST_IS_TASK(task) (G_TYPE_CHECK_INSTANCE_TYPE ((task), GST_TYPE_TASK))
|
||||||
|
#define GST_TASK_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), GST_TYPE_TASK, GstTaskClass))
|
||||||
|
#define GST_IS_TASK_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), GST_TYPE_TASK))
|
||||||
|
#define GST_TASK_GET_CLASS(task) (G_TYPE_INSTANCE_GET_CLASS ((task), GST_TYPE_TASK, GstTaskClass))
|
||||||
|
|
||||||
|
typedef struct _GstTask GstTask;
|
||||||
|
typedef struct _GstTaskClass GstTaskClass;
|
||||||
|
|
||||||
|
struct _GstTask {
|
||||||
|
GstObject object;
|
||||||
|
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstTaskClass {
|
||||||
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
|
gboolean (*start) (GstTask *task);
|
||||||
|
gboolean (*stop) (GstTask *task);
|
||||||
|
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gst_task_get_type (void);
|
||||||
|
|
||||||
|
gboolean gst_task_start (GstTask *task);
|
||||||
|
gboolean gst_task_stop (GstTask *task);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_TASK_H__ */
|
||||||
|
|
331
gst/schedulers/threadscheduler.c
Normal file
331
gst/schedulers/threadscheduler.c
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
/* GStreamer2
|
||||||
|
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
|
||||||
|
*
|
||||||
|
* threadscheduler.c: scheduler using threads
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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 Library General Public
|
||||||
|
* License along with this library; 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 <gst/gst.h>
|
||||||
|
#include "../gst-i18n-lib.h"
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_STATIC (debug_scheduler);
|
||||||
|
#define GST_CAT_DEFAULT debug_scheduler
|
||||||
|
|
||||||
|
#define GST_TYPE_THREAD_SCHEDULER \
|
||||||
|
(gst_thread_scheduler_get_type ())
|
||||||
|
#define GST_THREAD_SCHEDULER(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_THREAD_SCHEDULER,GstThreadScheduler))
|
||||||
|
#define GST_THREAD_SCHEDULER_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_THREAD_SCHEDULER,GstThreadSchedulerClass))
|
||||||
|
#define GST_IS_THREAD_SCHEDULER(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_THREAD_SCHEDULER))
|
||||||
|
#define GST_IS_THREAD_SCHEDULER_CLASS(obj) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_THREAD_SCHEDULER))
|
||||||
|
|
||||||
|
#define SCHED(element) (GST_THREAD_SCHEDULER ((element)->sched))
|
||||||
|
|
||||||
|
GType gst_thread_scheduler_get_type (void);
|
||||||
|
|
||||||
|
typedef struct _GstThreadScheduler GstThreadScheduler;
|
||||||
|
typedef struct _GstThreadSchedulerClass GstThreadSchedulerClass;
|
||||||
|
|
||||||
|
struct _GstThreadScheduler
|
||||||
|
{
|
||||||
|
GstScheduler scheduler;
|
||||||
|
|
||||||
|
GThreadPool *pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstThreadSchedulerClass
|
||||||
|
{
|
||||||
|
GstSchedulerClass scheduler_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ELEMENT_PRIVATE(element) GST_ELEMENT (element)->sched_private
|
||||||
|
#define PAD_PRIVATE(pad) (GST_REAL_PAD (pad))->sched_private
|
||||||
|
|
||||||
|
#define GST_TYPE_THREAD_SCHEDULER_TASK \
|
||||||
|
(gst_thread_scheduler_task_get_type ())
|
||||||
|
#define GST_THREAD_SCHEDULER_TASK(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_THREAD_SCHEDULER_TASK,GstThreadSchedulerTask))
|
||||||
|
#define GST_THREAD_SCHEDULER_TASK_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_THREAD_SCHEDULER_TASK,GstThreadSchedulerTaskClass))
|
||||||
|
#define GST_IS_THREAD_SCHEDULER_TASK(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_THREAD_SCHEDULER_TASK))
|
||||||
|
#define GST_IS_THREAD_SCHEDULER_TASK_CLASS(obj) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_THREAD_SCHEDULER_TASK))
|
||||||
|
|
||||||
|
typedef struct _GstThreadSchedulerTask GstThreadSchedulerTask;
|
||||||
|
typedef struct _GstThreadSchedulerTaskClass GstThreadSchedulerTaskClass;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STATE_STOPPED,
|
||||||
|
STATE_STARTED
|
||||||
|
} TaskState;
|
||||||
|
|
||||||
|
|
||||||
|
struct _GstThreadSchedulerTask
|
||||||
|
{
|
||||||
|
GstTask task;
|
||||||
|
|
||||||
|
TaskState state;
|
||||||
|
GMutex *lock;
|
||||||
|
|
||||||
|
GstTaskFunction func;
|
||||||
|
gpointer data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstThreadSchedulerTaskClass
|
||||||
|
{
|
||||||
|
GstTaskClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gst_thread_scheduler_task_class_init (gpointer g_class,
|
||||||
|
gpointer data);
|
||||||
|
static void gst_thread_scheduler_task_init (GstThreadSchedulerTask * object);
|
||||||
|
|
||||||
|
static gboolean gst_thread_scheduler_task_start (GstTask * task);
|
||||||
|
static gboolean gst_thread_scheduler_task_stop (GstTask * task);
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_thread_scheduler_task_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (object_type == 0) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GstThreadSchedulerTaskClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
gst_thread_scheduler_task_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstThreadSchedulerTask),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_thread_scheduler_task_init
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type =
|
||||||
|
g_type_register_static (GST_TYPE_TASK,
|
||||||
|
"GstThreadSchedulerTask", &object_info, 0);
|
||||||
|
}
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_task_class_init (gpointer klass, gpointer class_data)
|
||||||
|
{
|
||||||
|
GstTaskClass *task = GST_TASK_CLASS (klass);
|
||||||
|
|
||||||
|
task->start = gst_thread_scheduler_task_start;
|
||||||
|
task->stop = gst_thread_scheduler_task_stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_task_init (GstThreadSchedulerTask * task)
|
||||||
|
{
|
||||||
|
task->state = STATE_STOPPED;
|
||||||
|
task->lock = g_mutex_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_thread_scheduler_task_start (GstTask * task)
|
||||||
|
{
|
||||||
|
GstThreadSchedulerTask *ttask = GST_THREAD_SCHEDULER_TASK (task);
|
||||||
|
GstThreadScheduler *tsched =
|
||||||
|
GST_THREAD_SCHEDULER (gst_object_get_parent (GST_OBJECT (task)));
|
||||||
|
|
||||||
|
g_mutex_lock (ttask->lock);
|
||||||
|
if (ttask->state != STATE_STARTED) {
|
||||||
|
ttask->state = STATE_STARTED;
|
||||||
|
|
||||||
|
g_thread_pool_push (tsched->pool, task, NULL);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (ttask->lock);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_thread_scheduler_task_stop (GstTask * task)
|
||||||
|
{
|
||||||
|
GstThreadSchedulerTask *ttask = GST_THREAD_SCHEDULER_TASK (task);
|
||||||
|
|
||||||
|
g_mutex_lock (ttask->lock);
|
||||||
|
if (ttask->state != STATE_STOPPED) {
|
||||||
|
ttask->state = STATE_STOPPED;
|
||||||
|
}
|
||||||
|
g_mutex_unlock (ttask->lock);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void gst_thread_scheduler_class_init (gpointer g_class, gpointer data);
|
||||||
|
static void gst_thread_scheduler_init (GstThreadScheduler * object);
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_thread_scheduler_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (object_type == 0) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GstThreadSchedulerClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
gst_thread_scheduler_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstThreadScheduler),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_thread_scheduler_init
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type =
|
||||||
|
g_type_register_static (GST_TYPE_SCHEDULER,
|
||||||
|
"GstThreadScheduler", &object_info, 0);
|
||||||
|
}
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gst_thread_scheduler_setup (GstScheduler * sched);
|
||||||
|
static void gst_thread_scheduler_reset (GstScheduler * sched);
|
||||||
|
static void gst_thread_scheduler_add_element (GstScheduler * sched,
|
||||||
|
GstElement * element);
|
||||||
|
static void gst_thread_scheduler_remove_element (GstScheduler * sched,
|
||||||
|
GstElement * element);
|
||||||
|
static GstTask *gst_thread_scheduler_create_task (GstScheduler * sched,
|
||||||
|
GstTaskFunction func, gpointer data);
|
||||||
|
static void gst_thread_scheduler_show (GstScheduler * scheduler);
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_class_init (gpointer klass, gpointer class_data)
|
||||||
|
{
|
||||||
|
GstSchedulerClass *scheduler = GST_SCHEDULER_CLASS (klass);
|
||||||
|
|
||||||
|
scheduler->setup = gst_thread_scheduler_setup;
|
||||||
|
scheduler->reset = gst_thread_scheduler_reset;
|
||||||
|
scheduler->add_element = gst_thread_scheduler_add_element;
|
||||||
|
scheduler->remove_element = gst_thread_scheduler_remove_element;
|
||||||
|
scheduler->create_task = gst_thread_scheduler_create_task;
|
||||||
|
scheduler->clock_wait = NULL;
|
||||||
|
scheduler->show = gst_thread_scheduler_show;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_func (GstThreadSchedulerTask * task,
|
||||||
|
GstThreadScheduler * sched)
|
||||||
|
{
|
||||||
|
gst_object_ref (GST_OBJECT (task));
|
||||||
|
GST_DEBUG_OBJECT (sched, "Entering task %p, thread %p", task,
|
||||||
|
g_thread_self ());
|
||||||
|
g_mutex_lock (task->lock);
|
||||||
|
while (task->state == STATE_STARTED) {
|
||||||
|
g_mutex_unlock (task->lock);
|
||||||
|
task->func (task->data);
|
||||||
|
g_mutex_lock (task->lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (task->lock);
|
||||||
|
GST_DEBUG_OBJECT (sched, "Exit task %p, thread %p", task, g_thread_self ());
|
||||||
|
gst_object_unref (GST_OBJECT (task));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_init (GstThreadScheduler * scheduler)
|
||||||
|
{
|
||||||
|
scheduler->pool = g_thread_pool_new (
|
||||||
|
(GFunc) gst_thread_scheduler_func, scheduler, -1, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstTask *
|
||||||
|
gst_thread_scheduler_create_task (GstScheduler * sched, GstTaskFunction func,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GstThreadSchedulerTask *task;
|
||||||
|
|
||||||
|
task =
|
||||||
|
GST_THREAD_SCHEDULER_TASK (g_object_new (GST_TYPE_THREAD_SCHEDULER_TASK,
|
||||||
|
NULL));
|
||||||
|
gst_object_set_parent (GST_OBJECT (task), GST_OBJECT (sched));
|
||||||
|
task->func = func;
|
||||||
|
task->data = data;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (sched, "Created task %p", task);
|
||||||
|
|
||||||
|
return GST_TASK (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_setup (GstScheduler * sched)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_reset (GstScheduler * sched)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_add_element (GstScheduler * scheduler,
|
||||||
|
GstElement * element)
|
||||||
|
{
|
||||||
|
g_print ("add element\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_remove_element (GstScheduler * scheduler,
|
||||||
|
GstElement * element)
|
||||||
|
{
|
||||||
|
GstThreadSchedulerTask *task;;
|
||||||
|
|
||||||
|
task = ELEMENT_PRIVATE (element);
|
||||||
|
if (task) {
|
||||||
|
g_object_unref (G_OBJECT (task));
|
||||||
|
ELEMENT_PRIVATE (element) = NULL;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_thread_scheduler_show (GstScheduler * scheduler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_init (GstPlugin * plugin)
|
||||||
|
{
|
||||||
|
GstSchedulerFactory *factory;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (debug_scheduler, "thread", 0, "thread scheduler");
|
||||||
|
|
||||||
|
factory = gst_scheduler_factory_new ("thread",
|
||||||
|
"A scheduler using threads", GST_TYPE_THREAD_SCHEDULER);
|
||||||
|
if (factory == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "gstthreadscheduler",
|
||||||
|
"a thread scheduler", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE,
|
||||||
|
GST_ORIGIN)
|
Loading…
Reference in a new issue