gst-indent run on core

Original commit message from CVS:
gst-indent run on core
This commit is contained in:
Thomas Vander Stichele 2004-03-13 15:27:01 +00:00
parent b8edc59edb
commit a967370df5
446 changed files with 24365 additions and 23891 deletions

View file

@ -1,3 +1,7 @@
2004-03-13 Thomas Vander Stichele <thomas at apestaart dot org>
* *.c, *.h: commit of gst-indent run on core
2004-03-13 Thomas Vander Stichele <thomas at apestaart dot org>
* tools/gst-indent:

View file

@ -38,11 +38,12 @@ static BonoboGenericFactory *factory = NULL;
/*
* BonoboControl data
*/
typedef struct {
BonoboControl *bonobo_object;
BonoboUIComponent *uic;
typedef struct
{
BonoboControl *bonobo_object;
BonoboUIComponent *uic;
GstPlay *play;
GstPlay *play;
} control_data_t;
/*
@ -50,20 +51,20 @@ typedef struct {
* encounters a fatal CORBA exception.
*/
static void
control_system_exception_cb (BonoboControl *control, CORBA_Object corba_object,
CORBA_Environment *ev, gpointer data)
control_system_exception_cb (BonoboControl * control, CORBA_Object corba_object,
CORBA_Environment * ev, gpointer data)
{
bonobo_object_unref (BONOBO_OBJECT (control));
}
static void
control_update (control_data_t *control_data)
control_update (control_data_t * control_data)
{
gtk_widget_queue_draw (GTK_WIDGET (control_data->play));
}
static void
verb_Play_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
verb_Play_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname)
{
control_data_t *control_data = (control_data_t *) user_data;
@ -72,7 +73,7 @@ verb_Play_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
}
static void
verb_Pause_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
verb_Pause_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname)
{
control_data_t *control_data = (control_data_t *) user_data;
@ -81,7 +82,7 @@ verb_Pause_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
}
static void
verb_Stop_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
verb_Stop_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname)
{
control_data_t *control_data = (control_data_t *) user_data;
@ -89,51 +90,53 @@ verb_Stop_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
control_update (control_data);
}
typedef struct {
typedef struct
{
control_data_t *control_data;
GtkFileSelection *selector;
} file_select_struct;
static void
filename_selected (GtkButton *ok, gpointer user_data)
static void
filename_selected (GtkButton * ok, gpointer user_data)
{
file_select_struct *select = (file_select_struct *) user_data;
gchar *selected_filename;
selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(select->selector));
selected_filename =
gtk_file_selection_get_filename (GTK_FILE_SELECTION (select->selector));
gst_play_set_uri (select->control_data->play, selected_filename);
gst_play_play (select->control_data->play);
control_update (select->control_data);
g_free(select);
g_free (select);
}
static void
verb_Open_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
verb_Open_cb (BonoboUIComponent * uic, gpointer user_data, const char *cname)
{
control_data_t *control_data = (control_data_t *) user_data;
file_select_struct *data = g_new0(file_select_struct, 1);
file_select_struct *data = g_new0 (file_select_struct, 1);
GtkWidget *file_selector;
file_selector = gtk_file_selection_new("Select a media file");
file_selector = gtk_file_selection_new ("Select a media file");
data->selector = GTK_FILE_SELECTION (file_selector);
data->control_data = control_data;
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked", GTK_SIGNAL_FUNC (filename_selected), data);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selector)->cancel_button),
"clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->
ok_button), "clicked", GTK_SIGNAL_FUNC (filename_selected), data);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->
ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->
cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
(gpointer) file_selector);
gtk_widget_show (file_selector);
}
@ -142,37 +145,36 @@ verb_Open_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
* in with our container's menus.
*/
static void
control_create_menus (control_data_t *control_data)
control_create_menus (control_data_t * control_data)
{
BonoboControl *control = control_data->bonobo_object;
Bonobo_UIContainer remote_uic;
GdkPixbuf *pixbuf;
static char ui [] =
"<Root>"
" <commands>"
" <cmd name=\"Play\" _label=\"Play\" _tip=\"Play\"/>"
" <cmd name=\"Pause\" _label=\"Pause\" _tip=\"Pause\"/>"
" <cmd name=\"Stop\" _label=\"Stop\" _tip=\"Stop\"/>"
" <cmd name=\"Open\" _label=\"Open Media\" _tip=\"Open a media stream\"/>"
" </commands>"
" <menu>"
" <submenu name=\"Player\" _label=\"_Player\">"
" <menuitem name=\"Open\" pixtype=\"stock\" pixname=\"Open\" verb=\"\"/>"
" <separator/>"
" <menuitem name=\"Play\" verb=\"\"/>"
" <menuitem name=\"Pause\" verb=\"\"/>"
" <menuitem name=\"Stop\" verb=\"\"/>"
" </submenu>"
" </menu>"
" <dockitem name=\"GstMediaPlay\">"
" <toolitem name=\"Play\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Pause\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Stop\" type=\"toggle\" verb=\"\"/>"
" </dockitem>"
"</Root>";
static char ui[] =
"<Root>"
" <commands>"
" <cmd name=\"Play\" _label=\"Play\" _tip=\"Play\"/>"
" <cmd name=\"Pause\" _label=\"Pause\" _tip=\"Pause\"/>"
" <cmd name=\"Stop\" _label=\"Stop\" _tip=\"Stop\"/>"
" <cmd name=\"Open\" _label=\"Open Media\" _tip=\"Open a media stream\"/>"
" </commands>"
" <menu>"
" <submenu name=\"Player\" _label=\"_Player\">"
" <menuitem name=\"Open\" pixtype=\"stock\" pixname=\"Open\" verb=\"\"/>"
" <separator/>"
" <menuitem name=\"Play\" verb=\"\"/>"
" <menuitem name=\"Pause\" verb=\"\"/>"
" <menuitem name=\"Stop\" verb=\"\"/>"
" </submenu>"
" </menu>"
" <dockitem name=\"GstMediaPlay\">"
" <toolitem name=\"Play\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Pause\" type=\"toggle\" verb=\"\"/>"
" <toolitem name=\"Stop\" type=\"toggle\" verb=\"\"/>"
" </dockitem>" "</Root>";
g_print("create menu\n");
g_print ("create menu\n");
/*
* Get our container's UIContainer server.
*/
@ -206,8 +208,8 @@ control_create_menus (control_data_t *control_data)
node = bonobo_ui_node_from_string (ui);
bonobo_ui_util_translate_ui (node);
bonobo_ui_util_fixup_help (control_data->uic, node,
DATADIR, "gstmediaplay");
DATADIR, "gstmediaplay");
bonobo_ui_component_set_tree (control_data->uic, "/", node, NULL);
bonobo_ui_node_free (node);
@ -225,11 +227,11 @@ control_create_menus (control_data_t *control_data)
bonobo_ui_util_set_pixbuf (control_data->uic, "/commands/Stop", pixbuf);
gdk_pixbuf_unref (pixbuf);
g_print("create menu done\n");
g_print ("create menu done\n");
}
static void
control_remove_menus (control_data_t *control_data)
control_remove_menus (control_data_t * control_data)
{
bonobo_ui_component_unset_container (control_data->uic);
}
@ -238,18 +240,18 @@ control_remove_menus (control_data_t *control_data)
* Clean up our supplementary BonoboControl data sturctures.
*/
static void
control_destroy_cb (BonoboControl *control, gpointer data)
control_destroy_cb (BonoboControl * control, gpointer data)
{
control_data_t *control_data = (control_data_t *) data;
control_data->play = NULL;
g_free (control_data);
g_free (control_data);
running_objects--;
if (running_objects > 0)
return;
/*
* When the last object has gone, unref the factory & quit.
*/
@ -258,7 +260,7 @@ control_destroy_cb (BonoboControl *control, gpointer data)
}
static void
control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
control_activate_cb (BonoboControl * control, gboolean activate, gpointer data)
{
control_data_t *control_data = (control_data_t *) data;
@ -284,17 +286,17 @@ control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
}
static void
control_set_frame_cb (BonoboControl *control, gpointer data)
control_set_frame_cb (BonoboControl * control, gpointer data)
{
control_create_menus ((control_data_t *) data);
}
static BonoboObject *
bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data)
bonobo_gstmediaplay_factory (BonoboGenericFactory * this, void *data)
{
BonoboControl *bonobo_object;
control_data_t *control_data;
GtkWidget *vbox;
BonoboControl *bonobo_object;
control_data_t *control_data;
GtkWidget *vbox;
gst_init (NULL, NULL);
/*
@ -311,7 +313,7 @@ bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data)
vbox = gtk_vbox_new (TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (control_data->play),
TRUE, TRUE, 0);
TRUE, TRUE, 0);
gtk_widget_show_all (vbox);
gst_play_set_uri (control_data->play, "/opt/data/armageddon1.mpg");
@ -337,39 +339,39 @@ bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data)
* the "activate" signal.
*/
gtk_signal_connect (GTK_OBJECT (bonobo_object), "activate",
GTK_SIGNAL_FUNC (control_activate_cb), control_data);
GTK_SIGNAL_FUNC (control_activate_cb), control_data);
gtk_signal_connect (GTK_OBJECT (bonobo_object), "set_frame",
GTK_SIGNAL_FUNC (control_set_frame_cb), control_data);
GTK_SIGNAL_FUNC (control_set_frame_cb), control_data);
/*
* The "system_exception" signal is raised when the BonoboControl
* encounters a fatal CORBA exception.
*/
gtk_signal_connect (GTK_OBJECT (bonobo_object), "system_exception",
GTK_SIGNAL_FUNC (control_system_exception_cb), control_data);
GTK_SIGNAL_FUNC (control_system_exception_cb), control_data);
/*
* We'll need to be able to cleanup when this control gets
* destroyed.
*/
gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy",
GTK_SIGNAL_FUNC (control_destroy_cb), control_data);
GTK_SIGNAL_FUNC (control_destroy_cb), control_data);
bonobo_ui_component_add_verb (control_data->uic, "Play",
verb_Play_cb, control_data);
verb_Play_cb, control_data);
bonobo_ui_component_add_verb (control_data->uic, "Pause",
verb_Pause_cb, control_data);
verb_Pause_cb, control_data);
bonobo_ui_component_add_verb (control_data->uic, "Stop",
verb_Stop_cb, control_data);
verb_Stop_cb, control_data);
bonobo_ui_component_add_verb (control_data->uic, "Open",
verb_Open_cb, control_data);
verb_Open_cb, control_data);
/*
* Count the new running object
*/
running_objects++;
g_print("running objects: %d\n", running_objects);
g_print ("running objects: %d\n", running_objects);
return BONOBO_OBJECT (bonobo_object);
}
@ -377,9 +379,10 @@ bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data)
static void
init_gstmediaplay_factory (void)
{
factory = bonobo_generic_factory_new (
"OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18",
bonobo_gstmediaplay_factory, NULL);
factory =
bonobo_generic_factory_new
("OAFIID:bonobo_gstmediaplay_factory:420f20ca-55d7-4a33-b327-0b246136db18",
bonobo_gstmediaplay_factory, NULL);
}
static void
@ -393,9 +396,8 @@ init_server_factory (int argc, char **argv)
CORBA_exception_init (&ev);
gnome_init_with_popt_table("bonobo-gstmediaplay", VERSION,
argc, argv,
oaf_popt_options, 0, NULL);
gnome_init_with_popt_table ("bonobo-gstmediaplay", VERSION,
argc, argv, oaf_popt_options, 0, NULL);
orb = oaf_init (argc, argv);
if (bonobo_init (orb, NULL, NULL) == FALSE)
@ -403,7 +405,7 @@ init_server_factory (int argc, char **argv)
CORBA_exception_free (&ev);
}
int
main (int argc, char **argv)
{

View file

@ -27,48 +27,48 @@
#include <gst/gst.h>
#include <config.h>
static BonoboObject* gstreamer_factory (BonoboGenericFactory *factory,
gpointer user_data)
static BonoboObject *
gstreamer_factory (BonoboGenericFactory * factory, gpointer user_data)
{
return BONOBO_OBJECT (bonobo_media_gstreamer_new ());
return BONOBO_OBJECT (bonobo_media_gstreamer_new ());
}
static void init_bonobo (int argc, char **argv)
static void
init_bonobo (int argc, char **argv)
{
CORBA_ORB orb;
CORBA_ORB orb;
gnome_init_with_popt_table ("bonobo-media-gstreamer", VERSION,
argc, argv,
oaf_popt_options, 0, NULL);
gnome_init_with_popt_table ("bonobo-media-gstreamer", VERSION,
argc, argv, oaf_popt_options, 0, NULL);
orb = oaf_init (argc, argv);
orb = oaf_init (argc, argv);
if (bonobo_init (orb, NULL, NULL) == FALSE)
g_error ("Could not initialize Bonobo");
if (bonobo_init (orb, NULL, NULL) == FALSE)
g_error ("Could not initialize Bonobo");
}
static void last_unref_cb (BonoboObject *bonobo_object,
BonoboGenericFactory *factory)
static void
last_unref_cb (BonoboObject * bonobo_object, BonoboGenericFactory * factory)
{
bonobo_object_unref (BONOBO_OBJECT (factory));
gtk_main_quit ();
bonobo_object_unref (BONOBO_OBJECT (factory));
gtk_main_quit ();
}
int main (int argc, char **argv)
int
main (int argc, char **argv)
{
BonoboGenericFactory *factory;
BonoboGenericFactory *factory;
gst_init (&argc, &argv);
init_bonobo (argc, argv);
gst_init (&argc, &argv);
init_bonobo (argc, argv);
factory = bonobo_generic_factory_new (
"OAFIID:Bonobo_Media_GStreamer_Factory",
gstreamer_factory, NULL);
factory = bonobo_generic_factory_new ("OAFIID:Bonobo_Media_GStreamer_Factory",
gstreamer_factory, NULL);
gtk_signal_connect (GTK_OBJECT (bonobo_context_running_get ()), "last_unref",
GTK_SIGNAL_FUNC (last_unref_cb), factory);
gtk_signal_connect (GTK_OBJECT (bonobo_context_running_get ()), "last_unref",
GTK_SIGNAL_FUNC (last_unref_cb), factory);
bonobo_main ();
bonobo_main ();
return 0;
return 0;
}

View file

@ -174,12 +174,6 @@ pipeline</ulink> and Microsoft's DirectShow for some background.
@use_threads:
<!-- ##### VARIABLE g_log_domain_gstreamer ##### -->
<para>
The variable that holds the GStreamer log domain
</para>
<!-- ##### MACRO GST_VERSION_MAJOR ##### -->
<para>
The major version of GStreamer at compile time

View file

@ -72,6 +72,34 @@ The GstBin object
</para>
<!-- ##### SIGNAL GstBin::element-added ##### -->
<para>
</para>
@gstbin: the object which received the signal.
@arg1: the element that was added to the bin
<!-- ##### SIGNAL GstBin::element-removed ##### -->
<para>
</para>
@gstbin: the object which received the signal.
@arg1: the element that was removed from the bin
<!-- ##### SIGNAL GstBin::iterate ##### -->
<para>
This signal is emitted when a bin iterates, either automatically or
due to a #gst_bin_iterate() call. The return value is used to
determine if the object method handler processed any data.
In most normal cases, a user-provided signal handler should return
FALSE.
</para>
@gstbin: the object which received the signal.
@Returns: TRUE if the state of the bin was advanced.
<!-- ##### USER_FUNCTION GstBinPrePostIterateFunction ##### -->
<para>
The signature of the callback for the post and pre iterate function as set with
@ -224,31 +252,3 @@ gst_bin_set_pre_iterate_function() and gst_bin_set_post_iterate_function().
@clock:
<!-- ##### SIGNAL GstBin::element-added ##### -->
<para>
</para>
@gstbin: the object which received the signal.
@arg1: the element that was added to the bin
<!-- ##### SIGNAL GstBin::element-removed ##### -->
<para>
</para>
@gstbin: the object which received the signal.
@arg1: the element that was removed from the bin
<!-- ##### SIGNAL GstBin::iterate ##### -->
<para>
This signal is emitted when a bin iterates, either automatically or
due to a #gst_bin_iterate() call. The return value is used to
determine if the object method handler processed any data.
In most normal cases, a user-provided signal handler should return
FALSE.
</para>
@gstbin: the object which received the signal.
@Returns: TRUE if the state of the bin was advanced.

View file

@ -235,6 +235,21 @@ Get the clock flags
</para>
<!-- ##### ARG GstClock:event-diff ##### -->
<para>
</para>
<!-- ##### ARG GstClock:max-diff ##### -->
<para>
Maximum allowed diff for clock sync requests against the real time.
</para>
<!-- ##### ARG GstClock:stats ##### -->
<para>
Boolean property to activate stat generation on the clock.
</para>
<!-- ##### FUNCTION gst_clock_set_speed ##### -->
<para>
@ -402,18 +417,3 @@ Get the clock flags
@id:
<!-- ##### ARG GstClock:event-diff ##### -->
<para>
</para>
<!-- ##### ARG GstClock:max-diff ##### -->
<para>
Maximum allowed diff for clock sync requests against the real time.
</para>
<!-- ##### ARG GstClock:stats ##### -->
<para>
Boolean property to activate stat generation on the clock.
</para>

View file

@ -20,16 +20,6 @@ You'll get a bitmask of flags with gst_cpu_get_flags().
</para>
<!-- ##### ENUM GstCPUFlags ##### -->
<para>
Flags that represent cpu capabilities
</para>
@GST_CPU_FLAG_MMX: The cpu is mmx enabled
@GST_CPU_FLAG_SSE: The cpu is sse enabled
@GST_CPU_FLAG_MMXEXT: The cpu has extended mmx instructions
@GST_CPU_FLAG_3DNOW: The cpu is 3DNOW enabled
<!-- ##### FUNCTION gst_cpu_get_flags ##### -->
<para>
Request a set of bits specifiying the features of the CPU.

View file

@ -71,6 +71,59 @@ The element object
</para>
<!-- ##### SIGNAL GstElement::eos ##### -->
<para>
Signal emited when the element goes to PAUSED due to an end-of-stream
condition.
</para>
@gstelement: the object which received the signal.
<!-- ##### SIGNAL GstElement::error ##### -->
<para>
This signal is emitted when an element has encountered an error that caused
it to fail performing its function.
</para>
@gstelement: the object which received the signal.
@arg1: the original #GstElement that generated the error.
@arg2: a #GError containing the translated error message.
@arg3: a debug string providing additional untranslated debug information, or NULL.
<!-- ##### SIGNAL GstElement::found-tag ##### -->
<para>
</para>
@gstelement: the object which received the signal.
@arg1:
@arg2:
<!-- ##### SIGNAL GstElement::new-pad ##### -->
<para>
Is triggered whenever a new pad is added to an element.
</para>
@gstelement: the object which received the signal.
@arg1: the new pad that was added
<!-- ##### SIGNAL GstElement::pad-removed ##### -->
<para>
Is triggered whenever a pad has been removed from the element.
</para>
@gstelement: the object which received the signal.
@arg1: The pad that was removed.
<!-- ##### SIGNAL GstElement::state-change ##### -->
<para>
Is triggered whenever the state of an element changes.
</para>
@gstelement: the object which received the signal.
@arg1: the new state of the object
@arg2:
<!-- ##### MACRO gst_element_get_name ##### -->
<para>
Gets the name of the element.
@ -966,56 +1019,3 @@ Helper macro to create query type functions
@...: list of query types.
<!-- ##### SIGNAL GstElement::eos ##### -->
<para>
Signal emited when the element goes to PAUSED due to an end-of-stream
condition.
</para>
@gstelement: the object which received the signal.
<!-- ##### SIGNAL GstElement::error ##### -->
<para>
This signal is emitted when an element has encountered an error that caused
it to fail performing its function.
</para>
@gstelement: the object which received the signal.
@arg1: the original #GstElement that generated the error.
@arg2: a #GError containing the translated error message.
@arg3: a debug string providing additional untranslated debug information, or NULL.
<!-- ##### SIGNAL GstElement::found-tag ##### -->
<para>
</para>
@gstelement: the object which received the signal.
@arg1:
@arg2:
<!-- ##### SIGNAL GstElement::new-pad ##### -->
<para>
Is triggered whenever a new pad is added to an element.
</para>
@gstelement: the object which received the signal.
@arg1: the new pad that was added
<!-- ##### SIGNAL GstElement::pad-removed ##### -->
<para>
Is triggered whenever a pad has been removed from the element.
</para>
@gstelement: the object which received the signal.
@arg1: The pad that was removed.
<!-- ##### SIGNAL GstElement::state-change ##### -->
<para>
Is triggered whenever the state of an element changes.
</para>
@gstelement: the object which received the signal.
@arg1: the new state of the object
@arg2:

View file

@ -15,18 +15,6 @@ formats can be used to perform seeking or conversions/query operations.
#GstPad, #GstElement
</para>
<!-- ##### ENUM GstFormat ##### -->
<para>
Standard predefined formats
</para>
@GST_FORMAT_UNDEFINED: undefined format
@GST_FORMAT_DEFAULT: the default format of the pad/element
@GST_FORMAT_BYTES: bytes
@GST_FORMAT_TIME: time in nanoseconds
@GST_FORMAT_BUFFERS: buffers
@GST_FORMAT_PERCENT: percentage of stream
<!-- ##### MACRO GST_FORMAT_PERCENT_MAX ##### -->
<para>
The PERCENT format is between 0 and this value

View file

@ -209,6 +209,19 @@ The GstIndex object
</para>
<!-- ##### SIGNAL GstIndex::entry-added ##### -->
<para>
Is emited when a new entry is added to the index.
</para>
@gstindex: the object which received the signal.
@arg1: The entry added to the index.
<!-- ##### ARG GstIndex:resolver ##### -->
<para>
</para>
<!-- ##### FUNCTION gst_index_new ##### -->
<para>
@ -401,16 +414,3 @@ The GstIndex object
@id:
<!-- ##### SIGNAL GstIndex::entry-added ##### -->
<para>
Is emited when a new entry is added to the index.
</para>
@gstindex: the object which received the signal.
@arg1: The entry added to the index.
<!-- ##### ARG GstIndex:resolver ##### -->
<para>
</para>

View file

@ -21,12 +21,6 @@ The GstMemChunk is used to allocate critical resources for #GstBuffer and
#GstAtomic, #GstBuffer, #GstEvent, #GstData
</para>
<!-- ##### STRUCT GstMemChunk ##### -->
<para>
The memchunk structure
</para>
<!-- ##### FUNCTION gst_mem_chunk_new ##### -->
<para>

View file

@ -40,6 +40,47 @@ The GstObject
</para>
<!-- ##### SIGNAL GstObject::deep-notify ##### -->
<para>
The deep notify signal is used to be notified of property changes.
it is typically attached to the toplevel bin to receive notifications
from all the elements contained in that bin.
</para>
@gstobject: the object which received the signal.
@arg1: the object that originated the signal
@arg2: the property that changed
<!-- ##### SIGNAL GstObject::object-saved ##### -->
<para>
Is trigered whenever a new object is saved to XML. You can connect to
this signal to insert custom XML tags into the core XML.
</para>
@gstobject: the object which received the signal.
@arg1: the xmlNodePtr of the parent node
<!-- ##### SIGNAL GstObject::parent-set ##### -->
<para>
Is emitted when the parent of an object is set.
</para>
@gstobject: the object which received the signal.
@arg1: the new parent
<!-- ##### SIGNAL GstObject::parent-unset ##### -->
<para>
Is emitted when the parent of an object is unset.
</para>
@gstobject: the object which received the signal.
@arg1: the old parent
<!-- ##### ARG GstObject:name ##### -->
<para>
The name of the object
</para>
<!-- ##### MACRO GST_FLAGS ##### -->
<para>
This macro returns the entire set of flags for the object.
@ -290,44 +331,3 @@ Check if the object has been destroyed.
@Returns:
<!-- ##### SIGNAL GstObject::deep-notify ##### -->
<para>
The deep notify signal is used to be notified of property changes.
it is typically attached to the toplevel bin to receive notifications
from all the elements contained in that bin.
</para>
@gstobject: the object which received the signal.
@arg1: the object that originated the signal
@arg2: the property that changed
<!-- ##### SIGNAL GstObject::object-saved ##### -->
<para>
Is trigered whenever a new object is saved to XML. You can connect to
this signal to insert custom XML tags into the core XML.
</para>
@gstobject: the object which received the signal.
@arg1: the xmlNodePtr of the parent node
<!-- ##### SIGNAL GstObject::parent-set ##### -->
<para>
Is emitted when the parent of an object is set.
</para>
@gstobject: the object which received the signal.
@arg1: the new parent
<!-- ##### SIGNAL GstObject::parent-unset ##### -->
<para>
Is emitted when the parent of an object is unset.
</para>
@gstobject: the object which received the signal.
@arg1: the old parent
<!-- ##### ARG GstObject:name ##### -->
<para>
The name of the object
</para>

View file

@ -1193,6 +1193,11 @@ The Ghostpad object
</para>
<!-- ##### ARG GstGhostPad:real-pad ##### -->
<para>
</para>
<!-- ##### FUNCTION gst_ghost_pad_new ##### -->
<para>

View file

@ -86,6 +86,15 @@ The padtemplate object.
</para>
<!-- ##### SIGNAL GstPadTemplate::pad-created ##### -->
<para>
This signal is fired when an element creates a pad from this
template.
</para>
@gstpadtemplate: the object which received the signal.
@arg1: The pad that was created.
<!-- ##### ENUM GstPadTemplateFlags ##### -->
<para>
Flags for the padtemplate
@ -167,12 +176,3 @@ Check if the properties of the padtemplate are fixed
@Returns:
<!-- ##### SIGNAL GstPadTemplate::pad-created ##### -->
<para>
This signal is fired when an element creates a pad from this
template.
</para>
@gstpadtemplate: the object which received the signal.
@arg1: The pad that was created.

View file

@ -41,14 +41,6 @@ The error quark
<!-- ##### FUNCTION gst_plugin_error_quark ##### -->
<para>
Get the error quark
</para>
@Returns: The error quark used in GError messages
<!-- ##### ENUM GstPluginError ##### -->
<para>
The plugin loading errors

View file

@ -15,20 +15,6 @@ Query types can be used to perform queries on pads and elements.
#GstPad, #GstElement
</para>
<!-- ##### ENUM GstQueryType ##### -->
<para>
Standard predefined Query types
</para>
@GST_QUERY_NONE: invalid query type
@GST_QUERY_TOTAL: total length of stream
@GST_QUERY_POSITION: current position in stream
@GST_QUERY_LATENCY: latency of stream
@GST_QUERY_JITTER: current jitter of stream
@GST_QUERY_START: start of configured segment
@GST_QUERY_SEGMENT_END: end of configured segment
@GST_QUERY_RATE: current rate of the stream
<!-- ##### MACRO GST_QUERY_TYPE_RATE_DEN ##### -->
<para>
Rates are relative to this value
@ -89,8 +75,10 @@ Convenience function to define a function that returns an array of query types.
</para>
@type:
@Param1:
@Returns:
<!-- # Unused Parameters # -->
@type:
<!-- ##### FUNCTION gst_query_type_get_definitions ##### -->

View file

@ -4556,6 +4556,16 @@ can perform necessary cleanup.
@pool: The pool that is being destroyed
@user_data: user data as set on th bufferpool
<!-- ##### ENUM GstCPUFlags ##### -->
<para>
Flags that represent cpu capabilities
</para>
@GST_CPU_FLAG_MMX: The cpu is mmx enabled
@GST_CPU_FLAG_SSE: The cpu is sse enabled
@GST_CPU_FLAG_MMXEXT: The cpu has extended mmx instructions
@GST_CPU_FLAG_3DNOW: The cpu is 3DNOW enabled
<!-- ##### STRUCT GstCacheAssociation ##### -->
<para>
@ -5158,6 +5168,18 @@ Indicates the mmapped area should be touched to bring it into memory.
</para>
<!-- ##### ENUM GstFormat ##### -->
<para>
Standard predefined formats
</para>
@GST_FORMAT_UNDEFINED: undefined format
@GST_FORMAT_DEFAULT: the default format of the pad/element
@GST_FORMAT_BYTES: bytes
@GST_FORMAT_TIME: time in nanoseconds
@GST_FORMAT_BUFFERS: buffers
@GST_FORMAT_PERCENT: percentage of stream
<!-- ##### STRUCT GstHttpSrc ##### -->
<para>
@ -5275,6 +5297,12 @@ Specify the location of the file. The location must be a fully qualified URL.
</para>
<!-- ##### STRUCT GstMemChunk ##### -->
<para>
The memchunk structure
</para>
<!-- ##### STRUCT GstMemChunkElement ##### -->
<para>
An entry in the memchunk area
@ -5505,6 +5533,20 @@ Sets the command to be executed.
</para>
<!-- ##### ENUM GstQueryType ##### -->
<para>
Standard predefined Query types
</para>
@GST_QUERY_NONE: invalid query type
@GST_QUERY_TOTAL: total length of stream
@GST_QUERY_POSITION: current position in stream
@GST_QUERY_LATENCY: latency of stream
@GST_QUERY_JITTER: current jitter of stream
@GST_QUERY_START: start of configured segment
@GST_QUERY_SEGMENT_END: end of configured segment
@GST_QUERY_RATE: current rate of the stream
<!-- ##### STRUCT GstQueue ##### -->
<para>
@ -5571,6 +5613,17 @@ the region types for #gst_pad_pullregion.
@global_reg:
@local_reg:
<!-- ##### ENUM GstRegistryReturn ##### -->
<para>
The return value of registry operations
</para>
@GST_REGISTRY_OK: The registry reported no error.
@GST_REGISTRY_LOAD_ERROR: There was a load error
@GST_REGISTRY_SAVE_ERROR: There was an error saving the registry
@GST_REGISTRY_PLUGIN_LOAD_ERROR: There was an error loading a plugin
@GST_REGISTRY_PLUGIN_SIGNATURE_ERROR: There was an error saving a plugin
<!-- ##### STRUCT GstRegistryWrite ##### -->
<para>
@ -5798,6 +5851,20 @@ Flags for the GstSrc element
</para>
<!-- ##### ENUM GstTagMergeMode ##### -->
<para>
</para>
@GST_TAG_MERGE_UNDEFINED:
@GST_TAG_MERGE_REPLACE_ALL:
@GST_TAG_MERGE_REPLACE:
@GST_TAG_MERGE_APPEND:
@GST_TAG_MERGE_PREPEND:
@GST_TAG_MERGE_KEEP:
@GST_TAG_MERGE_KEEP_ALL:
@GST_TAG_MERGE_COUNT:
<!-- ##### STRUCT GstTee ##### -->
<para>
@ -5921,6 +5988,15 @@ Query the element for the current mime type
</para>
<!-- ##### SIGNAL GstXML::object-loaded ##### -->
<para>
</para>
@gstxml: the object which received the signal.
@arg1:
@arg2:
<!-- ##### USER_FUNCTION GstXMLRegistryAddPathList ##### -->
<para>
@ -6676,6 +6752,12 @@ must be defined to activate the tracing functionality.
@llink:
@Returns:
<!-- ##### VARIABLE g_log_domain_gstreamer ##### -->
<para>
The variable that holds the GStreamer log domain
</para>
<!-- ##### MACRO g_object_class_find_property ##### -->
<para>
@ -9561,6 +9643,13 @@ Destroys the pipeline.
@Returns:
<!-- ##### FUNCTION gst_plugin_error_quark ##### -->
<para>
Get the error quark
</para>
@Returns: The error quark used in GError messages
<!-- ##### FUNCTION gst_plugin_feature_get_type ##### -->
<para>

View file

@ -14,17 +14,6 @@ The registry holds the available plugins in the system.
#GstPlugin, #GstPluginFeature
</para>
<!-- ##### ENUM GstRegistryReturn ##### -->
<para>
The return value of registry operations
</para>
@GST_REGISTRY_OK: The registry reported no error.
@GST_REGISTRY_LOAD_ERROR: There was a load error
@GST_REGISTRY_SAVE_ERROR: There was an error saving the registry
@GST_REGISTRY_PLUGIN_LOAD_ERROR: There was an error loading a plugin
@GST_REGISTRY_PLUGIN_SIGNATURE_ERROR: There was an error saving a plugin
<!-- ##### ENUM GstRegistryFlags ##### -->
<para>
Flags for the registry

View file

@ -14,20 +14,6 @@ GstTag
</para>
<!-- ##### ENUM GstTagMergeMode ##### -->
<para>
</para>
@GST_TAG_MERGE_UNDEFINED:
@GST_TAG_MERGE_REPLACE_ALL:
@GST_TAG_MERGE_REPLACE:
@GST_TAG_MERGE_APPEND:
@GST_TAG_MERGE_PREPEND:
@GST_TAG_MERGE_KEEP:
@GST_TAG_MERGE_KEEP_ALL:
@GST_TAG_MERGE_COUNT:
<!-- ##### ENUM GstTagFlag ##### -->
<para>

View file

@ -34,15 +34,6 @@ The GstThread object
</para>
<!-- ##### FUNCTION gst_thread_new ##### -->
<para>
</para>
@name:
@Returns:
<!-- ##### SIGNAL GstThread::shutdown ##### -->
<para>
@ -55,3 +46,12 @@ The GstThread object
The thread priority
</para>
<!-- ##### FUNCTION gst_thread_new ##### -->
<para>
</para>
@name:
@Returns:

View file

@ -105,25 +105,3 @@ All GstElements can be serialized to an XML presentation and subsequently loaded
@Returns:
<!-- ##### SIGNAL GstXML::object-loaded ##### -->
<para>
</para>
@:
@:
@:
@gstxml: the object which received the signal.
@arg1:
@arg2:
<!-- ##### SIGNAL GstXML::object-loaded ##### -->
<para>
</para>
@gstxml: the object which received the signal.
@arg1:
@arg2:

View file

@ -3,13 +3,16 @@
static gchar *_subject, *_category;
static gint _testnum = 0;
static gboolean _passed;
static gint _total_tests = 0,_passed_tests = 0;
static gint _total_tests = 0, _passed_tests = 0;
static gint _random_size;
void tabpad(gchar *str,gint width) {
void
tabpad (gchar * str, gint width)
{
int i;
for (i=0;i<width-strlen(str);i++)
fprintf(stderr," ");
for (i = 0; i < width - strlen (str); i++)
fprintf (stderr, " ");
}
#define TEST_SUBJECT(subject) fprintf(stderr,"Subject: %s\n",subject),_subject = subject
@ -36,267 +39,276 @@ void tabpad(gchar *str,gint width) {
_total_tests++; \
}G_STMT_END;
void SETUP_RANDOM_SIZE(void *random,gint size) {
void
SETUP_RANDOM_SIZE (void *random, gint size)
{
int i;
if (random) g_free(random);
if (random)
g_free (random);
_random_size = size;
random = g_malloc(_random_size);
for (i=0;i<_random_size;i++)
((unsigned char *)random)[i] = i;
random = g_malloc (_random_size);
for (i = 0; i < _random_size; i++)
((unsigned char *) random)[i] = i;
}
#define SETUP_RANDOM(random,type) SETUP_RANDOM_SIZE(random,sizeof(type))
gboolean RANDOM_OK(void *random) {
gboolean
RANDOM_OK (void *random)
{
int i;
for (i=0;i<_random_size;i++) {
if (((unsigned char *)random)[i] != i) {
SETUP_RANDOM_SIZE(random,_random_size);
for (i = 0; i < _random_size; i++) {
if (((unsigned char *) random)[i] != i) {
SETUP_RANDOM_SIZE (random, _random_size);
return FALSE;
}
}
return TRUE;
}
int main(int argc,char *argv[]) {
int
main (int argc, char *argv[])
{
GstObject *object;
GstObject *parent;
GstObject *newparent;
GtkObject *gtkobject;
GstObject *curparent;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
TEST_SUBJECT("GstObject");
TEST_SUBJECT ("GstObject");
TEST_CATEGORY("Creation");
TEST_CATEGORY ("Creation");
TEST("create object");
TEST ("create object");
/* setup */
/* action */
object = gst_object_new();
object = gst_object_new ();
/* assertions */
ASSERT(object != NULL);
ASSERT(GST_IS_OBJECT(object));
ASSERT (object != NULL);
ASSERT (GST_IS_OBJECT (object));
/* cleanup */
g_free(object);
ENDTEST();
g_free (object);
ENDTEST ();
/* new category */
TEST_CATEGORY("Refcounting");
TEST_CATEGORY ("Refcounting");
/* category setup */
object = gst_object_new();
object = gst_object_new ();
TEST("new object");
TEST ("new object");
/* setup */
/* action */
/* assertions */
ASSERT(object->refcount == 1);
ASSERT(GTK_OBJECT_FLOATING(object) == TRUE);
ASSERT (object->refcount == 1);
ASSERT (GTK_OBJECT_FLOATING (object) == TRUE);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("increment refcount");
TEST ("increment refcount");
/* setup */
/* action */
gst_object_ref(object);
gst_object_ref (object);
/* assertions */
ASSERT(object->refcount == 2);
ASSERT(GTK_OBJECT_FLOATING(object) == TRUE);
ASSERT (object->refcount == 2);
ASSERT (GTK_OBJECT_FLOATING (object) == TRUE);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("sink object");
TEST ("sink object");
/* setup */
/* action */
gst_object_sink(object);
gst_object_sink (object);
/* assertions */
ASSERT(object->refcount == 1);
ASSERT(GTK_OBJECT_FLOATING(object) == FALSE);
ASSERT (object->refcount == 1);
ASSERT (GTK_OBJECT_FLOATING (object) == FALSE);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("increment refcount after sink");
TEST ("increment refcount after sink");
/* setup */
/* action */
gst_object_ref(object);
gst_object_ref (object);
/* assertions */
ASSERT(object->refcount == 2);
ASSERT(GTK_OBJECT_FLOATING(object) == FALSE);
ASSERT (object->refcount == 2);
ASSERT (GTK_OBJECT_FLOATING (object) == FALSE);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("decrement refcount after sink");
TEST ("decrement refcount after sink");
/* setup */
/* action */
gst_object_unref(object);
gst_object_unref (object);
/* assertions */
ASSERT(object->refcount == 1);
ASSERT(GTK_OBJECT_FLOATING(object) == FALSE);
ASSERT (object->refcount == 1);
ASSERT (GTK_OBJECT_FLOATING (object) == FALSE);
/* cleanup */
ENDTEST();
ENDTEST ();
/* category cleanup */
g_free(object);
g_free (object);
/* new category */
TEST_CATEGORY("Parentage");
TEST_CATEGORY ("Parentage");
/* category setup */
object = gst_object_new();
parent = gst_object_new();
newparent = gst_object_new();
gtkobject = gtk_type_new(gtk_object_get_type());
object = gst_object_new ();
parent = gst_object_new ();
newparent = gst_object_new ();
gtkobject = gtk_type_new (gtk_object_get_type ());
/* category assertions */
ASSERT(object != NULL);
ASSERT(object->refcount == 1);
ASSERT(object->parent == NULL);
ASSERT(parent != NULL);
ASSERT(newparent != NULL);
ASSERT(gtkobject != NULL);
ASSERT(!GST_IS_OBJECT(gtkobject));
ASSERT (object != NULL);
ASSERT (object->refcount == 1);
ASSERT (object->parent == NULL);
ASSERT (parent != NULL);
ASSERT (newparent != NULL);
ASSERT (gtkobject != NULL);
ASSERT (!GST_IS_OBJECT (gtkobject));
TEST("gst_object_set_parent: null object");
TEST ("gst_object_set_parent: null object");
/* setup */
/* action */
gst_object_set_parent(NULL,NULL);
gst_object_set_parent (NULL, NULL);
/* assertions */
ASSERT(object->parent == NULL);
ASSERT (object->parent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: invalid object");
TEST ("gst_object_set_parent: invalid object");
/* setup */
/* action */
gst_object_set_parent((GstObject*)gtkobject,NULL);
gst_object_set_parent ((GstObject *) gtkobject, NULL);
/* assertions */
ASSERT(object->parent == NULL);
ASSERT (object->parent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: null parent");
TEST ("gst_object_set_parent: null parent");
/* setup */
/* action */
gst_object_set_parent(object,NULL);
gst_object_set_parent (object, NULL);
/* assertions */
ASSERT(object->parent == NULL);
ASSERT (object->parent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: invalid parent");
TEST ("gst_object_set_parent: invalid parent");
/* setup */
/* action */
gst_object_set_parent(object,(GstObject*)gtkobject);
gst_object_set_parent (object, (GstObject *) gtkobject);
/* assertions */
ASSERT(object->parent == NULL);
ASSERT (object->parent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: valid object, parent is object");
TEST ("gst_object_set_parent: valid object, parent is object");
/* setup */
/* action */
gst_object_set_parent(object,object);
gst_object_set_parent (object, object);
/* assertions */
ASSERT(object->parent == NULL);
ASSERT (object->parent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: valid object and parent");
TEST ("gst_object_set_parent: valid object and parent");
/* setup */
/* action */
gst_object_set_parent(object,parent);
gst_object_set_parent (object, parent);
/* assertions */
ASSERT(object->parent == parent);
ASSERT (object->parent == parent);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_set_parent: parent already set");
TEST ("gst_object_set_parent: parent already set");
/* setup */
/* action */
gst_object_set_parent(object,newparent);
gst_object_set_parent (object, newparent);
/* assertions */
ASSERT(object->parent != newparent);
ASSERT(object->parent == parent);
ASSERT (object->parent != newparent);
ASSERT (object->parent == parent);
/* cleanup */
g_free(object);
ENDTEST();
g_free (object);
ENDTEST ();
TEST("gst_object_get_parent: null object");
TEST ("gst_object_get_parent: null object");
/* setup */
/* action */
curparent = gst_object_get_parent(NULL);
curparent = gst_object_get_parent (NULL);
/* assertions */
ASSERT(curparent == NULL);
ASSERT (curparent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_get_parent: invalid object");
TEST ("gst_object_get_parent: invalid object");
/* setup */
/* action */
curparent = gst_object_get_parent((GstObject*)gtkobject);
curparent = gst_object_get_parent ((GstObject *) gtkobject);
/* assertions */
ASSERT(curparent == NULL);
ASSERT (curparent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_get_parent: no parent");
TEST ("gst_object_get_parent: no parent");
/* setup */
object = gst_object_new();
object = gst_object_new ();
/* action */
curparent = gst_object_get_parent(object);
curparent = gst_object_get_parent (object);
/* assertions */
ASSERT(curparent == NULL);
ASSERT (curparent == NULL);
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_get_parent: valid parent");
TEST ("gst_object_get_parent: valid parent");
/* setup */
gst_object_set_parent(object,parent);
gst_object_set_parent (object, parent);
/* action */
curparent = gst_object_get_parent(object);
curparent = gst_object_get_parent (object);
/* assertions */
ASSERT(curparent == parent);
ASSERT (curparent == parent);
/* cleanup */
g_free(object);
ENDTEST();
g_free (object);
ENDTEST ();
TEST("gst_object_unparent: null object");
TEST ("gst_object_unparent: null object");
/* setup */
/* action */
gst_object_unparent(NULL);
gst_object_unparent (NULL);
/* assertions */
/* NONE - FIXME! */
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_unparent: invalid object");
TEST ("gst_object_unparent: invalid object");
/* setup */
/* action */
gst_object_unparent((GstObject*)gtkobject);
gst_object_unparent ((GstObject *) gtkobject);
/* assertions */
/* NONE - FIXME! */
/* cleanup */
ENDTEST();
ENDTEST ();
TEST("gst_object_unparent: no parent");
TEST ("gst_object_unparent: no parent");
/* setup */
object = gst_object_new();
object = gst_object_new ();
/* category cleanup */
g_free(object);
g_free(parent);
g_free(newparent);
g_free(gtkobject);
g_free (object);
g_free (parent);
g_free (newparent);
g_free (gtkobject);
fprintf(stderr,"\n\nTotal tests:\t%d\n",_total_tests);
fprintf(stderr,"Total passed:\t%d\n",_passed_tests);
fprintf(stderr,"Total FAILED:\t%d\n",_total_tests-_passed_tests);
fprintf (stderr, "\n\nTotal tests:\t%d\n", _total_tests);
fprintf (stderr, "Total passed:\t%d\n", _passed_tests);
fprintf (stderr, "Total FAILED:\t%d\n", _total_tests - _passed_tests);
}

View file

@ -20,21 +20,21 @@
#include <gst/gst.h>
static void
fill_queue (GstElement *queue, gint level, GstBin *pipeline)
fill_queue (GstElement * queue, gint level, GstBin * pipeline)
{
/* this needs to iterate till something is pushed
* in the queue */
gst_bin_iterate (pipeline);
}
gint
main (gint argc, gchar *argv[])
gint
main (gint argc, gchar * argv[])
{
GstElement *queue, *src, *pipeline;
GstBuffer *buffer;
gboolean done = FALSE;
GstPad *pad;
gst_init (&argc, &argv);
queue = gst_element_factory_make ("queue", "queue");
@ -50,19 +50,19 @@ main (gint argc, gchar *argv[])
gst_element_link_many (src, queue, NULL);
pad = gst_element_get_pad (queue, "src");
g_signal_connect (G_OBJECT (queue), "low_watermark", G_CALLBACK (fill_queue), pipeline);
g_signal_connect (G_OBJECT (queue), "low_watermark", G_CALLBACK (fill_queue),
pipeline);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
do {
do {
/* get buffer into the app */
buffer = GST_RPAD_GETFUNC (pad) (pad);
/* just exit on any event */
if (GST_IS_EVENT (buffer)) {
done = TRUE;
}
else {
} else {
gst_util_dump_mem (GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
}
gst_data_unref (GST_DATA (buffer));
@ -71,6 +71,6 @@ main (gint argc, gchar *argv[])
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}

View file

@ -16,23 +16,24 @@
#define DEBUG
gboolean playing = TRUE;
gboolean cut_start_signalled = FALSE;
gboolean cut_stop_signalled = FALSE;
gboolean playing = TRUE;
gboolean cut_start_signalled = FALSE;
gboolean cut_stop_signalled = FALSE;
int id = 0; /* increment this for each new cut */
GstElement *main_bin;
GstElement *audiosrc;
GstElement *queue;
GstElement *thread;
GstElement *cutter;
GstElement *disksink;
GstElement *encoder;
char buffer[255];
int id = 0; /* increment this for each new cut */
GstElement *main_bin;
GstElement *audiosrc;
GstElement *queue;
GstElement *thread;
GstElement *cutter;
GstElement *disksink;
GstElement *encoder;
char buffer[255];
/* signal callbacks */
void cut_start (GstElement *element)
void
cut_start (GstElement * element)
{
g_print ("\nDEBUG: main: cut start\n");
/* we should pause the pipeline, unlink cutter and disksink
@ -45,12 +46,14 @@ void cut_start (GstElement *element)
{
time_t seconds;
struct tm *ct;
time (&seconds);
ct = localtime (&seconds);
/* sprintf (buffer, "/news/incoming/audio/cutter.%06d.wav", id); */
sprintf (buffer, "/news/incoming/audio/cutter.%04d%02d%02d.%02d%02d%02d.wav",
ct->tm_year + 1900, ct->tm_mon, ct->tm_mday,
ct->tm_hour, ct->tm_min, ct->tm_sec);
sprintf (buffer,
"/news/incoming/audio/cutter.%04d%02d%02d.%02d%02d%02d.wav",
ct->tm_year + 1900, ct->tm_mon, ct->tm_mday, ct->tm_hour, ct->tm_min,
ct->tm_sec);
}
g_print ("DEBUG: cut_start: setting new location to %s\n", buffer);
g_object_set (G_OBJECT (disksink), "location", buffer, NULL);
@ -62,13 +65,15 @@ void cut_start (GstElement *element)
return;
}
void cut_start_signal (GstElement *element)
void
cut_start_signal (GstElement * element)
{
g_print ("\nDEBUG: main: cut start signal\n");
cut_start_signalled = TRUE;
}
void cut_stop (GstElement *element)
void
cut_stop (GstElement * element)
{
g_print ("\nDEBUG: main: cut stop\n");
/* we should pause the pipeline, unlink disksink, create a fake disksink,
@ -85,42 +90,41 @@ void cut_stop (GstElement *element)
return;
}
void cut_stop_signal (GstElement *element)
void
cut_stop_signal (GstElement * element)
{
g_print ("\nDEBUG: main: cut stop signal\n");
cut_stop_signalled = TRUE;
}
int main (int argc, char *argv[])
int
main (int argc, char *argv[])
{
/*int i, j; */
/*gboolean done; */
/*char buffer[20]; */
/*output_channel_t *channel_out; */
GstElement *audiosrc;
gst_init (&argc,&argv);
gst_init (&argc, &argv);
/*
if (argc == 1)
{
g_print("usage: %s <filename1> <filename2> <...>\n", argv[0]);
exit(-1);
}*/
/* set up input channel and main bin */
g_print ("creating main bin\n");
g_print ("creating main bin\n");
/* create cutter */
cutter = gst_element_factory_make ("cutter", "cutter");
g_object_set (G_OBJECT (cutter),
"threshold_dB", -40.0,
"runlength", 0.5,
"prelength", 1.0,
NULL);
g_object_set (G_OBJECT (cutter),
"threshold_dB", -40.0, "runlength", 0.5, "prelength", 1.0, NULL);
/* create an audio src */
if (!(audiosrc = gst_element_factory_make ("osssrc", "audio_src")))
@ -128,21 +132,20 @@ int main (int argc, char *argv[])
/* set params */
g_object_set (G_OBJECT (audiosrc), "frequency", 44100,
"channels", 1,
"format", 16, NULL);
g_object_set (G_OBJECT (audiosrc), "frequency", 44100,
"channels", 1, "format", 16, NULL);
if (!(encoder = gst_element_factory_make ("passthrough", "encoder")))
g_error ("Could not create 'passthrough' element !\n");
if (!(disksink = gst_element_factory_make ("afsink", "disk_sink")))
g_error ("Could not create 'afsink' element !\n");
g_object_set (G_OBJECT (disksink), "location", "/dev/null", NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create main bin */
main_bin = gst_pipeline_new ("bin");
g_assert (main_bin != NULL);
@ -161,10 +164,10 @@ int main (int argc, char *argv[])
/* set signal handlers */
g_print ("setting signal handlers\n");
g_signal_connect (G_OBJECT(cutter), "cut_start",
(GCallback)cut_start_signal, NULL);
g_signal_connect (G_OBJECT(cutter), "cut_stop",
(GCallback)cut_stop_signal, NULL);
g_signal_connect (G_OBJECT (cutter), "cut_start",
(GCallback) cut_start_signal, NULL);
g_signal_connect (G_OBJECT (cutter), "cut_stop",
(GCallback) cut_stop_signal, NULL);
/* start playing */
g_print ("setting to play\n");
@ -173,23 +176,20 @@ int main (int argc, char *argv[])
g_print ("setting thread to play\n");
gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING);
*/
while (playing)
{
while (playing) {
/* g_print ("> "); */
gst_bin_iterate (GST_BIN (main_bin));
gst_bin_iterate (GST_BIN (main_bin));
/* g_print (" <"); */
if (cut_start_signalled)
{
g_print ("\nDEBUG: main: cut_start_signalled true !\n");
cut_start (cutter);
cut_start_signalled = FALSE;
}
if (cut_stop_signalled)
{
g_print ("\nDEBUG: main: cut_stop_signalled true !\n");
cut_stop (cutter);
cut_stop_signalled = FALSE;
}
if (cut_start_signalled) {
g_print ("\nDEBUG: main: cut_start_signalled true !\n");
cut_start (cutter);
cut_start_signalled = FALSE;
}
if (cut_stop_signalled) {
g_print ("\nDEBUG: main: cut_stop_signalled true !\n");
cut_stop (cutter);
cut_stop_signalled = FALSE;
}
}
g_print ("we're done iterating.\n");
/* stop the bin */
@ -199,5 +199,5 @@ int main (int argc, char *argv[])
gst_object_unref (GST_OBJECT (disksink));
gst_object_unref (GST_OBJECT (main_bin));
exit(0);
exit (0);
}

View file

@ -3,12 +3,12 @@
* thomas@apestaart.org
*/
typedef struct
typedef struct
{
GstElement *pipe;
GstElement *disksink;
GstElement *audiosink;
char *location;
int channel_id;
} output_channel_t;

View file

@ -1,7 +1,8 @@
#include <stdlib.h>
#include <gst/gst.h>
int main (int argc, char *argv[])
int
main (int argc, char *argv[])
{
GstElement *bin, *filesrc, *decoder, *osssink;
@ -36,7 +37,7 @@ int main (int argc, char *argv[])
/* link the elements */
gst_element_link_many (filesrc, decoder, osssink, NULL);
/* start playing */
gst_element_set_state (bin, GST_STATE_PLAYING);
@ -47,4 +48,3 @@ int main (int argc, char *argv[])
exit (0);
}

View file

@ -1,7 +1,8 @@
#include <gst/gst.h>
static void
gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
gst_play_have_type (GstElement * typefind, GstCaps * caps,
GstElement * pipeline)
{
GstElement *osssink;
GstElement *new_element;
@ -21,18 +22,15 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
/* unlink_pads the typefind from the pipeline and remove it */
gst_element_unlink_pads (cache, "src", typefind, "sink");
gst_bin_remove (GST_BIN (autobin), typefind);
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
autoplug = gst_autoplug_factory_make ("staticrender");
g_assert (autoplug != NULL);
new_element = gst_autoplug_to_renderers (autoplug,
caps,
osssink,
NULL);
new_element = gst_autoplug_to_renderers (autoplug, caps, osssink, NULL);
if (!new_element) {
g_print ("could not autoplug, no suitable codecs found...\n");
@ -51,7 +49,7 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
}
static void
gst_play_cache_empty (GstElement *element, GstElement *pipeline)
gst_play_cache_empty (GstElement * element, GstElement * pipeline)
{
GstElement *autobin;
GstElement *filesrc;
@ -77,8 +75,8 @@ gst_play_cache_empty (GstElement *element, GstElement *pipeline)
fprintf (stderr, "done with cache_empty\n");
}
int
main (int argc, char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc;
GstElement *pipeline;
@ -105,23 +103,24 @@ main (int argc, char *argv[])
autobin = gst_bin_new ("autobin");
cache = gst_element_factory_make ("autoplugcache", "cache");
g_signal_connect (G_OBJECT (cache), "cache_empty",
G_CALLBACK (gst_play_cache_empty), pipeline);
g_signal_connect (G_OBJECT (cache), "cache_empty",
G_CALLBACK (gst_play_cache_empty), pipeline);
typefind = gst_element_factory_make ("typefind", "typefind");
g_signal_connect (G_OBJECT (typefind), "have_type",
G_CALLBACK (gst_play_have_type), pipeline);
g_signal_connect (G_OBJECT (typefind), "have_type",
G_CALLBACK (gst_play_have_type), pipeline);
gst_bin_add (GST_BIN (autobin), cache);
gst_bin_add (GST_BIN (autobin), typefind);
gst_element_link_pads (cache, "src", typefind, "sink");
gst_element_add_ghost_pad (autobin, gst_element_get_pad (cache, "sink"), "sink");
gst_element_add_ghost_pad (autobin, gst_element_get_pad (cache, "sink"),
"sink");
gst_bin_add (GST_BIN( pipeline), autobin);
gst_bin_add (GST_BIN (pipeline), autobin);
gst_element_link_pads (filesrc, "src", autobin, "sink");
/* start playing */
gst_element_set_state( GST_ELEMENT (pipeline), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
while (gst_bin_iterate (GST_BIN (pipeline)));
@ -130,6 +129,5 @@ main (int argc, char *argv[])
gst_object_unref (GST_OBJECT (pipeline));
exit(0);
exit (0);
}

View file

@ -2,7 +2,7 @@
#include <gst/gst.h>
int
main (int argc, char *argv[])
main (int argc, char *argv[])
{
GstElement *pipeline;
GstElement *filesrc;
@ -15,20 +15,22 @@ main (int argc, char *argv[])
return -1;
}
pipeline = (GstElement*) gst_parse_launch ("filesrc name=my_filesrc ! mad ! osssink", &error);
pipeline =
(GstElement *)
gst_parse_launch ("filesrc name=my_filesrc ! mad ! osssink", &error);
if (!pipeline) {
fprintf (stderr, "Parse error: %s", error->message);
exit (1);
}
filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "my_filesrc");
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (gst_bin_iterate (GST_BIN (pipeline)));
gst_element_set_state (pipeline, GST_STATE_NULL);
return 0;
}

View file

@ -24,88 +24,90 @@
/*#define AUTOPLUG * define if you want autoplugging of input channels * */
/* function prototypes */
input_channel_t* create_input_channel (int id, char* location);
void destroy_input_channel (input_channel_t *pipe);
void env_register_cp (GstElement *volenv, double cp_time, double cp_level);
input_channel_t *create_input_channel (int id, char *location);
void destroy_input_channel (input_channel_t * pipe);
void env_register_cp (GstElement * volenv, double cp_time, double cp_level);
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element)
void
eos (GstElement * element)
{
g_print("have eos, quitting ?\n");
g_print ("have eos, quitting ?\n");
/* playing = FALSE; */
}
G_GNUC_UNUSED static GstCaps*
gst_play_type_find (GstBin *bin, GstElement *element)
G_GNUC_UNUSED static GstCaps *
gst_play_type_find (GstBin * bin, GstElement * element)
{
GstElement *typefind;
GstElement *pipeline;
GstCaps *caps = NULL;
GST_DEBUG ("GstPipeline: typefind for element \"%s\"",
GST_ELEMENT_NAME(element));
GST_ELEMENT_NAME (element));
pipeline = gst_pipeline_new ("autoplug_pipeline");
typefind = gst_element_factory_make ("typefind", "typefind");
g_return_val_if_fail (typefind != NULL, FALSE);
gst_pad_link (gst_element_get_pad (element, "src"),
gst_element_get_pad (typefind, "sink"));
gst_element_get_pad (typefind, "sink"));
gst_bin_add (bin, typefind);
gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (bin));
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* push a buffer... the have_type signal handler will set the found flag */
gst_bin_iterate (GST_BIN (pipeline));
gst_element_set_state (pipeline, GST_STATE_NULL);
caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
gst_pad_unlink (gst_element_get_pad (element, "src"),
gst_element_get_pad (typefind, "sink"));
gst_element_get_pad (typefind, "sink"));
gst_bin_remove (bin, typefind);
gst_bin_remove (GST_BIN (pipeline), GST_ELEMENT (bin));
gst_object_unref (GST_OBJECT (typefind));
gst_object_unref (GST_OBJECT (pipeline));
return caps;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i, j;
int num_channels;
char buffer[20];
GList *input_channels; /* structure holding all the input channels */
GList *input_channels; /* structure holding all the input channels */
input_channel_t *channel_in;
GstElement *main_bin;
GstElement *adder;
GstElement *audiosink;
GstPad *pad; /* to request pads for the adder */
GstPad *pad; /* to request pads for the adder */
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc == 1) {
g_print("usage: %s <filename1> <filename2> <...>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename1> <filename2> <...>\n", argv[0]);
exit (-1);
}
num_channels = argc - 1;
/* set up output channel and main bin */
/* create adder */
adder = gst_element_factory_make ("adder", "adderel");
@ -113,33 +115,33 @@ int main(int argc,char *argv[])
audiosink = gst_element_factory_make ("esdsink", "play_audio");
/* create main bin */
main_bin = gst_pipeline_new("bin");
main_bin = gst_pipeline_new ("bin");
/* link adder and output to bin */
GST_INFO ( "main: adding adder to bin");
gst_bin_add (GST_BIN(main_bin), adder);
GST_INFO ( "main: adding audiosink to bin");
gst_bin_add (GST_BIN(main_bin), audiosink);
GST_INFO ("main: adding adder to bin");
gst_bin_add (GST_BIN (main_bin), adder);
GST_INFO ("main: adding audiosink to bin");
gst_bin_add (GST_BIN (main_bin), audiosink);
/* link adder and audiosink */
gst_pad_link(gst_element_get_pad(adder,"src"),
gst_element_get_pad(audiosink,"sink"));
gst_pad_link (gst_element_get_pad (adder, "src"),
gst_element_get_pad (audiosink, "sink"));
/* start looping */
input_channels = NULL;
for (i = 1; i < argc; ++i)
{
for (i = 1; i < argc; ++i) {
printf ("Opening channel %d from file %s...\n", i, argv[i]);
channel_in = create_input_channel (i, argv[i]);
input_channels = g_list_append (input_channels, channel_in);
if (i > 1) gst_element_set_state (main_bin, GST_STATE_PAUSED);
gst_bin_add (GST_BIN(main_bin), channel_in->pipe);
if (i > 1)
gst_element_set_state (main_bin, GST_STATE_PAUSED);
gst_bin_add (GST_BIN (main_bin), channel_in->pipe);
/* request pads and link to adder */
GST_INFO ( "requesting pad\n");
GST_INFO ("requesting pad\n");
pad = gst_element_get_request_pad (adder, "sink%d");
printf ("\tGot new adder sink pad %s\n", gst_pad_get_name (pad));
sprintf (buffer, "channel%d", i);
@ -155,78 +157,71 @@ int main(int argc,char *argv[])
* at a level ensuring no distortion
* example for three songs :
* song1 : starts at full level, plays 5 seconds, faded out at 10 seconds,
* sleep until 25, fade to end level at 30
* sleep until 25, fade to end level at 30
* song2 : starts silent, fades in at 5 seconds, full blast at 10 seconds,
* full level until 15, faded out at 20, sleep until 25, fade to end at 30
* full level until 15, faded out at 20, sleep until 25, fade to end at 30
* song3 : starts muted, fades in from 15, full at 20, until 25, fade to end level
*/
if (i == 1)
{
if (i == 1) {
/* first song gets special treatment for end style */
env_register_cp (channel_in->volenv, 0.0, 1.0);
env_register_cp (channel_in->volenv, 0.0, 1.0);
} else {
env_register_cp (channel_in->volenv, 0.0, 0.0000001); /* start muted */
env_register_cp (channel_in->volenv, i * 10.0 - 15.0, 0.0000001); /* start fade in */
env_register_cp (channel_in->volenv, i * 10.0 - 10.0, 1.0);
}
else
{
env_register_cp (channel_in->volenv, 0.0 , 0.0000001); /* start muted */
env_register_cp (channel_in->volenv, i * 10.0 - 15.0, 0.0000001); /* start fade in */
env_register_cp (channel_in->volenv, i * 10.0 - 10.0, 1.0);
}
env_register_cp (channel_in->volenv, i * 10.0 - 5.0, 1.0); /* end of full level */
env_register_cp (channel_in->volenv, i * 10.0 - 5.0, 1.0); /* end of full level */
if (i != num_channels)
{
env_register_cp (channel_in->volenv, i * 10.0 , 0.0000001); /* fade to black */
env_register_cp (channel_in->volenv, num_channels * 10.0 - 5.0, 0.0000001); /* start fade in */
}
env_register_cp (channel_in->volenv, num_channels * 10.0 , 1.0 / num_channels); /* to end level */
if (i != num_channels) {
env_register_cp (channel_in->volenv, i * 10.0, 0.0000001); /* fade to black */
env_register_cp (channel_in->volenv, num_channels * 10.0 - 5.0, 0.0000001); /* start fade in */
}
env_register_cp (channel_in->volenv, num_channels * 10.0, 1.0 / num_channels); /* to end level */
#ifndef GST_DISABLE_LOADSAVE
gst_xml_write_file (GST_ELEMENT (main_bin), fopen ("mixer.xml", "w"));
#endif
/* start playing */
gst_element_set_state(main_bin, GST_STATE_PLAYING);
gst_element_set_state (main_bin, GST_STATE_PLAYING);
/* write out the schedule */
gst_scheduler_show(GST_ELEMENT_SCHED(main_bin));
gst_scheduler_show (GST_ELEMENT_SCHED (main_bin));
playing = TRUE;
j = 0;
/*printf ("main: start iterating from 0"); */
while (playing && j < 100)
{
while (playing && j < 100) {
/* printf ("main: iterating %d\n", j); */
gst_bin_iterate(GST_BIN(main_bin));
/*fprintf(stderr,"after iterate()\n"); */
gst_bin_iterate (GST_BIN (main_bin));
/*fprintf(stderr,"after iterate()\n"); */
++j;
}
}
printf ("main: all the channels are open\n");
while (playing)
{
gst_bin_iterate(GST_BIN(main_bin));
while (playing) {
gst_bin_iterate (GST_BIN (main_bin));
/*fprintf(stderr,"after iterate()\n"); */
}
/* stop the bin */
gst_element_set_state(main_bin, GST_STATE_NULL);
gst_element_set_state (main_bin, GST_STATE_NULL);
while (input_channels)
{
while (input_channels) {
destroy_input_channel (input_channels->data);
input_channels = g_list_next (input_channels);
}
g_list_free (input_channels);
gst_object_unref(GST_OBJECT(audiosink));
gst_object_unref(GST_OBJECT(main_bin));
gst_object_unref (GST_OBJECT (audiosink));
exit(0);
gst_object_unref (GST_OBJECT (main_bin));
exit (0);
}
input_channel_t*
create_input_channel (int id, char* location)
input_channel_t *
create_input_channel (int id, char *location)
{
/* create an input channel, reading from location
* return a pointer to the channel
@ -234,51 +229,48 @@ create_input_channel (int id, char* location)
*/
input_channel_t *channel;
char buffer[20]; /* hold the names */
char buffer[20]; /* hold the names */
/* GstAutoplug *autoplug;
GstCaps *srccaps; */
GstElement *new_element;
GstElement *new_element;
GstElement *decoder;
GST_DEBUG ( "c_i_p : creating channel with id %d for file %s",
id, location);
GST_DEBUG ("c_i_p : creating channel with id %d for file %s", id, location);
/* allocate channel */
channel = (input_channel_t *) malloc (sizeof (input_channel_t));
if (channel == NULL)
{
if (channel == NULL) {
printf ("create_input_channel : could not allocate memory for channel !\n");
return NULL;
}
/* create channel */
GST_DEBUG ( "c_i_p : creating pipeline");
GST_DEBUG ("c_i_p : creating pipeline");
sprintf (buffer, "pipeline%d", id);
channel->pipe = gst_bin_new (buffer);
g_assert(channel->pipe != NULL);
g_assert (channel->pipe != NULL);
/* create elements */
GST_DEBUG ( "c_i_p : creating filesrc");
GST_DEBUG ("c_i_p : creating filesrc");
sprintf (buffer, "filesrc%d", id);
channel->filesrc = gst_element_factory_make ("filesrc", buffer);
g_assert(channel->filesrc != NULL);
g_assert (channel->filesrc != NULL);
GST_DEBUG ( "c_i_p : setting location");
g_object_set(G_OBJECT(channel->filesrc),"location", location, NULL);
GST_DEBUG ("c_i_p : setting location");
g_object_set (G_OBJECT (channel->filesrc), "location", location, NULL);
/* add filesrc to the bin before autoplug */
gst_bin_add(GST_BIN(channel->pipe), channel->filesrc);
gst_bin_add (GST_BIN (channel->pipe), channel->filesrc);
/* link signal to eos of filesrc */
g_signal_connect (G_OBJECT(channel->filesrc),"eos",
G_CALLBACK(eos),NULL);
g_signal_connect (G_OBJECT (channel->filesrc), "eos", G_CALLBACK (eos), NULL);
#ifdef DEBUG
@ -287,7 +279,7 @@ create_input_channel (int id, char* location)
sprintf (buffer, "volenv%d", id);
channel->volenv = gst_element_factory_make ("volenv", buffer);
g_assert(channel->volenv != NULL);
g_assert (channel->volenv != NULL);
/* autoplug the pipe */
@ -308,7 +300,7 @@ create_input_channel (int id, char* location)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_bin_remove (GST_BIN (pipeline), channel->pipe);
}
#endif
@ -317,7 +309,6 @@ create_input_channel (int id, char* location)
g_print ("could not autoplug, unknown media type...\n");
exit (-1);
}
#ifdef DEBUG
printf ("DEBUG : c_i_p : creating autoplug\n");
#endif
@ -328,51 +319,49 @@ create_input_channel (int id, char* location)
#ifdef DEBUG
printf ("DEBUG : c_i_p : autoplugging\n");
#endif
new_element = gst_autoplug_to_caps (autoplug, srccaps,
gst_caps_new ("audio/raw", NULL), NULL);
new_element = gst_autoplug_to_caps (autoplug, srccaps,
gst_caps_new ("audio/raw", NULL), NULL);
if (!new_element) {
g_print ("could not autoplug, no suitable codecs found...\n");
exit (-1);
}
#else
new_element = gst_bin_new ("autoplug_bin");
/* static plug, use mad plugin and assume mp3 input */
printf ("using static plugging for input channel\n");
decoder = gst_element_factory_make ("mad", "mpg123");
if (!decoder)
{
decoder = gst_element_factory_make ("mad", "mpg123");
if (!decoder) {
fprintf (stderr, "Could not get a decoder element !\n");
exit (1);
}
gst_bin_add (GST_BIN (new_element), decoder);
gst_element_add_ghost_pad (new_element,
gst_element_get_pad (decoder, "sink"), "sink");
gst_element_add_ghost_pad (new_element,
gst_element_get_pad (decoder, "src"), "src_00");
#endif
gst_element_add_ghost_pad (new_element,
gst_element_get_pad (decoder, "sink"), "sink");
gst_element_add_ghost_pad (new_element,
gst_element_get_pad (decoder, "src"), "src_00");
#endif
#ifndef GST_DISABLE_LOADSAVE
gst_xml_write_file (GST_ELEMENT (new_element), fopen ("mixer.gst", "w"));
#endif
#endif
gst_bin_add (GST_BIN(channel->pipe), channel->volenv);
gst_bin_add (GST_BIN (channel->pipe), channel->volenv);
gst_bin_add (GST_BIN (channel->pipe), new_element);
gst_element_link_pads (channel->filesrc, "src", new_element, "sink");
gst_element_link_pads (new_element, "src_00", channel->volenv, "sink");
/* add a ghost pad */
sprintf (buffer, "channel%d", id);
gst_element_add_ghost_pad (channel->pipe,
gst_element_get_pad (channel->volenv, "src"), buffer);
gst_element_get_pad (channel->volenv, "src"), buffer);
#ifdef DEBUG
printf ("DEBUG : c_i_p : end function\n");
#endif
@ -381,12 +370,12 @@ create_input_channel (int id, char* location)
}
void
destroy_input_channel (input_channel_t *channel)
destroy_input_channel (input_channel_t * channel)
{
/*
* destroy an input channel
*/
#ifdef DEBUG
printf ("DEBUG : d_i_p : start\n");
#endif
@ -398,11 +387,12 @@ destroy_input_channel (input_channel_t *channel)
free (channel);
}
void env_register_cp (GstElement *volenv, double cp_time, double cp_level)
void
env_register_cp (GstElement * volenv, double cp_time, double cp_level)
{
char buffer[30];
sprintf (buffer, "%f:%f", cp_time, cp_level);
g_object_set(G_OBJECT(volenv), "controlpoint", buffer, NULL);
g_object_set (G_OBJECT (volenv), "controlpoint", buffer, NULL);
}

View file

@ -3,10 +3,10 @@
* thomas@apestaart.org
*/
typedef struct
typedef struct
{
GstElement *pipe, *filesrc, *volenv;
char *location;
int channel_id;
} input_channel_t;

View file

@ -19,7 +19,7 @@
#include <gst/gst.h>
static GstElement*
static GstElement *
make_bin (gint count)
{
GstElement *bin;
@ -42,7 +42,7 @@ make_bin (gint count)
}
gint
main (gint argc, gchar *argv[])
main (gint argc, gchar * argv[])
{
GstElement *pipeline;
GstElement *aggregator, *sink;
@ -53,9 +53,9 @@ main (gint argc, gchar *argv[])
gst_init (&argc, &argv);
pipeline = gst_pipeline_new ("main");
g_signal_connect (pipeline, "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (pipeline, "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
aggregator = gst_element_factory_make ("aggregator", "mixer");
sink = gst_element_factory_make ("fakesink", "sink");
@ -85,7 +85,7 @@ main (gint argc, gchar *argv[])
i = 4;
while (i--)
gst_bin_iterate (GST_BIN (pipeline));
g_print ("playing bin1\n");
gst_element_set_state (bin1, GST_STATE_PLAYING);

View file

@ -27,18 +27,18 @@
* plugin, as well as author and version data. Use the GST_ELEMENT_DETAILS
* macro when defining it.
*/
static GstElementDetails example_details = GST_ELEMENT_DETAILS (
"An example plugin",
"Example/FirstExample",
"Shows the basic structure of a plugin",
"your name <your.name@your.isp>"
);
static GstElementDetails example_details =
GST_ELEMENT_DETAILS ("An example plugin",
"Example/FirstExample",
"Shows the basic structure of a plugin",
"your name <your.name@your.isp>");
/* These are the signals that this element can fire. They are zero-
* based because the numbers themselves are private to the object.
* LAST_SIGNAL is used for initialization of the signal array.
*/
enum {
enum
{
ASDF,
/* FILL ME */
LAST_SIGNAL
@ -47,51 +47,46 @@ enum {
/* Arguments are identified the same way, but cannot be zero, so you
* must leave the ARG_0 entry in as a placeholder.
*/
enum {
enum
{
ARG_0,
ARG_ACTIVE
/* FILL ME */
/* FILL ME */
};
/* The PadFactory structures describe what pads the element has or
* can have. They can be quite complex, but for this example plugin
* they are rather simple.
*/
GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE (
"sink", /* The name of the pad */
GST_PAD_SINK, /* Direction of the pad */
GST_PAD_ALWAYS, /* The pad exists for every instance */
GST_STATIC_CAPS (
"unknown/unknown, " /* The MIME media type */
"foo:int=1, " /* an integer property */
"bar:boolean=true, " /* a boolean property */
"baz:int={ 1, 3 }" /* a list of values */
)
);
GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", /* The name of the pad */
GST_PAD_SINK, /* Direction of the pad */
GST_PAD_ALWAYS, /* The pad exists for every instance */
GST_STATIC_CAPS ("unknown/unknown, " /* The MIME media type */
"foo:int=1, " /* an integer property */
"bar:boolean=true, " /* a boolean property */
"baz:int={ 1, 3 }" /* a list of values */
)
);
/* This factory is much simpler, and defines the source pad. */
GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"unknown/unknown"
)
);
GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("unknown/unknown")
);
/* A number of functon prototypes are given so we can refer to them later. */
static void gst_example_class_init (GstExampleClass *klass);
static void gst_example_init (GstExample *example);
static void gst_example_class_init (GstExampleClass * klass);
static void gst_example_init (GstExample * example);
static void gst_example_chain (GstPad *pad, GstData *_data);
static void gst_example_chain (GstPad * pad, GstData * _data);
static void gst_example_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_example_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static GstElementStateReturn
gst_example_change_state (GstElement *element);
static void gst_example_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_example_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstElementStateReturn gst_example_change_state (GstElement * element);
/* The parent class pointer needs to be kept around for some object
* operations.
@ -109,23 +104,25 @@ static guint gst_example_signals[LAST_SIGNAL] = { 0 };
* and pointers to the various functions that define the class.
*/
GType
gst_example_get_type(void)
gst_example_get_type (void)
{
static GType example_type = 0;
if (!example_type) {
static const GTypeInfo example_info = {
sizeof(GstExampleClass),
sizeof (GstExampleClass),
NULL,
NULL,
(GClassInitFunc)gst_example_class_init,
(GClassInitFunc) gst_example_class_init,
NULL,
NULL,
sizeof(GstExample),
sizeof (GstExample),
0,
(GInstanceInitFunc)gst_example_init,
(GInstanceInitFunc) gst_example_init,
};
example_type = g_type_register_static(GST_TYPE_ELEMENT, "GstExample", &example_info, 0);
example_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstExample", &example_info,
0);
}
return example_type;
}
@ -135,7 +132,7 @@ gst_example_get_type(void)
* it, based on the pointer to the function provided above.
*/
static void
gst_example_class_init (GstExampleClass *klass)
gst_example_class_init (GstExampleClass * klass)
{
/* Class pointers are needed to supply pointers to the private
* implementations of parent class methods.
@ -146,27 +143,24 @@ gst_example_class_init (GstExampleClass *klass)
/* Since the example class contains the parent classes, you can simply
* cast the pointer to get access to the parent classes.
*/
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
/* The parent class is needed for class method overrides. */
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
/* Here we add an argument to the object. This argument is an integer,
* and can be both read and written.
*/
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ACTIVE,
g_param_spec_int("active","active","active",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACTIVE, g_param_spec_int ("active", "active", "active", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); /* CHECKME */
/* Here we add a signal to the object. This is avery useless signal
* called asdf. The signal will also pass a pointer to the listeners
* which happens to be the example element itself */
gst_example_signals[ASDF] =
g_signal_new("asdf", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstExampleClass, asdf), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
GST_TYPE_EXAMPLE);
g_signal_new ("asdf", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstExampleClass, asdf), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, GST_TYPE_EXAMPLE);
/* The last thing is to provide the functions that implement get and set
@ -193,31 +187,33 @@ gst_example_class_init (GstExampleClass *klass)
* the plugin.
*/
static void
gst_example_init(GstExample *example)
gst_example_init (GstExample * example)
{
/* First we create the sink pad, which is the input to the element.
* We will use the template constructed by the factory.
*/
example->sinkpad = gst_pad_new_from_template (
gst_static_pad_template_get (&sink_template), "sink");
example->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
"sink");
/* Setting the chain function allows us to supply the function that will
* actually be performing the work. Without this, the element would do
* nothing, with undefined results (assertion failures and such).
*/
gst_pad_set_chain_function(example->sinkpad,gst_example_chain);
gst_pad_set_chain_function (example->sinkpad, gst_example_chain);
/* We then must add this pad to the element's list of pads. The base
* element class manages the list of pads, and provides accessors to it.
*/
gst_element_add_pad(GST_ELEMENT(example),example->sinkpad);
gst_element_add_pad (GST_ELEMENT (example), example->sinkpad);
/* The src pad, the output of the element, is created and registered
* in the same way, with the exception of the chain function. Source
* pads don't have chain functions, because they can't accept buffers,
* they only produce them.
*/
example->srcpad = gst_pad_new_from_template (
gst_static_pad_template_get (&src_template), "src");
gst_element_add_pad(GST_ELEMENT(example),example->srcpad);
example->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
"src");
gst_element_add_pad (GST_ELEMENT (example), example->srcpad);
/* Initialization of element's private variables. */
example->active = FALSE;
@ -228,7 +224,7 @@ gst_example_init(GstExample *example)
* as the buffer provided by the peer element.
*/
static void
gst_example_chain (GstPad *pad, GstData *_data)
gst_example_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstExample *example;
@ -237,34 +233,35 @@ gst_example_chain (GstPad *pad, GstData *_data)
/* Some of these checks are of dubious value, since if there were not
* already true, the chain function would never be called.
*/
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail(buf != NULL);
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (buf != NULL);
/* We need to get a pointer to the element this pad belogs to. */
example = GST_EXAMPLE(gst_pad_get_parent (pad));
example = GST_EXAMPLE (gst_pad_get_parent (pad));
/* A few more sanity checks to make sure that the element that owns
* this pad is the right kind of element, in case something got confused.
*/
g_return_if_fail(example != NULL);
g_return_if_fail(GST_IS_EXAMPLE(example));
g_return_if_fail (example != NULL);
g_return_if_fail (GST_IS_EXAMPLE (example));
/* If we are supposed to be doing something, here's where it happens. */
if (example->active) {
/* In this example we're going to copy the buffer to another one,
* so we need to allocate a new buffer first. */
outbuf = gst_buffer_new();
outbuf = gst_buffer_new ();
/* We need to copy the size and offset of the buffer at a minimum. */
GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf);
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
/* Then allocate the memory for the new buffer */
GST_BUFFER_DATA (outbuf) = (guchar *)g_malloc (GST_BUFFER_SIZE (outbuf));
GST_BUFFER_DATA (outbuf) = (guchar *) g_malloc (GST_BUFFER_SIZE (outbuf));
/* Then copy the data in the incoming buffer into the new buffer. */
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (outbuf));
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (outbuf));
/* we don't need the incomming buffer anymore so we unref it. When we are
* the last plugin with a handle to the buffer, its memory will be freed */
@ -274,15 +271,14 @@ gst_example_chain (GstPad *pad, GstData *_data)
* in the pipeline, through the element's source pad, which is stored
* in the element's structure.
*/
gst_pad_push(example->srcpad,GST_DATA (outbuf));
gst_pad_push (example->srcpad, GST_DATA (outbuf));
/* For fun we'll emit our useless signal here */
g_signal_emit(G_OBJECT (example), gst_example_signals[ASDF], 0,
example);
g_signal_emit (G_OBJECT (example), gst_example_signals[ASDF], 0, example);
/* If we're not doing something, just send the original incoming buffer. */
/* If we're not doing something, just send the original incoming buffer. */
} else {
gst_pad_push(example->srcpad,GST_DATA (buf));
gst_pad_push (example->srcpad, GST_DATA (buf));
}
}
@ -290,15 +286,16 @@ gst_example_chain (GstPad *pad, GstData *_data)
* enable the element to respond to various arguments.
*/
static void
gst_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_example_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstExample *example;
/* It's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_EXAMPLE(object));
g_return_if_fail (GST_IS_EXAMPLE (object));
/* Get a pointer of the right type. */
example = GST_EXAMPLE(object);
example = GST_EXAMPLE (object);
/* Check the argument id to see which argument we're setting. */
switch (prop_id) {
@ -309,7 +306,7 @@ gst_example_set_property (GObject *object, guint prop_id, const GValue *value, G
* is running, if you are using threads.
*/
example->active = g_value_get_int (value);
g_print("example: set active to %d\n",example->active);
g_print ("example: set active to %d\n", example->active);
break;
default:
break;
@ -318,13 +315,14 @@ gst_example_set_property (GObject *object, guint prop_id, const GValue *value, G
/* The set function is simply the inverse of the get fuction. */
static void
gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_example_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstExample *example;
/* It's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_EXAMPLE(object));
example = GST_EXAMPLE(object);
g_return_if_fail (GST_IS_EXAMPLE (object));
example = GST_EXAMPLE (object);
switch (prop_id) {
case ARG_ACTIVE:
@ -342,38 +340,38 @@ gst_example_get_property (GObject *object, guint prop_id, GValue *value, GParamS
* in the various state transitions.
*/
static GstElementStateReturn
gst_example_change_state (GstElement *element)
gst_example_change_state (GstElement * element)
{
GstExample *example;
/* cast to our plugin */
example = GST_EXAMPLE(element);
example = GST_EXAMPLE (element);
/* we perform our actions based on the state transition
* of the element */
switch (GST_STATE_TRANSITION (element)) {
/* The NULL to READY transition is used to
* create threads (if any) */
/* The NULL to READY transition is used to
* create threads (if any) */
case GST_STATE_NULL_TO_READY:
break;
/* In the READY to PAUSED state, the element should
* open devices (if any) */
/* In the READY to PAUSED state, the element should
* open devices (if any) */
case GST_STATE_READY_TO_PAUSED:
break;
/* In the PAUSED to PLAYING state, the element should
* prepare itself for operation or continue after a PAUSE */
/* In the PAUSED to PLAYING state, the element should
* prepare itself for operation or continue after a PAUSE */
case GST_STATE_PAUSED_TO_PLAYING:
break;
/* In the PLAYING to PAUSED state, the element should
* PAUSE itself and make sure it can resume operation */
/* In the PLAYING to PAUSED state, the element should
* PAUSE itself and make sure it can resume operation */
case GST_STATE_PLAYING_TO_PAUSED:
break;
/* In the PAUSED to READY state, the element should reset
* its internal state and close any devices. */
/* In the PAUSED to READY state, the element should reset
* its internal state and close any devices. */
case GST_STATE_PAUSED_TO_READY:
break;
/* The element should free all resources, terminate threads
* and put itself into its initial state again */
/* The element should free all resources, terminate threads
* and put itself into its initial state again */
case GST_STATE_READY_TO_NULL:
break;
}
@ -387,13 +385,14 @@ gst_example_change_state (GstElement *element)
* this function is called to register everything that the plugin provides.
*/
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
/* We need to register each element we provide with the plugin. This consists
* of the name of the element, a rank that gives the importance of the element
* when compared to similar plugins and the GType identifier.
*/
if (!gst_element_register (plugin, "example", GST_RANK_MARGINAL, GST_TYPE_EXAMPLE))
if (!gst_element_register (plugin, "example", GST_RANK_MARGINAL,
GST_TYPE_EXAMPLE))
return FALSE;
/* Now we can return successfully. */
@ -411,21 +410,19 @@ plugin_init (GstPlugin *plugin)
* The symbol pointing to this structure is the only symbol looked up when
* loading the plugin.
*/
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR, /* The major version of the core that this was built with */
GST_VERSION_MINOR, /* The minor version of the core that this was built with */
"example", /* The name of the plugin. This must be unique: plugins with
* the same name will be assumed to be identical, and only
* one will be loaded. */
"an example plugin", /* a short description of the plugin in English */
plugin_init, /* Pointer to the initialisation function for the plugin. */
"0.1", /* The version number of the plugin */
"LGPL", /* ieffective license the plugin can be shipped with. Must be
* valid for all libraries it links to, too. */
"my nifty plugin package",
/* package this plugin belongs to. */
"http://www.mydomain.com"
/* originating URL for this plugin. This is the place to look
* for updates, information and so on. */
);
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, /* The major version of the core that this was built with */
GST_VERSION_MINOR, /* The minor version of the core that this was built with */
"example", /* The name of the plugin. This must be unique: plugins with
* the same name will be assumed to be identical, and only
* one will be loaded. */
"an example plugin", /* a short description of the plugin in English */
plugin_init, /* Pointer to the initialisation function for the plugin. */
"0.1", /* The version number of the plugin */
"LGPL", /* ieffective license the plugin can be shipped with. Must be
* valid for all libraries it links to, too. */
"my nifty plugin package",
/* package this plugin belongs to. */
"http://www.mydomain.com"
/* originating URL for this plugin. This is the place to look
* for updates, information and so on. */
);

View file

@ -24,7 +24,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
/* This is the definition of the element's object structure. */
typedef struct _GstExample GstExample;
@ -33,11 +32,12 @@ typedef struct _GstExample GstExample;
* the beginning of the object. This allows the element to be cast to
* an Element or even an Object.
*/
struct _GstExample {
struct _GstExample
{
GstElement element;
/* We need to keep track of our pads, so we do so here. */
GstPad *sinkpad,*srcpad;
GstPad *sinkpad, *srcpad;
/* We'll use this to decide whether to do anything to the data we get. */
gboolean active;
@ -49,11 +49,12 @@ struct _GstExample {
* structure. */
typedef struct _GstExampleClass GstExampleClass;
struct _GstExampleClass {
struct _GstExampleClass
{
GstElementClass parent_class;
/* signals */
void (*asdf) (GstElement *element, GstExample *example);
void (*asdf) (GstElement * element, GstExample * example);
};
/* Five standard preprocessing macros are used in the Gtk+ object system.
@ -80,8 +81,7 @@ struct _GstExampleClass {
/* This is the only prototype needed, because it is used in the above
* GST_TYPE_EXAMPLE macro.
*/
GType gst_example_get_type(void);
GType gst_example_get_type (void);
G_END_DECLS
#endif /* __GST_EXAMPLE_H__ */

View file

@ -1,56 +1,56 @@
#include <stdlib.h>
#include <gst/gst.h>
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink, *parse, *decode, *queue;
GstElement *bin;
GstElement *thread;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new("thread");
g_assert(thread != NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
g_assert(bin != NULL);
bin = gst_bin_new ("bin");
g_assert (bin != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
parse = gst_element_factory_make("mp3parse", "parse");
decode = gst_element_factory_make("mpg123", "decode");
parse = gst_element_factory_make ("mp3parse", "parse");
decode = gst_element_factory_make ("mpg123", "decode");
queue = gst_element_factory_make("queue", "queue");
queue = gst_element_factory_make ("queue", "queue");
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
/* add objects to the main pipeline */
gst_bin_add_many (GST_BIN (bin), filesrc, parse, decode, queue, NULL);
gst_bin_add(GST_BIN(thread), osssink);
gst_bin_add(GST_BIN(bin), thread);
gst_bin_add (GST_BIN (thread), osssink);
gst_bin_add (GST_BIN (bin), thread);
gst_element_link_many (filesrc, parse, decode, queue, osssink, NULL);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
while (gst_bin_iterate(GST_BIN(bin)));
while (gst_bin_iterate (GST_BIN (bin)));
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -4,78 +4,78 @@
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
void
eos (GstElement * element, gpointer data)
{
g_print("have eos, quitting\n");
g_print ("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink, *queue;
GstElement *pipeline;
GstElement *thread;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new("thread");
g_assert(thread != NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new("pipeline");
g_assert(pipeline != NULL);
pipeline = gst_pipeline_new ("pipeline");
g_assert (pipeline != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
g_signal_connect (G_OBJECT(filesrc),"eos",
G_CALLBACK(eos), thread);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (eos), thread);
queue = gst_element_factory_make("queue", "queue");
queue = gst_element_factory_make ("queue", "queue");
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
/* add objects to the main pipeline */
/*
gst_pipeline_add_src(GST_PIPELINE(pipeline), filesrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue);
gst_pipeline_add_src(GST_PIPELINE(pipeline), filesrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue);
gst_bin_add(GST_BIN(thread), osssink);
gst_bin_add(GST_BIN(thread), osssink);
gst_pad_link(gst_element_get_pad(queue,"src"),
gst_element_get_pad(osssink,"sink"));
gst_pad_link(gst_element_get_pad(queue,"src"),
gst_element_get_pad(osssink,"sink"));
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("cannot autoplug pipeline\n");
exit(-1);
}
*/
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("cannot autoplug pipeline\n");
exit(-1);
}
*/
gst_bin_add(GST_BIN(pipeline), thread);
gst_bin_add (GST_BIN (pipeline), thread);
/* make it ready */
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(pipeline));
gst_bin_iterate (GST_BIN (pipeline));
}
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -4,73 +4,73 @@
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
void
eos (GstElement * element, gpointer data)
{
g_print("have eos, quitting\n");
g_print ("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink, *queue, *parse, *decode;
GstElement *bin;
GstElement *thread;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new("thread");
g_assert(thread != NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
g_assert(bin != NULL);
bin = gst_bin_new ("bin");
g_assert (bin != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
g_signal_connect(G_OBJECT(filesrc),"eos",
G_CALLBACK(eos), thread);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (eos), thread);
queue = gst_element_factory_make("queue", "queue");
queue = gst_element_factory_make ("queue", "queue");
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
parse = gst_element_factory_make("mp3parse", "parse");
decode = gst_element_factory_make("mpg123", "decode");
parse = gst_element_factory_make ("mp3parse", "parse");
decode = gst_element_factory_make ("mpg123", "decode");
/* add objects to the main bin */
gst_bin_add(GST_BIN(bin), filesrc);
gst_bin_add(GST_BIN(bin), queue);
gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), queue);
gst_bin_add(GST_BIN(thread), parse);
gst_bin_add(GST_BIN(thread), decode);
gst_bin_add(GST_BIN(thread), osssink);
gst_bin_add (GST_BIN (thread), parse);
gst_bin_add (GST_BIN (thread), decode);
gst_bin_add (GST_BIN (thread), osssink);
gst_element_link_many (filesrc, queue, parse, decode, osssink, NULL);
/* make it ready */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
gst_bin_iterate (GST_BIN (bin));
}
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -4,81 +4,81 @@
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
void
eos (GstElement * element, gpointer data)
{
g_print("have eos, quitting\n");
g_print ("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink, *queue, *queue2, *parse, *decode;
GstElement *bin;
GstElement *thread, *thread2;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new("thread");
g_assert(thread != NULL);
thread2 = gst_thread_new("thread2");
g_assert(thread2 != NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
thread2 = gst_thread_new ("thread2");
g_assert (thread2 != NULL);
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
g_assert(bin != NULL);
bin = gst_bin_new ("bin");
g_assert (bin != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
g_signal_connect(G_OBJECT(filesrc),"eos",
G_CALLBACK(eos), thread);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (eos), thread);
queue = gst_element_factory_make("queue", "queue");
queue2 = gst_element_factory_make("queue", "queue2");
queue = gst_element_factory_make ("queue", "queue");
queue2 = gst_element_factory_make ("queue", "queue2");
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
parse = gst_element_factory_make("mp3parse", "parse");
decode = gst_element_factory_make("mpg123", "decode");
parse = gst_element_factory_make ("mp3parse", "parse");
decode = gst_element_factory_make ("mpg123", "decode");
/* add objects to the main bin */
gst_bin_add(GST_BIN(bin), filesrc);
gst_bin_add(GST_BIN(bin), queue);
gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), queue);
gst_bin_add(GST_BIN(thread), parse);
gst_bin_add(GST_BIN(thread), decode);
gst_bin_add(GST_BIN(thread), queue2);
gst_bin_add (GST_BIN (thread), parse);
gst_bin_add (GST_BIN (thread), decode);
gst_bin_add (GST_BIN (thread), queue2);
gst_bin_add(GST_BIN(thread2), osssink);
gst_bin_add (GST_BIN (thread2), osssink);
gst_element_link_many (filesrc, queue, parse, decode, queue2, osssink, NULL);
gst_bin_add(GST_BIN(bin), thread);
gst_bin_add(GST_BIN(bin), thread2);
gst_bin_add (GST_BIN (bin), thread);
gst_bin_add (GST_BIN (bin), thread2);
/* make it ready */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
gst_bin_iterate (GST_BIN (bin));
}
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -16,11 +16,11 @@
#include <string.h>
int
main (int argc, char *argv[])
main (int argc, char *argv[])
{
GstElement *bin, *filesrc, *tag_changer, *filesink;
gchar *artist, *title, *ext, *filename;
/* initialize GStreamer */
gst_init (&argc, &argv);
@ -36,7 +36,8 @@ main (int argc, char *argv[])
artist = argv[1];
artist = g_strdup (artist);
ext = strrchr (artist, '.');
if (ext) *ext = '\0';
if (ext)
*ext = '\0';
title = strstr (artist, " - ");
if (title == NULL) {
g_print ("The format of the mp3 file is invalid.\n");
@ -44,8 +45,8 @@ main (int argc, char *argv[])
}
*title = '\0';
title += 3;
/* create a new bin to hold the elements */
bin = gst_pipeline_new ("pipeline");
g_assert (bin);
@ -66,25 +67,24 @@ main (int argc, char *argv[])
g_assert (filesink);
/* set the filenames */
filename = g_strdup_printf ("%s.temp", argv[1]); /* easy solution */
filename = g_strdup_printf ("%s.temp", argv[1]); /* easy solution */
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_object_set (G_OBJECT (filesink), "location", filename, NULL);
/* make sure the tag setter uses our stuff
(though that should already be default) */
gst_tag_setter_set_merge_mode (GST_TAG_SETTER (tag_changer), GST_TAG_MERGE_KEEP);
gst_tag_setter_set_merge_mode (GST_TAG_SETTER (tag_changer),
GST_TAG_MERGE_KEEP);
/* set the tagging information */
gst_tag_setter_add (GST_TAG_SETTER (tag_changer), GST_TAG_MERGE_REPLACE,
GST_TAG_ARTIST, artist,
GST_TAG_TITLE, title,
NULL);
GST_TAG_ARTIST, artist, GST_TAG_TITLE, title, NULL);
/* add objects to the main pipeline */
gst_bin_add_many (GST_BIN (bin), filesrc, tag_changer, filesink, NULL);
/* link the elements */
g_assert (gst_element_link_many (filesrc, tag_changer, filesink));
/* start playing */
gst_element_set_state (bin, GST_STATE_PLAYING);
@ -100,4 +100,3 @@ main (int argc, char *argv[])
return 0;
}

View file

@ -16,11 +16,11 @@
#include <string.h>
int
main (int argc, char *argv[])
main (int argc, char *argv[])
{
GstElement *bin, *filesrc, *decoder, *encoder, *filesink;
gchar *artist, *title, *ext, *filename;
/* initialize GStreamer */
gst_init (&argc, &argv);
@ -36,7 +36,8 @@ main (int argc, char *argv[])
artist = argv[1];
artist = g_strdup (artist);
ext = strrchr (artist, '.');
if (ext) *ext = '\0';
if (ext)
*ext = '\0';
title = strstr (artist, " - ");
if (title == NULL) {
g_print ("The format of the mp3 file is invalid.\n");
@ -45,8 +46,8 @@ main (int argc, char *argv[])
}
*title = '\0';
title += 3;
/* create a new bin to hold the elements */
bin = gst_pipeline_new ("pipeline");
g_assert (bin);
@ -68,13 +69,13 @@ main (int argc, char *argv[])
g_print ("cound not find plugin \"vorbisenc\"");
return 1;
}
/* and a file writer */
filesink = gst_element_factory_make ("filesink", "filesink");
g_assert (filesink);
/* set the filenames */
filename = g_strdup_printf ("%s.ogg", argv[1]); /* easy solution */
filename = g_strdup_printf ("%s.ogg", argv[1]); /* easy solution */
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_object_set (G_OBJECT (filesink), "location", filename, NULL);
g_free (filename);
@ -84,16 +85,14 @@ main (int argc, char *argv[])
gst_tag_setter_set_merge_mode (GST_TAG_SETTER (encoder), GST_TAG_MERGE_KEEP);
/* set the tagging information */
gst_tag_setter_add (GST_TAG_SETTER (encoder), GST_TAG_MERGE_REPLACE,
GST_TAG_ARTIST, artist,
GST_TAG_TITLE, title,
NULL);
GST_TAG_ARTIST, artist, GST_TAG_TITLE, title, NULL);
/* add objects to the main pipeline */
gst_bin_add_many (GST_BIN (bin), filesrc, decoder, encoder, filesink, NULL);
/* link the elements */
gst_element_link_many (filesrc, decoder, encoder, filesink, NULL);
/* start playing */
gst_element_set_state (bin, GST_STATE_PLAYING);
@ -104,4 +103,3 @@ main (int argc, char *argv[])
return 0;
}

View file

@ -2,73 +2,75 @@
#include <gst/gst.h>
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
void
eos (GstElement * element, gpointer data)
{
GstThread *thread = GST_THREAD(data);
g_print("have eos, quitting\n");
GstThread *thread = GST_THREAD (data);
g_print ("have eos, quitting\n");
/* stop the bin */
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
gst_main_quit();
gst_main_quit ();
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink;
GstElement *pipeline;
GstElement *thread;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new thread to hold the elements */
thread = gst_thread_new("thread");
g_assert(thread != NULL);
thread = gst_thread_new ("thread");
g_assert (thread != NULL);
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new("pipeline");
g_assert(pipeline != NULL);
pipeline = gst_pipeline_new ("pipeline");
g_assert (pipeline != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
g_signal_connect(G_OBJECT(filesrc),"eos",
G_CALLBACK(eos), thread);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (eos), thread);
/* and an audio sink */
osssink = gst_element_factory_make("osssink", "play_audio");
g_assert(osssink != NULL);
osssink = gst_element_factory_make ("osssink", "play_audio");
g_assert (osssink != NULL);
/* add objects to the main pipeline */
/*
gst_pipeline_add_src(GST_PIPELINE(pipeline), filesrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink);
gst_pipeline_add_src(GST_PIPELINE(pipeline), filesrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink);
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}
*/
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
g_print("unable to handle stream\n");
exit(-1);
}
*/
/*gst_bin_remove(GST_BIN(pipeline), filesrc); */
/*gst_bin_add(GST_BIN(thread), filesrc); */
gst_bin_add(GST_BIN(thread), GST_ELEMENT(pipeline));
gst_bin_add (GST_BIN (thread), GST_ELEMENT (pipeline));
/* make it ready */
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_READY);
gst_element_set_state (GST_ELEMENT (thread), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(thread), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING);
gst_main();
gst_main ();
gst_object_unref(GST_OBJECT(thread));
gst_object_unref (GST_OBJECT (thread));
exit(0);
exit (0);
}

View file

@ -1,12 +1,12 @@
#include <gst/gst.h>
void
type_found (GstElement *typefind, const GstCaps * caps)
type_found (GstElement * typefind, const GstCaps * caps)
{
xmlDocPtr doc;
xmlNodePtr parent;
doc = xmlNewDoc ("1.0");
doc = xmlNewDoc ("1.0");
doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
parent = xmlNewChild (doc->xmlRootNode, NULL, "Caps1", NULL);
@ -16,46 +16,45 @@ type_found (GstElement *typefind, const GstCaps * caps)
xmlDocDump (stdout, doc);
}
int
main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
GstElement *bin, *filesrc, *typefind;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create a new bin to hold the elements */
bin = gst_pipeline_new("bin");
g_assert(bin != NULL);
bin = gst_pipeline_new ("bin");
g_assert (bin != NULL);
/* create a file reader */
filesrc = gst_element_factory_make("filesrc", "file_source");
g_assert(filesrc != NULL);
g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL);
filesrc = gst_element_factory_make ("filesrc", "file_source");
g_assert (filesrc != NULL);
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
typefind = gst_element_factory_make("typefind", "typefind");
g_assert(typefind != NULL);
typefind = gst_element_factory_make ("typefind", "typefind");
g_assert (typefind != NULL);
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), filesrc);
gst_bin_add(GST_BIN(bin), typefind);
gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), typefind);
g_signal_connect (G_OBJECT (typefind), "have_type",
G_CALLBACK (type_found), NULL);
g_signal_connect (G_OBJECT (typefind), "have_type",
G_CALLBACK (type_found), NULL);
gst_element_link (filesrc, typefind);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
gst_bin_iterate(GST_BIN(bin));
gst_bin_iterate (GST_BIN (bin));
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -4,34 +4,37 @@
gboolean playing;
static void
object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
object_saved (GstObject * object, xmlNodePtr parent, gpointer data)
{
xmlNodePtr child;
xmlNsPtr ns;
/* first see if the namespace is already known */
ns = xmlSearchNsByHref (parent->doc, parent, "http://gstreamer.net/gst-test/1.0/");
ns = xmlSearchNsByHref (parent->doc, parent,
"http://gstreamer.net/gst-test/1.0/");
if (ns == NULL) {
xmlNodePtr root = xmlDocGetRootElement (parent->doc);
/* add namespace to root node */
ns = xmlNewNs (root, "http://gstreamer.net/gst-test/1.0/", "test");
}
child = xmlNewChild(parent, ns, "comment", NULL);
xmlNewChild(child, NULL, "text", (gchar *)data);
child = xmlNewChild (parent, ns, "comment", NULL);
xmlNewChild (child, NULL, "text", (gchar *) data);
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *filesrc, *osssink, *queue, *queue2, *decode;
GstElement *pipeline;
GstElement *thread, *thread2;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
if (argc != 2) {
g_print("usage: %s <filename>\n", argv[0]);
exit(-1);
g_print ("usage: %s <filename>\n", argv[0]);
exit (-1);
}
/* create new threads to hold the elements */
@ -42,12 +45,10 @@ int main(int argc,char *argv[])
/* these signals will allow us to save custom tags with the gst xml output */
g_signal_connect (G_OBJECT (thread), "object_saved",
G_CALLBACK (object_saved),
g_strdup ("decoder thread"));
G_CALLBACK (object_saved), g_strdup ("decoder thread"));
g_signal_connect (G_OBJECT (thread2), "object_saved",
G_CALLBACK (object_saved),
g_strdup ("render thread"));
G_CALLBACK (object_saved), g_strdup ("render thread"));
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new ("pipeline");
g_assert (pipeline != NULL);
@ -89,4 +90,3 @@ int main(int argc,char *argv[])
exit (0);
}

View file

@ -5,7 +5,7 @@
gboolean playing;
G_GNUC_UNUSED static void
xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
xml_loaded (GstXML * xml, GstObject * object, xmlNodePtr self, gpointer data)
{
xmlNodePtr children = self->xmlChildrenNode;
@ -14,10 +14,11 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
xmlNodePtr nodes = children->xmlChildrenNode;
while (nodes) {
if (!strcmp (nodes->name, "text")) {
gchar *name = g_strdup (xmlNodeGetContent (nodes));
g_print ("object %s loaded with comment '%s'\n",
gst_object_get_name (object), name);
if (!strcmp (nodes->name, "text")) {
gchar *name = g_strdup (xmlNodeGetContent (nodes));
g_print ("object %s loaded with comment '%s'\n",
gst_object_get_name (object), name);
}
nodes = nodes->next;
}
@ -26,13 +27,14 @@ xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
}
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstXML *xml;
GstElement *pipeline;
gboolean ret;
gst_init(&argc,&argv);
gst_init (&argc, &argv);
xml = gst_xml_new ();
@ -40,21 +42,20 @@ int main(int argc,char *argv[])
/* G_CALLBACK (xml_loaded), xml); */
if (argc == 2)
ret = gst_xml_parse_file(xml, argv[1], NULL);
ret = gst_xml_parse_file (xml, argv[1], NULL);
else
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
ret = gst_xml_parse_file (xml, "xmlTest.gst", NULL);
g_assert (ret == TRUE);
pipeline = gst_xml_get_element(xml, "pipeline");
pipeline = gst_xml_get_element (xml, "pipeline");
g_assert (pipeline != NULL);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (gst_bin_iterate(GST_BIN(pipeline)));
while (gst_bin_iterate (GST_BIN (pipeline)));
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_element_set_state (pipeline, GST_STATE_NULL);
exit(0);
exit (0);
}

View file

@ -35,17 +35,17 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_AUTOPLUG_ATTEMPT);
* though the GLib version should take a function as argument...
*/
static void
g_list_free_list_and_elements (GList *list)
g_list_free_list_and_elements (GList * list)
{
GList *walk = list;
while (walk)
{
while (walk) {
g_free (walk->data);
walk = g_list_next (walk);
}
g_list_free (list);
}
/**
* gst_autoplug_caps_intersect:
* @src: a source #GstCaps
@ -56,19 +56,19 @@ g_list_free_list_and_elements (GList *list)
* Returns: TRUE, if both caps intersect.
*/
gboolean
gst_autoplug_caps_intersect (const GstCaps *src, const GstCaps *sink)
gst_autoplug_caps_intersect (const GstCaps * src, const GstCaps * sink)
{
GstCaps *caps;
/* get an intersection */
caps = gst_caps_intersect (src, sink);
/* if the caps can't link, there is no intersection */
if (gst_caps_is_empty (caps)) {
gst_caps_free (caps);
return FALSE;
}
/* hurrah, we can link, now remove the intersection */
gst_caps_free (caps);
return TRUE;
@ -84,25 +84,24 @@ gst_autoplug_caps_intersect (const GstCaps *src, const GstCaps *sink)
* Returns: #GstPadTemplate that can connect to the given caps
*/
GstPadTemplate *
gst_autoplug_can_connect_src (GstElementFactory *fac, const GstCaps *src)
gst_autoplug_can_connect_src (GstElementFactory * fac, const GstCaps * src)
{
GList *templs;
templs = fac->padtemplates;
while (templs)
{
if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK) &&
gst_autoplug_caps_intersect (src,
GST_PAD_TEMPLATE_CAPS (templs->data)))
{
while (templs) {
if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK) &&
gst_autoplug_caps_intersect (src,
GST_PAD_TEMPLATE_CAPS (templs->data))) {
return GST_PAD_TEMPLATE (templs->data);
}
templs = g_list_next (templs);
}
return NULL;
return NULL;
}
/**
* gst_autoplug_can_connect_sink:
* @fac: factory to connect to
@ -113,74 +112,73 @@ gst_autoplug_can_connect_src (GstElementFactory *fac, const GstCaps *src)
* Returns: #GstPadTemplate that can connect to the given caps
*/
GstPadTemplate *
gst_autoplug_can_connect_sink (GstElementFactory *fac, const GstCaps *sink)
gst_autoplug_can_connect_sink (GstElementFactory * fac, const GstCaps * sink)
{
GList *templs;
templs = fac->padtemplates;
while (templs)
{
while (templs) {
GstCaps *caps = GST_PAD_TEMPLATE_CAPS (templs->data);
if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SRC) &&
gst_autoplug_caps_intersect (caps, sink))
{
gst_autoplug_caps_intersect (caps, sink)) {
return GST_PAD_TEMPLATE (templs->data);
}
templs = g_list_next (templs);
}
return NULL;
return NULL;
}
GstPadTemplate *
gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
gst_autoplug_can_match (GstElementFactory * src, GstElementFactory * dest)
{
GList *srctemps, *desttemps;
srctemps = src->padtemplates;
while (srctemps) {
GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data;
GstPadTemplate *srctemp = (GstPadTemplate *) srctemps->data;
desttemps = dest->padtemplates;
while (desttemps) {
GstPadTemplate *desttemp = (GstPadTemplate *)desttemps->data;
GstPadTemplate *desttemp = (GstPadTemplate *) desttemps->data;
if (srctemp->direction == GST_PAD_SRC &&
desttemp->direction == GST_PAD_SINK) {
if (gst_autoplug_caps_intersect (gst_pad_template_get_caps (srctemp),
gst_pad_template_get_caps (desttemp))) {
GST_DEBUG ("factory \"%s\" can connect with factory \"%s\"",
GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
return desttemp;
}
desttemp->direction == GST_PAD_SINK) {
if (gst_autoplug_caps_intersect (gst_pad_template_get_caps (srctemp),
gst_pad_template_get_caps (desttemp))) {
GST_DEBUG ("factory \"%s\" can connect with factory \"%s\"",
GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
return desttemp;
}
}
desttemps = g_list_next (desttemps);
}
srctemps = g_list_next (srctemps);
}
GST_DEBUG ("factory \"%s\" cannot connect with factory \"%s\"",
GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
GST_DEBUG ("factory \"%s\" cannot connect with factory \"%s\"",
GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest));
return NULL;
}
/* returns TRUE if the factory has padtemplates with the specified direction */
gboolean
gst_autoplug_factory_has_direction (GstElementFactory *fac, GstPadDirection dir)
gst_autoplug_factory_has_direction (GstElementFactory * fac,
GstPadDirection dir)
{
GList *templs = fac->padtemplates;
while (templs)
{
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir)
{
while (templs) {
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) {
return TRUE;
}
templs = g_list_next (templs);
}
return FALSE;
}
@ -188,52 +186,54 @@ gst_autoplug_factory_has_direction (GstElementFactory *fac, GstPadDirection dir)
* These functions return a new list so be sure to free it.
*/
GList *
gst_autoplug_factories_sinks (GList *factories)
gst_autoplug_factories_sinks (GList * factories)
{
GList *ret = NULL;
while (factories)
{
while (factories) {
if (gst_autoplug_factory_has_sink (factories->data))
ret = g_list_prepend (ret, factories->data);
factories = g_list_next (factories);
}
return ret;
return ret;
}
GList *
gst_autoplug_factories_srcs (GList *factories)
gst_autoplug_factories_srcs (GList * factories)
{
GList *ret = NULL;
while (factories)
{
while (factories) {
if (gst_autoplug_factory_has_src (factories->data))
ret = g_list_prepend (ret, factories->data);
factories = g_list_next (factories);
}
return ret;
return ret;
}
GList *
gst_autoplug_factories_filters (GList *factories)
GList *
gst_autoplug_factories_filters (GList * factories)
{
GList *ret = NULL;
while (factories)
{
while (factories) {
/* if you want it faster do src/sink check at once, don't call two functions */
if (gst_autoplug_factory_has_src (factories->data) && gst_autoplug_factory_has_sink (factories->data))
if (gst_autoplug_factory_has_src (factories->data)
&& gst_autoplug_factory_has_sink (factories->data))
ret = g_list_prepend (ret, factories->data);
factories = g_list_next (factories);
}
return ret;
return ret;
}
static gint
gst_autoplug_rank_compare (const GstElementFactory *a, const GstElementFactory *b)
static gint
gst_autoplug_rank_compare (const GstElementFactory * a,
const GstElementFactory * b)
{
if (GST_PLUGIN_FEATURE (a)->rank > GST_PLUGIN_FEATURE (b)->rank) return -1;
return (GST_PLUGIN_FEATURE (a)->rank < GST_PLUGIN_FEATURE (b)->rank) ? 1 : 0;
if (GST_PLUGIN_FEATURE (a)->rank > GST_PLUGIN_FEATURE (b)->rank)
return -1;
return (GST_PLUGIN_FEATURE (a)->rank < GST_PLUGIN_FEATURE (b)->rank) ? 1 : 0;
}
/* returns all factories which have sinks with non-NULL caps and srcs with
@ -241,42 +241,38 @@ gst_autoplug_rank_compare (const GstElementFactory *a, const GstElementFactory *
* rank descending.
*/
GList *
gst_autoplug_factories_filters_with_sink_caps (GList *factories)
gst_autoplug_factories_filters_with_sink_caps (GList * factories)
{
GList *ret = NULL;
GstElementFactory *factory;
GList *templs;
while (factories)
{
while (factories) {
factory = (GstElementFactory *) factories->data;
templs = factory->padtemplates;
if (GST_PLUGIN_FEATURE (factory)->rank > 0){
if (GST_PLUGIN_FEATURE (factory)->rank > 0) {
gboolean have_src = FALSE;
gboolean have_sink = FALSE;
while (templs)
{
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SRC)
{
have_src = TRUE;
}
if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK) && (GST_PAD_TEMPLATE_CAPS (templs->data) != NULL))
{
have_sink = TRUE;
}
if (have_src && have_sink)
{
ret = g_list_prepend (ret, factory);
break;
}
templs = g_list_next (templs);
while (templs) {
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SRC) {
have_src = TRUE;
}
if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK)
&& (GST_PAD_TEMPLATE_CAPS (templs->data) != NULL)) {
have_sink = TRUE;
}
if (have_src && have_sink) {
ret = g_list_prepend (ret, factory);
break;
}
templs = g_list_next (templs);
}
}
factories = g_list_next (factories);
}
return g_list_sort(ret, (GCompareFunc)gst_autoplug_rank_compare);
return g_list_sort (ret, (GCompareFunc) gst_autoplug_rank_compare);
}
@ -284,32 +280,31 @@ gst_autoplug_factories_filters_with_sink_caps (GList *factories)
/* returns all factories which have a maximum of maxtemplates GstPadTemplates in direction dir
*/
GList *
gst_autoplug_factories_at_most_templates(GList *factories, GstPadDirection dir, guint maxtemplates)
gst_autoplug_factories_at_most_templates (GList * factories,
GstPadDirection dir, guint maxtemplates)
{
GList *ret = NULL;
while (factories)
{
while (factories) {
guint count = 0;
GList *templs = ((GstElementFactory *) factories->data)->padtemplates;
while (templs)
{
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir)
{
count++;
while (templs) {
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) {
count++;
}
if (count > maxtemplates)
break;
break;
templs = g_list_next (templs);
}
if (count <= maxtemplates)
ret = g_list_prepend (ret, factories->data);
factories = g_list_next (factories);
}
return ret;
}
/*********************************************************************
*
* SHORTEST PATH ALGORITHM
@ -327,39 +322,38 @@ gst_autoplug_factories_at_most_templates(GList *factories, GstPadDirection dir,
* to get the shortest path.
*/
GList *
gst_autoplug_sp (const GstCaps *srccaps, const GstCaps *sinkcaps, GList *factories)
gst_autoplug_sp (const GstCaps * srccaps, const GstCaps * sinkcaps,
GList * factories)
{
GList *factory_nodes = NULL;
guint curcost = GST_AUTOPLUG_MAX_COST; /* below this cost, there is no path */
GstAutoplugNode *bestnode = NULL; /* best (unconnected) endpoint currently */
guint curcost = GST_AUTOPLUG_MAX_COST; /* below this cost, there is no path */
GstAutoplugNode *bestnode = NULL; /* best (unconnected) endpoint currently */
g_return_val_if_fail (srccaps != NULL, NULL);
g_return_val_if_fail (sinkcaps != NULL, NULL);
GST_INFO ("attempting to autoplug via shortest path from %"
GST_PTR_FORMAT " to %" GST_PTR_FORMAT, srccaps, sinkcaps);
/* wrap all factories as GstAutoplugNode
* initialize the cost */
while (factories)
{
while (factories) {
GstAutoplugNode *node = g_new0 (GstAutoplugNode, 1);
node->prev = NULL;
node->fac = (GstElementFactory *) factories->data;
GST_DEBUG ("trying with %s", node->fac->details.longname);
node->templ = gst_autoplug_can_connect_src (node->fac, srccaps);
node->cost = (node->templ ? gst_autoplug_get_cost (node->fac)
: GST_AUTOPLUG_MAX_COST);
node->cost = (node->templ ? gst_autoplug_get_cost (node->fac)
: GST_AUTOPLUG_MAX_COST);
node->endpoint = gst_autoplug_can_connect_sink (node->fac, sinkcaps);
if (node->templ && node->endpoint)
GST_DEBUG ("%s makes connection possible",
node->fac->details.longname);
GST_DEBUG ("%s makes connection possible", node->fac->details.longname);
else
GST_DEBUG ("direct connection with %s not possible",
node->fac->details.longname);
if ((node->endpoint != NULL) &&
((bestnode == NULL) || (node->cost < bestnode->cost)))
{
node->fac->details.longname);
if ((node->endpoint != NULL) &&
((bestnode == NULL) || (node->cost < bestnode->cost))) {
bestnode = node;
}
factory_nodes = g_list_prepend (factory_nodes, node);
@ -367,80 +361,81 @@ gst_autoplug_sp (const GstCaps *srccaps, const GstCaps *sinkcaps, GList *factori
curcost = node->cost < curcost ? node->cost : curcost;
factories = g_list_next (factories);
}
/* check if we even have possible endpoints */
if (bestnode == NULL)
{
if (bestnode == NULL) {
GST_DEBUG ("no factory found that could connect to sink caps");
g_list_free_list_and_elements (factory_nodes);
return NULL;
}
/* iterate until we found the best path */
while (curcost < GST_AUTOPLUG_MAX_COST)
{
while (curcost < GST_AUTOPLUG_MAX_COST) {
GList *nodes = factory_nodes;
guint nextcost = GST_AUTOPLUG_MAX_COST; /* next cost to check */
GST_DEBUG ("iterating at current cost %d, bestnode %s at %d", curcost, GST_OBJECT_NAME (bestnode->fac), bestnode->cost);
guint nextcost = GST_AUTOPLUG_MAX_COST; /* next cost to check */
GST_DEBUG ("iterating at current cost %d, bestnode %s at %d", curcost,
GST_OBJECT_NAME (bestnode->fac), bestnode->cost);
/* check if we already have a valid best connection to the sink */
if (bestnode->cost <= curcost)
{
if (bestnode->cost <= curcost) {
GList *ret;
GST_DEBUG ("found a way to connect via %s", GST_OBJECT_NAME ((GstObject *) bestnode->fac));
GST_DEBUG ("found a way to connect via %s",
GST_OBJECT_NAME ((GstObject *) bestnode->fac));
/* enter all factories into the return list */
ret = g_list_prepend (NULL, bestnode->fac);
bestnode = bestnode->prev;
while (bestnode != NULL)
{
ret = g_list_prepend (ret, bestnode->fac);
bestnode = bestnode->prev;
while (bestnode != NULL) {
ret = g_list_prepend (ret, bestnode->fac);
bestnode = bestnode->prev;
}
g_list_free_list_and_elements (factory_nodes);
return ret;
}
/* iterate over all factories we have
* if they have the current cost, calculate if this
* factory supplies shorter paths to other elements
*/
while (nodes)
{
if (((GstAutoplugNode *) nodes->data)->cost == curcost)
{
/* now check all elements if we got a shorter path */
GList *sinknodes = factory_nodes;
GstAutoplugNode *srcnode = (GstAutoplugNode *) nodes->data;
while (sinknodes)
{
GstAutoplugNode *sinknode = (GstAutoplugNode *) sinknodes->data;
GstPadTemplate *templ;
if ((sinknode->cost > srcnode->cost + gst_autoplug_get_cost (sinknode->fac)) && (templ = gst_autoplug_can_match(srcnode->fac, sinknode->fac)))
{
/* we got a shorter path
* now enter that path to that node */
sinknode->prev = srcnode;
sinknode->templ = templ;
sinknode->cost = srcnode->cost + gst_autoplug_get_cost (sinknode->fac);
/* make sure to set which cost to view next */
nextcost = (nextcost > sinknode->cost) ? sinknode->cost : nextcost;
/* did we get a new best node? */
if (sinknode->endpoint && (sinknode->cost < bestnode->cost))
{
bestnode = sinknode;
}
}
sinknodes = g_list_next (sinknodes);
}
/* FIXME: for speed remove the item we just iterated with from the factory_nodes
* but don't free it yet and don't forget to free it.
*/
while (nodes) {
if (((GstAutoplugNode *) nodes->data)->cost == curcost) {
/* now check all elements if we got a shorter path */
GList *sinknodes = factory_nodes;
GstAutoplugNode *srcnode = (GstAutoplugNode *) nodes->data;
while (sinknodes) {
GstAutoplugNode *sinknode = (GstAutoplugNode *) sinknodes->data;
GstPadTemplate *templ;
if ((sinknode->cost >
srcnode->cost + gst_autoplug_get_cost (sinknode->fac))
&& (templ =
gst_autoplug_can_match (srcnode->fac, sinknode->fac))) {
/* we got a shorter path
* now enter that path to that node */
sinknode->prev = srcnode;
sinknode->templ = templ;
sinknode->cost =
srcnode->cost + gst_autoplug_get_cost (sinknode->fac);
/* make sure to set which cost to view next */
nextcost = (nextcost > sinknode->cost) ? sinknode->cost : nextcost;
/* did we get a new best node? */
if (sinknode->endpoint && (sinknode->cost < bestnode->cost)) {
bestnode = sinknode;
}
}
sinknodes = g_list_next (sinknodes);
}
/* FIXME: for speed remove the item we just iterated with from the factory_nodes
* but don't free it yet and don't forget to free it.
*/
}
nodes = g_list_next (nodes);
}
curcost = nextcost;
}
GST_DEBUG ("found no path from source caps to sink caps");
GST_DEBUG ("found no path from source caps to sink caps");
g_list_free_list_and_elements (factory_nodes);
return NULL;
return NULL;
}

View file

@ -30,21 +30,27 @@
/* struct for a node, in the search tree */
typedef struct _GstAutoplugNode GstAutoplugNode;
struct _GstAutoplugNode {
GstAutoplugNode *prev; /* previous node */
GstElementFactory *fac; /* factory of element to connect to */
GstPadTemplate *templ; /* template which can connect */
guint cost; /* total cost to get here */
GstPadTemplate *endpoint; /* pad template that can connect to sink caps */
struct _GstAutoplugNode
{
GstAutoplugNode *prev; /* previous node */
GstElementFactory *fac; /* factory of element to connect to */
GstPadTemplate *templ; /* template which can connect */
guint cost; /* total cost to get here */
GstPadTemplate *endpoint; /* pad template that can connect to sink caps */
};
/* helper functions */
gboolean gst_autoplug_caps_intersect (const GstCaps *src, const GstCaps *sink);
GstPadTemplate * gst_autoplug_can_connect_src (GstElementFactory *fac, const GstCaps *src);
GstPadTemplate * gst_autoplug_can_connect_sink (GstElementFactory *fac, const GstCaps *sink);
GstPadTemplate * gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest);
gboolean gst_autoplug_factory_has_direction (GstElementFactory *fac, GstPadDirection dir);
gboolean gst_autoplug_caps_intersect (const GstCaps * src,
const GstCaps * sink);
GstPadTemplate *gst_autoplug_can_connect_src (GstElementFactory * fac,
const GstCaps * src);
GstPadTemplate *gst_autoplug_can_connect_sink (GstElementFactory * fac,
const GstCaps * sink);
GstPadTemplate *gst_autoplug_can_match (GstElementFactory * src,
GstElementFactory * dest);
gboolean gst_autoplug_factory_has_direction (GstElementFactory * fac,
GstPadDirection dir);
#define gst_autoplug_factory_has_sink(fac) gst_autoplug_factory_has_direction((fac), GST_PAD_SINK)
#define gst_autoplug_factory_has_src(fac) gst_autoplug_factory_has_direction((fac), GST_PAD_SRC)
@ -52,13 +58,15 @@ gboolean gst_autoplug_factory_has_direction (Gs
#define gst_autoplug_get_cost(fac) 1
/* factory selections */
GList * gst_autoplug_factories_sinks (GList *factories);
GList * gst_autoplug_factories_srcs (GList *factories);
GList * gst_autoplug_factories_filters (GList *factories);
GList * gst_autoplug_factories_filters_with_sink_caps(GList *factories);
GList * gst_autoplug_factories_at_most_templates(GList *factories, GstPadDirection dir, guint maxtemplates);
GList *gst_autoplug_factories_sinks (GList * factories);
GList *gst_autoplug_factories_srcs (GList * factories);
GList *gst_autoplug_factories_filters (GList * factories);
GList *gst_autoplug_factories_filters_with_sink_caps (GList * factories);
GList *gst_autoplug_factories_at_most_templates (GList * factories,
GstPadDirection dir, guint maxtemplates);
/* shortest path algorithm */
GList * gst_autoplug_sp (const GstCaps *src_caps, const GstCaps *sink_caps, GList *factories);
GList *gst_autoplug_sp (const GstCaps * src_caps, const GstCaps * sink_caps,
GList * factories);
#endif /* __GST_SEARCHFUNCS_H__ */

View file

@ -19,7 +19,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* TODO:
* - handle automatic removal of unneeded elements
@ -54,12 +54,14 @@ GST_DEBUG_CATEGORY (gst_spider_debug);
#define GST_CAT_DEFAULT gst_spider_debug
/* signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_FACTORIES,
/* FILL ME TOO */
@ -67,88 +69,96 @@ enum {
/* generic templates */
static GstStaticPadTemplate spider_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src_%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GST_STATIC_PAD_TEMPLATE ("src_%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
/* standard GObject stuff */
static void gst_spider_class_init (GstSpiderClass *klass);
static void gst_spider_init (GstSpider *spider);
static void gst_spider_dispose (GObject *object);
static void gst_spider_class_init (GstSpiderClass * klass);
static void gst_spider_init (GstSpider * spider);
static void gst_spider_dispose (GObject * object);
/* element class functions */
static GstPad* gst_spider_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name);
static void gst_spider_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_spider_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static GstPad *gst_spider_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name);
static void gst_spider_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_spider_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
/* link functions */
static GstSpiderConnection * gst_spider_link_new (GstSpiderIdentity *src);
static void gst_spider_link_destroy (GstSpiderConnection *conn);
static void gst_spider_link_reset (GstSpiderConnection *conn, GstElement *to);
static void gst_spider_link_add (GstSpiderConnection *conn, GstElement *element);
static GstSpiderConnection * gst_spider_link_find (GstSpiderIdentity *src);
static GstSpiderConnection * gst_spider_link_get (GstSpiderIdentity *src);
static GstSpiderConnection *gst_spider_link_new (GstSpiderIdentity * src);
static void gst_spider_link_destroy (GstSpiderConnection * conn);
static void gst_spider_link_reset (GstSpiderConnection * conn, GstElement * to);
static void gst_spider_link_add (GstSpiderConnection * conn,
GstElement * element);
static GstSpiderConnection *gst_spider_link_find (GstSpiderIdentity * src);
static GstSpiderConnection *gst_spider_link_get (GstSpiderIdentity * src);
/* autoplugging functions */
static GstElement * gst_spider_find_element_to_plug (GstElement *src, GstElementFactory *fac, GstPadDirection dir);
static GstPadLinkReturn gst_spider_plug (GstSpiderConnection *conn);
static GstPadLinkReturn gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad);
static GstElement *gst_spider_find_element_to_plug (GstElement * src,
GstElementFactory * fac, GstPadDirection dir);
static GstPadLinkReturn gst_spider_plug (GstSpiderConnection * conn);
static GstPadLinkReturn gst_spider_plug_from_srcpad (GstSpiderConnection * conn,
GstPad * srcpad);
/*static GstPadLinkReturn gst_spider_plug_peers (GstSpider *spider, GstPad *srcpad, GstPad *sinkpad); */
static GstPadLinkReturn gst_spider_create_and_plug (GstSpiderConnection *conn, GList *plugpath);
static GstPadLinkReturn gst_spider_create_and_plug (GstSpiderConnection * conn,
GList * plugpath);
/* random functions */
static gchar * gst_spider_unused_elementname (GstBin *bin, const gchar *startwith);
static gchar *gst_spider_unused_elementname (GstBin * bin,
const gchar * startwith);
/* debugging stuff
static void print_spider_contents (GstSpider *spider);
static void print_spider_link (GstSpiderConnection *conn); */
/* === variables === */
static GstElementClass * parent_class = NULL;
static GstElementClass *parent_class = NULL;
/* no signals yet
static guint gst_spider_signals[LAST_SIGNAL] = { 0 };*/
/* GObject and GStreamer init functions */
GType
gst_spider_get_type(void)
gst_spider_get_type (void)
{
static GType spider_type = 0;
if (!spider_type) {
static const GTypeInfo spider_info = {
sizeof(GstSpiderClass),
sizeof (GstSpiderClass),
NULL,
NULL,
(GClassInitFunc) gst_spider_class_init,
NULL,
NULL,
sizeof(GstSpider),
sizeof (GstSpider),
0,
(GInstanceInitFunc)gst_spider_init,
(GInstanceInitFunc) gst_spider_init,
};
spider_type = g_type_register_static (GST_TYPE_BIN, "GstSpider", &spider_info, 0);
spider_type =
g_type_register_static (GST_TYPE_BIN, "GstSpider", &spider_info, 0);
}
return spider_type;
}
static void
gst_spider_class_init (GstSpiderClass *klass)
gst_spider_class_init (GstSpiderClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*) klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref(GST_TYPE_BIN);
parent_class = g_type_class_ref (GST_TYPE_BIN);
/* properties */
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FACTORIES,
g_param_spec_pointer ("factories", "allowed factories", "allowed factories for autoplugging", G_PARAM_READWRITE));
g_param_spec_pointer ("factories", "allowed factories",
"allowed factories for autoplugging", G_PARAM_READWRITE));
gobject_class->set_property = gst_spider_set_property;
gobject_class->get_property = gst_spider_get_property;
@ -157,74 +167,81 @@ gst_spider_class_init (GstSpiderClass *klass)
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&spider_src_factory));
gst_element_class_set_details (gstelement_class, &gst_spider_details);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_spider_request_new_pad);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_spider_request_new_pad);
}
static void
gst_spider_init (GstSpider *spider)
static void
gst_spider_init (GstSpider * spider)
{
/* use only elements which have sources and sinks and where the sinks have caps */
/* FIXME: How do we handle factories that are added after the spider was constructed? */
spider->factories = gst_autoplug_factories_filters_with_sink_caps ((GList *)
gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY));
spider->factories = gst_autoplug_factories_filters_with_sink_caps ((GList *)
gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY));
spider->links = NULL;
spider->sink_ident = gst_spider_identity_new_sink ("sink_ident");
gst_bin_add (GST_BIN (spider), GST_ELEMENT (spider->sink_ident));
gst_element_add_ghost_pad (GST_ELEMENT(spider), spider->sink_ident->sink, "sink");
gst_element_add_ghost_pad (GST_ELEMENT (spider), spider->sink_ident->sink,
"sink");
}
static void
gst_spider_dispose (GObject *object)
gst_spider_dispose (GObject * object)
{
GstSpider *spider;
spider = GST_SPIDER (object);
g_list_free (spider->factories);
((GObjectClass *) parent_class)->dispose (object);
}
static GstPad *
gst_spider_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name)
gst_spider_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * name)
{
GstPad *returnpad;
gchar *padname;
GstSpiderIdentity *identity;
GstSpider *spider;
g_return_val_if_fail (templ != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC, NULL);
g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC,
NULL);
spider = GST_SPIDER (element);
/* create an identity object, so we have a pad */
padname = gst_spider_unused_elementname ((GstBin *)spider, "src_");
padname = gst_spider_unused_elementname ((GstBin *) spider, "src_");
identity = gst_spider_identity_new_src (padname);
returnpad = identity->src;
/* FIXME: use the requested name for the pad */
gst_object_replace ((GstObject **) &returnpad->padtemplate, (GstObject *) templ);
gst_object_replace ((GstObject **) & returnpad->padtemplate,
(GstObject *) templ);
gst_bin_add (GST_BIN (element), GST_ELEMENT (identity));
returnpad = gst_element_add_ghost_pad (element, returnpad, padname);
g_free (padname);
gst_spider_link_new (identity);
GST_DEBUG ("successuflly created requested pad %s:%s", GST_DEBUG_PAD_NAME (returnpad));
GST_DEBUG ("successuflly created requested pad %s:%s",
GST_DEBUG_PAD_NAME (returnpad));
return returnpad;
}
static void
gst_spider_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_spider_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstSpider *spider;
GList *list;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_SPIDER (object));
@ -233,8 +250,7 @@ gst_spider_set_property (GObject *object, guint prop_id, const GValue *value, GP
switch (prop_id) {
case ARG_FACTORIES:
list = (GList *) g_value_get_pointer (value);
while (list)
{
while (list) {
g_return_if_fail (list->data != NULL);
g_return_if_fail (GST_IS_ELEMENT_FACTORY (list->data));
list = g_list_next (list);
@ -247,12 +263,13 @@ gst_spider_set_property (GObject *object, guint prop_id, const GValue *value, GP
}
}
static void
gst_spider_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_spider_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstSpider *spider;
/* it's not null if we got it, but it might not be ours */
spider = GST_SPIDER(object);
spider = GST_SPIDER (object);
switch (prop_id) {
case ARG_FACTORIES:
@ -263,161 +280,167 @@ gst_spider_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
break;
}
}
/* get a name for an element that isn't used yet */
static gchar *
gst_spider_unused_elementname (GstBin *bin, const gchar *startwith)
gst_spider_unused_elementname (GstBin * bin, const gchar * startwith)
{
gchar * name = g_strdup_printf ("%s%d", startwith, 0);
gchar *name = g_strdup_printf ("%s%d", startwith, 0);
guint i;
for (i = 0; gst_bin_get_by_name (bin, name) != NULL; )
{
for (i = 0; gst_bin_get_by_name (bin, name) != NULL;) {
g_free (name);
name = g_strdup_printf ("%s%d", startwith, ++i);
}
return name;
}
static void
gst_spider_link_sometimes (GstElement *src, GstPad *pad, GstSpiderConnection *conn)
gst_spider_link_sometimes (GstElement * src, GstPad * pad,
GstSpiderConnection * conn)
{
gulong signal_id = conn->signal_id;
/* try to autoplug the elements */
if (gst_spider_plug_from_srcpad (conn, pad) != GST_PAD_LINK_REFUSED) {
GST_DEBUG ("%s:%s was autoplugged to %s:%s, removing callback",
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (conn->src->sink));
GST_DEBUG ("%s:%s was autoplugged to %s:%s, removing callback",
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (conn->src->sink));
g_signal_handler_disconnect (src, signal_id);
signal_id = 0;
}
}
/* create a new link from those two elements */
static GstSpiderConnection *
gst_spider_link_new (GstSpiderIdentity *src)
gst_spider_link_new (GstSpiderIdentity * src)
{
GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (src));
GstSpiderConnection *conn = g_new0 (GstSpiderConnection, 1);
conn->src = src;
conn->path = NULL;
conn->current = (GstElement *) spider->sink_ident;
spider->links = g_list_prepend (spider->links, conn);
return conn;
}
static void
gst_spider_link_destroy (GstSpiderConnection *conn)
gst_spider_link_destroy (GstSpiderConnection * conn)
{
GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (conn->src));
/* reset link to unplugged */
gst_spider_link_reset (conn, (GstElement *) spider->sink_ident);
g_free (conn);
}
static void
gst_spider_link_reset (GstSpiderConnection *conn, GstElement *to)
gst_spider_link_reset (GstSpiderConnection * conn, GstElement * to)
{
GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (conn->src));
GST_DEBUG ("resetting link from %s to %s, currently at %s to %s", GST_ELEMENT_NAME (spider->sink_ident),
GST_ELEMENT_NAME (conn->src), GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (to));
while ((conn->path != NULL) && ((GstElement *) conn->path->data != to))
{
GST_DEBUG ("resetting link from %s to %s, currently at %s to %s",
GST_ELEMENT_NAME (spider->sink_ident), GST_ELEMENT_NAME (conn->src),
GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (to));
while ((conn->path != NULL) && ((GstElement *) conn->path->data != to)) {
gst_object_unref ((GstObject *) conn->path->data);
conn->path = g_list_delete_link (conn->path, conn->path);
}
if (conn->path == NULL)
{
if (conn->path == NULL) {
conn->current = (GstElement *) spider->sink_ident;
} else {
conn->current = to;
}
}
/* add an element to the link */
static void
gst_spider_link_add (GstSpiderConnection *conn, GstElement *element)
gst_spider_link_add (GstSpiderConnection * conn, GstElement * element)
{
gst_object_ref ((GstObject *) element);
gst_object_sink ((GstObject *) element);
conn->path = g_list_prepend (conn->path, element);
conn->current = element;
}
/* find the link from those two elements */
static GstSpiderConnection *
gst_spider_link_find (GstSpiderIdentity *src)
gst_spider_link_find (GstSpiderIdentity * src)
{
GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (src);
GList *list = spider->links;
while (list)
{
while (list) {
GstSpiderConnection *conn = (GstSpiderConnection *) list->data;
if (conn->src == src){
if (conn->src == src) {
return conn;
}
list = g_list_next(list);
list = g_list_next (list);
}
return NULL;
}
/* get a new link from those two elements
* search first; if none is found, create a new one */
static GstSpiderConnection *
gst_spider_link_get (GstSpiderIdentity *src)
gst_spider_link_get (GstSpiderIdentity * src)
{
GstSpiderConnection *ret;
if ((ret = gst_spider_link_find (src)) != NULL)
{
if ((ret = gst_spider_link_find (src)) != NULL) {
return ret;
}
return gst_spider_link_new (src);
}
void
gst_spider_identity_plug (GstSpiderIdentity *ident)
}
void
gst_spider_identity_plug (GstSpiderIdentity * ident)
{
GstSpider *spider;
const GList *padlist;
GstPadDirection dir;
GstSpiderConnection *conn;
/* checks */
g_return_if_fail (ident != NULL);
g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident));
spider = GST_SPIDER (GST_ELEMENT_PARENT (ident));
g_assert (spider != NULL);
g_assert (GST_IS_SPIDER (spider));
/* return if we're already plugged */
if (ident->plugged) return;
if (ident->plugged)
return;
/* check if there is at least one element factory that can handle the
identity's src caps */
{
GstCaps *src_caps = gst_pad_get_caps (ident->src);
if (! gst_caps_is_empty (src_caps) && ! gst_caps_is_any (src_caps))
{
if (!gst_caps_is_empty (src_caps) && !gst_caps_is_any (src_caps)) {
GList *factories;
GstPadTemplate *padtemp;
gboolean found = FALSE;
factories = spider->factories;
while (factories)
{
if ((padtemp = gst_autoplug_can_connect_src (factories->data, src_caps)))
{
const GstCaps *caps = gst_pad_template_get_caps (padtemp);
GST_DEBUG ("can connect src to pad template: %" GST_PTR_FORMAT, caps);
found = TRUE;
}
factories = factories->next;
while (factories) {
if ((padtemp =
gst_autoplug_can_connect_src (factories->data, src_caps))) {
const GstCaps *caps = gst_pad_template_get_caps (padtemp);
GST_DEBUG ("can connect src to pad template: %" GST_PTR_FORMAT, caps);
found = TRUE;
}
factories = factories->next;
}
if (!found)
{
if (!found) {
const char *mime;
mime = gst_structure_get_name (gst_caps_get_structure (src_caps, 0));
GST_ELEMENT_ERROR (spider, STREAM, CODEC_NOT_FOUND,
(_("There is no element present to handle the stream's mime type %s."), mime),
(NULL));
GST_ELEMENT_ERROR (spider, STREAM, CODEC_NOT_FOUND,
(_("There is no element present to handle the stream's mime type %s."), mime), (NULL));
gst_caps_free (src_caps);
return;
}
@ -428,10 +451,8 @@ gst_spider_identity_plug (GstSpiderIdentity *ident)
/* get the direction of our ident */
if (GST_PAD_PEER (ident->sink))
{
if (GST_PAD_PEER (ident->src))
{
if (GST_PAD_PEER (ident->sink)) {
if (GST_PAD_PEER (ident->src)) {
/* Hey, the ident is linked on both sides */
g_warning ("Trying to autoplug a linked element. Aborting...");
return;
@ -439,8 +460,7 @@ gst_spider_identity_plug (GstSpiderIdentity *ident)
dir = GST_PAD_SINK;
}
} else {
if (GST_PAD_PEER (ident->src))
{
if (GST_PAD_PEER (ident->src)) {
dir = GST_PAD_SRC;
} else {
/* the ident isn't linked on either side */
@ -451,8 +471,7 @@ gst_spider_identity_plug (GstSpiderIdentity *ident)
/* now iterate all possible pads and link when needed */
padlist = gst_element_get_pad_list (GST_ELEMENT (spider));
while (padlist)
{
while (padlist) {
GstPad *otherpad;
GstSpiderIdentity *peer;
@ -460,169 +479,182 @@ gst_spider_identity_plug (GstSpiderIdentity *ident)
otherpad = (GstPad *) GST_GPAD_REALPAD (padlist->data);
peer = (GstSpiderIdentity *) GST_PAD_PARENT (otherpad);
/* we only want to link to the other side */
if (dir != GST_PAD_DIRECTION (otherpad))
{
if (dir != GST_PAD_DIRECTION (otherpad)) {
/* we only link to plugged in elements */
if (peer->plugged == TRUE)
{
/* plug in the right direction */
if (dir == GST_PAD_SINK)
{
if (peer->plugged == TRUE) {
/* plug in the right direction */
if (dir == GST_PAD_SINK) {
conn = gst_spider_link_get (peer);
} else {
} else {
conn = gst_spider_link_get (ident);
}
if ((GstElement *) spider->sink_ident == conn->current)
{
}
if ((GstElement *) spider->sink_ident == conn->current) {
gst_spider_plug (conn);
}
}
}
padlist = g_list_next (padlist);
}
ident->plugged = TRUE;
ident->plugged = TRUE;
}
void
gst_spider_identity_unplug (GstSpiderIdentity *ident)
gst_spider_identity_unplug (GstSpiderIdentity * ident)
{
GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (ident);
GList *list = spider->links;
while (list)
{
while (list) {
GstSpiderConnection *conn = list->data;
GList *cur = list;
list = g_list_next (list);
if (conn->src == ident)
{
if (conn->src == ident) {
g_list_delete_link (spider->links, cur);
gst_spider_link_destroy (conn);
}
}
ident->plugged = FALSE;
}
/* links src to sink using the elementfactories in plugpath
* plugpath will be removed afterwards */
static GstPadLinkReturn
gst_spider_create_and_plug (GstSpiderConnection *conn, GList *plugpath)
gst_spider_create_and_plug (GstSpiderConnection * conn, GList * plugpath)
{
GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->src);
GList *endelements = NULL, *templist = NULL;
GstElement *element;
/* exit if plugging is already done */
if ((GstElement *) conn->src == conn->current)
return GST_PAD_LINK_DONE;
/* try to shorten the list at the end and not duplicate link code */
if (plugpath != NULL)
{
if (plugpath != NULL) {
templist = g_list_last (plugpath);
element = (GstElement *) conn->src;
while ((plugpath != NULL) && (element = gst_spider_find_element_to_plug (element, (GstElementFactory *) plugpath->data, GST_PAD_SINK)))
{
while ((plugpath != NULL)
&& (element =
gst_spider_find_element_to_plug (element,
(GstElementFactory *) plugpath->data, GST_PAD_SINK))) {
GList *cur = templist;
endelements = g_list_prepend (endelements, element);
templist = g_list_previous (templist);
g_list_delete_link (cur, cur);
g_list_delete_link (cur, cur);
}
}
/* do the linking */
while (conn->current != (GstElement *) (endelements == NULL ? conn->src : endelements->data))
{
while (conn->current != (GstElement *) (endelements ==
NULL ? conn->src : endelements->data)) {
/* get sink element to plug, src is conn->current */
if (plugpath == NULL)
{
element = (GstElement *) (endelements == NULL ? conn->src : endelements->data);
if (plugpath == NULL) {
element =
(GstElement *) (endelements == NULL ? conn->src : endelements->data);
} else {
element = gst_element_factory_create ((GstElementFactory *) plugpath->data, NULL);
GST_DEBUG ("Adding element %s of type %s and syncing state with autoplugger",
GST_ELEMENT_NAME (element), GST_PLUGIN_FEATURE_NAME (plugpath->data));
element =
gst_element_factory_create ((GstElementFactory *) plugpath->data,
NULL);
GST_DEBUG
("Adding element %s of type %s and syncing state with autoplugger",
GST_ELEMENT_NAME (element), GST_PLUGIN_FEATURE_NAME (plugpath->data));
gst_bin_add (GST_BIN (spider), element);
}
/* insert and link new element */
if (gst_element_link (conn->current, element)) {
gst_element_sync_state_with_parent (element);
gst_element_sync_state_with_parent (element);
} else {
/* check if the src has SOMETIMES templates. If so, link a callback */
GList *templs = gst_element_get_pad_template_list (conn->current);
/* remove element that couldn't be linked, if it wasn't the endpoint */
if (element != (GstElement *) conn->src)
gst_bin_remove (GST_BIN (spider), element);
gst_bin_remove (GST_BIN (spider), element);
while (templs) {
GstPadTemplate *templ = (GstPadTemplate *) templs->data;
if ((GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) && (GST_PAD_TEMPLATE_PRESENCE(templ) == GST_PAD_SOMETIMES))
{
GST_DEBUG ("adding callback to link element %s to %s", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
conn->signal_id = g_signal_connect (G_OBJECT (conn->current), "new_pad",
G_CALLBACK (gst_spider_link_sometimes), conn);
GstPadTemplate *templ = (GstPadTemplate *) templs->data;
if ((GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC)
&& (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)) {
GST_DEBUG ("adding callback to link element %s to %s",
GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
conn->signal_id =
g_signal_connect (G_OBJECT (conn->current), "new_pad",
G_CALLBACK (gst_spider_link_sometimes), conn);
g_list_free (plugpath);
return GST_PAD_LINK_DELAYED;
}
templs = g_list_next (templs);
}
templs = g_list_next (templs);
}
GST_DEBUG ("no chance to link element %s to %s", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
GST_DEBUG ("no chance to link element %s to %s",
GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
g_list_free (plugpath);
return GST_PAD_LINK_REFUSED;
}
GST_DEBUG ("added element %s and attached it to element %s", GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (conn->current));
GST_DEBUG ("added element %s and attached it to element %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (conn->current));
gst_spider_link_add (conn, element);
if (plugpath != NULL)
plugpath = g_list_delete_link (plugpath, plugpath);
}
/* ref all elements at the end */
while (endelements)
{
while (endelements) {
gst_spider_link_add (conn, endelements->data);
endelements = g_list_delete_link (endelements, endelements);
}
return GST_PAD_LINK_DONE;
}
/* checks, if src is already linked to an element from factory fac on direction dir */
static GstElement *
gst_spider_find_element_to_plug (GstElement *src, GstElementFactory *fac, GstPadDirection dir)
gst_spider_find_element_to_plug (GstElement * src, GstElementFactory * fac,
GstPadDirection dir)
{
GList *padlist = GST_ELEMENT_PADS (src);
while (padlist)
{
while (padlist) {
GstPad *pad = (GstPad *) GST_PAD_REALIZE (padlist->data);
/* is the pad on the right side and is it linked? */
if ((GST_PAD_DIRECTION (pad) == dir) && (pad = (GstPad *) (GST_RPAD_PEER (pad))))
{
if ((GST_PAD_DIRECTION (pad) == dir)
&& (pad = (GstPad *) (GST_RPAD_PEER (pad)))) {
/* is the element the pad is linked to of the right type? */
GstElement *element = GST_PAD_PARENT (pad);
if (G_TYPE_FROM_INSTANCE (element) == gst_element_factory_get_element_type (fac)) {
return element;
if (G_TYPE_FROM_INSTANCE (element) ==
gst_element_factory_get_element_type (fac)) {
return element;
}
}
padlist = g_list_next (padlist);
}
return NULL;
}
/* try to establish the link */
static GstPadLinkReturn
gst_spider_plug (GstSpiderConnection *conn)
gst_spider_plug (GstSpiderConnection * conn)
{
GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->src);
if ((GstElement *) conn->src == conn->current)
return GST_PAD_LINK_DONE;
if ((GstElement *) spider->sink_ident == conn->current)
return gst_spider_plug_from_srcpad (conn, spider->sink_ident->src);
g_warning ("FIXME: autoplugging only possible from GstSpiderIdentity conn->sink yet (yep, that's technical)\n");
g_warning
("FIXME: autoplugging only possible from GstSpiderIdentity conn->sink yet (yep, that's technical)\n");
return GST_PAD_LINK_REFUSED;
}
/* try to establish the link using this pad */
static GstPadLinkReturn
gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad)
gst_spider_plug_from_srcpad (GstSpiderConnection * conn, GstPad * srcpad)
{
GstElement *element;
GList *plugpath;
@ -633,37 +665,38 @@ gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad)
GstCaps *caps2;
g_assert ((GstElement *) GST_OBJECT_PARENT (srcpad) == conn->current);
GST_DEBUG ("trying to plug from %s:%s to %s",
GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (conn->src));
GST_DEBUG ("trying to plug from %s:%s to %s",
GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (conn->src));
/* see if they match already */
if (gst_pad_link (srcpad, conn->src->sink)) {
GST_DEBUG ("%s:%s and %s:%s can link directly",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (conn->src->sink));
GST_DEBUG ("%s:%s and %s:%s can link directly",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (conn->src->sink));
gst_pad_unlink (srcpad, conn->src->sink);
gst_spider_create_and_plug (conn, NULL);
return GST_PAD_LINK_OK;
}
/* find a path from src to sink */
caps1 = gst_pad_get_caps (srcpad);
caps2 = gst_pad_get_caps (conn->src->sink);
plugpath = gst_autoplug_sp (caps1, caps2, spider->factories);
gst_caps_free (caps1);
gst_caps_free (caps2);
/* prints out the path that was found for plugging */
/* g_print ("found path from %s to %s:\n", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
templist = plugpath;
while (templist)
{
g_print("%s\n", GST_OBJECT_NAME (templist->data));
templist = g_list_next (templist);
}*/
templist = plugpath;
while (templist)
{
g_print("%s\n", GST_OBJECT_NAME (templist->data));
templist = g_list_next (templist);
} */
/* if there is no way to plug: return */
if (plugpath == NULL) {
GST_DEBUG ("no chance to plug from %s to %s", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
GST_DEBUG ("no chance to plug from %s to %s",
GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
return GST_PAD_LINK_REFUSED;
}
GST_DEBUG ("found a link that needs %d elements", g_list_length (plugpath));
@ -673,53 +706,50 @@ gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad)
* plugging and alter the plugpath to represent the elements, that must be plugged
*/
element = conn->current;
while ((plugpath != NULL) && (element = gst_spider_find_element_to_plug (element, (GstElementFactory *) plugpath->data, GST_PAD_SRC)))
{
while ((plugpath != NULL)
&& (element =
gst_spider_find_element_to_plug (element,
(GstElementFactory *) plugpath->data, GST_PAD_SRC))) {
gst_spider_link_add (conn, element);
plugpath = g_list_delete_link (plugpath, plugpath);
}
GST_DEBUG ("%d elements must be inserted to establish the link", g_list_length (plugpath));
GST_DEBUG ("%d elements must be inserted to establish the link",
g_list_length (plugpath));
/* create the elements and plug them */
result = gst_spider_create_and_plug (conn, plugpath);
/* reset the "current" element */
if (result == GST_PAD_LINK_REFUSED)
{
gst_spider_link_reset (conn, startelement);
if (result == GST_PAD_LINK_REFUSED) {
gst_spider_link_reset (conn, startelement);
}
return result;
return result;
}
GstElementDetails gst_spider_details = GST_ELEMENT_DETAILS (
"Spider",
"Generic",
"Automatically link sinks and sources",
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
GstElementDetails gst_spider_details = GST_ELEMENT_DETAILS ("Spider",
"Generic",
"Automatically link sinks and sources",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gst_spider_debug, "spider", 0, "spider autoplugging element");
GST_DEBUG_CATEGORY_INIT (gst_spider_debug, "spider", 0,
"spider autoplugging element");
if (!gst_element_register (plugin, "spider", GST_RANK_SECONDARY, GST_TYPE_SPIDER))
if (!gst_element_register (plugin, "spider", GST_RANK_SECONDARY,
GST_TYPE_SPIDER))
return FALSE;
if (!gst_element_register (plugin, "spideridentity", GST_RANK_NONE, GST_TYPE_SPIDER_IDENTITY))
if (!gst_element_register (plugin, "spideridentity", GST_RANK_NONE,
GST_TYPE_SPIDER_IDENTITY))
return FALSE;
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstspider",
"a 1:n autoplugger",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstspider",
"a 1:n autoplugger",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)

View file

@ -19,17 +19,16 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_SPIDER_H__
#define __GST_SPIDER_H__
#include <gst/gst.h>
#include "gstspideridentity.h"
G_BEGIN_DECLS
extern GstElementDetails gst_spider_details;
GST_DEBUG_CATEGORY_EXTERN(gst_spider_debug);
G_BEGIN_DECLS extern GstElementDetails gst_spider_details;
GST_DEBUG_CATEGORY_EXTERN (gst_spider_debug);
/*
* Theory of operation:
@ -46,7 +45,8 @@ GST_DEBUG_CATEGORY_EXTERN(gst_spider_debug);
* are refcounted once for every path.
* A GstSpider keeps a list of all GstSpiderConnections in it.
*/
typedef struct {
typedef struct
{
GstSpiderIdentity *src;
/* dunno if the path should stay here or if its too much load.
* it's at least easier then always searching it */
@ -60,35 +60,36 @@ typedef struct {
#define GST_SPIDER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPIDER,GstSpider))
#define GST_SPIDER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPIDER,GstSpiderClass))
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPIDER,GstSpiderClass))
#define GST_IS_SPIDER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPIDER))
#define GST_IS_SPIDER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPIDER))
typedef struct _GstSpider GstSpider;
typedef struct _GstSpiderClass GstSpiderClass;
struct _GstSpider {
GstBin parent;
GstSpiderIdentity *sink_ident;
GList * factories; /* factories to use for plugging */
struct _GstSpider
{
GstBin parent;
GList * links; /* GStSpiderConnection list of all links */
GstSpiderIdentity *sink_ident;
GList *factories; /* factories to use for plugging */
GList *links; /* GStSpiderConnection list of all links */
};
struct _GstSpiderClass {
struct _GstSpiderClass
{
GstBinClass parent_class;
};
/* default initialization stuff */
GType gst_spider_get_type (void);
GType gst_spider_get_type (void);
/* private link functions to be called by GstSpiderIdentity */
void gst_spider_identity_plug (GstSpiderIdentity *ident);
void gst_spider_identity_unplug (GstSpiderIdentity *ident);
void gst_spider_identity_plug (GstSpiderIdentity * ident);
void gst_spider_identity_unplug (GstSpiderIdentity * ident);
G_END_DECLS
#endif /* __GST_SPIDER_H__ */

View file

@ -30,159 +30,174 @@
GST_DEBUG_CATEGORY_STATIC (gst_spider_identity_debug);
#define GST_CAT_DEFAULT gst_spider_identity_debug
static GstElementDetails gst_spider_identity_details = GST_ELEMENT_DETAILS (
"SpiderIdentity",
"Generic",
"Link between spider and outside elements",
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
static GstElementDetails gst_spider_identity_details =
GST_ELEMENT_DETAILS ("SpiderIdentity",
"Generic",
"Link between spider and outside elements",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
/* generic templates
* delete me when meging with spider.c
*/
static GstStaticPadTemplate spider_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
static GstStaticPadTemplate spider_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate spider_sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
/* SpiderIdentity signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0
/* FILL ME */
/* FILL ME */
};
/* GObject stuff */
static void gst_spider_identity_class_init (GstSpiderIdentityClass *klass);
static void gst_spider_identity_init (GstSpiderIdentity *spider_identity);
static void gst_spider_identity_class_init (GstSpiderIdentityClass * klass);
static void gst_spider_identity_init (GstSpiderIdentity * spider_identity);
/* functions set in pads, elements and stuff */
static void gst_spider_identity_chain (GstPad *pad, GstBuffer *buf);
static GstElementStateReturn gst_spider_identity_change_state (GstElement *element);
static GstPadLinkReturn gst_spider_identity_link (GstPad *pad, const GstCaps *caps);
static GstCaps * gst_spider_identity_getcaps (GstPad *pad);
/* loop functions */
static void gst_spider_identity_dumb_loop (GstSpiderIdentity *ident);
static void gst_spider_identity_src_loop (GstSpiderIdentity *ident);
static void gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident);
static void gst_spider_identity_chain (GstPad * pad, GstBuffer * buf);
static GstElementStateReturn gst_spider_identity_change_state (GstElement *
element);
static GstPadLinkReturn gst_spider_identity_link (GstPad * pad,
const GstCaps * caps);
static GstCaps *gst_spider_identity_getcaps (GstPad * pad);
static gboolean gst_spider_identity_handle_src_event (GstPad *pad, GstEvent *event);
/* loop functions */
static void gst_spider_identity_dumb_loop (GstSpiderIdentity * ident);
static void gst_spider_identity_src_loop (GstSpiderIdentity * ident);
static void gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *
ident);
static gboolean gst_spider_identity_handle_src_event (GstPad * pad,
GstEvent * event);
/* other functions */
static void gst_spider_identity_start_type_finding (GstSpiderIdentity *ident);
static void gst_spider_identity_start_type_finding (GstSpiderIdentity * ident);
static GstElementClass *parent_class = NULL;
static GstElementClass * parent_class = NULL;
/* no signals
static guint gst_spider_identity_signals[LAST_SIGNAL] = { 0 }; */
GType
gst_spider_identity_get_type (void)
gst_spider_identity_get_type (void)
{
static GType spider_identity_type = 0;
if (!spider_identity_type) {
static const GTypeInfo spider_identity_info = {
sizeof(GstSpiderIdentityClass), NULL,
sizeof (GstSpiderIdentityClass), NULL,
NULL,
(GClassInitFunc)gst_spider_identity_class_init,
(GClassInitFunc) gst_spider_identity_class_init,
NULL,
NULL,
sizeof(GstSpiderIdentity),
sizeof (GstSpiderIdentity),
0,
(GInstanceInitFunc)gst_spider_identity_init,
(GInstanceInitFunc) gst_spider_identity_init,
};
spider_identity_type = g_type_register_static (GST_TYPE_ELEMENT, "GstSpiderIdentity",
&spider_identity_info, 0);
GST_DEBUG_CATEGORY_INIT (gst_spider_identity_debug, "spideridentity",
0, "spider autoplugging proxy element");
spider_identity_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstSpiderIdentity",
&spider_identity_info, 0);
GST_DEBUG_CATEGORY_INIT (gst_spider_identity_debug, "spideridentity", 0,
"spider autoplugging proxy element");
}
return spider_identity_type;
}
static void
gst_spider_identity_class_init (GstSpiderIdentityClass *klass)
static void
gst_spider_identity_class_init (GstSpiderIdentityClass * klass)
{
GstElementClass *gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
/* add our two pad templates */
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&spider_src_factory));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&spider_sink_factory));
gst_element_class_set_details (gstelement_class, &gst_spider_identity_details);
gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_spider_identity_change_state);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_spider_identity_request_new_pad);
gst_element_class_set_details (gstelement_class,
&gst_spider_identity_details);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_spider_identity_change_state);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_spider_identity_request_new_pad);
}
static void
gst_spider_identity_init (GstSpiderIdentity *ident)
static void
gst_spider_identity_init (GstSpiderIdentity * ident)
{
/* sink */
ident->sink = gst_pad_new_from_template (
gst_static_pad_template_get (&spider_sink_factory), "sink");
ident->sink =
gst_pad_new_from_template (gst_static_pad_template_get
(&spider_sink_factory), "sink");
gst_element_add_pad (GST_ELEMENT (ident), ident->sink);
gst_pad_set_link_function (ident->sink, GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->sink, GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_link_function (ident->sink,
GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->sink,
GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
/* src */
ident->src = gst_pad_new_from_template (
gst_static_pad_template_get (&spider_src_factory), "src");
ident->src =
gst_pad_new_from_template (gst_static_pad_template_get
(&spider_src_factory), "src");
gst_element_add_pad (GST_ELEMENT (ident), ident->src);
gst_pad_set_link_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_event_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event));
gst_pad_set_link_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_event_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event));
/* variables */
ident->plugged = FALSE;
}
static void
gst_spider_identity_chain (GstPad *pad, GstBuffer *buf)
static void
gst_spider_identity_chain (GstPad * pad, GstBuffer * buf)
{
GstSpiderIdentity *ident;
/*g_print ("chaining on pad %s:%s with buffer %p\n", GST_DEBUG_PAD_NAME (pad), buf);*/
/*g_print ("chaining on pad %s:%s with buffer %p\n", GST_DEBUG_PAD_NAME (pad), buf); */
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
if (buf == NULL) return;
if (buf == NULL)
return;
ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad));
if (GST_IS_EVENT (buf)) {
/* start hack for current event stuff here */
/* check for unlinked elements and send them the EOS event, too */
if (GST_EVENT_TYPE (GST_EVENT (buf)) == GST_EVENT_EOS)
{
if (GST_EVENT_TYPE (GST_EVENT (buf)) == GST_EVENT_EOS) {
GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (ident);
GList *list = spider->links;
while (list)
{
while (list) {
GstSpiderConnection *conn = (GstSpiderConnection *) list->data;
list = g_list_next (list);
if (conn->current != (GstElement *) conn->src) {
GST_DEBUG ("sending EOS to unconnected element %s from %s",
GST_ELEMENT_NAME (conn->src), GST_ELEMENT_NAME (ident));
gst_pad_push (conn->src->src, GST_DATA (GST_BUFFER (gst_event_new (GST_EVENT_EOS))));
gst_element_set_eos (GST_ELEMENT (conn->src));
if (conn->current != (GstElement *) conn->src) {
GST_DEBUG ("sending EOS to unconnected element %s from %s",
GST_ELEMENT_NAME (conn->src), GST_ELEMENT_NAME (ident));
gst_pad_push (conn->src->src,
GST_DATA (GST_BUFFER (gst_event_new (GST_EVENT_EOS))));
gst_element_set_eos (GST_ELEMENT (conn->src));
}
}
}
@ -194,40 +209,48 @@ gst_spider_identity_chain (GstPad *pad, GstBuffer *buf)
if ((ident->src != NULL) && (GST_PAD_PEER (ident->src) != NULL)) {
/* g_print("pushing buffer %p (refcount %d - buffersize %d) to pad %s:%s\n", buf, GST_BUFFER_REFCOUNT (buf), GST_BUFFER_SIZE (buf), GST_DEBUG_PAD_NAME (ident->src)); */
GST_LOG ( "push %p %" G_GINT64_FORMAT, buf, GST_BUFFER_OFFSET (buf));
GST_LOG ("push %p %" G_GINT64_FORMAT, buf, GST_BUFFER_OFFSET (buf));
gst_pad_push (ident->src, GST_DATA (buf));
} else if (GST_IS_BUFFER (buf)) {
gst_buffer_unref (buf);
}
}
GstSpiderIdentity*
gst_spider_identity_new_src (gchar *name)
GstSpiderIdentity *
gst_spider_identity_new_src (gchar * name)
{
GstSpiderIdentity *ret = (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
GstSpiderIdentity *ret =
(GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
/* set the right functions */
gst_element_set_loop_function (GST_ELEMENT (ret), (GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_src_loop));
gst_element_set_loop_function (GST_ELEMENT (ret),
(GstElementLoopFunction)
GST_DEBUG_FUNCPTR (gst_spider_identity_src_loop));
return ret;
}
GstSpiderIdentity*
gst_spider_identity_new_sink (gchar *name)
GstSpiderIdentity *
gst_spider_identity_new_sink (gchar * name)
{
GstSpiderIdentity *ret = (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
GstSpiderIdentity *ret =
(GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
/* set the right functions */
gst_element_set_loop_function (GST_ELEMENT (ret), (GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
gst_element_set_loop_function (GST_ELEMENT (ret),
(GstElementLoopFunction)
GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
return ret;
}
/* shamelessly stolen from gstqueue.c to get proxy links */
static GstPadLinkReturn
gst_spider_identity_link (GstPad *pad, const GstCaps *caps)
gst_spider_identity_link (GstPad * pad, const GstCaps * caps)
{
GstSpiderIdentity *spider_identity = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad));
GstSpiderIdentity *spider_identity =
GST_SPIDER_IDENTITY (gst_pad_get_parent (pad));
GstPad *otherpad;
if (pad == spider_identity->src)
if (pad == spider_identity->src)
otherpad = spider_identity->sink;
else
otherpad = spider_identity->src;
@ -239,13 +262,13 @@ gst_spider_identity_link (GstPad *pad, const GstCaps *caps)
return gst_pad_try_set_caps (otherpad, caps);
}
static GstCaps*
gst_spider_identity_getcaps (GstPad *pad)
static GstCaps *
gst_spider_identity_getcaps (GstPad * pad)
{
GstSpiderIdentity *ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad));
GstPad *otherpad;
if (pad == ident->src)
if (pad == ident->src)
otherpad = ident->sink;
else
otherpad = ident->src;
@ -253,8 +276,10 @@ gst_spider_identity_getcaps (GstPad *pad)
if (otherpad != NULL) {
if (GST_PAD_PEER (otherpad)) {
GstCaps *ret = gst_pad_get_allowed_caps (otherpad);
if (ident->caps) {
GstCaps *ret2 = gst_caps_intersect (ident->caps, ret);
gst_caps_free (ret);
ret = ret2;
}
@ -267,44 +292,52 @@ gst_spider_identity_getcaps (GstPad *pad)
return gst_caps_new_any ();
}
GstPad*
gst_spider_identity_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name)
GstPad *
gst_spider_identity_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name)
{
GstSpiderIdentity *ident;
/*checks */
g_return_val_if_fail (templ != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
ident = GST_SPIDER_IDENTITY (element);
g_return_val_if_fail (ident != NULL, NULL);
g_return_val_if_fail (GST_IS_SPIDER_IDENTITY (ident), NULL);
switch (GST_PAD_TEMPLATE_DIRECTION (templ))
{
switch (GST_PAD_TEMPLATE_DIRECTION (templ)) {
case GST_PAD_SINK:
if (ident->sink != NULL) break;
if (ident->sink != NULL)
break;
/* sink */
GST_DEBUG ( "element %s requests new sink pad", GST_ELEMENT_NAME(ident));
GST_DEBUG ("element %s requests new sink pad", GST_ELEMENT_NAME (ident));
ident->sink = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (ident), ident->sink);
gst_pad_set_link_function (ident->sink, GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->sink, GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_link_function (ident->sink,
GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->sink,
GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
return ident->sink;
case GST_PAD_SRC:
/* src */
if (ident->src != NULL) break;
GST_DEBUG ( "element %s requests new src pad", GST_ELEMENT_NAME(ident));
if (ident->src != NULL)
break;
GST_DEBUG ("element %s requests new src pad", GST_ELEMENT_NAME (ident));
ident->src = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (ident), ident->src);
gst_pad_set_link_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_event_function (ident->src, GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event));
gst_pad_set_link_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_link));
gst_pad_set_getcaps_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps));
gst_pad_set_event_function (ident->src,
GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event));
return ident->src;
default:
break;
}
GST_DEBUG ( "element %s requested a new pad but none could be created", GST_ELEMENT_NAME(ident));
GST_DEBUG ("element %s requested a new pad but none could be created",
GST_ELEMENT_NAME (ident));
return NULL;
}
@ -314,17 +347,17 @@ gst_spider_identity_request_new_pad (GstElement *element, GstPadTemplate *templ
* ...
*/
static GstElementStateReturn
gst_spider_identity_change_state (GstElement *element)
gst_spider_identity_change_state (GstElement * element)
{
GstSpiderIdentity *ident;
GstSpider *spider;
GstElementStateReturn ret = GST_STATE_SUCCESS;
/* element check */
ident = GST_SPIDER_IDENTITY (element);
g_return_val_if_fail (ident != NULL, GST_STATE_FAILURE);
g_return_val_if_fail (GST_IS_SPIDER_IDENTITY (ident), GST_STATE_FAILURE);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY:
gst_caps_replace (&ident->caps, NULL);
@ -334,55 +367,58 @@ gst_spider_identity_change_state (GstElement *element)
spider = GST_SPIDER (GST_ELEMENT_PARENT (ident));
g_return_val_if_fail (spider != NULL, GST_STATE_FAILURE);
g_return_val_if_fail (GST_IS_SPIDER (spider), GST_STATE_FAILURE);
/* start typefinding or plugging */
if ((GST_RPAD_PEER (ident->sink) != NULL) && (GST_RPAD_PEER (ident->src) == NULL))
{
GstCaps *caps = gst_pad_get_caps ((GstPad *) GST_PAD_PEER (ident->sink));
if (gst_caps_is_any (caps) || gst_caps_is_empty (caps))
{
gst_spider_identity_start_type_finding (ident);
if ((GST_RPAD_PEER (ident->sink) != NULL)
&& (GST_RPAD_PEER (ident->src) == NULL)) {
GstCaps *caps =
gst_pad_get_caps ((GstPad *) GST_PAD_PEER (ident->sink));
if (gst_caps_is_any (caps) || gst_caps_is_empty (caps)) {
gst_spider_identity_start_type_finding (ident);
gst_caps_free (caps);
break;
} else {
gst_spider_identity_plug (ident);
}
break;
} else {
gst_spider_identity_plug (ident);
}
gst_caps_free (caps);
}
/* autoplug on src */
if ((GST_RPAD_PEER (ident->src) != NULL) && (GST_RPAD_PEER (ident->sink) == NULL))
{
gst_spider_identity_plug (ident);
if ((GST_RPAD_PEER (ident->src) != NULL)
&& (GST_RPAD_PEER (ident->sink) == NULL)) {
gst_spider_identity_plug (ident);
}
default:
break;
}
if ((ret != GST_STATE_FAILURE) && (GST_ELEMENT_CLASS (parent_class)->change_state))
if ((ret != GST_STATE_FAILURE)
&& (GST_ELEMENT_CLASS (parent_class)->change_state))
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
return ret;
}
static void
gst_spider_identity_start_type_finding (GstSpiderIdentity *ident)
gst_spider_identity_start_type_finding (GstSpiderIdentity * ident)
{
/* GstElement* typefind;
gchar *name;*/
gboolean restart = FALSE;
GST_DEBUG ("element %s starts typefinding", GST_ELEMENT_NAME(ident));
if (GST_STATE (GST_ELEMENT_PARENT (ident)) == GST_STATE_PLAYING)
{
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)), GST_STATE_PAUSED);
GST_DEBUG ("element %s starts typefinding", GST_ELEMENT_NAME (ident));
if (GST_STATE (GST_ELEMENT_PARENT (ident)) == GST_STATE_PLAYING) {
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)),
GST_STATE_PAUSED);
restart = TRUE;
}
gst_element_set_loop_function (GST_ELEMENT (ident), (GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_sink_loop_type_finding));
gst_element_set_loop_function (GST_ELEMENT (ident),
(GstElementLoopFunction)
GST_DEBUG_FUNCPTR (gst_spider_identity_sink_loop_type_finding));
if (restart)
{
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)), GST_STATE_PLAYING);
if (restart) {
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)),
GST_STATE_PLAYING);
}
}
@ -390,7 +426,7 @@ gst_spider_identity_start_type_finding (GstSpiderIdentity *ident)
* we have to use a dumb one
*/
static void
gst_spider_identity_dumb_loop (GstSpiderIdentity *ident)
gst_spider_identity_dumb_loop (GstSpiderIdentity * ident)
{
GstBuffer *buf;
@ -402,27 +438,31 @@ gst_spider_identity_dumb_loop (GstSpiderIdentity *ident)
gst_spider_identity_chain (ident->sink, buf);
}
/* do nothing until we're linked - then disable yourself
*/
static void
gst_spider_identity_src_loop (GstSpiderIdentity *ident)
gst_spider_identity_src_loop (GstSpiderIdentity * ident)
{
/* checks - disable for speed */
g_return_if_fail (ident != NULL);
g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident));
/* we don't want a loop function if we're plugged */
if (ident->sink && GST_PAD_PEER (ident->sink))
{
gst_element_set_loop_function (GST_ELEMENT (ident), (GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
if (ident->sink && GST_PAD_PEER (ident->sink)) {
gst_element_set_loop_function (GST_ELEMENT (ident),
(GstElementLoopFunction)
GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
gst_spider_identity_dumb_loop (ident);
return;
}
gst_element_interrupt (GST_ELEMENT (ident));
}
/* This loop function is only needed when typefinding.
*/
typedef struct {
typedef struct
{
GstBuffer *buffer;
guint best_probability;
GstCaps *caps;
@ -431,19 +471,20 @@ guint8 *
spider_find_peek (gpointer data, gint64 offset, guint size)
{
SpiderTypeFind *find = (SpiderTypeFind *) data;
gint64 buffer_offset = GST_BUFFER_OFFSET_IS_VALID (find->buffer) ?
GST_BUFFER_OFFSET (find->buffer) : 0;
if (offset >= buffer_offset && offset + size <= buffer_offset + GST_BUFFER_SIZE (find->buffer)) {
GST_LOG ("peek %"G_GINT64_FORMAT", %u successful", offset, size);
gint64 buffer_offset = GST_BUFFER_OFFSET_IS_VALID (find->buffer) ?
GST_BUFFER_OFFSET (find->buffer) : 0;
if (offset >= buffer_offset
&& offset + size <= buffer_offset + GST_BUFFER_SIZE (find->buffer)) {
GST_LOG ("peek %" G_GINT64_FORMAT ", %u successful", offset, size);
return GST_BUFFER_DATA (find->buffer) + offset - buffer_offset;
} else {
GST_LOG ("peek %"G_GINT64_FORMAT", %u failed", offset, size);
GST_LOG ("peek %" G_GINT64_FORMAT ", %u failed", offset, size);
return NULL;
}
}
static void
spider_find_suggest (gpointer data, guint probability, const GstCaps *caps)
spider_find_suggest (gpointer data, guint probability, const GstCaps * caps)
{
SpiderTypeFind *find = (SpiderTypeFind *) data;
@ -454,7 +495,7 @@ spider_find_suggest (gpointer data, guint probability, const GstCaps *caps)
}
}
static void
gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity * ident)
{
GstData *data;
GstTypeFind gst_find;
@ -468,7 +509,7 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
gst_spider_identity_chain (ident->sink, GST_BUFFER (data));
return;
}
find.buffer = GST_BUFFER (data);
/* maybe there are already valid caps now? */
find.caps = gst_pad_get_allowed_caps (ident->sink);
@ -478,10 +519,10 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
gst_caps_free (find.caps);
find.caps = NULL;
}
/* now do the actual typefinding with the supplied buffer */
walk = type_list = gst_type_find_factory_get_list ();
find.best_probability = 0;
find.caps = NULL;
gst_find.data = &find;
@ -490,7 +531,8 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
while (walk) {
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
GST_DEBUG ("trying typefind function %s", GST_PLUGIN_FEATURE_NAME (factory));
GST_DEBUG ("trying typefind function %s",
GST_PLUGIN_FEATURE_NAME (factory));
gst_type_find_factory_call_function (factory, &gst_find);
if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
goto plug;
@ -503,23 +545,24 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
end:
/* remove loop function */
gst_element_set_loop_function (GST_ELEMENT (ident),
(GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
gst_element_set_loop_function (GST_ELEMENT (ident),
(GstElementLoopFunction)
GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop));
/* push the buffer */
gst_spider_identity_chain (ident->sink, find.buffer);
return;
plug:
GST_INFO ("typefind function found caps");
GST_INFO ("typefind function found caps");
ident->caps = find.caps;
if (GST_PAD_IS_LINKED (ident->src)) {
GstPadLinkReturn ret;
ret = gst_pad_try_set_caps (ident->src, find.caps);
if (GST_PAD_LINK_FAILED (ret)){
g_critical("could not set caps on spideridentity src pad\n");
if (GST_PAD_LINK_FAILED (ret)) {
g_critical ("could not set caps on spideridentity src pad\n");
}
}
GST_LOG_OBJECT (ident, "spider starting caps: %" GST_PTR_FORMAT, find.caps);
@ -532,12 +575,12 @@ plug:
}
static gboolean
gst_spider_identity_handle_src_event (GstPad *pad, GstEvent *event)
gst_spider_identity_handle_src_event (GstPad * pad, GstEvent * event)
{
gboolean res = TRUE;
GstSpiderIdentity *ident;
GST_DEBUG ( "spider_identity src_event");
GST_DEBUG ("spider_identity src_event");
ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad));

View file

@ -27,7 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_SPIDER_IDENTITY \
(gst_spider_identity_get_type())
#define GST_SPIDER_IDENTITY(obj) \
@ -38,35 +37,36 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPIDER_IDENTITY))
#define GST_IS_SPIDER_IDENTITY_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPIDER_IDENTITY))
typedef struct _GstSpiderIdentity GstSpiderIdentity;
typedef struct _GstSpiderIdentityClass GstSpiderIdentityClass;
struct _GstSpiderIdentity {
struct _GstSpiderIdentity
{
GstElement element;
/* sink and source */
GstPad *sink;
GstPad *src;
/* plugged into autoplugger yet? */
gboolean plugged;
/* Caps from typefinding */
GstCaps *caps;
};
struct _GstSpiderIdentityClass {
struct _GstSpiderIdentityClass
{
GstElementClass parent_class;
};
GType gst_spider_identity_get_type (void);
GType gst_spider_identity_get_type (void);
GstSpiderIdentity* gst_spider_identity_new_sink (gchar *name);
GstSpiderIdentity* gst_spider_identity_new_src (gchar *name);
GstPad* gst_spider_identity_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name);
GstSpiderIdentity *gst_spider_identity_new_sink (gchar * name);
GstSpiderIdentity *gst_spider_identity_new_src (gchar * name);
GstPad *gst_spider_identity_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name);
G_END_DECLS
#endif /* __GST_SPIDER_IDENTITY_H__ */

View file

@ -4,41 +4,40 @@
/* returns all factories which have a maximum of maxtemplates GstPadTemplates in direction dir
*/
GList *
gst_factories_at_most_templates(GList *factories, GstPadDirection dir, guint maxtemplates)
gst_factories_at_most_templates (GList * factories, GstPadDirection dir,
guint maxtemplates)
{
GList *ret = NULL;
while (factories)
{
while (factories) {
guint count = 0;
GList *templs = ((GstElementFactory *) factories->data)->padtemplates;
while (templs)
{
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir)
{
count++;
while (templs) {
if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) {
count++;
}
if (count > maxtemplates)
break;
break;
templs = g_list_next (templs);
}
if (count <= maxtemplates)
ret = g_list_prepend (ret, factories->data);
factories = g_list_next (factories);
}
return ret;
}
static void
property_change_callback (GObject *object, GstObject *orig, GParamSpec *pspec)
property_change_callback (GObject * object, GstObject * orig,
GParamSpec * pspec)
{
GValue value = { 0, }; /* the important thing is that value.type = 0 */
GValue value = { 0, }; /* the important thing is that value.type = 0 */
gchar *str = 0;
if (pspec->flags & G_PARAM_READABLE) {
g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property (G_OBJECT (orig), pspec->name, &value);
if (G_IS_PARAM_SPEC_STRING (pspec))
str = g_value_dup_string (&value);
@ -48,17 +47,17 @@ property_change_callback (GObject *object, GstObject *orig, GParamSpec *pspec)
str = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (&value));
else
str = g_strdup_value_contents (&value);
g_print ("%s: %s = %s\n", GST_OBJECT_NAME (orig), pspec->name, str);
g_free (str);
g_value_unset(&value);
g_value_unset (&value);
} else {
g_warning ("Parameter not readable. What's up with that?");
}
}
static void
error_callback (GObject *object, GstObject *orig, gchar *error)
error_callback (GObject * object, GstObject * orig, gchar * error)
{
g_print ("ERROR: %s: %s\n", GST_OBJECT_NAME (orig), error);
}
@ -70,42 +69,44 @@ error_callback (GObject *object, GstObject *orig, gchar *error)
* USAGE: spidertest <mediafile>
* If mediafile can be recognized, xvideo and oss audio output are tried.
*/
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
GstElement *bin, *filesrc, *decoder, *osssink, *videosink;
GList *facs;
if (argc < 2) {
g_print("usage: %s <file>\n", argv[0]);
exit(-1);
g_print ("usage: %s <file>\n", argv[0]);
exit (-1);
}
gst_init(&argc,&argv);
gst_init (&argc, &argv);
/* create a new bin to hold the elements */
bin = gst_pipeline_new("pipeline");
g_signal_connect (bin, "deep_notify", G_CALLBACK (property_change_callback), NULL);
bin = gst_pipeline_new ("pipeline");
g_signal_connect (bin, "deep_notify", G_CALLBACK (property_change_callback),
NULL);
g_signal_connect (bin, "error", G_CALLBACK (error_callback), NULL);
/* create a disk reader */
filesrc = gst_element_factory_make("filesrc", "disk_source");
g_object_set(G_OBJECT(filesrc),"location", argv[1], NULL);
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
/* now it's time to get the decoder */
decoder = gst_element_factory_make("spider", "spider");
decoder = gst_element_factory_make ("spider", "spider");
if (!decoder) {
g_print ("could not find plugin \"spider\"\n");
exit (-2);
}
/* only use decoding plugins */
g_object_get (decoder, "factories", &facs, NULL);
facs = gst_factories_at_most_templates(facs, GST_PAD_SINK, 1);
facs = gst_factories_at_most_templates (facs, GST_PAD_SINK, 1);
g_object_set (decoder, "factories", facs, NULL);
/* create video and audio sink */
osssink = gst_element_factory_make("osssink", "audio");
videosink = gst_element_factory_make("xvideosink", "video");
osssink = gst_element_factory_make ("osssink", "audio");
videosink = gst_element_factory_make ("xvideosink", "video");
if ((!osssink) || (!videosink)) {
g_print ("could not create output plugins\n");
@ -113,16 +114,15 @@ int main(int argc,char *argv[])
}
/* add objects to the main pipeline */
gst_bin_add(GST_BIN(bin), filesrc);
gst_bin_add(GST_BIN(bin), decoder);
gst_bin_add(GST_BIN(bin), osssink);
gst_bin_add(GST_BIN(bin), videosink);
gst_bin_add (GST_BIN (bin), filesrc);
gst_bin_add (GST_BIN (bin), decoder);
gst_bin_add (GST_BIN (bin), osssink);
gst_bin_add (GST_BIN (bin), videosink);
/* link objects */
if (!(gst_element_link(filesrc, decoder) &&
gst_element_link(decoder, osssink) &&
gst_element_link(decoder, videosink)))
{
if (!(gst_element_link (filesrc, decoder) &&
gst_element_link (decoder, osssink) &&
gst_element_link (decoder, videosink))) {
g_print ("the pipeline could not be linked\n");
exit (-4);
}
@ -130,10 +130,9 @@ int main(int argc,char *argv[])
/* gst_bin_use_clock (GST_BIN (bin), gst_system_clock_obtain ());*/
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);
gst_element_set_state (bin, GST_STATE_PLAYING);
while (gst_bin_iterate(GST_BIN(bin)));
while (gst_bin_iterate (GST_BIN (bin)));
exit(0);
exit (0);
}

View file

@ -59,11 +59,11 @@
#define COTHREAD_MAXTHREADS 16
#define COTHREAD_STACKSIZE (STACK_SIZE/COTHREAD_MAXTHREADS)
static void cothread_destroy (cothread_state *cothread);
static void cothread_destroy (cothread_state * cothread);
struct _cothread_context
{
cothread_state *cothreads[COTHREAD_MAXTHREADS]; /* array of cothread states */
cothread_state *cothreads[COTHREAD_MAXTHREADS]; /* array of cothread states */
int ncothreads;
int current;
unsigned long stack_top;
@ -92,10 +92,10 @@ cothread_get_current_context (void)
cothread_context *ctx;
ctx = g_static_private_get (&_cothread_ctx_key);
g_assert(ctx);
g_assert (ctx);
#ifdef COTHREAD_PARANOID
g_assert (ctx->thread == g_thread_self());
g_assert (ctx->thread == g_thread_self ());
#endif
return ctx;
@ -112,15 +112,15 @@ cothread_context *
cothread_context_init (void)
{
char __csf;
void *current_stack_frame = &__csf; /* Get pointer inside current stack frame */
void *current_stack_frame = &__csf; /* Get pointer inside current stack frame */
cothread_context *ctx;
/* if there already is a cotread context for this thread,
* just return it */
ctx = g_static_private_get (&_cothread_ctx_key);
if (ctx) {
GST_CAT_INFO (GST_CAT_COTHREADS,
"returning private _cothread_ctx_key %p", ctx);
GST_CAT_INFO (GST_CAT_COTHREADS,
"returning private _cothread_ctx_key %p", ctx);
return ctx;
}
@ -133,16 +133,17 @@ cothread_context_init (void)
ctx->ncothreads = 1;
ctx->current = 0;
ctx->data = g_hash_table_new (g_str_hash, g_str_equal);
ctx->thread = g_thread_self();
ctx->thread = g_thread_self ();
GST_CAT_INFO (GST_CAT_COTHREADS, "initializing cothreads");
/* set this thread's context pointer */
GST_CAT_INFO (GST_CAT_COTHREADS, "setting private _cothread_ctx_key to %p in thread %p",
ctx,g_thread_self());
GST_CAT_INFO (GST_CAT_COTHREADS,
"setting private _cothread_ctx_key to %p in thread %p", ctx,
g_thread_self ());
g_static_private_set (&_cothread_ctx_key, ctx, NULL);
g_assert(ctx == cothread_get_current_context());
g_assert (ctx == cothread_get_current_context ());
/* clear the cothread data */
memset (ctx->cothreads, 0, sizeof (ctx->cothreads));
@ -170,8 +171,8 @@ cothread_context_init (void)
ctx->cothreads[0]->flags = COTHREAD_STARTED;
ctx->cothreads[0]->sp = (void *) current_stack_frame;
GST_CAT_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p",
ctx->cothreads[0], ctx->cothreads[0]->sp);
GST_CAT_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p",
ctx->cothreads[0], ctx->cothreads[0]->sp);
return ctx;
}
@ -183,12 +184,12 @@ cothread_context_init (void)
* Free the cothread context.
*/
void
cothread_context_free (cothread_context *ctx)
cothread_context_free (cothread_context * ctx)
{
gint i;
g_return_if_fail (ctx != NULL);
g_assert (ctx->thread == g_thread_self());
g_assert (ctx->thread == g_thread_self ());
g_assert (ctx->current == 0);
GST_CAT_INFO (GST_CAT_COTHREADS, "free cothread context");
@ -199,13 +200,14 @@ cothread_context_free (cothread_context *ctx)
}
}
if (ctx->cothreads[0]) {
g_free(ctx->cothreads[0]);
g_free (ctx->cothreads[0]);
ctx->cothreads[0] = NULL;
}
g_hash_table_destroy (ctx->data);
/* make sure we free the private key for cothread context */
GST_CAT_INFO (GST_CAT_COTHREADS, "setting private _cothread_ctx_key to NULL in thread %p",
g_thread_self());
GST_CAT_INFO (GST_CAT_COTHREADS,
"setting private _cothread_ctx_key to NULL in thread %p",
g_thread_self ());
g_static_private_set (&_cothread_ctx_key, NULL, NULL);
g_free (ctx);
}
@ -218,8 +220,8 @@ cothread_context_free (cothread_context *ctx)
*
* Returns: the new cothread state or NULL on error
*/
cothread_state*
cothread_create (cothread_context *ctx)
cothread_state *
cothread_create (cothread_context * ctx)
{
cothread_state *cothread;
void *mmaped = 0;
@ -228,8 +230,8 @@ cothread_create (cothread_context *ctx)
g_return_val_if_fail (ctx != NULL, NULL);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "manager sef %p, cothread self %p",
ctx->thread, g_thread_self());
GST_CAT_DEBUG (GST_CAT_COTHREADS, "manager sef %p, cothread self %p",
ctx->thread, g_thread_self ());
if (ctx->ncothreads == COTHREAD_MAXTHREADS) {
/* this is pretty fatal */
@ -241,7 +243,7 @@ cothread_create (cothread_context *ctx)
if (ctx->cothreads[slot] == NULL)
break;
else if (ctx->cothreads[slot]->flags & COTHREAD_DESTROYED &&
slot != ctx->current) {
slot != ctx->current) {
cothread_destroy (ctx->cothreads[slot]);
break;
}
@ -251,66 +253,69 @@ cothread_create (cothread_context *ctx)
/* cothread stack space of the thread is mapped in reverse, with cothread 0
* stack space at the top */
cothread = (cothread_state *) (ctx->stack_top - (slot + 1) * COTHREAD_STACKSIZE);
cothread =
(cothread_state *) (ctx->stack_top - (slot + 1) * COTHREAD_STACKSIZE);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread pointer is %p", cothread);
#if 0
/* This tests to see whether or not we can grow down the stack */
{
unsigned long ptr;
for(ptr=ctx->stack_top - 4096; ptr > (unsigned long)cothread; ptr -= 4096){
for (ptr = ctx->stack_top - 4096; ptr > (unsigned long) cothread;
ptr -= 4096) {
GST_CAT_DEBUG (GST_CAT_COTHREADS, "touching location 0x%08lx", ptr);
*(volatile unsigned int *)ptr = *(volatile unsigned int *)ptr;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "ok (0x%08x)", *(unsigned int *)ptr);
*(volatile unsigned int *) ptr = *(volatile unsigned int *) ptr;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "ok (0x%08x)", *(unsigned int *) ptr);
}
}
#endif
#ifdef _SC_PAGESIZE
page_size = sysconf(_SC_PAGESIZE);
page_size = sysconf (_SC_PAGESIZE);
#else
page_size = getpagesize();
page_size = getpagesize ();
#endif
/* The mmap is necessary on Linux/i386, and possibly others, since the
* kernel is picky about when we can expand our stack. */
GST_CAT_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", cothread,
COTHREAD_STACKSIZE);
COTHREAD_STACKSIZE);
/* Remap with a guard page. This decreases our stack size by 8 kB (for
* 4 kB pages) and also wastes almost 4 kB for the cothreads
* structure */
munmap((void *)cothread, COTHREAD_STACKSIZE);
munmap ((void *) cothread, COTHREAD_STACKSIZE);
mmaped = mmap ((void *) cothread, page_size,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
mmaped = mmap (((void *) cothread) + page_size * 2,
COTHREAD_STACKSIZE - page_size * 2,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
COTHREAD_STACKSIZE - page_size * 2,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "coming out of mmap");
if (mmaped == MAP_FAILED) {
perror ("mmap'ing cothread stack space");
return NULL;
}
if (mmaped != (void *)cothread + page_size * 2) {
if (mmaped != (void *) cothread + page_size * 2) {
g_warning ("could not mmap requested memory for cothread");
return NULL;
}
cothread->magic_number = COTHREAD_MAGIC_NUMBER;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "create cothread %d with magic number 0x%x",
slot, cothread->magic_number);
GST_CAT_DEBUG (GST_CAT_COTHREADS,
"create cothread %d with magic number 0x%x", slot,
cothread->magic_number);
cothread->ctx = ctx;
cothread->cothreadnum = slot;
cothread->flags = 0;
cothread->priv = NULL;
cothread->sp = ((guchar *) cothread + COTHREAD_STACKSIZE);
cothread->stack_size = COTHREAD_STACKSIZE - page_size * 2;
cothread->stack_base = (void *)cothread + 2 * page_size;
cothread->stack_base = (void *) cothread + 2 * page_size;
GST_CAT_INFO (GST_CAT_COTHREADS,
"created cothread #%d in slot %d: %p at sp:%p",
ctx->ncothreads, slot, cothread, cothread->sp);
GST_CAT_INFO (GST_CAT_COTHREADS,
"created cothread #%d in slot %d: %p at sp:%p",
ctx->ncothreads, slot, cothread, cothread->sp);
ctx->cothreads[slot] = cothread;
ctx->ncothreads++;
@ -325,12 +330,12 @@ cothread_create (cothread_context *ctx)
* Free the given cothread state
*/
void
cothread_free (cothread_state *cothread)
cothread_free (cothread_state * cothread)
{
g_return_if_fail (cothread != NULL);
GST_CAT_INFO (GST_CAT_COTHREADS, "flag cothread %d for destruction",
cothread->cothreadnum);
GST_CAT_INFO (GST_CAT_COTHREADS, "flag cothread %d for destruction",
cothread->cothreadnum);
/* we simply flag the cothread for destruction here */
if (cothread)
@ -340,7 +345,7 @@ cothread_free (cothread_state *cothread)
}
static void
cothread_destroy (cothread_state *cothread)
cothread_destroy (cothread_state * cothread)
{
cothread_context *ctx;
gint cothreadnum;
@ -349,27 +354,28 @@ cothread_destroy (cothread_state *cothread)
cothreadnum = cothread->cothreadnum;
ctx = cothread->ctx;
g_assert (ctx->thread == g_thread_self());
g_assert (ctx == cothread_get_current_context());
g_assert (ctx->thread == g_thread_self ());
g_assert (ctx == cothread_get_current_context ());
GST_CAT_INFO (GST_CAT_COTHREADS, "destroy cothread %d %p %d",
cothreadnum, cothread, ctx->current);
GST_CAT_INFO (GST_CAT_COTHREADS, "destroy cothread %d %p %d",
cothreadnum, cothread, ctx->current);
/* cothread 0 needs to be destroyed specially */
g_assert(cothreadnum != 0);
g_assert (cothreadnum != 0);
/* we have to unlock here because we might be switched out
* with the lock held */
cothread_unlock (cothread);
/* doing cleanups of the cothread create */
GST_CAT_DEBUG (GST_CAT_COTHREADS, "destroy cothread %d with magic number 0x%x",
cothreadnum, cothread->magic_number);
GST_CAT_DEBUG (GST_CAT_COTHREADS,
"destroy cothread %d with magic number 0x%x", cothreadnum,
cothread->magic_number);
g_assert (cothread->magic_number == COTHREAD_MAGIC_NUMBER);
g_assert (cothread->priv == NULL);
memset(cothread,0,sizeof(*cothread));
memset (cothread, 0, sizeof (*cothread));
ctx->cothreads[cothreadnum] = NULL;
ctx->ncothreads--;
@ -385,7 +391,8 @@ cothread_destroy (cothread_state *cothread)
* Set the cothread function
*/
void
cothread_setfunc (cothread_state* cothread, cothread_func func, int argc, char **argv)
cothread_setfunc (cothread_state * cothread, cothread_func func, int argc,
char **argv)
{
cothread->func = func;
cothread->argc = argc;
@ -399,7 +406,7 @@ cothread_setfunc (cothread_state* cothread, cothread_func func, int argc, char *
* Stop the cothread and reset the stack and program counter.
*/
void
cothread_stop (cothread_state* cothread)
cothread_stop (cothread_state * cothread)
{
cothread->flags &= ~COTHREAD_STARTED;
}
@ -412,13 +419,13 @@ cothread_stop (cothread_state* cothread)
*
* Returns: the #cothread_state of the main (0th) cothread.
*/
cothread_state*
cothread_main (cothread_context* ctx)
cothread_state *
cothread_main (cothread_context * ctx)
{
g_assert (ctx->thread == g_thread_self());
g_assert (ctx->thread == g_thread_self ());
GST_CAT_DEBUG (GST_CAT_COTHREADS, "returning %p, the 0th cothread",
ctx->cothreads[0]);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "returning %p, the 0th cothread",
ctx->cothreads[0]);
return ctx->cothreads[0];
}
@ -429,10 +436,10 @@ cothread_main (cothread_context* ctx)
*
* Returns: the #cothread_state of the main (0th) thread in the current GThread
*/
cothread_state*
cothread_state *
cothread_current_main (void)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
return ctx->cothreads[0];
}
@ -444,10 +451,10 @@ cothread_current_main (void)
*
* Returns: the #cothread_state of the current cothread
*/
cothread_state*
cothread_state *
cothread_current (void)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
return ctx->cothreads[ctx->current];
}
@ -455,9 +462,10 @@ cothread_current (void)
static void
cothread_stub (void)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
cothread_state *cothread = ctx->cothreads[ctx->current];
#ifndef GST_DISABLE_GST_DEBUG
#ifndef GST_DISABLE_GST_DEBUG
char __csf;
void *current_stack_frame = &__csf;
#endif
@ -469,11 +477,13 @@ cothread_stub (void)
while (TRUE) {
cothread->func (cothread->argc, cothread->argv);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread[%d] thread->func exited", ctx->current);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread[%d] thread->func exited",
ctx->current);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "sp=%p", current_stack_frame);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "ctx=%p current=%p", ctx,cothread_get_current_context());
g_assert (ctx == cothread_get_current_context());
GST_CAT_DEBUG (GST_CAT_COTHREADS, "ctx=%p current=%p", ctx,
cothread_get_current_context ());
g_assert (ctx == cothread_get_current_context ());
g_assert (ctx->current != 0);
@ -489,12 +499,13 @@ cothread_stub (void)
*
* Returns: the current cothread id
*/
int cothread_getcurrent (void) G_GNUC_NO_INSTRUMENT;
int
cothread_getcurrent (void)
G_GNUC_NO_INSTRUMENT;
int cothread_getcurrent (void)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
if (!ctx)
return -1;
@ -510,7 +521,7 @@ cothread_getcurrent (void)
* set private data for the cothread.
*/
void
cothread_set_private (cothread_state *cothread, gpointer data)
cothread_set_private (cothread_state * cothread, gpointer data)
{
cothread->priv = data;
}
@ -524,9 +535,10 @@ cothread_set_private (cothread_state *cothread, gpointer data)
* adds data to a cothread
*/
void
cothread_context_set_data (cothread_state *cothread, gchar *key, gpointer data)
cothread_context_set_data (cothread_state * cothread, gchar * key,
gpointer data)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
g_hash_table_insert (ctx->data, key, data);
}
@ -540,7 +552,7 @@ cothread_context_set_data (cothread_state *cothread, gchar *key, gpointer data)
* Returns: the private data of the cothread
*/
gpointer
cothread_get_private (cothread_state *cothread)
cothread_get_private (cothread_state * cothread)
{
return cothread->priv;
}
@ -555,9 +567,9 @@ cothread_get_private (cothread_state *cothread)
* Returns: the data associated with the key
*/
gpointer
cothread_context_get_data (cothread_state *cothread, gchar *key)
cothread_context_get_data (cothread_state * cothread, gchar * key)
{
cothread_context *ctx = cothread_get_current_context();
cothread_context *ctx = cothread_get_current_context ();
return g_hash_table_lookup (ctx->data, key);
}
@ -569,7 +581,7 @@ cothread_context_get_data (cothread_state *cothread, gchar *key)
* Switches to the given cothread state
*/
void
cothread_switch (cothread_state *cothread)
cothread_switch (cothread_state * cothread)
{
cothread_context *ctx;
cothread_state *current;
@ -582,7 +594,7 @@ cothread_switch (cothread_state *cothread)
ctx = cothread->ctx;
/* paranoia check to make sure we're in the right thread */
g_assert (ctx->thread == g_thread_self());
g_assert (ctx->thread == g_thread_self ());
#ifdef COTHREAD_PARANOID
if (ctx == NULL)
@ -599,9 +611,9 @@ cothread_switch (cothread_state *cothread)
/* find the number of the thread to switch to */
GST_CAT_INFO (GST_CAT_COTHREAD_SWITCH,
"switching from cothread #%d to cothread #%d",
ctx->current, cothread->cothreadnum);
GST_CAT_INFO (GST_CAT_COTHREAD_SWITCH,
"switching from cothread #%d to cothread #%d",
ctx->current, cothread->cothreadnum);
ctx->current = cothread->cothreadnum;
/* save the current stack pointer, frame pointer, and pc */
@ -610,13 +622,13 @@ cothread_switch (cothread_state *cothread)
#endif
enter = setjmp (current->jmp);
if (enter != 0) {
GST_CAT_DEBUG (GST_CAT_COTHREADS,
"enter cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
GST_CAT_DEBUG (GST_CAT_COTHREADS,
"enter cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
return;
}
GST_CAT_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
enter = 1;
if (current->flags & COTHREAD_DESTROYED) {
@ -629,22 +641,21 @@ cothread_switch (cothread_state *cothread)
GST_CAT_DEBUG (GST_CAT_COTHREADS, "via longjmp() jmpbuf %p", cothread->jmp);
/* switch to it */
longjmp (cothread->jmp, 1);
}
else {
} else {
#ifdef HAVE_MAKECONTEXT
ucontext_t ucp;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "making context");
g_assert (cothread != cothread_main(ctx));
g_assert (cothread != cothread_main (ctx));
getcontext (&ucp);
ucp.uc_stack.ss_sp = (void *)cothread->stack_base;
ucp.uc_stack.ss_sp = (void *) cothread->stack_base;
ucp.uc_stack.ss_size = cothread->stack_size;
makecontext (&ucp, cothread_stub, 0);
setcontext (&ucp);
#else
GST_ARCH_SETUP_STACK ((char*)cothread->sp);
GST_ARCH_SETUP_STACK ((char *) cothread->sp);
GST_ARCH_SET_SP (cothread->sp);
/* start it */
GST_ARCH_CALL (cothread_stub);
@ -668,7 +679,8 @@ nocurrent:
exit (2);
#endif /* COTHREAD_PARANOID */
selfswitch:
g_warning ("cothread: trying to switch to same thread, legal but not necessary");
g_warning
("cothread: trying to switch to same thread, legal but not necessary");
return;
}
@ -679,7 +691,7 @@ selfswitch:
* Locks the cothread state.
*/
void
cothread_lock (cothread_state *cothread)
cothread_lock (cothread_state * cothread)
{
}
@ -692,7 +704,7 @@ cothread_lock (cothread_state *cothread)
* Returns: TRUE if the cothread could be locked.
*/
gboolean
cothread_trylock (cothread_state *cothread)
cothread_trylock (cothread_state * cothread)
{
return TRUE;
}
@ -704,6 +716,6 @@ cothread_trylock (cothread_state *cothread)
* Unlock the cothread state.
*/
void
cothread_unlock (cothread_state *cothread)
cothread_unlock (cothread_state * cothread)
{
}

View file

@ -26,56 +26,56 @@
#include <glib.h>
#include <setjmp.h>
typedef struct _cothread_state cothread_state;
typedef struct _cothread_context cothread_context;
typedef struct _cothread_state cothread_state;
typedef struct _cothread_context cothread_context;
typedef int (*cothread_func) (int argc,char **argv);
typedef int (*cothread_func) (int argc, char **argv);
#define COTHREAD_STARTED 0x01
#define COTHREAD_DESTROYED 0x02
struct _cothread_state {
cothread_context *ctx;
int cothreadnum;
gpointer priv;
struct _cothread_state
{
cothread_context *ctx;
int cothreadnum;
gpointer priv;
cothread_func func;
int argc;
char **argv;
cothread_func func;
int argc;
char **argv;
int flags;
void *sp;
jmp_buf jmp;
void *stack_base;
unsigned long stack_size;
int flags;
void *sp;
jmp_buf jmp;
void *stack_base;
unsigned long stack_size;
int magic_number;
int magic_number;
};
cothread_context* cothread_context_init (void);
void cothread_context_free (cothread_context *ctx);
void cothread_context_set_data (cothread_state *cothread,
gchar *key, gpointer data);
gpointer cothread_context_get_data (cothread_state *cothread, gchar *key);
cothread_context *cothread_context_init (void);
void cothread_context_free (cothread_context * ctx);
void cothread_context_set_data (cothread_state * cothread,
gchar * key, gpointer data);
gpointer cothread_context_get_data (cothread_state * cothread, gchar * key);
cothread_state* cothread_create (cothread_context *ctx);
void cothread_free (cothread_state *cothread);
void cothread_setfunc (cothread_state *cothread, cothread_func func,
int argc, char **argv);
void cothread_stop (cothread_state *cothread);
cothread_state *cothread_create (cothread_context * ctx);
void cothread_free (cothread_state * cothread);
void cothread_setfunc (cothread_state * cothread, cothread_func func,
int argc, char **argv);
void cothread_stop (cothread_state * cothread);
void cothread_switch (cothread_state *cothread);
void cothread_set_private (cothread_state *cothread,
gpointer data);
gpointer cothread_get_private (cothread_state *cothread);
void cothread_switch (cothread_state * cothread);
void cothread_set_private (cothread_state * cothread, gpointer data);
gpointer cothread_get_private (cothread_state * cothread);
void cothread_lock (cothread_state *cothread);
gboolean cothread_trylock (cothread_state *cothread);
void cothread_unlock (cothread_state *cothread);
void cothread_lock (cothread_state * cothread);
gboolean cothread_trylock (cothread_state * cothread);
void cothread_unlock (cothread_state * cothread);
cothread_state* cothread_main (cothread_context *ctx);
cothread_state* cothread_current_main (void);
cothread_state* cothread_current (void);
cothread_state *cothread_main (cothread_context * ctx);
cothread_state *cothread_current_main (void);
cothread_state *cothread_current (void);
#endif /* __COTHREAD_H__ */

View file

@ -29,20 +29,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_aggregator_debug);
#define GST_CAT_DEFAULT gst_aggregator_debug
GstElementDetails gst_aggregator_details = GST_ELEMENT_DETAILS (
"Aggregator pipe fitting",
"Generic",
"N-to-1 pipe fitting",
"Wim Taymans <wim.taymans@chello.be>"
);
GstElementDetails gst_aggregator_details =
GST_ELEMENT_DETAILS ("Aggregator pipe fitting",
"Generic",
"N-to-1 pipe fitting",
"Wim Taymans <wim.taymans@chello.be>");
/* Aggregator signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_NUM_PADS,
ARG_SILENT,
@ -51,12 +52,11 @@ enum {
/* FILL ME */
};
GstStaticPadTemplate aggregator_src_template = GST_STATIC_PAD_TEMPLATE (
"sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate aggregator_src_template =
GST_STATIC_PAD_TEMPLATE ("sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
#define GST_TYPE_AGGREGATOR_SCHED (gst_aggregator_sched_get_type())
static GType
@ -64,75 +64,80 @@ gst_aggregator_sched_get_type (void)
{
static GType aggregator_sched_type = 0;
static GEnumValue aggregator_sched[] = {
{ AGGREGATOR_LOOP, "1", "Loop Based"},
{ AGGREGATOR_LOOP_SELECT, "3", "Loop Based Select"},
{ AGGREGATOR_CHAIN, "4", "Chain Based"},
{AGGREGATOR_LOOP, "1", "Loop Based"},
{AGGREGATOR_LOOP_SELECT, "3", "Loop Based Select"},
{AGGREGATOR_CHAIN, "4", "Chain Based"},
{0, NULL, NULL},
};
if (!aggregator_sched_type) {
aggregator_sched_type = g_enum_register_static ("GstAggregatorSched", aggregator_sched);
aggregator_sched_type =
g_enum_register_static ("GstAggregatorSched", aggregator_sched);
}
return aggregator_sched_type;
}
#define AGGREGATOR_IS_LOOP_BASED(ag) ((ag)->sched != AGGREGATOR_CHAIN)
static GstPad* gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *temp, const
gchar *unused);
static void gst_aggregator_update_functions (GstAggregator *aggregator);
static GstPad *gst_aggregator_request_new_pad (GstElement * element,
GstPadTemplate * temp, const gchar * unused);
static void gst_aggregator_update_functions (GstAggregator * aggregator);
static void gst_aggregator_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_aggregator_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_aggregator_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_aggregator_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_aggregator_chain (GstPad *pad, GstData *_data);
static void gst_aggregator_loop (GstElement *element);
static void gst_aggregator_chain (GstPad * pad, GstData * _data);
static void gst_aggregator_loop (GstElement * element);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_aggregator_debug, "aggregator", 0, "aggregator element");
GST_BOILERPLATE_FULL (GstAggregator, gst_aggregator, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstAggregator, gst_aggregator, GstElement,
GST_TYPE_ELEMENT, _do_init);
static void
gst_aggregator_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&aggregator_src_template));
gst_element_class_set_details (gstelement_class, &gst_aggregator_details);
}
static void
gst_aggregator_class_init (GstAggregatorClass *klass)
gst_aggregator_class_init (GstAggregatorClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*) klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_PADS,
g_param_spec_int ("num_pads", "Num pads", "The number of source pads",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_param_spec_int ("num_pads", "Num pads", "The number of source pads",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "Silent", "Don't produce messages",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "Silent", "Don't produce messages",
FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SCHED,
g_param_spec_enum ("sched", "Scheduling", "The type of scheduling this element should use",
GST_TYPE_AGGREGATOR_SCHED, AGGREGATOR_CHAIN, G_PARAM_READWRITE));
g_param_spec_enum ("sched", "Scheduling",
"The type of scheduling this element should use",
GST_TYPE_AGGREGATOR_SCHED, AGGREGATOR_CHAIN, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last_message", "Last message", "The current state of the element",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last_message", "Last message",
"The current state of the element", NULL, G_PARAM_READABLE));
gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_aggregator_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_aggregator_get_property);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_aggregator_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_aggregator_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_aggregator_request_new_pad);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_aggregator_request_new_pad);
}
static void
gst_aggregator_init (GstAggregator *aggregator)
static void
gst_aggregator_init (GstAggregator * aggregator)
{
aggregator->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_getcaps_function (aggregator->srcpad, gst_pad_proxy_getcaps);
@ -146,8 +151,9 @@ gst_aggregator_init (GstAggregator *aggregator)
gst_aggregator_update_functions (aggregator);
}
static GstPad*
gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
static GstPad *
gst_aggregator_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
{
gchar *name;
GstPad *sinkpad;
@ -162,43 +168,42 @@ gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ, cons
aggregator = GST_AGGREGATOR (element);
name = g_strdup_printf ("sink%d",aggregator->numsinkpads);
name = g_strdup_printf ("sink%d", aggregator->numsinkpads);
sinkpad = gst_pad_new_from_template (templ, name);
g_free (name);
if (!AGGREGATOR_IS_LOOP_BASED (aggregator)) {
gst_pad_set_chain_function (sinkpad, gst_aggregator_chain);
}
gst_pad_set_getcaps_function (sinkpad, gst_pad_proxy_getcaps);
gst_element_add_pad (GST_ELEMENT (aggregator), sinkpad);
aggregator->sinkpads = g_list_prepend (aggregator->sinkpads, sinkpad);
aggregator->numsinkpads++;
return sinkpad;
}
static void
gst_aggregator_update_functions (GstAggregator *aggregator)
gst_aggregator_update_functions (GstAggregator * aggregator)
{
GList *pads;
if (AGGREGATOR_IS_LOOP_BASED (aggregator)) {
gst_element_set_loop_function (GST_ELEMENT (aggregator), GST_DEBUG_FUNCPTR (gst_aggregator_loop));
}
else {
gst_element_set_loop_function (GST_ELEMENT (aggregator),
GST_DEBUG_FUNCPTR (gst_aggregator_loop));
} else {
gst_element_set_loop_function (GST_ELEMENT (aggregator), NULL);
}
pads = aggregator->sinkpads;
while (pads) {
GstPad *pad = GST_PAD (pads->data);
if (AGGREGATOR_IS_LOOP_BASED (aggregator)) {
gst_pad_set_get_function (pad, NULL);
}
else {
} else {
gst_element_set_loop_function (GST_ELEMENT (aggregator), NULL);
}
pads = g_list_next (pads);
@ -206,7 +211,8 @@ gst_aggregator_update_functions (GstAggregator *aggregator)
}
static void
gst_aggregator_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_aggregator_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstAggregator *aggregator;
@ -229,7 +235,8 @@ gst_aggregator_set_property (GObject *object, guint prop_id, const GValue *value
}
static void
gst_aggregator_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_aggregator_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstAggregator *aggregator;
@ -256,15 +263,17 @@ gst_aggregator_get_property (GObject *object, guint prop_id, GValue *value, GPar
}
}
static void
gst_aggregator_push (GstAggregator *aggregator, GstPad *pad, GstBuffer *buf, guchar *debug)
static void
gst_aggregator_push (GstAggregator * aggregator, GstPad * pad, GstBuffer * buf,
guchar * debug)
{
if (!aggregator->silent) {
g_free (aggregator->last_message);
aggregator->last_message = g_strdup_printf ("%10.10s ******* (%s:%s)a (%d bytes, %"
G_GUINT64_FORMAT ")",
debug, GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
aggregator->last_message =
g_strdup_printf ("%10.10s ******* (%s:%s)a (%d bytes, %"
G_GUINT64_FORMAT ")", debug, GST_DEBUG_PAD_NAME (pad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
g_object_notify (G_OBJECT (aggregator), "last_message");
}
@ -272,8 +281,8 @@ gst_aggregator_push (GstAggregator *aggregator, GstPad *pad, GstBuffer *buf, guc
gst_pad_push (aggregator->srcpad, GST_DATA (buf));
}
static void
gst_aggregator_loop (GstElement *element)
static void
gst_aggregator_loop (GstElement * element)
{
GstAggregator *aggregator;
GstBuffer *buf;
@ -288,6 +297,7 @@ gst_aggregator_loop (GstElement *element)
* active ones */
while (pads) {
GstPad *pad = GST_PAD (pads->data);
pads = g_list_next (pads);
/* we need to check is the pad is usable. IS_USABLE will check
@ -296,15 +306,14 @@ gst_aggregator_loop (GstElement *element)
* and that the peer pad is also enabled.
*/
if (GST_PAD_IS_USABLE (pad)) {
buf = GST_BUFFER (gst_pad_pull (pad));
debug = "loop";
buf = GST_BUFFER (gst_pad_pull (pad));
debug = "loop";
/* then push it forward */
gst_aggregator_push (aggregator, pad, buf, debug);
gst_aggregator_push (aggregator, pad, buf, debug);
}
}
}
else {
} else {
if (aggregator->sched == AGGREGATOR_LOOP_SELECT) {
GstPad *pad;
@ -314,8 +323,7 @@ gst_aggregator_loop (GstElement *element)
buf = GST_BUFFER (gst_pad_pull (pad));
gst_aggregator_push (aggregator, pad, buf, debug);
}
else {
} else {
g_assert_not_reached ();
}
}
@ -328,8 +336,8 @@ gst_aggregator_loop (GstElement *element)
*
* Chain a buffer on a pad.
*/
static void
gst_aggregator_chain (GstPad *pad, GstData *_data)
static void
gst_aggregator_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstAggregator *aggregator;
@ -343,4 +351,3 @@ gst_aggregator_chain (GstPad *pad, GstData *_data)
gst_aggregator_push (aggregator, pad, buf, "chain");
}

View file

@ -26,11 +26,9 @@
#include <gst/gst.h>
G_BEGIN_DECLS
typedef enum {
AGGREGATOR_LOOP = 1,
G_BEGIN_DECLS typedef enum
{
AGGREGATOR_LOOP = 1,
AGGREGATOR_LOOP_SELECT,
AGGREGATOR_CHAIN
} GstAggregatorSchedType;
@ -46,10 +44,11 @@ typedef enum {
#define GST_IS_AGGREGATOR_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR))
typedef struct _GstAggregator GstAggregator;
typedef struct _GstAggregatorClass GstAggregatorClass;
typedef struct _GstAggregator GstAggregator;
typedef struct _GstAggregatorClass GstAggregatorClass;
struct _GstAggregator {
struct _GstAggregator
{
GstElement element;
GstPad *srcpad;
@ -63,14 +62,14 @@ struct _GstAggregator {
gchar *last_message;
};
struct _GstAggregatorClass {
struct _GstAggregatorClass
{
GstElementClass parent_class;
};
GType gst_aggregator_get_type (void);
GType gst_aggregator_get_type (void);
gboolean gst_aggregator_factory_init (GstElementFactory *factory);
gboolean gst_aggregator_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_AGGREGATOR_H__ */

View file

@ -29,47 +29,53 @@
GST_DEBUG_CATEGORY_STATIC (gst_buffer_store_debug);
#define GST_CAT_DEFAULT gst_buffer_store_debug
enum {
enum
{
CLEARED,
BUFFER_ADDED,
LAST_SIGNAL
};
enum {
enum
{
ARG_0
};
static void gst_buffer_store_dispose (GObject * object);
static void gst_buffer_store_dispose (GObject * object);
static gboolean gst_buffer_store_add_buffer_func (GstBufferStore * store,
GstBuffer * buffer);
static void gst_buffer_store_cleared_func (GstBufferStore * store);
static gboolean gst_buffer_store_add_buffer_func (GstBufferStore * store,
GstBuffer * buffer);
static void gst_buffer_store_cleared_func (GstBufferStore * store);
static guint gst_buffer_store_signals[LAST_SIGNAL] = { 0 };
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_buffer_store_debug, "GstBufferStore", 0, "buffer store helper");
GST_BOILERPLATE_FULL (GstBufferStore, gst_buffer_store, GObject, G_TYPE_OBJECT, _do_init);
GST_BOILERPLATE_FULL (GstBufferStore, gst_buffer_store, GObject, G_TYPE_OBJECT,
_do_init);
G_GNUC_UNUSED static void
debug_buffers (GstBufferStore *store)
debug_buffers (GstBufferStore * store)
{
GList *walk = store->buffers;
g_printerr ("BUFFERS in store:\n");
while (walk) {
g_print ("%15"G_GUINT64_FORMAT" - %7u\n", GST_BUFFER_OFFSET (walk->data), GST_BUFFER_SIZE (walk->data));
g_print ("%15" G_GUINT64_FORMAT " - %7u\n", GST_BUFFER_OFFSET (walk->data),
GST_BUFFER_SIZE (walk->data));
walk = g_list_next (walk);
}
g_printerr ("\n");
}
static gboolean
continue_accu (GSignalInvocationHint *ihint, GValue *return_accu,
const GValue *handler_return, gpointer data)
continue_accu (GSignalInvocationHint * ihint, GValue * return_accu,
const GValue * handler_return, gpointer data)
{
gboolean do_continue = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, do_continue);
return do_continue;
@ -79,31 +85,31 @@ gst_buffer_store_base_init (gpointer g_class)
{
}
static void
gst_buffer_store_class_init (GstBufferStoreClass *store_class)
gst_buffer_store_class_init (GstBufferStoreClass * store_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (store_class);
gobject_class->dispose = gst_buffer_store_dispose;
gst_buffer_store_signals[CLEARED] = g_signal_new ("cleared",
G_TYPE_FROM_CLASS (store_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, cleared), NULL, NULL,
gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_buffer_store_signals[BUFFER_ADDED] = g_signal_new ("buffer-added",
G_TYPE_FROM_CLASS (store_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, buffer_added), continue_accu, NULL,
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_BUFFER);
gst_buffer_store_signals[CLEARED] = g_signal_new ("cleared",
G_TYPE_FROM_CLASS (store_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, cleared), NULL, NULL,
gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_buffer_store_signals[BUFFER_ADDED] = g_signal_new ("buffer-added",
G_TYPE_FROM_CLASS (store_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, buffer_added), continue_accu, NULL,
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_BUFFER);
store_class->cleared = gst_buffer_store_cleared_func;
store_class->buffer_added = gst_buffer_store_add_buffer_func;
}
static void
gst_buffer_store_init (GstBufferStore *store)
gst_buffer_store_init (GstBufferStore * store)
{
store->buffers = NULL;
}
static void
gst_buffer_store_dispose (GObject *object)
gst_buffer_store_dispose (GObject * object)
{
GstBufferStore *store = GST_BUFFER_STORE (object);
@ -111,22 +117,24 @@ gst_buffer_store_dispose (GObject *object)
parent_class->dispose (object);
}
static gboolean
gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
gst_buffer_store_add_buffer_func (GstBufferStore * store, GstBuffer * buffer)
{
g_assert (buffer != NULL);
if (!GST_BUFFER_OFFSET_IS_VALID (buffer) &&
store->buffers &&
GST_BUFFER_OFFSET_IS_VALID (store->buffers->data)) {
store->buffers && GST_BUFFER_OFFSET_IS_VALID (store->buffers->data)) {
/* we assumed valid offsets, but suddenly they are not anymore */
GST_DEBUG_OBJECT (store, "attempting to add buffer %p with invalid offset to store with valid offset, abort",
buffer);
GST_DEBUG_OBJECT (store,
"attempting to add buffer %p with invalid offset to store with valid offset, abort",
buffer);
return FALSE;
} else if (!store->buffers || !GST_BUFFER_OFFSET_IS_VALID (store->buffers->data)) {
} else if (!store->buffers
|| !GST_BUFFER_OFFSET_IS_VALID (store->buffers->data)) {
/* the starting buffer had an invalid offset, in that case we assume continuous buffers */
GST_LOG_OBJECT (store, "adding buffer %p with invalid offset and size %u",
buffer, GST_BUFFER_SIZE (buffer));
buffer, GST_BUFFER_SIZE (buffer));
gst_data_ref (GST_DATA (buffer));
store->buffers = g_list_append (store->buffers, buffer);
return TRUE;
@ -134,10 +142,12 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
/* both list and buffer have valid offsets, we can really go wild */
GList *walk, *current_list = NULL;
GstBuffer *current;
g_assert (GST_BUFFER_OFFSET_IS_VALID (buffer));
GST_LOG_OBJECT (store, "attempting to add buffer %p with offset %"G_GUINT64_FORMAT" and size %u",
buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
GST_LOG_OBJECT (store,
"attempting to add buffer %p with offset %" G_GUINT64_FORMAT
" and size %u", buffer, GST_BUFFER_OFFSET (buffer),
GST_BUFFER_SIZE (buffer));
/* we keep a sorted list of non-overlapping buffers */
walk = store->buffers;
while (walk) {
@ -148,9 +158,10 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
continue;
} else if (GST_BUFFER_OFFSET (current) == GST_BUFFER_OFFSET (buffer)) {
guint needed_size;
if (walk) {
needed_size = MIN (GST_BUFFER_SIZE (buffer),
GST_BUFFER_OFFSET (walk->data) - GST_BUFFER_OFFSET (current));
needed_size = MIN (GST_BUFFER_SIZE (buffer),
GST_BUFFER_OFFSET (walk->data) - GST_BUFFER_OFFSET (current));
} else {
needed_size = GST_BUFFER_SIZE (buffer);
}
@ -161,14 +172,17 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
if (needed_size < GST_BUFFER_SIZE (buffer)) {
/* need to create subbuffer to not have overlapping data */
GstBuffer *sub = gst_buffer_create_sub (buffer, 0, needed_size);
g_assert (sub);
buffer = sub;
} else {
gst_data_ref (GST_DATA (buffer));
}
/* replace current buffer with new one */
GST_INFO_OBJECT (store, "replacing buffer %p with buffer %p with offset %"G_GINT64_FORMAT" and size %u",
current_list->data, buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
GST_INFO_OBJECT (store,
"replacing buffer %p with buffer %p with offset %" G_GINT64_FORMAT
" and size %u", current_list->data, buffer,
GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
gst_data_unref (GST_DATA (current_list->data));
current_list->data = buffer;
buffer = NULL;
@ -176,8 +190,9 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
}
} else if (GST_BUFFER_OFFSET (current) > GST_BUFFER_OFFSET (buffer)) {
GList *previous = g_list_previous (current_list);
guint64 start_offset = previous ?
GST_BUFFER_OFFSET (previous->data) + GST_BUFFER_SIZE (previous->data) : 0;
guint64 start_offset = previous ?
GST_BUFFER_OFFSET (previous->data) +
GST_BUFFER_SIZE (previous->data) : 0;
if (start_offset == GST_BUFFER_OFFSET (current)) {
buffer = NULL;
@ -185,23 +200,28 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
} else {
/* we have data to insert */
if (start_offset > GST_BUFFER_OFFSET (buffer) ||
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) > GST_BUFFER_OFFSET (current)) {
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) >
GST_BUFFER_OFFSET (current)) {
GstBuffer *sub;
/* need a subbuffer */
start_offset = GST_BUFFER_OFFSET (buffer) > start_offset ? 0 :
start_offset - GST_BUFFER_OFFSET (buffer);
start_offset = GST_BUFFER_OFFSET (buffer) > start_offset ? 0 :
start_offset - GST_BUFFER_OFFSET (buffer);
sub = gst_buffer_create_sub (buffer, start_offset,
MIN (GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (current) - start_offset - GST_BUFFER_OFFSET (buffer)));
MIN (GST_BUFFER_SIZE (buffer),
GST_BUFFER_OFFSET (current) - start_offset -
GST_BUFFER_OFFSET (buffer)));
g_assert (sub);
GST_BUFFER_OFFSET (sub) = start_offset + GST_BUFFER_OFFSET (buffer);
buffer = sub;
} else {
gst_data_ref (GST_DATA (buffer));
}
GST_INFO_OBJECT (store, "adding buffer %p with offset %"G_GINT64_FORMAT" and size %u",
buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
store->buffers = g_list_insert_before (store->buffers, current_list, buffer);
GST_INFO_OBJECT (store,
"adding buffer %p with offset %" G_GINT64_FORMAT " and size %u",
buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
store->buffers =
g_list_insert_before (store->buffers, current_list, buffer);
buffer = NULL;
break;
}
@ -209,8 +229,9 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
}
if (buffer) {
gst_data_ref (GST_DATA (buffer));
GST_INFO_OBJECT (store, "adding buffer %p with offset %"G_GINT64_FORMAT" and size %u",
buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
GST_INFO_OBJECT (store,
"adding buffer %p with offset %" G_GINT64_FORMAT " and size %u",
buffer, GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
if (current_list) {
g_list_append (current_list, buffer);
} else {
@ -222,12 +243,13 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer)
}
}
static void
gst_buffer_store_cleared_func (GstBufferStore *store)
gst_buffer_store_cleared_func (GstBufferStore * store)
{
g_list_foreach (store->buffers, (GFunc) gst_data_unref, NULL);
g_list_free (store->buffers);
store->buffers = NULL;
}
/**
* gst_buffer_store_new:
*
@ -240,6 +262,7 @@ gst_buffer_store_new (void)
{
return GST_BUFFER_STORE (g_object_new (GST_TYPE_BUFFER_STORE, NULL));
}
/**
* gst_buffer_store_clear:
* @store: a bufferstore
@ -249,12 +272,13 @@ gst_buffer_store_new (void)
*/
/* FIXME: call this function _reset ? */
void
gst_buffer_store_clear (GstBufferStore *store)
gst_buffer_store_clear (GstBufferStore * store)
{
g_return_if_fail (GST_IS_BUFFER_STORE (store));
g_signal_emit (store, gst_buffer_store_signals [CLEARED], 0, NULL);
g_signal_emit (store, gst_buffer_store_signals[CLEARED], 0, NULL);
}
/**
* gst_buffer_store_add_buffer:
* @store: a bufferstore
@ -265,10 +289,10 @@ gst_buffer_store_clear (GstBufferStore *store)
* Returns: TRUE, if the buffer was added, FALSE if an error occured.
*/
gboolean
gst_buffer_store_add_buffer (GstBufferStore *store, GstBuffer *buffer)
gst_buffer_store_add_buffer (GstBufferStore * store, GstBuffer * buffer)
{
gboolean ret;
g_return_val_if_fail (GST_IS_BUFFER_STORE (store), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
@ -276,11 +300,13 @@ gst_buffer_store_add_buffer (GstBufferStore *store, GstBuffer *buffer)
GST_BUFFER_OFFSET_IS_VALID (store->buffers->data) &&
!GST_BUFFER_OFFSET_IS_VALID (buffer))
return FALSE;
g_signal_emit (store, gst_buffer_store_signals [BUFFER_ADDED], 0, buffer, &ret);
g_signal_emit (store, gst_buffer_store_signals[BUFFER_ADDED], 0, buffer,
&ret);
return ret;
}
/**
* gst_buffer_store_get_buffer:
* @store: a bufferstore
@ -295,7 +321,7 @@ gst_buffer_store_add_buffer (GstBufferStore *store, GstBuffer *buffer)
* available.
*/
GstBuffer *
gst_buffer_store_get_buffer (GstBufferStore *store, guint64 offset, guint size)
gst_buffer_store_get_buffer (GstBufferStore * store, guint64 offset, guint size)
{
GstBuffer *current;
GList *walk;
@ -324,38 +350,39 @@ gst_buffer_store_get_buffer (GstBufferStore *store, guint64 offset, guint size)
if (cur_offset > offset) {
/* #include <windows.h>
do_nothing_loop (); */
} else if (cur_offset == offset &&
GST_BUFFER_SIZE (current) == size) {
GST_LOG_OBJECT (store, "found matching buffer %p for offset %"G_GUINT64_FORMAT" and size %u",
current, offset, size);
} else if (cur_offset == offset && GST_BUFFER_SIZE (current) == size) {
GST_LOG_OBJECT (store,
"found matching buffer %p for offset %" G_GUINT64_FORMAT
" and size %u", current, offset, size);
ret = current;
gst_data_ref (GST_DATA (ret));
GST_LOG_OBJECT (store, "refcount %d",
GST_DATA_REFCOUNT_VALUE(ret));
GST_LOG_OBJECT (store, "refcount %d", GST_DATA_REFCOUNT_VALUE (ret));
break;
} else if (cur_offset + GST_BUFFER_SIZE (current) > offset) {
if (cur_offset + GST_BUFFER_SIZE (current) >= offset + size) {
ret = gst_buffer_create_sub (current, offset - cur_offset, size);
GST_LOG_OBJECT (store, "created subbuffer %p from buffer %p for offset %llu and size %u",
ret, current, offset, size);
GST_LOG_OBJECT (store,
"created subbuffer %p from buffer %p for offset %llu and size %u",
ret, current, offset, size);
break;
}
/* uh, the requested data spans some buffers */
ret = gst_buffer_new_and_alloc (size);
GST_LOG_OBJECT (store, "created buffer %p for offset %"G_GUINT64_FORMAT
" and size %u, will fill with data now",
ret, offset, size);
GST_LOG_OBJECT (store, "created buffer %p for offset %" G_GUINT64_FORMAT
" and size %u, will fill with data now", ret, offset, size);
data = GST_BUFFER_DATA (ret);
tmp = GST_BUFFER_SIZE (current) - offset + cur_offset;
memcpy (data, GST_BUFFER_DATA (current) + offset - cur_offset, tmp);
data += tmp;
size -= tmp;
while (size) {
if (walk == NULL ||
(have_offset &&
GST_BUFFER_OFFSET (current) + GST_BUFFER_SIZE (current) != GST_BUFFER_OFFSET (walk->data))) {
GST_DEBUG_OBJECT (store, "not all data for offset %"G_GUINT64_FORMAT" and remaining size %u available, aborting",
offset, size);
if (walk == NULL ||
(have_offset &&
GST_BUFFER_OFFSET (current) + GST_BUFFER_SIZE (current) !=
GST_BUFFER_OFFSET (walk->data))) {
GST_DEBUG_OBJECT (store,
"not all data for offset %" G_GUINT64_FORMAT
" and remaining size %u available, aborting", offset, size);
gst_data_unref (GST_DATA (ret));
ret = NULL;
goto out;
@ -373,9 +400,10 @@ gst_buffer_store_get_buffer (GstBufferStore *store, guint64 offset, guint size)
}
}
out:
return ret;
}
/**
* gst_buffer_store_get_size:
* @store: a bufferstore
@ -388,7 +416,7 @@ out:
* offset.
*/
guint
gst_buffer_store_get_size (GstBufferStore *store, guint64 offset)
gst_buffer_store_get_size (GstBufferStore * store, guint64 offset)
{
GList *walk;
gboolean have_offset;
@ -408,8 +436,9 @@ gst_buffer_store_get_size (GstBufferStore *store, guint64 offset)
have_offset = FALSE;
}
while (walk) {
if (have_offset && counting &&
cur_offset + GST_BUFFER_SIZE (current) != GST_BUFFER_OFFSET (walk->data)) {
if (have_offset && counting &&
cur_offset + GST_BUFFER_SIZE (current) !=
GST_BUFFER_OFFSET (walk->data)) {
break;
}
current = GST_BUFFER (walk->data);
@ -432,6 +461,6 @@ gst_buffer_store_get_size (GstBufferStore *store, guint64 offset)
cur_offset += GST_BUFFER_SIZE (current);
}
}
return ret;
}

View file

@ -28,46 +28,42 @@
#include <gst/gstmarshal.h>
G_BEGIN_DECLS
#define GST_TYPE_BUFFER_STORE (gst_buffer_store_get_type ())
#define GST_BUFFER_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BUFFER_STORE, GstBufferStore))
#define GST_IS_BUFFER_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BUFFER_STORE))
#define GST_BUFFER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BUFFER_STORE, GstBufferStoreClass))
#define GST_IS_BUFFER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BUFFER_STORE))
#define GST_BUFFER_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BUFFER_STORE, GstBufferStoreClass))
typedef struct _GstBufferStore GstBufferStore;
typedef struct _GstBufferStoreClass GstBufferStoreClass;
typedef struct _GstBufferStore GstBufferStore;
typedef struct _GstBufferStoreClass GstBufferStoreClass;
struct _GstBufferStore
{
GObject object;
struct _GstBufferStore {
GObject object;
GList * buffers;
GList *buffers;
};
struct _GstBufferStoreClass {
GObjectClass parent_class;
struct _GstBufferStoreClass
{
GObjectClass parent_class;
/* signals */
void (* cleared) (GstBufferStore * store);
gboolean (* buffer_added) (GstBufferStore * store,
GstBuffer * buffer);
void (*cleared) (GstBufferStore * store);
gboolean (*buffer_added) (GstBufferStore * store, GstBuffer * buffer);
};
GType gst_buffer_store_get_type (void);
GType gst_buffer_store_get_type (void);
GstBufferStore * gst_buffer_store_new (void);
void gst_buffer_store_clear (GstBufferStore * store);
GstBufferStore *gst_buffer_store_new (void);
void gst_buffer_store_clear (GstBufferStore * store);
gboolean gst_buffer_store_add_buffer (GstBufferStore * store,
GstBuffer * buffer);
gboolean gst_buffer_store_add_buffer (GstBufferStore * store,
GstBuffer * buffer);
GstBuffer * gst_buffer_store_get_buffer (GstBufferStore * store,
guint64 offset,
guint size);
guint gst_buffer_store_get_size (GstBufferStore * store,
guint64 offset);
GstBuffer *gst_buffer_store_get_buffer (GstBufferStore * store,
guint64 offset, guint size);
guint gst_buffer_store_get_size (GstBufferStore * store, guint64 offset);
G_END_DECLS
#endif /* __GST_BUFFER_STORE_H__ */

View file

@ -44,42 +44,44 @@
#include "gsttypefind.h"
struct _elements_entry {
struct _elements_entry
{
gchar *name;
guint rank;
GType (*type) (void);
GType (*type) (void);
};
extern GType gst_filesrc_get_type(void);
extern GType gst_filesrc_get_type (void);
extern GstElementDetails gst_filesrc_details;
static struct _elements_entry _elements[] = {
{ "aggregator", GST_RANK_NONE, gst_aggregator_get_type },
{ "fakesrc", GST_RANK_NONE, gst_fakesrc_get_type },
{ "fakesink", GST_RANK_NONE, gst_fakesink_get_type },
{ "fdsink", GST_RANK_NONE, gst_fdsink_get_type },
{ "fdsrc", GST_RANK_NONE, gst_fdsrc_get_type },
{ "filesrc", GST_RANK_NONE, gst_filesrc_get_type },
{ "filesink", GST_RANK_NONE, gst_filesink_get_type },
{ "identity", GST_RANK_NONE, gst_identity_get_type },
{ "md5sink", GST_RANK_NONE, gst_md5sink_get_type },
{ "multifilesrc", GST_RANK_NONE, gst_multifilesrc_get_type },
{ "pipefilter", GST_RANK_NONE, gst_pipefilter_get_type },
{ "shaper", GST_RANK_NONE, gst_shaper_get_type },
{ "statistics", GST_RANK_NONE, gst_statistics_get_type },
{ "tee", GST_RANK_NONE, gst_tee_get_type },
{ "typefind", GST_RANK_NONE, gst_type_find_element_get_type },
{ NULL, 0 },
{"aggregator", GST_RANK_NONE, gst_aggregator_get_type},
{"fakesrc", GST_RANK_NONE, gst_fakesrc_get_type},
{"fakesink", GST_RANK_NONE, gst_fakesink_get_type},
{"fdsink", GST_RANK_NONE, gst_fdsink_get_type},
{"fdsrc", GST_RANK_NONE, gst_fdsrc_get_type},
{"filesrc", GST_RANK_NONE, gst_filesrc_get_type},
{"filesink", GST_RANK_NONE, gst_filesink_get_type},
{"identity", GST_RANK_NONE, gst_identity_get_type},
{"md5sink", GST_RANK_NONE, gst_md5sink_get_type},
{"multifilesrc", GST_RANK_NONE, gst_multifilesrc_get_type},
{"pipefilter", GST_RANK_NONE, gst_pipefilter_get_type},
{"shaper", GST_RANK_NONE, gst_shaper_get_type},
{"statistics", GST_RANK_NONE, gst_statistics_get_type},
{"tee", GST_RANK_NONE, gst_tee_get_type},
{"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
{NULL, 0},
};
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
struct _elements_entry *my_elements = _elements;
while ((*my_elements).name) {
if (!gst_element_register (plugin, (*my_elements).name, (*my_elements).rank, ((*my_elements).type) ()))
while ((*my_elements).name) {
if (!gst_element_register (plugin, (*my_elements).name, (*my_elements).rank,
((*my_elements).type) ()))
return FALSE;
my_elements++;
}
@ -87,15 +89,8 @@ plugin_init (GstPlugin *plugin)
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstelements",
"standard GStreamer elements",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstelements",
"standard GStreamer elements",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)

View file

@ -31,22 +31,22 @@
GST_DEBUG_CATEGORY_STATIC (gst_fakesink_debug);
#define GST_CAT_DEFAULT gst_fakesink_debug
GstElementDetails gst_fakesink_details = GST_ELEMENT_DETAILS (
"Fake Sink",
"Sink",
"Black hole for data",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
GstElementDetails gst_fakesink_details = GST_ELEMENT_DETAILS ("Fake Sink",
"Sink",
"Black hole for data",
"Erik Walthinsen <omega@cse.ogi.edu>");
/* FakeSink signals and args */
enum {
enum
{
/* FILL ME */
SIGNAL_HANDOFF,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_STATE_ERROR,
ARG_NUM_SINKS,
@ -57,12 +57,10 @@ enum {
ARG_LAST_MESSAGE,
};
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE (
"sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate fakesink_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
#define GST_TYPE_FAKESINK_STATE_ERROR (gst_fakesink_state_error_get_type())
static GType
@ -70,17 +68,24 @@ gst_fakesink_state_error_get_type (void)
{
static GType fakesink_state_error_type = 0;
static GEnumValue fakesink_state_error[] = {
{ FAKESINK_STATE_ERROR_NONE, "0", "No state change errors"},
{ FAKESINK_STATE_ERROR_NULL_READY, "1", "Fail state change from NULL to READY"},
{ FAKESINK_STATE_ERROR_READY_PAUSED, "2", "Fail state change from READY to PAUSED"},
{ FAKESINK_STATE_ERROR_PAUSED_PLAYING, "3", "Fail state change from PAUSED to PLAYING"},
{ FAKESINK_STATE_ERROR_PLAYING_PAUSED, "4", "Fail state change from PLAYING to PAUSED"},
{ FAKESINK_STATE_ERROR_PAUSED_READY , "5", "Fail state change from PAUSED to READY"},
{ FAKESINK_STATE_ERROR_READY_NULL , "6", "Fail state change from READY to NULL"},
{FAKESINK_STATE_ERROR_NONE, "0", "No state change errors"},
{FAKESINK_STATE_ERROR_NULL_READY, "1",
"Fail state change from NULL to READY"},
{FAKESINK_STATE_ERROR_READY_PAUSED, "2",
"Fail state change from READY to PAUSED"},
{FAKESINK_STATE_ERROR_PAUSED_PLAYING, "3",
"Fail state change from PAUSED to PLAYING"},
{FAKESINK_STATE_ERROR_PLAYING_PAUSED, "4",
"Fail state change from PLAYING to PAUSED"},
{FAKESINK_STATE_ERROR_PAUSED_READY, "5",
"Fail state change from PAUSED to READY"},
{FAKESINK_STATE_ERROR_READY_NULL, "6",
"Fail state change from READY to NULL"},
{0, NULL, NULL},
};
if (!fakesink_state_error_type) {
fakesink_state_error_type = g_enum_register_static ("GstFakeSinkStateError", fakesink_state_error);
fakesink_state_error_type =
g_enum_register_static ("GstFakeSinkStateError", fakesink_state_error);
}
return fakesink_state_error_type;
}
@ -88,82 +93,86 @@ gst_fakesink_state_error_get_type (void)
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_fakesink_debug, "fakesink", 0, "fakesink element");
GST_BOILERPLATE_FULL (GstFakeSink, gst_fakesink, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFakeSink, gst_fakesink, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void gst_fakesink_set_clock (GstElement *element, GstClock *clock);
static GstPad* gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
gchar *unused);
static void gst_fakesink_set_clock (GstElement * element, GstClock * clock);
static GstPad *gst_fakesink_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * unused);
static void gst_fakesink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_fakesink_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_fakesink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_fakesink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstElementStateReturn
gst_fakesink_change_state (GstElement *element);
static GstElementStateReturn gst_fakesink_change_state (GstElement * element);
static void gst_fakesink_chain (GstPad *pad, GstData *_data);
static void gst_fakesink_chain (GstPad * pad, GstData * _data);
static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
static void
gst_fakesink_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_fakesink_details);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&fakesink_sink_template));
}
static void
gst_fakesink_class_init (GstFakeSinkClass *klass)
gst_fakesink_class_init (GstFakeSinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SINKS,
g_param_spec_int ("num_sinks", "Number of sinks", "The number of sinkpads",
1, G_MAXINT, 1, G_PARAM_READABLE));
g_param_spec_int ("num_sinks", "Number of sinks",
"The number of sinkpads", 1, G_MAXINT, 1, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STATE_ERROR,
g_param_spec_enum ("state_error", "State Error", "Generate a state change error",
GST_TYPE_FAKESINK_STATE_ERROR, FAKESINK_STATE_ERROR_NONE, G_PARAM_READWRITE));
g_param_spec_enum ("state_error", "State Error",
"Generate a state change error", GST_TYPE_FAKESINK_STATE_ERROR,
FAKESINK_STATE_ERROR_NONE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last_message", "Last Message", "The message describing current status",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last_message", "Last Message",
"The message describing current status", NULL, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC,
g_param_spec_boolean ("sync", "Sync", "Sync on the clock",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("sync", "Sync", "Sync on the clock", FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIGNAL_HANDOFFS,
g_param_spec_boolean ("signal-handoffs", "Signal handoffs", "Send a signal before unreffing the buffer",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
"Send a signal before unreffing the buffer", FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "Silent", "Don't produce last_message events",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "Silent",
"Don't produce last_message events", FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("dump", "Dump", "Dump received bytes to stdout",
FALSE, G_PARAM_READWRITE));
gst_fakesink_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesink_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesink_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesink_request_new_pad);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesink_set_clock);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesink_change_state);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_fakesink_request_new_pad);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_fakesink_set_clock);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_fakesink_change_state);
}
static void
gst_fakesink_init (GstFakeSink *fakesink)
static void
gst_fakesink_init (GstFakeSink * fakesink)
{
GstPad *pad;
@ -182,17 +191,18 @@ gst_fakesink_init (GstFakeSink *fakesink)
}
static void
gst_fakesink_set_clock (GstElement *element, GstClock *clock)
{
gst_fakesink_set_clock (GstElement * element, GstClock * clock)
{
GstFakeSink *sink;
sink = GST_FAKESINK (element);
sink->clock = clock;
}
}
static GstPad*
gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
static GstPad *
gst_fakesink_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
{
gchar *name;
GstPad *sinkpad;
@ -212,14 +222,15 @@ gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const
sinkpad = gst_pad_new_from_template (templ, name);
g_free (name);
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad);
return sinkpad;
}
static void
gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_fakesink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstFakeSink *sink;
@ -247,16 +258,17 @@ gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value,
}
}
static void
gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_fakesink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFakeSink *sink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FAKESINK (object));
sink = GST_FAKESINK (object);
switch (prop_id) {
case ARG_NUM_SINKS:
g_value_set_int (value, GST_ELEMENT (sink)->numsinkpads);
@ -285,8 +297,8 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
}
}
static void
gst_fakesink_chain (GstPad *pad, GstData *_data)
static void
gst_fakesink_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstFakeSink *fakesink;
@ -299,51 +311,52 @@ gst_fakesink_chain (GstPad *pad, GstData *_data)
if (GST_IS_EVENT (buf)) {
GstEvent *event = GST_EVENT (buf);
if (!fakesink->silent) {
if (!fakesink->silent) {
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)E (type: %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE (event), event);
fakesink->last_message =
g_strdup_printf ("chain ******* (%s:%s)E (type: %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE (event), event);
g_object_notify (G_OBJECT (fakesink), "last_message");
}
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
if (fakesink->sync && fakesink->clock) {
gint64 value = GST_EVENT_DISCONT_OFFSET (event, 0).value;
gst_element_set_time (GST_ELEMENT (fakesink), value);
if (fakesink->sync && fakesink->clock) {
gint64 value = GST_EVENT_DISCONT_OFFSET (event, 0).value;
gst_element_set_time (GST_ELEMENT (fakesink), value);
}
default:
gst_pad_event_default (pad, event);
break;
break;
}
return;
}
if (fakesink->sync && fakesink->clock) {
if (fakesink->sync && fakesink->clock) {
gst_element_wait (GST_ELEMENT (fakesink), GST_BUFFER_TIMESTAMP (buf));
}
if (!fakesink->silent) {
if (!fakesink->silent) {
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, timestamp: %"
G_GINT64_FORMAT ", duration: %"
G_GINT64_FORMAT ", offset: %"
G_GINT64_FORMAT ", flags: %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf),
GST_BUFFER_TIMESTAMP (buf),
GST_BUFFER_DURATION (buf),
GST_BUFFER_OFFSET (buf),
GST_BUFFER_FLAGS (buf), buf);
fakesink->last_message =
g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, timestamp: %"
G_GINT64_FORMAT ", duration: %" G_GINT64_FORMAT ", offset: %"
G_GINT64_FORMAT ", flags: %d) %p", GST_DEBUG_PAD_NAME (pad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf),
GST_BUFFER_DURATION (buf), GST_BUFFER_OFFSET (buf),
GST_BUFFER_FLAGS (buf), buf);
g_object_notify (G_OBJECT (fakesink), "last_message");
}
if (fakesink->signal_handoffs)
g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0, buf, pad);
g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0,
buf, pad);
if (fakesink->dump) {
gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
@ -353,7 +366,7 @@ gst_fakesink_chain (GstPad *pad, GstData *_data)
}
static GstElementStateReturn
gst_fakesink_change_state (GstElement *element)
gst_fakesink_change_state (GstElement * element)
{
GstFakeSink *fakesink = GST_FAKESINK (element);
@ -395,4 +408,3 @@ error:
GST_ELEMENT_ERROR (element, CORE, STATE_CHANGE, (NULL), (NULL));
return GST_STATE_FAILURE;
}

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_FAKESINK \
(gst_fakesink_get_type())
#define GST_FAKESINK(obj) \
@ -39,8 +37,8 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FAKESINK))
#define GST_IS_FAKESINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FAKESINK))
typedef enum {
typedef enum
{
FAKESINK_STATE_ERROR_NONE = 0,
FAKESINK_STATE_ERROR_NULL_READY,
FAKESINK_STATE_ERROR_READY_PAUSED,
@ -53,30 +51,31 @@ typedef enum {
typedef struct _GstFakeSink GstFakeSink;
typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink {
GstElement element;
struct _GstFakeSink
{
GstElement element;
gboolean silent;
gboolean dump;
gboolean sync;
gboolean signal_handoffs;
GstClock *clock;
gboolean silent;
gboolean dump;
gboolean sync;
gboolean signal_handoffs;
GstClock *clock;
GstFakeSinkStateError state_error;
gchar *last_message;
gchar *last_message;
};
struct _GstFakeSinkClass {
struct _GstFakeSinkClass
{
GstElementClass parent_class;
/* signals */
void (*handoff) (GstElement *element, GstBuffer *buf, GstPad *pad);
void (*handoff) (GstElement * element, GstBuffer * buf, GstPad * pad);
};
GType gst_fakesink_get_type(void);
GType gst_fakesink_get_type (void);
gboolean gst_fakesink_factory_init (GstElementFactory *factory);
gboolean gst_fakesink_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_FAKESINK_H__ */

View file

@ -38,23 +38,23 @@
GST_DEBUG_CATEGORY_STATIC (gst_fakesrc_debug);
#define GST_CAT_DEFAULT gst_fakesrc_debug
GstElementDetails gst_fakesrc_details = GST_ELEMENT_DETAILS (
"Fake Source",
"Source",
"Push empty (no data) buffers around",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>"
);
GstElementDetails gst_fakesrc_details = GST_ELEMENT_DETAILS ("Fake Source",
"Source",
"Push empty (no data) buffers around",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>");
/* FakeSrc signals and args */
enum {
enum
{
/* FILL ME */
SIGNAL_HANDOFF,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_NUM_SOURCES,
ARG_LOOP_BASED,
@ -74,43 +74,42 @@ enum {
ARG_LAST_MESSAGE,
};
GstStaticPadTemplate fakesrc_src_template = GST_STATIC_PAD_TEMPLATE (
"src%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate fakesrc_src_template = GST_STATIC_PAD_TEMPLATE ("src%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
#define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
static GType
gst_fakesrc_output_get_type (void)
gst_fakesrc_output_get_type (void)
{
static GType fakesrc_output_type = 0;
static GEnumValue fakesrc_output[] = {
{ FAKESRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
{ FAKESRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
{ FAKESRC_PING_PONG, "3", "Ping-Pong"},
{ FAKESRC_ORDERED_RANDOM, "4", "Ordered Random"},
{ FAKESRC_RANDOM, "5", "Random"},
{ FAKESRC_PATTERN_LOOP, "6", "Patttern loop"},
{ FAKESRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
{ FAKESRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
{FAKESRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
{FAKESRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
{FAKESRC_PING_PONG, "3", "Ping-Pong"},
{FAKESRC_ORDERED_RANDOM, "4", "Ordered Random"},
{FAKESRC_RANDOM, "5", "Random"},
{FAKESRC_PATTERN_LOOP, "6", "Patttern loop"},
{FAKESRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
{FAKESRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
{0, NULL, NULL},
};
if (!fakesrc_output_type) {
fakesrc_output_type = g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
fakesrc_output_type =
g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
}
return fakesrc_output_type;
}
#define GST_TYPE_FAKESRC_DATA (gst_fakesrc_data_get_type())
static GType
gst_fakesrc_data_get_type (void)
gst_fakesrc_data_get_type (void)
{
static GType fakesrc_data_type = 0;
static GEnumValue fakesrc_data[] = {
{ FAKESRC_DATA_ALLOCATE, "1", "Allocate data"},
{ FAKESRC_DATA_SUBBUFFER, "2", "Subbuffer data"},
{FAKESRC_DATA_ALLOCATE, "1", "Allocate data"},
{FAKESRC_DATA_SUBBUFFER, "2", "Subbuffer data"},
{0, NULL, NULL},
};
if (!fakesrc_data_type) {
@ -121,36 +120,40 @@ gst_fakesrc_data_get_type (void)
#define GST_TYPE_FAKESRC_SIZETYPE (gst_fakesrc_sizetype_get_type())
static GType
gst_fakesrc_sizetype_get_type (void)
gst_fakesrc_sizetype_get_type (void)
{
static GType fakesrc_sizetype_type = 0;
static GEnumValue fakesrc_sizetype[] = {
{ FAKESRC_SIZETYPE_NULL, "1", "Send empty buffers"},
{ FAKESRC_SIZETYPE_FIXED, "2", "Fixed size buffers (sizemax sized)"},
{ FAKESRC_SIZETYPE_RANDOM, "3", "Random sized buffers (sizemin <= size <= sizemax)"},
{FAKESRC_SIZETYPE_NULL, "1", "Send empty buffers"},
{FAKESRC_SIZETYPE_FIXED, "2", "Fixed size buffers (sizemax sized)"},
{FAKESRC_SIZETYPE_RANDOM, "3",
"Random sized buffers (sizemin <= size <= sizemax)"},
{0, NULL, NULL},
};
if (!fakesrc_sizetype_type) {
fakesrc_sizetype_type = g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
fakesrc_sizetype_type =
g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
}
return fakesrc_sizetype_type;
}
#define GST_TYPE_FAKESRC_FILLTYPE (gst_fakesrc_filltype_get_type())
static GType
gst_fakesrc_filltype_get_type (void)
gst_fakesrc_filltype_get_type (void)
{
static GType fakesrc_filltype_type = 0;
static GEnumValue fakesrc_filltype[] = {
{ FAKESRC_FILLTYPE_NOTHING, "1", "Leave data as malloced"},
{ FAKESRC_FILLTYPE_NULL, "2", "Fill buffers with zeros"},
{ FAKESRC_FILLTYPE_RANDOM, "3", "Fill buffers with random crap"},
{ FAKESRC_FILLTYPE_PATTERN, "4", "Fill buffers with pattern 0x00 -> 0xff"},
{ FAKESRC_FILLTYPE_PATTERN_CONT, "5", "Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
{FAKESRC_FILLTYPE_NOTHING, "1", "Leave data as malloced"},
{FAKESRC_FILLTYPE_NULL, "2", "Fill buffers with zeros"},
{FAKESRC_FILLTYPE_RANDOM, "3", "Fill buffers with random crap"},
{FAKESRC_FILLTYPE_PATTERN, "4", "Fill buffers with pattern 0x00 -> 0xff"},
{FAKESRC_FILLTYPE_PATTERN_CONT, "5",
"Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
{0, NULL, NULL},
};
if (!fakesrc_filltype_type) {
fakesrc_filltype_type = g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
fakesrc_filltype_type =
g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
}
return fakesrc_filltype_type;
}
@ -158,106 +161,113 @@ gst_fakesrc_filltype_get_type (void)
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_fakesrc_debug, "fakesrc", 0, "fakesrc element");
GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT,
_do_init);
static GstPad* gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ,const gchar *unused);
static void gst_fakesrc_update_functions (GstFakeSrc *src);
static void gst_fakesrc_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_fakesrc_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * unused);
static void gst_fakesrc_update_functions (GstFakeSrc * src);
static void gst_fakesrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_fakesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstElementStateReturn gst_fakesrc_change_state (GstElement *element);
static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
static GstData* gst_fakesrc_get (GstPad *pad);
static void gst_fakesrc_loop (GstElement *element);
static GstData *gst_fakesrc_get (GstPad * pad);
static void gst_fakesrc_loop (GstElement * element);
static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
static void
gst_fakesrc_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_fakesrc_details);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&fakesrc_src_template));
}
static void
gst_fakesrc_class_init (GstFakeSrcClass *klass)
gst_fakesrc_class_init (GstFakeSrcClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
1, G_MAXINT, 1, G_PARAM_READABLE));
g_param_spec_int ("num-sources", "num-sources", "Number of sources",
1, G_MAXINT, 1, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
g_param_spec_boolean ("loop-based", "loop-based", "Enable loop-based operation",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("loop-based", "loop-based",
"Enable loop-based operation", FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
g_param_spec_enum ("output", "output", "Output method (currently unused)",
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
g_param_spec_enum ("output", "output", "Output method (currently unused)",
GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
g_param_spec_enum ("data", "data", "Data allocation method",
GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE));
g_param_spec_enum ("data", "data", "Data allocation method",
GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
g_param_spec_enum ("sizetype", "sizetype", "How to determine buffer sizes",
GST_TYPE_FAKESRC_SIZETYPE, FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE));
g_param_spec_enum ("sizetype", "sizetype",
"How to determine buffer sizes", GST_TYPE_FAKESRC_SIZETYPE,
FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
g_param_spec_int ("sizemin","sizemin","Minimum buffer size",
0, G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
g_param_spec_int ("sizemax","sizemax","Maximum buffer size",
0, G_MAXINT, DEFAULT_SIZEMAX, G_PARAM_READWRITE));
g_param_spec_int ("sizemax", "sizemax", "Maximum buffer size", 0,
G_MAXINT, DEFAULT_SIZEMAX, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
g_param_spec_int ("parentsize","parentsize","Size of parent buffer for sub-buffered allocation",
0, G_MAXINT, DEFAULT_PARENTSIZE, G_PARAM_READWRITE));
g_param_spec_int ("parentsize", "parentsize",
"Size of parent buffer for sub-buffered allocation", 0, G_MAXINT,
DEFAULT_PARENTSIZE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
g_param_spec_enum ("filltype", "filltype", "How to fill the buffer, if at all",
GST_TYPE_FAKESRC_FILLTYPE, FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
g_param_spec_enum ("filltype", "filltype",
"How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
g_param_spec_string ("pattern", "pattern", "pattern",
NULL, G_PARAM_READWRITE));
g_param_spec_string ("pattern", "pattern", "pattern", NULL,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
g_param_spec_int ("num-buffers", "num-buffers", "Number of buffers to output before sending EOS",
G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
g_param_spec_int ("num-buffers", "num-buffers",
"Number of buffers to output before sending EOS", G_MININT, G_MAXINT,
0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
g_param_spec_boolean ("eos", "eos", "Send out the EOS event?",
TRUE, G_PARAM_READWRITE));
g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "The last status message",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last-message", "last-message",
"The last status message", NULL, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "Silent", "Don't produce last_message events",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "Silent",
"Don't produce last_message events", FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIGNAL_HANDOFFS,
g_param_spec_boolean ("signal-handoffs", "Signal handoffs", "Send a signal before pushing the buffer",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
"Send a signal before pushing the buffer", FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
FALSE, G_PARAM_READWRITE));
gst_fakesrc_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
}
static void
gst_fakesrc_init (GstFakeSrc *fakesrc)
static void
gst_fakesrc_init (GstFakeSrc * fakesrc)
{
GstPad *pad;
@ -289,8 +299,9 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
fakesrc->last_message = NULL;
}
static GstPad*
gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
static GstPad *
gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
{
gchar *name;
GstPad *srcpad;
@ -317,7 +328,7 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ, const g
}
static const GstFormat *
gst_fakesrc_get_formats (GstPad *pad)
gst_fakesrc_get_formats (GstPad * pad)
{
static const GstFormat formats[] = {
GST_FORMAT_DEFAULT,
@ -327,7 +338,7 @@ gst_fakesrc_get_formats (GstPad *pad)
}
static const GstQueryType *
gst_fakesrc_get_query_types (GstPad *pad)
gst_fakesrc_get_query_types (GstPad * pad)
{
static const GstQueryType types[] = {
GST_QUERY_TOTAL,
@ -340,8 +351,8 @@ gst_fakesrc_get_query_types (GstPad *pad)
}
static gboolean
gst_fakesrc_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
gst_fakesrc_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad));
@ -360,24 +371,24 @@ gst_fakesrc_query (GstPad *pad, GstQueryType type,
break;
default:
return FALSE;
}
}
return TRUE;
}
static const GstEventMask *
gst_fakesrc_get_event_mask (GstPad *pad)
gst_fakesrc_get_event_mask (GstPad * pad)
{
static const GstEventMask masks[] = {
{ GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH },
{ GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP },
{ GST_EVENT_FLUSH, 0 },
{ 0, 0 },
{GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH},
{GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP},
{GST_EVENT_FLUSH, 0},
{0, 0},
};
return masks;
}
static gboolean
gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
gst_fakesrc_event_handler (GstPad * pad, GstEvent * event)
{
GstFakeSrc *src;
@ -388,14 +399,15 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
if (!GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) {
break;
break;
}
/* else we do a flush too */
case GST_EVENT_SEEK_SEGMENT:
src->segment_start = GST_EVENT_SEEK_OFFSET (event);
src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
src->buffer_count = src->segment_start;
src->segment_loop = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
src->segment_loop =
GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
break;
case GST_EVENT_FLUSH:
src->need_flush = TRUE;
@ -409,14 +421,14 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
}
static void
gst_fakesrc_update_functions (GstFakeSrc *src)
gst_fakesrc_update_functions (GstFakeSrc * src)
{
GList *pads;
if (src->loop_based) {
gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
}
else {
gst_element_set_loop_function (GST_ELEMENT (src),
GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
} else {
gst_element_set_loop_function (GST_ELEMENT (src), NULL);
}
@ -426,8 +438,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
if (src->loop_based) {
gst_pad_set_get_function (pad, NULL);
}
else {
} else {
gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
}
@ -441,7 +452,7 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
}
static void
gst_fakesrc_alloc_parent (GstFakeSrc *src)
gst_fakesrc_alloc_parent (GstFakeSrc * src)
{
GstBuffer *buf;
@ -454,13 +465,14 @@ gst_fakesrc_alloc_parent (GstFakeSrc *src)
}
static void
gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstFakeSrc *src;
/* it's not null if we got it, but it might not be ours */
src = GST_FAKESRC (object);
switch (prop_id) {
case ARG_LOOP_BASED:
src->loop_based = g_value_get_boolean (value);
@ -473,13 +485,13 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
src->data = g_value_get_enum (value);
if (src->data == FAKESRC_DATA_SUBBUFFER) {
if (!src->parent)
gst_fakesrc_alloc_parent (src);
if (!src->parent)
gst_fakesrc_alloc_parent (src);
} else {
if (src->parent) {
gst_buffer_unref (src->parent);
src->parent = NULL;
}
if (src->parent) {
gst_buffer_unref (src->parent);
src->parent = NULL;
}
}
break;
case ARG_SIZETYPE:
@ -504,7 +516,7 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
break;
case ARG_EOS:
src->eos = g_value_get_boolean (value);
GST_INFO ( "will EOS on next buffer");
GST_INFO ("will EOS on next buffer");
break;
case ARG_SILENT:
src->silent = g_value_get_boolean (value);
@ -520,16 +532,17 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
}
}
static void
gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFakeSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FAKESRC (object));
src = GST_FAKESRC (object);
switch (prop_id) {
case ARG_NUM_SOURCES:
g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
@ -586,9 +599,9 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
}
static void
gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf)
gst_fakesrc_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
{
if (GST_BUFFER_SIZE (buf) == 0)
if (GST_BUFFER_SIZE (buf) == 0)
return;
switch (src->filltype) {
@ -601,7 +614,7 @@ gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf)
guint8 *ptr = GST_BUFFER_DATA (buf);
for (i = GST_BUFFER_SIZE (buf); i; i--) {
*ptr++ = (gint8)((255.0)*rand()/(RAND_MAX));
*ptr++ = (gint8) ((255.0) * rand () / (RAND_MAX));
}
break;
}
@ -623,29 +636,29 @@ gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf)
}
}
static GstBuffer*
gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size)
static GstBuffer *
gst_fakesrc_alloc_buffer (GstFakeSrc * src, guint size)
{
GstBuffer *buf;
buf = gst_buffer_new ();
GST_BUFFER_SIZE(buf) = size;
GST_BUFFER_SIZE (buf) = size;
if (size != 0) {
if (size != 0) {
switch (src->filltype) {
case FAKESRC_FILLTYPE_NOTHING:
GST_BUFFER_DATA(buf) = g_malloc (size);
break;
GST_BUFFER_DATA (buf) = g_malloc (size);
break;
case FAKESRC_FILLTYPE_NULL:
GST_BUFFER_DATA(buf) = g_malloc0 (size);
break;
GST_BUFFER_DATA (buf) = g_malloc0 (size);
break;
case FAKESRC_FILLTYPE_RANDOM:
case FAKESRC_FILLTYPE_PATTERN:
case FAKESRC_FILLTYPE_PATTERN_CONT:
default:
GST_BUFFER_DATA(buf) = g_malloc (size);
gst_fakesrc_prepare_buffer (src, buf);
break;
GST_BUFFER_DATA (buf) = g_malloc (size);
gst_fakesrc_prepare_buffer (src, buf);
break;
}
}
@ -653,7 +666,7 @@ gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size)
}
static guint
gst_fakesrc_get_size (GstFakeSrc *src)
gst_fakesrc_get_size (GstFakeSrc * src)
{
guint size;
@ -662,11 +675,14 @@ gst_fakesrc_get_size (GstFakeSrc *src)
size = src->sizemax;
break;
case FAKESRC_SIZETYPE_RANDOM:
size = src->sizemin + (guint8)(((gfloat)src->sizemax)*rand()/(RAND_MAX + (gfloat)src->sizemin));
size =
src->sizemin +
(guint8) (((gfloat) src->sizemax) * rand () / (RAND_MAX +
(gfloat) src->sizemin));
break;
case FAKESRC_SIZETYPE_NULL:
default:
size = 0;
size = 0;
break;
}
@ -674,7 +690,7 @@ gst_fakesrc_get_size (GstFakeSrc *src)
}
static GstBuffer *
gst_fakesrc_create_buffer (GstFakeSrc *src)
gst_fakesrc_create_buffer (GstFakeSrc * src)
{
GstBuffer *buf;
guint size;
@ -682,7 +698,7 @@ gst_fakesrc_create_buffer (GstFakeSrc *src)
size = gst_fakesrc_get_size (src);
if (size == 0)
return gst_buffer_new();
return gst_buffer_new ();
switch (src->data) {
case FAKESRC_DATA_ALLOCATE:
@ -696,21 +712,20 @@ gst_fakesrc_create_buffer (GstFakeSrc *src)
}
/* see if it's large enough */
if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
src->parentoffset += size;
}
else {
buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
src->parentoffset += size;
} else {
/* the parent is useless now */
gst_buffer_unref (src->parent);
src->parent = NULL;
/* try again (this will allocate a new parent) */
return gst_fakesrc_create_buffer (src);
return gst_fakesrc_create_buffer (src);
}
gst_fakesrc_prepare_buffer (src, buf);
break;
default:
g_warning ("fakesrc: dunno how to allocate buffers !");
buf = gst_buffer_new();
buf = gst_buffer_new ();
break;
}
if (dump) {
@ -721,7 +736,7 @@ gst_fakesrc_create_buffer (GstFakeSrc *src)
}
static GstData *
gst_fakesrc_get(GstPad *pad)
gst_fakesrc_get (GstPad * pad)
{
GstFakeSrc *src;
GstBuffer *buf;
@ -734,31 +749,29 @@ gst_fakesrc_get(GstPad *pad)
if (src->need_flush) {
src->need_flush = FALSE;
return GST_DATA(gst_event_new (GST_EVENT_FLUSH));
return GST_DATA (gst_event_new (GST_EVENT_FLUSH));
}
if (src->buffer_count == src->segment_end) {
if (src->segment_loop) {
return GST_DATA(gst_event_new (GST_EVENT_SEGMENT_DONE));
}
else {
return GST_DATA (gst_event_new (GST_EVENT_SEGMENT_DONE));
} else {
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA(gst_event_new (GST_EVENT_EOS));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
}
if (src->rt_num_buffers == 0) {
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA(gst_event_new (GST_EVENT_EOS));
}
else {
return GST_DATA (gst_event_new (GST_EVENT_EOS));
} else {
if (src->rt_num_buffers > 0)
src->rt_num_buffers--;
}
if (src->eos) {
GST_INFO ( "fakesrc is setting eos on pad");
return GST_DATA(gst_event_new (GST_EVENT_EOS));
GST_INFO ("fakesrc is setting eos on pad");
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
buf = gst_fakesrc_create_buffer (src);
@ -767,9 +780,10 @@ gst_fakesrc_get(GstPad *pad)
if (!src->silent) {
g_free (src->last_message);
src->last_message = g_strdup_printf ("get ******* (%s:%s)> (%d bytes, %"
G_GUINT64_FORMAT " ) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
src->last_message =
g_strdup_printf ("get ******* (%s:%s)> (%d bytes, %"
G_GUINT64_FORMAT " ) %p", GST_DEBUG_PAD_NAME (pad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
g_object_notify (G_OBJECT (src), "last_message");
}
@ -777,7 +791,7 @@ gst_fakesrc_get(GstPad *pad)
if (src->signal_handoffs) {
GST_LOG_OBJECT (src, "pre handoff emit");
g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
buf, pad);
buf, pad);
GST_LOG_OBJECT (src, "post handoff emit");
}
@ -791,13 +805,13 @@ gst_fakesrc_get(GstPad *pad)
* generate an empty buffer and push it to the next element.
*/
static void
gst_fakesrc_loop(GstElement *element)
gst_fakesrc_loop (GstElement * element)
{
GstFakeSrc *src;
const GList *pads;
g_return_if_fail(element != NULL);
g_return_if_fail(GST_IS_FAKESRC(element));
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_FAKESRC (element));
src = GST_FAKESRC (element);
@ -819,7 +833,7 @@ gst_fakesrc_loop(GstElement *element)
}
static GstElementStateReturn
gst_fakesrc_change_state (GstElement *element)
gst_fakesrc_change_state (GstElement * element)
{
GstFakeSrc *fakesrc;
@ -842,8 +856,8 @@ gst_fakesrc_change_state (GstElement *element)
break;
case GST_STATE_PAUSED_TO_READY:
if (fakesrc->parent) {
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
gst_buffer_unref (fakesrc->parent);
fakesrc->parent = NULL;
}
g_free (fakesrc->last_message);
fakesrc->last_message = NULL;
@ -860,4 +874,3 @@ gst_fakesrc_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}

View file

@ -26,10 +26,8 @@
#include <gst/gst.h>
G_BEGIN_DECLS
typedef enum {
G_BEGIN_DECLS typedef enum
{
FAKESRC_FIRST_LAST_LOOP = 1,
FAKESRC_LAST_FIRST_LOOP,
FAKESRC_PING_PONG,
@ -40,18 +38,21 @@ typedef enum {
FAKESRC_GET_ALWAYS_SUCEEDS
} GstFakeSrcOutputType;
typedef enum {
typedef enum
{
FAKESRC_DATA_ALLOCATE = 1,
FAKESRC_DATA_SUBBUFFER,
} GstFakeSrcDataType;
typedef enum {
typedef enum
{
FAKESRC_SIZETYPE_NULL = 1,
FAKESRC_SIZETYPE_FIXED,
FAKESRC_SIZETYPE_RANDOM
} GstFakeSrcSizeType;
typedef enum {
typedef enum
{
FAKESRC_FILLTYPE_NOTHING = 1,
FAKESRC_FILLTYPE_NULL,
FAKESRC_FILLTYPE_RANDOM,
@ -73,50 +74,51 @@ typedef enum {
typedef struct _GstFakeSrc GstFakeSrc;
typedef struct _GstFakeSrcClass GstFakeSrcClass;
struct _GstFakeSrc {
GstElement element;
struct _GstFakeSrc
{
GstElement element;
gboolean loop_based;
gboolean eos;
gboolean loop_based;
gboolean eos;
GstFakeSrcOutputType output;
GstFakeSrcDataType data;
GstFakeSrcSizeType sizetype;
GstFakeSrcFillType filltype;
GstFakeSrcDataType data;
GstFakeSrcSizeType sizetype;
GstFakeSrcFillType filltype;
guint sizemin;
guint sizemax;
GstBuffer *parent;
guint parentsize;
guint parentoffset;
guint8 pattern_byte;
gchar *pattern;
GList *patternlist;
gint64 segment_start;
gint64 segment_end;
gboolean segment_loop;
gint num_buffers;
gint rt_num_buffers; /* we are going to change this at runtime */
guint64 buffer_count;
gboolean silent;
gboolean signal_handoffs;
gboolean dump;
gboolean need_flush;
guint sizemin;
guint sizemax;
GstBuffer *parent;
guint parentsize;
guint parentoffset;
guint8 pattern_byte;
gchar *pattern;
GList *patternlist;
gint64 segment_start;
gint64 segment_end;
gboolean segment_loop;
gint num_buffers;
gint rt_num_buffers; /* we are going to change this at runtime */
guint64 buffer_count;
gboolean silent;
gboolean signal_handoffs;
gboolean dump;
gboolean need_flush;
gchar *last_message;
gchar *last_message;
};
struct _GstFakeSrcClass {
struct _GstFakeSrcClass
{
GstElementClass parent_class;
/* signals */
void (*handoff) (GstElement *element, GstBuffer *buf, GstPad *pad);
void (*handoff) (GstElement * element, GstBuffer * buf, GstPad * pad);
};
GType gst_fakesrc_get_type(void);
GType gst_fakesrc_get_type (void);
gboolean gst_fakesrc_factory_init (GstElementFactory *factory);
gboolean gst_fakesrc_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_FAKESRC_H__ */

View file

@ -30,21 +30,22 @@
GST_DEBUG_CATEGORY_STATIC (gst_fdsink_debug);
#define GST_CAT_DEFAULT gst_fdsink_debug
GstElementDetails gst_fdsink_details = GST_ELEMENT_DETAILS (
"Filedescriptor Sink",
"Sink/File",
"Write data to a file descriptor",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
GstElementDetails gst_fdsink_details =
GST_ELEMENT_DETAILS ("Filedescriptor Sink",
"Sink/File",
"Write data to a file descriptor",
"Erik Walthinsen <omega@cse.ogi.edu>");
/* FdSink signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_FD
};
@ -53,25 +54,26 @@ enum {
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_fdsink_debug, "fdsink", 0, "fdsink element");
GST_BOILERPLATE_FULL (GstFdSink, gst_fdsink, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFdSink, gst_fdsink, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void gst_fdsink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_fdsink_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_fdsink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_fdsink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_fdsink_chain (GstPad *pad,GstData *_data);
static void gst_fdsink_chain (GstPad * pad, GstData * _data);
static void
gst_fdsink_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_fdsink_details);
}
static void
gst_fdsink_class_init (GstFdSinkClass *klass)
gst_fdsink_class_init (GstFdSinkClass * klass)
{
GObjectClass *gobject_class;
@ -79,15 +81,15 @@ gst_fdsink_class_init (GstFdSinkClass *klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FD,
g_param_spec_int ("fd", "fd", "An open file descriptor to write to",
0, G_MAXINT, 1, G_PARAM_READWRITE));
g_param_spec_int ("fd", "fd", "An open file descriptor to write to",
0, G_MAXINT, 1, G_PARAM_READWRITE));
gobject_class->set_property = gst_fdsink_set_property;
gobject_class->get_property = gst_fdsink_get_property;
}
static void
gst_fdsink_init (GstFdSink *fdsink)
static void
gst_fdsink_init (GstFdSink * fdsink)
{
fdsink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (fdsink), fdsink->sinkpad);
@ -96,8 +98,8 @@ gst_fdsink_init (GstFdSink *fdsink)
fdsink->fd = 1;
}
static void
gst_fdsink_chain (GstPad *pad, GstData *_data)
static void
gst_fdsink_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstFdSink *fdsink;
@ -107,25 +109,27 @@ gst_fdsink_chain (GstPad *pad, GstData *_data)
g_return_if_fail (buf != NULL);
fdsink = GST_FDSINK (gst_pad_get_parent (pad));
g_return_if_fail (fdsink->fd >= 0);
if (GST_BUFFER_DATA (buf)) {
GST_DEBUG ("writing %d bytes to file descriptor %d",GST_BUFFER_SIZE (buf), fdsink->fd);
GST_DEBUG ("writing %d bytes to file descriptor %d", GST_BUFFER_SIZE (buf),
fdsink->fd);
write (fdsink->fd, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
}
gst_buffer_unref (buf);
}
static void
gst_fdsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void
gst_fdsink_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstFdSink *fdsink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FDSINK (object));
fdsink = GST_FDSINK (object);
switch (prop_id) {
@ -137,14 +141,15 @@ gst_fdsink_set_property (GObject *object, guint prop_id, const GValue *value, GP
}
}
static void
gst_fdsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_fdsink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFdSink *fdsink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FDSINK (object));
fdsink = GST_FDSINK (object);
switch (prop_id) {

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_FDSINK \
(gst_fdsink_get_type())
#define GST_FDSINK(obj) \
@ -39,11 +37,11 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FDSINK))
#define GST_IS_FDSINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FDSINK))
typedef struct _GstFdSink GstFdSink;
typedef struct _GstFdSinkClass GstFdSinkClass;
struct _GstFdSink {
struct _GstFdSink
{
GstElement element;
GstPad *sinkpad;
@ -51,12 +49,12 @@ struct _GstFdSink {
int fd;
};
struct _GstFdSinkClass {
struct _GstFdSinkClass
{
GstElementClass parent_class;
};
GType gst_fdsink_get_type(void);
GType gst_fdsink_get_type (void);
G_END_DECLS
#endif /* __GST_FDSINK_H__ */

View file

@ -39,21 +39,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_fdsrc_debug);
#define GST_CAT_DEFAULT gst_fdsrc_debug
GstElementDetails gst_fdsrc_details = GST_ELEMENT_DETAILS (
"Disk Source",
"Source/File",
"Synchronous read from a file",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
GstElementDetails gst_fdsrc_details = GST_ELEMENT_DETAILS ("Disk Source",
"Source/File",
"Synchronous read from a file",
"Erik Walthinsen <omega@cse.ogi.edu>");
/* FdSrc signals and args */
enum {
enum
{
SIGNAL_TIMEOUT,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_FD,
ARG_BLOCKSIZE,
@ -65,52 +65,56 @@ static guint gst_fdsrc_signals[LAST_SIGNAL] = { 0 };
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_fdsrc_debug, "fdsrc", 0, "fdsrc element");
GST_BOILERPLATE_FULL (GstFdSrc, gst_fdsrc, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFdSrc, gst_fdsrc, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void gst_fdsrc_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_fdsrc_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_fdsrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_fdsrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstData * gst_fdsrc_get (GstPad *pad);
static GstData *gst_fdsrc_get (GstPad * pad);
static void
gst_fdsrc_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_fdsrc_details);
}
static void
gst_fdsrc_class_init (GstFdSrcClass *klass)
gst_fdsrc_class_init (GstFdSrcClass * klass)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (klass);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FD,
g_param_spec_int ("fd", "fd", "An open file descriptor to read from",
0, G_MAXINT, 0, G_PARAM_READWRITE));
g_param_spec_int ("fd", "fd", "An open file descriptor to read from",
0, G_MAXINT, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCKSIZE,
g_param_spec_ulong ("blocksize", "Block size", "Size in bytes to read per buffer",
1, G_MAXULONG, DEFAULT_BLOCKSIZE, G_PARAM_READWRITE));
g_param_spec_ulong ("blocksize", "Block size",
"Size in bytes to read per buffer", 1, G_MAXULONG, DEFAULT_BLOCKSIZE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TIMEOUT,
g_param_spec_uint64 ("timeout", "Timeout", "Read timeout in nanoseconds",
0, G_MAXUINT64, 0, G_PARAM_READWRITE));
g_param_spec_uint64 ("timeout", "Timeout", "Read timeout in nanoseconds",
0, G_MAXUINT64, 0, G_PARAM_READWRITE));
gst_fdsrc_signals[SIGNAL_TIMEOUT] =
g_signal_new ("timeout", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFdSrcClass, timeout), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_signal_new ("timeout", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFdSrcClass, timeout), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gobject_class->set_property = gst_fdsrc_set_property;
gobject_class->get_property = gst_fdsrc_get_property;
}
static void gst_fdsrc_init(GstFdSrc *fdsrc) {
static void
gst_fdsrc_init (GstFdSrc * fdsrc)
{
fdsrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (fdsrc->srcpad, gst_fdsrc_get);
gst_element_add_pad (GST_ELEMENT (fdsrc), fdsrc->srcpad);
@ -122,14 +126,15 @@ static void gst_fdsrc_init(GstFdSrc *fdsrc) {
}
static void
gst_fdsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void
gst_fdsrc_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstFdSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FDSRC (object));
src = GST_FDSRC (object);
switch (prop_id) {
@ -147,14 +152,15 @@ gst_fdsrc_set_property (GObject *object, guint prop_id, const GValue *value, GPa
}
}
static void
gst_fdsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_fdsrc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFdSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FDSRC (object));
src = GST_FDSRC (object);
switch (prop_id) {
@ -174,7 +180,7 @@ gst_fdsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe
}
static GstData *
gst_fdsrc_get(GstPad *pad)
gst_fdsrc_get (GstPad * pad)
{
GstFdSrc *src;
GstBuffer *buf;
@ -191,38 +197,31 @@ gst_fdsrc_get(GstPad *pad)
FD_ZERO (&readfds);
FD_SET (src->fd, &readfds);
if (src->timeout != 0)
{
if (src->timeout != 0) {
GST_TIME_TO_TIMEVAL (src->timeout, t);
}
else
} else
tp = NULL;
do
{
do {
retval = select (1, &readfds, NULL, NULL, tp);
} while (retval == -1 && errno == EINTR); /* retry if interrupted */
} while (retval == -1 && errno == EINTR); /* retry if interrupted */
if (retval == -1)
{
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("select on file descriptor: %s.", g_strerror(errno)));
if (retval == -1) {
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("select on file descriptor: %s.", g_strerror (errno)));
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
} else if (retval == 0) {
g_signal_emit (G_OBJECT (src), gst_fdsrc_signals[SIGNAL_TIMEOUT], 0);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
else if (retval == 0)
{
g_signal_emit (G_OBJECT (src), gst_fdsrc_signals[SIGNAL_TIMEOUT], 0);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA(gst_event_new (GST_EVENT_EOS));
}
do
{
do {
readbytes = read (src->fd, GST_BUFFER_DATA (buf), src->blocksize);
} while (readbytes == -1 && errno == EINTR); /* retry if interrupted */
} while (readbytes == -1 && errno == EINTR); /* retry if interrupted */
if (readbytes > 0)
{
if (readbytes > 0) {
GST_BUFFER_OFFSET (buf) = src->curoffset;
GST_BUFFER_SIZE (buf) = readbytes;
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
@ -230,15 +229,12 @@ gst_fdsrc_get(GstPad *pad)
/* we're done, return the buffer */
return GST_DATA (buf);
}
else if (readbytes == 0)
{
} else if (readbytes == 0) {
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
else
{
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("read on file descriptor: %s.", g_strerror(errno)));
} else {
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("read on file descriptor: %s.", g_strerror (errno)));
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_FDSRC \
(gst_fdsrc_get_type())
#define GST_FDSRC(obj) \
@ -39,12 +37,11 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FDSRC))
#define GST_IS_FDSRC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FDSRC))
typedef struct _GstFdSrc GstFdSrc;
typedef struct _GstFdSrcClass GstFdSrcClass;
struct _GstFdSrc {
struct _GstFdSrc
{
GstElement element;
/* pads */
GstPad *srcpad;
@ -52,22 +49,22 @@ struct _GstFdSrc {
/* fd */
gint fd;
gulong curoffset; /* current offset in file */
gulong blocksize; /* bytes per read */
guint64 timeout; /* read timeout, in nanoseconds */
gulong seq; /* buffer sequence number */
gulong curoffset; /* current offset in file */
gulong blocksize; /* bytes per read */
guint64 timeout; /* read timeout, in nanoseconds */
gulong seq; /* buffer sequence number */
};
struct _GstFdSrcClass {
struct _GstFdSrcClass
{
GstElementClass parent_class;
/* signals */
void (*timeout) (GstElement *element);
void (*timeout) (GstElement * element);
};
GType gst_fdsrc_get_type(void);
GType gst_fdsrc_get_type (void);
G_END_DECLS
#endif /* __GST_FDSRC_H__ */

View file

@ -39,28 +39,28 @@
GST_DEBUG_CATEGORY_STATIC (gst_filesink_debug);
#define GST_CAT_DEFAULT gst_filesink_debug
GstElementDetails gst_filesink_details = GST_ELEMENT_DETAILS (
"File Sink",
"Sink/File",
"Write stream to a file",
"Thomas <thomas@apestaart.org>"
);
GstElementDetails gst_filesink_details = GST_ELEMENT_DETAILS ("File Sink",
"Sink/File",
"Write stream to a file",
"Thomas <thomas@apestaart.org>");
/* FileSink signals and args */
enum {
enum
{
/* FILL ME */
SIGNAL_HANDOFF,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_LOCATION
};
static const GstFormat *
gst_filesink_get_formats (GstPad *pad)
gst_filesink_get_formats (GstPad * pad)
{
static const GstFormat formats[] = {
GST_FORMAT_BYTES,
@ -70,7 +70,7 @@ gst_filesink_get_formats (GstPad *pad)
}
static const GstQueryType *
gst_filesink_get_query_types (GstPad *pad)
gst_filesink_get_query_types (GstPad * pad)
{
static const GstQueryType types[] = {
GST_QUERY_TOTAL,
@ -80,24 +80,25 @@ gst_filesink_get_query_types (GstPad *pad)
return types;
}
static void gst_filesink_dispose (GObject *object);
static void gst_filesink_dispose (GObject * object);
static void gst_filesink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_filesink_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_filesink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_filesink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_filesink_open_file (GstFileSink *sink);
static void gst_filesink_close_file (GstFileSink *sink);
static gboolean gst_filesink_open_file (GstFileSink * sink);
static void gst_filesink_close_file (GstFileSink * sink);
static gboolean gst_filesink_handle_event (GstPad *pad, GstEvent *event);
static gboolean gst_filesink_pad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value);
static void gst_filesink_chain (GstPad *pad,GstData *_data);
static gboolean gst_filesink_handle_event (GstPad * pad, GstEvent * event);
static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value);
static void gst_filesink_chain (GstPad * pad, GstData * _data);
static void gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstElementStateReturn gst_filesink_change_state (GstElement *element);
static void gst_filesink_uri_handler_init (gpointer g_iface,
gpointer iface_data);
static GstElementStateReturn gst_filesink_change_state (GstElement * element);
static guint gst_filesink_signals[LAST_SIGNAL] = { 0 };
@ -109,12 +110,15 @@ _do_init (GType filesink_type)
NULL,
NULL
};
g_type_add_interface_static (filesink_type, GST_TYPE_URI_HANDLER, &urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesink_debug, "filesink", 0, "filesink element");
g_type_add_interface_static (filesink_type, GST_TYPE_URI_HANDLER,
&urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesink_debug, "filesink", 0,
"filesink element");
}
GST_BOILERPLATE_FULL (GstFileSink, gst_filesink, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFileSink, gst_filesink, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void
gst_filesink_base_init (gpointer g_class)
@ -125,26 +129,26 @@ gst_filesink_base_init (gpointer g_class)
gst_element_class_set_details (gstelement_class, &gst_filesink_details);
}
static void
gst_filesink_class_init (GstFileSinkClass *klass)
gst_filesink_class_init (GstFileSinkClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
g_param_spec_string ("location", "File Location", "Location of the file to write",
NULL, G_PARAM_READWRITE));
g_param_spec_string ("location", "File Location",
"Location of the file to write", NULL, G_PARAM_READWRITE));
gst_filesink_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFileSinkClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFileSinkClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gobject_class->set_property = gst_filesink_set_property;
gobject_class->get_property = gst_filesink_get_property;
gobject_class->dispose = gst_filesink_dispose;
gobject_class->dispose = gst_filesink_dispose;
}
static void
gst_filesink_init (GstFileSink *filesink)
static void
gst_filesink_init (GstFileSink * filesink)
{
GstPad *pad;
@ -152,7 +156,7 @@ gst_filesink_init (GstFileSink *filesink)
gst_element_add_pad (GST_ELEMENT (filesink), pad);
gst_pad_set_chain_function (pad, gst_filesink_chain);
GST_FLAG_SET (GST_ELEMENT(filesink), GST_ELEMENT_EVENT_AWARE);
GST_FLAG_SET (GST_ELEMENT (filesink), GST_ELEMENT_EVENT_AWARE);
gst_pad_set_query_function (pad, gst_filesink_pad_query);
gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
@ -162,19 +166,20 @@ gst_filesink_init (GstFileSink *filesink)
filesink->file = NULL;
}
static void
gst_filesink_dispose (GObject *object)
gst_filesink_dispose (GObject * object)
{
GstFileSink *sink = GST_FILESINK (object);
G_OBJECT_CLASS (parent_class)->dispose (object);
g_free (sink->uri);
sink->uri = NULL;
g_free (sink->filename);
sink->filename = NULL;
}
static gboolean
gst_filesink_set_location (GstFileSink *sink, const gchar *location)
gst_filesink_set_location (GstFileSink * sink, const gchar * location)
{
/* the element must be stopped or paused in order to do this */
if (GST_STATE (sink) > GST_STATE_PAUSED)
@ -192,14 +197,15 @@ gst_filesink_set_location (GstFileSink *sink, const gchar *location)
sink->filename = NULL;
sink->uri = NULL;
}
if (GST_STATE (sink) == GST_STATE_PAUSED)
gst_filesink_open_file (sink);
return TRUE;
}
static void
gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_filesink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstFileSink *sink;
@ -216,16 +222,17 @@ gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value,
}
}
static void
gst_filesink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_filesink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFileSink *sink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_FILESINK (object));
sink = GST_FILESINK (object);
switch (prop_id) {
case ARG_LOCATION:
g_value_set_string (value, sink->filename);
@ -237,23 +244,22 @@ gst_filesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
}
static gboolean
gst_filesink_open_file (GstFileSink *sink)
gst_filesink_open_file (GstFileSink * sink)
{
g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN), FALSE);
/* open the file */
if (sink->filename == NULL || sink->filename[0] == '\0')
{
if (sink->filename == NULL || sink->filename[0] == '\0') {
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
(_("No file name specified for writing.")), (NULL));
(_("No file name specified for writing.")), (NULL));
return FALSE;
}
sink->file = fopen (sink->filename, "w");
if (sink->file == NULL) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
(_("Could not open file \"%s\" for writing."), sink->filename),
GST_ERROR_SYSTEM);
(_("Could not open file \"%s\" for writing."), sink->filename),
GST_ERROR_SYSTEM);
return FALSE;
}
@ -265,24 +271,21 @@ gst_filesink_open_file (GstFileSink *sink)
}
static void
gst_filesink_close_file (GstFileSink *sink)
gst_filesink_close_file (GstFileSink * sink)
{
g_return_if_fail (GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN));
if (fclose (sink->file) != 0)
{
if (fclose (sink->file) != 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
(_("Error closing file \"%s\"."), sink->filename),
GST_ERROR_SYSTEM);
}
else {
(_("Error closing file \"%s\"."), sink->filename), GST_ERROR_SYSTEM);
} else {
GST_FLAG_UNSET (sink, GST_FILESINK_OPEN);
}
}
static gboolean
gst_filesink_pad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
gst_filesink_pad_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
@ -290,23 +293,23 @@ gst_filesink_pad_query (GstPad *pad, GstQueryType type,
case GST_QUERY_TOTAL:
switch (*format) {
case GST_FORMAT_BYTES:
if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
*value = sink->data_written; /* FIXME - doesn't the kernel provide
such a function? */
break;
}
default:
if (GST_FLAG_IS_SET (GST_ELEMENT (sink), GST_FILESINK_OPEN)) {
*value = sink->data_written; /* FIXME - doesn't the kernel provide
such a function? */
break;
}
default:
return FALSE;
}
break;
case GST_QUERY_POSITION:
switch (*format) {
case GST_FORMAT_BYTES:
if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
*value = ftell (sink->file);
break;
}
default:
if (GST_FLAG_IS_SET (GST_ELEMENT (sink), GST_FILESINK_OPEN)) {
*value = ftell (sink->file);
break;
}
default:
return FALSE;
}
break;
@ -319,60 +322,58 @@ gst_filesink_pad_query (GstPad *pad, GstQueryType type,
/* handle events (search) */
static gboolean
gst_filesink_handle_event (GstPad *pad, GstEvent *event)
gst_filesink_handle_event (GstPad * pad, GstEvent * event)
{
GstEventType type;
GstFileSink *filesink;
filesink = GST_FILESINK (gst_pad_get_parent (pad));
g_return_val_if_fail (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN),
FALSE);
g_return_val_if_fail (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN), FALSE);
type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
switch (type) {
case GST_EVENT_SEEK:
g_return_val_if_fail (GST_EVENT_SEEK_FORMAT (event) == GST_FORMAT_BYTES,
FALSE);
FALSE);
if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
if (fflush (filesink->file))
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
GST_ERROR_SYSTEM);
if (fflush (filesink->file))
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
GST_ERROR_SYSTEM);
switch (GST_EVENT_SEEK_METHOD(event))
{
case GST_SEEK_METHOD_SET:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
break;
case GST_SEEK_METHOD_CUR:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
break;
case GST_SEEK_METHOD_END:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
break;
default:
g_warning ("unknown seek method!");
break;
switch (GST_EVENT_SEEK_METHOD (event)) {
case GST_SEEK_METHOD_SET:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
break;
case GST_SEEK_METHOD_CUR:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
break;
case GST_SEEK_METHOD_END:
fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
break;
default:
g_warning ("unknown seek method!");
break;
}
break;
case GST_EVENT_DISCONTINUOUS:
{
gint64 offset;
if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &offset))
fseek (filesink->file, offset, SEEK_SET);
fseek (filesink->file, offset, SEEK_SET);
gst_event_unref (event);
break;
}
case GST_EVENT_FLUSH:
if (fflush (filesink->file)) {
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
GST_ERROR_SYSTEM);
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
GST_ERROR_SYSTEM);
}
break;
case GST_EVENT_EOS:
@ -394,8 +395,8 @@ gst_filesink_handle_event (GstPad *pad, GstEvent *event)
*
* take the buffer from the pad and write to file if it's open
*/
static void
gst_filesink_chain (GstPad *pad, GstData *_data)
static void
gst_filesink_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstFileSink *filesink;
@ -406,27 +407,26 @@ gst_filesink_chain (GstPad *pad, GstData *_data)
filesink = GST_FILESINK (gst_pad_get_parent (pad));
if (GST_IS_EVENT(buf))
{
gst_filesink_handle_event(pad, GST_EVENT(buf));
if (GST_IS_EVENT (buf)) {
gst_filesink_handle_event (pad, GST_EVENT (buf));
return;
}
if (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN))
{
if (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN)) {
guint bytes_written = 0, back_pending = 0;
if (ftell(filesink->file) < filesink->data_written)
back_pending = filesink->data_written - ftell(filesink->file);
if (ftell (filesink->file) < filesink->data_written)
back_pending = filesink->data_written - ftell (filesink->file);
while (bytes_written < GST_BUFFER_SIZE (buf)) {
size_t wrote = fwrite (GST_BUFFER_DATA (buf) + bytes_written, 1,
GST_BUFFER_SIZE (buf) - bytes_written,
filesink->file);
GST_BUFFER_SIZE (buf) - bytes_written,
filesink->file);
if (wrote <= 0) {
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
("Only %d of %d bytes written: %s",
bytes_written, GST_BUFFER_SIZE (buf),
strerror (errno)));
GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filesink->filename),
("Only %d of %d bytes written: %s",
bytes_written, GST_BUFFER_SIZE (buf), strerror (errno)));
break;
}
bytes_written += wrote;
@ -438,25 +438,24 @@ gst_filesink_chain (GstPad *pad, GstData *_data)
gst_buffer_unref (buf);
g_signal_emit (G_OBJECT (filesink),
gst_filesink_signals[SIGNAL_HANDOFF], 0,
filesink);
gst_filesink_signals[SIGNAL_HANDOFF], 0, filesink);
}
static GstElementStateReturn
gst_filesink_change_state (GstElement *element)
gst_filesink_change_state (GstElement * element)
{
g_return_val_if_fail (GST_IS_FILESINK (element), GST_STATE_FAILURE);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY:
if (GST_FLAG_IS_SET (element, GST_FILESINK_OPEN))
gst_filesink_close_file (GST_FILESINK (element));
gst_filesink_close_file (GST_FILESINK (element));
break;
case GST_STATE_READY_TO_PAUSED:
if (!GST_FLAG_IS_SET (element, GST_FILESINK_OPEN)) {
if (!gst_filesink_open_file (GST_FILESINK (element)))
return GST_STATE_FAILURE;
if (!gst_filesink_open_file (GST_FILESINK (element)))
return GST_STATE_FAILURE;
}
break;
}
@ -475,20 +474,21 @@ gst_filesink_uri_get_type (void)
return GST_URI_SINK;
}
static gchar **
gst_filesink_uri_get_protocols(void)
gst_filesink_uri_get_protocols (void)
{
static gchar *protocols[] = {"file", NULL};
static gchar *protocols[] = { "file", NULL };
return protocols;
}
static const gchar *
gst_filesink_uri_get_uri (GstURIHandler *handler)
gst_filesink_uri_get_uri (GstURIHandler * handler)
{
GstFileSink *sink = GST_FILESINK (handler);
return sink->uri;
}
static gboolean
gst_filesink_uri_set_uri (GstURIHandler *handler, const gchar *uri)
gst_filesink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
gchar *protocol, *location;
gboolean ret;

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_FILESINK \
(gst_filesink_get_type())
#define GST_FILESINK(obj) \
@ -39,17 +37,18 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FILESINK))
#define GST_IS_FILESINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FILESINK))
typedef struct _GstFileSink GstFileSink;
typedef struct _GstFileSinkClass GstFileSinkClass;
typedef enum {
GST_FILESINK_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum
{
GST_FILESINK_OPEN = GST_ELEMENT_FLAG_LAST,
GST_FILESINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
GST_FILESINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
} GstFileSinkFlags;
struct _GstFileSink {
struct _GstFileSink
{
GstElement element;
gchar *filename;
@ -59,15 +58,15 @@ struct _GstFileSink {
guint64 data_written;
};
struct _GstFileSinkClass {
struct _GstFileSinkClass
{
GstElementClass parent_class;
/* signals */
void (*handoff) (GstElement *element, GstPad *pad);
void (*handoff) (GstElement * element, GstPad * pad);
};
GType gst_filesink_get_type(void);
GType gst_filesink_get_type (void);
G_END_DECLS
#endif /* __GST_FILESINK_H__ */

View file

@ -77,23 +77,23 @@
GST_DEBUG_CATEGORY_STATIC (gst_filesrc_debug);
#define GST_CAT_DEFAULT gst_filesrc_debug
GstElementDetails gst_filesrc_details = GST_ELEMENT_DETAILS (
"File Source",
"Source/File",
"Read from arbitrary point in a file",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
GstElementDetails gst_filesrc_details = GST_ELEMENT_DETAILS ("File Source",
"Source/File",
"Read from arbitrary point in a file",
"Erik Walthinsen <omega@cse.ogi.edu>");
#define DEFAULT_BLOCKSIZE 4*1024
#define DEFAULT_MMAPSIZE 4*1024*1024
/* FileSrc signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_LOCATION,
ARG_FD,
@ -103,22 +103,20 @@ enum {
};
static const GstEventMask *
gst_filesrc_get_event_mask (GstPad *pad)
gst_filesrc_get_event_mask (GstPad * pad)
{
static const GstEventMask masks[] = {
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_END |
GST_SEEK_FLAG_FLUSH },
{ GST_EVENT_FLUSH, 0 },
{ GST_EVENT_SIZE, 0 },
{ 0, 0 }
{GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
GST_SEEK_METHOD_SET | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
{GST_EVENT_FLUSH, 0},
{GST_EVENT_SIZE, 0},
{0, 0}
};
return masks;
}
static const GstQueryType *
gst_filesrc_get_query_types (GstPad *pad)
gst_filesrc_get_query_types (GstPad * pad)
{
static const GstQueryType types[] = {
GST_QUERY_TOTAL,
@ -129,7 +127,7 @@ gst_filesrc_get_query_types (GstPad *pad)
}
static const GstFormat *
gst_filesrc_get_formats (GstPad *pad)
gst_filesrc_get_formats (GstPad * pad)
{
static const GstFormat formats[] = {
GST_FORMAT_BYTES,
@ -138,22 +136,23 @@ gst_filesrc_get_formats (GstPad *pad)
return formats;
}
static void gst_filesrc_dispose (GObject *object);
static void gst_filesrc_dispose (GObject * object);
static void gst_filesrc_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_filesrc_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_filesrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_filesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_filesrc_check_filesize (GstFileSrc *src);
static GstData * gst_filesrc_get (GstPad *pad);
static gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event);
static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value);
static gboolean gst_filesrc_check_filesize (GstFileSrc * src);
static GstData *gst_filesrc_get (GstPad * pad);
static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event);
static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value);
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
static GstElementStateReturn gst_filesrc_change_state (GstElement * element);
static void gst_filesrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
static void gst_filesrc_uri_handler_init (gpointer g_iface,
gpointer iface_data);
static void
_do_init (GType filesrc_type)
@ -163,12 +162,14 @@ _do_init (GType filesrc_type)
NULL,
NULL
};
g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER,
&urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesrc_debug, "filesrc", 0, "filesrc element");
}
GST_BOILERPLATE_FULL (GstFileSrc, gst_filesrc, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstFileSrc, gst_filesrc, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void
gst_filesrc_base_init (gpointer g_class)
{
@ -177,41 +178,42 @@ gst_filesrc_base_init (gpointer g_class)
gst_element_class_set_details (gstelement_class, &gst_filesrc_details);
}
static void
gst_filesrc_class_init (GstFileSrcClass *klass)
gst_filesrc_class_init (GstFileSrcClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass*)klass;
gobject_class = (GObjectClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FD,
g_param_spec_int ("fd", "File-descriptor", "File-descriptor for the file being mmap()d",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_param_spec_int ("fd", "File-descriptor",
"File-descriptor for the file being mmap()d", 0, G_MAXINT, 0,
G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
g_param_spec_string ("location", "File Location", "Location of the file to read",
NULL, G_PARAM_READWRITE));
g_param_spec_string ("location", "File Location",
"Location of the file to read", NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCKSIZE,
g_param_spec_ulong ("blocksize", "Block size", "Size in bytes to read per buffer",
1, G_MAXULONG, DEFAULT_BLOCKSIZE, G_PARAM_READWRITE));
g_param_spec_ulong ("blocksize", "Block size",
"Size in bytes to read per buffer", 1, G_MAXULONG, DEFAULT_BLOCKSIZE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MMAPSIZE,
g_param_spec_ulong ("mmapsize", "mmap() Block Size",
"Size in bytes of mmap()d regions",
0, G_MAXULONG, DEFAULT_MMAPSIZE, G_PARAM_READWRITE));
g_param_spec_ulong ("mmapsize", "mmap() Block Size",
"Size in bytes of mmap()d regions", 0, G_MAXULONG, DEFAULT_MMAPSIZE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOUCH,
g_param_spec_boolean ("touch", "Touch read data",
"Touch data to force disk read",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("touch", "Touch read data",
"Touch data to force disk read", FALSE, G_PARAM_READWRITE));
gobject_class->dispose = gst_filesrc_dispose;
gobject_class->set_property = gst_filesrc_set_property;
gobject_class->get_property = gst_filesrc_get_property;
gobject_class->dispose = gst_filesrc_dispose;
gobject_class->set_property = gst_filesrc_set_property;
gobject_class->get_property = gst_filesrc_get_property;
gstelement_class->change_state = gst_filesrc_change_state;
}
static void
gst_filesrc_init (GstFileSrc *src)
gst_filesrc_init (GstFileSrc * src)
{
src->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (src->srcpad, gst_filesrc_get);
@ -222,7 +224,7 @@ gst_filesrc_init (GstFileSrc *src)
gst_pad_set_formats_function (src->srcpad, gst_filesrc_get_formats);
gst_element_add_pad (GST_ELEMENT (src), src->srcpad);
src->pagesize = getpagesize();
src->pagesize = getpagesize ();
src->filename = NULL;
src->fd = 0;
@ -233,13 +235,13 @@ gst_filesrc_init (GstFileSrc *src)
src->touch = FALSE;
src->mapbuf = NULL;
src->mapsize = DEFAULT_MMAPSIZE; /* default is 4MB */
src->mapsize = DEFAULT_MMAPSIZE; /* default is 4MB */
src->seek_happened = FALSE;
}
static void
gst_filesrc_dispose (GObject *object)
gst_filesrc_dispose (GObject * object)
{
GstFileSrc *src;
@ -254,15 +256,16 @@ gst_filesrc_dispose (GObject *object)
}
static gboolean
gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
gst_filesrc_set_location (GstFileSrc * src, const gchar * location)
{
/* the element must be stopped in order to do this */
if (GST_STATE (src) != GST_STATE_READY &&
GST_STATE (src) != GST_STATE_NULL)
if (GST_STATE (src) != GST_STATE_READY && GST_STATE (src) != GST_STATE_NULL)
return FALSE;
if (src->filename) g_free (src->filename);
if (src->uri) g_free (src->uri);
if (src->filename)
g_free (src->filename);
if (src->uri)
g_free (src->uri);
/* clear the filename if we get a NULL (is that possible?) */
if (location == NULL) {
src->filename = NULL;
@ -278,7 +281,8 @@ gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
}
static void
gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_filesrc_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstFileSrc *src;
@ -297,11 +301,12 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
break;
case ARG_MMAPSIZE:
if ((src->mapsize % src->pagesize) == 0) {
src->mapsize = g_value_get_ulong (value);
g_object_notify (G_OBJECT (src), "mmapsize");
src->mapsize = g_value_get_ulong (value);
g_object_notify (G_OBJECT (src), "mmapsize");
} else {
GST_INFO_OBJECT (src, "invalid mapsize, must be a multiple of pagesize, which is %d",
src->pagesize);
GST_INFO_OBJECT (src,
"invalid mapsize, must be a multiple of pagesize, which is %d",
src->pagesize);
}
break;
case ARG_TOUCH:
@ -314,7 +319,8 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
}
static void
gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_filesrc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstFileSrc *src;
@ -346,9 +352,9 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
}
static void
gst_filesrc_free_parent_mmap (GstBuffer *buf)
gst_filesrc_free_parent_mmap (GstBuffer * buf)
{
GST_LOG ("freeing mmap()d buffer at %"G_GUINT64_FORMAT"+%u",
GST_LOG ("freeing mmap()d buffer at %" G_GUINT64_FORMAT "+%u",
GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
#ifdef MADV_DONTNEED
@ -359,16 +365,15 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf)
munmap (GST_BUFFER_DATA (buf), GST_BUFFER_MAXSIZE (buf));
/* cast to unsigned long, since there's no gportable way to print
* guint64 as hex */
GST_LOG ("unmapped region %08lx+%08lx at %p",
GST_LOG ("unmapped region %08lx+%08lx at %p",
(unsigned long) GST_BUFFER_OFFSET (buf),
(unsigned long) GST_BUFFER_MAXSIZE (buf),
GST_BUFFER_DATA (buf));
(unsigned long) GST_BUFFER_MAXSIZE (buf), GST_BUFFER_DATA (buf));
GST_BUFFER_DATA (buf) = NULL;
}
static GstBuffer *
gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
gst_filesrc_map_region (GstFileSrc * src, off_t offset, size_t size)
{
GstBuffer *buf;
gint retval;
@ -376,20 +381,20 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
g_return_val_if_fail (offset >= 0, NULL);
GST_LOG_OBJECT (src, "mapping region %08llx+%08lx from file into memory",offset,(unsigned long)size);
GST_LOG_OBJECT (src, "mapping region %08llx+%08lx from file into memory",
offset, (unsigned long) size);
mmapregion = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
if (mmapregion == NULL) {
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, (NULL), ("mmap call failed."));
return NULL;
}
else if (mmapregion == MAP_FAILED) {
} else if (mmapregion == MAP_FAILED) {
GST_WARNING_OBJECT (src, "mmap (0x%08lx, %d, 0x%llx) failed: %s",
(unsigned long)size, src->fd, offset, strerror (errno));
(unsigned long) size, src->fd, offset, strerror (errno));
return NULL;
}
GST_LOG_OBJECT (src, "mapped region %08lx+%08lx from file into memory at %p",
(unsigned long)offset, (unsigned long)size, mmapregion);
GST_LOG_OBJECT (src, "mapped region %08lx+%08lx from file into memory at %p",
(unsigned long) offset, (unsigned long) size, mmapregion);
/* time to allocate a new mapbuf */
buf = gst_buffer_new ();
@ -398,7 +403,8 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
#ifdef MADV_SEQUENTIAL
/* madvise to tell the kernel what to do with it */
retval = madvise (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), MADV_SEQUENTIAL);
retval =
madvise (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), MADV_SEQUENTIAL);
#endif
/* fill in the rest of the fields */
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY);
@ -415,7 +421,7 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
}
static GstBuffer *
gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
gst_filesrc_map_small_region (GstFileSrc * src, off_t offset, size_t size)
{
size_t mapsize;
off_t mod, mapbase;
@ -428,9 +434,10 @@ gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
GstBuffer *ret;
mapbase = offset - mod;
mapsize = ((size + mod + src->pagesize - 1) / src->pagesize) * src->pagesize;
mapsize =
((size + mod + src->pagesize - 1) / src->pagesize) * src->pagesize;
/* printf("not on page boundaries, resizing map to %d+%d\n",mapbase,mapsize);*/
map = gst_filesrc_map_region(src, mapbase, mapsize);
map = gst_filesrc_map_region (src, mapbase, mapsize);
if (map == NULL)
return NULL;
@ -442,7 +449,7 @@ gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
return ret;
}
return gst_filesrc_map_region(src,offset,size);
return gst_filesrc_map_region (src, offset, size);
}
/**
@ -452,19 +459,19 @@ gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
* Push a new buffer from the filesrc at the current offset.
*/
static GstBuffer *
gst_filesrc_get_mmap (GstFileSrc *src)
gst_filesrc_get_mmap (GstFileSrc * src)
{
GstBuffer *buf = NULL;
size_t readsize, mapsize;
off_t readend,mapstart,mapend;
off_t readend, mapstart, mapend;
int i;
/* calculate end pointers so we don't have to do so repeatedly later */
readsize = src->block_size;
readend = src->curoffset + src->block_size; /* note this is the byte *after* the read */
readend = src->curoffset + src->block_size; /* note this is the byte *after* the read */
mapstart = GST_BUFFER_OFFSET (src->mapbuf);
mapsize = GST_BUFFER_SIZE (src->mapbuf);
mapend = mapstart + mapsize; /* note this is the byte *after* the map */
mapend = mapstart + mapsize; /* note this is the byte *after* the map */
/* check to see if we're going to overflow the end of the file */
if (readend > src->filelen) {
@ -474,40 +481,46 @@ gst_filesrc_get_mmap (GstFileSrc *src)
}
}
GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
(unsigned long)readsize, (unsigned long)readend,
(unsigned long)mapstart, (unsigned long)mapend);
GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
(unsigned long) readsize, (unsigned long) readend,
(unsigned long) mapstart, (unsigned long) mapend);
/* if the start is past the mapstart */
if (src->curoffset >= mapstart) {
/* if the end is before the mapend, the buffer is in current mmap region... */
/* ('cause by definition if readend is in the buffer, so's readstart) */
if (readend <= mapend) {
GST_LOG_OBJECT (src, "read buf %llu+%d lives in current mapbuf %lld+%d, creating subbuffer of mapbuf",
src->curoffset, (int)readsize, mapstart, mapsize);
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - mapstart,
readsize);
GST_LOG_OBJECT (src,
"read buf %llu+%d lives in current mapbuf %lld+%d, creating subbuffer of mapbuf",
src->curoffset, (int) readsize, mapstart, mapsize);
buf =
gst_buffer_create_sub (src->mapbuf, src->curoffset - mapstart,
readsize);
GST_BUFFER_OFFSET (buf) = src->curoffset;
/* if the start actually is within the current mmap region, map an overlap buffer */
/* if the start actually is within the current mmap region, map an overlap buffer */
} else if (src->curoffset < mapend) {
GST_LOG_OBJECT (src, "read buf %llu+%d starts in mapbuf %d+%d but ends outside, creating new mmap",
(unsigned long long) src->curoffset, (gint) readsize, (gint) mapstart, (gint) mapsize);
GST_LOG_OBJECT (src,
"read buf %llu+%d starts in mapbuf %d+%d but ends outside, creating new mmap",
(unsigned long long) src->curoffset, (gint) readsize, (gint) mapstart,
(gint) mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
return NULL;
}
/* the only other option is that buffer is totally outside, which means we search for it */
/* now we can assume that the start is *before* the current mmap region */
/* if the readend is past mapstart, we have two options */
/* now we can assume that the start is *before* the current mmap region */
/* if the readend is past mapstart, we have two options */
} else if (readend >= mapstart) {
/* either the read buffer overlaps the start of the mmap region */
/* or the read buffer fully contains the current mmap region */
/* either way, it's really not relevant, we just create a new region anyway*/
GST_LOG_OBJECT (src, "read buf %llu+%d starts before mapbuf %d+%d, but overlaps it",
(unsigned long long) src->curoffset, (gint) readsize, (gint) mapstart, (gint) mapsize);
/* either way, it's really not relevant, we just create a new region anyway */
GST_LOG_OBJECT (src,
"read buf %llu+%d starts before mapbuf %d+%d, but overlaps it",
(unsigned long long) src->curoffset, (gint) readsize, (gint) mapstart,
(gint) mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
@ -517,32 +530,35 @@ gst_filesrc_get_mmap (GstFileSrc *src)
if (buf == NULL) {
/* first check to see if there's a map that covers the right region already */
GST_LOG_OBJECT (src, "searching for mapbuf to cover %llu+%d",
src->curoffset,(int)readsize);
src->curoffset, (int) readsize);
/* if the read buffer crosses a mmap region boundary, create a one-off region */
if ((src->curoffset / src->mapsize) != (readend / src->mapsize)) {
GST_LOG_OBJECT (src, "read buf %llu+%d crosses a %d-byte boundary, creating a one-off",
src->curoffset,(int)readsize,(int)src->mapsize);
GST_LOG_OBJECT (src,
"read buf %llu+%d crosses a %d-byte boundary, creating a one-off",
src->curoffset, (int) readsize, (int) src->mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
/* otherwise we will create a new mmap region and set it to the default */
/* otherwise we will create a new mmap region and set it to the default */
} else {
size_t mapsize;
off_t nextmap = src->curoffset - (src->curoffset % src->mapsize);
GST_LOG_OBJECT (src, "read buf %llu+%d in new mapbuf at %llu+%d, mapping and subbuffering",
src->curoffset, readsize, nextmap, src->mapsize);
GST_LOG_OBJECT (src,
"read buf %llu+%d in new mapbuf at %llu+%d, mapping and subbuffering",
src->curoffset, readsize, nextmap, src->mapsize);
/* first, we're done with the old mapbuf */
gst_buffer_unref(src->mapbuf);
gst_buffer_unref (src->mapbuf);
mapsize = src->mapsize;
/* double the mapsize as long as the readsize is smaller */
while (readsize - (src->curoffset - nextmap) > mapsize) {
GST_LOG_OBJECT (src, "readsize smaller then mapsize %08x %d",
readsize, (int)mapsize);
mapsize <<=1;
readsize, (int) mapsize);
mapsize <<= 1;
}
/* create a new one */
src->mapbuf = gst_filesrc_map_region (src, nextmap, mapsize);
@ -550,8 +566,11 @@ gst_filesrc_get_mmap (GstFileSrc *src)
return NULL;
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET (src->mapbuf) + src->curoffset - nextmap;
buf =
gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap,
readsize);
GST_BUFFER_OFFSET (buf) =
GST_BUFFER_OFFSET (src->mapbuf) + src->curoffset - nextmap;
}
}
@ -559,18 +578,18 @@ gst_filesrc_get_mmap (GstFileSrc *src)
if (src->touch) {
volatile guchar *p = GST_BUFFER_DATA (buf), c;
for (i=0; i < GST_BUFFER_SIZE (buf); i += src->pagesize)
for (i = 0; i < GST_BUFFER_SIZE (buf); i += src->pagesize)
c = p[i];
}
/* we're done, return the buffer */
g_assert (src->curoffset == GST_BUFFER_OFFSET (buf));
src->curoffset += GST_BUFFER_SIZE(buf);
src->curoffset += GST_BUFFER_SIZE (buf);
return buf;
}
static GstBuffer *
gst_filesrc_get_read (GstFileSrc *src)
gst_filesrc_get_read (GstFileSrc * src)
{
GstBuffer *buf = NULL;
size_t readsize;
@ -578,7 +597,8 @@ gst_filesrc_get_read (GstFileSrc *src)
readsize = src->block_size;
if (src->curoffset + readsize > src->filelen) {
if (!gst_filesrc_check_filesize (src) || src->curoffset + readsize > src->filelen) {
if (!gst_filesrc_check_filesize (src)
|| src->curoffset + readsize > src->filelen) {
readsize = src->filelen - src->curoffset;
}
}
@ -587,12 +607,13 @@ gst_filesrc_get_read (GstFileSrc *src)
g_return_val_if_fail (buf != NULL, NULL);
ret = read (src->fd, GST_BUFFER_DATA (buf), readsize);
if (ret < 0){
if (ret < 0) {
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
return NULL;
}
if (ret < readsize) {
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("unexpected end of file."));
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("unexpected end of file."));
return NULL;
}
@ -606,7 +627,7 @@ gst_filesrc_get_read (GstFileSrc *src)
}
static GstData *
gst_filesrc_get (GstPad *pad)
gst_filesrc_get (GstPad * pad)
{
GstFileSrc *src;
@ -626,7 +647,9 @@ gst_filesrc_get (GstPad *pad)
src->seek_happened = FALSE;
GST_DEBUG_OBJECT (src, "sending discont");
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL);
event =
gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset,
NULL);
return GST_DATA (event);
}
@ -634,77 +657,76 @@ gst_filesrc_get (GstPad *pad)
g_assert (src->curoffset <= src->filelen);
if (src->curoffset == src->filelen) {
if (!gst_filesrc_check_filesize (src) || src->curoffset >= src->filelen) {
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT " %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
}
if (src->using_mmap){
if (src->using_mmap) {
return GST_DATA (gst_filesrc_get_mmap (src));
}else{
} else {
return GST_DATA (gst_filesrc_get_read (src));
}
}
/* TRUE if the filesize of the file was updated */
static gboolean
gst_filesrc_check_filesize (GstFileSrc *src)
gst_filesrc_check_filesize (GstFileSrc * src)
{
struct stat stat_results;
g_return_val_if_fail (GST_FLAG_IS_SET (src ,GST_FILESRC_OPEN), FALSE);
fstat(src->fd, &stat_results);
GST_DEBUG_OBJECT (src, "checked filesize on %s (was %"G_GUINT64_FORMAT", is %"G_GUINT64_FORMAT")",
src->filename, src->filelen, (guint64) stat_results.st_size);
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), FALSE);
fstat (src->fd, &stat_results);
GST_DEBUG_OBJECT (src,
"checked filesize on %s (was %" G_GUINT64_FORMAT ", is %" G_GUINT64_FORMAT
")", src->filename, src->filelen, (guint64) stat_results.st_size);
if (src->filelen == (guint64) stat_results.st_size)
return FALSE;
src->filelen = stat_results.st_size;
return TRUE;
}
/* open the file and mmap it, necessary to go to READY state */
static gboolean
gst_filesrc_open_file (GstFileSrc *src)
gst_filesrc_open_file (GstFileSrc * src)
{
g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_FILESRC_OPEN), FALSE);
g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), FALSE);
if (src->filename == NULL || src->filename[0] == '\0')
{
if (src->filename == NULL || src->filename[0] == '\0') {
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
(_("No file name specified for reading.")), (NULL));
(_("No file name specified for reading.")), (NULL));
return FALSE;
}
GST_INFO_OBJECT (src, "opening file %s",src->filename);
GST_INFO_OBJECT (src, "opening file %s", src->filename);
/* open the file */
src->fd = open (src->filename, O_RDONLY);
if (src->fd < 0)
{
if (src->fd < 0) {
if (errno == ENOENT)
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), (NULL));
else
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
(_("Could not open file \"%s\" for reading."), src->filename),
GST_ERROR_SYSTEM);
(_("Could not open file \"%s\" for reading."), src->filename),
GST_ERROR_SYSTEM);
return FALSE;
} else {
/* check if it is a regular file, otherwise bail out */
struct stat stat_results;
fstat(src->fd, &stat_results);
fstat (src->fd, &stat_results);
if (!S_ISREG(stat_results.st_mode)) {
if (!S_ISREG (stat_results.st_mode)) {
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
(_("File \"%s\" isn't a regular file."), src->filename),
(NULL));
close(src->fd);
(_("File \"%s\" isn't a regular file."), src->filename), (NULL));
close (src->fd);
return FALSE;
}
/* find the file length */
src->filelen = stat_results.st_size;
@ -712,7 +734,7 @@ gst_filesrc_open_file (GstFileSrc *src)
src->mapbuf = gst_filesrc_map_region (src, 0, src->mapsize);
if (src->mapbuf == NULL) {
src->using_mmap = FALSE;
}else{
} else {
src->using_mmap = TRUE;
}
@ -725,7 +747,7 @@ gst_filesrc_open_file (GstFileSrc *src)
/* unmap and close the file */
static void
gst_filesrc_close_file (GstFileSrc *src)
gst_filesrc_close_file (GstFileSrc * src)
{
g_return_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN));
@ -747,9 +769,9 @@ gst_filesrc_close_file (GstFileSrc *src)
static GstElementStateReturn
gst_filesrc_change_state (GstElement *element)
gst_filesrc_change_state (GstElement * element)
{
GstFileSrc *src = GST_FILESRC(element);
GstFileSrc *src = GST_FILESRC (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
@ -758,13 +780,13 @@ gst_filesrc_change_state (GstElement *element)
break;
case GST_STATE_READY_TO_PAUSED:
if (!GST_FLAG_IS_SET (element, GST_FILESRC_OPEN)) {
if (!gst_filesrc_open_file (GST_FILESRC (element)))
return GST_STATE_FAILURE;
if (!gst_filesrc_open_file (GST_FILESRC (element)))
return GST_STATE_FAILURE;
}
break;
case GST_STATE_PAUSED_TO_READY:
if (GST_FLAG_IS_SET (element, GST_FILESRC_OPEN))
gst_filesrc_close_file (GST_FILESRC (element));
gst_filesrc_close_file (GST_FILESRC (element));
src->seek_happened = TRUE;
break;
default:
@ -778,8 +800,8 @@ gst_filesrc_change_state (GstElement *element)
}
static gboolean
gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
GstFileSrc *src = GST_FILESRC (GST_PAD_PARENT (pad));
@ -794,14 +816,14 @@ gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
case GST_QUERY_POSITION:
switch (*format) {
case GST_FORMAT_BYTES:
*value = src->curoffset;
break;
*value = src->curoffset;
break;
case GST_FORMAT_PERCENT:
if (src->filelen == 0)
return FALSE;
*value = src->curoffset * GST_FORMAT_PERCENT_MAX / src->filelen;
break;
default:
*value = src->curoffset * GST_FORMAT_PERCENT_MAX / src->filelen;
break;
default:
return FALSE;
}
break;
@ -813,7 +835,7 @@ gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
}
static gboolean
gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event)
gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event)
{
GstFileSrc *src = GST_FILESRC (GST_PAD_PARENT (pad));
@ -831,35 +853,41 @@ gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event)
offset = GST_EVENT_SEEK_OFFSET (event);
switch (GST_EVENT_SEEK_METHOD (event)) {
case GST_SEEK_METHOD_SET:
if (offset > src->filelen && (!gst_filesrc_check_filesize (src) || offset > src->filelen)) {
goto error;
case GST_SEEK_METHOD_SET:
if (offset > src->filelen && (!gst_filesrc_check_filesize (src)
|| offset > src->filelen)) {
goto error;
}
src->curoffset = offset;
GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT, src->curoffset);
src->curoffset = offset;
GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT,
src->curoffset);
break;
case GST_SEEK_METHOD_CUR:
if (offset + src->curoffset > src->filelen)
if (!gst_filesrc_check_filesize (src) || offset + src->curoffset > src->filelen)
case GST_SEEK_METHOD_CUR:
if (offset + src->curoffset > src->filelen)
if (!gst_filesrc_check_filesize (src)
|| offset + src->curoffset > src->filelen)
goto error;
src->curoffset += offset;
GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT, src->curoffset);
src->curoffset += offset;
GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT,
src->curoffset);
break;
case GST_SEEK_METHOD_END:
if (ABS (offset) > src->filelen) {
if (!gst_filesrc_check_filesize (src) || ABS (offset) > src->filelen)
case GST_SEEK_METHOD_END:
if (ABS (offset) > src->filelen) {
if (!gst_filesrc_check_filesize (src)
|| ABS (offset) > src->filelen)
goto error;
goto error;
}
src->curoffset = src->filelen - ABS (offset);
GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT, src->curoffset);
src->curoffset = src->filelen - ABS (offset);
GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT,
src->curoffset);
break;
default:
goto error;
goto error;
break;
}
src->seek_happened = TRUE;
src->need_flush = GST_EVENT_SEEK_FLAGS(event) & GST_SEEK_FLAG_FLUSH;
src->need_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
break;
}
case GST_EVENT_SIZE:
@ -867,7 +895,7 @@ gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event)
goto error;
}
src->block_size = GST_EVENT_SIZE_VALUE (event);
g_object_notify (G_OBJECT (src), "blocksize");
g_object_notify (G_OBJECT (src), "blocksize");
break;
case GST_EVENT_FLUSH:
src->need_flush = TRUE;
@ -892,20 +920,21 @@ gst_filesrc_uri_get_type (void)
return GST_URI_SRC;
}
static gchar **
gst_filesrc_uri_get_protocols(void)
gst_filesrc_uri_get_protocols (void)
{
static gchar *protocols[] = {"file", NULL};
static gchar *protocols[] = { "file", NULL };
return protocols;
}
static const gchar *
gst_filesrc_uri_get_uri (GstURIHandler *handler)
gst_filesrc_uri_get_uri (GstURIHandler * handler)
{
GstFileSrc *src = GST_FILESRC (handler);
return src->uri;
}
static gboolean
gst_filesrc_uri_set_uri (GstURIHandler *handler, const gchar *uri)
gst_filesrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
gchar *protocol, *location;
gboolean ret;

View file

@ -29,21 +29,19 @@
#include <sys/types.h>
G_BEGIN_DECLS
#define GST_TYPE_FILESRC \
(gst_filesrc_get_type())
#define GST_FILESRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FILESRC,GstFileSrc))
#define GST_FILESRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FILESRC,GstFileSrcClass))
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FILESRC,GstFileSrcClass))
#define GST_IS_FILESRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FILESRC))
#define GST_IS_FILESRC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FILESRC))
typedef enum {
GST_FILESRC_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum
{
GST_FILESRC_OPEN = GST_ELEMENT_FLAG_LAST,
GST_FILESRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
} GstFileSrcFlags;
@ -51,20 +49,21 @@ typedef enum {
typedef struct _GstFileSrc GstFileSrc;
typedef struct _GstFileSrcClass GstFileSrcClass;
struct _GstFileSrc {
struct _GstFileSrc
{
GstElement element;
GstPad *srcpad;
guint pagesize; /* system page size*/
gchar *filename; /* filename */
gchar *uri; /* caching the URI */
gint fd; /* open file descriptor*/
off_t filelen; /* what's the file length?*/
guint pagesize; /* system page size */
off_t curoffset; /* current offset in file*/
off_t block_size; /* bytes per read */
gboolean touch; /* whether to touch every page */
gchar *filename; /* filename */
gchar *uri; /* caching the URI */
gint fd; /* open file descriptor */
off_t filelen; /* what's the file length? */
off_t curoffset; /* current offset in file */
off_t block_size; /* bytes per read */
gboolean touch; /* whether to touch every page */
gboolean using_mmap;
GstBuffer *mapbuf;
@ -74,12 +73,12 @@ struct _GstFileSrc {
gboolean need_flush;
};
struct _GstFileSrcClass {
struct _GstFileSrcClass
{
GstElementClass parent_class;
};
GType gst_filesrc_get_type(void);
GType gst_filesrc_get_type (void);
G_END_DECLS
#endif /* __GST_FILESRC_H__ */

View file

@ -34,22 +34,22 @@
GST_DEBUG_CATEGORY_STATIC (gst_identity_debug);
#define GST_CAT_DEFAULT gst_identity_debug
GstElementDetails gst_identity_details = GST_ELEMENT_DETAILS (
"Identity",
"Generic",
"Pass data without modification",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
GstElementDetails gst_identity_details = GST_ELEMENT_DETAILS ("Identity",
"Generic",
"Pass data without modification",
"Erik Walthinsen <omega@cse.ogi.edu>");
/* Identity signals and args */
enum {
enum
{
SIGNAL_HANDOFF,
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_LOOP_BASED,
ARG_SLEEP_TIME,
@ -65,12 +65,15 @@ enum {
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_identity_debug, "identity", 0, "identity element");
GST_BOILERPLATE_FULL (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void gst_identity_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_identity_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_identity_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_identity_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_identity_chain (GstPad *pad, GstData *_data);
static void gst_identity_chain (GstPad * pad, GstData * _data);
static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
@ -78,11 +81,11 @@ static void
gst_identity_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_identity_details);
}
static void
gst_identity_class_init (GstIdentityClass *klass)
static void
gst_identity_class_init (GstIdentityClass * klass)
{
GObjectClass *gobject_class;
@ -90,50 +93,52 @@ gst_identity_class_init (GstIdentityClass *klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
g_param_spec_boolean ("loop-based", "Loop-based",
"Set to TRUE to use loop-based rather than chain-based scheduling",
TRUE, G_PARAM_READWRITE));
g_param_spec_boolean ("loop-based", "Loop-based",
"Set to TRUE to use loop-based rather than chain-based scheduling",
TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME,
g_param_spec_uint ("sleep-time", "Sleep time", "Microseconds to sleep between processing",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
g_param_spec_uint ("sleep-time", "Sleep time",
"Microseconds to sleep between processing", 0, G_MAXUINT, 0,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE,
g_param_spec_uint ("duplicate", "Duplicate Buffers", "Push the buffers N times",
0, G_MAXUINT, 1, G_PARAM_READWRITE));
g_param_spec_uint ("duplicate", "Duplicate Buffers",
"Push the buffers N times", 0, G_MAXUINT, 1, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_AFTER,
g_param_spec_int ("error_after", "Error After", "Error after N buffers",
G_MININT, G_MAXINT, -1, G_PARAM_READWRITE));
g_param_spec_int ("error_after", "Error After", "Error after N buffers",
G_MININT, G_MAXINT, -1, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_PROBABILITY,
g_param_spec_float ("drop_probability", "Drop Probability", "The Probability a buffer is dropped",
0.0, 1.0, 0.0, G_PARAM_READWRITE));
g_param_spec_float ("drop_probability", "Drop Probability",
"The Probability a buffer is dropped", 0.0, 1.0, 0.0,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "silent", "silent",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "silent", "silent", FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last-message", "last-message", "last-message", NULL,
G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
g_param_spec_boolean("dump", "Dump", "Dump buffer contents",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", FALSE,
G_PARAM_READWRITE));
gst_identity_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstIdentityClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
GST_TYPE_BUFFER);
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstIdentityClass, handoff), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, GST_TYPE_BUFFER);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
}
static void
gst_identity_init (GstIdentity *identity)
static void
gst_identity_init (GstIdentity * identity)
{
identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad);
gst_pad_set_chain_function (identity->sinkpad, GST_DEBUG_FUNCPTR (gst_identity_chain));
gst_pad_set_chain_function (identity->sinkpad,
GST_DEBUG_FUNCPTR (gst_identity_chain));
gst_pad_set_link_function (identity->sinkpad, gst_pad_proxy_pad_link);
gst_pad_set_getcaps_function (identity->sinkpad, gst_pad_proxy_getcaps);
identity->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad);
gst_pad_set_link_function (identity->srcpad, gst_pad_proxy_pad_link);
@ -150,8 +155,8 @@ gst_identity_init (GstIdentity *identity)
identity->srccaps = NULL;
}
static void
gst_identity_chain (GstPad *pad, GstData *_data)
static void
gst_identity_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstIdentity *identity;
@ -168,20 +173,20 @@ gst_identity_chain (GstPad *pad, GstData *_data)
if (identity->error_after == 0) {
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (identity, CORE, FAILED,
(_("Failed after iterations as requested.")),
(NULL));
(_("Failed after iterations as requested.")), (NULL));
return;
}
}
if (identity->drop_probability > 0.0) {
if ((gfloat)(1.0*rand()/(RAND_MAX)) < identity->drop_probability) {
if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) {
if (identity->last_message != NULL) {
g_free (identity->last_message);
}
identity->last_message = g_strdup_printf ("dropping ******* (%s:%s)i (%d bytes, %"
G_GINT64_FORMAT ")",
GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
identity->last_message =
g_strdup_printf ("dropping ******* (%s:%s)i (%d bytes, %"
G_GINT64_FORMAT ")", GST_DEBUG_PAD_NAME (identity->sinkpad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
g_object_notify (G_OBJECT (identity), "last-message");
gst_buffer_unref (buf);
return;
@ -194,16 +199,17 @@ gst_identity_chain (GstPad *pad, GstData *_data)
for (i = identity->duplicate; i; i--) {
if (!identity->silent) {
g_free (identity->last_message);
identity->last_message = g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, %"
G_GINT64_FORMAT ")",
GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
identity->last_message =
g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, %"
G_GINT64_FORMAT ")", GST_DEBUG_PAD_NAME (identity->sinkpad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
g_object_notify (G_OBJECT (identity), "last-message");
}
g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0,
buf);
buf);
if (i>1)
if (i > 1)
gst_buffer_ref (buf);
gst_pad_push (identity->srcpad, GST_DATA (buf));
@ -213,8 +219,8 @@ gst_identity_chain (GstPad *pad, GstData *_data)
}
}
static void
gst_identity_loop (GstElement *element)
static void
gst_identity_loop (GstElement * element)
{
GstIdentity *identity;
GstBuffer *buf;
@ -223,43 +229,42 @@ gst_identity_loop (GstElement *element)
g_return_if_fail (GST_IS_IDENTITY (element));
identity = GST_IDENTITY (element);
buf = GST_BUFFER (gst_pad_pull (identity->sinkpad));
if (GST_IS_EVENT (buf)) {
GstEvent *event = GST_EVENT (buf);
if (GST_EVENT_IS_INTERRUPT (event)) {
gst_event_unref (event);
}
else {
} else {
gst_pad_event_default (identity->sinkpad, event);
}
}
else {
} else {
gst_identity_chain (identity->sinkpad, GST_DATA (buf));
}
}
static void
gst_identity_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void
gst_identity_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_IDENTITY (object));
identity = GST_IDENTITY (object);
switch (prop_id) {
case ARG_LOOP_BASED:
identity->loop_based = g_value_get_boolean (value);
if (identity->loop_based) {
gst_element_set_loop_function (GST_ELEMENT (identity), gst_identity_loop);
gst_pad_set_chain_function (identity->sinkpad, NULL);
}
else {
gst_pad_set_chain_function (identity->sinkpad, gst_identity_chain);
gst_element_set_loop_function (GST_ELEMENT (identity), NULL);
gst_element_set_loop_function (GST_ELEMENT (identity),
gst_identity_loop);
gst_pad_set_chain_function (identity->sinkpad, NULL);
} else {
gst_pad_set_chain_function (identity->sinkpad, gst_identity_chain);
gst_element_set_loop_function (GST_ELEMENT (identity), NULL);
}
break;
case ARG_SLEEP_TIME:
@ -285,12 +290,15 @@ gst_identity_set_property (GObject *object, guint prop_id, const GValue *value,
}
}
static void gst_identity_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
static void
gst_identity_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstIdentity *identity;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_IDENTITY (object));
identity = GST_IDENTITY (object);
switch (prop_id) {

View file

@ -28,8 +28,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_IDENTITY \
(gst_identity_get_type())
#define GST_IDENTITY(obj) \
@ -40,36 +38,36 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IDENTITY))
#define GST_IS_IDENTITY_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IDENTITY))
typedef struct _GstIdentity GstIdentity;
typedef struct _GstIdentityClass GstIdentityClass;
struct _GstIdentity {
GstElement element;
struct _GstIdentity
{
GstElement element;
GstPad *sinkpad;
GstPad *srcpad;
GstPad *sinkpad;
GstPad *srcpad;
gboolean loop_based;
guint duplicate;
gint error_after;
gfloat drop_probability;
guint sleep_time;
gboolean silent;
gboolean dump;
gchar *last_message;
GstCaps *srccaps;
gboolean loop_based;
guint duplicate;
gint error_after;
gfloat drop_probability;
guint sleep_time;
gboolean silent;
gboolean dump;
gchar *last_message;
GstCaps *srccaps;
};
struct _GstIdentityClass {
struct _GstIdentityClass
{
GstElementClass parent_class;
/* signals */
void (*handoff) (GstElement *element, GstBuffer *buf);
void (*handoff) (GstElement * element, GstBuffer * buf);
};
GType gst_identity_get_type(void);
GType gst_identity_get_type (void);
G_END_DECLS
#endif /* __GST_IDENTITY_H__ */

View file

@ -35,63 +35,64 @@
GST_DEBUG_CATEGORY_STATIC (gst_md5sink_debug);
#define GST_CAT_DEFAULT gst_md5sink_debug
GstElementDetails gst_md5sink_details = GST_ELEMENT_DETAILS (
"MD5 Sink",
"Sink",
"compute MD5 for incoming data",
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
GstElementDetails gst_md5sink_details = GST_ELEMENT_DETAILS ("MD5 Sink",
"Sink",
"compute MD5 for incoming data",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
/* MD5Sink signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_MD5,
/* FILL ME */
};
GstStaticPadTemplate md5_sink_template = GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate md5_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_md5sink_debug, "md5sink", 0, "md5sink element");
GST_BOILERPLATE_FULL (GstMD5Sink, gst_md5sink, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstMD5Sink, gst_md5sink, GstElement, GST_TYPE_ELEMENT,
_do_init);
/* GObject stuff */
/*static void gst_md5sink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);*/
static void gst_md5sink_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_md5sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_md5sink_chain (GstPad *pad, GstData *_data);
static GstElementStateReturn gst_md5sink_change_state (GstElement *element);
static void gst_md5sink_chain (GstPad * pad, GstData * _data);
static GstElementStateReturn gst_md5sink_change_state (GstElement * element);
/* MD5 stuff */
static void md5_init_ctx (GstMD5Sink *ctx);
static gpointer md5_read_ctx (GstMD5Sink *ctx, gpointer resbuf);
static gpointer md5_finish_ctx (GstMD5Sink *ctx, gpointer resbuf);
static void md5_process_bytes (const void *buffer, size_t len, GstMD5Sink *ctx);
static void md5_process_block (const void *buffer, size_t len, GstMD5Sink *ctx);
static void md5_init_ctx (GstMD5Sink * ctx);
static gpointer md5_read_ctx (GstMD5Sink * ctx, gpointer resbuf);
static gpointer md5_finish_ctx (GstMD5Sink * ctx, gpointer resbuf);
static void md5_process_bytes (const void *buffer, size_t len,
GstMD5Sink * ctx);
static void md5_process_block (const void *buffer, size_t len,
GstMD5Sink * ctx);
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const guchar fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
static const guchar fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* MD5 functions */
/* Initialize structure containing state of computation.
(RFC 1321, 3.3: Step 3) */
static void
md5_init_ctx (GstMD5Sink *ctx)
md5_init_ctx (GstMD5Sink * ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
@ -101,13 +102,14 @@ md5_init_ctx (GstMD5Sink *ctx)
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
static gpointer
md5_finish_ctx (GstMD5Sink *ctx, gpointer resbuf)
md5_finish_ctx (GstMD5Sink * ctx, gpointer resbuf)
{
/* Take yet unprocessed bytes into account. */
guint32 bytes = ctx->buflen;
@ -122,22 +124,23 @@ md5_finish_ctx (GstMD5Sink *ctx, gpointer resbuf)
memcpy (&ctx->buffer[bytes], fillbuf, pad);
/* Put the 64-bit file length in *bits* at the end of the buffer. */
*(guint32 *) &ctx->buffer[bytes + pad] = GUINT32_TO_LE (ctx->total[0] << 3);
*(guint32 *) &ctx->buffer[bytes + pad + 4] = GUINT32_TO_LE ((ctx->total[1] << 3) |
(ctx->total[0] >> 29));
*(guint32 *) & ctx->buffer[bytes + pad] = GUINT32_TO_LE (ctx->total[0] << 3);
*(guint32 *) & ctx->buffer[bytes + pad + 4] =
GUINT32_TO_LE ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
/* Process last bytes. */
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
return md5_read_ctx (ctx, resbuf);
}
/* Put result from CTX in first 16 bytes following RESBUF. The result
must be in little endian byte order.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
static gpointer
md5_read_ctx (GstMD5Sink *ctx, gpointer resbuf)
md5_read_ctx (GstMD5Sink * ctx, gpointer resbuf)
{
((guint32 *) resbuf)[0] = GUINT32_TO_LE (ctx->A);
((guint32 *) resbuf)[1] = GUINT32_TO_LE (ctx->B);
@ -148,66 +151,60 @@ md5_read_ctx (GstMD5Sink *ctx, gpointer resbuf)
}
static void
md5_process_bytes (const void *buffer, size_t len, GstMD5Sink *ctx)
md5_process_bytes (const void *buffer, size_t len, GstMD5Sink * ctx)
{
/*const void aligned_buffer = buffer; */
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
if (ctx->buflen != 0) {
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
/* Only put full words in the buffer. */
/* Forcing alignment here appears to be only an optimization.
* The glibc source uses __alignof__, which seems to be a
* gratuitous usage of a GCC extension, when sizeof() will
* work fine. (And don't question the sanity of using
* sizeof(guint32) instead of 4. */
/* add -= add % __alignof__ (guint32); */
add -= add % sizeof(guint32);
/* Only put full words in the buffer. */
/* Forcing alignment here appears to be only an optimization.
* The glibc source uses __alignof__, which seems to be a
* gratuitous usage of a GCC extension, when sizeof() will
* work fine. (And don't question the sanity of using
* sizeof(guint32) instead of 4. */
/* add -= add % __alignof__ (guint32); */
add -= add % sizeof (guint32);
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
if (ctx->buflen > 64) {
md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len > 64)
{
md5_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
if (len > 64) {
md5_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
/* Move remaining bytes in internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
if (len > 0) {
size_t left_over = ctx->buflen;
memcpy (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
md5_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[64], left_over);
}
ctx->buflen = left_over;
memcpy (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 64) {
md5_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[64], left_over);
}
ctx->buflen = left_over;
}
}
@ -223,7 +220,7 @@ md5_process_bytes (const void *buffer, size_t len, GstMD5Sink *ctx)
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0. */
static void
md5_process_block (const void *buffer, size_t len, GstMD5Sink *ctx)
md5_process_block (const void *buffer, size_t len, GstMD5Sink * ctx)
{
guint32 correct_words[16];
const guint32 *words = buffer;
@ -243,20 +240,19 @@ md5_process_block (const void *buffer, size_t len, GstMD5Sink *ctx)
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */
while (words < endp)
{
guint32 *cwp = correct_words;
guint32 A_save = A;
guint32 B_save = B;
guint32 C_save = C;
guint32 D_save = D;
while (words < endp) {
guint32 *cwp = correct_words;
guint32 A_save = A;
guint32 B_save = B;
guint32 C_save = C;
guint32 D_save = D;
/* First round: using the given function, the context and a constant
the next context is computed. Because the algorithms processing
unit is a 32-bit word and it is determined to work on words in
little endian byte order we perhaps have to change the byte order
before the computation. To reduce the work for the next steps
we store the swapped words in the array CORRECT_WORDS. */
/* First round: using the given function, the context and a constant
the next context is computed. Because the algorithms processing
unit is a 32-bit word and it is determined to work on words in
little endian byte order we perhaps have to change the byte order
before the computation. To reduce the work for the next steps
we store the swapped words in the array CORRECT_WORDS. */
#define OP(a, b, c, d, s, T) \
do \
@ -268,37 +264,37 @@ md5_process_block (const void *buffer, size_t len, GstMD5Sink *ctx)
} \
while (0)
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
/* Before we start, one word to the strange constants.
They are defined in RFC 1321 as
/* Before we start, one word to the strange constants.
They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
/* For the second to fourth round we have the possibly swapped words
in CORRECT_WORDS. Redefine the macro to take an additional first
argument specifying the function to use. */
/* For the second to fourth round we have the possibly swapped words
in CORRECT_WORDS. Redefine the macro to take an additional first
argument specifying the function to use. */
#undef OP
#define OP(f, a, b, c, d, k, s, T) \
do \
@ -309,66 +305,66 @@ md5_process_block (const void *buffer, size_t len, GstMD5Sink *ctx)
} \
while (0)
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Add the starting values of the context. */
A += A_save;
B += B_save;
C += C_save;
D += D_save;
}
/* Add the starting values of the context. */
A += A_save;
B += B_save;
C += C_save;
D += D_save;
}
/* Put checksum in context given as argument. */
ctx->A = A;
@ -381,14 +377,14 @@ static void
gst_md5sink_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_md5sink_details);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&md5_sink_template));
}
static void
gst_md5sink_class_init (GstMD5SinkClass *klass)
gst_md5sink_class_init (GstMD5SinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
@ -400,18 +396,20 @@ gst_md5sink_class_init (GstMD5SinkClass *klass)
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_md5sink_get_property);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MD5,
g_param_spec_string ("md5", "md5", "current value of the md5 sum",
"", G_PARAM_READABLE));
g_param_spec_string ("md5", "md5", "current value of the md5 sum",
"", G_PARAM_READABLE));
gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_md5sink_change_state);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_md5sink_change_state);
}
static void
gst_md5sink_init (GstMD5Sink *md5sink)
static void
gst_md5sink_init (GstMD5Sink * md5sink)
{
GstPad *pad;
pad = gst_pad_new_from_template (gst_static_pad_template_get (
&md5_sink_template), "sink");
pad =
gst_pad_new_from_template (gst_static_pad_template_get
(&md5_sink_template), "sink");
gst_element_add_pad (GST_ELEMENT (md5sink), pad);
gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_md5sink_chain));
@ -419,15 +417,15 @@ gst_md5sink_init (GstMD5Sink *md5sink)
}
static GstElementStateReturn
gst_md5sink_change_state (GstElement *element)
gst_md5sink_change_state (GstElement * element)
{
GstMD5Sink *sink;
/* element check */
sink = GST_MD5SINK (element);
g_return_val_if_fail (GST_IS_MD5SINK (sink), GST_STATE_FAILURE);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_READY_TO_PAUSED:
md5_init_ctx (sink);
@ -440,38 +438,39 @@ gst_md5sink_change_state (GstElement *element)
default:
break;
}
if ((GST_ELEMENT_CLASS (parent_class)->change_state))
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}
static void
gst_md5sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_md5sink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstMD5Sink *sink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_MD5SINK (object));
sink = GST_MD5SINK (object);
switch (prop_id) {
case ARG_MD5:
{
/* you could actually get a value for the current md5.
* This is currently disabled.
* md5_read_ctx (sink, sink->md5); */
/* md5 is a guchar[16] */
int i;
guchar *md5string = g_malloc0 (33);
{
/* you could actually get a value for the current md5.
* This is currently disabled.
* md5_read_ctx (sink, sink->md5); */
/* md5 is a guchar[16] */
int i;
guchar *md5string = g_malloc0 (33);
for (i = 0; i < 16; ++i)
sprintf (md5string + i * 2, "%02x", sink->md5[i]);
g_value_set_string (value, md5string);
g_free (md5string);
}
for (i = 0; i < 16; ++i)
sprintf (md5string + i * 2, "%02x", sink->md5[i]);
g_value_set_string (value, md5string);
g_free (md5string);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -479,8 +478,8 @@ gst_md5sink_get_property (GObject *object, guint prop_id, GValue *value, GParamS
}
}
static void
gst_md5sink_chain (GstPad *pad, GstData *_data)
static void
gst_md5sink_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstMD5Sink *md5sink;
@ -491,11 +490,9 @@ gst_md5sink_chain (GstPad *pad, GstData *_data)
md5sink = GST_MD5SINK (gst_pad_get_parent (pad));
if (GST_IS_BUFFER (buf))
{
if (GST_IS_BUFFER (buf)) {
md5_process_bytes (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), md5sink);
}
gst_buffer_unref (buf);
}

View file

@ -28,8 +28,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_MD5SINK \
(gst_md5sink_get_type())
#define GST_MD5SINK(obj) \
@ -40,11 +38,11 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MD5SINK))
#define GST_IS_MD5SINK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MD5SINK))
typedef struct _GstMD5Sink GstMD5Sink;
typedef struct _GstMD5SinkClass GstMD5SinkClass;
struct _GstMD5Sink {
struct _GstMD5Sink
{
GstElement element;
/* md5 information */
@ -56,21 +54,21 @@ struct _GstMD5Sink {
guint32 total[2];
guint32 buflen;
gchar buffer[128];
/* latest md5 */
guchar md5[16];
};
struct _GstMD5SinkClass {
struct _GstMD5SinkClass
{
GstElementClass parent_class;
};
GType gst_md5sink_get_type (void);
GType gst_md5sink_get_type (void);
gboolean gst_md5sink_factory_init (GstElementFactory *factory);
gboolean gst_md5sink_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_MD5SINK_H__ */

View file

@ -40,20 +40,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_multifilesrc_debug);
#define GST_CAT_DEFAULT gst_multifilesrc_debug
GstElementDetails gst_multifilesrc_details = GST_ELEMENT_DETAILS (
"Multi File Source",
"Source/File",
"Read from multiple files in order",
"Dominic Ludlam <dom@openfx.org>"
);
GstElementDetails gst_multifilesrc_details =
GST_ELEMENT_DETAILS ("Multi File Source",
"Source/File",
"Read from multiple files in order",
"Dominic Ludlam <dom@openfx.org>");
/* FileSrc signals and args */
enum {
enum
{
NEW_FILE,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_LOCATIONS
};
@ -61,18 +62,24 @@ enum {
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_multifilesrc_debug, "multifilesrc", 0, "multifilesrc element");
GST_BOILERPLATE_FULL (GstMultiFileSrc, gst_multifilesrc, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstMultiFileSrc, gst_multifilesrc, GstElement,
GST_TYPE_ELEMENT, _do_init);
static void gst_multifilesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_multifilesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_multifilesrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_multifilesrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstData *gst_multifilesrc_get (GstPad * pad);
static GstData * gst_multifilesrc_get (GstPad *pad);
/*static GstBuffer * gst_multifilesrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len);*/
static GstElementStateReturn gst_multifilesrc_change_state (GstElement *element);
static GstElementStateReturn gst_multifilesrc_change_state (GstElement *
element);
static gboolean gst_multifilesrc_open_file (GstMultiFileSrc *src, GstPad *srcpad);
static void gst_multifilesrc_close_file (GstMultiFileSrc *src);
static gboolean gst_multifilesrc_open_file (GstMultiFileSrc * src,
GstPad * srcpad);
static void gst_multifilesrc_close_file (GstMultiFileSrc * src);
static guint gst_multifilesrc_signals[LAST_SIGNAL] = { 0 };
@ -80,28 +87,25 @@ static void
gst_multifilesrc_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_multifilesrc_details);
}
static void
gst_multifilesrc_class_init (GstMultiFileSrcClass *klass)
gst_multifilesrc_class_init (GstMultiFileSrcClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gst_multifilesrc_signals[NEW_FILE] =
g_signal_new ("new-file", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMultiFileSrcClass, new_file), NULL, NULL,
g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1,
G_TYPE_STRING);
g_signal_new ("new-file", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMultiFileSrcClass, new_file), NULL, NULL,
g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOCATIONS,
g_param_spec_pointer("locations","locations","locations",
G_PARAM_READWRITE)); /* CHECKME */
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATIONS, g_param_spec_pointer ("locations", "locations", "locations", G_PARAM_READWRITE)); /* CHECKME */
gobject_class->set_property = gst_multifilesrc_set_property;
gobject_class->get_property = gst_multifilesrc_get_property;
@ -110,12 +114,12 @@ gst_multifilesrc_class_init (GstMultiFileSrcClass *klass)
}
static void
gst_multifilesrc_init (GstMultiFileSrc *multifilesrc)
gst_multifilesrc_init (GstMultiFileSrc * multifilesrc)
{
/* GST_FLAG_SET (filesrc, GST_SRC_); */
multifilesrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (multifilesrc->srcpad,gst_multifilesrc_get);
gst_pad_set_get_function (multifilesrc->srcpad, gst_multifilesrc_get);
/* gst_pad_set_getregion_function (multifilesrc->srcpad,gst_multifilesrc_get_region); */
gst_element_add_pad (GST_ELEMENT (multifilesrc), multifilesrc->srcpad);
@ -128,7 +132,8 @@ gst_multifilesrc_init (GstMultiFileSrc *multifilesrc)
}
static void
gst_multifilesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_multifilesrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstMultiFileSrc *src;
@ -144,11 +149,11 @@ gst_multifilesrc_set_property (GObject *object, guint prop_id, const GValue *val
/* clear the filename if we get a NULL */
if (g_value_get_pointer (value) == NULL) {
gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
src->listptr = NULL;
/* otherwise set the new filenames */
gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
src->listptr = NULL;
/* otherwise set the new filenames */
} else {
src->listptr = g_value_get_pointer (value);
src->listptr = g_value_get_pointer (value);
}
break;
default:
@ -157,7 +162,8 @@ gst_multifilesrc_set_property (GObject *object, guint prop_id, const GValue *val
}
static void
gst_multifilesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_multifilesrc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstMultiFileSrc *src;
@ -183,7 +189,7 @@ gst_multifilesrc_get_property (GObject *object, guint prop_id, GValue *value, GP
* Push a new buffer from the filesrc at the current offset.
*/
static GstData *
gst_multifilesrc_get (GstPad *pad)
gst_multifilesrc_get (GstPad * pad)
{
GstMultiFileSrc *src;
GstBuffer *buf;
@ -193,7 +199,7 @@ gst_multifilesrc_get (GstPad *pad)
src = GST_MULTIFILESRC (gst_pad_get_parent (pad));
if (GST_FLAG_IS_SET (src, GST_MULTIFILESRC_OPEN))
gst_multifilesrc_close_file(src);
gst_multifilesrc_close_file (src);
if (!src->listptr) {
return GST_DATA (gst_event_new (GST_EVENT_EOS));
@ -203,11 +209,11 @@ gst_multifilesrc_get (GstPad *pad)
src->currentfilename = (gchar *) list->data;
src->listptr = src->listptr->next;
if (!gst_multifilesrc_open_file(src, pad))
return NULL;
if (!gst_multifilesrc_open_file (src, pad))
return NULL;
/* emitted after the open, as the user may free the list and string from here*/
g_signal_emit(G_OBJECT(src), gst_multifilesrc_signals[NEW_FILE], 0, list);
/* emitted after the open, as the user may free the list and string from here */
g_signal_emit (G_OBJECT (src), gst_multifilesrc_signals[NEW_FILE], 0, list);
/* create the buffer */
/* FIXME: should eventually use a bufferpool for this */
@ -231,24 +237,23 @@ gst_multifilesrc_get (GstPad *pad)
}
/* open the file and mmap it, necessary to go to READY state */
static
gboolean gst_multifilesrc_open_file (GstMultiFileSrc *src, GstPad *srcpad)
static gboolean
gst_multifilesrc_open_file (GstMultiFileSrc * src, GstPad * srcpad)
{
g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_MULTIFILESRC_OPEN), FALSE);
if (src->currentfilename == NULL || src->currentfilename[0] == '\0')
{
if (src->currentfilename == NULL || src->currentfilename[0] == '\0') {
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
(_("No file name specified for reading.")), (NULL));
(_("No file name specified for reading.")), (NULL));
return FALSE;
}
/* open the file */
src->fd = open ((const char *) src->currentfilename, O_RDONLY);
if (src->fd < 0) {
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
(_("Could not open file \"%s\" for reading."), src->currentfilename),
GST_ERROR_SYSTEM);
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
(_("Could not open file \"%s\" for reading."), src->currentfilename),
GST_ERROR_SYSTEM);
return FALSE;
} else {
@ -257,12 +262,12 @@ gboolean gst_multifilesrc_open_file (GstMultiFileSrc *src, GstPad *srcpad)
lseek (src->fd, 0, SEEK_SET);
/* map the file into memory */
src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED, src->fd, 0);
madvise (src->map,src->size, 2);
madvise (src->map, src->size, 2);
/* collapse state if that failed */
if (src->map == NULL) {
close (src->fd);
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, (NULL),
("mmap call failed."));
("mmap call failed."));
return FALSE;
}
GST_FLAG_SET (src, GST_MULTIFILESRC_OPEN);
@ -273,7 +278,7 @@ gboolean gst_multifilesrc_open_file (GstMultiFileSrc *src, GstPad *srcpad)
/* unmap and close the file */
static void
gst_multifilesrc_close_file (GstMultiFileSrc *src)
gst_multifilesrc_close_file (GstMultiFileSrc * src)
{
g_return_if_fail (GST_FLAG_IS_SET (src, GST_MULTIFILESRC_OPEN));
@ -291,7 +296,7 @@ gst_multifilesrc_close_file (GstMultiFileSrc *src)
}
static GstElementStateReturn
gst_multifilesrc_change_state (GstElement *element)
gst_multifilesrc_change_state (GstElement * element)
{
g_return_val_if_fail (GST_IS_MULTIFILESRC (element), GST_STATE_FAILURE);

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_MULTIFILESRC \
(gst_multifilesrc_get_type())
#define GST_MULTIFILESRC(obj) \
@ -39,41 +37,42 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULTIFILESRC))
#define GST_IS_MULTIFILESRC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTIFILESRC))
typedef enum
{
GST_MULTIFILESRC_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum {
GST_MULTIFILESRC_OPEN = GST_ELEMENT_FLAG_LAST,
GST_MULTIFILESRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
GST_MULTIFILESRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
} GstMultiFileSrcFlags;
typedef struct _GstMultiFileSrc GstMultiFileSrc;
typedef struct _GstMultiFileSrcClass GstMultiFileSrcClass;
struct _GstMultiFileSrc {
struct _GstMultiFileSrc
{
GstElement element;
/* pads */
GstPad *srcpad;
/* current file details */
gchar *currentfilename;
gchar *currentfilename;
GSList *listptr;
/* mapping parameters */
gint fd;
gulong size; /* how long is the file? */
guchar *map; /* where the file is mapped to */
gulong size; /* how long is the file? */
guchar *map; /* where the file is mapped to */
gboolean new_seek;
};
struct _GstMultiFileSrcClass {
struct _GstMultiFileSrcClass
{
GstElementClass parent_class;
void (*new_file) (GstMultiFileSrc *multifilesrc, gchar *newfilename);
void (*new_file) (GstMultiFileSrc * multifilesrc, gchar * newfilename);
};
GType gst_multifilesrc_get_type(void);
GType gst_multifilesrc_get_type (void);
G_END_DECLS
#endif /* __GST_MULTIFILESRC_H__ */

View file

@ -40,22 +40,22 @@
GST_DEBUG_CATEGORY_STATIC (gst_pipefilter_debug);
#define GST_CAT_DEFAULT gst_pipefilter_debug
GstElementDetails gst_pipefilter_details = GST_ELEMENT_DETAILS (
"Pipefilter",
"Filter",
"Interoperate with an external program using stdin and stdout",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>"
);
GstElementDetails gst_pipefilter_details = GST_ELEMENT_DETAILS ("Pipefilter",
"Filter",
"Interoperate with an external program using stdin and stdout",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>");
/* Pipefilter signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_COMMAND
};
@ -64,46 +64,47 @@ enum {
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_pipefilter_debug, "pipefilter", 0, "pipefilter element");
GST_BOILERPLATE_FULL (GstPipefilter, gst_pipefilter, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstPipefilter, gst_pipefilter, GstElement,
GST_TYPE_ELEMENT, _do_init);
static void gst_pipefilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_pipefilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_pipefilter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_pipefilter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstData* gst_pipefilter_get (GstPad *pad);
static void gst_pipefilter_chain (GstPad *pad, GstData *_data);
static gboolean gst_pipefilter_handle_event (GstPad *pad, GstEvent *event);
static GstData *gst_pipefilter_get (GstPad * pad);
static void gst_pipefilter_chain (GstPad * pad, GstData * _data);
static gboolean gst_pipefilter_handle_event (GstPad * pad, GstEvent * event);
static GstElementStateReturn gst_pipefilter_change_state (GstElement *element);
static GstElementStateReturn gst_pipefilter_change_state (GstElement * element);
static void
gst_pipefilter_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_pipefilter_details);
}
static void
gst_pipefilter_class_init (GstPipefilterClass *klass)
static void
gst_pipefilter_class_init (GstPipefilterClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gobject_class->set_property = gst_pipefilter_set_property;
gobject_class->set_property = gst_pipefilter_set_property;
gobject_class->get_property = gst_pipefilter_get_property;
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_COMMAND,
g_param_spec_string("command","command","command",
NULL, G_PARAM_READWRITE)); /* CHECKME */
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COMMAND, g_param_spec_string ("command", "command", "command", NULL, G_PARAM_READWRITE)); /* CHECKME */
gstelement_class->change_state = gst_pipefilter_change_state;
}
static void
gst_pipefilter_init (GstPipefilter *pipefilter)
gst_pipefilter_init (GstPipefilter * pipefilter)
{
GST_FLAG_SET (pipefilter, GST_ELEMENT_DECOUPLED);
@ -122,7 +123,7 @@ gst_pipefilter_init (GstPipefilter *pipefilter)
}
static gboolean
gst_pipefilter_handle_event (GstPad *pad, GstEvent *event)
gst_pipefilter_handle_event (GstPad * pad, GstEvent * event)
{
GstPipefilter *pipefilter;
@ -133,9 +134,9 @@ gst_pipefilter_handle_event (GstPad *pad, GstEvent *event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
if (close (pipefilter->fdin[1]) < 0)
perror("close");
perror ("close");
if (close (pipefilter->fdout[0]) < 0)
perror("close");
perror ("close");
break;
default:
break;
@ -146,8 +147,8 @@ gst_pipefilter_handle_event (GstPad *pad, GstEvent *event)
return TRUE;
}
static GstData*
gst_pipefilter_get (GstPad *pad)
static GstData *
gst_pipefilter_get (GstPad * pad)
{
GstPipefilter *pipefilter;
GstBuffer *newbuf;
@ -157,16 +158,18 @@ gst_pipefilter_get (GstPad *pad)
/* create the buffer */
/* FIXME: should eventually use a bufferpool for this */
newbuf = gst_buffer_new();
g_return_val_if_fail(newbuf, NULL);
newbuf = gst_buffer_new ();
g_return_val_if_fail (newbuf, NULL);
/* allocate the space for the buffer data */
GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read);
g_return_val_if_fail(GST_BUFFER_DATA(newbuf) != NULL, NULL);
GST_BUFFER_DATA (newbuf) = g_malloc (pipefilter->bytes_per_read);
g_return_val_if_fail (GST_BUFFER_DATA (newbuf) != NULL, NULL);
/* read it in from the file */
GST_DEBUG ("attemting to read %ld bytes", pipefilter->bytes_per_read);
readbytes = read(pipefilter->fdout[0], GST_BUFFER_DATA(newbuf), pipefilter->bytes_per_read);
readbytes =
read (pipefilter->fdout[0], GST_BUFFER_DATA (newbuf),
pipefilter->bytes_per_read);
GST_DEBUG ("read %ld bytes", readbytes);
if (readbytes < 0) {
GST_ELEMENT_ERROR (pipefilter, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
@ -178,15 +181,15 @@ gst_pipefilter_get (GstPad *pad)
}
GST_BUFFER_OFFSET(newbuf) = pipefilter->curoffset;
GST_BUFFER_SIZE(newbuf) = readbytes;
GST_BUFFER_OFFSET (newbuf) = pipefilter->curoffset;
GST_BUFFER_SIZE (newbuf) = readbytes;
pipefilter->curoffset += readbytes;
return GST_DATA (newbuf);
}
static void
gst_pipefilter_chain (GstPad *pad,GstData *_data)
gst_pipefilter_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf;
GstPipefilter *pipefilter;
@ -194,8 +197,8 @@ gst_pipefilter_chain (GstPad *pad,GstData *_data)
guchar *data;
gulong size;
g_return_if_fail(pad != NULL);
g_return_if_fail(GST_IS_PAD(pad));
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
if (GST_IS_EVENT (_data)) {
gst_pipefilter_handle_event (pad, GST_EVENT (_data));
@ -205,32 +208,33 @@ gst_pipefilter_chain (GstPad *pad,GstData *_data)
pipefilter = GST_PIPEFILTER (gst_pad_get_parent (pad));
buf = GST_BUFFER (_data);
data = GST_BUFFER_DATA(buf);
size = GST_BUFFER_SIZE(buf);
data = GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf);
GST_DEBUG ("attemting to write %ld bytes", size);
writebytes = write(pipefilter->fdin[1],data,size);
writebytes = write (pipefilter->fdin[1], data, size);
GST_DEBUG ("written %ld bytes", writebytes);
if (writebytes < 0) {
GST_ELEMENT_ERROR (pipefilter, RESOURCE, WRITE, (NULL), GST_ERROR_SYSTEM);
return;
}
gst_buffer_unref(buf);
gst_buffer_unref (buf);
}
static void
gst_pipefilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_pipefilter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstPipefilter *pipefilter;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_PIPEFILTER(object));
pipefilter = GST_PIPEFILTER(object);
g_return_if_fail (GST_IS_PIPEFILTER (object));
pipefilter = GST_PIPEFILTER (object);
switch (prop_id) {
case ARG_COMMAND:
pipefilter->orig_command = g_strdup(g_value_get_string (value));
pipefilter->command = g_strsplit(g_value_get_string (value), " ", 0);
pipefilter->orig_command = g_strdup (g_value_get_string (value));
pipefilter->command = g_strsplit (g_value_get_string (value), " ", 0);
break;
default:
break;
@ -238,13 +242,14 @@ gst_pipefilter_set_property (GObject *object, guint prop_id, const GValue *value
}
static void
gst_pipefilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_pipefilter_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstPipefilter *pipefilter;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_PIPEFILTER(object));
pipefilter = GST_PIPEFILTER(object);
g_return_if_fail (GST_IS_PIPEFILTER (object));
pipefilter = GST_PIPEFILTER (object);
switch (prop_id) {
case ARG_COMMAND:
@ -258,78 +263,75 @@ gst_pipefilter_get_property (GObject *object, guint prop_id, GValue *value, GPar
/* open the file, necessary to go to RUNNING state */
static gboolean
gst_pipefilter_open_file (GstPipefilter *src)
gst_pipefilter_open_file (GstPipefilter * src)
{
g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN), FALSE);
g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_PIPEFILTER_OPEN), FALSE);
pipe(src->fdin);
pipe(src->fdout);
pipe (src->fdin);
pipe (src->fdout);
if((src->childpid = fork()) == -1)
{
if ((src->childpid = fork ()) == -1) {
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, (NULL), GST_ERROR_SYSTEM);
return FALSE;
}
if(src->childpid == 0)
{
close(src->fdin[1]);
close(src->fdout[0]);
if (src->childpid == 0) {
close (src->fdin[1]);
close (src->fdout[0]);
/* child */
dup2(src->fdin[0], STDIN_FILENO); /* set the childs input stream */
dup2(src->fdout[1], STDOUT_FILENO); /* set the childs output stream */
execvp(src->command[0], &src->command[0]);
dup2 (src->fdin[0], STDIN_FILENO); /* set the childs input stream */
dup2 (src->fdout[1], STDOUT_FILENO); /* set the childs output stream */
execvp (src->command[0], &src->command[0]);
/* will only be reached if execvp has an error */
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, (NULL), GST_ERROR_SYSTEM);
return FALSE;
} else {
close (src->fdin[0]);
close (src->fdout[1]);
}
else {
close(src->fdin[0]);
close(src->fdout[1]);
}
GST_FLAG_SET(src,GST_PIPEFILTER_OPEN);
GST_FLAG_SET (src, GST_PIPEFILTER_OPEN);
return TRUE;
}
/* close the file */
static void
gst_pipefilter_close_file (GstPipefilter *src)
gst_pipefilter_close_file (GstPipefilter * src)
{
g_return_if_fail(GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN));
g_return_if_fail (GST_FLAG_IS_SET (src, GST_PIPEFILTER_OPEN));
/* close the file */
close(src->fdout[0]);
close(src->fdout[1]);
close(src->fdin[0]);
close(src->fdin[1]);
close (src->fdout[0]);
close (src->fdout[1]);
close (src->fdin[0]);
close (src->fdin[1]);
/* zero out a lot of our state */
src->curoffset = 0;
src->seq = 0;
GST_FLAG_UNSET(src,GST_PIPEFILTER_OPEN);
GST_FLAG_UNSET (src, GST_PIPEFILTER_OPEN);
}
static GstElementStateReturn
gst_pipefilter_change_state (GstElement *element)
gst_pipefilter_change_state (GstElement * element)
{
g_return_val_if_fail(GST_IS_PIPEFILTER(element), FALSE);
g_return_val_if_fail (GST_IS_PIPEFILTER (element), FALSE);
/* if going down into NULL state, close the file if it's open */
if (GST_STATE_PENDING(element) == GST_STATE_NULL) {
if (GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN))
gst_pipefilter_close_file(GST_PIPEFILTER(element));
/* otherwise (READY or higher) we need to open the file */
/* if going down into NULL state, close the file if it's open */
if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
if (GST_FLAG_IS_SET (element, GST_PIPEFILTER_OPEN))
gst_pipefilter_close_file (GST_PIPEFILTER (element));
/* otherwise (READY or higher) we need to open the file */
} else {
if (!GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN)) {
if (!gst_pipefilter_open_file(GST_PIPEFILTER(element)))
return GST_STATE_FAILURE;
if (!GST_FLAG_IS_SET (element, GST_PIPEFILTER_OPEN)) {
if (!gst_pipefilter_open_file (GST_PIPEFILTER (element)))
return GST_STATE_FAILURE;
}
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}

View file

@ -28,8 +28,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_PIPEFILTER \
(gst_pipefilter_get_type())
#define GST_PIPEFILTER(obj) \
@ -40,17 +38,18 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PIPEFILTER))
#define GST_IS_PIPEFILTER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPEFILTER))
typedef enum
{
GST_PIPEFILTER_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum {
GST_PIPEFILTER_OPEN = GST_ELEMENT_FLAG_LAST,
GST_PIPEFILTER_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
GST_PIPEFILTER_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
} GstPipeFilterFlags;
typedef struct _GstPipefilter GstPipefilter;
typedef struct _GstPipefilterClass GstPipefilterClass;
struct _GstPipefilter {
struct _GstPipefilter
{
GstElement element;
GstPad *sinkpad;
@ -62,20 +61,20 @@ struct _GstPipefilter {
/* fd */
gint fdout[2];
gint fdin[2];
pid_t childpid;
pid_t childpid;
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong curoffset; /* current offset in file */
gulong bytes_per_read; /* bytes per read */
gulong seq; /* buffer sequence number */
gulong seq; /* buffer sequence number */
};
struct _GstPipefilterClass {
struct _GstPipefilterClass
{
GstElementClass parent_class;
};
GType gst_pipefilter_get_type(void);
GType gst_pipefilter_get_type (void);
G_END_DECLS
#endif /* __GST_PIPEFILTER_H__ */

View file

@ -32,21 +32,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_shaper_debug);
#define GST_CAT_DEFAULT gst_shaper_debug
GstElementDetails gst_shaper_details = GST_ELEMENT_DETAILS (
"Shaper",
"Generic",
"Synchronizes streams on different pads",
"Wim Taymans <wim.taymans@chello.be>"
);
GstElementDetails gst_shaper_details = GST_ELEMENT_DETAILS ("Shaper",
"Generic",
"Synchronizes streams on different pads",
"Wim Taymans <wim.taymans@chello.be>");
/* Shaper signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_POLICY,
ARG_SILENT,
@ -55,24 +55,20 @@ enum {
typedef struct
{
GstPad *sinkpad;
GstPad *srcpad;
GstBuffer *buffer;
GstPad *sinkpad;
GstPad *srcpad;
GstBuffer *buffer;
} GstShaperConnection;
GstStaticPadTemplate shaper_src_template = GST_STATIC_PAD_TEMPLATE (
"src%d",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate shaper_src_template = GST_STATIC_PAD_TEMPLATE ("src%d",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
GstStaticPadTemplate shaper_sink_template = GST_STATIC_PAD_TEMPLATE (
"sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate shaper_sink_template = GST_STATIC_PAD_TEMPLATE ("sink%d",
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
#define GST_TYPE_SHAPER_POLICY (gst_shaper_policy_get_type())
static GType
@ -80,12 +76,13 @@ gst_shaper_policy_get_type (void)
{
static GType shaper_policy_type = 0;
static GEnumValue shaper_policy[] = {
{ SHAPER_POLICY_TIMESTAMPS, "1", "sync on timestamps"},
{ SHAPER_POLICY_BUFFERSIZE, "2", "sync on buffer size"},
{SHAPER_POLICY_TIMESTAMPS, "1", "sync on timestamps"},
{SHAPER_POLICY_BUFFERSIZE, "2", "sync on buffer size"},
{0, NULL, NULL},
};
if (!shaper_policy_type) {
shaper_policy_type = g_enum_register_static ("GstShaperPolicy", shaper_policy);
shaper_policy_type =
g_enum_register_static ("GstShaperPolicy", shaper_policy);
}
return shaper_policy_type;
}
@ -93,24 +90,25 @@ gst_shaper_policy_get_type (void)
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_shaper_debug, "shaper", 0, "shaper element");
GST_BOILERPLATE_FULL (GstShaper, gst_shaper, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstShaper, gst_shaper, GstElement, GST_TYPE_ELEMENT,
_do_init);
static void gst_shaper_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_shaper_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_shaper_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_shaper_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstPad* gst_shaper_request_new_pad (GstElement *element, GstPadTemplate *templ,
const gchar *unused);
static GstPad *gst_shaper_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * unused);
static void gst_shaper_loop (GstElement *element);
static void gst_shaper_loop (GstElement * element);
static void
gst_shaper_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_shaper_details);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&shaper_src_template));
@ -118,41 +116,43 @@ gst_shaper_base_init (gpointer g_class)
gst_static_pad_template_get (&shaper_sink_template));
}
static void
gst_shaper_class_init (GstShaperClass *klass)
static void
gst_shaper_class_init (GstShaperClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*) klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_POLICY,
g_param_spec_enum ("policy", "Policy", "Shaper policy",
GST_TYPE_SHAPER_POLICY, SHAPER_POLICY_TIMESTAMPS, G_PARAM_READWRITE));
g_param_spec_enum ("policy", "Policy", "Shaper policy",
GST_TYPE_SHAPER_POLICY, SHAPER_POLICY_TIMESTAMPS, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "silent", "silent",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "silent", "silent",
FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message", "last-message",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last-message", "last-message", "last-message",
NULL, G_PARAM_READABLE));
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_shaper_set_property);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_shaper_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_shaper_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_shaper_request_new_pad);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_shaper_request_new_pad);
}
static GstCaps*
gst_shaper_getcaps (GstPad *pad)
static GstCaps *
gst_shaper_getcaps (GstPad * pad)
{
GstPad *otherpad;
GstShaperConnection *connection;
connection = gst_pad_get_element_private (pad);
otherpad = (pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
otherpad =
(pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
if (GST_PAD_PEER (otherpad)) {
return gst_pad_get_caps (GST_PAD_PEER (otherpad));
@ -161,8 +161,8 @@ gst_shaper_getcaps (GstPad *pad)
}
}
static GList*
gst_shaper_get_internal_link (GstPad *pad)
static GList *
gst_shaper_get_internal_link (GstPad * pad)
{
GList *res = NULL;
GstShaperConnection *connection;
@ -170,7 +170,8 @@ gst_shaper_get_internal_link (GstPad *pad)
connection = gst_pad_get_element_private (pad);
otherpad = (pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
otherpad =
(pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
res = g_list_prepend (res, otherpad);
@ -178,20 +179,21 @@ gst_shaper_get_internal_link (GstPad *pad)
}
static GstPadLinkReturn
gst_shaper_link (GstPad *pad, const GstCaps *caps)
gst_shaper_link (GstPad * pad, const GstCaps * caps)
{
GstPad *otherpad;
GstShaperConnection *connection;
connection = gst_pad_get_element_private (pad);
otherpad = (pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
otherpad =
(pad == connection->srcpad ? connection->sinkpad : connection->srcpad);
return gst_pad_try_set_caps (otherpad, caps);
}
static GstShaperConnection*
gst_shaper_create_connection (GstShaper *shaper)
static GstShaperConnection *
gst_shaper_create_connection (GstShaper * shaper)
{
GstShaperConnection *connection;
gchar *padname;
@ -201,21 +203,25 @@ gst_shaper_create_connection (GstShaper *shaper)
connection = g_new0 (GstShaperConnection, 1);
padname = g_strdup_printf ("sink%d", shaper->nconnections);
connection->sinkpad = gst_pad_new_from_template (
gst_static_pad_template_get (&shaper_sink_template), padname);
connection->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&shaper_sink_template), padname);
g_free (padname);
gst_pad_set_getcaps_function (connection->sinkpad, gst_shaper_getcaps);
gst_pad_set_internal_link_function (connection->sinkpad, gst_shaper_get_internal_link);
gst_pad_set_internal_link_function (connection->sinkpad,
gst_shaper_get_internal_link);
gst_pad_set_link_function (connection->sinkpad, gst_shaper_link);
gst_pad_set_element_private (connection->sinkpad, connection);
gst_element_add_pad (GST_ELEMENT (shaper), connection->sinkpad);
padname = g_strdup_printf ("src%d", shaper->nconnections);
connection->srcpad = gst_pad_new_from_template (
gst_static_pad_template_get (&shaper_src_template), padname);
connection->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&shaper_src_template), padname);
g_free (padname);
gst_pad_set_getcaps_function (connection->srcpad, gst_shaper_getcaps);
gst_pad_set_internal_link_function (connection->srcpad, gst_shaper_get_internal_link);
gst_pad_set_internal_link_function (connection->srcpad,
gst_shaper_get_internal_link);
gst_pad_set_link_function (connection->srcpad, gst_shaper_link);
gst_pad_set_element_private (connection->srcpad, connection);
gst_element_add_pad (GST_ELEMENT (shaper), connection->srcpad);
@ -225,8 +231,9 @@ gst_shaper_create_connection (GstShaper *shaper)
return connection;
}
static GstPad*
gst_shaper_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
static GstPad *
gst_shaper_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
{
GstShaper *shaper = GST_SHAPER (element);
GstShaperConnection *connection;
@ -236,8 +243,8 @@ gst_shaper_request_new_pad (GstElement *element, GstPadTemplate *templ, const gc
return connection->sinkpad;
}
static void
gst_shaper_init (GstShaper *shaper)
static void
gst_shaper_init (GstShaper * shaper)
{
gst_element_set_loop_function (GST_ELEMENT (shaper), gst_shaper_loop);
@ -248,8 +255,8 @@ gst_shaper_init (GstShaper *shaper)
shaper->last_message = NULL;
}
static void
gst_shaper_loop (GstElement *element)
static void
gst_shaper_loop (GstElement * element)
{
GstShaper *shaper;
GSList *connections;
@ -278,16 +285,15 @@ gst_shaper_loop (GstElement *element)
gst_pad_push (connection->srcpad, GST_DATA (buffer));
switch (type) {
/* on EOS we disable the pad so that we don't pull on
* it again and never get more data */
case GST_EVENT_EOS:
/* on EOS we disable the pad so that we don't pull on
* it again and never get more data */
case GST_EVENT_EOS:
gst_pad_set_active (connection->sinkpad, FALSE);
break;
default:
break;
}
}
else {
} else {
/* we store the buffer */
connection->buffer = buffer;
}
@ -295,9 +301,8 @@ gst_shaper_loop (GstElement *element)
/* FIXME policy stuff goes here */
/* find connection with lowest timestamp */
if (min == NULL || (connection->buffer != NULL &&
(GST_BUFFER_TIMESTAMP (connection->buffer) <
GST_BUFFER_TIMESTAMP (min->buffer))))
{
(GST_BUFFER_TIMESTAMP (connection->buffer) <
GST_BUFFER_TIMESTAMP (min->buffer)))) {
min = connection;
}
connections = g_slist_next (connections);
@ -309,20 +314,21 @@ gst_shaper_loop (GstElement *element)
/* since we pushed a buffer, it's not EOS */
eos = FALSE;
}
if (eos) {
gst_element_set_eos (element);
}
}
static void
gst_shaper_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void
gst_shaper_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstShaper *shaper;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_SHAPER (object));
shaper = GST_SHAPER (object);
switch (prop_id) {
@ -338,12 +344,15 @@ gst_shaper_set_property (GObject *object, guint prop_id, const GValue *value, GP
}
}
static void gst_shaper_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
static void
gst_shaper_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstShaper *shaper;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_SHAPER (object));
shaper = GST_SHAPER (object);
switch (prop_id) {
@ -361,4 +370,3 @@ static void gst_shaper_get_property(GObject *object, guint prop_id, GValue *valu
break;
}
}

View file

@ -28,8 +28,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_SHAPER \
(gst_shaper_get_type())
#define GST_SHAPER(obj) \
@ -40,8 +38,8 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SHAPER))
#define GST_IS_SHAPER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SHAPER))
typedef enum {
typedef enum
{
SHAPER_POLICY_TIMESTAMPS = 1,
SHAPER_POLICY_BUFFERSIZE
} GstShaperPolicyType;
@ -49,26 +47,27 @@ typedef enum {
typedef struct _GstShaper GstShaper;
typedef struct _GstShaperClass GstShaperClass;
struct _GstShaper {
GstElement element;
struct _GstShaper
{
GstElement element;
GSList *connections;
gint nconnections;
GSList *connections;
gint nconnections;
GstShaperPolicyType policy;
GstShaperPolicyType policy;
gboolean silent;
gchar *last_message;
gboolean silent;
gchar *last_message;
};
struct _GstShaperClass {
struct _GstShaperClass
{
GstElementClass parent_class;
};
GType gst_shaper_get_type (void);
gboolean gst_shaper_factory_init (GstElementFactory *factory);
GType gst_shaper_get_type (void);
gboolean gst_shaper_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_SHAPER_H__ */

View file

@ -30,21 +30,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_statistics_debug);
#define GST_CAT_DEFAULT gst_statistics_debug
GstElementDetails gst_statistics_details = GST_ELEMENT_DETAILS (
"Statistics",
"Generic",
"Statistics on buffers/bytes/events",
"David I. Lehn <dlehn@users.sourceforge.net>"
);
GstElementDetails gst_statistics_details = GST_ELEMENT_DETAILS ("Statistics",
"Generic",
"Statistics on buffers/bytes/events",
"David I. Lehn <dlehn@users.sourceforge.net>");
/* Statistics signals and args */
enum {
enum
{
SIGNAL_UPDATE,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_BUFFERS,
ARG_BYTES,
@ -61,14 +61,17 @@ enum {
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_statistics_debug, "statistics", 0, "statistics element");
GST_BOILERPLATE_FULL (GstStatistics, gst_statistics, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstStatistics, gst_statistics, GstElement,
GST_TYPE_ELEMENT, _do_init);
static void gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_statistics_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_statistics_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_statistics_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_statistics_chain (GstPad *pad, GstData *_data);
static void gst_statistics_reset (GstStatistics *statistics);
static void gst_statistics_print (GstStatistics *statistics);
static void gst_statistics_chain (GstPad * pad, GstData * _data);
static void gst_statistics_reset (GstStatistics * statistics);
static void gst_statistics_print (GstStatistics * statistics);
static guint gst_statistics_signals[LAST_SIGNAL] = { 0, };
@ -79,71 +82,75 @@ static void
gst_statistics_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_statistics_details);
}
static void
gst_statistics_class_init (GstStatisticsClass *klass)
static void
gst_statistics_class_init (GstStatisticsClass * klass)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (klass);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFERS,
g_param_spec_int64 ("buffers", "buffers", "total buffers count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_param_spec_int64 ("buffers", "buffers", "total buffers count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTES,
g_param_spec_int64 ("bytes", "bytes", "total bytes count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_param_spec_int64 ("bytes", "bytes", "total bytes count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EVENTS,
g_param_spec_int64 ("events", "events", "total event count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFER_UPDATE_FREQ,
g_param_spec_int64 ("buffer_update_freq", "buffer update freq", "buffer update frequency",
0, G_MAXINT64, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTES_UPDATE_FREQ,
g_param_spec_int64 ("bytes_update_freq", "bytes update freq", "bytes update frequency",
0, G_MAXINT64, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EVENT_UPDATE_FREQ,
g_param_spec_int64 ("event_update_freq", "event update freq", "event update frequency",
0, G_MAXINT64, 0, G_PARAM_READWRITE));
g_param_spec_int64 ("events", "events", "total event count",
0, G_MAXINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass),
ARG_BUFFER_UPDATE_FREQ, g_param_spec_int64 ("buffer_update_freq",
"buffer update freq", "buffer update frequency", 0, G_MAXINT64, 0,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass),
ARG_BYTES_UPDATE_FREQ, g_param_spec_int64 ("bytes_update_freq",
"bytes update freq", "bytes update frequency", 0, G_MAXINT64, 0,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass),
ARG_EVENT_UPDATE_FREQ, g_param_spec_int64 ("event_update_freq",
"event update freq", "event update frequency", 0, G_MAXINT64, 0,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UPDATE_ON_EOS,
g_param_spec_boolean ("update_on_eos", "update on EOS", "update on EOS event",
TRUE,G_PARAM_READWRITE));
g_param_spec_boolean ("update_on_eos", "update on EOS",
"update on EOS event", TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UPDATE,
g_param_spec_boolean ("update", "update", "update",
TRUE,G_PARAM_READWRITE));
g_param_spec_boolean ("update", "update", "update", TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "silent", "silent",
TRUE,G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "silent", "silent", TRUE,
G_PARAM_READWRITE));
gst_statistics_signals[SIGNAL_UPDATE] =
g_signal_new ("update", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstStatisticsClass, update), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_signal_new ("update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstStatisticsClass, update), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_statistics_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_statistics_get_property);
}
static void
gst_statistics_init (GstStatistics *statistics)
static void
gst_statistics_init (GstStatistics * statistics)
{
statistics->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (statistics), statistics->sinkpad);
gst_pad_set_chain_function (statistics->sinkpad, GST_DEBUG_FUNCPTR (gst_statistics_chain));
gst_pad_set_chain_function (statistics->sinkpad,
GST_DEBUG_FUNCPTR (gst_statistics_chain));
statistics->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (statistics), statistics->srcpad);
statistics->timer = NULL;
statistics->last_timer = NULL;
gst_statistics_reset(statistics);
gst_statistics_reset (statistics);
}
static void
gst_statistics_reset (GstStatistics *statistics)
gst_statistics_reset (GstStatistics * statistics)
{
g_return_if_fail (statistics != NULL);
g_return_if_fail (GST_IS_STATISTICS (statistics));
@ -169,15 +176,16 @@ gst_statistics_reset (GstStatistics *statistics)
statistics->silent = FALSE;
if (!statistics->timer) {
statistics->timer = g_timer_new();
statistics->timer = g_timer_new ();
}
if (!statistics->last_timer) {
statistics->last_timer = g_timer_new();
statistics->last_timer = g_timer_new ();
}
}
static void
print_stats(gboolean first, const gchar *name, const gchar *type, stats *base, stats *final, double time)
print_stats (gboolean first, const gchar * name, const gchar * type,
stats * base, stats * final, double time)
{
const gchar *header0 = "statistics";
const gchar *headerN = " ";
@ -187,25 +195,21 @@ print_stats(gboolean first, const gchar *name, const gchar *type, stats *base, s
delta.bytes = final->bytes - base->bytes;
delta.events = final->events - base->events;
g_print("%s: (%s) %s: s:%g buffers:%" G_GINT64_FORMAT
" bytes:%" G_GINT64_FORMAT
" events:%" G_GINT64_FORMAT "\n",
first ? header0 : headerN,
name, type, time,
final->buffers,
final->bytes,
final->events);
g_print("%s: (%s) %s: buf/s:%g B/s:%g e/s:%g B/buf:%g\n",
headerN,
name, type,
delta.buffers/time,
delta.bytes/time,
delta.events/time,
((double)delta.bytes/(double)delta.buffers));
g_print ("%s: (%s) %s: s:%g buffers:%" G_GINT64_FORMAT
" bytes:%" G_GINT64_FORMAT
" events:%" G_GINT64_FORMAT "\n",
first ? header0 : headerN,
name, type, time, final->buffers, final->bytes, final->events);
g_print ("%s: (%s) %s: buf/s:%g B/s:%g e/s:%g B/buf:%g\n",
headerN,
name, type,
delta.buffers / time,
delta.bytes / time,
delta.events / time, ((double) delta.bytes / (double) delta.buffers));
}
static void
gst_statistics_print (GstStatistics *statistics)
gst_statistics_print (GstStatistics * statistics)
{
const gchar *name;
double elapsed;
@ -214,22 +218,23 @@ gst_statistics_print (GstStatistics *statistics)
g_return_if_fail (statistics != NULL);
g_return_if_fail (GST_IS_STATISTICS (statistics));
name = gst_object_get_name(GST_OBJECT(statistics));
name = gst_object_get_name (GST_OBJECT (statistics));
if (!name) {
name = "";
}
elapsed = g_timer_elapsed(statistics->timer, NULL);
last_elapsed = g_timer_elapsed(statistics->last_timer, NULL);
elapsed = g_timer_elapsed (statistics->timer, NULL);
last_elapsed = g_timer_elapsed (statistics->last_timer, NULL);
print_stats(1, name, "total", &zero_stats, &statistics->stats, elapsed);
print_stats(0, name, "last", &statistics->last_stats, &statistics->stats, last_elapsed);
print_stats (1, name, "total", &zero_stats, &statistics->stats, elapsed);
print_stats (0, name, "last", &statistics->last_stats, &statistics->stats,
last_elapsed);
statistics->last_stats = statistics->stats;
g_timer_reset(statistics->last_timer);
g_timer_reset (statistics->last_timer);
}
static void
gst_statistics_chain (GstPad *pad, GstData *_data)
static void
gst_statistics_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstStatistics *statistics;
@ -241,20 +246,21 @@ gst_statistics_chain (GstPad *pad, GstData *_data)
statistics = GST_STATISTICS (gst_pad_get_parent (pad));
if (GST_IS_EVENT(buf)) {
if (GST_IS_EVENT (buf)) {
GstEvent *event = GST_EVENT (buf);
statistics->stats.events += 1;
if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
gst_element_set_eos (GST_ELEMENT (statistics));
if (statistics->update_on_eos) {
update = TRUE;
update = TRUE;
}
}
if (statistics->update_freq.events) {
statistics->update_count.events += 1;
if (statistics->update_count.events == statistics->update_freq.events) {
statistics->update_count.events = 0;
update = TRUE;
statistics->update_count.events = 0;
update = TRUE;
}
}
} else {
@ -262,17 +268,17 @@ gst_statistics_chain (GstPad *pad, GstData *_data)
if (statistics->update_freq.buffers) {
statistics->update_count.buffers += 1;
if (statistics->update_count.buffers == statistics->update_freq.buffers) {
statistics->update_count.buffers = 0;
update = TRUE;
statistics->update_count.buffers = 0;
update = TRUE;
}
}
statistics->stats.bytes += GST_BUFFER_SIZE(buf);
statistics->stats.bytes += GST_BUFFER_SIZE (buf);
if (statistics->update_freq.bytes) {
statistics->update_count.bytes += GST_BUFFER_SIZE(buf);
statistics->update_count.bytes += GST_BUFFER_SIZE (buf);
if (statistics->update_count.bytes >= statistics->update_freq.bytes) {
statistics->update_count.bytes = 0;
update = TRUE;
statistics->update_count.bytes = 0;
update = TRUE;
}
}
}
@ -280,24 +286,26 @@ gst_statistics_chain (GstPad *pad, GstData *_data)
if (update) {
if (statistics->update) {
GST_DEBUG ("[%s]: pre update emit", GST_ELEMENT_NAME (statistics));
g_signal_emit (G_OBJECT (statistics), gst_statistics_signals[SIGNAL_UPDATE], 0);
g_signal_emit (G_OBJECT (statistics),
gst_statistics_signals[SIGNAL_UPDATE], 0);
GST_DEBUG ("[%s]: post update emit", GST_ELEMENT_NAME (statistics));
}
if (!statistics->silent) {
gst_statistics_print(statistics);
gst_statistics_print (statistics);
}
}
gst_pad_push (statistics->srcpad, GST_DATA (buf));
}
static void
gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void
gst_statistics_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstStatistics *statistics;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_STATISTICS (object));
statistics = GST_STATISTICS (object);
switch (prop_id) {
@ -325,12 +333,15 @@ gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value
}
}
static void gst_statistics_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
static void
gst_statistics_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstStatistics *statistics;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_STATISTICS (object));
statistics = GST_STATISTICS (object);
switch (prop_id) {

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_STATISTICS \
(gst_statistics_get_type())
#define GST_STATISTICS(obj) \
@ -39,19 +37,20 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STATISTICS))
#define GST_IS_STATISTICS_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STATISTICS))
typedef struct _GstStatistics GstStatistics;
typedef struct _GstStatisticsClass GstStatisticsClass;
typedef struct _stats stats;
struct _stats {
struct _stats
{
gint64 buffers;
gint64 bytes;
gint64 events;
};
struct _GstStatistics {
struct _GstStatistics
{
GstElement element;
GstPad *sinkpad;
@ -65,20 +64,20 @@ struct _GstStatistics {
stats update_count;
stats update_freq;
gboolean update_on_eos;
gboolean update_on_eos;
gboolean update;
gboolean silent;
};
struct _GstStatisticsClass {
struct _GstStatisticsClass
{
GstElementClass parent_class;
/* signals */
void (*update) (GstElement *element);
void (*update) (GstElement * element);
};
GType gst_statistics_get_type(void);
GType gst_statistics_get_type (void);
G_END_DECLS
#endif /* __GST_STATISTICS_H__ */

View file

@ -31,21 +31,21 @@
GST_DEBUG_CATEGORY_STATIC (gst_tee_debug);
#define GST_CAT_DEFAULT gst_tee_debug
GstElementDetails gst_tee_details = GST_ELEMENT_DETAILS (
"Tee pipe fitting",
"Generic",
"1-to-N pipe fitting",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>"
);
GstElementDetails gst_tee_details = GST_ELEMENT_DETAILS ("Tee pipe fitting",
"Generic",
"1-to-N pipe fitting",
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>");
/* Tee signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_SILENT,
ARG_NUM_PADS,
@ -53,89 +53,93 @@ enum {
/* FILL ME */
};
GstStaticPadTemplate tee_src_template = GST_STATIC_PAD_TEMPLATE (
"src%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate tee_src_template = GST_STATIC_PAD_TEMPLATE ("src%d",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS_ANY);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element");
GST_BOILERPLATE_FULL (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT, _do_init);
static GstPad* gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused);
static GstPad *gst_tee_request_new_pad (GstElement * element,
GstPadTemplate * temp, const gchar * unused);
static void gst_tee_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_tee_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_tee_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_tee_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_tee_chain (GstPad *pad, GstData *_data);
static void gst_tee_chain (GstPad * pad, GstData * _data);
static void
gst_tee_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_tee_details);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&tee_src_template));
}
static void
gst_tee_class_init (GstTeeClass *klass)
gst_tee_class_init (GstTeeClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_PADS,
g_param_spec_int ("num_pads", "num_pads", "num_pads",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_param_spec_int ("num_pads", "num_pads", "num_pads",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
g_param_spec_boolean ("silent", "silent", "silent",
TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_param_spec_boolean ("silent", "silent", "silent",
TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
g_param_spec_string ("last_message", "last_message", "last_message",
NULL, G_PARAM_READABLE));
g_param_spec_string ("last_message", "last_message", "last_message",
NULL, G_PARAM_READABLE));
gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_tee_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_tee_get_property);
gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_tee_request_new_pad);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_tee_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_tee_get_property);
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_tee_request_new_pad);
}
static void
gst_tee_init (GstTee *tee)
static void
gst_tee_init (GstTee * tee)
{
tee->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_pad_set_link_function (tee->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
gst_pad_set_getcaps_function (tee->sinkpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
tee->last_message = NULL;
}
/* helper compare function */
gint name_pad_compare (gconstpointer a, gconstpointer b)
gint
name_pad_compare (gconstpointer a, gconstpointer b)
{
GstPad* pad = (GstPad*) a;
GstPad *pad = (GstPad *) a;
gchar *name = (gchar *) b;
g_assert (GST_IS_PAD (pad));
return strcmp (name, gst_pad_get_name (pad)); /* returns 0 if match */
return strcmp (name, gst_pad_get_name (pad)); /* returns 0 if match */
}
static GstPad*
gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
static GstPad *
gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * unused)
{
gchar *name;
GstPad *srcpad;
@ -144,7 +148,7 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
const GList *pads;
g_return_val_if_fail (GST_IS_TEE (element), NULL);
if (templ->direction != GST_PAD_SRC) {
g_warning ("gsttee: request new pad that is not a SRC pad\n");
return NULL;
@ -154,13 +158,12 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
/* try names in order and find one that's not in use atm */
pads = gst_element_get_pad_list (element);
name = NULL;
while (!name)
{
while (!name) {
name = g_strdup_printf ("src%d", i);
if (g_list_find_custom ((GList *)pads, (gconstpointer) name, name_pad_compare) != NULL)
{
if (g_list_find_custom ((GList *) pads, (gconstpointer) name,
name_pad_compare) != NULL) {
/* this name is taken, use the next one */
++i;
g_free (name);
@ -172,11 +175,13 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
tee->last_message = g_strdup_printf ("new pad %s", name);
g_object_notify (G_OBJECT (tee), "last_message");
}
srcpad = gst_pad_new_from_template (templ, name);
g_free (name);
gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_pad_set_link_function (srcpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link));
gst_pad_set_getcaps_function (srcpad,
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (tee), srcpad);
GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
@ -188,7 +193,8 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar
}
static void
gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_tee_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
{
GstTee *tee;
@ -209,7 +215,8 @@ gst_tee_set_property (GObject *object, guint prop_id, const GValue *value, GPara
}
static void
gst_tee_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_tee_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstTee *tee;
@ -241,8 +248,8 @@ gst_tee_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
*
* Chain a buffer on a pad.
*/
static void
gst_tee_chain (GstPad *pad, GstData *_data)
static void
gst_tee_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstTee *tee;
@ -255,11 +262,12 @@ gst_tee_chain (GstPad *pad, GstData *_data)
tee = GST_TEE (gst_pad_get_parent (pad));
gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads - 1);
pads = gst_element_get_pad_list (GST_ELEMENT (tee));
while (pads) {
GstPad *outpad = GST_PAD (pads->data);
pads = g_list_next (pads);
if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC)
@ -267,9 +275,10 @@ gst_tee_chain (GstPad *pad, GstData *_data)
if (!tee->silent) {
g_free (tee->last_message);
tee->last_message = g_strdup_printf ("chain ******* (%s:%s)t (%d bytes, %"
G_GUINT64_FORMAT ") %p",
GST_DEBUG_PAD_NAME (outpad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
tee->last_message =
g_strdup_printf ("chain ******* (%s:%s)t (%d bytes, %"
G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (outpad),
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
g_object_notify (G_OBJECT (tee), "last_message");
}
@ -279,4 +288,3 @@ gst_tee_chain (GstPad *pad, GstData *_data)
gst_buffer_unref (buf);
}
}

View file

@ -27,8 +27,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_TEE \
(gst_tee_get_type())
#define GST_TEE(obj) \
@ -39,27 +37,27 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEE))
#define GST_IS_TEE_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEE))
typedef struct _GstTee GstTee;
typedef struct _GstTeeClass GstTeeClass;
typedef struct _GstTee GstTee;
typedef struct _GstTeeClass GstTeeClass;
struct _GstTee {
struct _GstTee
{
GstElement element;
GstPad *sinkpad;
gboolean silent;
gchar *last_message;
gchar *last_message;
};
struct _GstTeeClass {
struct _GstTeeClass
{
GstElementClass parent_class;
};
GType gst_tee_get_type (void);
GType gst_tee_get_type (void);
gboolean gst_tee_factory_init (GstElementFactory *factory);
gboolean gst_tee_factory_init (GstElementFactory * factory);
G_END_DECLS
#endif /* __GST_TEE_H__ */

View file

@ -49,42 +49,42 @@
GST_DEBUG_CATEGORY_STATIC (gst_type_find_element_debug);
#define GST_CAT_DEFAULT gst_type_find_element_debug
GstElementDetails gst_type_find_element_details = GST_ELEMENT_DETAILS (
"TypeFind",
"Generic",
"Finds the media type of a stream",
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
GstElementDetails gst_type_find_element_details =
GST_ELEMENT_DETAILS ("TypeFind",
"Generic",
"Finds the media type of a stream",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
/* generic templates */
GstStaticPadTemplate type_find_element_sink_template = GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate type_find_element_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
GstStaticPadTemplate type_find_element_src_template = GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY
);
GstStaticPadTemplate type_find_element_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
/* TypeFind signals and args */
enum {
enum
{
HAVE_TYPE,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_CAPS,
ARG_MINIMUM,
ARG_MAXIMUM
};
enum {
MODE_NORMAL, /* act as identity */
MODE_TYPEFIND, /* do typefinding */
enum
{
MODE_NORMAL, /* act as identity */
MODE_TYPEFIND, /* do typefinding */
};
@ -92,32 +92,28 @@ enum {
GST_DEBUG_CATEGORY_INIT (gst_type_find_element_debug, "typefind", \
GST_DEBUG_BG_YELLOW | GST_DEBUG_FG_GREEN, "type finding element");
GST_BOILERPLATE_FULL (GstTypeFindElement, gst_type_find_element, GstElement, GST_TYPE_ELEMENT, _do_init);
GST_BOILERPLATE_FULL (GstTypeFindElement, gst_type_find_element, GstElement,
GST_TYPE_ELEMENT, _do_init);
static void gst_type_find_element_dispose (GObject * object);
static void gst_type_find_element_set_property (GObject * object,
guint prop_id,
const GValue * value,
GParamSpec * pspec);
static void gst_type_find_element_get_property (GObject * object,
guint prop_id,
GValue * value,
GParamSpec * pspec);
static void gst_type_find_element_dispose (GObject * object);
static void gst_type_find_element_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_type_find_element_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static const GstEventMask *
gst_type_find_element_src_event_mask (GstPad * pad);
static gboolean gst_type_find_element_src_event (GstPad * pad,
GstEvent * event);
static const GstEventMask *gst_type_find_element_src_event_mask (GstPad * pad);
static gboolean gst_type_find_element_src_event (GstPad * pad,
GstEvent * event);
static void gst_type_find_element_chain (GstPad * sinkpad,
GstData * data);
static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data);
static GstElementStateReturn
gst_type_find_element_change_state (GstElement * element);
gst_type_find_element_change_state (GstElement * element);
static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 };
static void
gst_type_find_element_have_type (GstTypeFindElement *typefind, guint probability, const GstCaps *caps)
gst_type_find_element_have_type (GstTypeFindElement * typefind,
guint probability, const GstCaps * caps)
{
g_assert (typefind->caps == NULL);
g_assert (caps != NULL);
@ -130,53 +126,62 @@ static void
gst_type_find_element_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_type_find_element_details);
gst_element_class_set_details (gstelement_class,
&gst_type_find_element_details);
}
static void
gst_type_find_element_class_init (GstTypeFindElementClass *typefind_class)
gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (typefind_class);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (typefind_class);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_type_find_element_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_type_find_element_get_property);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_type_find_element_dispose);
gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_type_find_element_set_property);
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_type_find_element_get_property);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_type_find_element_dispose);
typefind_class->have_type = gst_type_find_element_have_type;
g_object_class_install_property (gobject_class, ARG_CAPS,
g_param_spec_boxed ("caps", _("caps"), _("detected capabilities in stream"),
gst_caps_get_type(), G_PARAM_READABLE));
g_param_spec_boxed ("caps", _("caps"),
_("detected capabilities in stream"), gst_caps_get_type (),
G_PARAM_READABLE));
g_object_class_install_property (gobject_class, ARG_MINIMUM,
g_param_spec_uint ("minimum", _("minimum"), "minimum probability required to accept caps",
GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM, G_PARAM_READWRITE));
g_param_spec_uint ("minimum", _("minimum"),
"minimum probability required to accept caps", GST_TYPE_FIND_MINIMUM,
GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_MINIMUM,
g_param_spec_uint ("maximum", _("maximum"), "probability to stop typefinding",
GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MAXIMUM, G_PARAM_READWRITE));
g_param_spec_uint ("maximum", _("maximum"),
"probability to stop typefinding", GST_TYPE_FIND_MINIMUM,
GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MAXIMUM, G_PARAM_READWRITE));
gst_type_find_element_signals[HAVE_TYPE] = g_signal_new ("have_type",
G_TYPE_FROM_CLASS (typefind_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTypeFindElementClass, have_type), NULL, NULL,
gst_marshal_VOID__UINT_BOXED, G_TYPE_NONE, 2,
G_TYPE_UINT, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
gst_type_find_element_signals[HAVE_TYPE] = g_signal_new ("have_type",
G_TYPE_FROM_CLASS (typefind_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTypeFindElementClass, have_type), NULL, NULL,
gst_marshal_VOID__UINT_BOXED, G_TYPE_NONE, 2,
G_TYPE_UINT, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
}
static void
gst_type_find_element_init (GstTypeFindElement *typefind)
gst_type_find_element_init (GstTypeFindElement * typefind)
{
/* sinkpad */
typefind->sink = gst_pad_new_from_template (
gst_static_pad_template_get (&type_find_element_sink_template), "sink");
gst_pad_set_chain_function (typefind->sink,
gst_type_find_element_chain);
typefind->sink =
gst_pad_new_from_template (gst_static_pad_template_get
(&type_find_element_sink_template), "sink");
gst_pad_set_chain_function (typefind->sink, gst_type_find_element_chain);
gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink);
/* srcpad */
typefind->src = gst_pad_new_from_template (
gst_static_pad_template_get (&type_find_element_src_template), "src");
typefind->src =
gst_pad_new_from_template (gst_static_pad_template_get
(&type_find_element_src_template), "src");
gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event);
gst_pad_set_event_mask_function (typefind->src, gst_type_find_element_src_event_mask);
gst_pad_set_event_mask_function (typefind->src,
gst_type_find_element_src_event_mask);
gst_pad_use_explicit_caps (typefind->src);
gst_element_add_pad (GST_ELEMENT (typefind), typefind->src);
@ -189,7 +194,7 @@ gst_type_find_element_init (GstTypeFindElement *typefind)
GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE);
}
static void
gst_type_find_element_dispose (GObject *object)
gst_type_find_element_dispose (GObject * object)
{
GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (object);
@ -201,8 +206,8 @@ gst_type_find_element_dispose (GObject *object)
}
}
static void
gst_type_find_element_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
gst_type_find_element_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstTypeFindElement *typefind;
@ -225,8 +230,8 @@ gst_type_find_element_set_property (GObject *object, guint prop_id,
}
}
static void
gst_type_find_element_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
gst_type_find_element_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstTypeFindElement *typefind;
@ -250,18 +255,21 @@ gst_type_find_element_get_property (GObject *object, guint prop_id,
}
}
static const GstEventMask *
gst_type_find_element_src_event_mask (GstPad *pad)
gst_type_find_element_src_event_mask (GstPad * pad)
{
static const GstEventMask mask[] = {
{ GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
{GST_EVENT_SEEK,
GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END |
GST_SEEK_FLAG_FLUSH},
/* add more if you want, event masks suck and need to die anyway */
{ 0, }
{0,}
};
return mask;
}
static gboolean
gst_type_find_element_src_event (GstPad *pad, GstEvent *event)
static gboolean
gst_type_find_element_src_event (GstPad * pad, GstEvent * event)
{
GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
@ -272,15 +280,16 @@ gst_type_find_element_src_event (GstPad *pad, GstEvent *event)
}
return gst_pad_event_default (pad, event);
}
typedef struct {
GstTypeFindFactory * factory;
gint probability;
GstCaps * caps;
gint64 requested_offset;
guint requested_size;
typedef struct
{
GstTypeFindFactory *factory;
gint probability;
GstCaps *caps;
gint64 requested_offset;
guint requested_size;
GList * buffers;
GstTypeFindElement * self;
GList *buffers;
GstTypeFindElement *self;
} TypeFindEntry;
static inline TypeFindEntry *
@ -289,42 +298,45 @@ new_entry (void)
return g_new0 (TypeFindEntry, 1);
}
static void
free_entry_buffers (TypeFindEntry *entry)
free_entry_buffers (TypeFindEntry * entry)
{
g_list_foreach (entry->buffers, (GFunc) gst_data_unref, NULL);
g_list_free (entry->buffers);
entry->buffers = NULL;
}
static void
free_entry (TypeFindEntry *entry)
free_entry (TypeFindEntry * entry)
{
free_entry_buffers (entry);
if (entry->caps)
gst_caps_free (entry->caps);
g_free (entry);
}
static void
start_typefinding (GstTypeFindElement *typefind)
start_typefinding (GstTypeFindElement * typefind)
{
g_assert (typefind->caps == NULL);
g_assert (typefind->possibilities == NULL);
GST_DEBUG_OBJECT (typefind, "starting typefinding");
typefind->mode = MODE_TYPEFIND;
typefind->stream_length_available = TRUE;
typefind->stream_length = 0;
typefind->mode = MODE_TYPEFIND;
typefind->stream_length_available = TRUE;
typefind->stream_length = 0;
}
static void
stop_typefinding (GstTypeFindElement *typefind)
stop_typefinding (GstTypeFindElement * typefind)
{
/* stop all typefinding and set mode back to normal */
gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING;
GST_DEBUG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : "");
gboolean push_cached_buffers =
gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING;
GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
push_cached_buffers ? " and pushing cached buffers" : "");
if (typefind->possibilities != NULL) {
/* this should only happen on PAUSED => READY or EOS */
GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions", g_list_length (typefind->possibilities));
GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions",
g_list_length (typefind->possibilities));
g_list_foreach (typefind->possibilities, (GFunc) free_entry, NULL);
g_list_free (typefind->possibilities);
typefind->possibilities = NULL;
@ -336,51 +348,59 @@ stop_typefinding (GstTypeFindElement *typefind)
GstBuffer *buffer;
guint size = gst_buffer_store_get_size (typefind->store, 0);
if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) {
if (size
&& (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) {
GST_LOG_OBJECT (typefind, "pushing cached data (%u bytes)", size);
gst_pad_push (typefind->src, GST_DATA (buffer));
} else {
size = 0;
}
GST_LOG_OBJECT (typefind, "seeking back to current position %u", size);
if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink),
gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) {
GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size);
if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink),
gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES,
size))) {
GST_WARNING_OBJECT (typefind,
"could not seek to required position %u, hope for the best", size);
}
}
gst_buffer_store_clear (typefind->store);
}
static guint64
find_element_get_length (gpointer data)
{
TypeFindEntry *entry = (TypeFindEntry *) data;
GstTypeFindElement *typefind = entry->self;
GstFormat format = GST_FORMAT_BYTES;
if (!typefind->stream_length_available) {
GST_LOG_OBJECT (entry->self, "'%s' called get_length () but we know it's not available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
GST_LOG_OBJECT (entry->self,
"'%s' called get_length () but we know it's not available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
return 0;
}
if (entry->self->stream_length == 0) {
typefind->stream_length_available = gst_pad_query (GST_PAD_PEER (entry->self->sink), GST_QUERY_TOTAL,
&format, &entry->self->stream_length);
typefind->stream_length_available =
gst_pad_query (GST_PAD_PEER (entry->self->sink), GST_QUERY_TOTAL,
&format, &entry->self->stream_length);
if (format != GST_FORMAT_BYTES)
typefind->stream_length_available = FALSE;
if (!typefind->stream_length_available) {
GST_DEBUG_OBJECT (entry->self, "'%s' called get_length () but it's not available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
GST_DEBUG_OBJECT (entry->self,
"'%s' called get_length () but it's not available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
return 0;
} else {
GST_DEBUG_OBJECT (entry->self, "'%s' called get_length () and it's %"G_GUINT64_FORMAT" bytes",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->self->stream_length);
GST_DEBUG_OBJECT (entry->self,
"'%s' called get_length () and it's %" G_GUINT64_FORMAT " bytes",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->self->stream_length);
}
}
return entry->self->stream_length;
}
static void
gst_type_find_element_handle_event (GstPad *pad, GstEvent *event)
gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
{
TypeFindEntry *entry;
GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
@ -388,20 +408,24 @@ gst_type_find_element_handle_event (GstPad *pad, GstEvent *event)
if (typefind->mode == MODE_TYPEFIND) {
/* need to do more? */
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
/* this should only happen when we got all available data */
entry = (TypeFindEntry *) typefind->possibilities ? typefind->possibilities->data : NULL;
if (entry && entry->probability >= typefind->min_probability) {
GST_INFO_OBJECT (typefind, "'%s' is the best typefind left after we got all data, using it now (probability %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->probability);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, entry->probability, entry->caps);
}
stop_typefinding (typefind);
gst_pad_event_default (pad, event);
break;
default:
gst_data_unref (GST_DATA (event));
break;
case GST_EVENT_EOS:
/* this should only happen when we got all available data */
entry =
(TypeFindEntry *) typefind->possibilities ? typefind->
possibilities->data : NULL;
if (entry && entry->probability >= typefind->min_probability) {
GST_INFO_OBJECT (typefind,
"'%s' is the best typefind left after we got all data, using it now (probability %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->probability);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
entry->probability, entry->caps);
}
stop_typefinding (typefind);
gst_pad_event_default (pad, event);
break;
default:
gst_data_unref (GST_DATA (event));
break;
}
} else {
gst_pad_event_default (pad, event);
@ -412,9 +436,9 @@ find_peek (gpointer data, gint64 offset, guint size)
{
GstBuffer *buf;
TypeFindEntry *entry = (TypeFindEntry *) data;
GST_LOG_OBJECT (entry->self, "'%s' called peek (%"G_GINT64_FORMAT", %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), offset, size);
GST_LOG_OBJECT (entry->self, "'%s' called peek (%" G_GINT64_FORMAT ", %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), offset, size);
if (offset >= 0) {
buf = gst_buffer_store_get_buffer (entry->self->store, offset, size);
} else {
@ -424,7 +448,9 @@ find_peek (gpointer data, gint64 offset, guint size)
if (length == 0) {
buf = NULL;
} else {
buf = gst_buffer_store_get_buffer (entry->self->store, length + offset, size);
buf =
gst_buffer_store_get_buffer (entry->self->store, length + offset,
size);
}
}
@ -433,8 +459,9 @@ find_peek (gpointer data, gint64 offset, guint size)
return GST_BUFFER_DATA (buf);
} else {
if (entry->requested_size == 0) {
GST_LOG_OBJECT (entry->self, "setting requested peek (%"G_GINT64_FORMAT", %u) on '%s'",
offset, size, GST_PLUGIN_FEATURE_NAME (entry->factory));
GST_LOG_OBJECT (entry->self,
"setting requested peek (%" G_GINT64_FORMAT ", %u) on '%s'", offset,
size, GST_PLUGIN_FEATURE_NAME (entry->factory));
entry->requested_offset = offset;
entry->requested_size = size;
}
@ -442,12 +469,12 @@ find_peek (gpointer data, gint64 offset, guint size)
}
}
static void
find_suggest (gpointer data, guint probability, const GstCaps *caps)
find_suggest (gpointer data, guint probability, const GstCaps * caps)
{
TypeFindEntry *entry = (TypeFindEntry *) data;
GST_LOG_OBJECT (entry->self, "'%s' called suggest (%u, %" GST_PTR_FORMAT ")",
GST_PLUGIN_FEATURE_NAME (entry->factory), probability, caps);
GST_LOG_OBJECT (entry->self, "'%s' called suggest (%u, %" GST_PTR_FORMAT ")",
GST_PLUGIN_FEATURE_NAME (entry->factory), probability, caps);
if (((gint) probability) > entry->probability) {
entry->probability = probability;
gst_caps_replace (&entry->caps, gst_caps_copy (caps));
@ -472,13 +499,13 @@ compare_type_find_factory (gconstpointer fac1, gconstpointer fac2)
return GST_PLUGIN_FEATURE (fac1)->rank - GST_PLUGIN_FEATURE (fac2)->rank;
}
static void
gst_type_find_element_chain (GstPad *pad, GstData *data)
gst_type_find_element_chain (GstPad * pad, GstData * data)
{
GstTypeFindElement *typefind;
GList *entries;
TypeFindEntry *entry;
GList *walk;
GstTypeFind find = {find_peek, find_suggest, NULL, find_element_get_length };
GstTypeFind find = { find_peek, find_suggest, NULL, find_element_get_length };
typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
if (GST_IS_EVENT (data)) {
@ -489,36 +516,39 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
case MODE_NORMAL:
gst_pad_push (typefind->src, data);
return;
case MODE_TYPEFIND: {
case MODE_TYPEFIND:{
guint64 current_offset;
gst_buffer_store_add_buffer (typefind->store, GST_BUFFER (data));
current_offset = GST_BUFFER_OFFSET_IS_VALID (data) ?
GST_BUFFER_OFFSET (data) + GST_BUFFER_SIZE (data) :
current_offset = GST_BUFFER_OFFSET_IS_VALID (data) ?
GST_BUFFER_OFFSET (data) + GST_BUFFER_SIZE (data) :
gst_buffer_store_get_size (typefind->store, 0);
gst_data_unref (data);
if (typefind->possibilities == NULL) {
/* not yet started, get all typefinding functions into our "queue" */
GList *all_factories = gst_type_find_factory_get_list ();
GST_INFO_OBJECT (typefind, "starting with %u typefinding functions",
g_list_length ((GList *) all_factories));
GST_INFO_OBJECT (typefind, "starting with %u typefinding functions",
g_list_length ((GList *) all_factories));
all_factories = g_list_sort (all_factories, compare_type_find_factory);
walk = all_factories;
while (all_factories) {
entry = new_entry ();
entry->factory = GST_TYPE_FIND_FACTORY (all_factories->data);
entry->self = typefind;
entry->probability = 0;
typefind->possibilities = g_list_prepend (typefind->possibilities, entry);
typefind->possibilities =
g_list_prepend (typefind->possibilities, entry);
all_factories = g_list_next (all_factories);
}
g_list_free (all_factories);
}
/* call every typefind function once */
walk = entries = typefind->possibilities;
GST_INFO_OBJECT (typefind, "iterating %u typefinding functions", g_list_length (entries));
GST_INFO_OBJECT (typefind, "iterating %u typefinding functions",
g_list_length (entries));
typefind->possibilities = NULL;
while (walk) {
find.data = entry = (TypeFindEntry *) walk->data;
@ -529,16 +559,19 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
gst_type_find_factory_call_function (entry->factory, &find);
free_entry_buffers (entry);
if (entry->probability == 0 && entry->requested_size == 0) {
GST_DEBUG_OBJECT (typefind, "'%s' was removed - no chance of being the right plugin",
GST_PLUGIN_FEATURE_NAME (entry->factory));
GST_DEBUG_OBJECT (typefind,
"'%s' was removed - no chance of being the right plugin",
GST_PLUGIN_FEATURE_NAME (entry->factory));
free_entry (entry);
} else if (entry->probability >= typefind->max_probability) {
/* wooha, got caps */
GstCaps *found_caps = entry->caps;
guint probability = entry->probability;
GST_INFO_OBJECT (typefind, "'%s' returned %u/%u probability, using it NOW",
GST_PLUGIN_FEATURE_NAME (entry->factory), probability, typefind->max_probability);
GST_INFO_OBJECT (typefind,
"'%s' returned %u/%u probability, using it NOW",
GST_PLUGIN_FEATURE_NAME (entry->factory), probability,
typefind->max_probability);
while (walk) {
free_entry ((TypeFindEntry *) walk->data);
walk = g_list_next (walk);
@ -549,11 +582,13 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
walk = g_list_next (walk);
}
typefind->possibilities = NULL;
g_list_free (typefind->possibilities);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, probability, found_caps);
g_list_free (typefind->possibilities);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
probability, found_caps);
free_entry (entry);
} else {
typefind->possibilities = g_list_prepend (typefind->possibilities, entry);
typefind->possibilities =
g_list_prepend (typefind->possibilities, entry);
}
}
g_list_free (entries);
@ -564,8 +599,9 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
} else {
/* set up typefind element for next iteration */
typefind->possibilities = g_list_sort (typefind->possibilities, compare_type_find_entry);
typefind->possibilities =
g_list_sort (typefind->possibilities, compare_type_find_entry);
/* look for typefind functions that require data without seeking */
for (walk = typefind->possibilities; walk; walk = g_list_next (walk)) {
entry = (TypeFindEntry *) walk->data;
@ -582,19 +618,27 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
gint64 seek_offset;
GstEvent *event;
seek_offset = entry->requested_offset > 0 ? entry->requested_offset :
find_element_get_length (entry) + entry->requested_offset;
seek_offset += gst_buffer_store_get_size (typefind->store, seek_offset);
event = gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET, seek_offset);
seek_offset =
entry->requested_offset >
0 ? entry->
requested_offset : find_element_get_length (entry) +
entry->requested_offset;
seek_offset +=
gst_buffer_store_get_size (typefind->store, seek_offset);
event =
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET,
seek_offset);
if (gst_pad_send_event (GST_PAD_PEER (typefind->sink), event)) {
/* done seeking */
GST_DEBUG_OBJECT (typefind, "'%s' was reset - seeked to %"G_GINT64_FORMAT,
GST_PLUGIN_FEATURE_NAME (entry->factory), seek_offset);
GST_DEBUG_OBJECT (typefind,
"'%s' was reset - seeked to %" G_GINT64_FORMAT,
GST_PLUGIN_FEATURE_NAME (entry->factory), seek_offset);
break;
} else if (entry->requested_offset < 0) {
/* impossible to seek */
GST_DEBUG_OBJECT (typefind, "'%s' was reset - couldn't seek to %"G_GINT64_FORMAT,
GST_PLUGIN_FEATURE_NAME (entry->factory), seek_offset);
GST_DEBUG_OBJECT (typefind,
"'%s' was reset - couldn't seek to %" G_GINT64_FORMAT,
GST_PLUGIN_FEATURE_NAME (entry->factory), seek_offset);
entry->requested_size = 0;
entry->requested_offset = 0;
}
@ -605,21 +649,26 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
walk = g_list_next (typefind->possibilities);
while (walk) {
GList *cur = walk;
entry = (TypeFindEntry *) walk->data;
walk = g_list_next (walk);
if (entry->requested_size == 0) {
GST_DEBUG_OBJECT (typefind, "'%s' was removed - higher possibilities available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
GST_DEBUG_OBJECT (typefind,
"'%s' was removed - higher possibilities available",
GST_PLUGIN_FEATURE_NAME (entry->factory));
free_entry (entry);
typefind->possibilities = g_list_delete_link (typefind->possibilities, cur);
typefind->possibilities =
g_list_delete_link (typefind->possibilities, cur);
}
}
if (g_list_next (typefind->possibilities) == NULL) {
entry = (TypeFindEntry *) typefind->possibilities->data;
if (entry->probability > typefind->min_probability) {
GST_INFO_OBJECT (typefind, "'%s' is the only typefind left, using it now (probability %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->probability);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, entry->probability, entry->caps);
GST_INFO_OBJECT (typefind,
"'%s' is the only typefind left, using it now (probability %u)",
GST_PLUGIN_FEATURE_NAME (entry->factory), entry->probability);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
0, entry->probability, entry->caps);
free_entry (entry);
g_list_free (typefind->possibilities);
typefind->possibilities = NULL;
@ -635,7 +684,7 @@ gst_type_find_element_chain (GstPad *pad, GstData *data)
}
}
static GstElementStateReturn
gst_type_find_element_change_state (GstElement *element)
gst_type_find_element_change_state (GstElement * element)
{
GstTypeFindElement *typefind;
@ -652,6 +701,6 @@ gst_type_find_element_change_state (GstElement *element)
default:
break;
}
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
}

View file

@ -29,48 +29,44 @@
#include "gstbufferstore.h"
G_BEGIN_DECLS
#define GST_TYPE_TYPE_FIND_ELEMENT (gst_type_find_element_get_type ())
#define GST_TYPE_FIND_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TYPE_FIND_ELEMENT, GstTypeFindElement))
#define GST_IS_TYPE_FIND_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TYPE_FIND_ELEMENT))
#define GST_TYPE_FIND_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TYPE_FIND_ELEMENT, GstTypeFindElementClass))
#define GST_IS_TYPE_FIND_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TYPE_FIND_ELEMENT))
#define GST_TYPE_FIND_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TYPE_FIND_ELEMENT, GstTypeFindElementClass))
typedef struct _GstTypeFindElement GstTypeFindElement;
typedef struct _GstTypeFindElementClass GstTypeFindElementClass;
typedef struct _GstTypeFindElement GstTypeFindElement;
typedef struct _GstTypeFindElementClass GstTypeFindElementClass;
struct _GstTypeFindElement
{
GstElement element;
struct _GstTypeFindElement {
GstElement element;
GstPad *sink;
GstPad *src;
GstPad * sink;
GstPad * src;
guint min_probability;
guint max_probability;
GstCaps *caps;
guint min_probability;
guint max_probability;
GstCaps * caps;
guint mode;
GstBufferStore *store;
guint64 stream_length;
gboolean stream_length_available;
guint mode;
GstBufferStore * store;
guint64 stream_length;
gboolean stream_length_available;
GList * possibilities;
GList *possibilities;
};
struct _GstTypeFindElementClass {
GstElementClass parent_class;
struct _GstTypeFindElementClass
{
GstElementClass parent_class;
/* signals */
void (*have_type) (GstTypeFindElement *element,
guint probability,
const GstCaps * caps);
void (*have_type) (GstTypeFindElement * element,
guint probability, const GstCaps * caps);
};
GType gst_type_find_element_get_type (void);
G_END_DECLS
#endif /* __GST_TYPE_FIND_ELEMENT_H__ */

View file

@ -23,7 +23,7 @@
#ifndef __GST_I18N_APP_H__
#define __GST_I18N_APP_H__
#include "gettext.h" /* included with gettext distribution and copied */
#include "gettext.h" /* included with gettext distribution and copied */
/* we want to use shorthand _() for translating and N_() for marking */
#define _(String) gettext (String)

View file

@ -23,7 +23,7 @@
#ifndef __GST_I18N_LIB_H__
#define __GST_I18N_LIB_H__
#include "gettext.h" /* included with gettext distribution and copied */
#include "gettext.h" /* included with gettext distribution and copied */
#ifndef GETTEXT_PACKAGE
#error You must define GETTEXT_PACKAGE before including this header.

360
gst/gst.c
View file

@ -53,6 +53,7 @@ static gboolean _gst_use_threads = TRUE;
static gboolean _gst_enable_cpu_opt = TRUE;
static gboolean gst_initialized = FALSE;
/* this will be set in popt callbacks when a problem has been encountered */
static gboolean _gst_initialization_failure = FALSE;
extern gint _gst_trace_on;
@ -63,23 +64,20 @@ gboolean _gst_disable_segtrap = FALSE;
extern GThreadFunctions gst_thread_dummy_functions;
static void load_plugin_func (gpointer data, gpointer user_data);
static void init_popt_callback (poptContext context,
enum poptCallbackReason reason,
const GstPoptOption *option,
const char *arg, void *data);
static gboolean init_pre (void);
static gboolean init_post (void);
static void load_plugin_func (gpointer data, gpointer user_data);
static void init_popt_callback (poptContext context,
enum poptCallbackReason reason,
const GstPoptOption * option, const char *arg, void *data);
static gboolean init_pre (void);
static gboolean init_post (void);
static GSList *preload_plugins = NULL;
const gchar *g_log_domain_gstreamer = "GStreamer";
static void
debug_log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
debug_log_handler (const gchar * log_domain,
GLogLevelFlags log_level, const gchar * message, gpointer user_data)
{
g_log_default_handler (log_domain, log_level, message, user_data);
/* FIXME: do we still need this ? fatal errors these days are all
@ -87,8 +85,9 @@ debug_log_handler (const gchar *log_domain,
/* g_on_error_query (NULL); */
}
enum {
ARG_VERSION=1,
enum
{
ARG_VERSION = 1,
ARG_FATAL_WARNINGS,
#ifndef GST_DISABLE_GST_DEBUG
ARG_DEBUG_LEVEL,
@ -114,27 +113,56 @@ enum {
* the GST_SCHEDULER_DEFAULT_NAME define.
*/
static const GstPoptOption gstreamer_options[] = {
{NULL, NUL, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *) &init_popt_callback, 0, NULL, NULL},
{NULL, NUL, POPT_ARG_CALLBACK | POPT_CBFLAG_PRE | POPT_CBFLAG_POST,
(void *) &init_popt_callback, 0, NULL, NULL},
/* make sure we use our GETTEXT_PACKAGE as the domain for popt translations */
{NULL, NUL, POPT_ARG_INTL_DOMAIN, GETTEXT_PACKAGE, 0, NULL, NULL},
{"gst-version", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_VERSION, N_("Print the GStreamer version"), NULL},
{"gst-fatal-warnings", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_FATAL_WARNINGS, N_("Make all warnings fatal"), NULL},
{"gst-version", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL, ARG_VERSION,
N_("Print the GStreamer version"), NULL},
{"gst-fatal-warnings", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_FATAL_WARNINGS, N_("Make all warnings fatal"), NULL},
#ifndef GST_DISABLE_GST_DEBUG
{"gst-debug-help", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_HELP, N_("Print available debug categories and exit"), NULL},
{"gst-debug-level", NUL, POPT_ARG_INT|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_LEVEL, N_("Default debug level from 1 (only error) to 5 (anything) or 0 for no output"), N_("LEVEL")},
{"gst-debug", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG, N_("Comma-separated list of category_name:level pairs to set specific levels for the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3"), N_("LIST")},
{"gst-debug-no-color", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_NO_COLOR, N_("Disable colored debugging output"), NULL},
{"gst-debug-disable", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_DISABLE, N_("Disable debugging")},
{"gst-debug-help", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_DEBUG_HELP, N_("Print available debug categories and exit"), NULL},
{"gst-debug-level", NUL, POPT_ARG_INT | POPT_ARGFLAG_STRIP, NULL,
ARG_DEBUG_LEVEL,
N_
("Default debug level from 1 (only error) to 5 (anything) or 0 for no output"),
N_("LEVEL")},
{"gst-debug", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG,
N_
("Comma-separated list of category_name:level pairs to set specific levels for the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3"),
N_("LIST")},
{"gst-debug-no-color", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_DEBUG_NO_COLOR, N_("Disable colored debugging output"), NULL},
{"gst-debug-disable", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_DEBUG_DISABLE, N_("Disable debugging")},
#endif
{"gst-disable-cpu-opt",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DISABLE_CPU_OPT,N_("Disable accelerated CPU instructions"), NULL},
{"gst-plugin-spew", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_SPEW, N_("Enable verbose plugin loading diagnostics"), NULL},
{"gst-plugin-path", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH, N_("path list for loading plugins (separated by '" G_SEARCHPATH_SEPARATOR_S "')"),N_("PATHS")},
{"gst-plugin-load", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD, N_("Comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"), N_("PLUGINS")},
{"gst-disable-segtrap",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_SEGTRAP_DISABLE,N_("Disable trapping of segmentation faults during plugin loading"), NULL},
{"gst-scheduler", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER, N_("Scheduler to use ('"GST_SCHEDULER_DEFAULT_NAME"' is the default)"), N_("SCHEDULER")},
{"gst-registry", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY, N_("Registry to use") , N_("REGISTRY")},
{"gst-disable-cpu-opt", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_DISABLE_CPU_OPT, N_("Disable accelerated CPU instructions"), NULL},
{"gst-plugin-spew", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_PLUGIN_SPEW, N_("Enable verbose plugin loading diagnostics"), NULL},
{"gst-plugin-path", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
ARG_PLUGIN_PATH,
N_("path list for loading plugins (separated by '"
G_SEARCHPATH_SEPARATOR_S "')"), N_("PATHS")},
{"gst-plugin-load", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
ARG_PLUGIN_LOAD,
N_
("Comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"),
N_("PLUGINS")},
{"gst-disable-segtrap", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
ARG_SEGTRAP_DISABLE,
N_("Disable trapping of segmentation faults during plugin loading"),
NULL},
{"gst-scheduler", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
ARG_SCHEDULER,
N_("Scheduler to use ('" GST_SCHEDULER_DEFAULT_NAME
"' is the default)"), N_("SCHEDULER")},
{"gst-registry", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
ARG_REGISTRY, N_("Registry to use"), N_("REGISTRY")},
POPT_TABLEEND
};
@ -212,13 +240,14 @@ gst_init (int *argc, char **argv[])
*/
void
gst_init_with_popt_table (int *argc, char **argv[],
const GstPoptOption *popt_options)
const GstPoptOption * popt_options)
{
if (!gst_init_check_with_popt_table (argc, argv, popt_options)) {
g_print ("Could not initialize GStreamer !\n");
exit (1);
}
}
/**
* gst_init_check_with_popt_table:
* @argc: pointer to application's argc
@ -233,25 +262,29 @@ gst_init_with_popt_table (int *argc, char **argv[],
*/
gboolean
gst_init_check_with_popt_table (int *argc, char **argv[],
const GstPoptOption *popt_options)
const GstPoptOption * popt_options)
{
poptContext context;
gint nextopt;
GstPoptOption *options;
GstPoptOption options_with[] = {
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0, "GStreamer options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) popt_options, 0, "Application options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:",
NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0,
"GStreamer options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) popt_options, 0,
"Application options:", NULL},
POPT_TABLEEND
};
GstPoptOption options_without[] = {
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0, "GStreamer options:", NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:",
NULL},
{NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0,
"GStreamer options:", NULL},
POPT_TABLEEND
};
if (gst_initialized)
{
if (gst_initialized) {
GST_DEBUG ("already initialized gst");
return TRUE;
}
@ -260,8 +293,10 @@ gst_init_check_with_popt_table (int *argc, char **argv[],
if (argc || argv)
g_warning ("gst_init: Only one of argc or argv was NULL");
if (!init_pre ()) return FALSE;
if (!init_post ()) return FALSE;
if (!init_pre ())
return FALSE;
if (!init_post ())
return FALSE;
gst_initialized = TRUE;
return TRUE;
}
@ -271,21 +306,19 @@ gst_init_check_with_popt_table (int *argc, char **argv[],
} else {
options = options_with;
}
context = poptGetContext ("GStreamer", *argc, (const char**)*argv,
options, 0);
context = poptGetContext ("GStreamer", *argc, (const char **) *argv,
options, 0);
while ((nextopt = poptGetNextOpt (context)) > 0)
{
while ((nextopt = poptGetNextOpt (context)) > 0) {
/* we only check for failures here, actual work is done in callbacks */
if (_gst_initialization_failure) return FALSE;
if (_gst_initialization_failure)
return FALSE;
}
if (nextopt != -1) {
g_print ("Error on option %s: %s.\nRun '%s --help' "
"to see a full list of available command line options.\n",
poptBadOption (context, 0),
poptStrerror (nextopt),
(*argv)[0]);
"to see a full list of available command line options.\n",
poptBadOption (context, 0), poptStrerror (nextopt), (*argv)[0]);
poptFreeContext (context);
return FALSE;
@ -305,7 +338,7 @@ add_path_func (gpointer data, gpointer user_data)
GstRegistry *registry = GST_REGISTRY (user_data);
GST_INFO ("Adding plugin path: \"%s\"", (gchar *) data);
gst_registry_add_path (registry, (gchar *)data);
gst_registry_add_path (registry, (gchar *) data);
}
#endif
@ -316,7 +349,7 @@ prepare_for_load_plugin_func (gpointer data, gpointer user_data)
}
static void
parse_debug_list (const gchar *list)
parse_debug_list (const gchar * list)
{
gchar **split;
gchar **walk;
@ -326,16 +359,18 @@ parse_debug_list (const gchar *list)
walk = split = g_strsplit (list, ",", 0);
while (walk[0]) {
gchar **values = g_strsplit ( walk[0], ":", 2);
gchar **values = g_strsplit (walk[0], ":", 2);
if (values[0] && values[1]) {
gint level = 0;
g_strstrip (values[0]);
g_strstrip (values[1]);
level = strtol (values[1], NULL, 0);
if (level >= 0 && level < GST_LEVEL_COUNT) {
GST_DEBUG ("setting debugging to level %d for name \"%s\"",
level, values[0]);
gst_debug_set_threshold_for_name (values[0], level);
GST_DEBUG ("setting debugging to level %d for name \"%s\"",
level, values[0]);
gst_debug_set_threshold_for_name (values[0], level);
}
}
g_strfreev (values);
@ -365,7 +400,8 @@ load_plugin_func (gpointer data, gpointer user_data)
}
static void
split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator, gpointer user_data)
split_and_iterate (const gchar * stringlist, gchar * separator, GFunc iterator,
gpointer user_data)
{
gchar **strings;
gint j = 0;
@ -379,10 +415,10 @@ split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator, gp
while (strings[j]) {
iterator (strings[j], user_data);
if (++j == MAX_PATH_SPLIT) {
lastlist = g_strdup (strings[j]);
g_strfreev (strings);
j=0;
break;
lastlist = g_strdup (strings[j]);
g_strfreev (strings);
j = 0;
break;
}
}
}
@ -404,7 +440,7 @@ init_pre (void)
g_thread_init (&gst_thread_dummy_functions);
}
/* we need threading to be enabled right here */
_gst_debug_init();
_gst_debug_init ();
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
@ -426,7 +462,8 @@ init_pre (void)
gchar *user_reg;
const gchar *homedir;
_global_registry = gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
_global_registry =
gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
#ifdef PLUGINS_USE_BUILDDIR
/* location libgstelements.so */
@ -434,19 +471,17 @@ init_pre (void)
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/schedulers");
gst_registry_add_path (_global_registry,
PLUGINS_BUILDDIR "/gst/schedulers");
gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/indexers");
#else
/* add the main (installed) library path */
gst_registry_add_path (_global_registry, PLUGINS_DIR);
#endif /* PLUGINS_USE_BUILDDIR */
if (g_getenv ("GST_REGISTRY"))
{
if (g_getenv ("GST_REGISTRY")) {
user_reg = g_strdup (g_getenv ("GST_REGISTRY"));
}
else
{
} else {
homedir = g_get_home_dir ();
user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
}
@ -460,13 +495,17 @@ init_pre (void)
}
static gboolean
gst_register_core_elements (GstPlugin *plugin)
gst_register_core_elements (GstPlugin * plugin)
{
/* register some standard builtin types */
g_assert (gst_element_register (plugin, "bin", GST_RANK_PRIMARY, GST_TYPE_BIN));
g_assert (gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY, GST_TYPE_PIPELINE));
g_assert (gst_element_register (plugin, "thread", GST_RANK_PRIMARY, GST_TYPE_THREAD));
g_assert (gst_element_register (plugin, "queue", GST_RANK_PRIMARY, GST_TYPE_QUEUE));
g_assert (gst_element_register (plugin, "bin", GST_RANK_PRIMARY,
GST_TYPE_BIN));
g_assert (gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY,
GST_TYPE_PIPELINE));
g_assert (gst_element_register (plugin, "thread", GST_RANK_PRIMARY,
GST_TYPE_THREAD));
g_assert (gst_element_register (plugin, "queue", GST_RANK_PRIMARY,
GST_TYPE_QUEUE));
return TRUE;
}
@ -502,6 +541,7 @@ init_post (void)
{
GLogLevelFlags llf;
const gchar *plugin_path;
#ifndef GST_DISABLE_TRACE
GstTrace *gst_trace;
#endif /* GST_DISABLE_TRACE */
@ -510,7 +550,7 @@ init_post (void)
g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
GST_INFO ("Initializing GStreamer Core Library version %s %s",
VERSION, _gst_use_threads ? "" : "(no threads)");
VERSION, _gst_use_threads ? "" : "(no threads)");
_gst_format_initialize ();
_gst_query_type_initialize ();
@ -532,7 +572,8 @@ init_post (void)
plugin_path = g_getenv ("GST_PLUGIN_PATH");
#ifndef GST_DISABLE_REGISTRY
split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func, _global_registry);
split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func,
_global_registry);
#endif /* GST_DISABLE_REGISTRY */
/* register core plugins */
@ -551,7 +592,8 @@ init_post (void)
if (!_gst_registry_fixed) {
/* don't override command-line options */
if (g_getenv ("GST_REGISTRY")) {
g_object_set (_global_registry, "location", g_getenv ("GST_REGISTRY"), NULL);
g_object_set (_global_registry, "location", g_getenv ("GST_REGISTRY"),
NULL);
_gst_registry_fixed = TRUE;
}
}
@ -574,7 +616,6 @@ init_post (void)
g_slist_free (preload_plugins);
preload_plugins = NULL;
}
#ifndef GST_DISABLE_TRACE
_gst_trace_on = 0;
if (_gst_trace_on) {
@ -594,7 +635,7 @@ static gint
sort_by_category_name (gconstpointer a, gconstpointer b)
{
return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
gst_debug_category_get_name ((GstDebugCategory *) b));
gst_debug_category_get_name ((GstDebugCategory *) b));
}
static void
gst_debug_help (void)
@ -608,14 +649,18 @@ gst_debug_help (void)
walk2 = list2 = gst_registry_pool_plugin_list ();
while (walk2) {
GstPlugin *plugin = GST_PLUGIN (walk2->data);
walk2 = g_list_next (walk2);
if (!gst_plugin_is_loaded (plugin)) {
#ifndef GST_DISABLE_REGISTRY
if (GST_IS_REGISTRY (plugin->manager)) {
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s", plugin->desc.name);
if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager), plugin) != GST_REGISTRY_OK)
GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed", plugin->desc.name);
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s",
plugin->desc.name);
if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager),
plugin) != GST_REGISTRY_OK)
GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed",
plugin->desc.name);
}
#endif /* GST_DISABLE_REGISTRY */
}
@ -634,19 +679,19 @@ gst_debug_help (void)
if (gst_debug_is_colored ()) {
gchar *color = gst_debug_construct_term_color (cat->color);
g_print ("%s%-20s\033[00m %1d %s %s%s\033[00m\n",
color,
gst_debug_category_get_name (cat),
gst_debug_category_get_threshold (cat),
gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
color,
gst_debug_category_get_description (cat));
color,
gst_debug_category_get_name (cat),
gst_debug_category_get_threshold (cat),
gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
color, gst_debug_category_get_description (cat));
g_free (color);
} else {
g_print ("%-20s %1d %s %s\n", gst_debug_category_get_name (cat),
gst_debug_category_get_threshold (cat),
gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
gst_debug_category_get_description (cat));
gst_debug_category_get_threshold (cat),
gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
gst_debug_category_get_description (cat));
}
walk = g_slist_next (walk);
}
@ -657,82 +702,86 @@ gst_debug_help (void)
static void
init_popt_callback (poptContext context, enum poptCallbackReason reason,
const GstPoptOption *option, const char *arg, void *data)
const GstPoptOption * option, const char *arg, void *data)
{
GLogLevelFlags fatal_mask;
if (gst_initialized)
return;
switch (reason) {
case POPT_CALLBACK_REASON_PRE:
if (!init_pre ()) _gst_initialization_failure = TRUE;
break;
case POPT_CALLBACK_REASON_OPTION:
switch (option->val) {
case ARG_VERSION:
g_print ("GStreamer Core Library version %s\n", GST_VERSION);
exit (0);
case ARG_FATAL_WARNINGS:
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
case POPT_CALLBACK_REASON_PRE:
if (!init_pre ())
_gst_initialization_failure = TRUE;
break;
case POPT_CALLBACK_REASON_OPTION:
switch (option->val) {
case ARG_VERSION:
g_print ("GStreamer Core Library version %s\n", GST_VERSION);
exit (0);
case ARG_FATAL_WARNINGS:
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
break;
#ifndef GST_DISABLE_GST_DEBUG
case ARG_DEBUG_LEVEL: {
gint tmp = 0;
tmp = strtol (arg, NULL, 0);
if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
gst_debug_set_default_threshold (tmp);
case ARG_DEBUG_LEVEL:{
gint tmp = 0;
tmp = strtol (arg, NULL, 0);
if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
gst_debug_set_default_threshold (tmp);
}
break;
}
case ARG_DEBUG:
parse_debug_list (arg);
break;
case ARG_DEBUG_NO_COLOR:
gst_debug_set_colored (FALSE);
break;
case ARG_DEBUG_DISABLE:
gst_debug_set_active (FALSE);
break;
case ARG_DEBUG_HELP:
gst_debug_help ();
exit (0);
#endif
case ARG_DISABLE_CPU_OPT:
_gst_enable_cpu_opt = FALSE;
break;
case ARG_PLUGIN_SPEW:
break;
case ARG_PLUGIN_PATH:
#ifndef GST_DISABLE_REGISTRY
split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func,
_user_registry);
#endif /* GST_DISABLE_REGISTRY */
break;
case ARG_PLUGIN_LOAD:
split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
break;
case ARG_SEGTRAP_DISABLE:
_gst_disable_segtrap = TRUE;
break;
case ARG_SCHEDULER:
gst_scheduler_factory_set_default_name (arg);
break;
case ARG_REGISTRY:
#ifndef GST_DISABLE_REGISTRY
g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
_gst_registry_fixed = TRUE;
#endif /* GST_DISABLE_REGISTRY */
break;
default:
g_warning ("option %d not recognized", option->val);
break;
}
break;
}
case ARG_DEBUG:
parse_debug_list (arg);
case POPT_CALLBACK_REASON_POST:
if (!init_post ())
_gst_initialization_failure = TRUE;
gst_initialized = TRUE;
break;
case ARG_DEBUG_NO_COLOR:
gst_debug_set_colored (FALSE);
break;
case ARG_DEBUG_DISABLE:
gst_debug_set_active (FALSE);
break;
case ARG_DEBUG_HELP:
gst_debug_help ();
exit (0);
#endif
case ARG_DISABLE_CPU_OPT:
_gst_enable_cpu_opt = FALSE;
break;
case ARG_PLUGIN_SPEW:
break;
case ARG_PLUGIN_PATH:
#ifndef GST_DISABLE_REGISTRY
split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
#endif /* GST_DISABLE_REGISTRY */
break;
case ARG_PLUGIN_LOAD:
split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
break;
case ARG_SEGTRAP_DISABLE:
_gst_disable_segtrap = TRUE;
break;
case ARG_SCHEDULER:
gst_scheduler_factory_set_default_name (arg);
break;
case ARG_REGISTRY:
#ifndef GST_DISABLE_REGISTRY
g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
_gst_registry_fixed = TRUE;
#endif /* GST_DISABLE_REGISTRY */
break;
default:
g_warning ("option %d not recognized", option->val);
break;
}
break;
case POPT_CALLBACK_REASON_POST:
if (!init_post ()) _gst_initialization_failure = TRUE;
gst_initialized = TRUE;
break;
}
}
@ -802,6 +851,7 @@ gst_main_quit (void)
g_error ("Quit more loops than there are");
else {
GMainLoop *loop = mainloops->data;
mainloops = g_slist_delete_link (mainloops, mainloops);
g_main_loop_quit (loop);
g_main_loop_unref (loop);
@ -817,7 +867,7 @@ gst_main_quit (void)
* Gets the version number of the GStreamer library.
*/
void
gst_version (guint *major, guint *minor, guint *micro)
gst_version (guint * major, guint * minor, guint * micro)
{
g_return_if_fail (major);
g_return_if_fail (minor);

View file

@ -69,31 +69,26 @@
#include <gst/gstcompat.h>
G_BEGIN_DECLS
/* make our own type for poptOption because the struct poptOption
* definition is iffy */
typedef struct poptOption GstPoptOption;
/* initialize GST */
void gst_init (int *argc, char **argv[]);
gboolean gst_init_check (int *argc, char **argv[]);
void gst_init_with_popt_table (int *argc, char **argv[],
const GstPoptOption
*popt_options);
gboolean gst_init_check_with_popt_table (int *argc, char **argv[],
const GstPoptOption
*popt_options);
void gst_init (int *argc, char **argv[]);
gboolean gst_init_check (int *argc, char **argv[]);
void gst_init_with_popt_table (int *argc, char **argv[],
const GstPoptOption * popt_options);
gboolean gst_init_check_with_popt_table (int *argc, char **argv[],
const GstPoptOption * popt_options);
const GstPoptOption * gst_init_get_popt_table (void);
const GstPoptOption *gst_init_get_popt_table (void);
void gst_use_threads (gboolean use_threads);
gboolean gst_has_threads (void);
void gst_use_threads (gboolean use_threads);
gboolean gst_has_threads (void);
void gst_main (void);
void gst_main_quit (void);
void gst_main (void);
void gst_main_quit (void);
G_END_DECLS
#include <gst/gstlog.h>
#endif /* __GST_H__ */

View file

@ -47,17 +47,18 @@
#define GST_ARCH_SET_SP(stackpointer) \
__asm__("lwz r1,%0" : : "m"(stackpointer))
#define GST_ARCH_CALL(target) \
__asm__( "mr r0,%0\n\t" \
"mtlr r0\n\t" \
"blrl" : : "r"(target) );
struct minimal_ppc_stackframe {
unsigned long back_chain;
unsigned long LR_save;
unsigned long unused1;
unsigned long unused2;
struct minimal_ppc_stackframe
{
unsigned long back_chain;
unsigned long LR_save;
unsigned long unused1;
unsigned long unused2;
};
#define GST_ARCH_SETUP_STACK(sp) \
@ -79,11 +80,12 @@ struct minimal_ppc_stackframe {
/* Need to get more information about the stackframe format
* and get the fields more correct. Check GDB sources maybe?
*/
struct minimal_stackframe {
unsigned long back_chain;
unsigned long LR_save;
unsigned long unused1;
unsigned long unused2;
struct minimal_stackframe
{
unsigned long back_chain;
unsigned long LR_save;
unsigned long unused1;
unsigned long unused2;
};
#define GST_ARCH_SETUP_STACK(sp) \
@ -141,7 +143,7 @@ struct minimal_stackframe {
/* assuming the stackframe is 16 bytes */
#define GST_ARCH_SETUP_STACK(sp) sp -= 4
/***** HP-PA *****/
@ -167,11 +169,12 @@ struct minimal_stackframe {
#define GST_ARCH_CALL(target) \
__asm__( "basr 14,%0" : : "a"(target) );
struct minimal_s390_stackframe {
unsigned long back_chain;
unsigned long reserved;
unsigned long greg[14];
double freg[4];
struct minimal_s390_stackframe
{
unsigned long back_chain;
unsigned long reserved;
unsigned long greg[14];
double freg[4];
};
#define GST_ARCH_SETUP_STACK(sp) \

View file

@ -22,4 +22,3 @@
#include "gstatomic.h"
#include "gstatomic_impl.h"

View file

@ -22,27 +22,25 @@
#include <glib.h>
G_BEGIN_DECLS
typedef volatile gint gst_vgint; /* gtk-doc volatile workaround */
G_BEGIN_DECLS typedef volatile gint gst_vgint; /* gtk-doc volatile workaround */
typedef struct _GstAtomicInt GstAtomicInt;
struct _GstAtomicInt {
gst_vgint counter;
GMutex *lock; /* for C fallback */
struct _GstAtomicInt
{
gst_vgint counter;
GMutex *lock; /* for C fallback */
};
void gst_atomic_int_init (GstAtomicInt *aint, gint val);
void gst_atomic_int_destroy (GstAtomicInt *aint);
void gst_atomic_int_set (GstAtomicInt *aint, gint val);
gint gst_atomic_int_read (GstAtomicInt *aint);
void gst_atomic_int_add (GstAtomicInt *aint, gint val);
void gst_atomic_int_inc (GstAtomicInt *aint);
gboolean gst_atomic_int_dec_and_test (GstAtomicInt *aint);
void gst_atomic_int_init (GstAtomicInt * aint, gint val);
void gst_atomic_int_destroy (GstAtomicInt * aint);
void gst_atomic_int_set (GstAtomicInt * aint, gint val);
gint gst_atomic_int_read (GstAtomicInt * aint);
void gst_atomic_int_add (GstAtomicInt * aint, gint val);
void gst_atomic_int_inc (GstAtomicInt * aint);
gboolean gst_atomic_int_dec_and_test (GstAtomicInt * aint);
G_END_DECLS
#endif /* __GST_ATOMIC_H__ */

View file

@ -34,57 +34,62 @@
#include "gstmacros.h"
G_BEGIN_DECLS
#if defined (GST_CAN_INLINE) || defined (__GST_ATOMIC_C__)
/***** Intel x86 *****/
#if defined (HAVE_CPU_I386) && defined(__GNUC__)
#ifdef GST_CONFIG_NO_SMP
#define SMP_LOCK ""
#else
#define SMP_LOCK "lock ; "
#endif
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
__asm__ __volatile__(
SMP_LOCK "addl %1,%0"
:"=m" (aint->counter)
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
__asm__ __volatile__ (SMP_LOCK "addl %1,%0":"=m" (aint->counter)
:"ir" (val), "m" (aint->counter));
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
__asm__ __volatile__(
SMP_LOCK "incl %0"
:"=m" (aint->counter)
__asm__ __volatile__ (SMP_LOCK "incl %0":"=m" (aint->counter)
:"m" (aint->counter));
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
guchar res;
__asm__ __volatile__(
SMP_LOCK "decl %0; sete %1"
:"=m" (aint->counter), "=qm" (res)
:"m" (aint->counter) : "memory");
__asm__ __volatile__ (SMP_LOCK "decl %0; sete %1":"=m" (aint->counter),
"=qm" (res)
:"m" (aint->counter):"memory");
return res != 0;
}
/***** PowerPC *****/
#elif defined (HAVE_CPU_PPC) && defined(__GNUC__)
#ifdef GST_CONFIG_NO_SMP
#define SMP_SYNC ""
#define SMP_ISYNC
@ -92,7 +97,6 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
#define SMP_SYNC "\tsync\n"
#define SMP_ISYNC "\tisync\n"
#endif
/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
* The old ATOMIC_SYNC_FIX covered some but not all of this.
*/
@ -101,111 +105,123 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
#else
#define PPC405_ERR77(ra,rb)
#endif
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
int t;
__asm__ __volatile__(
"1: lwarx %0,0,%3\n"
" add %0,%2,%0\n"
PPC405_ERR77(0,%3)
" stwcx. %0,0,%3 \n"
" bne- 1b\n"
: "=&r" (t), "=m" (aint->counter)
: "r" (val), "r" (&aint->counter), "m" (aint->counter)
: "cc");
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
int t;
__asm__ __volatile__(
"1: lwarx %0,0,%2\n"
" addic %0,%0,1\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2\n"
" bne- 1b\n"
: "=&r" (t), "=m" (aint->counter)
: "r" (&aint->counter), "m" (aint->counter)
: "cc");
__asm__ __volatile__ ("1: lwarx %0,0,%3\n"
" add %0,%2,%0\n" PPC405_ERR77 (0, %3)
" stwcx. %0,0,%3 \n"
" bne- 1b\n":"=&r" (t), "=m" (aint->counter)
:"r" (val), "r" (&aint->counter), "m" (aint->counter)
:"cc");
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt * aint)
{
int t;
__asm__ __volatile__ ("1: lwarx %0,0,%2\n"
" addic %0,%0,1\n" PPC405_ERR77 (0, %2)
" stwcx. %0,0,%2\n"
" bne- 1b\n":"=&r" (t), "=m" (aint->counter)
:"r" (&aint->counter), "m" (aint->counter)
:"cc");
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
int t;
__asm__ __volatile__(
"1: lwarx %0,0,%1\n"
" addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n"
" bne- 1b\n"
SMP_ISYNC
: "=&r" (t)
: "r" (&aint->counter)
: "cc", "memory");
__asm__ __volatile__ ("1: lwarx %0,0,%1\n"
" addic %0,%0,-1\n" PPC405_ERR77 (0, %1)
" stwcx. %0,0,%1\n" " bne- 1b\n" SMP_ISYNC:"=&r" (t)
:"r" (&aint->counter)
:"cc", "memory");
return t == 0;
}
/***** DEC[/Compaq/HP?/Intel?] Alpha *****/
#elif defined(HAVE_CPU_ALPHA) && defined(__GNUC__)
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
unsigned long temp;
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" addl %0,%2,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (aint->counter)
__asm__ __volatile__ ("1: ldl_l %0,%1\n"
" addl %0,%2,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
".subsection 2\n"
"2: br 1b\n" ".previous":"=&r" (temp), "=m" (aint->counter)
:"Ir" (val), "m" (aint->counter));
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
gst_atomic_int_add (aint, 1);
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
long temp, result;
int val = 1;
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" subl %0,%3,%2\n"
" subl %0,%3,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
" mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (aint->counter), "=&r" (result)
:"Ir" (val), "m" (aint->counter) : "memory");
__asm__ __volatile__ ("1: ldl_l %0,%1\n"
" subl %0,%3,%2\n"
" subl %0,%3,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
" mb\n"
".subsection 2\n"
"2: br 1b\n"
".previous":"=&r" (temp), "=m" (aint->counter), "=&r" (result)
:"Ir" (val), "m" (aint->counter):"memory");
return result == 0;
}
@ -213,16 +229,38 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
/***** Sun SPARC *****/
#elif 0 && defined(HAVE_CPU_SPARC) && defined(__GNUC__)
/* allegedly broken again */
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
#ifdef GST_CONFIG_NO_SMP
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
#else
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = (val<<8); }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = (val<<8); }
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = (val << 8);
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = (val << 8);
}
/*
* For SMP the trick is you embed the spin lock byte within
@ -235,8 +273,8 @@ GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint-
* 31 8 7 0
*/
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt *aint)
{
gst_atomic_int_read (GstAtomicInt * aint)
{
int ret = aint->counter;
while (ret & 0xff)
@ -246,8 +284,8 @@ gst_atomic_int_read (GstAtomicInt *aint)
}
#endif /* GST_CONFIG_NO_SMP */
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
volatile int increment, *ptr;
int lock = 1;
@ -256,41 +294,28 @@ gst_atomic_int_add (GstAtomicInt *aint, gint val)
ptr = &(aint->counter);
#if __GNUC__ > 3 || (__GNUC__ >=3 && __GNUC_MINOR__ >= 2)
__asm__ __volatile__("1: ldstub [%[ptr] + 3], %[lock]\n"
"\torcc %[lock], 0, %[ignore]\n"
"\tbne 1b\n" /* go back until we have the lock */
"\tld [%[ptr]], %[inc]\n"
"\tsra %[inc], 8, %[inc]\n"
"\tadd %[inc], %[val], %[inc]\n"
"\tsll %[inc], 8, %[lock]\n"
"\tst %[lock],[%[ptr]]\n" /* Release the lock */
: [inc] "=&r" (increment), [lock] "=r" (lock),
[ignore] "=&r" (ignore)
: "0" (increment), [ptr] "r" (ptr), [val] "r" (val)
);
__asm__ __volatile__ ("1: ldstub [%[ptr] + 3], %[lock]\n" "\torcc %[lock], 0, %[ignore]\n" "\tbne 1b\n" /* go back until we have the lock */
"\tld [%[ptr]], %[inc]\n" "\tsra %[inc], 8, %[inc]\n" "\tadd %[inc], %[val], %[inc]\n" "\tsll %[inc], 8, %[lock]\n" "\tst %[lock],[%[ptr]]\n" /* Release the lock */
:[inc] "=&r" (increment),[lock] "=r" (lock),[ignore] "=&r" (ignore)
:"0" (increment),[ptr] "r" (ptr),[val] "r" (val)
);
#else
__asm__ __volatile__("1: ldstub [%4 + 3], %1\n"
"\torcc %1, 0, %2\n"
"\tbne 1b\n" /* go back until we have the lock */
"\tld [%4], %0\n"
"\tsra %0, 8, %0\n"
"\tadd %0, %5, %0\n"
"\tsll %0, 8, %1\n"
"\tst %1,[%4]\n" /* Release the lock */
: "=&r" (increment), "=r" (lock), "=&r" (ignore)
: "0" (increment), "r" (ptr), "r" (val)
);
__asm__ __volatile__ ("1: ldstub [%4 + 3], %1\n" "\torcc %1, 0, %2\n" "\tbne 1b\n" /* go back until we have the lock */
"\tld [%4], %0\n" "\tsra %0, 8, %0\n" "\tadd %0, %5, %0\n" "\tsll %0, 8, %1\n" "\tst %1,[%4]\n" /* Release the lock */
:"=&r" (increment), "=r" (lock), "=&r" (ignore)
:"0" (increment), "r" (ptr), "r" (val)
);
#endif
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
gst_atomic_int_add (aint, 1);
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
volatile int increment, *ptr;
int lock = 1;
@ -299,30 +324,17 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
ptr = &aint->counter;
#if __GNUC__ > 3 || (__GNUC__ >=3 && __GNUC_MINOR__ >= 2)
__asm__ __volatile__("1: ldstub [%[ptr] + 3], %[lock]\n"
"\torcc %[lock], 0, %[ignore]\n"
"\tbne 1b\n" /* go back until we have the lock */
"\tld [%[ptr]], %[inc]\n"
"\tsra %[inc], 8, %[inc]\n"
"\tsub %[inc], 1, %[inc]\n"
"\tsll %[inc], 8, %[lock]\n"
"\tst %[lock],[%[ptr]]\n" /* Release the lock */
: [inc] "=&r" (increment), [lock] "=r" (lock),
[ignore] "=&r" (ignore)
: "0" (increment), [ptr] "r" (ptr)
);
__asm__ __volatile__ ("1: ldstub [%[ptr] + 3], %[lock]\n" "\torcc %[lock], 0, %[ignore]\n" "\tbne 1b\n" /* go back until we have the lock */
"\tld [%[ptr]], %[inc]\n" "\tsra %[inc], 8, %[inc]\n" "\tsub %[inc], 1, %[inc]\n" "\tsll %[inc], 8, %[lock]\n" "\tst %[lock],[%[ptr]]\n" /* Release the lock */
:[inc] "=&r" (increment),[lock] "=r" (lock),[ignore] "=&r" (ignore)
:"0" (increment),[ptr] "r" (ptr)
);
#else
__asm__ __volatile__("1: ldstub [%4 + 3], %1\n"
"\torcc %1, 0, %2\n"
"\tbne 1b\n" /* go back until we have the lock */
"\tld [%4], %0\n"
"\tsra %0, 8, %0\n"
"\tsub %0, 1, %0\n"
"\tsll %0, 8, %1\n"
"\tst %1,[%4]\n" /* Release the lock */
: "=&r" (increment), "=r" (lock), "=&r" (ignore)
: "0" (increment), "r" (ptr)
);
__asm__ __volatile__ ("1: ldstub [%4 + 3], %1\n" "\torcc %1, 0, %2\n" "\tbne 1b\n" /* go back until we have the lock */
"\tld [%4], %0\n" "\tsra %0, 8, %0\n" "\tsub %0, 1, %0\n" "\tsll %0, 8, %1\n" "\tst %1,[%4]\n" /* Release the lock */
:"=&r" (increment), "=r" (lock), "=&r" (ignore)
:"0" (increment), "r" (ptr)
);
#endif
return increment == 0;
@ -332,63 +344,93 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
/* This is disabled because the asm code is broken on most MIPS
* processors and doesn't generally compile. */
#elif defined(HAVE_CPU_MIPS) && defined(__GNUC__) && 0
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
/* this only works on MIPS II and better */
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
unsigned long temp;
__asm__ __volatile__(
"1: ll %0, %1 # atomic_add\n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
: "=&r" (temp), "=m" (aint->counter)
: "Ir" (val), "m" (aint->counter));
__asm__ __volatile__ ("1: ll %0, %1 # atomic_add\n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n":"=&r" (temp),
"=m" (aint->counter)
:"Ir" (val), "m" (aint->counter));
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
gst_atomic_int_add (aint, 1);
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
unsigned long temp, result;
int val = 1;
__asm__ __volatile__(
".set push \n"
".set noreorder # atomic_sub_return\n"
"1: ll %1, %2 \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
".set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (aint->counter)
: "Ir" (val), "m" (aint->counter)
: "memory");
__asm__ __volatile__ (".set push \n"
".set noreorder # atomic_sub_return\n"
"1: ll %1, %2 \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
".set pop \n":"=&r" (result),
"=&r" (temp), "=m" (aint->counter)
:"Ir" (val), "m" (aint->counter)
:"memory");
return result == 0;
}
/***** S/390 *****/
#elif defined(HAVE_CPU_S390) && defined(__GNUC__)
typedef struct { volatile int counter; } atomic_t __attribute__ ((aligned (4)));
typedef struct
{
volatile int counter;
} atomic_t __attribute__ ((aligned (4)));
GST_INLINE_FUNC void gst_atomic_int_init (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC void gst_atomic_int_destroy (GstAtomicInt *aint) { }
GST_INLINE_FUNC void gst_atomic_int_set (GstAtomicInt *aint, gint val) { aint->counter = val; }
GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->counter; }
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt * aint)
{
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
aint->counter = val;
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt * aint)
{
return aint->counter;
}
#define __CS_LOOP(old_val, new_val, ptr, op_val, op_string) \
__asm__ __volatile__(" l %0,0(%3)\n" \
@ -400,49 +442,51 @@ GST_INLINE_FUNC gint gst_atomic_int_read (GstAtomicInt *aint) { return aint->c
"+m" (((atomic_t *)(ptr))->counter) \
: "a" (ptr), "d" (op_val) : "cc" );
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
int old_val, new_val;
__CS_LOOP(old_val, new_val, aint, val, "ar");
__CS_LOOP (old_val, new_val, aint, val, "ar");
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
int old_val, new_val;
__CS_LOOP(old_val, new_val, aint, 1, "ar");
__CS_LOOP (old_val, new_val, aint, 1, "ar");
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
int old_val, new_val;
__CS_LOOP(old_val, new_val, aint, 1, "sr");
__CS_LOOP (old_val, new_val, aint, 1, "sr");
return new_val == 0;
}
#else
#else
#warning consider putting your architecture specific atomic implementations here
/*
* generic implementation
*/
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_init (GstAtomicInt * aint, gint val)
{
aint->counter = val;
aint->lock = g_mutex_new ();
}
GST_INLINE_FUNC void
gst_atomic_int_destroy (GstAtomicInt *aint)
gst_atomic_int_destroy (GstAtomicInt * aint)
{
g_mutex_free (aint->lock);
}
GST_INLINE_FUNC void
gst_atomic_int_set (GstAtomicInt *aint, gint val)
gst_atomic_int_set (GstAtomicInt * aint, gint val)
{
g_mutex_lock (aint->lock);
aint->counter = val;
@ -450,7 +494,7 @@ gst_atomic_int_set (GstAtomicInt *aint, gint val)
}
GST_INLINE_FUNC gint
gst_atomic_int_read (GstAtomicInt *aint)
gst_atomic_int_read (GstAtomicInt * aint)
{
gint res;
@ -461,8 +505,8 @@ gst_atomic_int_read (GstAtomicInt *aint)
return res;
}
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt *aint, gint val)
GST_INLINE_FUNC void
gst_atomic_int_add (GstAtomicInt * aint, gint val)
{
g_mutex_lock (aint->lock);
aint->counter += val;
@ -470,7 +514,7 @@ gst_atomic_int_add (GstAtomicInt *aint, gint val)
}
GST_INLINE_FUNC void
gst_atomic_int_inc (GstAtomicInt *aint)
gst_atomic_int_inc (GstAtomicInt * aint)
{
g_mutex_lock (aint->lock);
aint->counter++;
@ -478,10 +522,10 @@ gst_atomic_int_inc (GstAtomicInt *aint)
}
GST_INLINE_FUNC gboolean
gst_atomic_int_dec_and_test (GstAtomicInt *aint)
gst_atomic_int_dec_and_test (GstAtomicInt * aint)
{
gboolean res;
g_mutex_lock (aint->lock);
aint->counter--;
res = (aint->counter == 0);
@ -490,11 +534,11 @@ gst_atomic_int_dec_and_test (GstAtomicInt *aint)
return res;
}
#endif
#endif
/*
* common functions
*/
GST_INLINE_FUNC GstAtomicInt*
*/
GST_INLINE_FUNC GstAtomicInt *
gst_atomic_int_new (gint val)
{
GstAtomicInt *aint;
@ -506,14 +550,13 @@ gst_atomic_int_new (gint val)
}
GST_INLINE_FUNC void
gst_atomic_int_free (GstAtomicInt *aint)
gst_atomic_int_free (GstAtomicInt * aint)
{
gst_atomic_int_destroy (aint);
g_free (aint);
}
#endif /* defined (GST_CAN_INLINE) || defined (__GST_TRASH_STACK_C__)*/
#endif /* defined (GST_CAN_INLINE) || defined (__GST_TRASH_STACK_C__) */
G_END_DECLS
#endif /* __GST_ATOMIC_IMPL_H__ */

View file

@ -33,40 +33,38 @@
#include "gstscheduler.h"
#include "gstindex.h"
static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS (
"Generic bin",
"Generic/Bin",
"Simple container object",
"Erik Walthinsen <omega@cse.ogi.edu>"
);
static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin",
"Generic/Bin",
"Simple container object",
"Erik Walthinsen <omega@cse.ogi.edu>");
GType _gst_bin_type = 0;
static gboolean _gst_boolean_did_something_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu, const GValue *handler_return, gpointer dummy);
static gboolean _gst_boolean_did_something_accumulator (GSignalInvocationHint *
ihint, GValue * return_accu, const GValue * handler_return, gpointer dummy);
static void gst_bin_dispose (GObject * object);
static void gst_bin_dispose (GObject * object);
static GstElementStateReturn gst_bin_change_state (GstElement *element);
static GstElementStateReturn gst_bin_change_state_norecurse (GstBin *bin);
static GstElementStateReturn gst_bin_change_state (GstElement * element);
static GstElementStateReturn gst_bin_change_state_norecurse (GstBin * bin);
#ifndef GST_DISABLE_INDEX
static void gst_bin_set_index (GstElement *element, GstIndex *index);
static void gst_bin_set_index (GstElement * element, GstIndex * index);
#endif
static void gst_bin_add_func (GstBin *bin, GstElement *element);
static void gst_bin_remove_func (GstBin *bin, GstElement *element);
static void gst_bin_child_state_change_func (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *child);
static void gst_bin_add_func (GstBin * bin, GstElement * element);
static void gst_bin_remove_func (GstBin * bin, GstElement * element);
static void gst_bin_child_state_change_func (GstBin * bin,
GstElementState oldstate, GstElementState newstate, GstElement * child);
static GstClock* gst_bin_get_clock_func (GstElement *element);
static void gst_bin_set_clock_func (GstElement *element, GstClock *clock);
static GstClock *gst_bin_get_clock_func (GstElement * element);
static void gst_bin_set_clock_func (GstElement * element, GstClock * clock);
static gboolean gst_bin_iterate_func (GstBin *bin);
static gboolean gst_bin_iterate_func (GstBin * bin);
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
#endif
/* Bin signals and args */
@ -81,12 +79,12 @@ enum
enum
{
ARG_0
/* FILL ME */
/* FILL ME */
};
static void gst_bin_base_init (gpointer g_class);
static void gst_bin_class_init (GstBinClass * klass);
static void gst_bin_init (GstBin * bin);
static void gst_bin_base_init (gpointer g_class);
static void gst_bin_class_init (GstBinClass * klass);
static void gst_bin_init (GstBin * bin);
static GstElementClass *parent_class = NULL;
static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
@ -108,7 +106,8 @@ gst_bin_get_type (void)
NULL
};
_gst_bin_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
_gst_bin_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
}
return _gst_bin_type;
}
@ -117,7 +116,7 @@ static void
gst_bin_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_bin_details);
}
@ -135,40 +134,42 @@ gst_bin_class_init (GstBinClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gst_bin_signals[ELEMENT_ADDED] =
g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstBinClass, element_added), NULL, NULL,
gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
gst_bin_signals[ELEMENT_REMOVED] =
g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstBinClass, element_removed), NULL, NULL,
gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
gst_bin_signals[ITERATE] =
g_signal_new ("iterate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBinClass, iterate),
_gst_boolean_did_something_accumulator, NULL,
gst_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0);
g_signal_new ("iterate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBinClass, iterate),
_gst_boolean_did_something_accumulator, NULL, gst_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
#ifndef GST_DISABLE_LOADSAVE
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
gstobject_class->restore_thyself =
GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
#endif
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
#ifndef GST_DISABLE_INDEX
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index);
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index);
#endif
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
klass->child_state_change = GST_DEBUG_FUNCPTR (gst_bin_child_state_change_func);
klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
klass->child_state_change =
GST_DEBUG_FUNCPTR (gst_bin_child_state_change_func);
klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
}
static gboolean
_gst_boolean_did_something_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu, const GValue *handler_return, gpointer dummy)
_gst_boolean_did_something_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer dummy)
{
gboolean did_something;
@ -205,19 +206,19 @@ gst_bin_new (const gchar * name)
return gst_element_factory_make ("bin", name);
}
static GstClock*
gst_bin_get_clock_func (GstElement *element)
static GstClock *
gst_bin_get_clock_func (GstElement * element)
{
if (GST_ELEMENT_SCHED (element))
if (GST_ELEMENT_SCHED (element))
return gst_scheduler_get_clock (GST_ELEMENT_SCHED (element));
return NULL;
}
static void
gst_bin_set_clock_func (GstElement *element, GstClock *clock)
gst_bin_set_clock_func (GstElement * element, GstClock * clock)
{
if (GST_ELEMENT_SCHED (element))
if (GST_ELEMENT_SCHED (element))
gst_scheduler_use_clock (GST_ELEMENT_SCHED (element), clock);
}
@ -229,8 +230,8 @@ gst_bin_set_clock_func (GstElement *element, GstClock *clock)
*
* Returns: the #GstClock of the bin
*/
GstClock*
gst_bin_get_clock (GstBin *bin)
GstClock *
gst_bin_get_clock (GstBin * bin)
{
g_return_val_if_fail (bin != NULL, NULL);
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
@ -247,7 +248,7 @@ gst_bin_get_clock (GstBin *bin)
* force it to use no clock at all.
*/
void
gst_bin_use_clock (GstBin *bin, GstClock *clock)
gst_bin_use_clock (GstBin * bin, GstClock * clock)
{
g_return_if_fail (GST_IS_BIN (bin));
@ -261,20 +262,20 @@ gst_bin_use_clock (GstBin *bin, GstClock *clock)
* Let the bin select a clock automatically.
*/
void
gst_bin_auto_clock (GstBin *bin)
gst_bin_auto_clock (GstBin * bin)
{
g_return_if_fail (GST_IS_BIN (bin));
if (GST_ELEMENT_SCHED (bin))
if (GST_ELEMENT_SCHED (bin))
gst_scheduler_auto_clock (GST_ELEMENT_SCHED (bin));
}
#ifndef GST_DISABLE_INDEX
static void
gst_bin_set_index (GstElement *element, GstIndex *index)
gst_bin_set_index (GstElement * element, GstIndex * index)
{
GstBin *bin = GST_BIN (element);
g_return_if_fail (GST_IS_BIN (bin));
g_list_foreach (bin->children, (GFunc) gst_element_set_index, index);
@ -282,27 +283,28 @@ gst_bin_set_index (GstElement *element, GstIndex *index)
#endif
static void
gst_bin_set_element_sched (GstElement *element, GstScheduler *sched)
gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
{
GST_CAT_LOG (GST_CAT_SCHEDULING, "setting element \"%s\" sched to %p",
GST_ELEMENT_NAME (element), sched);
GST_ELEMENT_NAME (element), sched);
/* if it's actually a Bin */
if (GST_IS_BIN (element)) {
if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element,
"child is already a manager, not resetting sched");
"child is already a manager, not resetting sched");
if (GST_ELEMENT_SCHED (element))
gst_scheduler_add_scheduler (sched, GST_ELEMENT_SCHED (element));
gst_scheduler_add_scheduler (sched, GST_ELEMENT_SCHED (element));
return;
}
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element,
"setting child bin's scheduler to be the same as the parent's");
"setting child bin's scheduler to be the same as the parent's");
gst_scheduler_add_element (sched, element);
/* set the children's schedule */
g_list_foreach (GST_BIN (element)->children, (GFunc) gst_bin_set_element_sched, sched);
g_list_foreach (GST_BIN (element)->children,
(GFunc) gst_bin_set_element_sched, sched);
}
/* otherwise, if it's just a regular old element */
else {
@ -320,19 +322,19 @@ gst_bin_set_element_sched (GstElement *element, GstScheduler *sched)
/* we only operate on real pads */
if (!GST_IS_REAL_PAD (pad))
continue;
continue;
/* if the peer element exists and is a candidate */
if (GST_PAD_PEER (pad)) {
if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) {
GST_CAT_LOG (GST_CAT_SCHEDULING,
"peer is in same scheduler, telling scheduler");
if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) {
GST_CAT_LOG (GST_CAT_SCHEDULING,
"peer is in same scheduler, telling scheduler");
if (GST_PAD_IS_SRC (pad))
gst_scheduler_pad_link (sched, pad, GST_PAD_PEER (pad));
else
gst_scheduler_pad_link (sched, GST_PAD_PEER (pad), pad);
}
if (GST_PAD_IS_SRC (pad))
gst_scheduler_pad_link (sched, pad, GST_PAD_PEER (pad));
else
gst_scheduler_pad_link (sched, GST_PAD_PEER (pad), pad);
}
}
}
}
@ -340,30 +342,32 @@ gst_bin_set_element_sched (GstElement *element, GstScheduler *sched)
static void
gst_bin_unset_element_sched (GstElement *element, GstScheduler *sched)
gst_bin_unset_element_sched (GstElement * element, GstScheduler * sched)
{
if (GST_ELEMENT_SCHED (element) == NULL) {
GST_CAT_DEBUG (GST_CAT_SCHEDULING, "element \"%s\" has no scheduler",
GST_ELEMENT_NAME (element));
GST_ELEMENT_NAME (element));
return;
}
GST_CAT_DEBUG (GST_CAT_SCHEDULING, "removing element \"%s\" from its sched %p",
GST_ELEMENT_NAME (element), GST_ELEMENT_SCHED (element));
GST_CAT_DEBUG (GST_CAT_SCHEDULING,
"removing element \"%s\" from its sched %p", GST_ELEMENT_NAME (element),
GST_ELEMENT_SCHED (element));
/* if it's actually a Bin */
if (GST_IS_BIN (element)) {
if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element,
"child is already a manager, not unsetting sched");
"child is already a manager, not unsetting sched");
if (sched) {
gst_scheduler_remove_scheduler (sched, GST_ELEMENT_SCHED (element));
gst_scheduler_remove_scheduler (sched, GST_ELEMENT_SCHED (element));
}
return;
}
/* for each child, remove them from their schedule */
g_list_foreach (GST_BIN (element)->children, (GFunc) gst_bin_unset_element_sched, sched);
g_list_foreach (GST_BIN (element)->children,
(GFunc) gst_bin_unset_element_sched, sched);
gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
}
@ -381,18 +385,19 @@ gst_bin_unset_element_sched (GstElement *element, GstScheduler *sched)
/* we only operate on real pads */
if (!GST_IS_REAL_PAD (pad))
continue;
continue;
/* if the peer element exists and is a candidate */
if (GST_PAD_PEER (pad)) {
if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) {
GST_CAT_LOG (GST_CAT_SCHEDULING, "peer is in same scheduler, telling scheduler");
if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) {
GST_CAT_LOG (GST_CAT_SCHEDULING,
"peer is in same scheduler, telling scheduler");
if (GST_PAD_IS_SRC (pad))
gst_scheduler_pad_unlink (sched, pad, GST_PAD_PEER (pad));
else
gst_scheduler_pad_unlink (sched, GST_PAD_PEER (pad), pad);
}
if (GST_PAD_IS_SRC (pad))
gst_scheduler_pad_unlink (sched, pad, GST_PAD_PEER (pad));
else
gst_scheduler_pad_unlink (sched, GST_PAD_PEER (pad), pad);
}
}
}
gst_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
@ -409,7 +414,7 @@ gst_bin_unset_element_sched (GstElement *element, GstScheduler *sched)
* Add a list of elements to a bin. Uses #gst_bin_add.
*/
void
gst_bin_add_many (GstBin *bin, GstElement *element_1, ...)
gst_bin_add_many (GstBin * bin, GstElement * element_1, ...)
{
va_list args;
@ -420,15 +425,15 @@ gst_bin_add_many (GstBin *bin, GstElement *element_1, ...)
while (element_1) {
gst_bin_add (bin, element_1);
element_1 = va_arg (args, GstElement*);
element_1 = va_arg (args, GstElement *);
}
va_end (args);
}
static void
gst_bin_add_func (GstBin *bin, GstElement *element)
gst_bin_add_func (GstBin * bin, GstElement * element)
{
gint state_idx = 0;
GstElementState state;
@ -438,11 +443,10 @@ gst_bin_add_func (GstBin *bin, GstElement *element)
g_return_if_fail (GST_ELEMENT_PARENT (element) == NULL);
/* then check to see if the element's name is already taken in the bin */
if (gst_object_check_uniqueness (bin->children,
GST_ELEMENT_NAME (element)) == FALSE)
{
if (gst_object_check_uniqueness (bin->children,
GST_ELEMENT_NAME (element)) == FALSE) {
g_warning ("Name %s is not unique in bin %s, not adding\n",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
return;
}
@ -454,7 +458,8 @@ gst_bin_add_func (GstBin *bin, GstElement *element)
/* bump our internal state counter */
state = GST_STATE (element);
while (state >>= 1) state_idx++;
while (state >>= 1)
state_idx++;
bin->child_states[state_idx]++;
/* now we have to deal with manager stuff
@ -465,8 +470,8 @@ gst_bin_add_func (GstBin *bin, GstElement *element)
gst_bin_set_element_sched (element, sched);
}
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
GST_OBJECT_NAME (element));
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
GST_OBJECT_NAME (element));
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
}
@ -480,30 +485,29 @@ gst_bin_add_func (GstBin *bin, GstElement *element)
* add a reference.
*/
void
gst_bin_add (GstBin *bin, GstElement *element)
gst_bin_add (GstBin * bin, GstElement * element)
{
GstBinClass *bclass;
g_return_if_fail (GST_IS_BIN (bin));
g_return_if_fail (GST_IS_ELEMENT (element));
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "adding element \"%s\"",
GST_OBJECT_NAME (element));
GST_OBJECT_NAME (element));
bclass = GST_BIN_GET_CLASS (bin);
if (bclass->add_element) {
bclass->add_element (bin, element);
}
else {
} else {
GST_ELEMENT_ERROR (bin, CORE, FAILED, (NULL),
("cannot add element %s to bin %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin)));
("cannot add element %s to bin %s",
GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin)));
}
}
static void
gst_bin_remove_func (GstBin *bin, GstElement *element)
gst_bin_remove_func (GstBin * bin, GstElement * element)
{
gint state_idx = 0;
GstElementState state;
@ -514,7 +518,7 @@ gst_bin_remove_func (GstBin *bin, GstElement *element)
/* the element must be in the bin's list of children */
if (g_list_find (bin->children, element) == NULL) {
g_warning ("no element \"%s\" in bin \"%s\"\n", GST_ELEMENT_NAME (element),
GST_ELEMENT_NAME (bin));
GST_ELEMENT_NAME (bin));
return;
}
@ -527,11 +531,12 @@ gst_bin_remove_func (GstBin *bin, GstElement *element)
/* bump our internal state counter */
state = GST_STATE (element);
while (state >>= 1) state_idx++;
while (state >>= 1)
state_idx++;
bin->child_states[state_idx]--;
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
GST_OBJECT_NAME (element));
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
GST_OBJECT_NAME (element));
/* ref as we're going to emit a signal */
gst_object_ref (GST_OBJECT (element));
@ -560,12 +565,12 @@ gst_bin_remove_func (GstBin *bin, GstElement *element)
* #gst_object_ref before removing it from the bin.
*/
void
gst_bin_remove (GstBin *bin, GstElement *element)
gst_bin_remove (GstBin * bin, GstElement * element)
{
GstBinClass *bclass;
GST_CAT_DEBUG (GST_CAT_PARENTAGE, "[%s]: trying to remove child %s",
GST_ELEMENT_NAME (bin), GST_ELEMENT_NAME (element));
GST_ELEMENT_NAME (bin), GST_ELEMENT_NAME (element));
g_return_if_fail (GST_IS_BIN (bin));
g_return_if_fail (GST_IS_ELEMENT (element));
@ -575,8 +580,7 @@ gst_bin_remove (GstBin *bin, GstElement *element)
if (bclass->remove_element) {
bclass->remove_element (bin, element);
}
else {
} else {
g_warning ("cannot remove elements from bin %s\n", GST_ELEMENT_NAME (bin));
}
}
@ -590,7 +594,7 @@ gst_bin_remove (GstBin *bin, GstElement *element)
* Remove a list of elements from a bin. Uses #gst_bin_remove.
*/
void
gst_bin_remove_many (GstBin *bin, GstElement *element_1, ...)
gst_bin_remove_many (GstBin * bin, GstElement * element_1, ...)
{
va_list args;
@ -601,8 +605,8 @@ gst_bin_remove_many (GstBin *bin, GstElement *element_1, ...)
while (element_1) {
gst_bin_remove (bin, element_1);
element_1 = va_arg (args, GstElement*);
element_1 = va_arg (args, GstElement *);
}
va_end (args);
@ -619,57 +623,58 @@ gst_bin_remove_many (GstBin *bin, GstElement *element_1, ...)
* of a child.
*/
void
gst_bin_child_state_change (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *child)
gst_bin_child_state_change (GstBin * bin, GstElementState oldstate,
GstElementState newstate, GstElement * child)
{
GstBinClass *bclass;
g_return_if_fail (GST_IS_BIN (bin));
g_return_if_fail (GST_IS_ELEMENT (child));
GST_CAT_LOG (GST_CAT_STATES, "child %s changed state in bin %s from %s to %s",
GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin),
gst_element_state_get_name (oldstate),
gst_element_state_get_name (newstate));
GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin),
gst_element_state_get_name (oldstate),
gst_element_state_get_name (newstate));
bclass = GST_BIN_GET_CLASS (bin);
if (bclass->child_state_change) {
bclass->child_state_change (bin, oldstate, newstate, child);
}
else {
g_warning ("cannot signal state change of child %s to bin %s\n",
GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin));
} else {
g_warning ("cannot signal state change of child %s to bin %s\n",
GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin));
}
}
static void
gst_bin_child_state_change_func (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *child)
gst_bin_child_state_change_func (GstBin * bin, GstElementState oldstate,
GstElementState newstate, GstElement * child)
{
gint old_idx = 0, new_idx = 0, i;
while (oldstate >>= 1) old_idx++;
while (newstate >>= 1) new_idx++;
while (oldstate >>= 1)
old_idx++;
while (newstate >>= 1)
new_idx++;
GST_LOCK (bin);
bin->child_states[old_idx]--;
bin->child_states[new_idx]++;
for (i = GST_NUM_STATES - 1; i >= 0; i--) {
if (bin->child_states[i] != 0) {
gint state = (1 << i);
if (GST_STATE (bin) != state) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"highest child state is %s, changing bin state accordingly",
gst_element_state_get_name (state));
"highest child state is %s, changing bin state accordingly",
gst_element_state_get_name (state));
GST_STATE_PENDING (bin) = state;
GST_UNLOCK (bin);
GST_UNLOCK (bin);
gst_bin_change_state_norecurse (bin);
if (state != GST_STATE (bin)) {
g_warning ("%s: state change in callback %d %d",
GST_ELEMENT_NAME (bin),
state, GST_STATE (bin));
g_warning ("%s: state change in callback %d %d",
GST_ELEMENT_NAME (bin), state, GST_STATE (bin));
}
return;
}
@ -699,18 +704,17 @@ gst_bin_change_state (GstElement * element)
transition = GST_STATE_TRANSITION (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"changing state of children from %s to %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending));
"changing state of children from %s to %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending));
if (pending == GST_STATE_VOID_PENDING)
return GST_STATE_SUCCESS;
if (old_state == pending)
{
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
"old and pending state are both %s, returning",
gst_element_state_get_name (pending));
if (old_state == pending) {
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
"old and pending state are both %s, returning",
gst_element_state_get_name (pending));
return GST_STATE_SUCCESS;
}
@ -728,16 +732,16 @@ gst_bin_change_state (GstElement * element)
old_child_state = GST_STATE (child);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"changing state of child %s from current %s to pending %s",
GST_ELEMENT_NAME (child), gst_element_state_get_name (old_child_state),
gst_element_state_get_name (pending));
"changing state of child %s from current %s to pending %s",
GST_ELEMENT_NAME (child), gst_element_state_get_name (old_child_state),
gst_element_state_get_name (pending));
switch (gst_element_set_state (child, pending)) {
case GST_STATE_FAILURE:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"child '%s' failed to go to state %d(%s)",
GST_ELEMENT_NAME (child),
pending, gst_element_state_get_name (pending));
"child '%s' failed to go to state %d(%s)",
GST_ELEMENT_NAME (child),
pending, gst_element_state_get_name (pending));
gst_element_set_state (child, old_child_state);
/* There was a check for elements being in the same scheduling group
@ -750,30 +754,31 @@ gst_bin_change_state (GstElement * element)
break;
case GST_STATE_ASYNC:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"child '%s' is changing state asynchronously",
GST_ELEMENT_NAME (child));
"child '%s' is changing state asynchronously",
GST_ELEMENT_NAME (child));
have_async = TRUE;
break;
case GST_STATE_SUCCESS:
GST_CAT_DEBUG (GST_CAT_STATES, "child '%s' changed state to %d(%s) successfully",
GST_ELEMENT_NAME (child), pending, gst_element_state_get_name (pending));
break;
GST_CAT_DEBUG (GST_CAT_STATES,
"child '%s' changed state to %d(%s) successfully",
GST_ELEMENT_NAME (child), pending,
gst_element_state_get_name (pending));
break;
}
}
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"done changing bin's state from %s to %s, now in %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending),
gst_element_state_get_name (GST_STATE (element)));
"done changing bin's state from %s to %s, now in %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (pending),
gst_element_state_get_name (GST_STATE (element)));
if (have_async)
ret = GST_STATE_ASYNC;
else {
if (parent_class->change_state) {
ret = parent_class->change_state(element);
}
else
ret = parent_class->change_state (element);
} else
ret = GST_STATE_SUCCESS;
}
return ret;
@ -790,8 +795,7 @@ gst_bin_change_state_norecurse (GstBin * bin)
ret = parent_class->change_state (GST_ELEMENT (bin));
return ret;
}
else
} else
return GST_STATE_FAILURE;
}
@ -842,8 +846,8 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name)
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
g_return_val_if_fail (name != NULL, NULL);
GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
GST_ELEMENT_NAME (bin), name);
GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
GST_ELEMENT_NAME (bin), name);
children = bin->children;
while (children) {
@ -925,10 +929,10 @@ gst_bin_get_list (GstBin * bin)
* Returns: An element inside the bin implementing the interface.
*/
GstElement *
gst_bin_get_by_interface (GstBin *bin, GType interface)
gst_bin_get_by_interface (GstBin * bin, GType interface)
{
GList *walk;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
@ -938,6 +942,7 @@ gst_bin_get_by_interface (GstBin *bin, GType interface)
return GST_ELEMENT (walk->data);
if (GST_IS_BIN (walk->data)) {
GstElement *ret;
ret = gst_bin_get_by_interface (GST_BIN (walk->data), interface);
if (ret)
return ret;
@ -961,10 +966,10 @@ gst_bin_get_by_interface (GstBin *bin, GType interface)
* Returns: An element inside the bin implementing the interface.
*/
GList *
gst_bin_get_all_by_interface (GstBin *bin, GType interface)
gst_bin_get_all_by_interface (GstBin * bin, GType interface)
{
GList *walk, *ret = NULL;
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
@ -973,13 +978,13 @@ gst_bin_get_all_by_interface (GstBin *bin, GType interface)
if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface))
ret = g_list_prepend (ret, walk->data);
if (GST_IS_BIN (walk->data)) {
ret = g_list_concat (ret,
ret = g_list_concat (ret,
gst_bin_get_all_by_interface (GST_BIN (walk->data), interface));
}
walk = g_list_next (walk);
}
return ret;
return ret;
}
/**
@ -995,7 +1000,7 @@ gst_bin_get_all_by_interface (GstBin *bin, GType interface)
* this function returns #GST_STATE_FAILURE.
*/
GstElementStateReturn
gst_bin_sync_children_state (GstBin *bin)
gst_bin_sync_children_state (GstBin * bin)
{
GList *children;
GstElement *element;
@ -1006,31 +1011,33 @@ gst_bin_sync_children_state (GstBin *bin)
state = GST_STATE (bin);
children = bin->children;
GST_CAT_INFO (GST_CAT_STATES, "syncing state of children with bin \"%s\"'s state %s",
GST_ELEMENT_NAME (bin), gst_element_state_get_name (state));
GST_CAT_INFO (GST_CAT_STATES,
"syncing state of children with bin \"%s\"'s state %s",
GST_ELEMENT_NAME (bin), gst_element_state_get_name (state));
while (children) {
element = GST_ELEMENT (children->data);
children = children->next;
if (GST_STATE(element) != state) {
if (GST_STATE (element) != state) {
switch (gst_element_set_state (element, state)) {
case GST_STATE_SUCCESS:
break;
case GST_STATE_ASYNC:
if (ret == GST_STATE_SUCCESS)
ret = GST_STATE_ASYNC;
break;
case GST_STATE_FAILURE:
ret = GST_STATE_FAILURE;
default:
/* make sure gst_element_set_state never returns this */
g_assert_not_reached ();
case GST_STATE_SUCCESS:
break;
case GST_STATE_ASYNC:
if (ret == GST_STATE_SUCCESS)
ret = GST_STATE_ASYNC;
break;
case GST_STATE_FAILURE:
ret = GST_STATE_FAILURE;
default:
/* make sure gst_element_set_state never returns this */
g_assert_not_reached ();
}
}
}
return ret;
}
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr
gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
@ -1045,8 +1052,8 @@ gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
childlist = xmlNewChild (parent, NULL, "children", NULL);
GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
GST_ELEMENT_NAME (bin), bin->numchildren);
GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
GST_ELEMENT_NAME (bin), bin->numchildren);
children = bin->children;
while (children) {
@ -1067,17 +1074,19 @@ gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
while (field) {
if (!strcmp (field->name, "children")) {
GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children", GST_ELEMENT_NAME (object));
GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
GST_ELEMENT_NAME (object));
childlist = field->xmlChildrenNode;
while (childlist) {
if (!strcmp (childlist->name, "element")) {
GstElement *element = gst_xml_make_element (childlist, GST_OBJECT (bin));
/* it had to be parented to find the pads, now we ref and unparent so
* we can add it to the bin */
gst_object_ref (GST_OBJECT (element));
gst_object_unparent (GST_OBJECT (element));
GstElement *element =
gst_xml_make_element (childlist, GST_OBJECT (bin));
/* it had to be parented to find the pads, now we ref and unparent so
* we can add it to the bin */
gst_object_ref (GST_OBJECT (element));
gst_object_unparent (GST_OBJECT (element));
gst_bin_add (bin, element);
}
childlist = childlist->next;
@ -1101,14 +1110,12 @@ gst_bin_iterate_func (GstBin * bin)
if (state == GST_SCHEDULER_STATE_RUNNING) {
return TRUE;
}
else if (state == GST_SCHEDULER_STATE_ERROR) {
} else if (state == GST_SCHEDULER_STATE_ERROR) {
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
}
}
else {
g_warning ("bin \"%s\" is not the managing bin, can't be iterated on!\n",
GST_ELEMENT_NAME (bin));
} else {
g_warning ("bin \"%s\" is not the managing bin, can't be iterated on!\n",
GST_ELEMENT_NAME (bin));
}
return FALSE;
@ -1124,7 +1131,7 @@ gst_bin_iterate_func (GstBin * bin)
* can be used to determine it the bin is in EOS.
*/
gboolean
gst_bin_iterate (GstBin *bin)
gst_bin_iterate (GstBin * bin)
{
gboolean running;
@ -1141,10 +1148,11 @@ gst_bin_iterate (GstBin *bin)
GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, bin, "finished iteration");
if (!running) {
if (GST_STATE (bin) == GST_STATE_PLAYING &&
if (GST_STATE (bin) == GST_STATE_PLAYING &&
GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
GST_CAT_DEBUG (GST_CAT_DATAFLOW, "[%s]: polling for child shutdown after useless iteration",
GST_ELEMENT_NAME (bin));
GST_CAT_DEBUG (GST_CAT_DATAFLOW,
"[%s]: polling for child shutdown after useless iteration",
GST_ELEMENT_NAME (bin));
g_usleep (1);
running = TRUE;
}

View file

@ -26,9 +26,7 @@
#include <gst/gstelement.h>
G_BEGIN_DECLS
extern GType _gst_bin_type;
G_BEGIN_DECLS extern GType _gst_bin_type;
#define GST_TYPE_BIN (_gst_bin_type)
#define GST_IS_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BIN))
@ -37,11 +35,12 @@ extern GType _gst_bin_type;
#define GST_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BIN, GstBin))
#define GST_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BIN, GstBinClass))
typedef void (*GstBinPrePostIterateFunction) (GstBin *bin, gpointer user_data);
typedef void (*GstBinPrePostIterateFunction) (GstBin * bin, gpointer user_data);
typedef enum {
typedef enum
{
/* this bin is a manager of child elements, i.e. a pipeline or thread */
GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST,
GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST,
/* this bin iterates itself */
GST_BIN_SELF_SCHEDULABLE,
@ -52,81 +51,78 @@ typedef enum {
GST_BIN_FLAG_FIXED_CLOCK,
/* padding */
GST_BIN_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 5
GST_BIN_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 5
} GstBinFlags;
/*typedef struct _GstBin GstBin; */
/*typedef struct _GstBinClass GstBinClass; */
struct _GstBin {
GstElement element;
struct _GstBin
{
GstElement element;
/* our children */
gint numchildren;
GList *children;
gint numchildren;
GList *children;
GstElementState child_states[GST_NUM_STATES];
gpointer _gst_reserved[GST_PADDING];
};
struct _GstBinClass {
struct _GstBinClass
{
GstElementClass parent_class;
/* vtable */
void (*add_element) (GstBin *bin, GstElement *element);
void (*remove_element) (GstBin *bin, GstElement *element);
void (*child_state_change) (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *element);
void (*add_element) (GstBin * bin, GstElement * element);
void (*remove_element) (GstBin * bin, GstElement * element);
void (*child_state_change) (GstBin * bin, GstElementState oldstate,
GstElementState newstate, GstElement * element);
/* run a full iteration of operation */
gboolean (*iterate) (GstBin *bin);
gboolean (*iterate) (GstBin * bin);
/* signals */
void (*element_added) (GstBin *bin, GstElement *child);
void (*element_removed) (GstBin *bin, GstElement *child);
void (*element_added) (GstBin * bin, GstElement * child);
void (*element_removed) (GstBin * bin, GstElement * child);
gpointer _gst_reserved[GST_PADDING];
};
GType gst_bin_get_type (void);
GstElement* gst_bin_new (const gchar *name);
GType gst_bin_get_type (void);
GstElement *gst_bin_new (const gchar * name);
/* add and remove elements from the bin */
void gst_bin_add (GstBin *bin, GstElement *element);
void gst_bin_add_many (GstBin *bin, GstElement *element_1, ...);
void gst_bin_remove (GstBin *bin, GstElement *element);
void gst_bin_remove_many (GstBin *bin, GstElement *element_1, ...);
void gst_bin_add (GstBin * bin, GstElement * element);
void gst_bin_add_many (GstBin * bin, GstElement * element_1, ...);
void gst_bin_remove (GstBin * bin, GstElement * element);
void gst_bin_remove_many (GstBin * bin, GstElement * element_1, ...);
/* retrieve a single element or the list of children */
GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name);
GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin, const gchar *name);
G_CONST_RETURN GList*
gst_bin_get_list (GstBin *bin);
GstElement* gst_bin_get_by_interface (GstBin *bin, GType interface);
GList * gst_bin_get_all_by_interface (GstBin *bin, GType interface);
GstElement *gst_bin_get_by_name (GstBin * bin, const gchar * name);
GstElement *gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name);
G_CONST_RETURN GList *gst_bin_get_list (GstBin * bin);
GstElement *gst_bin_get_by_interface (GstBin * bin, GType interface);
GList *gst_bin_get_all_by_interface (GstBin * bin, GType interface);
gboolean gst_bin_iterate (GstBin *bin);
gboolean gst_bin_iterate (GstBin * bin);
void gst_bin_use_clock (GstBin *bin, GstClock *clock);
GstClock* gst_bin_get_clock (GstBin *bin);
void gst_bin_auto_clock (GstBin *bin);
void gst_bin_use_clock (GstBin * bin, GstClock * clock);
GstClock *gst_bin_get_clock (GstBin * bin);
void gst_bin_auto_clock (GstBin * bin);
GstElementStateReturn gst_bin_sync_children_state (GstBin *bin);
GstElementStateReturn gst_bin_sync_children_state (GstBin * bin);
/* internal */
/* one of our childs signaled a state change */
void gst_bin_child_state_change (GstBin *bin, GstElementState oldstate,
GstElementState newstate, GstElement *child);
void gst_bin_child_state_change (GstBin * bin, GstElementState oldstate,
GstElementState newstate, GstElement * child);
void gst_bin_set_pre_iterate_function (GstBin *bin,
GstBinPrePostIterateFunction func,
gpointer user_data);
void gst_bin_set_post_iterate_function (GstBin *bin,
GstBinPrePostIterateFunction func,
gpointer user_data);
void gst_bin_set_pre_iterate_function (GstBin * bin,
GstBinPrePostIterateFunction func, gpointer user_data);
void gst_bin_set_post_iterate_function (GstBin * bin,
GstBinPrePostIterateFunction func, gpointer user_data);
G_END_DECLS
#endif /* __GST_BIN_H__ */

View file

@ -43,15 +43,14 @@ void
_gst_buffer_initialize (void)
{
_gst_buffer_type = g_boxed_type_register_static ("GstBuffer",
(GBoxedCopyFunc) gst_data_copy,
(GBoxedFreeFunc) gst_data_unref);
(GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref);
#ifndef GST_DISABLE_TRACE
_gst_buffer_trace = gst_alloc_trace_register (GST_BUFFER_TRACE_NAME);
#endif
chunk = gst_mem_chunk_new ("GstBufferChunk", sizeof (GstBuffer),
sizeof (GstBuffer) * 200, 0);
chunk = gst_mem_chunk_new ("GstBufferChunk", sizeof (GstBuffer),
sizeof (GstBuffer) * 200, 0);
GST_CAT_LOG (GST_CAT_BUFFER, "Buffers are initialized now");
}
@ -63,7 +62,7 @@ gst_buffer_get_type (void)
}
static void
_gst_buffer_sub_free (GstBuffer *buffer)
_gst_buffer_sub_free (GstBuffer * buffer)
{
gst_data_unref (GST_DATA (buffer->buffer_private));
@ -71,7 +70,7 @@ _gst_buffer_sub_free (GstBuffer *buffer)
GST_BUFFER_SIZE (buffer) = 0;
_GST_DATA_DISPOSE (GST_DATA (buffer));
gst_mem_chunk_free (chunk, GST_DATA (buffer));
#ifndef GST_DISABLE_TRACE
gst_alloc_trace_free (_gst_buffer_trace, buffer);
@ -86,14 +85,14 @@ _gst_buffer_sub_free (GstBuffer *buffer)
* unless the GST_BUFFER_DONTFREE flags was set or the buffer data is NULL.
*/
void
gst_buffer_default_free (GstBuffer *buffer)
gst_buffer_default_free (GstBuffer * buffer)
{
g_return_if_fail (buffer != NULL);
/* free our data */
if (GST_BUFFER_FREE_DATA_FUNC (buffer)) {
GST_BUFFER_FREE_DATA_FUNC (buffer) (buffer);
} else if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE)) {
} else if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE)) {
g_free (GST_BUFFER_DATA (buffer));
}
@ -118,16 +117,17 @@ gst_buffer_default_free (GstBuffer *buffer)
* the other.
*/
void
gst_buffer_stamp (GstBuffer *dest, const GstBuffer *src)
gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
{
g_return_if_fail (dest != NULL);
g_return_if_fail (src != NULL);
GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
}
/**
* gst_buffer_default_copy:
* @buffer: a #GstBuffer to make a copy of.
@ -136,8 +136,8 @@ gst_buffer_stamp (GstBuffer *dest, const GstBuffer *src)
*
* Returns: the new #GstBuffer.
*/
GstBuffer*
gst_buffer_default_copy (GstBuffer *buffer)
GstBuffer *
gst_buffer_default_copy (GstBuffer * buffer)
{
GstBuffer *copy;
@ -149,17 +149,17 @@ gst_buffer_default_copy (GstBuffer *buffer)
gst_alloc_trace_new (_gst_buffer_trace, copy);
#endif
_GST_DATA_INIT (GST_DATA (copy),
_gst_buffer_type,
0,
(GstDataFreeFunction) gst_buffer_default_free,
(GstDataCopyFunction) gst_buffer_default_copy);
_GST_DATA_INIT (GST_DATA (copy),
_gst_buffer_type,
0,
(GstDataFreeFunction) gst_buffer_default_free,
(GstDataCopyFunction) gst_buffer_default_copy);
/* we simply copy everything from our parent */
GST_BUFFER_DATA (copy) = g_memdup (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (buffer));
GST_BUFFER_SIZE (copy) = GST_BUFFER_SIZE (buffer);
GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_SIZE (buffer);
GST_BUFFER_DATA (copy) = g_memdup (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (buffer));
GST_BUFFER_SIZE (copy) = GST_BUFFER_SIZE (buffer);
GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_SIZE (buffer);
gst_buffer_stamp (copy, buffer);
GST_BUFFER_FREE_DATA_FUNC (copy) = NULL;
@ -175,11 +175,11 @@ gst_buffer_default_copy (GstBuffer *buffer)
*
* Returns: the new #GstBuffer.
*/
GstBuffer*
GstBuffer *
gst_buffer_new (void)
{
GstBuffer *newbuf;
newbuf = gst_mem_chunk_alloc (chunk);
#ifndef GST_DISABLE_TRACE
gst_alloc_trace_new (_gst_buffer_trace, newbuf);
@ -187,19 +187,19 @@ gst_buffer_new (void)
GST_CAT_LOG (GST_CAT_BUFFER, "new %p", newbuf);
_GST_DATA_INIT (GST_DATA (newbuf),
_gst_buffer_type,
0,
(GstDataFreeFunction) gst_buffer_default_free,
(GstDataCopyFunction) gst_buffer_default_copy);
_GST_DATA_INIT (GST_DATA (newbuf),
_gst_buffer_type,
0,
(GstDataFreeFunction) gst_buffer_default_free,
(GstDataCopyFunction) gst_buffer_default_copy);
GST_BUFFER_DATA (newbuf) = NULL;
GST_BUFFER_SIZE (newbuf) = 0;
GST_BUFFER_MAXSIZE (newbuf) = GST_BUFFER_MAXSIZE_NONE;
GST_BUFFER_TIMESTAMP (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_DATA (newbuf) = NULL;
GST_BUFFER_SIZE (newbuf) = 0;
GST_BUFFER_MAXSIZE (newbuf) = GST_BUFFER_MAXSIZE_NONE;
GST_BUFFER_TIMESTAMP (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_FREE_DATA_FUNC (newbuf) = NULL;
GST_BUFFER_PRIVATE (newbuf) = NULL;
@ -214,15 +214,15 @@ gst_buffer_new (void)
*
* Returns: the new #GstBuffer.
*/
GstBuffer*
GstBuffer *
gst_buffer_new_and_alloc (guint size)
{
GstBuffer *newbuf;
newbuf = gst_buffer_new ();
GST_BUFFER_DATA (newbuf) = g_malloc (size);
GST_BUFFER_SIZE (newbuf) = size;
GST_BUFFER_DATA (newbuf) = g_malloc (size);
GST_BUFFER_SIZE (newbuf) = size;
GST_BUFFER_MAXSIZE (newbuf) = size;
return newbuf;
@ -242,12 +242,12 @@ gst_buffer_new_and_alloc (guint size)
*
* Returns: the new #GstBuffer, or NULL if there was an error.
*/
GstBuffer*
gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
GstBuffer *
gst_buffer_create_sub (GstBuffer * parent, guint offset, guint size)
{
GstBuffer *buffer;
gpointer buffer_data;
g_return_val_if_fail (parent != NULL, NULL);
g_return_val_if_fail (GST_BUFFER_REFCOUNT_VALUE (parent) > 0, NULL);
g_return_val_if_fail (size > 0, NULL);
@ -272,32 +272,31 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
/* make sure nobody overwrites data in the new buffer
* by setting the READONLY flag */
_GST_DATA_INIT (GST_DATA (buffer),
_gst_buffer_type,
GST_DATA_FLAG_SHIFT (GST_BUFFER_SUBBUFFER) |
GST_DATA_FLAG_SHIFT (GST_DATA_READONLY),
(GstDataFreeFunction) _gst_buffer_sub_free,
(GstDataCopyFunction) gst_buffer_default_copy);
_GST_DATA_INIT (GST_DATA (buffer),
_gst_buffer_type,
GST_DATA_FLAG_SHIFT (GST_BUFFER_SUBBUFFER) |
GST_DATA_FLAG_SHIFT (GST_DATA_READONLY),
(GstDataFreeFunction) _gst_buffer_sub_free,
(GstDataCopyFunction) gst_buffer_default_copy);
/* set the right values in the child */
GST_BUFFER_DATA (buffer) = buffer_data;
GST_BUFFER_SIZE (buffer) = size;
GST_BUFFER_MAXSIZE (buffer) = size;
GST_BUFFER_DATA (buffer) = buffer_data;
GST_BUFFER_SIZE (buffer) = size;
GST_BUFFER_MAXSIZE (buffer) = size;
GST_BUFFER_FREE_DATA_FUNC (buffer) = NULL;
GST_BUFFER_PRIVATE (buffer) = parent;
/* we can copy the timestamp and offset if the new buffer starts at
* offset 0 */
if (offset == 0) {
GST_BUFFER_TIMESTAMP (buffer) = GST_BUFFER_TIMESTAMP (parent);
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET (parent);
}
else {
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_TIMESTAMP (buffer) = GST_BUFFER_TIMESTAMP (parent);
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET (parent);
} else {
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
}
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
if (GST_BUFFER_FLAG_IS_SET (parent, GST_BUFFER_DONTKEEP)) {
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_DONTKEEP);
@ -324,8 +323,8 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
*
* Returns: the new #GstBuffer that's the concatenation of the source buffers.
*/
GstBuffer*
gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
GstBuffer *
gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
{
GstBuffer *result;
@ -347,7 +346,7 @@ gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
* FALSE if a copy would be required.
*/
gboolean
gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
{
g_return_val_if_fail (buf1 != NULL && buf2 != NULL, FALSE);
g_return_val_if_fail (GST_BUFFER_REFCOUNT_VALUE (buf1) > 0, FALSE);
@ -355,9 +354,9 @@ gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
/* it's only fast if we have subbuffers of the same parent */
return ((GST_BUFFER_FLAG_IS_SET (buf1, GST_BUFFER_SUBBUFFER)) &&
(GST_BUFFER_FLAG_IS_SET (buf2, GST_BUFFER_SUBBUFFER)) &&
(buf1->buffer_private == buf2->buffer_private) &&
((buf1->data + buf1->size) == buf2->data));
(GST_BUFFER_FLAG_IS_SET (buf2, GST_BUFFER_SUBBUFFER)) &&
(buf1->buffer_private == buf2->buffer_private) &&
((buf1->data + buf1->size) == buf2->data));
}
/**
@ -380,8 +379,9 @@ gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
*
* Returns: the new #GstBuffer that spans the two source buffers.
*/
GstBuffer*
gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
GstBuffer *
gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
guint32 len)
{
GstBuffer *newbuf;
@ -394,21 +394,21 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
/* if the two buffers have the same parent and are adjacent */
if (gst_buffer_is_span_fast (buf1, buf2)) {
GstBuffer *parent = GST_BUFFER (buf1->buffer_private);
/* we simply create a subbuffer of the common parent */
newbuf = gst_buffer_create_sub (parent,
buf1->data - parent->data + offset, len);
}
else {
GST_CAT_DEBUG (GST_CAT_BUFFER, "slow path taken while spanning buffers %p and %p",
buf1, buf2);
newbuf = gst_buffer_create_sub (parent,
buf1->data - parent->data + offset, len);
} else {
GST_CAT_DEBUG (GST_CAT_BUFFER,
"slow path taken while spanning buffers %p and %p", buf1, buf2);
/* otherwise we simply have to brute-force copy the buffers */
newbuf = gst_buffer_new_and_alloc (len);
/* copy the first buffer's data across */
memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
/* copy the second buffer's data across */
memcpy (newbuf->data + (buf1->size - offset), buf2->data,
len - (buf1->size - offset));
memcpy (newbuf->data + (buf1->size - offset), buf2->data,
len - (buf1->size - offset));
/* if the offset is 0, the new buffer has the same timestamp as buf1 */
if (offset == 0) {
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
@ -422,8 +422,8 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
if (GST_BUFFER_DURATION_IS_VALID (buf1) &&
GST_BUFFER_DURATION_IS_VALID (buf2)) {
/* add duration */
GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
GST_BUFFER_DURATION (buf2);
GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
GST_BUFFER_DURATION (buf2);
}
if (GST_BUFFER_OFFSET_END_IS_VALID (buf2)) {
/* add offset_end */
@ -433,4 +433,3 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
return newbuf;
}

View file

@ -27,11 +27,9 @@
#include <gst/gstdata.h>
#include <gst/gstclock.h>
G_BEGIN_DECLS
G_BEGIN_DECLS typedef struct _GstBuffer GstBuffer;
typedef struct _GstBuffer GstBuffer;
typedef void (*GstBufferFreeDataFunc) (GstBuffer *buffer);
typedef void (*GstBufferFreeDataFunc) (GstBuffer * buffer);
#define GST_BUFFER_TRACE_NAME "GstBuffer"
@ -74,27 +72,29 @@ extern GType _gst_buffer_type;
#define GST_BUFFER_OFFSET_END_IS_VALID(buffer) (GST_BUFFER_OFFSET_END (buffer) != GST_BUFFER_OFFSET_NONE)
#define GST_BUFFER_MAXSIZE_IS_VALID(buffer) (GST_BUFFER_MAXSIZE (buffer) != GST_BUFFER_MAXSIZE_NONE)
typedef enum {
GST_BUFFER_READONLY = GST_DATA_READONLY,
GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST,
typedef enum
{
GST_BUFFER_READONLY = GST_DATA_READONLY,
GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST,
GST_BUFFER_ORIGINAL,
GST_BUFFER_DONTFREE,
GST_BUFFER_KEY_UNIT,
GST_BUFFER_DONTKEEP,
GST_BUFFER_FLAG_LAST = GST_DATA_FLAG_LAST + 8
GST_BUFFER_FLAG_LAST = GST_DATA_FLAG_LAST + 8
} GstBufferFlag;
struct _GstBuffer {
GstData data_type;
struct _GstBuffer
{
GstData data_type;
/* pointer to data and its size */
guint8 *data; /* pointer to buffer data */
guint size; /* size of buffer data */
guint maxsize; /* max size of this buffer */
guint8 *data; /* pointer to buffer data */
guint size; /* size of buffer data */
guint maxsize; /* max size of this buffer */
/* timestamp */
GstClockTime timestamp;
GstClockTime duration;
GstClockTime timestamp;
GstClockTime duration;
/* media specific offset
* for video frames, this could be the number of frames,
@ -103,19 +103,19 @@ struct _GstBuffer {
* offset_end is the last offset contained in the buffer. The format specifies
* the meaning of both of them exactly.
*/
guint64 offset;
guint64 offset_end;
guint64 offset;
guint64 offset_end;
GstBufferFreeDataFunc free_data;
gpointer buffer_private;
GstBufferFreeDataFunc free_data;
gpointer buffer_private;
gpointer _gst_reserved[GST_PADDING];
};
/* allocation */
GType gst_buffer_get_type (void);
GstBuffer* gst_buffer_new (void);
GstBuffer* gst_buffer_new_and_alloc (guint size);
GType gst_buffer_get_type (void);
GstBuffer *gst_buffer_new (void);
GstBuffer *gst_buffer_new_and_alloc (guint size);
#define gst_buffer_set_data(buf, data, size) \
G_STMT_START { \
@ -128,25 +128,26 @@ G_STMT_START { \
#define gst_buffer_ref_by_count(buf,c) GST_BUFFER (gst_data_ref_by_count (GST_DATA (buf), c))
#define gst_buffer_unref(buf) gst_data_unref (GST_DATA (buf))
/* copy buffer */
void gst_buffer_stamp (GstBuffer *dest, const GstBuffer *src);
void gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src);
#define gst_buffer_copy(buf) GST_BUFFER (gst_data_copy (GST_DATA (buf)))
#define gst_buffer_is_writable(buf) gst_data_is_writable (GST_DATA (buf))
#define gst_buffer_copy_on_write(buf) GST_BUFFER (gst_data_copy_on_write (GST_DATA (buf)))
/* creating a subbuffer */
GstBuffer* gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size);
GstBuffer *gst_buffer_create_sub (GstBuffer * parent, guint offset, guint size);
/* merge, span, or append two buffers, intelligently */
GstBuffer* gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2);
gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
GstBuffer *gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2);
gboolean gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2);
GstBuffer *gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
guint32 len);
/* --- private --- */
void _gst_buffer_initialize (void);
void _gst_buffer_initialize (void);
void gst_buffer_default_free (GstBuffer *buffer);
GstBuffer* gst_buffer_default_copy (GstBuffer *buffer);
void gst_buffer_default_free (GstBuffer * buffer);
GstBuffer *gst_buffer_default_copy (GstBuffer * buffer);
G_END_DECLS
#endif /* __GST_BUFFER_H__ */

File diff suppressed because it is too large Load diff

View file

@ -24,119 +24,103 @@
#include <gst/gststructure.h>
G_BEGIN_DECLS
#define GST_TYPE_CAPS gst_caps_get_type()
#define GST_CAPS(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GST_TYPE_CAPS, GstCaps))
#define GST_IS_CAPS(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GST_TYPE_CAPS))
#define GST_CAPS_FLAGS_ANY (1 << 0)
#define GST_CAPS_ANY gst_caps_new_any()
#define GST_CAPS_NONE gst_caps_new_empty()
#define GST_STATIC_CAPS_ANY GST_STATIC_CAPS("ANY")
#define GST_STATIC_CAPS_NONE GST_STATIC_CAPS("NONE")
#define GST_CAPS_IS_SIMPLE(caps) (gst_caps_get_size(caps) == 1)
#define gst_caps_is_simple(caps) GST_CAPS_IS_SIMPLE(caps)
#ifndef GST_DISABLE_DEPRECATED
#define GST_DEBUG_CAPS(string, caps) \
GST_DEBUG ( string "%s: " GST_PTR_FORMAT, caps)
#endif
#define GST_STATIC_CAPS(string) \
{ \
/* caps */ { 0 }, \
/* string */ string, \
}
typedef struct _GstCaps GstCaps;
typedef struct _GstStaticCaps GstStaticCaps;
struct _GstCaps {
struct _GstCaps
{
GType type;
guint16 flags;
GPtrArray *structs;
};
struct _GstStaticCaps {
struct _GstStaticCaps
{
GstCaps caps;
const char *string;
};
GType gst_caps_get_type (void) G_GNUC_CONST;
GstCaps * gst_caps_new_empty (void);
GstCaps * gst_caps_new_any (void);
GstCaps * gst_caps_new_simple (const char *media_type,
const char *fieldname,
...);
GstCaps * gst_caps_new_full (GstStructure *struct1,
...);
GstCaps * gst_caps_new_full_valist (GstStructure *structure,
va_list var_args);
GstCaps * gst_caps_copy (const GstCaps *caps);
void gst_caps_free (GstCaps *caps);
G_CONST_RETURN GstCaps * gst_static_caps_get (GstStaticCaps *caps);
GType
gst_caps_get_type (void)
G_GNUC_CONST;
GstCaps *gst_caps_new_empty (void);
GstCaps *gst_caps_new_any (void);
GstCaps *gst_caps_new_simple (const char *media_type,
const char *fieldname, ...);
GstCaps *gst_caps_new_full (GstStructure * struct1, ...);
GstCaps *gst_caps_new_full_valist (GstStructure * structure,
va_list var_args);
GstCaps *gst_caps_copy (const GstCaps * caps);
void gst_caps_free (GstCaps * caps);
G_CONST_RETURN GstCaps *gst_static_caps_get (GstStaticCaps * caps);
/* manipulation */
void gst_caps_append (GstCaps *caps1,
GstCaps *caps2);
void gst_caps_append_structure (GstCaps *caps1,
GstStructure *structure);
GstCaps * gst_caps_split_one (GstCaps *caps);
int gst_caps_get_size (const GstCaps *caps);
GstStructure * gst_caps_get_structure (const GstCaps *caps,
int index);
void gst_caps_append (GstCaps * caps1, GstCaps * caps2);
void gst_caps_append_structure (GstCaps * caps1, GstStructure * structure);
GstCaps *gst_caps_split_one (GstCaps * caps);
int gst_caps_get_size (const GstCaps * caps);
GstStructure *gst_caps_get_structure (const GstCaps * caps, int index);
#ifndef GST_DISABLE_DEPRECATED
GstCaps * gst_caps_copy_1 (const GstCaps *caps);
GstCaps *gst_caps_copy_1 (const GstCaps * caps);
#endif
void gst_caps_set_simple (GstCaps *caps,
char *field, ...);
void gst_caps_set_simple_valist (GstCaps *caps,
char *field,
va_list varargs);
void gst_caps_set_simple (GstCaps * caps, char *field, ...);
void gst_caps_set_simple_valist (GstCaps * caps,
char *field, va_list varargs);
/* tests */
gboolean gst_caps_is_any (const GstCaps *caps);
gboolean gst_caps_is_empty (const GstCaps *caps);
gboolean gst_caps_is_any (const GstCaps * caps);
gboolean gst_caps_is_empty (const GstCaps * caps);
#ifndef GST_DISABLE_DEPRECATED
gboolean gst_caps_is_chained (const GstCaps *caps);
gboolean gst_caps_is_chained (const GstCaps * caps);
#endif
gboolean gst_caps_is_fixed (const GstCaps *caps);
gboolean gst_caps_is_equal_fixed (const GstCaps *caps1,
const GstCaps *caps2);
gboolean gst_caps_is_always_compatible (const GstCaps *caps1,
const GstCaps *caps2);
gboolean gst_caps_is_fixed (const GstCaps * caps);
gboolean gst_caps_is_equal_fixed (const GstCaps * caps1,
const GstCaps * caps2);
gboolean gst_caps_is_always_compatible (const GstCaps * caps1,
const GstCaps * caps2);
/* operations */
GstCaps * gst_caps_intersect (const GstCaps *caps1,
const GstCaps *caps2);
GstCaps * gst_caps_union (const GstCaps *caps1,
const GstCaps *caps2);
GstCaps * gst_caps_normalize (const GstCaps *caps);
GstCaps * gst_caps_simplify (const GstCaps *caps);
GstCaps *gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2);
GstCaps *gst_caps_union (const GstCaps * caps1, const GstCaps * caps2);
GstCaps *gst_caps_normalize (const GstCaps * caps);
GstCaps *gst_caps_simplify (const GstCaps * caps);
#ifndef GST_DISABLE_LOADSAVE
xmlNodePtr gst_caps_save_thyself (const GstCaps *caps,
xmlNodePtr parent);
GstCaps * gst_caps_load_thyself (xmlNodePtr parent);
xmlNodePtr gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent);
GstCaps *gst_caps_load_thyself (xmlNodePtr parent);
#endif
/* utility */
void gst_caps_replace (GstCaps **caps,
GstCaps *newcaps);
gchar * gst_caps_to_string (const GstCaps *caps);
GstCaps * gst_caps_from_string (const gchar *string);
void gst_caps_replace (GstCaps ** caps, GstCaps * newcaps);
gchar *gst_caps_to_string (const GstCaps * caps);
GstCaps *gst_caps_from_string (const gchar * string);
gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure,
const char *field_name,
int target);
gboolean gst_caps_structure_fixate_field_nearest_double (GstStructure *structure,
const char *field_name,
double target);
gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *
structure, const char *field_name, int target);
gboolean gst_caps_structure_fixate_field_nearest_double (GstStructure *
structure, const char *field_name, double target);
G_END_DECLS
#endif /* __GST_CAPS_H__ */

View file

@ -37,35 +37,37 @@ static GstAllocTrace *_gst_clock_entry_trace;
#define DEFAULT_EVENT_DIFF (GST_SECOND)
#define DEFAULT_MAX_DIFF (2 * GST_SECOND)
enum {
enum
{
ARG_0,
ARG_STATS,
ARG_MAX_DIFF,
ARG_EVENT_DIFF
};
static GstMemChunk *_gst_clock_entries_chunk;
static GstMemChunk *_gst_clock_entries_chunk;
void gst_clock_id_unlock (GstClockID id);
void gst_clock_id_unlock (GstClockID id);
static void gst_clock_class_init (GstClockClass *klass);
static void gst_clock_init (GstClock *clock);
static void gst_clock_dispose (GObject *object);
static void gst_clock_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_clock_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec * pspec);
static void gst_clock_update_stats (GstClock *clock);
static void gst_clock_class_init (GstClockClass * klass);
static void gst_clock_init (GstClock * clock);
static void gst_clock_dispose (GObject * object);
static void gst_clock_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_clock_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_clock_update_stats (GstClock * clock);
static GstObjectClass *parent_class = NULL;
/* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
static GstClockID
gst_clock_entry_new (GstClock *clock, GstClockTime time,
GstClockTime interval, GstClockEntryType type)
gst_clock_entry_new (GstClock * clock, GstClockTime time,
GstClockTime interval, GstClockEntryType type)
{
GstClockEntry *entry;
@ -94,14 +96,12 @@ gst_clock_entry_new (GstClock *clock, GstClockTime time,
* Returns: An id that can be used to request the time notification.
*/
GstClockID
gst_clock_new_single_shot_id (GstClock *clock, GstClockTime time)
gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
return gst_clock_entry_new (clock,
time,
GST_CLOCK_TIME_NONE,
GST_CLOCK_ENTRY_SINGLE);
return gst_clock_entry_new (clock,
time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
}
/**
@ -117,17 +117,15 @@ gst_clock_new_single_shot_id (GstClock *clock, GstClockTime time)
* Returns: An id that can be used to request the time notification.
*/
GstClockID
gst_clock_new_periodic_id (GstClock *clock, GstClockTime start_time,
GstClockTime interval)
gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
GstClockTime interval)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
g_return_val_if_fail (interval != 0, NULL);
return gst_clock_entry_new (clock,
start_time,
interval,
GST_CLOCK_ENTRY_PERIODIC);
return gst_clock_entry_new (clock,
start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
}
/**
@ -143,7 +141,7 @@ gst_clock_id_get_time (GstClockID id)
{
g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
return GST_CLOCK_ENTRY_TIME ((GstClockEntry *)id);
return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
}
@ -158,30 +156,30 @@ gst_clock_id_get_time (GstClockID id)
* Returns: the result of the blocking wait.
*/
GstClockReturn
gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
{
GstClockEntry *entry;
GstClock *clock;
GstClockReturn res = GST_CLOCK_UNSUPPORTED;
GstClockTime requested;
GstClockClass *cclass;
g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
entry = (GstClockEntry *) id;
requested = GST_CLOCK_ENTRY_TIME (entry);
if (! GST_CLOCK_TIME_IS_VALID (requested)) {
if (!GST_CLOCK_TIME_IS_VALID (requested)) {
GST_CAT_DEBUG (GST_CAT_CLOCK, "invalid time requested, returning _TIMEOUT");
return GST_CLOCK_TIMEOUT;
}
clock = GST_CLOCK_ENTRY_CLOCK (entry);
cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->wait) {
GstClockTime now;
GST_LOCK (clock);
clock->entries = g_list_prepend (clock->entries, entry);
GST_UNLOCK (clock);
@ -223,20 +221,20 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff *jitter)
*/
GstClockReturn
gst_clock_id_wait_async (GstClockID id,
GstClockCallback func, gpointer user_data)
GstClockCallback func, gpointer user_data)
{
GstClockEntry *entry;
GstClock *clock;
GstClockReturn res = GST_CLOCK_UNSUPPORTED;
GstClockClass *cclass;
g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
entry = (GstClockEntry *) id;
clock = entry->clock;
if (! GST_CLOCK_TIME_IS_VALID (GST_CLOCK_ENTRY_TIME (entry))) {
if (!GST_CLOCK_TIME_IS_VALID (GST_CLOCK_ENTRY_TIME (entry))) {
(func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
return GST_CLOCK_TIMEOUT;
}
@ -254,11 +252,11 @@ gst_clock_id_wait_async (GstClockID id,
}
static void
gst_clock_reschedule_func (GstClockEntry *entry)
gst_clock_reschedule_func (GstClockEntry * entry)
{
entry->status = GST_CLOCK_ENTRY_OK;
gst_clock_id_unlock ((GstClockID)entry);
gst_clock_id_unlock ((GstClockID) entry);
}
/**
@ -273,7 +271,7 @@ gst_clock_id_unschedule (GstClockID id)
GstClockEntry *entry;
GstClock *clock;
GstClockClass *cclass;
g_return_if_fail (id != NULL);
entry = (GstClockEntry *) id;
@ -314,7 +312,7 @@ gst_clock_id_unlock (GstClockID id)
GstClockEntry *entry;
GstClock *clock;
GstClockClass *cclass;
g_return_if_fail (id != NULL);
entry = (GstClockEntry *) id;
@ -348,20 +346,20 @@ gst_clock_get_type (void)
(GInstanceInitFunc) gst_clock_init,
NULL
};
clock_type = g_type_register_static (GST_TYPE_OBJECT, "GstClock",
&clock_info, G_TYPE_FLAG_ABSTRACT);
clock_type = g_type_register_static (GST_TYPE_OBJECT, "GstClock",
&clock_info, G_TYPE_FLAG_ABSTRACT);
}
return clock_type;
}
static void
gst_clock_class_init (GstClockClass *klass)
gst_clock_class_init (GstClockClass * klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
gobject_class = (GObjectClass*) klass;
gstobject_class = (GstObjectClass*) klass;
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
@ -369,31 +367,33 @@ gst_clock_class_init (GstClockClass *klass)
g_thread_init (NULL);
_gst_clock_entries_chunk = gst_mem_chunk_new ("GstClockEntries",
sizeof (GstClockEntry), sizeof (GstClockEntry) * 32,
G_ALLOC_AND_FREE);
sizeof (GstClockEntry), sizeof (GstClockEntry) * 32, G_ALLOC_AND_FREE);
#ifndef GST_DISABLE_TRACE
_gst_clock_entry_trace = gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
_gst_clock_entry_trace =
gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
#endif
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_clock_dispose);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_clock_dispose);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STATS,
g_param_spec_boolean ("stats", "Stats", "Enable clock stats",
FALSE, G_PARAM_READWRITE));
g_param_spec_boolean ("stats", "Stats", "Enable clock stats",
FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_DIFF,
g_param_spec_int64 ("max-diff", "Max diff", "The maximum amount of time to wait in nanoseconds",
0, G_MAXINT64, DEFAULT_MAX_DIFF, G_PARAM_READWRITE));
g_param_spec_int64 ("max-diff", "Max diff",
"The maximum amount of time to wait in nanoseconds", 0, G_MAXINT64,
DEFAULT_MAX_DIFF, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EVENT_DIFF,
g_param_spec_uint64 ("event-diff", "event diff",
"The amount of time that may elapse until 2 events are treated as happening at different times",
0, G_MAXUINT64, DEFAULT_EVENT_DIFF, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_param_spec_uint64 ("event-diff", "event diff",
"The amount of time that may elapse until 2 events are treated as happening at different times",
0, G_MAXUINT64, DEFAULT_EVENT_DIFF,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
static void
gst_clock_init (GstClock *clock)
gst_clock_init (GstClock * clock)
{
clock->max_diff = DEFAULT_MAX_DIFF;
@ -408,7 +408,7 @@ gst_clock_init (GstClock *clock)
}
static void
gst_clock_dispose (GObject *object)
gst_clock_dispose (GObject * object)
{
GstClock *clock = GST_CLOCK (object);
@ -429,7 +429,7 @@ gst_clock_dispose (GObject *object)
* Returns: the new speed of the clock.
*/
gdouble
gst_clock_set_speed (GstClock *clock, gdouble speed)
gst_clock_set_speed (GstClock * clock, gdouble speed)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);
@ -446,7 +446,7 @@ gst_clock_set_speed (GstClock *clock, gdouble speed)
* Returns: the speed of the clock.
*/
gdouble
gst_clock_get_speed (GstClock *clock)
gst_clock_get_speed (GstClock * clock)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), 0.0);
@ -464,7 +464,7 @@ gst_clock_get_speed (GstClock *clock)
* Returns: the new resolution of the clock.
*/
guint64
gst_clock_set_resolution (GstClock *clock, guint64 resolution)
gst_clock_set_resolution (GstClock * clock, guint64 resolution)
{
GstClockClass *cclass;
@ -474,7 +474,8 @@ gst_clock_set_resolution (GstClock *clock, guint64 resolution)
cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->change_resolution)
clock->resolution = cclass->change_resolution (clock, clock->resolution, resolution);
clock->resolution =
cclass->change_resolution (clock, clock->resolution, resolution);
return clock->resolution;
}
@ -488,7 +489,7 @@ gst_clock_set_resolution (GstClock *clock, guint64 resolution)
* Returns: the resolution of the clock in microseconds.
*/
guint64
gst_clock_get_resolution (GstClock *clock)
gst_clock_get_resolution (GstClock * clock)
{
GstClockClass *cclass;
@ -511,10 +512,10 @@ gst_clock_get_resolution (GstClock *clock)
* As soon as the clock is activated, the time will start ticking.
*/
void
gst_clock_set_active (GstClock *clock, gboolean active)
gst_clock_set_active (GstClock * clock, gboolean active)
{
g_return_if_fail (GST_IS_CLOCK (clock));
GST_ERROR_OBJECT (clock, "called deprecated function that does nothing now.");
return;
@ -529,7 +530,7 @@ gst_clock_set_active (GstClock *clock, gboolean active)
* Returns: TRUE if the clock is active.
*/
gboolean
gst_clock_is_active (GstClock *clock)
gst_clock_is_active (GstClock * clock)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
@ -545,7 +546,7 @@ gst_clock_is_active (GstClock *clock)
* Reset the clock to time 0.
*/
void
gst_clock_reset (GstClock *clock)
gst_clock_reset (GstClock * clock)
{
GstClockTime time = G_GINT64_CONSTANT (0);
GstClockClass *cclass;
@ -555,7 +556,7 @@ gst_clock_reset (GstClock *clock)
GST_ERROR_OBJECT (clock, "called deprecated function.");
cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->get_internal_time) {
time = cclass->get_internal_time (clock);
}
@ -580,7 +581,7 @@ gst_clock_reset (GstClock *clock)
* discontinuitity in the pipeline is honoured.
*/
gboolean
gst_clock_handle_discont (GstClock *clock, guint64 time)
gst_clock_handle_discont (GstClock * clock, guint64 time)
{
GST_ERROR_OBJECT (clock, "called deprecated function.");
@ -597,7 +598,7 @@ gst_clock_handle_discont (GstClock *clock, guint64 time)
* Returns: the time of the clock.
*/
GstClockTime
gst_clock_get_time (GstClock *clock)
gst_clock_get_time (GstClock * clock)
{
GstClockTime ret = G_GINT64_CONSTANT (0);
GstClockClass *cclass;
@ -612,8 +613,7 @@ gst_clock_get_time (GstClock *clock)
/* make sure the time is increasing, else return last_time */
if ((gint64) ret < (gint64) clock->last_time) {
ret = clock->last_time;
}
else {
} else {
clock->last_time = ret;
}
@ -632,23 +632,23 @@ gst_clock_get_time (GstClock *clock)
* Returns: the time of the event
*/
GstClockTime
gst_clock_get_event_time (GstClock *clock)
gst_clock_get_event_time (GstClock * clock)
{
GstClockTime time;
g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
time = gst_clock_get_time (clock);
if (clock->last_event + clock->max_event_diff >= time) {
GST_LOG_OBJECT (clock, "reporting last event time %"G_GUINT64_FORMAT,
GST_LOG_OBJECT (clock, "reporting last event time %" G_GUINT64_FORMAT,
clock->last_event);
} else {
GST_LOG_OBJECT (clock, "reporting new event time %"G_GUINT64_FORMAT,
GST_LOG_OBJECT (clock, "reporting new event time %" G_GUINT64_FORMAT,
clock->last_event);
clock->last_event = time;
}
return clock->last_event;
}
@ -661,7 +661,7 @@ gst_clock_get_event_time (GstClock *clock)
* Returns: a clockid or NULL is no event is pending.
*/
GstClockID
gst_clock_get_next_id (GstClock *clock)
gst_clock_get_next_id (GstClock * clock)
{
GstClockEntry *entry = NULL;
@ -676,16 +676,16 @@ gst_clock_get_next_id (GstClock *clock)
}
static void
gst_clock_update_stats (GstClock *clock)
gst_clock_update_stats (GstClock * clock)
{
}
static void
gst_clock_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
gst_clock_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstClock *clock;
clock = GST_CLOCK (object);
switch (prop_id) {
@ -704,15 +704,15 @@ gst_clock_set_property (GObject *object, guint prop_id,
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
}
static void
gst_clock_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec * pspec)
gst_clock_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstClock *clock;
clock = GST_CLOCK (object);
switch (prop_id) {
@ -728,5 +728,5 @@ gst_clock_get_property (GObject *object, guint prop_id,
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
}

Some files were not shown because too many files have changed in this diff Show more