gst-indent

Original commit message from CVS:
gst-indent
This commit is contained in:
Thomas Vander Stichele 2004-03-14 22:34:34 +00:00
parent e9bef8b9bd
commit 4df3f18839
215 changed files with 17714 additions and 18367 deletions

View file

@ -1,3 +1,7 @@
2004-03-14 Thomas Vander Stichele <thomas at apestaart dot org>
* *.c, *.h: run gst-indent
2004-03-14 Benjamin Otte <otte@gnome.org>
* gst/modplug/gstmodplug.cc:

View file

@ -6,7 +6,7 @@
* connection would use the I420 format (assuming Xv is enabled) */
static void
new_pad_func (GstElement *element, GstPad *newpad, gpointer data)
new_pad_func (GstElement * element, GstPad * newpad, gpointer data)
{
GstElement *pipeline = (GstElement *) data;
GstElement *queue = gst_bin_get_by_name (GST_BIN (pipeline), "queue");
@ -19,7 +19,7 @@ new_pad_func (GstElement *element, GstPad *newpad, gpointer data)
}
gint
main (gint argc, gchar *argv[])
main (gint argc, gchar * argv[])
{
GstElement *pipeline;
GstElement *filesrc;
@ -44,7 +44,8 @@ main (gint argc, gchar *argv[])
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
demux = gst_element_factory_make ("mpegdemux", "demux");
g_return_val_if_fail (demux, -1);
g_signal_connect (G_OBJECT (demux), "new_pad", G_CALLBACK (new_pad_func), pipeline);
g_signal_connect (G_OBJECT (demux), "new_pad", G_CALLBACK (new_pad_func),
pipeline);
thread = gst_thread_new ("thread");
queue = gst_element_factory_make ("queue", "queue");
@ -58,7 +59,7 @@ main (gint argc, gchar *argv[])
gst_bin_add (GST_BIN (pipeline), filesrc);
gst_bin_add (GST_BIN (pipeline), demux);
gst_bin_add (GST_BIN (thread), queue);
gst_bin_add (GST_BIN (thread), mpeg2dec);
gst_bin_add (GST_BIN (thread), colorspace);
@ -70,11 +71,9 @@ main (gint argc, gchar *argv[])
gst_element_link (mpeg2dec, "src", colorspace, "sink");
/* force RGB data passing between colorspace and xvideosink */
res = gst_element_link_filtered (colorspace, "src", xvideosink, "sink",
GST_CAPS_NEW (
"filtercaps",
"video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
));
GST_CAPS_NEW ("filtercaps",
"video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
));
if (!res) {
g_print ("could not connect colorspace and xvideosink\n");
return -1;
@ -83,7 +82,7 @@ main (gint argc, gchar *argv[])
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

@ -18,13 +18,13 @@ struct _filter_ui
GtkWidget *window; /* top-level interface window */
GtkWidget *buttons; /* all of the control buttons */
GtkWidget *parse, *play, *stop; /* control buttons */
GtkWidget *parse, *play, *stop; /* control buttons */
GtkWidget *feedback; /* here's where we'll tell you stuff */
GtkTextBuffer *fb_buffer; /* feedback buffer */
GtkWidget *selection; /* the place to input element stuff */
GtkWidget *input, *filter, *output; /* the selection widgets */
GtkWidget *input, *filter, *output; /* the selection widgets */
GtkWidget *control; /* the dynamically generated control UI */
};
@ -33,13 +33,13 @@ typedef struct _filter_ui _filter_ui_t;
/* back-end data */
struct _filter_data
{
_filter_ui_t *ui; /* the UI data */
_filter_ui_t *ui; /* the UI data */
gchar *input_pipe, *output_pipe, *filter_element;
gchar *pipe_string;
GList *filter_choices;
gboolean playing;
GstElement *input, *output; /* these are in and out bins */
GstElement *input, *output; /* these are in and out bins */
GstElement *pipeline;
GstElement *filter;
};
@ -47,17 +47,18 @@ struct _filter_data
typedef struct _filter_data _filter_data_t;
/* internal prototypes when they can't be avoided */
void cb_remove_and_destroy (GtkWidget *widget, gpointer user_data);
//void cb_dynparm_value_changed (GtkWidget *widget, gpointer user_data);
void cb_dynparm_value_changed (GtkRange *range, GstDParam *dparam);
void cb_remove_and_destroy (GtkWidget * widget, gpointer user_data);
//void cb_dynparm_value_changed (GtkWidget *widget, gpointer user_data);
void cb_dynparm_value_changed (GtkRange * range, GstDParam * dparam);
/* GStreamer helper functions go here */
/* go through a bin, finding the one pad that is unconnected in the given
* direction, and return a ghost pad */
GstPad *
gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction,
gchar *name)
gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction,
gchar * name)
{
GstPad *pad = NULL;
GList *elements = NULL;
@ -67,39 +68,36 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction,
g_print ("DEBUG: find_unconnected start\n");
elements = (GList *) gst_bin_get_list (bin);
/* traverse all elements looking for unconnected pads */
while (elements && pad == NULL)
{
while (elements && pad == NULL) {
element = GST_ELEMENT (elements->data);
g_print ("DEBUG: looking in element %s\n", gst_element_get_name (element));
pads = gst_element_get_pad_list (element);
while (pads)
{
while (pads) {
/* check if the direction matches */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction)
{
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL)
{
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
/* found it ! */
g_print ("DEBUG: found an unconnected pad !\n");
pad = GST_PAD (pads->data);
}
}
if (pad) break; /* found one already */
if (pad)
break; /* found one already */
pads = g_list_next (pads);
}
elements = g_list_next (elements);
}
g_print ("DEBUG: find_unconnected stop\n");
if (pad == NULL) /* we didn't find it at all */
if (pad == NULL) /* we didn't find it at all */
return NULL;
pad = gst_ghost_pad_new (name, pad);
return pad;
}
void
ui_feedback_add_text (_filter_ui_t *ui, const gchar *text)
ui_feedback_add_text (_filter_ui_t * ui, const gchar * text)
{
GtkTextIter iter;
@ -108,7 +106,7 @@ ui_feedback_add_text (_filter_ui_t *ui, const gchar *text)
}
void
ui_feedback_add (_filter_ui_t *ui, const gchar *format, ...)
ui_feedback_add (_filter_ui_t * ui, const gchar * format, ...)
{
va_list args;
gchar *buffer = NULL;
@ -121,7 +119,7 @@ ui_feedback_add (_filter_ui_t *ui, const gchar *format, ...)
}
void
ui_feedback_clear (_filter_ui_t *ui)
ui_feedback_clear (_filter_ui_t * ui)
{
gtk_text_buffer_set_text (ui->fb_buffer, "", 0);
}
@ -129,7 +127,7 @@ ui_feedback_clear (_filter_ui_t *ui)
/* create the control widget using the element's dynparams
* control is a vbox which we need to empty first */
void
ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
ui_control_create (GstElement * element, GtkWidget * control, _filter_ui_t * ui)
{
GtkWidget *hbox = NULL;
GtkWidget *widget = NULL;
@ -137,70 +135,63 @@ ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
GstDParam *dparam = NULL;
GParamSpec **specs = NULL;
int i = 0;
g_assert (GTK_IS_VBOX (control));
/* empty control vbox */
g_print ("DEBUG: emptying control widget\n");
gtk_container_foreach (GTK_CONTAINER (control), cb_remove_and_destroy,
(gpointer) control);
gtk_container_foreach (GTK_CONTAINER (control), cb_remove_and_destroy,
(gpointer) control);
g_print ("DEBUG: adding label to control widget\n");
widget = gtk_label_new ("Dynamic Parameters");
gtk_container_add (GTK_CONTAINER (control), widget);
gtk_widget_show (widget);
if ((dpman = gst_dpman_get_manager (element)))
{
if ((dpman = gst_dpman_get_manager (element))) {
ui_feedback_add (ui, "Found Dynamic Parameters on filter element.\n");
specs = gst_dpman_list_dparam_specs (dpman);
for (i = 0; specs[i] != NULL; ++i)
{
for (i = 0; specs[i] != NULL; ++i) {
hbox = gtk_hbox_new (FALSE, 0);
widget = gtk_label_new (g_param_spec_get_name (specs[i]));
gtk_container_add (GTK_CONTAINER (hbox), widget);
gtk_widget_show (widget);
switch (G_PARAM_SPEC_VALUE_TYPE (specs[i]))
{
case G_TYPE_INT64:
switch (G_PARAM_SPEC_VALUE_TYPE (specs[i])) {
case G_TYPE_INT64:
widget = gtk_hscale_new_with_range (
(gdouble) (((GParamSpecInt64*)specs[i])->minimum),
(gdouble) (((GParamSpecInt64*)specs[i])->maximum),
1.0);
(gdouble) (((GParamSpecInt64 *) specs[i])->minimum),
(gdouble) (((GParamSpecInt64 *) specs[i])->maximum), 1.0);
gtk_range_set_value (GTK_RANGE (widget),
(gdouble) ((GParamSpecInt64*)specs[i])->default_value);
break;
(gdouble) ((GParamSpecInt64 *) specs[i])->default_value);
break;
case G_TYPE_INT:
widget = gtk_hscale_new_with_range (
(gdouble) (((GParamSpecInt*)specs[i])->minimum),
(gdouble) (((GParamSpecInt*)specs[i])->maximum),
1.0);
(gdouble) (((GParamSpecInt *) specs[i])->minimum),
(gdouble) (((GParamSpecInt *) specs[i])->maximum), 1.0);
gtk_range_set_value (GTK_RANGE (widget),
(gdouble) ((GParamSpecInt*)specs[i])->default_value);
break;
case G_TYPE_FLOAT:
(gdouble) ((GParamSpecInt *) specs[i])->default_value);
break;
case G_TYPE_FLOAT:
widget = gtk_hscale_new_with_range (
(gdouble) (((GParamSpecFloat*)specs[i])->minimum),
(gdouble) (((GParamSpecFloat*)specs[i])->maximum),
0.00001);
(gdouble) (((GParamSpecFloat *) specs[i])->minimum),
(gdouble) (((GParamSpecFloat *) specs[i])->maximum), 0.00001);
gtk_range_set_value (GTK_RANGE (widget),
(gdouble) ((GParamSpecFloat*)specs[i])->default_value);
(gdouble) ((GParamSpecFloat *) specs[i])->default_value);
break;
}
/* create the dparam object */
dparam = gst_dpsmooth_new (G_PARAM_SPEC_VALUE_TYPE (specs[i]));
g_object_set (G_OBJECT (dparam), "update_period", 2000000LL, NULL);
g_assert (gst_dpman_attach_dparam (dpman,
(gchar *) g_param_spec_get_name (specs[i]),
dparam));
gst_dpman_set_mode(dpman, "asynchronous");
g_assert (gst_dpman_attach_dparam (dpman,
(gchar *) g_param_spec_get_name (specs[i]), dparam));
gst_dpman_set_mode (dpman, "asynchronous");
g_signal_connect (widget, "value-changed",
G_CALLBACK (cb_dynparm_value_changed), dparam);
G_CALLBACK (cb_dynparm_value_changed), dparam);
cb_dynparm_value_changed (GTK_RANGE (widget), dparam);
gtk_container_add (GTK_CONTAINER (hbox), widget);
gtk_widget_show (widget);
gtk_widget_show (widget);
}
gtk_container_add (GTK_CONTAINER (control), hbox);
gtk_widget_show (hbox);
@ -209,7 +200,7 @@ ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
/* all the pretty callbacks gather here please */
void
cb_remove_and_destroy (GtkWidget *widget, gpointer user_data)
cb_remove_and_destroy (GtkWidget * widget, gpointer user_data)
{
GtkContainer *container = GTK_CONTAINER (user_data);
@ -220,55 +211,51 @@ cb_remove_and_destroy (GtkWidget *widget, gpointer user_data)
/* when the scale associated with a dparam changes, respond */
void
cb_dynparm_value_changed (GtkRange *range, GstDParam *dparam)
cb_dynparm_value_changed (GtkRange * range, GstDParam * dparam)
{
/*
GstDParam *dparam = GST_DPARAM (user_data);
GtkHScale *adj = GTK_HSCALE (widget);
*/
GstDParam *dparam = GST_DPARAM (user_data);
GtkHScale *adj = GTK_HSCALE (widget);
*/
gdouble value = 0.0;
g_assert (GST_IS_DPARAM (dparam));
g_assert (GTK_IS_RANGE (range));
value = gtk_range_get_value (range);
g_print ("DEBUG: setting value to %f\n", value);
g_print ("DEBUG: setting value to %f\n", value);
switch (G_PARAM_SPEC_VALUE_TYPE (GST_DPARAM_PARAM_SPEC (dparam)))
{
switch (G_PARAM_SPEC_VALUE_TYPE (GST_DPARAM_PARAM_SPEC (dparam))) {
case G_TYPE_INT64:
g_object_set (G_OBJECT (dparam), "value_int64",
(gint64) value, NULL);
g_object_set (G_OBJECT (dparam), "value_int64", (gint64) value, NULL);
break;
case G_TYPE_INT:
g_object_set (G_OBJECT (dparam), "value_int",
(gint) value, NULL);
g_object_set (G_OBJECT (dparam), "value_int", (gint) value, NULL);
break;
case G_TYPE_FLOAT:
g_object_set (G_OBJECT (dparam), "value_float",
(gfloat) value, NULL);
g_object_set (G_OBJECT (dparam), "value_float", (gfloat) value, NULL);
break;
}
}
void
cb_entry_activate (GtkEntry *entry, gpointer user_data)
cb_entry_activate (GtkEntry * entry, gpointer user_data)
{
g_print ("DEBUG: oi ! you activated an entry !\n");
g_print ("DEBUG: pipeline: %s\n", gtk_entry_get_text (entry));
}
void
cb_play_clicked (GtkButton *button, gpointer *user_data)
cb_play_clicked (GtkButton * button, gpointer * user_data)
{
_filter_data_t *fd = (_filter_data_t *) user_data;
g_return_if_fail (GST_IS_PIPELINE (fd->pipeline));
if (GST_STATE (fd->pipeline) == GST_STATE_PLAYING)
{
if (GST_STATE (fd->pipeline) == GST_STATE_PLAYING) {
ui_feedback_add (fd->ui, "Pipeline is already playing !\n");
return;
}
@ -276,12 +263,11 @@ cb_play_clicked (GtkButton *button, gpointer *user_data)
}
void
cb_stop_clicked (GtkButton *button, gpointer *user_data)
cb_stop_clicked (GtkButton * button, gpointer * user_data)
{
_filter_data_t *fd = (_filter_data_t *) user_data;
if (GST_STATE (fd->pipeline) != GST_STATE_PLAYING)
{
if (GST_STATE (fd->pipeline) != GST_STATE_PLAYING) {
ui_feedback_add (fd->ui, "Pipeline is not playing !\n");
return;
}
@ -289,67 +275,72 @@ cb_stop_clicked (GtkButton *button, gpointer *user_data)
}
void
cb_parse_clicked (GtkButton *button, gpointer *user_data)
cb_parse_clicked (GtkButton * button, gpointer * user_data)
{
_filter_data_t *fd = (_filter_data_t *) user_data;
GtkCombo *filter = GTK_COMBO (fd->ui->filter);
GError *error = NULL;
GstPad *src_pad, *sink_pad;
g_print ("DEBUG: you pressed parse.\n");
ui_feedback_clear (fd->ui);
ui_feedback_add (fd->ui, "Parsing pipeline ...\n");
if (fd->input_pipe) g_free (fd->input_pipe);
if (fd->output_pipe) g_free (fd->output_pipe);
if (fd->filter_element) g_free (fd->filter_element);
if (fd->input_pipe)
g_free (fd->input_pipe);
if (fd->output_pipe)
g_free (fd->output_pipe);
if (fd->filter_element)
g_free (fd->filter_element);
fd->input_pipe = g_strdup_printf ("bin.( %s )",
gtk_entry_get_text (GTK_ENTRY (fd->ui->input)));
gtk_entry_get_text (GTK_ENTRY (fd->ui->input)));
fd->output_pipe = g_strdup_printf ("bin.( %s )",
gtk_entry_get_text (GTK_ENTRY (fd->ui->output)));
gtk_entry_get_text (GTK_ENTRY (fd->ui->output)));
/* gtkcombo.h says I can access the entry field directly */
fd->filter_element = g_strdup (gtk_entry_get_text (GTK_ENTRY (filter->entry)));
g_print ("Input pipeline :\t%s (%d)\n", fd->input_pipe, (int)strlen (fd->input_pipe));
g_print ("Filter element :\t%s (%d)\n", fd->filter_element, (int)strlen (fd->filter_element));
g_print ("Output pipeline :\t%s (%d)\n", fd->output_pipe, (int)strlen (fd->output_pipe));
fd->filter_element =
g_strdup (gtk_entry_get_text (GTK_ENTRY (filter->entry)));
g_print ("Input pipeline :\t%s (%d)\n", fd->input_pipe,
(int) strlen (fd->input_pipe));
g_print ("Filter element :\t%s (%d)\n", fd->filter_element,
(int) strlen (fd->filter_element));
g_print ("Output pipeline :\t%s (%d)\n", fd->output_pipe,
(int) strlen (fd->output_pipe));
/* try to create in and out bins */
if (strlen (fd->input_pipe) == 0)
{
if (strlen (fd->input_pipe) == 0) {
ui_feedback_add (fd->ui, "Error : try setting an input pipe.\n");
return;
}
if (fd->input) gst_object_unref (GST_OBJECT (fd->input));
if (fd->input)
gst_object_unref (GST_OBJECT (fd->input));
fd->input = GST_ELEMENT (gst_parse_launch (fd->input_pipe, &error));
if (error)
{
ui_feedback_add (fd->ui, "Error : parsing input pipeline : %s\n",
error->message);
if (error) {
ui_feedback_add (fd->ui, "Error : parsing input pipeline : %s\n",
error->message);
g_error_free (error);
return;
}
if (strlen (fd->output_pipe) == 0)
{
if (strlen (fd->output_pipe) == 0) {
ui_feedback_add (fd->ui, "Error : try setting an output pipe.\n");
return;
}
if (fd->output) gst_object_unref (GST_OBJECT (fd->output));
if (fd->output)
gst_object_unref (GST_OBJECT (fd->output));
fd->output = GST_ELEMENT (gst_parse_launch (fd->output_pipe, &error));
if (error)
{
ui_feedback_add (fd->ui, "Error : parsing output pipeline : %s\n",
error->message);
if (error) {
ui_feedback_add (fd->ui, "Error : parsing output pipeline : %s\n",
error->message);
g_error_free (error);
return;
}
/* try to create filter */
if (fd->filter) gst_object_unref (GST_OBJECT (fd->filter));
if (fd->filter)
gst_object_unref (GST_OBJECT (fd->filter));
fd->filter = gst_element_factory_make (fd->filter_element, "filter");
if (fd->filter == NULL)
{
if (fd->filter == NULL) {
ui_feedback_add (fd->ui, "Error : could not create element %s\n",
fd->filter_element);
fd->filter_element);
return;
}
@ -360,35 +351,33 @@ cb_parse_clicked (GtkButton *button, gpointer *user_data)
fd->pipeline = gst_thread_new ("toplevel");
/* add the players to it */
gst_bin_add_many (GST_BIN (fd->pipeline),
fd->input, fd->filter,
fd->output, NULL);
gst_bin_add_many (GST_BIN (fd->pipeline),
fd->input, fd->filter, fd->output, NULL);
/* connect filter to input and output bin */
src_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->input), GST_PAD_SRC,
"source");
if (src_pad == NULL)
{
ui_feedback_add (fd->ui,
"Error : could not find an unconnected source pad !\n");
src_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->input), GST_PAD_SRC,
"source");
if (src_pad == NULL) {
ui_feedback_add (fd->ui,
"Error : could not find an unconnected source pad !\n");
return;
}
sink_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->output), GST_PAD_SINK,
"sink");
if (sink_pad == NULL)
{
ui_feedback_add (fd->ui,
"Error : could not find an unconnected sink pad !\n");
sink_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->output), GST_PAD_SINK,
"sink");
if (sink_pad == NULL) {
ui_feedback_add (fd->ui,
"Error : could not find an unconnected sink pad !\n");
return;
}
gst_element_add_pad (fd->input, src_pad);
gst_element_add_pad (fd->output, sink_pad);
gst_element_link_many (fd->input, fd->filter, fd->output, NULL);
if (fd->pipe_string) g_free (fd->pipe_string);
if (fd->pipe_string)
g_free (fd->pipe_string);
fd->pipe_string = g_strdup_printf ("%s ! %s ! %s", fd->input_pipe,
fd->filter_element, fd->output_pipe);
fd->filter_element, fd->output_pipe);
g_print ("Pipeline : %s\n", fd->pipe_string);
ui_feedback_add (fd->ui, "Complete parsed pipeline: %s\n", fd->pipe_string);
@ -404,12 +393,12 @@ get_filter_choices (void)
choices = g_list_append (choices, "volume");
choices = g_list_append (choices, "ladspa_lpf");
choices = g_list_append (choices, "ladspa_hpf");
return choices;
}
void
init_data (_filter_data_t *fd)
init_data (_filter_data_t * fd)
{
fd->input_pipe = NULL;
fd->output_pipe = NULL;
@ -426,11 +415,11 @@ init_data (_filter_data_t *fd)
}
void
create_ui (_filter_ui_t *fui, _filter_data_t *fd)
create_ui (_filter_ui_t * fui, _filter_data_t * fd)
{
GtkWidget *widget; /* temporary widget */
GtkWidget *vbox; /* temporary vbox */
g_print ("DEBUG: creating top-level window\n");
fui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
widget = gtk_vbox_new (FALSE, 0);
@ -452,22 +441,22 @@ create_ui (_filter_ui_t *fui, _filter_data_t *fd)
fui->parse = gtk_button_new_with_label ("Parse");
gtk_container_add (GTK_CONTAINER (fui->buttons), fui->parse);
g_signal_connect (G_OBJECT (fui->parse), "clicked",
G_CALLBACK (cb_parse_clicked), fd);
G_CALLBACK (cb_parse_clicked), fd);
fui->play = gtk_button_new_with_label ("Play");
gtk_container_add (GTK_CONTAINER (fui->buttons), fui->play);
g_signal_connect (G_OBJECT (fui->play), "clicked",
G_CALLBACK (cb_play_clicked), fd);
G_CALLBACK (cb_play_clicked), fd);
fui->stop = gtk_button_new_with_label ("Stop");
gtk_container_add (GTK_CONTAINER (fui->buttons), fui->stop);
g_signal_connect (G_OBJECT (fui->stop), "clicked",
G_CALLBACK (cb_stop_clicked), fd);
G_CALLBACK (cb_stop_clicked), fd);
/* feedback widget */
fui->fb_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (fui->feedback));
gtk_text_buffer_set_text (fui->fb_buffer,
"Hello, and welcome to the GStreamer filter demo app !\n"\
gtk_text_buffer_set_text (fui->fb_buffer,
"Hello, and welcome to the GStreamer filter demo app !\n"
"I'll be your feedback window for today.\n", -1);
/* selection widget */
vbox = gtk_vbox_new (FALSE, 0);
widget = gtk_label_new ("Input Pipe");
@ -476,8 +465,8 @@ create_ui (_filter_ui_t *fui, _filter_data_t *fd)
gtk_entry_set_text (GTK_ENTRY (fui->input), "sinesrc");
gtk_container_add (GTK_CONTAINER (vbox), fui->input);
gtk_container_add (GTK_CONTAINER (fui->selection), vbox);
g_signal_connect (G_OBJECT (fui->input), "activate",
G_CALLBACK (cb_entry_activate), NULL);
g_signal_connect (G_OBJECT (fui->input), "activate",
G_CALLBACK (cb_entry_activate), NULL);
vbox = gtk_vbox_new (FALSE, 0);
widget = gtk_label_new ("Filter");
@ -491,18 +480,18 @@ create_ui (_filter_ui_t *fui, _filter_data_t *fd)
widget = gtk_label_new ("Output Pipe");
gtk_container_add (GTK_CONTAINER (vbox), widget);
fui->output = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (fui->output), "osssink fragment=1572872"); /* fixme: gconf default ? */
gtk_entry_set_text (GTK_ENTRY (fui->output), "osssink fragment=1572872"); /* fixme: gconf default ? */
gtk_container_add (GTK_CONTAINER (vbox), fui->output);
gtk_container_add (GTK_CONTAINER (fui->selection), vbox);
g_signal_connect (G_OBJECT (fui->output), "activate",
G_CALLBACK (cb_entry_activate), NULL);
g_signal_connect (G_OBJECT (fui->output), "activate",
G_CALLBACK (cb_entry_activate), NULL);
/* control widget is dynamically generated */
/*
g_print ("DEBUG: labeling control area.\n");
widget = gtk_label_new ("This is the big control area.");
gtk_container_add (GTK_CONTAINER (fui->control), widget);
*/
g_print ("DEBUG: labeling control area.\n");
widget = gtk_label_new ("This is the big control area.");
gtk_container_add (GTK_CONTAINER (fui->control), widget);
*/
}
@ -511,8 +500,8 @@ main (int argc, char *argv[])
{
_filter_data_t filter_data;
_filter_ui_t filter_ui;
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
gst_control_init (&argc, &argv);
@ -524,7 +513,6 @@ main (int argc, char *argv[])
gtk_widget_show_all (filter_ui.window);
gtk_main ();
return 0;
}

View file

@ -16,14 +16,14 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gst/play/play.h>
static GMainLoop *loop = NULL;
static gint64 length = 0;
static void
print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
{
gint i, count;
@ -31,14 +31,14 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
for (i = 0; i < count; i++) {
gchar *str;
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
g_assert (gst_tag_list_get_string_index (list, tag, i, &str));
} else {
str = g_strdup_value_contents (
gst_tag_list_get_value_index (list, tag, i));
str =
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
}
if (i == 0) {
g_print ("%15s: %s\n", gst_tag_get_nick (tag), str);
} else {
@ -50,46 +50,46 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
}
static void
got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list)
got_found_tag (GstPlay * play, GstElement * source, GstTagList * tag_list)
{
gst_tag_list_foreach (tag_list, print_tag, NULL);
}
static void
got_time_tick (GstPlay *play, gint64 time_nanos)
got_time_tick (GstPlay * play, gint64 time_nanos)
{
g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
}
static void
got_stream_length (GstPlay *play, gint64 length_nanos)
got_stream_length (GstPlay * play, gint64 length_nanos)
{
g_print ("got length %llu\n", length_nanos);
length = length_nanos;
}
static void
got_video_size (GstPlay *play, gint width, gint height)
got_video_size (GstPlay * play, gint width, gint height)
{
g_print ("got video size %d, %d\n", width, height);
}
static void
got_eos (GstPlay *play)
got_eos (GstPlay * play)
{
g_print ("End Of Stream\n");
g_main_loop_quit (loop);
}
static gboolean
seek_timer (GstPlay *play)
seek_timer (GstPlay * play)
{
gst_play_seek_to_time (play, length / 2);
return FALSE;
}
static gboolean
idle_iterate (GstPlay *play)
idle_iterate (GstPlay * play)
{
gst_bin_iterate (GST_BIN (play));
return (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING);
@ -114,8 +114,7 @@ main (int argc, char *argv[])
/* Creating the GstPlay object */
play = gst_play_new (&error);
if (error)
{
if (error) {
g_print ("Error: could not create play object:\n%s\n", error->message);
g_error_free (error);
return 1;
@ -140,17 +139,16 @@ main (int argc, char *argv[])
/* gst_xml_write_file (GST_ELEMENT (play), stdout); */
g_signal_connect (G_OBJECT (play), "time_tick",
G_CALLBACK (got_time_tick), NULL);
G_CALLBACK (got_time_tick), NULL);
g_signal_connect (G_OBJECT (play), "stream_length",
G_CALLBACK (got_stream_length), NULL);
G_CALLBACK (got_stream_length), NULL);
g_signal_connect (G_OBJECT (play), "have_video_size",
G_CALLBACK (got_video_size), NULL);
G_CALLBACK (got_video_size), NULL);
g_signal_connect (G_OBJECT (play), "found_tag",
G_CALLBACK (got_found_tag), NULL);
G_CALLBACK (got_found_tag), NULL);
g_signal_connect (G_OBJECT (play), "error",
G_CALLBACK (gst_element_default_error), NULL);
g_signal_connect (G_OBJECT (play), "eos",
G_CALLBACK (got_eos), NULL);
G_CALLBACK (gst_element_default_error), NULL);
g_signal_connect (G_OBJECT (play), "eos", G_CALLBACK (got_eos), NULL);
/* Change state to PLAYING */
gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
@ -163,9 +161,9 @@ main (int argc, char *argv[])
g_print ("setting pipeline to ready\n");
gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
/* unref
gst_object_unref (GST_OBJECT (play)); */
gst_object_unref (GST_OBJECT (play)); */
exit (0);
}

View file

@ -24,26 +24,26 @@ static gboolean verbose = FALSE;
static gboolean quiet = FALSE;
static void
entry_added (GstIndex *index, GstIndexEntry *entry)
entry_added (GstIndex * index, GstIndexEntry * entry)
{
switch (entry->type) {
case GST_INDEX_ENTRY_ID:
g_print ("id %d describes writer %s\n", entry->id,
GST_INDEX_ID_DESCRIPTION (entry));
g_print ("id %d describes writer %s\n", entry->id,
GST_INDEX_ID_DESCRIPTION (entry));
break;
case GST_INDEX_ENTRY_FORMAT:
g_print ("%d: registered format %d for %s\n", entry->id,
GST_INDEX_FORMAT_FORMAT (entry),
GST_INDEX_FORMAT_KEY (entry));
g_print ("%d: registered format %d for %s\n", entry->id,
GST_INDEX_FORMAT_FORMAT (entry), GST_INDEX_FORMAT_KEY (entry));
break;
case GST_INDEX_ENTRY_ASSOCIATION:
{
gint i;
g_print ("%p, %d: %08x ", entry, entry->id, GST_INDEX_ASSOC_FLAGS (entry));
g_print ("%p, %d: %08x ", entry, entry->id,
GST_INDEX_ASSOC_FLAGS (entry));
for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) {
g_print ("%d %lld ", GST_INDEX_ASSOC_FORMAT (entry, i),
GST_INDEX_ASSOC_VALUE (entry, i));
g_print ("%d %lld ", GST_INDEX_ASSOC_FORMAT (entry, i),
GST_INDEX_ASSOC_VALUE (entry, i));
}
g_print ("\n");
break;
@ -55,15 +55,15 @@ entry_added (GstIndex *index, GstIndexEntry *entry)
typedef struct
{
const gchar *padname;
GstPad *target;
GstElement *bin;
GstElement *pipeline;
GstIndex *index;
const gchar *padname;
GstPad *target;
GstElement *bin;
GstElement *pipeline;
GstIndex *index;
} dyn_link;
static void
dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
{
dyn_link *link = (dyn_link *) data;
@ -77,27 +77,25 @@ dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
}
static void
setup_dynamic_linking (GstElement *pipeline,
GstElement *element,
const gchar *padname,
GstPad *target,
GstElement *bin,
GstIndex *index)
setup_dynamic_linking (GstElement * pipeline,
GstElement * element,
const gchar * padname, GstPad * target, GstElement * bin, GstIndex * index)
{
dyn_link *link;
link = g_new0 (dyn_link, 1);
link->padname = g_strdup (padname);
link->target = target;
link->bin = bin;
link->pipeline = pipeline;
link->index = index;
link->padname = g_strdup (padname);
link->target = target;
link->bin = bin;
link->pipeline = pipeline;
link->index = index;
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link), link);
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
link);
}
static GstElement*
make_mpeg_systems_pipeline (const gchar *path, GstIndex *index)
static GstElement *
make_mpeg_systems_pipeline (const gchar * path, GstIndex * index)
{
GstElement *pipeline;
GstElement *src, *demux;
@ -117,12 +115,12 @@ make_mpeg_systems_pipeline (const gchar *path, GstIndex *index)
}
gst_element_link_pads (src, "src", demux, "sink");
return pipeline;
}
static GstElement*
make_mpeg_decoder_pipeline (const gchar *path, GstIndex *index)
static GstElement *
make_mpeg_decoder_pipeline (const gchar * path, GstIndex * index)
{
GstElement *pipeline;
GstElement *src, *demux;
@ -145,29 +143,27 @@ make_mpeg_decoder_pipeline (const gchar *path, GstIndex *index)
video_decoder = gst_element_factory_make ("mpeg2dec", "video_decoder");
gst_bin_add (GST_BIN (video_bin), video_decoder);
setup_dynamic_linking (pipeline, demux, "video_00",
gst_element_get_pad (video_decoder, "sink"),
video_bin, index);
setup_dynamic_linking (pipeline, demux, "video_00",
gst_element_get_pad (video_decoder, "sink"), video_bin, index);
audio_bin = gst_bin_new ("audio_bin");
audio_decoder = gst_element_factory_make ("mad", "audio_decoder");
setup_dynamic_linking (pipeline, demux, "audio_00",
gst_element_get_pad (audio_decoder, "sink"),
audio_bin, index);
setup_dynamic_linking (pipeline, demux, "audio_00",
gst_element_get_pad (audio_decoder, "sink"), audio_bin, index);
gst_bin_add (GST_BIN (audio_bin), audio_decoder);
if (index) {
gst_element_set_index (pipeline, index);
}
return pipeline;
}
static void
print_progress (GstPad *pad)
print_progress (GstPad * pad)
{
gint i = 0;
gchar status[53];
@ -181,14 +177,14 @@ print_progress (GstPad *pad)
format = GST_FORMAT_PERCENT;
res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
if (res) {
percent = value / (2 * GST_FORMAT_PERCENT_SCALE);
percent = value / (2 * GST_FORMAT_PERCENT_SCALE);
}
for (i = 0; i < percent; i++) {
status[i+1] = '=';
status[i + 1] = '=';
}
for (i = percent; i < 50; i++) {
status[i+1] = ' ';
status[i + 1] = ' ';
}
status[51] = '|';
status[52] = 0;
@ -196,8 +192,8 @@ print_progress (GstPad *pad)
g_print ("%s\r", status);
}
gint
main (gint argc, gchar *argv[])
gint
main (gint argc, gchar * argv[])
{
GstElement *pipeline;
GstElement *src;
@ -208,27 +204,28 @@ main (gint argc, gchar *argv[])
gboolean res;
GstElement *sink;
struct poptOption options[] = {
{ "verbose", 'v', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &verbose, 0,
"Print index entries", NULL},
{ "quiet", 'q', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &quiet, 0,
"don't print progress bar", NULL},
POPT_TABLEEND
};
{"verbose", 'v', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &verbose, 0,
"Print index entries", NULL},
{"quiet", 'q', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &quiet, 0,
"don't print progress bar", NULL},
POPT_TABLEEND
};
if (!gst_init_check_with_popt_table (&argc, &argv, options) || argc < 3) {
g_print ("usage: %s [-v] <type> <filename> \n"
" type can be: 0 mpeg_systems\n"
" 1 mpeg_decoder\n"
" -v : report added index entries\n"
" -q : don't print progress\n" , argv[0]);
g_print ("usage: %s [-v] <type> <filename> \n"
" type can be: 0 mpeg_systems\n"
" 1 mpeg_decoder\n"
" -v : report added index entries\n"
" -q : don't print progress\n", argv[0]);
return -1;
}
/* create index that elements can fill */
index = gst_index_factory_make ("memindex");
if (index) {
if (verbose)
g_signal_connect (G_OBJECT (index), "entry_added", G_CALLBACK (entry_added), NULL);
if (verbose)
g_signal_connect (G_OBJECT (index), "entry_added",
G_CALLBACK (entry_added), NULL);
g_object_set (G_OBJECT (index), "resolver", 1, NULL);
}
@ -247,10 +244,10 @@ main (gint argc, gchar *argv[])
}
/* setup some default info/error handlers */
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (G_OBJECT (pipeline), "error",
G_CALLBACK (gst_element_default_error), NULL);
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (G_OBJECT (pipeline), "error",
G_CALLBACK (gst_element_default_error), NULL);
/* get a pad to perform progress reporting on */
src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
@ -259,7 +256,7 @@ main (gint argc, gchar *argv[])
/* prepare for iteration */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_print ("indexing %s...\n", argv [2]);
g_print ("indexing %s...\n", argv[2]);
/* run through the complete stream to let it generate an index */
while (gst_bin_iterate (GST_BIN (pipeline))) {
if (!quiet && (count % 1000 == 0)) {
@ -285,24 +282,23 @@ main (gint argc, gchar *argv[])
gint total_tm;
gst_index_get_writer_id (index, GST_OBJECT (src), &id);
entry = gst_index_get_assoc_entry (index, id, GST_INDEX_LOOKUP_BEFORE, 0,
GST_FORMAT_TIME, G_MAXINT64);
GST_FORMAT_TIME, G_MAXINT64);
g_assert (entry);
gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &result);
total_tm = result * 60 / GST_SECOND;
g_print ("total time = %.2fs\n", total_tm / 60.0);
}
pad = gst_element_get_pad (src, "src");
sink = gst_element_factory_make ("fakesink", "sink");
gst_element_link_pads (src, "src", sink, "sink");
gst_bin_add (GST_BIN (pipeline), sink);
g_print ("seeking %s...\n", argv [2]);
g_print ("seeking %s...\n", argv[2]);
event = gst_event_new_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, 5 * GST_SECOND);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, 5 * GST_SECOND);
res = gst_pad_send_event (pad, event);
if (!res) {
@ -322,4 +318,3 @@ main (gint argc, gchar *argv[])
return 1;
}

View file

@ -3,7 +3,7 @@
#include <string.h>
static void
get_position_info (GstElement *cdparanoia)
get_position_info (GstElement * cdparanoia)
{
GstFormat track_format;
const GstFormat *formats;
@ -24,14 +24,13 @@ get_position_info (GstElement *cdparanoia)
definition = gst_format_get_details (*formats);
format = *formats;
res = gst_pad_query (pad, GST_QUERY_POSITION,
&format, &position);
res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &position);
if (format == GST_FORMAT_TIME) {
position /= GST_SECOND;
g_print ("%s: %lld:%02lld", definition->nick, position/60, position%60);
}
else {
g_print ("%s: %lld:%02lld", definition->nick, position / 60,
position % 60);
} else {
g_print ("%s: %lld", definition->nick, position);
}
@ -44,7 +43,7 @@ get_position_info (GstElement *cdparanoia)
}
static void
get_track_info (GstElement *cdparanoia)
get_track_info (GstElement * cdparanoia)
{
GstFormat track_format;
gint64 total_tracks = 0, total_time = 0;
@ -52,7 +51,7 @@ get_track_info (GstElement *cdparanoia)
const GstFormat *formats;
gint i;
gint64 time_count = 0;
track_format = gst_format_get_by_nick ("track");
g_assert (track_format != 0);
@ -66,26 +65,24 @@ get_track_info (GstElement *cdparanoia)
gint64 total;
GstFormat format;
gboolean res;
definition = gst_format_get_details (*formats);
format = *formats;
res = gst_pad_query (pad, GST_QUERY_TOTAL,
&format, &total);
res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &total);
if (res) {
if (format == GST_FORMAT_TIME) {
total /= GST_SECOND;
g_print ("%s total: %lld:%02lld\n", definition->nick, total/60, total%60);
}
else
g_print ("%s total: %lld\n", definition->nick, total);
g_print ("%s total: %lld:%02lld\n", definition->nick, total / 60,
total % 60);
} else
g_print ("%s total: %lld\n", definition->nick, total);
if (format == track_format)
total_tracks = total;
else if (format == GST_FORMAT_TIME)
total_time = total;
}
else
} else
g_print ("failed to get %s total\n", definition->nick);
formats++;
@ -102,11 +99,9 @@ get_track_info (GstElement *cdparanoia)
GstFormat format;
format = GST_FORMAT_TIME;
res = gst_pad_convert (pad, track_format, i,
&format, &time);
res = gst_pad_convert (pad, track_format, i, &format, &time);
time /= GST_SECOND;
}
else {
} else {
time = total_time;
res = TRUE;
}
@ -117,14 +112,12 @@ get_track_info (GstElement *cdparanoia)
if (i > 0) {
gint64 length = time - time_count;
g_print ("track %d: %lld:%02lld -> %lld:%02lld, length: %lld:%02lld\n",
i-1,
time_count / 60, time_count % 60,
time / 60, time % 60,
length / 60, length % 60);
g_print ("track %d: %lld:%02lld -> %lld:%02lld, length: %lld:%02lld\n",
i - 1,
time_count / 60, time_count % 60,
time / 60, time % 60, length / 60, length % 60);
}
}
else {
} else {
g_print ("could not get time for track %d\n", i);
}
@ -161,7 +154,7 @@ main (int argc, char **argv)
gst_element_link_pads (cdparanoia, "src", osssink, "sink");
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
G_CALLBACK (gst_element_default_deep_notify), NULL);
gst_element_set_state (pipeline, GST_STATE_PAUSED);
@ -177,9 +170,7 @@ main (int argc, char **argv)
g_print ("playing from track 3\n");
/* seek to track3 */
event = gst_event_new_seek (track_format |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH,
3);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, 3);
res = gst_pad_send_event (pad, event);
if (!res)
@ -198,9 +189,8 @@ main (int argc, char **argv)
g_print ("\nplaying from second 25 to second 29\n");
/* seek to some seconds */
event = gst_event_new_segment_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH,
25 * GST_SECOND, 29 * GST_SECOND);
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, 25 * GST_SECOND, 29 * GST_SECOND);
res = gst_pad_send_event (pad, event);
if (!res)
g_warning ("seek failed");

View file

@ -15,11 +15,11 @@ static guint update_id;
#define UPDATE_INTERVAL 500
static GstElement*
make_cdaudio_pipeline (void)
static GstElement *
make_cdaudio_pipeline (void)
{
GstElement *cdaudio;
cdaudio = gst_element_factory_make ("cdaudio", "cdaudio");
g_assert (cdaudio != NULL);
@ -28,9 +28,8 @@ make_cdaudio_pipeline (void)
return cdaudio;
}
static gchar*
format_value (GtkScale *scale,
gdouble value)
static gchar *
format_value (GtkScale * scale, gdouble value)
{
gint64 real;
gint64 seconds;
@ -41,9 +40,7 @@ format_value (GtkScale *scale,
subseconds = (gint64) real / (GST_SECOND / 100);
return g_strdup_printf ("%02lld:%02lld:%02lld",
seconds/60,
seconds%60,
subseconds%100);
seconds / 60, seconds % 60, subseconds % 100);
}
typedef struct
@ -52,13 +49,12 @@ typedef struct
const GstFormat format;
} seek_format;
static seek_format seek_formats[] =
{
{ "tim", GST_FORMAT_TIME },
{ "byt", GST_FORMAT_BYTES },
{ "buf", GST_FORMAT_BUFFERS },
{ "def", GST_FORMAT_DEFAULT },
{ NULL, 0 },
static seek_format seek_formats[] = {
{"tim", GST_FORMAT_TIME},
{"byt", GST_FORMAT_BYTES},
{"buf", GST_FORMAT_BUFFERS},
{"def", GST_FORMAT_DEFAULT},
{NULL, 0},
};
@ -80,10 +76,9 @@ query_durations ()
format = seek_formats[i].format;
res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
@ -110,10 +105,9 @@ query_positions ()
format = seek_formats[i].format;
res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
@ -123,7 +117,7 @@ query_positions ()
}
static gboolean
update_scale (gpointer data)
update_scale (gpointer data)
{
GstClock *clock;
guint64 position = 0;
@ -134,6 +128,7 @@ update_scale (gpointer data)
if (seekable_elements) {
GstElement *element = GST_ELEMENT (seekable_elements->data);
gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
}
if (clock)
@ -141,7 +136,8 @@ update_scale (gpointer data)
if (stats) {
if (clock)
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
g_print ("clock: %13llu (%s)\n", position,
gst_object_get_name (GST_OBJECT (clock)));
query_durations ();
query_positions ();
}
@ -167,7 +163,7 @@ iterate (gpointer data)
}
static gboolean
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gtk_timeout_remove (update_id);
@ -176,7 +172,7 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
}
static gboolean
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
gboolean res;
@ -188,8 +184,7 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable));
s_event = gst_event_new_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, real);
res = gst_element_send_event (seekable, s_event);
@ -199,7 +194,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
return FALSE;
}
@ -211,7 +207,8 @@ play_cb (GtkButton * button, gpointer data)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
}
}
@ -236,22 +233,23 @@ stop_cb (GtkButton * button, gpointer data)
int
main (int argc, char **argv)
{
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button,
*hscale;
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button, *hscale;
struct poptOption options[] = {
{"stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
"Show element stats", NULL},
POPT_TABLEEND
};
{"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
"Show element stats", NULL},
POPT_TABLEEND
};
gst_init_with_popt_table (&argc, &argv, options);
gtk_init (&argc, &argv);
pipeline = make_cdaudio_pipeline ();
g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
g_signal_connect (pipeline, "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
NULL);
/* initialize gui elements ... */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@ -261,17 +259,18 @@ main (int argc, char **argv)
pause_button = gtk_button_new_with_label ("pause");
stop_button = gtk_button_new_with_label ("stop");
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
adjustment =
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
hscale = gtk_hscale_new (adjustment);
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"format_value", G_CALLBACK (format_value), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"format_value", G_CALLBACK (format_value), pipeline);
/* do the packing stuff ... */
gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
@ -283,9 +282,12 @@ main (int argc, char **argv)
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
/* connect things ... */
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
pipeline);
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
/* show the gui. */

View file

@ -25,26 +25,25 @@ static guint update_id;
typedef struct
{
const gchar *padname;
GstPad *target;
GstElement *bin;
const gchar *padname;
GstPad *target;
GstElement *bin;
} dyn_link;
static GstElement *
gst_element_factory_make_or_warn (gchar *type, gchar *name)
gst_element_factory_make_or_warn (gchar * type, gchar * name)
{
GstElement *element = gst_element_factory_make (type, name);
if (!element) {
g_warning ("Failed to create element %s of type %s",
name, type);
g_warning ("Failed to create element %s of type %s", name, type);
}
return element;
}
static void
dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
{
dyn_link *connect = (dyn_link *) data;
@ -60,25 +59,27 @@ dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
}
static void
setup_dynamic_link (GstElement *element, const gchar *padname, GstPad *target, GstElement *bin)
setup_dynamic_link (GstElement * element, const gchar * padname,
GstPad * target, GstElement * bin)
{
dyn_link *connect;
connect = g_new0 (dyn_link, 1);
connect->padname = g_strdup (padname);
connect->target = target;
connect->bin = bin;
connect->padname = g_strdup (padname);
connect->target = target;
connect->bin = bin;
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link), connect);
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
connect);
}
static GstElement*
make_mod_pipeline (const gchar *location)
static GstElement *
make_mod_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -103,13 +104,13 @@ make_mod_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_dv_pipeline (const gchar *location)
static GstElement *
make_dv_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink, *videosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -140,13 +141,13 @@ make_dv_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_wav_pipeline (const gchar *location)
static GstElement *
make_wav_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -171,13 +172,13 @@ make_wav_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_flac_pipeline (const gchar *location)
static GstElement *
make_flac_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -202,13 +203,13 @@ make_flac_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_sid_pipeline (const gchar *location)
static GstElement *
make_sid_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -233,13 +234,13 @@ make_sid_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_parse_pipeline (const gchar *location)
static GstElement *
make_parse_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *parser, *fakesink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -265,13 +266,13 @@ make_parse_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_vorbis_pipeline (const gchar *location)
static GstElement *
make_vorbis_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -296,13 +297,13 @@ make_vorbis_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_mp3_pipeline (const gchar *location)
static GstElement *
make_mp3_pipeline (const gchar * location)
{
GstElement *pipeline;
GstElement *src, *decoder, *osssink, *queue, *audio_thread;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -335,14 +336,15 @@ make_mp3_pipeline (const gchar *location)
return pipeline;
}
static GstElement*
make_avi_pipeline (const gchar *location)
static GstElement *
make_avi_pipeline (const gchar * location)
{
GstElement *pipeline, *audio_bin, *video_bin;
GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue = NULL, *video_thread = NULL;
GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue =
NULL, *video_thread = NULL;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -369,12 +371,14 @@ make_avi_pipeline (const gchar *location)
gst_bin_add (GST_BIN (audio_thread), audiosink);
gst_element_set_state (audio_bin, GST_STATE_PAUSED);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
"sink"), audio_bin);
seekable = gst_element_get_pad (a_queue, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
video_bin = gst_bin_new ("v_decoder_bin");
//v_decoder = gst_element_factory_make_or_warn ("identity", "v_dec");
@ -395,25 +399,27 @@ make_avi_pipeline (const gchar *location)
gst_element_set_state (video_bin, GST_STATE_PAUSED);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
"sink"), video_bin);
seekable = gst_element_get_pad (v_queue, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
return pipeline;
}
static GstElement*
make_mpeg_pipeline (const gchar *location)
static GstElement *
make_mpeg_pipeline (const gchar * location)
{
GstElement *pipeline, *audio_bin, *video_bin;
GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
GstElement *audiosink, *videosink;
GstElement *a_queue, *audio_thread, *v_queue, *video_thread;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -441,12 +447,14 @@ make_mpeg_pipeline (const gchar *location)
gst_bin_add (GST_BIN (audio_thread), a_queue);
gst_bin_add (GST_BIN (audio_thread), audiosink);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
"sink"), audio_bin);
seekable = gst_element_get_pad (a_queue, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
video_bin = gst_bin_new ("v_decoder_bin");
v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
@ -456,30 +464,32 @@ make_mpeg_pipeline (const gchar *location)
v_filter = gst_element_factory_make_or_warn ("colorspace", "v_filter");
videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
gst_element_link_many (v_decoder, v_queue, v_filter, NULL);
gst_element_link (v_filter, videosink);
gst_bin_add_many (GST_BIN (video_bin), v_decoder, video_thread, NULL);
gst_bin_add_many (GST_BIN (video_thread), v_queue, v_filter, videosink, NULL);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
"sink"), video_bin);
seekable = gst_element_get_pad (v_queue, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
return pipeline;
}
static GstElement*
make_mpegnt_pipeline (const gchar *location)
static GstElement *
make_mpegnt_pipeline (const gchar * location)
{
GstElement *pipeline, *audio_bin, *video_bin;
GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
GstElement *audiosink, *videosink;
GstElement *a_queue, *audio_thread;
GstPad *seekable;
pipeline = gst_pipeline_new ("app");
src = gst_element_factory_make_or_warn (SOURCE, "src");
@ -508,40 +518,43 @@ make_mpegnt_pipeline (const gchar *location)
gst_bin_add (GST_BIN (audio_thread), a_queue);
gst_bin_add (GST_BIN (audio_thread), audiosink);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
"sink"), audio_bin);
seekable = gst_element_get_pad (a_queue, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
video_bin = gst_bin_new ("v_decoder_bin");
v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
v_filter = gst_element_factory_make_or_warn ("colorspace", "v_filter");
videosink = gst_element_factory_make_or_warn ("xvideosink", "v_sink");
gst_element_link_many (v_decoder, v_filter, videosink, NULL);
gst_bin_add_many (GST_BIN (video_bin), v_decoder, v_filter, videosink, NULL);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
"sink"), video_bin);
seekable = gst_element_get_pad (v_decoder, "src");
seekable_pads = g_list_prepend (seekable_pads, seekable);
rate_pads = g_list_prepend (rate_pads, seekable);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
return pipeline;
}
static GstElement*
make_playerbin_pipeline (const gchar *location)
static GstElement *
make_playerbin_pipeline (const gchar * location)
{
return NULL;
}
static gchar*
format_value (GtkScale *scale,
gdouble value)
static gchar *
format_value (GtkScale * scale, gdouble value)
{
gint64 real;
gint64 seconds;
@ -552,9 +565,7 @@ format_value (GtkScale *scale,
subseconds = (gint64) real / (GST_SECOND / 100);
return g_strdup_printf ("%02lld:%02lld:%02lld",
seconds/60,
seconds%60,
subseconds%100);
seconds / 60, seconds % 60, subseconds % 100);
}
typedef struct
@ -563,13 +574,12 @@ typedef struct
const GstFormat format;
} seek_format;
static seek_format seek_formats[] =
{
{ "tim", GST_FORMAT_TIME },
{ "byt", GST_FORMAT_BYTES },
{ "buf", GST_FORMAT_BUFFERS },
{ "def", GST_FORMAT_DEFAULT },
{ NULL, 0 },
static seek_format seek_formats[] = {
{"tim", GST_FORMAT_TIME},
{"byt", GST_FORMAT_BYTES},
{"buf", GST_FORMAT_BUFFERS},
{"def", GST_FORMAT_DEFAULT},
{NULL, 0},
};
G_GNUC_UNUSED static void
@ -588,13 +598,10 @@ query_rates (void)
format = seek_formats[i].format;
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND,
&format, &value))
{
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
@ -623,15 +630,14 @@ query_durations ()
format = seek_formats[i].format;
res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
g_print (" %s:%s\n", GST_DEBUG_PAD_NAME (pad));
walk = g_list_next (walk);
}
}
@ -654,10 +660,9 @@ query_positions ()
format = seek_formats[i].format;
res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
@ -668,7 +673,7 @@ query_positions ()
}
static gboolean
update_scale (gpointer data)
update_scale (gpointer data)
{
GstClock *clock;
guint64 position;
@ -679,12 +684,14 @@ update_scale (gpointer data)
if (seekable_pads) {
GstPad *pad = GST_PAD (seekable_pads->data);
gst_pad_query (pad, GST_QUERY_TOTAL, &format, &duration);
}
position = gst_clock_get_time (clock);
if (stats) {
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
g_print ("clock: %13llu (%s)\n", position,
gst_object_get_name (GST_OBJECT (clock)));
query_durations ();
query_positions ();
query_rates ();
@ -711,7 +718,7 @@ iterate (gpointer data)
}
static gboolean
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gtk_timeout_remove (update_id);
@ -720,21 +727,23 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
}
static gboolean
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
gboolean res;
GstEvent *s_event;
#ifdef PAD_SEEK
GList *walk = seekable_pads;
while (walk) {
GstPad *seekable = GST_PAD (walk->data);
g_print ("seek to %lld on pad %s:%s\n", real, GST_DEBUG_PAD_NAME (seekable));
s_event = gst_event_new_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
g_print ("seek to %lld on pad %s:%s\n", real,
GST_DEBUG_PAD_NAME (seekable));
s_event =
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
res = gst_pad_send_event (seekable, s_event);
@ -746,10 +755,11 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
while (walk) {
GstElement *seekable = GST_ELEMENT (walk->data);
g_print ("seek to %lld on element %s\n", real, gst_element_get_name (seekable));
s_event = gst_event_new_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
g_print ("seek to %lld on element %s\n", real,
gst_element_get_name (seekable));
s_event =
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
res = gst_element_send_event (seekable, s_event);
@ -759,7 +769,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
return FALSE;
}
@ -770,7 +781,8 @@ play_cb (GtkButton * button, gpointer data)
if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) {
gst_element_set_state (pipeline, GST_STATE_PLAYING);
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
}
}
@ -795,23 +807,23 @@ stop_cb (GtkButton * button, gpointer data)
typedef struct
{
gchar *name;
GstElement* (*func) (const gchar *location);
GstElement *(*func) (const gchar * location);
} Pipeline;
static Pipeline pipelines[] = {
{ "mp3", make_mp3_pipeline },
{ "avi", make_avi_pipeline },
{ "mpeg1", make_mpeg_pipeline },
{ "mpegparse", make_parse_pipeline },
{ "vorbis", make_vorbis_pipeline },
{ "sid", make_sid_pipeline },
{ "flac", make_flac_pipeline },
{ "wav", make_wav_pipeline },
{ "mod", make_mod_pipeline },
{ "dv", make_dv_pipeline },
{ "mpeg1nothreads", make_mpegnt_pipeline },
{ "playerbin", make_playerbin_pipeline },
{ NULL, NULL},
{"mp3", make_mp3_pipeline},
{"avi", make_avi_pipeline},
{"mpeg1", make_mpeg_pipeline},
{"mpegparse", make_parse_pipeline},
{"vorbis", make_vorbis_pipeline},
{"sid", make_sid_pipeline},
{"flac", make_flac_pipeline},
{"wav", make_wav_pipeline},
{"mod", make_mod_pipeline},
{"dv", make_dv_pipeline},
{"mpeg1nothreads", make_mpegnt_pipeline},
{"playerbin", make_playerbin_pipeline},
{NULL, NULL},
};
#define NUM_TYPES ((sizeof (pipelines) / sizeof (Pipeline)) - 1)
@ -832,16 +844,15 @@ print_usage (int argc, char **argv)
int
main (int argc, char **argv)
{
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button,
*hscale;
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button, *hscale;
struct poptOption options[] = {
{ "stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
"Show pad stats", NULL },
{"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
"Show pad stats", NULL},
POPT_TABLEEND
};
gint type;
gst_init_with_popt_table (&argc, &argv, options);
gtk_init (&argc, &argv);
@ -868,17 +879,18 @@ main (int argc, char **argv)
pause_button = gtk_button_new_with_label ("pause");
stop_button = gtk_button_new_with_label ("stop");
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
adjustment =
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
hscale = gtk_hscale_new (adjustment);
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"format_value", G_CALLBACK (format_value), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"format_value", G_CALLBACK (format_value), pipeline);
/* do the packing stuff ... */
gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
@ -890,16 +902,21 @@ main (int argc, char **argv)
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
/* connect things ... */
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
pipeline);
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
/* show the gui. */
gtk_widget_show_all (window);
g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
g_signal_connect (pipeline, "deep_notify",
G_CALLBACK (gst_element_default_deep_notify), NULL);
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
NULL);
gtk_main ();

View file

@ -19,19 +19,19 @@ static guint update_id;
#define UPDATE_INTERVAL 500
static GstElement*
make_spider_pipeline (const gchar *location, gboolean thread)
static GstElement *
make_spider_pipeline (const gchar * location, gboolean thread)
{
GstElement *pipeline;
GstElement *src, *decoder, *audiosink, *videosink, *a_thread, *v_thread, *a_queue, *v_queue;
GstElement *src, *decoder, *audiosink, *videosink, *a_thread, *v_thread,
*a_queue, *v_queue;
if (thread) {
pipeline = gst_thread_new ("app");
}
else {
} else {
pipeline = gst_pipeline_new ("app");
}
src = gst_element_factory_make (SOURCE, "src");
decoder = gst_element_factory_make ("spider", "decoder");
@ -64,15 +64,16 @@ make_spider_pipeline (const gchar *location, gboolean thread)
seekable_elements = g_list_prepend (seekable_elements, videosink);
seekable_elements = g_list_prepend (seekable_elements, audiosink);
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (audiosink, "sink"));
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (videosink, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (audiosink, "sink"));
rate_pads =
g_list_prepend (rate_pads, gst_element_get_pad (videosink, "sink"));
return pipeline;
}
static gchar*
format_value (GtkScale *scale,
gdouble value)
static gchar *
format_value (GtkScale * scale, gdouble value)
{
gint64 real;
gint64 seconds;
@ -83,9 +84,7 @@ format_value (GtkScale *scale,
subseconds = (gint64) real / (GST_SECOND / 100);
return g_strdup_printf ("%02lld:%02lld:%02lld",
seconds/60,
seconds%60,
subseconds%100);
seconds / 60, seconds % 60, subseconds % 100);
}
typedef struct
@ -94,13 +93,12 @@ typedef struct
const GstFormat format;
} seek_format;
static seek_format seek_formats[] =
{
{ "tim", GST_FORMAT_TIME },
{ "byt", GST_FORMAT_BYTES },
{ "buf", GST_FORMAT_BUFFERS },
{ "def", GST_FORMAT_DEFAULT },
{ NULL, 0 },
static seek_format seek_formats[] = {
{"tim", GST_FORMAT_TIME},
{"byt", GST_FORMAT_BYTES},
{"buf", GST_FORMAT_BUFFERS},
{"def", GST_FORMAT_DEFAULT},
{NULL, 0},
};
G_GNUC_UNUSED static void
@ -119,13 +117,10 @@ query_rates (void)
format = seek_formats[i].format;
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND,
&format, &value))
{
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
@ -154,10 +149,9 @@ query_durations ()
format = seek_formats[i].format;
res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
@ -184,10 +178,9 @@ query_positions ()
format = seek_formats[i].format;
res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
if (res) {
g_print ("%s %13lld | ", seek_formats[i].name, value);
}
else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
g_print ("%s %13lld | ", seek_formats[i].name, value);
} else {
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
}
i++;
}
@ -197,7 +190,7 @@ query_positions ()
}
static gboolean
update_scale (gpointer data)
update_scale (gpointer data)
{
GstClock *clock;
guint64 position;
@ -208,12 +201,14 @@ update_scale (gpointer data)
if (seekable_elements) {
GstElement *element = GST_ELEMENT (seekable_elements->data);
gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
}
position = gst_clock_get_time (clock);
if (stats) {
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
g_print ("clock: %13llu (%s)\n", position,
gst_object_get_name (GST_OBJECT (clock)));
query_durations ();
query_positions ();
query_rates ();
@ -239,7 +234,7 @@ iterate (gpointer data)
}
static gboolean
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gtk_timeout_remove (update_id);
@ -248,7 +243,7 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
}
static gboolean
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
gboolean res;
@ -260,8 +255,7 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable));
s_event = gst_event_new_seek (GST_FORMAT_TIME |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH, real);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, real);
res = gst_element_send_event (seekable, s_event);
@ -271,7 +265,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
return FALSE;
}
@ -283,7 +278,8 @@ play_cb (GtkButton * button, gpointer data)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
gtk_idle_add ((GtkFunction) iterate, pipeline);
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
update_id =
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
}
}
@ -308,17 +304,16 @@ stop_cb (GtkButton * button, gpointer data)
int
main (int argc, char **argv)
{
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button,
*hscale;
GtkWidget *window, *hbox, *vbox,
*play_button, *pause_button, *stop_button, *hscale;
gboolean threaded = FALSE;
struct poptOption options[] = {
{"threaded", 't', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &threaded, 0,
"Run the pipeline in a toplevel thread", NULL},
{"stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
"Show element stats", NULL},
POPT_TABLEEND
};
{"threaded", 't', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &threaded, 0,
"Run the pipeline in a toplevel thread", NULL},
{"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
"Show element stats", NULL},
POPT_TABLEEND
};
gst_init_with_popt_table (&argc, &argv, options);
gtk_init (&argc, &argv);
@ -338,17 +333,18 @@ main (int argc, char **argv)
pause_button = gtk_button_new_with_label ("pause");
stop_button = gtk_button_new_with_label ("stop");
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
adjustment =
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
hscale = gtk_hscale_new (adjustment);
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect(GTK_OBJECT(hscale),
"format_value", G_CALLBACK (format_value), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_press_event", G_CALLBACK (start_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"button_release_event", G_CALLBACK (stop_seek), pipeline);
gtk_signal_connect (GTK_OBJECT (hscale),
"format_value", G_CALLBACK (format_value), pipeline);
/* do the packing stuff ... */
gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
@ -360,9 +356,12 @@ main (int argc, char **argv)
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
/* connect things ... */
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
pipeline);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
pipeline);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
pipeline);
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
/* show the gui. */

View file

@ -4,34 +4,37 @@
static gboolean ready = FALSE;
struct probe_context {
struct probe_context
{
GstElement *pipeline;
GstElement *element;
GstPad *pad;
GstFormat ls_format;
GstPad *pad;
GstFormat ls_format;
gint total_ls;
gint total_ls;
GstCaps *metadata;
GstCaps *streaminfo;
GstCaps *caps;
GstCaps *metadata;
GstCaps *streaminfo;
GstCaps *caps;
};
static void
print_caps (GstCaps *caps)
print_caps (GstCaps * caps)
{
char *s;
s = gst_caps_to_string (caps);
g_print(" %s\n", s);
g_print (" %s\n", s);
g_free (s);
}
static void
print_format (GstCaps *caps)
print_format (GstCaps * caps)
{
char *s;
s = gst_caps_to_string (caps);
g_print(" format: %s\n", s);
g_print (" format: %s\n", s);
g_free (s);
}
@ -61,35 +64,31 @@ print_lbs_info (struct probe_context *context, gint stream)
definition = gst_format_get_details (format);
/* get start and end position of this stream */
res = gst_pad_convert (context->pad,
context->ls_format, stream,
&format, &value_start);
res = gst_pad_convert (context->pad,
context->ls_format, stream, &format, &value_start);
res &= gst_pad_convert (context->pad,
context->ls_format, stream + 1,
&format, &value_end);
context->ls_format, stream + 1, &format, &value_end);
if (res) {
/* substract to get the length */
value_end -= value_start;
if (format == GST_FORMAT_TIME) {
value_end /= (GST_SECOND/100);
g_print (" %s: %lld:%02lld.%02lld\n", definition->nick,
value_end/6000, (value_end/100)%60, (value_end%100));
value_end /= (GST_SECOND / 100);
g_print (" %s: %lld:%02lld.%02lld\n", definition->nick,
value_end / 6000, (value_end / 100) % 60, (value_end % 100));
} else {
g_print (" %s: %lld\n", definition->nick, value_end);
}
else {
g_print (" %s: %lld\n", definition->nick, value_end);
}
}
else
} else
g_print (" could not get logical stream %s\n", definition->nick);
}
}
static void
deep_notify (GObject *object, GstObject *origin,
GParamSpec *pspec, gpointer data)
deep_notify (GObject * object, GstObject * origin,
GParamSpec * pspec, gpointer data)
{
struct probe_context *context = (struct probe_context *) data;
GValue value = { 0, };
@ -99,8 +98,7 @@ deep_notify (GObject *object, GstObject *origin,
g_value_init (&value, pspec->value_type);
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
context->metadata = g_value_peek_pointer (&value);
}
else if (!strcmp (pspec->name, "streaminfo")) {
} else if (!strcmp (pspec->name, "streaminfo")) {
g_value_init (&value, pspec->value_type);
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
@ -127,9 +125,7 @@ collect_logical_stream_properties (struct probe_context *context, gint stream)
/* seek to stream */
event = gst_event_new_seek (context->ls_format |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH,
stream);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, stream);
res = gst_pad_send_event (context->pad, event);
if (!res) {
g_warning ("seek to logical track failed");
@ -141,7 +137,8 @@ collect_logical_stream_properties (struct probe_context *context, gint stream)
ready = FALSE;
while (gst_bin_iterate (GST_BIN (context->pipeline)) && !ready) {
count++;
if (count > 10) break;
if (count > 10)
break;
}
print_caps (context->metadata);
@ -177,21 +174,19 @@ collect_stream_properties (struct probe_context *context)
format = *formats;
formats++;
res = gst_pad_query (context->pad, GST_QUERY_TOTAL,
&format, &value);
res = gst_pad_query (context->pad, GST_QUERY_TOTAL, &format, &value);
definition = gst_format_get_details (format);
if (res) {
if (format == GST_FORMAT_TIME) {
value /= (GST_SECOND/100);
g_print (" total %s: %lld:%02lld.%02lld\n", definition->nick,
value/6000, (value/100)%60, (value%100));
}
else {
if (format == context->ls_format)
context->total_ls = value;
g_print (" total %s: %lld\n", definition->nick, value);
value /= (GST_SECOND / 100);
g_print (" total %s: %lld:%02lld.%02lld\n", definition->nick,
value / 6000, (value / 100) % 60, (value % 100));
} else {
if (format == context->ls_format)
context->total_ls = value;
g_print (" total %s: %lld\n", definition->nick, value);
}
}
}
@ -248,7 +243,7 @@ main (int argc, char **argv)
context->ls_format = logical_stream_format;
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
G_CALLBACK (deep_notify), context);
G_CALLBACK (deep_notify), context);
gst_element_set_state (pipeline, GST_STATE_PLAYING);

View file

@ -24,8 +24,8 @@
* compression status of mpeg audio to ogg vorbis transcoding.
*/
gint
main (gint argc, gchar *argv[])
gint
main (gint argc, gchar * argv[])
{
GstElement *pipeline;
GError *error = NULL;
@ -34,21 +34,22 @@ main (gint argc, gchar *argv[])
GstPad *dec_sink, *enc_src;
gst_init (&argc, &argv);
if (argc < 3) {
g_print ("usage: %s <inputfile> <outputfile>\n", argv[0]);
return -1;
}
description = g_strdup_printf ("filesrc location=\"%s\" ! mad name=decoder ! "
"vorbisenc name=encoder ! filesink location=\"%s\"", argv[1], argv[2]);
"vorbisenc name=encoder ! filesink location=\"%s\"", argv[1], argv[2]);
pipeline = GST_ELEMENT (gst_parse_launch (description, &error));
if (!pipeline) {
if (error)
g_print ("ERROR: pipeline could not be constructed: %s\n", error->message);
g_print ("ERROR: pipeline could not be constructed: %s\n",
error->message);
else
g_print ("ERROR: pipeline could not be constructed\n");
g_print ("ERROR: pipeline could not be constructed\n");
return -1;
}
@ -57,7 +58,7 @@ main (gint argc, gchar *argv[])
dec_sink = gst_element_get_pad (decoder, "sink");
enc_src = gst_element_get_pad (encoder, "src");
if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) {
g_print ("pipeline doesn't want to play\n");
return -1;
@ -71,33 +72,29 @@ main (gint argc, gchar *argv[])
format = GST_FORMAT_TIME;
/* get the position */
gst_pad_query (enc_src, GST_QUERY_POSITION,
&format, &position);
gst_pad_query (enc_src, GST_QUERY_POSITION, &format, &position);
/* get the total duration */
gst_pad_query (enc_src, GST_QUERY_TOTAL,
&format, &duration);
gst_pad_query (enc_src, GST_QUERY_TOTAL, &format, &duration);
format = GST_FORMAT_BYTES;
/* see how many bytes are genereated per 8 seconds (== bitrate) */
gst_pad_convert (enc_src, GST_FORMAT_TIME, 8 * GST_SECOND,
&format, &bitrate_enc);
&format, &bitrate_enc);
gst_pad_convert (dec_sink, GST_FORMAT_TIME, 8 * GST_SECOND,
&format, &bitrate_dec);
&format, &bitrate_dec);
g_print ("[%2dm %.2ds] of [%2dm %.2ds], "
"src avg bitrate: %lld, dest avg birate: %lld, ratio [%02.2f] \r",
(gint)(position / (GST_SECOND * 60)),
(gint)(position / (GST_SECOND)) % 60,
(gint)(duration / (GST_SECOND * 60)),
(gint)(duration / (GST_SECOND)) % 60,
bitrate_dec,
bitrate_enc,
(gfloat)bitrate_dec/bitrate_enc);
"src avg bitrate: %lld, dest avg birate: %lld, ratio [%02.2f] \r",
(gint) (position / (GST_SECOND * 60)),
(gint) (position / (GST_SECOND)) % 60,
(gint) (duration / (GST_SECOND * 60)),
(gint) (duration / (GST_SECOND)) % 60,
bitrate_dec, bitrate_enc, (gfloat) bitrate_dec / bitrate_enc);
}
g_print ("\n");
return 0;
}

View file

@ -16,7 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -28,38 +28,36 @@ static GMainLoop *loop = NULL;
static void
got_eos (GstElement *pipeline)
got_eos (GstElement * pipeline)
{
g_main_loop_quit (loop);
}
static gboolean
idle_iterate (GstElement *pipeline)
idle_iterate (GstElement * pipeline)
{
gst_bin_iterate (GST_BIN (pipeline));
return (GST_STATE (GST_ELEMENT (pipeline)) == GST_STATE_PLAYING);
}
static gboolean
switch_timer (GstElement *video_switch)
switch_timer (GstElement * video_switch)
{
gint nb_sources, active_source;
g_object_get (G_OBJECT (video_switch), "nb_sources", &nb_sources, NULL);
g_object_get (G_OBJECT (video_switch), "active_source",
&active_source, NULL);
active_source ++;
g_object_get (G_OBJECT (video_switch), "active_source", &active_source, NULL);
active_source++;
if (active_source > nb_sources - 1)
active_source = 0;
g_object_set (G_OBJECT (video_switch), "active_source",
active_source, NULL);
g_object_set (G_OBJECT (video_switch), "active_source", active_source, NULL);
g_message ("current number of sources : %d, active source %d",
nb_sources, active_source);
nb_sources, active_source);
return (GST_STATE (GST_ELEMENT (video_switch)) == GST_STATE_PLAYING);
}
@ -72,7 +70,7 @@ main (int argc, char *argv[])
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
pipeline = gst_pipeline_new ("pipeline");
src1 = gst_element_factory_make ("videotestsrc", "src1");
g_object_set (G_OBJECT (src1), "pattern", 0, NULL);
@ -80,26 +78,25 @@ main (int argc, char *argv[])
g_object_set (G_OBJECT (src2), "pattern", 1, NULL);
video_switch = gst_element_factory_make ("switch", "video_switch");
video_sink = gst_element_factory_make ("ximagesink", "video_sink");
gst_bin_add_many (GST_BIN (pipeline), src1, src2, video_switch,
video_sink, NULL);
video_sink, NULL);
gst_element_link (src1, video_switch);
gst_element_link (src2, video_switch);
gst_element_link (video_switch, video_sink);
g_signal_connect (G_OBJECT (pipeline), "eos",
G_CALLBACK (got_eos), NULL);
g_signal_connect (G_OBJECT (pipeline), "eos", G_CALLBACK (got_eos), NULL);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
g_idle_add ((GSourceFunc) idle_iterate, pipeline);
g_timeout_add (2000, (GSourceFunc) switch_timer, video_switch);
g_main_loop_run (loop);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
/* unref */
gst_object_unref (GST_OBJECT (pipeline));

File diff suppressed because it is too large Load diff

View file

@ -72,8 +72,8 @@ GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
#define GST_ALSA_MIN_RATE 8000
#define GST_ALSA_MAX_RATE 192000
#define GST_ALSA_MAX_TRACKS 64 /* we don't support more than 64 tracks */
#define GST_ALSA_MAX_CHANNELS 32 /* tracks can have up to 32 channels */
#define GST_ALSA_MAX_TRACKS 64 /* we don't support more than 64 tracks */
#define GST_ALSA_MAX_CHANNELS 32 /* tracks can have up to 32 channels */
/* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for
GST_ALSA_MAX_CHANNELS comes from alsa/mixer.h. */
@ -84,26 +84,26 @@ GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
#define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10)
G_BEGIN_DECLS
#define GST_ALSA(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa))
#define GST_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA, GstAlsaClass))
#define GST_ALSA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ALSA, GstAlsaClass))
#define GST_IS_ALSA(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA))
#define GST_IS_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA))
#define GST_TYPE_ALSA (gst_alsa_get_type())
enum {
enum
{
GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST,
GST_ALSA_RUNNING,
GST_ALSA_CAPS_NEGO,
GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3,
};
typedef enum {
typedef enum
{
GST_ALSA_CAPS_PAUSE = 0,
GST_ALSA_CAPS_RESUME,
GST_ALSA_CAPS_SYNC_START
/* add more */
/* add more */
} GstAlsaPcmCaps;
#define GST_ALSA_CAPS_IS_SET(obj, flag) (GST_ALSA (obj)->pcm_caps & (1<<(flag)))
@ -118,56 +118,60 @@ typedef struct _GstAlsaClockClass GstAlsaClockClass;
typedef struct _GstAlsa GstAlsa;
typedef struct _GstAlsaClass GstAlsaClass;
typedef int (*GstAlsaTransmitFunction) (GstAlsa *this, snd_pcm_sframes_t *avail);
typedef int (*GstAlsaTransmitFunction) (GstAlsa * this,
snd_pcm_sframes_t * avail);
typedef struct {
snd_pcm_format_t format;
guint rate;
gint channels;
typedef struct
{
snd_pcm_format_t format;
guint rate;
gint channels;
} GstAlsaFormat;
struct _GstAlsa {
GstElement parent;
struct _GstAlsa
{
GstElement parent;
/* array of GstAlsaPads */
GstPad * pad[GST_ALSA_MAX_TRACKS];
GstPad *pad[GST_ALSA_MAX_TRACKS];
gchar * device;
snd_pcm_t * handle;
snd_pcm_info_t * info;
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
snd_output_t * out;
gchar *device;
snd_pcm_t *handle;
snd_pcm_info_t *info;
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
snd_output_t *out;
GstAlsaFormat * format; /* NULL if undefined */
gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */
GstAlsaTransmitFunction transmit;
GstAlsaFormat *format; /* NULL if undefined */
gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */
GstAlsaTransmitFunction transmit;
/* latency / performance parameters */
snd_pcm_uframes_t period_size;
unsigned int period_count;
snd_pcm_uframes_t period_size;
unsigned int period_count;
gboolean autorecover;
gboolean autorecover;
/* clocking */
GstAlsaClock * clock; /* our provided clock */
snd_pcm_uframes_t transmitted; /* samples transmitted since last sync
This thing actually is our master clock.
We will event insert silent samples or
drop some to sync to incoming timestamps.
*/
GstClockTime max_discont; /* max difference between current
playback timestamp and buffers timestamps
*/
GstAlsaClock *clock; /* our provided clock */
snd_pcm_uframes_t transmitted; /* samples transmitted since last sync
This thing actually is our master clock.
We will event insert silent samples or
drop some to sync to incoming timestamps.
*/
GstClockTime max_discont; /* max difference between current
playback timestamp and buffers timestamps
*/
};
struct _GstAlsaClass {
GstElementClass parent_class;
struct _GstAlsaClass
{
GstElementClass parent_class;
snd_pcm_stream_t stream;
snd_pcm_stream_t stream;
/* different transmit functions */
GstAlsaTransmitFunction transmit_mmap;
GstAlsaTransmitFunction transmit_rw;
GstAlsaTransmitFunction transmit_mmap;
GstAlsaTransmitFunction transmit_rw;
/* autodetected devices available */
GList *devices;
@ -175,36 +179,29 @@ struct _GstAlsaClass {
GType gst_alsa_get_type (void);
void gst_alsa_set_eos (GstAlsa * this);
GstPadLinkReturn gst_alsa_link (GstPad * pad,
const GstCaps * caps);
GstCaps * gst_alsa_get_caps (GstPad * pad);
GstCaps * gst_alsa_fixate (GstPad * pad,
const GstCaps * caps);
GstCaps * gst_alsa_caps (snd_pcm_format_t format,
gint rate,
gint channels);
void gst_alsa_set_eos (GstAlsa * this);
GstPadLinkReturn gst_alsa_link (GstPad * pad, const GstCaps * caps);
GstCaps *gst_alsa_get_caps (GstPad * pad);
GstCaps *gst_alsa_fixate (GstPad * pad, const GstCaps * caps);
GstCaps *gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels);
/* audio processing functions */
inline snd_pcm_sframes_t gst_alsa_update_avail (GstAlsa * this);
inline gboolean gst_alsa_pcm_wait (GstAlsa * this);
inline gboolean gst_alsa_start (GstAlsa * this);
gboolean gst_alsa_xrun_recovery (GstAlsa * this);
inline snd_pcm_sframes_t gst_alsa_update_avail (GstAlsa * this);
inline gboolean gst_alsa_pcm_wait (GstAlsa * this);
inline gboolean gst_alsa_start (GstAlsa * this);
gboolean gst_alsa_xrun_recovery (GstAlsa * this);
/* format conversions */
inline snd_pcm_uframes_t gst_alsa_timestamp_to_samples (GstAlsa * this,
GstClockTime time);
inline GstClockTime gst_alsa_samples_to_timestamp (GstAlsa * this,
snd_pcm_uframes_t samples);
inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this,
guint bytes);
inline guint gst_alsa_samples_to_bytes (GstAlsa * this,
snd_pcm_uframes_t samples);
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this,
guint bytes);
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this,
GstClockTime time);
inline snd_pcm_uframes_t gst_alsa_timestamp_to_samples (GstAlsa * this,
GstClockTime time);
inline GstClockTime gst_alsa_samples_to_timestamp (GstAlsa * this,
snd_pcm_uframes_t samples);
inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this,
guint bytes);
inline guint gst_alsa_samples_to_bytes (GstAlsa * this,
snd_pcm_uframes_t samples);
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this, guint bytes);
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this, GstClockTime time);
G_END_DECLS
#endif /* __GST_ALSA_H__ */

View file

@ -26,25 +26,24 @@
#include "gstalsaclock.h"
/* clock functions */
static void gst_alsa_clock_class_init (gpointer g_class,
gpointer class_data);
static void gst_alsa_clock_init (GstAlsaClock * clock);
static void gst_alsa_clock_class_init (gpointer g_class, gpointer class_data);
static void gst_alsa_clock_init (GstAlsaClock * clock);
static GstClockTime gst_alsa_clock_get_internal_time (GstClock * clock);
static guint64 gst_alsa_clock_get_resolution (GstClock * clock);
static GstClockEntryStatus gst_alsa_clock_wait (GstClock * clock,
GstClockEntry * entry);
static void gst_alsa_clock_unlock (GstClock * clock,
GstClockEntry * entry);
static GstClockTime gst_alsa_clock_get_internal_time (GstClock * clock);
static guint64 gst_alsa_clock_get_resolution (GstClock * clock);
static GstClockEntryStatus gst_alsa_clock_wait (GstClock * clock,
GstClockEntry * entry);
static void gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry);
static GstClockClass *clock_parent_class = NULL;
static GstClockClass * clock_parent_class = NULL;
/* static guint gst_alsa_clock_signals[LAST_SIGNAL] = { 0 }; */
GType
gst_alsa_clock_get_type (void)
{
{
static GType clock_type = 0;
if (!clock_type) {
static const GTypeInfo clock_info = {
sizeof (GstAlsaClockClass),
@ -59,7 +58,7 @@ gst_alsa_clock_get_type (void)
NULL
};
clock_type = g_type_register_static (GST_TYPE_CLOCK, "GstAlsaClock",
&clock_info, 0);
&clock_info, 0);
}
return clock_type;
}
@ -72,9 +71,9 @@ gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
GstAlsaClockClass *klass;
klass = (GstAlsaClockClass *) g_class;
gobject_class = (GObjectClass*) klass;
gstobject_class = (GstObjectClass*) klass;
gstclock_class = (GstClockClass*) klass;
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
gstclock_class = (GstClockClass *) klass;
clock_parent_class = g_type_class_ref (GST_TYPE_CLOCK);
@ -84,16 +83,19 @@ gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
gstclock_class->unlock = gst_alsa_clock_unlock;
}
static void
gst_alsa_clock_init (GstAlsaClock *clock)
gst_alsa_clock_init (GstAlsaClock * clock)
{
gst_object_set_name (GST_OBJECT (clock), "GstAlsaClock");
clock->start_time = GST_CLOCK_TIME_NONE;
}
GstAlsaClock*
gst_alsa_clock_new (gchar *name, GstAlsaClockGetTimeFunc get_time, GstAlsa *owner)
GstAlsaClock *
gst_alsa_clock_new (gchar * name, GstAlsaClockGetTimeFunc get_time,
GstAlsa * owner)
{
GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
GstAlsaClock *alsa_clock =
GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
g_assert (alsa_clock);
@ -106,44 +108,50 @@ gst_alsa_clock_new (gchar *name, GstAlsaClockGetTimeFunc get_time, GstAlsa *owne
return alsa_clock;
}
void
gst_alsa_clock_start (GstAlsaClock *clock)
gst_alsa_clock_start (GstAlsaClock * clock)
{
g_assert (!GST_CLOCK_TIME_IS_VALID (clock->start_time));
if (clock->owner->format) {
clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock))
- clock->get_time (clock->owner);
- clock->get_time (clock->owner);
} else {
clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock));
}
}
void
gst_alsa_clock_stop (GstAlsaClock *clock)
gst_alsa_clock_stop (GstAlsaClock * clock)
{
GTimeVal timeval;
g_get_current_time (&timeval);
g_assert (GST_CLOCK_TIME_IS_VALID (clock->start_time));
clock->adjust += GST_TIMEVAL_TO_TIME (timeval) - gst_clock_get_event_time (GST_CLOCK (clock));
clock->adjust +=
GST_TIMEVAL_TO_TIME (timeval) -
gst_clock_get_event_time (GST_CLOCK (clock));
clock->start_time = GST_CLOCK_TIME_NONE;
}
static GstClockTime
gst_alsa_clock_get_internal_time (GstClock *clock)
gst_alsa_clock_get_internal_time (GstClock * clock)
{
GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (clock);
if (GST_CLOCK_TIME_IS_VALID (alsa_clock->start_time)) {
return alsa_clock->get_time (alsa_clock->owner) + alsa_clock->start_time;
} else {
GTimeVal timeval;
g_get_current_time (&timeval);
return GST_TIMEVAL_TO_TIME (timeval) + alsa_clock->adjust;
}
}
static guint64
gst_alsa_clock_get_resolution (GstClock *clock)
gst_alsa_clock_get_resolution (GstClock * clock)
{
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
@ -155,7 +163,7 @@ gst_alsa_clock_get_resolution (GstClock *clock)
}
}
static GstClockEntryStatus
gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
gst_alsa_clock_wait (GstClock * clock, GstClockEntry * entry)
{
GstClockTime target, entry_time;
GstClockTimeDiff diff;
@ -166,32 +174,33 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
if (diff < 0)
return GST_CLOCK_ENTRY_EARLY;
if (diff > clock->max_diff) {
GST_INFO_OBJECT (this, "GstAlsaClock: abnormal clock request diff: %" G_GINT64_FORMAT") >"
" %"G_GINT64_FORMAT, diff, clock->max_diff);
GST_INFO_OBJECT (this,
"GstAlsaClock: abnormal clock request diff: %" G_GINT64_FORMAT ") >"
" %" G_GINT64_FORMAT, diff, clock->max_diff);
return GST_CLOCK_ENTRY_EARLY;
}
target = entry_time + diff;
GST_DEBUG_OBJECT (this, "real_target %" G_GUINT64_FORMAT
" target %" G_GUINT64_FORMAT
" now %" G_GUINT64_FORMAT,
target, GST_CLOCK_ENTRY_TIME (entry), entry_time);
" target %" G_GUINT64_FORMAT
" now %" G_GUINT64_FORMAT,
target, GST_CLOCK_ENTRY_TIME (entry), entry_time);
while (gst_alsa_clock_get_internal_time (clock) < target &&
this->last_unlock < entry_time) {
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC / GST_SECOND);
while (gst_alsa_clock_get_internal_time (clock) < target &&
this->last_unlock < entry_time) {
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC /
GST_SECOND);
}
return entry->status;
}
static void
gst_alsa_clock_unlock (GstClock *clock, GstClockEntry *entry)
gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry)
{
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
this->last_unlock = this->get_time (this->owner);
}

View file

@ -25,38 +25,36 @@
#include "gstalsa.h"
G_BEGIN_DECLS
#define GST_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_CLOCK,GstAlsaClock))
#define GST_ALSA_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_CLOCK,GstAlsaClockClass))
#define GST_IS_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_CLOCK))
#define GST_IS_ALSA_CLOCK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_CLOCK))
#define GST_TYPE_ALSA_CLOCK (gst_alsa_clock_get_type())
typedef GstClockTime (*GstAlsaClockGetTimeFunc) (GstAlsa *);
struct _GstAlsaClock {
GstSystemClock parent;
struct _GstAlsaClock
{
GstSystemClock parent;
GstAlsaClockGetTimeFunc get_time;
GstAlsa * owner;
GstAlsaClockGetTimeFunc get_time;
GstAlsa *owner;
GstClockTimeDiff adjust; /* adjustment to real clock (recalculated when stopping) */
GstClockTime start_time; /* time when the stream started (NONE when stopped) */
GstClockTime last_unlock; /* time of last unlock request */
GstClockTimeDiff adjust; /* adjustment to real clock (recalculated when stopping) */
GstClockTime start_time; /* time when the stream started (NONE when stopped) */
GstClockTime last_unlock; /* time of last unlock request */
};
struct _GstAlsaClockClass {
struct _GstAlsaClockClass
{
GstSystemClockClass parent_class;
};
GType gst_alsa_clock_get_type (void);
GstAlsaClock * gst_alsa_clock_new (gchar * name,
GstAlsaClockGetTimeFunc func,
GstAlsa * owner);
GType gst_alsa_clock_get_type (void);
GstAlsaClock *gst_alsa_clock_new (gchar * name,
GstAlsaClockGetTimeFunc func, GstAlsa * owner);
void gst_alsa_clock_start (GstAlsaClock * clock);
void gst_alsa_clock_stop (GstAlsaClock * clock);
void gst_alsa_clock_start (GstAlsaClock * clock);
void gst_alsa_clock_stop (GstAlsaClock * clock);
G_END_DECLS
#endif /* __GST_ALSA_CLOCK_H__ */

View file

@ -24,45 +24,39 @@
#include "gstalsamixer.h"
/* elementfactory information */
static GstElementDetails gst_alsa_mixer_details = GST_ELEMENT_DETAILS (
"Alsa Mixer",
"Generic/Audio",
"Control sound input and output levels with ALSA",
"Leif Johnson <leif@ambient.2y.net>"
);
static GstElementDetails gst_alsa_mixer_details =
GST_ELEMENT_DETAILS ("Alsa Mixer",
"Generic/Audio",
"Control sound input and output levels with ALSA",
"Leif Johnson <leif@ambient.2y.net>");
static void gst_alsa_interface_init (GstImplementsInterfaceClass *klass);
static void gst_alsa_interface_init (GstImplementsInterfaceClass * klass);
static void gst_alsa_mixer_class_init (gpointer g_class,
gpointer class_data);
static void gst_alsa_mixer_init (GstAlsaMixer * mixer);
static void gst_alsa_mixer_dispose (GObject * object);
static void gst_alsa_mixer_interface_init (GstMixerClass* klass);
static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface,
GType iface_type);
static void gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data);
static void gst_alsa_mixer_init (GstAlsaMixer * mixer);
static void gst_alsa_mixer_dispose (GObject * object);
static void gst_alsa_mixer_interface_init (GstMixerClass * klass);
static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface,
GType iface_type);
/* GStreamer stuff */
static GstElementStateReturn gst_alsa_mixer_change_state (GstElement * element);
static GstElementStateReturn gst_alsa_mixer_change_state (GstElement * element);
static void gst_alsa_mixer_build_list (GstAlsaMixer * mixer);
static void gst_alsa_mixer_free_list (GstAlsaMixer * mixer);
static void gst_alsa_mixer_build_list (GstAlsaMixer * mixer);
static void gst_alsa_mixer_free_list (GstAlsaMixer * mixer);
/* interface implementation */
static const GList * gst_alsa_mixer_list_tracks (GstMixer * mixer);
static const GList *gst_alsa_mixer_list_tracks (GstMixer * mixer);
static void gst_alsa_mixer_set_volume (GstMixer * mixer,
GstMixerTrack* track,
gint * volumes);
static void gst_alsa_mixer_get_volume (GstMixer * mixer,
GstMixerTrack* track,
gint * volumes);
static void gst_alsa_mixer_set_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
static void gst_alsa_mixer_get_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
static void gst_alsa_mixer_set_record (GstMixer * mixer,
GstMixerTrack* track,
gboolean record);
static void gst_alsa_mixer_set_mute (GstMixer * mixer,
GstMixerTrack* track,
gboolean mute);
static void gst_alsa_mixer_set_record (GstMixer * mixer,
GstMixerTrack * track, gboolean record);
static void gst_alsa_mixer_set_mute (GstMixer * mixer,
GstMixerTrack * track, gboolean mute);
/*** GOBJECT STUFF ************************************************************/
@ -96,10 +90,14 @@ gst_alsa_mixer_get_type (void)
NULL,
};
alsa_mixer_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info, 0);
alsa_mixer_type =
g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info,
0);
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE, &alsa_iface_info);
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER, &alsa_mixer_iface_info);
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE,
&alsa_iface_info);
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER,
&alsa_mixer_iface_info);
}
return alsa_mixer_type;
@ -112,7 +110,7 @@ gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data)
GstElementClass *element_class;
GstAlsaClass *klass;
klass = (GstAlsaClass *)g_class;
klass = (GstAlsaClass *) g_class;
object_class = (GObjectClass *) g_class;
element_class = (GstElementClass *) g_class;
@ -132,38 +130,37 @@ gst_alsa_mixer_init (GstAlsaMixer * mixer)
gint err;
GstAlsa *alsa = GST_ALSA (mixer);
mixer->mixer_handle = (snd_mixer_t *) -1;
mixer->mixer_handle = (snd_mixer_t *) - 1;
/* open and initialize the mixer device */
err = snd_mixer_open(&mixer->mixer_handle, 0);
err = snd_mixer_open (&mixer->mixer_handle, 0);
if (err < 0 || mixer->mixer_handle == NULL) {
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot open mixer device.");
mixer->mixer_handle = (snd_mixer_t *) -1;
mixer->mixer_handle = (snd_mixer_t *) - 1;
return;
}
if ((err = snd_mixer_attach(mixer->mixer_handle, alsa->device)) < 0) {
if ((err = snd_mixer_attach (mixer->mixer_handle, alsa->device)) < 0) {
GST_ERROR_OBJECT (GST_OBJECT (mixer),
"Cannot attach mixer to sound device `%s'.",
alsa->device);
"Cannot attach mixer to sound device `%s'.", alsa->device);
goto error;
}
if ((err = snd_mixer_selem_register(mixer->mixer_handle, NULL, NULL)) < 0) {
if ((err = snd_mixer_selem_register (mixer->mixer_handle, NULL, NULL)) < 0) {
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot register mixer elements.");
goto error;
}
if ((err = snd_mixer_load(mixer->mixer_handle)) < 0) {
if ((err = snd_mixer_load (mixer->mixer_handle)) < 0) {
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot load mixer settings.");
goto error;
}
return;
error:
error:
snd_mixer_close (mixer->mixer_handle);
mixer->mixer_handle = (snd_mixer_t *) -1;
mixer->mixer_handle = (snd_mixer_t *) - 1;
}
static void
@ -171,25 +168,26 @@ gst_alsa_mixer_dispose (GObject * object)
{
GstAlsaMixer *mixer = GST_ALSA_MIXER (object);
if (((gint) mixer->mixer_handle) == -1) return;
if (((gint) mixer->mixer_handle) == -1)
return;
snd_mixer_close (mixer->mixer_handle);
mixer->mixer_handle = (snd_mixer_t *) -1;
mixer->mixer_handle = (snd_mixer_t *) - 1;
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_alsa_interface_init (GstImplementsInterfaceClass *klass)
gst_alsa_interface_init (GstImplementsInterfaceClass * klass)
{
klass->supported = gst_alsa_mixer_supported;
}
static void
gst_alsa_mixer_interface_init (GstMixerClass *klass)
gst_alsa_mixer_interface_init (GstMixerClass * klass)
{
GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
/* set up the interface hooks */
klass->list_tracks = gst_alsa_mixer_list_tracks;
klass->set_volume = gst_alsa_mixer_set_volume;
@ -199,7 +197,7 @@ gst_alsa_mixer_interface_init (GstMixerClass *klass)
}
gboolean
gst_alsa_mixer_supported (GstImplementsInterface *iface, GType iface_type)
gst_alsa_mixer_supported (GstImplementsInterface * iface, GType iface_type)
{
g_assert (iface_type == GST_TYPE_MIXER);
@ -207,7 +205,7 @@ gst_alsa_mixer_supported (GstImplementsInterface *iface, GType iface_type)
}
static void
gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
{
gint i, count;
snd_mixer_elem_t *element;
@ -215,26 +213,27 @@ gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
g_return_if_fail (((gint) mixer->mixer_handle) != -1);
count = snd_mixer_get_count(mixer->mixer_handle);
element = snd_mixer_first_elem(mixer->mixer_handle);
count = snd_mixer_get_count (mixer->mixer_handle);
element = snd_mixer_first_elem (mixer->mixer_handle);
/* build track list */
for (i = 0; i < count; i++) {
gint channels = 0;
if (! snd_mixer_selem_is_active(element)) continue;
if (!snd_mixer_selem_is_active (element))
continue;
/* find out if this element can be an input */
if (snd_mixer_selem_has_capture_channel(element, 0) ||
snd_mixer_selem_has_capture_switch(element) ||
snd_mixer_selem_is_capture_mono(element)) {
while (snd_mixer_selem_has_capture_channel(element, channels))
channels++;
if (snd_mixer_selem_has_capture_channel (element, 0) ||
snd_mixer_selem_has_capture_switch (element) ||
snd_mixer_selem_is_capture_mono (element)) {
while (snd_mixer_selem_has_capture_channel (element, channels))
channels++;
track = gst_alsa_mixer_track_new
(element, i, channels, GST_MIXER_TRACK_INPUT);
(element, i, channels, GST_MIXER_TRACK_INPUT);
mixer->tracklist = g_list_append (mixer->tracklist, track);
}
@ -242,23 +241,23 @@ gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
channels = 0;
if (snd_mixer_selem_has_playback_channel(element, 0) ||
snd_mixer_selem_has_playback_switch(element) ||
snd_mixer_selem_is_playback_mono(element)) {
while (snd_mixer_selem_has_playback_channel(element, channels))
channels++;
if (snd_mixer_selem_has_playback_channel (element, 0) ||
snd_mixer_selem_has_playback_switch (element) ||
snd_mixer_selem_is_playback_mono (element)) {
while (snd_mixer_selem_has_playback_channel (element, channels))
channels++;
track = gst_alsa_mixer_track_new
(element, i, channels, GST_MIXER_TRACK_OUTPUT);
(element, i, channels, GST_MIXER_TRACK_OUTPUT);
mixer->tracklist = g_list_append (mixer->tracklist, track);
}
element = snd_mixer_elem_next(element);
element = snd_mixer_elem_next (element);
}
}
static void
gst_alsa_mixer_free_list (GstAlsaMixer *mixer)
gst_alsa_mixer_free_list (GstAlsaMixer * mixer)
{
g_return_if_fail (((gint) mixer->mixer_handle) != -1);
@ -270,7 +269,7 @@ gst_alsa_mixer_free_list (GstAlsaMixer *mixer)
/*** GSTREAMER FUNCTIONS ******************************************************/
static GstElementStateReturn
gst_alsa_mixer_change_state (GstElement *element)
gst_alsa_mixer_change_state (GstElement * element)
{
GstAlsaMixer *this;
@ -278,12 +277,14 @@ gst_alsa_mixer_change_state (GstElement *element)
this = GST_ALSA_MIXER (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
gst_alsa_mixer_build_list (this); break;
case GST_STATE_READY_TO_NULL:
gst_alsa_mixer_free_list (this); break;
default:
g_assert_not_reached();
case GST_STATE_NULL_TO_READY:
gst_alsa_mixer_build_list (this);
break;
case GST_STATE_READY_TO_NULL:
gst_alsa_mixer_free_list (this);
break;
default:
g_assert_not_reached ();
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
@ -295,7 +296,7 @@ gst_alsa_mixer_change_state (GstElement *element)
/*** INTERFACE IMPLEMENTATION *************************************************/
static const GList *
gst_alsa_mixer_list_tracks (GstMixer *mixer)
gst_alsa_mixer_list_tracks (GstMixer * mixer)
{
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
@ -305,9 +306,8 @@ gst_alsa_mixer_list_tracks (GstMixer *mixer)
}
static void
gst_alsa_mixer_get_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_alsa_mixer_get_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes)
{
gint i;
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
@ -321,21 +321,21 @@ gst_alsa_mixer_get_volume (GstMixer *mixer,
} else {
for (i = 0; i < track->num_channels; i++) {
long tmp;
if (snd_mixer_selem_has_playback_channel(alsa_track->element, i)) {
snd_mixer_selem_get_playback_volume(alsa_track->element, i, &tmp);
volumes[i] = (gint) tmp;
} else if (snd_mixer_selem_has_capture_channel(alsa_track->element, i)) {
snd_mixer_selem_get_capture_volume(alsa_track->element, i, &tmp);
volumes[i] = (gint) tmp;
if (snd_mixer_selem_has_playback_channel (alsa_track->element, i)) {
snd_mixer_selem_get_playback_volume (alsa_track->element, i, &tmp);
volumes[i] = (gint) tmp;
} else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i)) {
snd_mixer_selem_get_capture_volume (alsa_track->element, i, &tmp);
volumes[i] = (gint) tmp;
}
}
}
}
static void
gst_alsa_mixer_set_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_alsa_mixer_set_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes)
{
gint i;
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
@ -344,12 +344,14 @@ gst_alsa_mixer_set_volume (GstMixer *mixer,
g_return_if_fail (((gint) alsa_mixer->mixer_handle) != -1);
/* only set the volume with ALSA lib if the track isn't muted. */
if (! (track->flags & GST_MIXER_TRACK_MUTE)) {
if (!(track->flags & GST_MIXER_TRACK_MUTE)) {
for (i = 0; i < track->num_channels; i++) {
if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
snd_mixer_selem_set_playback_volume(alsa_track->element, i, (long) volumes[i]);
else if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
snd_mixer_selem_set_capture_volume(alsa_track->element, i, (long) volumes[i]);
if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
snd_mixer_selem_set_playback_volume (alsa_track->element, i,
(long) volumes[i]);
else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
snd_mixer_selem_set_capture_volume (alsa_track->element, i,
(long) volumes[i]);
}
}
@ -358,9 +360,7 @@ gst_alsa_mixer_set_volume (GstMixer *mixer,
}
static void
gst_alsa_mixer_set_mute (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute)
gst_alsa_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
{
gint i;
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
@ -372,29 +372,28 @@ gst_alsa_mixer_set_mute (GstMixer *mixer,
track->flags |= GST_MIXER_TRACK_MUTE;
for (i = 0; i < track->num_channels; i++) {
if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
snd_mixer_selem_set_capture_volume(alsa_track->element, i, 0);
else if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
snd_mixer_selem_set_playback_volume(alsa_track->element, i, 0);
if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
snd_mixer_selem_set_capture_volume (alsa_track->element, i, 0);
else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
snd_mixer_selem_set_playback_volume (alsa_track->element, i, 0);
}
} else {
track->flags &= ~GST_MIXER_TRACK_MUTE;
for (i = 0; i < track->num_channels; i++) {
if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
snd_mixer_selem_set_capture_volume(alsa_track->element, i,
alsa_track->volumes[i]);
else if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
snd_mixer_selem_set_playback_volume(alsa_track->element, i,
alsa_track->volumes[i]);
if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
snd_mixer_selem_set_capture_volume (alsa_track->element, i,
alsa_track->volumes[i]);
else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
snd_mixer_selem_set_playback_volume (alsa_track->element, i,
alsa_track->volumes[i]);
}
}
}
static void
gst_alsa_mixer_set_record (GstMixer *mixer,
GstMixerTrack *track,
gboolean record)
gst_alsa_mixer_set_record (GstMixer * mixer,
GstMixerTrack * track, gboolean record)
{
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);

View file

@ -24,28 +24,27 @@
#include <gst/mixer/mixer.h>
G_BEGIN_DECLS
#define GST_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer))
#define GST_ALSA_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER,GstAlsaMixerClass))
#define GST_IS_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER))
#define GST_IS_ALSA_MIXER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER))
#define GST_TYPE_ALSA_MIXER (gst_alsa_mixer_get_type())
typedef struct _GstAlsaMixer GstAlsaMixer;
typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
struct _GstAlsaMixer {
GstAlsa parent;
GList * tracklist; /* list of available tracks */
snd_mixer_t * mixer_handle;
struct _GstAlsaMixer
{
GstAlsa parent;
GList *tracklist; /* list of available tracks */
snd_mixer_t *mixer_handle;
};
struct _GstAlsaMixerClass {
GstAlsaClass parent;
struct _GstAlsaMixerClass
{
GstAlsaClass parent;
};
GType gst_alsa_mixer_get_type (void);
GType gst_alsa_mixer_get_type (void);
G_END_DECLS
#endif /* __GST_ALSA_MIXER_H__ */

View file

@ -23,9 +23,9 @@
#include "gstalsamixertrack.h"
static void gst_alsa_mixer_track_init (GstAlsaMixerTrack * alsa_track);
static void gst_alsa_mixer_track_class_init (gpointer g_class,
gpointer class_data);
static void gst_alsa_mixer_track_init (GstAlsaMixerTrack * alsa_track);
static void gst_alsa_mixer_track_class_init (gpointer g_class,
gpointer class_data);
static GstMixerTrackClass *parent_class = NULL;
@ -47,7 +47,9 @@ gst_alsa_mixer_track_get_type (void)
(GInstanceInitFunc) gst_alsa_mixer_track_init,
};
track_type = g_type_register_static (GST_TYPE_MIXER_TRACK, "GstAlsaMixerTrack", &track_info, 0);
track_type =
g_type_register_static (GST_TYPE_MIXER_TRACK, "GstAlsaMixerTrack",
&track_info, 0);
}
return track_type;
@ -61,14 +63,13 @@ gst_alsa_mixer_track_class_init (gpointer g_class, gpointer class_data)
}
static void
gst_alsa_mixer_track_init (GstAlsaMixerTrack *alsa_track)
{ }
gst_alsa_mixer_track_init (GstAlsaMixerTrack * alsa_track)
{
}
GstMixerTrack *
gst_alsa_mixer_track_new (snd_mixer_elem_t *element,
gint track_num,
gint channels,
gint flags)
gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
gint track_num, gint channels, gint flags)
{
gint i;
long min, max;
@ -77,28 +78,29 @@ gst_alsa_mixer_track_new (snd_mixer_elem_t *element,
GstAlsaMixerTrack *alsa_track = (GstAlsaMixerTrack *) track;
/* set basic information */
track->label = g_strdup_printf("%s", snd_mixer_selem_get_name(element));
track->label = g_strdup_printf ("%s", snd_mixer_selem_get_name (element));
track->num_channels = channels;
track->flags = flags;
alsa_track->element = element;
alsa_track->track_num = track_num;
/* set volume information */
snd_mixer_selem_get_playback_volume_range(element, &min, &max);
snd_mixer_selem_get_playback_volume_range (element, &min, &max);
track->min_volume = (gint) min;
track->max_volume = (gint) max;
snd_mixer_selem_get_capture_volume_range(element, &min, &max);
snd_mixer_selem_get_capture_volume_range (element, &min, &max);
alsa_track->min_rec_volume = (gint) min;
alsa_track->max_rec_volume = (gint) max;
for (i = 0; i < channels; i++) {
long tmp;
if (snd_mixer_selem_has_playback_channel(element, i)) {
snd_mixer_selem_get_playback_volume(element, i, &tmp);
if (snd_mixer_selem_has_playback_channel (element, i)) {
snd_mixer_selem_get_playback_volume (element, i, &tmp);
alsa_track->volumes[i] = (gint) tmp;
} else if (snd_mixer_selem_has_capture_channel(element, i)) {
snd_mixer_selem_get_capture_volume(element, i, &tmp);
} else if (snd_mixer_selem_has_capture_channel (element, i)) {
snd_mixer_selem_get_capture_volume (element, i, &tmp);
alsa_track->volumes[i] = (gint) tmp;
}
}

View file

@ -23,35 +23,32 @@
#include <gst/mixer/mixertrack.h>
G_BEGIN_DECLS
#define GST_ALSA_MIXER_TRACK_TYPE (gst_alsa_mixer_track_get_type ())
#define GST_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrack))
#define GST_ALSA_MIXER_TRACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrackClass))
#define GST_IS_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER_TRACK))
#define GST_IS_ALSA_MIXER_TRACK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_TRACK))
#define GST_TYPE_ALSA_MIXER_TRACK (gst_alsa_mixer_track_get_type())
typedef struct _GstAlsaMixerTrack GstAlsaMixerTrack;
typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
struct _GstAlsaMixerTrack {
GstMixerTrack parent;
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
gint track_num;
gint min_rec_volume, max_rec_volume;
gint volumes[GST_ALSA_MAX_CHANNELS];
struct _GstAlsaMixerTrack
{
GstMixerTrack parent;
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
gint track_num;
gint min_rec_volume, max_rec_volume;
gint volumes[GST_ALSA_MAX_CHANNELS];
};
struct _GstAlsaMixerTrackClass {
struct _GstAlsaMixerTrackClass
{
GstMixerTrackClass parent;
};
GType gst_alsa_mixer_track_get_type (void);
GstMixerTrack * gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
gint track_num,
gint channels,
gint flags);
GType gst_alsa_mixer_track_get_type (void);
GstMixerTrack *gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
gint track_num, gint channels, gint flags);
G_END_DECLS
#endif /* __GST_ALSA_MIXER_TRACK_H__ */

View file

@ -34,24 +34,21 @@ plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (alsa_debug, "alsa", 0, "alsa plugins");
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE, GST_TYPE_ALSA_MIXER))
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
GST_TYPE_ALSA_MIXER))
return FALSE;
if (!gst_element_register (plugin, "alsasrc", GST_RANK_NONE, GST_TYPE_ALSA_SRC))
if (!gst_element_register (plugin, "alsasrc", GST_RANK_NONE,
GST_TYPE_ALSA_SRC))
return FALSE;
if (!gst_element_register (plugin, "alsasink", GST_RANK_NONE, GST_TYPE_ALSA_SINK))
if (!gst_element_register (plugin, "alsasink", GST_RANK_NONE,
GST_TYPE_ALSA_SINK))
return FALSE;
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"alsa",
"ALSA plugin library",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"alsa",
"ALSA plugin library",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)

View file

@ -27,34 +27,28 @@
#include "gstalsaclock.h"
/* elementfactory information */
static GstElementDetails gst_alsa_sink_details = GST_ELEMENT_DETAILS (
"Alsa Sink",
"Sink/Audio",
"Output to a sound card via ALSA",
"Thomas Nyberg <thomas@codefactory.se>, "
"Andy Wingo <apwingo@eos.ncsu.edu>, "
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
static GstElementDetails gst_alsa_sink_details =
GST_ELEMENT_DETAILS ("Alsa Sink",
"Sink/Audio",
"Output to a sound card via ALSA",
"Thomas Nyberg <thomas@codefactory.se>, "
"Andy Wingo <apwingo@eos.ncsu.edu>, "
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
static GstPadTemplate * gst_alsa_sink_pad_factory (void);
static GstPadTemplate * gst_alsa_sink_request_pad_factory(void);
static void gst_alsa_sink_base_init (gpointer g_class);
static void gst_alsa_sink_class_init (gpointer g_klass,
gpointer class_data);
static void gst_alsa_sink_init (GstAlsaSink * this);
static inline void gst_alsa_sink_flush_one_pad (GstAlsaSink * sink,
gint i);
static void gst_alsa_sink_flush_pads (GstAlsaSink * sink);
static int gst_alsa_sink_mmap (GstAlsa * this,
snd_pcm_sframes_t * avail);
static int gst_alsa_sink_write (GstAlsa * this,
snd_pcm_sframes_t * avail);
static void gst_alsa_sink_loop (GstElement * element);
static gboolean gst_alsa_sink_check_event (GstAlsaSink * sink,
gint pad_nr);
static GstElementStateReturn gst_alsa_sink_change_state (GstElement * element);
static GstPadTemplate *gst_alsa_sink_pad_factory (void);
static GstPadTemplate *gst_alsa_sink_request_pad_factory (void);
static void gst_alsa_sink_base_init (gpointer g_class);
static void gst_alsa_sink_class_init (gpointer g_klass, gpointer class_data);
static void gst_alsa_sink_init (GstAlsaSink * this);
static inline void gst_alsa_sink_flush_one_pad (GstAlsaSink * sink, gint i);
static void gst_alsa_sink_flush_pads (GstAlsaSink * sink);
static int gst_alsa_sink_mmap (GstAlsa * this, snd_pcm_sframes_t * avail);
static int gst_alsa_sink_write (GstAlsa * this, snd_pcm_sframes_t * avail);
static void gst_alsa_sink_loop (GstElement * element);
static gboolean gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr);
static GstElementStateReturn gst_alsa_sink_change_state (GstElement * element);
static GstClockTime gst_alsa_sink_get_time (GstAlsa * this);
static GstClockTime gst_alsa_sink_get_time (GstAlsa * this);
static GstAlsa *sink_parent_class = NULL;
@ -65,7 +59,7 @@ gst_alsa_sink_pad_factory (void)
if (!template)
template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
return template;
}
@ -76,11 +70,12 @@ gst_alsa_sink_request_pad_factory (void)
if (!template)
template =
gst_pad_template_new ("sink%d", GST_PAD_SINK, GST_PAD_REQUEST,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1));
gst_pad_template_new ("sink%d", GST_PAD_SINK, GST_PAD_REQUEST,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1));
return template;
}
GType
gst_alsa_sink_get_type (void)
{
@ -99,7 +94,9 @@ gst_alsa_sink_get_type (void)
(GInstanceInitFunc) gst_alsa_sink_init,
};
alsa_sink_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaSink", &alsa_sink_info, 0);
alsa_sink_type =
g_type_register_static (GST_TYPE_ALSA, "GstAlsaSink", &alsa_sink_info,
0);
}
return alsa_sink_type;
}
@ -108,9 +105,11 @@ static void
gst_alsa_sink_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class, gst_alsa_sink_pad_factory ());
gst_element_class_add_pad_template (element_class, gst_alsa_sink_request_pad_factory ());
gst_element_class_add_pad_template (element_class,
gst_alsa_sink_pad_factory ());
gst_element_class_add_pad_template (element_class,
gst_alsa_sink_request_pad_factory ());
gst_element_class_set_details (element_class, &gst_alsa_sink_details);
}
@ -130,25 +129,27 @@ gst_alsa_sink_class_init (gpointer g_class, gpointer class_data)
if (sink_parent_class == NULL)
sink_parent_class = g_type_class_ref (GST_TYPE_ALSA);
alsa_class->stream = SND_PCM_STREAM_PLAYBACK;
alsa_class->transmit_mmap = gst_alsa_sink_mmap;
alsa_class->transmit_rw = gst_alsa_sink_write;
element_class->change_state = gst_alsa_sink_change_state;
alsa_class->stream = SND_PCM_STREAM_PLAYBACK;
alsa_class->transmit_mmap = gst_alsa_sink_mmap;
alsa_class->transmit_rw = gst_alsa_sink_write;
element_class->change_state = gst_alsa_sink_change_state;
}
static void
gst_alsa_sink_init (GstAlsaSink *sink)
gst_alsa_sink_init (GstAlsaSink * sink)
{
GstAlsa *this = GST_ALSA (sink);
this->pad[0] = gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
this->pad[0] =
gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
gst_pad_set_link_function (this->pad[0], gst_alsa_link);
gst_pad_set_getcaps_function (this->pad[0], gst_alsa_get_caps);
gst_pad_set_fixate_function (this->pad[0], gst_alsa_fixate);
gst_element_add_pad (GST_ELEMENT (this), this->pad[0]);
this->clock = gst_alsa_clock_new ("alsasinkclock", gst_alsa_sink_get_time, this);
this->clock =
gst_alsa_clock_new ("alsasinkclock", gst_alsa_sink_get_time, this);
/* we hold a ref to our clock until we're disposed */
gst_object_ref (GST_OBJECT (this->clock));
gst_object_sink (GST_OBJECT (this->clock));
@ -157,29 +158,29 @@ gst_alsa_sink_init (GstAlsaSink *sink)
}
static inline void
gst_alsa_sink_flush_one_pad (GstAlsaSink *sink, gint i)
gst_alsa_sink_flush_one_pad (GstAlsaSink * sink, gint i)
{
switch (sink->behaviour[i]) {
case 0:
if (sink->buf[i])
gst_data_unref (GST_DATA (sink->buf[i]));
sink->buf[i] = NULL;
sink->data[i] = NULL;
sink->behaviour[i] = 0;
sink->size[i] = 0;
break;
case 1:
g_free (sink->data[i]);
sink->data[i] = NULL;
sink->behaviour[i] = 0;
sink->size[i] = 0;
break;
default:
g_assert_not_reached ();
case 0:
if (sink->buf[i])
gst_data_unref (GST_DATA (sink->buf[i]));
sink->buf[i] = NULL;
sink->data[i] = NULL;
sink->behaviour[i] = 0;
sink->size[i] = 0;
break;
case 1:
g_free (sink->data[i]);
sink->data[i] = NULL;
sink->behaviour[i] = 0;
sink->size[i] = 0;
break;
default:
g_assert_not_reached ();
}
}
static void
gst_alsa_sink_flush_pads (GstAlsaSink *sink)
gst_alsa_sink_flush_pads (GstAlsaSink * sink)
{
gint i;
@ -189,9 +190,10 @@ gst_alsa_sink_flush_pads (GstAlsaSink *sink)
gst_alsa_sink_flush_one_pad (sink, i);
}
}
/* TRUE, if everything should continue */
static gboolean
gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr)
{
gboolean cont = TRUE;
GstEvent *event = GST_EVENT (sink->buf[pad_nr]);
@ -200,38 +202,42 @@ gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
if (event) {
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
gst_alsa_set_eos (this);
cont = FALSE;
break;
gst_alsa_set_eos (this);
cont = FALSE;
break;
case GST_EVENT_INTERRUPT:
cont = FALSE;
break;
case GST_EVENT_DISCONTINUOUS:
{
GstClockTime value;
/* only the first pad my seek */
if (pad_nr != 0) {
break;
}
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &value)) {
gst_element_set_time (GST_ELEMENT (this), value);
} else if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)) {
value = gst_alsa_samples_to_timestamp (this, value);
gst_element_set_time (GST_ELEMENT (this), value);
} else if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &value)) {
value = gst_alsa_bytes_to_timestamp (this, value);
gst_element_set_time (GST_ELEMENT (this), value);
} else {
GST_ERROR_OBJECT (this, "couldn't extract time from discont event. Bad things might happen!");
}
break;
case GST_EVENT_DISCONTINUOUS:
{
GstClockTime value;
/* only the first pad my seek */
if (pad_nr != 0) {
break;
}
}
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &value)) {
gst_element_set_time (GST_ELEMENT (this), value);
} else if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT,
&value)) {
value = gst_alsa_samples_to_timestamp (this, value);
gst_element_set_time (GST_ELEMENT (this), value);
} else if (gst_event_discont_get_value (event, GST_FORMAT_BYTES,
&value)) {
value = gst_alsa_bytes_to_timestamp (this, value);
gst_element_set_time (GST_ELEMENT (this), value);
} else {
GST_ERROR_OBJECT (this,
"couldn't extract time from discont event. Bad things might happen!");
}
break;
}
default:
GST_INFO_OBJECT (this, "got an unknown event (Type: %d)", GST_EVENT_TYPE (event));
break;
GST_INFO_OBJECT (this, "got an unknown event (Type: %d)",
GST_EVENT_TYPE (event));
break;
}
gst_event_unref (event);
sink->buf[pad_nr] = NULL;
@ -242,7 +248,7 @@ gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
return cont;
}
static int
gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
gst_alsa_sink_mmap (GstAlsa * this, snd_pcm_sframes_t * avail)
{
snd_pcm_uframes_t offset;
const snd_pcm_channel_area_t *dst;
@ -251,7 +257,7 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
int i, err, width = snd_pcm_format_physical_width (this->format->format);
/* areas points to the memory areas that belong to gstreamer. */
src = g_malloc0 (this->format->channels * sizeof(snd_pcm_channel_area_t));
src = g_malloc0 (this->format->channels * sizeof (snd_pcm_channel_area_t));
if (((GstElement *) this)->numpads == 1) {
/* interleaved */
@ -274,7 +280,9 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
return -1;
}
if ((err = snd_pcm_areas_copy (dst, offset, src, 0, this->format->channels, *avail, this->format->format)) < 0) {
if ((err =
snd_pcm_areas_copy (dst, offset, src, 0, this->format->channels,
*avail, this->format->format)) < 0) {
snd_pcm_mmap_commit (this->handle, offset, 0);
GST_ERROR_OBJECT (this, "data copy failed: %s", snd_strerror (err));
return -1;
@ -287,7 +295,7 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
return err;
}
static int
gst_alsa_sink_write (GstAlsa *this, snd_pcm_sframes_t *avail)
gst_alsa_sink_write (GstAlsa * this, snd_pcm_sframes_t * avail)
{
GstAlsaSink *sink = GST_ALSA_SINK (this);
void *channels[this->format->channels];
@ -314,12 +322,12 @@ gst_alsa_sink_write (GstAlsa *this, snd_pcm_sframes_t *avail)
return err;
}
static void
gst_alsa_sink_loop (GstElement *element)
gst_alsa_sink_loop (GstElement * element)
{
snd_pcm_sframes_t avail, avail2, copied, sample_diff, max_discont;
snd_pcm_uframes_t samplestamp, time_sample;
gint i;
guint bytes; /* per channel */
guint bytes; /* per channel */
GstAlsa *this = GST_ALSA (element);
GstAlsaSink *sink = GST_ALSA_SINK (element);
@ -328,80 +336,97 @@ gst_alsa_sink_loop (GstElement *element)
sink_restart:
avail = gst_alsa_update_avail (this);
if (avail == -EPIPE) goto sink_restart;
if (avail < 0) return;
if (avail == -EPIPE)
goto sink_restart;
if (avail < 0)
return;
if (avail > 0) {
/* Not enough space. We grab data nonetheless and sleep afterwards */
/* Not enough space. We grab data nonetheless and sleep afterwards */
if (avail < this->period_size) {
avail = this->period_size;
}
/* check how many bytes we still have in all our bytestreams */
/* initialize this value to a somewhat sane state, we might alloc this much data below (which would be a bug, but who knows)... */
bytes = this->period_size * this->period_count * element->numpads * 8; /* must be > max sample size in bytes */
bytes = this->period_size * this->period_count * element->numpads * 8; /* must be > max sample size in bytes */
for (i = 0; i < element->numpads; i++) {
g_assert (this->pad[i] != NULL);
while (sink->size[i] == 0) {
if (!sink->buf[i])
sink->buf[i] = GST_BUFFER (gst_pad_pull (this->pad[i]));
if (GST_IS_EVENT (sink->buf[i])) {
if (!sink->buf[i])
sink->buf[i] = GST_BUFFER (gst_pad_pull (this->pad[i]));
if (GST_IS_EVENT (sink->buf[i])) {
if (gst_alsa_sink_check_event (sink, i))
continue;
return;
}
/* caps nego failed somewhere */
if (this->format == NULL) {
GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
("ALSA format not negotiated"));
}
samplestamp = gst_alsa_timestamp_to_samples (this, GST_BUFFER_TIMESTAMP (sink->buf[i]));
max_discont = gst_alsa_timestamp_to_samples (this, this->max_discont);
time_sample = gst_alsa_timestamp_to_samples (this, gst_element_get_time (GST_ELEMENT (this)));
/* caps nego failed somewhere */
if (this->format == NULL) {
GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
("ALSA format not negotiated"));
}
samplestamp =
gst_alsa_timestamp_to_samples (this,
GST_BUFFER_TIMESTAMP (sink->buf[i]));
max_discont = gst_alsa_timestamp_to_samples (this, this->max_discont);
time_sample =
gst_alsa_timestamp_to_samples (this,
gst_element_get_time (GST_ELEMENT (this)));
snd_pcm_delay (this->handle, &sample_diff);
/* actual diff = buffer samplestamp - played - to_play */
sample_diff = samplestamp - time_sample - sample_diff;
if ((!GST_BUFFER_TIMESTAMP_IS_VALID (sink->buf[i])) ||
(-max_discont <= sample_diff && sample_diff <= max_discont)) {
if ((!GST_BUFFER_TIMESTAMP_IS_VALID (sink->buf[i])) ||
(-max_discont <= sample_diff && sample_diff <= max_discont)) {
/* difference between expected and current is < GST_ALSA_DEVIATION */
no_difference:
/* difference between expected and current is < GST_ALSA_DEVIATION */
no_difference:
sink->size[i] = sink->buf[i]->size;
sink->data[i] = sink->buf[i]->data;
sink->behaviour[i] = 0;
sink->data[i] = sink->buf[i]->data;
sink->behaviour[i] = 0;
} else if (sample_diff > 0) {
/* there are empty samples in front of us, fill them with silence */
int samples = MIN (bytes, sample_diff) *
(element->numpads == 1 ? this->format->channels : 1);
int size = samples * snd_pcm_format_physical_width (this->format->format) / 8;
GST_INFO_OBJECT (this, "Allocating %d bytes (%ld samples) now to resync: sample %ld expected, but got %ld",
size, MIN (bytes, sample_diff), time_sample, samplestamp);
(element->numpads == 1 ? this->format->channels : 1);
int size =
samples * snd_pcm_format_physical_width (this->format->format) /
8;
GST_INFO_OBJECT (this,
"Allocating %d bytes (%ld samples) now to resync: sample %ld expected, but got %ld",
size, MIN (bytes, sample_diff), time_sample, samplestamp);
sink->data[i] = g_try_malloc (size);
if (!sink->data[i]) {
GST_WARNING_OBJECT (this, "error allocating %d bytes, buffers unsynced now.", size);
GST_WARNING_OBJECT (this,
"error allocating %d bytes, buffers unsynced now.", size);
goto no_difference;
}
sink->size[i] = size;
if (0 != snd_pcm_format_set_silence (this->format->format, sink->data[i], samples)) {
GST_WARNING_OBJECT (this, "error silencing buffer, enjoy the noise.");
if (0 != snd_pcm_format_set_silence (this->format->format,
sink->data[i], samples)) {
GST_WARNING_OBJECT (this,
"error silencing buffer, enjoy the noise.");
}
sink->behaviour[i] = 1;
} else if (gst_alsa_samples_to_bytes (this, -sample_diff) >= sink->buf[i]->size) {
GST_INFO_OBJECT (this, "Skipping %lu samples to resync (complete buffer): sample %ld expected, but got %ld",
gst_alsa_bytes_to_samples (this, sink->buf[i]->size), time_sample, samplestamp);
} else if (gst_alsa_samples_to_bytes (this,
-sample_diff) >= sink->buf[i]->size) {
GST_INFO_OBJECT (this,
"Skipping %lu samples to resync (complete buffer): sample %ld expected, but got %ld",
gst_alsa_bytes_to_samples (this, sink->buf[i]->size), time_sample,
samplestamp);
/* this buffer is way behind */
gst_buffer_unref (sink->buf[i]);
sink->buf[i] = NULL;
continue;
} else if (sample_diff < 0) {
gint difference = gst_alsa_samples_to_bytes (this, -samplestamp);
GST_INFO_OBJECT (this, "Skipping %lu samples to resync: sample %ld expected, but got %ld",
(gulong) -sample_diff, time_sample, samplestamp);
GST_INFO_OBJECT (this,
"Skipping %lu samples to resync: sample %ld expected, but got %ld",
(gulong) - sample_diff, time_sample, samplestamp);
/* this buffer is only a bit behind */
sink->size[i] = sink->buf[i]->size - difference;
sink->data[i] = sink->buf[i]->data + difference;
sink->behaviour[i] = 0;
sink->size[i] = sink->buf[i]->size - difference;
sink->data[i] = sink->buf[i]->data + difference;
sink->behaviour[i] = 0;
} else {
g_assert_not_reached ();
}
@ -412,17 +437,22 @@ no_difference:
avail = MIN (avail, gst_alsa_bytes_to_samples (this, bytes));
/* wait until the hw buffer has enough space */
while (gst_element_get_state (element) == GST_STATE_PLAYING && (avail2 = gst_alsa_update_avail (this)) < avail) {
if (avail2 <= -EPIPE) goto sink_restart;
if (avail2 < 0) return;
if (avail2 < avail && snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING)
if (!gst_alsa_start (this)) return;
while (gst_element_get_state (element) == GST_STATE_PLAYING
&& (avail2 = gst_alsa_update_avail (this)) < avail) {
if (avail2 <= -EPIPE)
goto sink_restart;
if (avail2 < 0)
return;
if (avail2 < avail
&& snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING)
if (!gst_alsa_start (this))
return;
if (gst_alsa_pcm_wait (this) == FALSE)
return;
return;
}
/* FIXME: lotsa stuff can have happened while fetching data. Do we need to check something? */
/* put this data into alsa */
if ((copied = this->transmit (this, &avail)) < 0)
return;
@ -432,23 +462,24 @@ no_difference:
bytes = gst_alsa_samples_to_bytes (this, copied);
for (i = 0; i < element->numpads; i++) {
if ((sink->size[i] -= bytes) == 0) {
gst_alsa_sink_flush_one_pad (sink, i);
continue;
gst_alsa_sink_flush_one_pad (sink, i);
continue;
}
g_assert (sink->size[i] > 0);
if (sink->behaviour[i] != 1)
sink->data[i] += bytes;
sink->data[i] += bytes;
}
}
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING && snd_pcm_avail_update (this->handle) == 0) {
if (snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING
&& snd_pcm_avail_update (this->handle) == 0) {
gst_alsa_start (this);
}
}
static GstElementStateReturn
gst_alsa_sink_change_state (GstElement *element)
gst_alsa_sink_change_state (GstElement * element)
{
GstAlsaSink *sink;
@ -456,18 +487,18 @@ gst_alsa_sink_change_state (GstElement *element)
sink = GST_ALSA_SINK (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
gst_alsa_sink_flush_pads (sink);
break;
case GST_STATE_READY_TO_NULL:
break;
default:
g_assert_not_reached();
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
gst_alsa_sink_flush_pads (sink);
break;
case GST_STATE_READY_TO_NULL:
break;
default:
g_assert_not_reached ();
}
if (GST_ELEMENT_CLASS (sink_parent_class)->change_state)
@ -477,14 +508,14 @@ gst_alsa_sink_change_state (GstElement *element)
}
static GstClockTime
gst_alsa_sink_get_time (GstAlsa *this)
gst_alsa_sink_get_time (GstAlsa * this)
{
snd_pcm_sframes_t delay;
if (snd_pcm_delay (this->handle, &delay) == 0 && this->format) {
return GST_SECOND * (GstClockTime) (this->transmitted > delay ? this->transmitted - delay : 0) / this->format->rate;
return GST_SECOND * (GstClockTime) (this->transmitted >
delay ? this->transmitted - delay : 0) / this->format->rate;
} else {
return 0;
}
}

View file

@ -25,35 +25,34 @@
#include "gstalsa.h"
G_BEGIN_DECLS
#define GST_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SINK, GstAlsaSink))
#define GST_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA_SINK, GstAlsaSinkClass))
#define GST_IS_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA_SINK))
#define GST_IS_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA_SINK))
#define GST_TYPE_ALSA_SINK (gst_alsa_sink_get_type())
typedef struct _GstAlsaSink GstAlsaSink;
typedef struct _GstAlsaSinkClass GstAlsaSinkClass;
struct _GstAlsaSink {
GstAlsa parent;
struct _GstAlsaSink
{
GstAlsa parent;
/* array of the data on the channels */
guint8 *data[GST_ALSA_MAX_TRACKS]; /* pointer into buffer */
guint size[GST_ALSA_MAX_TRACKS]; /* sink: bytes left in buffer */
GstBuffer *buf[GST_ALSA_MAX_TRACKS]; /* current buffer */
guint behaviour[GST_ALSA_MAX_TRACKS]; /* 0 = data points into buffer (so unref when size == 0),
1 = data should be freed, use buffer after that */
guint8 *data[GST_ALSA_MAX_TRACKS]; /* pointer into buffer */
guint size[GST_ALSA_MAX_TRACKS]; /* sink: bytes left in buffer */
GstBuffer *buf[GST_ALSA_MAX_TRACKS]; /* current buffer */
guint behaviour[GST_ALSA_MAX_TRACKS]; /* 0 = data points into buffer (so unref when size == 0),
1 = data should be freed, use buffer after that */
};
struct _GstAlsaSinkClass {
struct _GstAlsaSinkClass
{
GstAlsaClass parent_class;
};
GType gst_alsa_sink_get_type (void);
gboolean gst_alsa_sink_factory_init (GstPlugin *plugin);
gboolean gst_alsa_sink_factory_init (GstPlugin * plugin);
G_END_DECLS
#endif /* __GST_ALSA_SINK_H__ */

View file

@ -27,29 +27,24 @@
#include "gstalsaclock.h"
/* elementfactory information */
static GstElementDetails gst_alsa_src_details = GST_ELEMENT_DETAILS (
"Alsa Src",
"Source/Audio",
"Read from a sound card via ALSA",
"Thomas Nyberg <thomas@codefactory.se>, "
"Andy Wingo <apwingo@eos.ncsu.edu>, "
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
static GstElementDetails gst_alsa_src_details = GST_ELEMENT_DETAILS ("Alsa Src",
"Source/Audio",
"Read from a sound card via ALSA",
"Thomas Nyberg <thomas@codefactory.se>, "
"Andy Wingo <apwingo@eos.ncsu.edu>, "
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
static GstPadTemplate * gst_alsa_src_pad_factory (void);
static void gst_alsa_src_base_init (gpointer g_class);
static void gst_alsa_src_class_init (gpointer g_class,
gpointer class_data);
static void gst_alsa_src_init (GstAlsaSrc * this);
static int gst_alsa_src_mmap (GstAlsa * this,
snd_pcm_sframes_t * avail);
static int gst_alsa_src_read (GstAlsa * this,
snd_pcm_sframes_t * avail);
static void gst_alsa_src_loop (GstElement * element);
static void gst_alsa_src_flush (GstAlsaSrc * src);
static GstElementStateReturn gst_alsa_src_change_state (GstElement * element);
static GstPadTemplate *gst_alsa_src_pad_factory (void);
static void gst_alsa_src_base_init (gpointer g_class);
static void gst_alsa_src_class_init (gpointer g_class, gpointer class_data);
static void gst_alsa_src_init (GstAlsaSrc * this);
static int gst_alsa_src_mmap (GstAlsa * this, snd_pcm_sframes_t * avail);
static int gst_alsa_src_read (GstAlsa * this, snd_pcm_sframes_t * avail);
static void gst_alsa_src_loop (GstElement * element);
static void gst_alsa_src_flush (GstAlsaSrc * src);
static GstElementStateReturn gst_alsa_src_change_state (GstElement * element);
static GstClockTime gst_alsa_src_get_time (GstAlsa * this);
static GstClockTime gst_alsa_src_get_time (GstAlsa * this);
static GstAlsa *src_parent_class = NULL;
@ -60,7 +55,7 @@ gst_alsa_src_pad_factory (void)
if (!template)
template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
return template;
}
@ -83,7 +78,8 @@ gst_alsa_src_get_type (void)
(GInstanceInitFunc) gst_alsa_src_init,
};
alsa_src_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaSrc", &alsa_src_info, 0);
alsa_src_type =
g_type_register_static (GST_TYPE_ALSA, "GstAlsaSrc", &alsa_src_info, 0);
}
return alsa_src_type;
}
@ -92,8 +88,9 @@ static void
gst_alsa_src_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class, gst_alsa_src_pad_factory ());
gst_element_class_add_pad_template (element_class,
gst_alsa_src_pad_factory ());
gst_element_class_set_details (element_class, &gst_alsa_src_details);
}
@ -114,14 +111,14 @@ gst_alsa_src_class_init (gpointer g_class, gpointer class_data)
if (src_parent_class == NULL)
src_parent_class = g_type_class_ref (GST_TYPE_ALSA);
alsa_class->stream = SND_PCM_STREAM_CAPTURE;
alsa_class->transmit_mmap = gst_alsa_src_mmap;
alsa_class->transmit_rw = gst_alsa_src_read;
alsa_class->stream = SND_PCM_STREAM_CAPTURE;
alsa_class->transmit_mmap = gst_alsa_src_mmap;
alsa_class->transmit_rw = gst_alsa_src_read;
element_class->change_state = gst_alsa_src_change_state;
element_class->change_state = gst_alsa_src_change_state;
}
static void
gst_alsa_src_init (GstAlsaSrc *src)
gst_alsa_src_init (GstAlsaSrc * src)
{
GstAlsa *this = GST_ALSA (src);
@ -129,8 +126,9 @@ gst_alsa_src_init (GstAlsaSrc *src)
gst_pad_set_link_function (this->pad[0], gst_alsa_link);
gst_pad_set_getcaps_function (this->pad[0], gst_alsa_get_caps);
gst_element_add_pad (GST_ELEMENT (this), this->pad[0]);
this->clock = gst_alsa_clock_new ("alsasrcclock", gst_alsa_src_get_time, this);
this->clock =
gst_alsa_clock_new ("alsasrcclock", gst_alsa_src_get_time, this);
/* we hold a ref to our clock until we're disposed */
gst_object_ref (GST_OBJECT (this->clock));
gst_object_sink (GST_OBJECT (this->clock));
@ -138,7 +136,7 @@ gst_alsa_src_init (GstAlsaSrc *src)
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
}
static int
gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
gst_alsa_src_mmap (GstAlsa * this, snd_pcm_sframes_t * avail)
{
snd_pcm_uframes_t offset;
snd_pcm_channel_area_t *dst;
@ -147,7 +145,7 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
GstAlsaSrc *alsa_src = GST_ALSA_SRC (this);
/* areas points to the memory areas that belong to gstreamer. */
dst = g_malloc0 (this->format->channels * sizeof(snd_pcm_channel_area_t));
dst = g_malloc0 (this->format->channels * sizeof (snd_pcm_channel_area_t));
if (((GstElement *) this)->numpads == 1) {
/* interleaved */
@ -169,7 +167,10 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
GST_ERROR_OBJECT (this, "mmap failed: %s", snd_strerror (err));
return -1;
}
if (*avail > 0 && (err = snd_pcm_areas_copy (dst, 0, src, offset, this->format->channels, *avail, this->format->format)) < 0) {
if (*avail > 0
&& (err =
snd_pcm_areas_copy (dst, 0, src, offset, this->format->channels,
*avail, this->format->format)) < 0) {
snd_pcm_mmap_commit (this->handle, offset, 0);
GST_ERROR_OBJECT (this, "data copy failed: %s", snd_strerror (err));
return -1;
@ -182,7 +183,7 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
return err;
}
static int
gst_alsa_src_read (GstAlsa *this, snd_pcm_sframes_t *avail)
gst_alsa_src_read (GstAlsa * this, snd_pcm_sframes_t * avail)
{
void *channels[this->format->channels];
int err, i;
@ -224,8 +225,9 @@ gst_alsa_src_adjust_rate (gint rate, gboolean aggressive)
return 0;
}
static gboolean
gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
gst_alsa_src_set_caps (GstAlsaSrc * src, gboolean aggressive)
{
GstCaps *all_caps, *caps;
GstStructure *structure, *walk;
@ -236,19 +238,21 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
GstAlsa *this = GST_ALSA (src);
all_caps = gst_alsa_get_caps (this->pad[0]);
if (all_caps == NULL) return FALSE;
if (all_caps == NULL)
return FALSE;
/* now intersect this with all caps of the peers... */
for (i = 0; i < GST_ELEMENT (src)->numpads; i++) {
all_caps = gst_caps_intersect (all_caps, gst_pad_get_allowed_caps (this->pad[i]));
all_caps =
gst_caps_intersect (all_caps, gst_pad_get_allowed_caps (this->pad[i]));
if (all_caps == NULL) {
GST_DEBUG ("No compatible caps found in alsasrc (%s)", GST_ELEMENT_NAME (this));
GST_DEBUG ("No compatible caps found in alsasrc (%s)",
GST_ELEMENT_NAME (this));
return FALSE;
}
}
/* construct caps */
caps = gst_caps_new_simple ("audio/x-raw-int",
NULL);
caps = gst_caps_new_simple ("audio/x-raw-int", NULL);
g_assert (gst_caps_get_size (caps) == 1);
structure = gst_caps_get_structure (caps, 0);
@ -256,37 +260,43 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
for (i = 0; i < gst_caps_get_size (all_caps); i++) {
walk = gst_caps_get_structure (all_caps, i);
if (!(gst_structure_get_int (walk, "signed", &sign) &&
gst_structure_get_int (walk, "width", &width) &&
gst_structure_get_int (walk, "depth", &depth))) {
gst_structure_get_int (walk, "width", &width) &&
gst_structure_get_int (walk, "depth", &depth))) {
GST_ERROR_OBJECT (src, "couldn't parse my own format. Huh?");
continue;
}
if (!gst_structure_get_int (walk, "endianness", &endian)) {
endian = G_BYTE_ORDER;
}
gst_structure_set (structure,
gst_structure_set (structure,
"endianness", G_TYPE_INT, endian,
"width", G_TYPE_INT, width,
"depth", G_TYPE_INT, depth,
"signed", G_TYPE_BOOLEAN, sign,
NULL);
"width", G_TYPE_INT, width,
"depth", G_TYPE_INT, depth, "signed", G_TYPE_BOOLEAN, sign, NULL);
min_rate = gst_value_get_int_range_min (gst_structure_get_value (walk, "rate"));
max_rate = gst_value_get_int_range_max (gst_structure_get_value (walk, "rate"));
min_channels = gst_value_get_int_range_min (gst_structure_get_value (walk, "channels"));
max_channels = gst_value_get_int_range_max (gst_structure_get_value (walk, "channels"));
min_rate =
gst_value_get_int_range_min (gst_structure_get_value (walk, "rate"));
max_rate =
gst_value_get_int_range_max (gst_structure_get_value (walk, "rate"));
min_channels =
gst_value_get_int_range_min (gst_structure_get_value (walk,
"channels"));
max_channels =
gst_value_get_int_range_max (gst_structure_get_value (walk,
"channels"));
for (rate = max_rate;; rate--) {
if ((rate = gst_alsa_src_adjust_rate (rate, aggressive)) < min_rate)
break;
gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
for (channels = aggressive ? max_channels : MIN (max_channels, 2); channels >= min_channels; channels--) {
gst_structure_set (structure, "channels", G_TYPE_INT, channels, NULL);
GST_DEBUG ("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d",
sign ? "" : "un", endian, width, depth, channels, rate);
if (gst_pad_try_set_caps (this->pad[0], caps) != GST_PAD_LINK_REFUSED)
gst_alsa_link (this->pad[0], caps);
for (channels = aggressive ? max_channels : MIN (max_channels, 2);
channels >= min_channels; channels--) {
gst_structure_set (structure, "channels", G_TYPE_INT, channels, NULL);
GST_DEBUG
("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d",
sign ? "" : "un", endian, width, depth, channels, rate);
if (gst_pad_try_set_caps (this->pad[0], caps) != GST_PAD_LINK_REFUSED)
gst_alsa_link (this->pad[0], caps);
if (this->format) {
if (this->format) {
/* try to set caps here */
return TRUE;
}
@ -299,9 +309,10 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
return FALSE;
}
/* we transmit buffers of period_size frames */
static void
gst_alsa_src_loop (GstElement *element)
gst_alsa_src_loop (GstElement * element)
{
snd_pcm_sframes_t avail, copied;
gint i;
@ -311,16 +322,18 @@ gst_alsa_src_loop (GstElement *element)
/* set the caps on all pads */
if (!this->format) {
if (!gst_alsa_src_set_caps (src, FALSE)) {
GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL),
("ALSA format not negotiated"));
GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL),
("ALSA format not negotiated"));
return;
}
}
while ((avail = gst_alsa_update_avail (this)) < this->period_size) {
if (avail == -EPIPE) continue;
if (avail < 0) return;
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING) {
if (avail == -EPIPE)
continue;
if (avail < 0)
return;
if (snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING) {
if (!gst_alsa_start (this))
return;
continue;
@ -345,8 +358,10 @@ gst_alsa_src_loop (GstElement *element)
return;
if (copied != this->period_size)
GST_BUFFER_SIZE (src->buf[i]) = gst_alsa_samples_to_bytes (this, copied);
GST_BUFFER_TIMESTAMP (src->buf[i]) = gst_alsa_samples_to_timestamp (this, this->transmitted);
GST_BUFFER_DURATION (src->buf[i]) = gst_alsa_samples_to_timestamp (this, copied);
GST_BUFFER_TIMESTAMP (src->buf[i]) =
gst_alsa_samples_to_timestamp (this, this->transmitted);
GST_BUFFER_DURATION (src->buf[i]) =
gst_alsa_samples_to_timestamp (this, copied);
gst_pad_push (this->pad[i], GST_DATA (src->buf[i]));
src->buf[i] = NULL;
}
@ -354,11 +369,11 @@ gst_alsa_src_loop (GstElement *element)
}
static void
gst_alsa_src_flush (GstAlsaSrc *src)
gst_alsa_src_flush (GstAlsaSrc * src)
{
gint i;
for (i = 0; i < GST_ELEMENT (src)->numpads; i++) {
for (i = 0; i < GST_ELEMENT (src)->numpads; i++) {
if (src->buf[i]) {
gst_buffer_unref (src->buf[i]);
src->buf[i] = NULL;
@ -366,7 +381,7 @@ gst_alsa_src_flush (GstAlsaSrc *src)
}
}
static GstElementStateReturn
gst_alsa_src_change_state (GstElement *element)
gst_alsa_src_change_state (GstElement * element)
{
GstAlsaSrc *src;
@ -374,18 +389,18 @@ gst_alsa_src_change_state (GstElement *element)
src = GST_ALSA_SRC (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
gst_alsa_src_flush (src);
break;
case GST_STATE_READY_TO_NULL:
break;
default:
g_assert_not_reached();
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
case GST_STATE_PAUSED_TO_PLAYING:
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
gst_alsa_src_flush (src);
break;
case GST_STATE_READY_TO_NULL:
break;
default:
g_assert_not_reached ();
}
if (GST_ELEMENT_CLASS (src_parent_class)->change_state)
@ -395,14 +410,13 @@ gst_alsa_src_change_state (GstElement *element)
}
static GstClockTime
gst_alsa_src_get_time (GstAlsa *this)
gst_alsa_src_get_time (GstAlsa * this)
{
snd_pcm_sframes_t delay;
if (snd_pcm_delay (this->handle, &delay) == 0) {
return GST_SECOND * (this->transmitted + delay) / this->format->rate;
} else {
return 0;
}
}

View file

@ -25,29 +25,28 @@
#include "gstalsa.h"
G_BEGIN_DECLS
#define GST_ALSA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SRC, GstAlsaSrc))
#define GST_ALSA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA_SRC, GstAlsaSrcClass))
#define GST_IS_ALSA_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA_SRC))
#define GST_IS_ALSA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA_SRC))
#define GST_TYPE_ALSA_SRC (gst_alsa_src_get_type())
typedef struct _GstAlsaSrc GstAlsaSrc;
typedef struct _GstAlsaSrcClass GstAlsaSrcClass;
struct _GstAlsaSrc {
GstAlsa parent;
GstBuffer *buf[GST_ALSA_MAX_TRACKS];
struct _GstAlsaSrc
{
GstAlsa parent;
GstBuffer *buf[GST_ALSA_MAX_TRACKS];
};
struct _GstAlsaSrcClass {
struct _GstAlsaSrcClass
{
GstAlsaClass parent_class;
};
GType gst_alsa_src_get_type (void);
gboolean gst_alsa_src_factory_init (GstPlugin *plugin);
gboolean gst_alsa_src_factory_init (GstPlugin * plugin);
G_END_DECLS
#endif /* __GST_ALSA_SRC_H__ */

File diff suppressed because it is too large Load diff

View file

@ -26,20 +26,21 @@
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern "C"
{
#endif /* __cplusplus */
#define size16 gint16
#define size32 gint32
#ifdef CDPARANOIA_HEADERS_IN_DIR
#include <cdda/cdda_interface.h>
#include <cdda/cdda_paranoia.h>
#include <cdda/cdda_interface.h>
#include <cdda/cdda_paranoia.h>
#else
#include <cdda_interface.h>
#include <cdda_paranoia.h>
#include <cdda_interface.h>
#include <cdda_paranoia.h>
#endif
/*#define CDPARANOIA_BASEOFFSET 0xf1d2 */
@ -57,69 +58,72 @@ extern "C" {
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDPARANOIA))
/* NOTE: per-element flags start with 16 for now */
typedef enum {
CDPARANOIA_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum
{
CDPARANOIA_OPEN = GST_ELEMENT_FLAG_LAST,
CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2,
} CDParanoiaFlags;
CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
} CDParanoiaFlags;
typedef struct _CDParanoia CDParanoia;
typedef struct _CDParanoiaClass CDParanoiaClass;
typedef struct _CDParanoia CDParanoia;
typedef struct _CDParanoiaClass CDParanoiaClass;
struct _CDParanoia {
GstElement element;
/* pads */
GstPad *srcpad;
struct _CDParanoia
{
GstElement element;
/* pads */
GstPad *srcpad;
/* Index */
GstIndex *index;
int index_id;
gchar *device;
gchar *generic_device;
gint default_sectors;
gint search_overlap;
gint endian;
gint read_speed;
gint toc_offset;
gboolean toc_bias;
gint never_skip;
gboolean abort_on_skip;
gint paranoia_mode;
/* Index */
GstIndex *index;
int index_id;
cdrom_drive *d;
cdrom_paranoia *p;
gchar *device;
gchar *generic_device;
gint default_sectors;
gint search_overlap;
gint endian;
gint read_speed;
gint toc_offset;
gboolean toc_bias;
gint never_skip;
gboolean abort_on_skip;
gint paranoia_mode;
gint cur_sector;
gint segment_start_sector;
gint segment_end_sector;
cdrom_drive *d;
cdrom_paranoia *p;
gint first_sector;
gint last_sector;
gint cur_sector;
gint segment_start_sector;
gint segment_end_sector;
/* hacks by Gordon Irving */
gchar discid[20];
gint64 offsets[MAXTRK];
gint64 total_seconds;
gint first_sector;
gint last_sector;
gint seq;
gboolean discont_pending;
};
/* hacks by Gordon Irving */
gchar discid[20];
gint64 offsets[MAXTRK];
gint64 total_seconds;
struct _CDParanoiaClass {
GstElementClass parent_class;
gint seq;
gboolean discont_pending;
};
/* signal callbacks */
void (*smilie_change) (CDParanoia *cdparanoia, gchar *smilie);
void (*transport_error) (CDParanoia *cdparanoia, gint offset);
void (*uncorrected_error) (CDParanoia *cdparanoia, gint offset);
};
struct _CDParanoiaClass
{
GstElementClass parent_class;
GType cdparanoia_get_type(void);
/* signal callbacks */
void (*smilie_change) (CDParanoia * cdparanoia, gchar * smilie);
void (*transport_error) (CDParanoia * cdparanoia, gint offset);
void (*uncorrected_error) (CDParanoia * cdparanoia, gint offset);
};
GType cdparanoia_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* __CDPARANOIA_H__ */
#endif /* __CDPARANOIA_H__ */

View file

@ -28,16 +28,15 @@
#include "gstgnomevfs.h"
#include <gst/gst.h>
static gboolean
plugin_init(GstPlugin *plugin)
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_element_register (plugin, "gnomevfssrc",
GST_RANK_SECONDARY, gst_gnomevfssrc_get_type()) ||
!gst_element_register (plugin, "gnomevfssink",
GST_RANK_SECONDARY, gst_gnomevfssink_get_type())) {
if (!gst_element_register (plugin, "gnomevfssrc",
GST_RANK_SECONDARY, gst_gnomevfssrc_get_type ()) ||
!gst_element_register (plugin, "gnomevfssink",
GST_RANK_SECONDARY, gst_gnomevfssink_get_type ())) {
return FALSE;
}
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@ -46,15 +45,8 @@ plugin_init(GstPlugin *plugin)
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gnomevfs",
"elements to access the Gnome vfs",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gnomevfs",
"elements to access the Gnome vfs",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)

View file

@ -23,13 +23,9 @@
#include <glib-object.h>
G_BEGIN_DECLS
GType gst_gnomevfssink_get_type (void);
G_BEGIN_DECLS GType gst_gnomevfssink_get_type (void);
GType gst_gnomevfssrc_get_type (void);
G_END_DECLS
#endif /* __GST_GNOME_VFS_H__ */

View file

@ -51,13 +51,15 @@
typedef struct _GstGnomeVFSSink GstGnomeVFSSink;
typedef struct _GstGnomeVFSSinkClass GstGnomeVFSSinkClass;
typedef enum {
GST_GNOMEVFSSINK_OPEN = GST_ELEMENT_FLAG_LAST,
typedef enum
{
GST_GNOMEVFSSINK_OPEN = GST_ELEMENT_FLAG_LAST,
GST_GNOMEVFSSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
GST_GNOMEVFSSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
} GstGnomeVFSSinkFlags;
struct _GstGnomeVFSSink {
struct _GstGnomeVFSSink
{
GstElement element;
/* filename */
@ -70,32 +72,34 @@ struct _GstGnomeVFSSink {
gboolean erase;
};
struct _GstGnomeVFSSinkClass {
struct _GstGnomeVFSSinkClass
{
GstElementClass parent_class;
/* signals */
void (*handoff) (GstElement *element,GstPad *pad);
void (*erase_ask) (GstElement *element,GstPad *pad);
void (*handoff) (GstElement * element, GstPad * pad);
void (*erase_ask) (GstElement * element, GstPad * pad);
};
/* elementfactory information */
static GstElementDetails gst_gnomevfssink_details = GST_ELEMENT_DETAILS (
"GnomeVFS Sink",
"Sink/File",
"Write stream to a GnomeVFS URI",
"Bastien Nocera <hadess@hadess.net>"
);
static GstElementDetails gst_gnomevfssink_details =
GST_ELEMENT_DETAILS ("GnomeVFS Sink",
"Sink/File",
"Write stream to a GnomeVFS URI",
"Bastien Nocera <hadess@hadess.net>");
/* GnomeVFSSink signals and args */
enum {
enum
{
/* FILL ME */
SIGNAL_HANDOFF,
SIGNAL_ERASE_ASK,
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_LOCATION,
ARG_HANDLE,
@ -103,41 +107,46 @@ enum {
};
static void gst_gnomevfssink_base_init (gpointer g_class);
static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass);
static void gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink);
static void gst_gnomevfssink_base_init (gpointer g_class);
static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass);
static void gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink);
static void gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_gnomevfssink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gnomevfssink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_gnomevfssink_open_file (GstGnomeVFSSink *sink);
static void gst_gnomevfssink_close_file (GstGnomeVFSSink *sink);
static gboolean gst_gnomevfssink_open_file (GstGnomeVFSSink * sink);
static void gst_gnomevfssink_close_file (GstGnomeVFSSink * sink);
static void gst_gnomevfssink_chain (GstPad *pad,GstData *_data);
static void gst_gnomevfssink_chain (GstPad * pad, GstData * _data);
static GstElementStateReturn gst_gnomevfssink_change_state (GstElement *element);
static GstElementStateReturn gst_gnomevfssink_change_state (GstElement *
element);
static GstElementClass *parent_class = NULL;
static guint gst_gnomevfssink_signals[LAST_SIGNAL] = { 0 };
GType
gst_gnomevfssink_get_type (void)
gst_gnomevfssink_get_type (void)
{
static GType gnomevfssink_type = 0;
if (!gnomevfssink_type) {
static const GTypeInfo gnomevfssink_info = {
sizeof(GstGnomeVFSSinkClass),
sizeof (GstGnomeVFSSinkClass),
gst_gnomevfssink_base_init,
NULL,
(GClassInitFunc)gst_gnomevfssink_class_init,
(GClassInitFunc) gst_gnomevfssink_class_init,
NULL,
NULL,
sizeof(GstGnomeVFSSink),
sizeof (GstGnomeVFSSink),
0,
(GInstanceInitFunc)gst_gnomevfssink_init,
(GInstanceInitFunc) gst_gnomevfssink_init,
};
gnomevfssink_type = g_type_register_static (GST_TYPE_ELEMENT, "GstGnomeVFSSink", &gnomevfssink_info, 0);
gnomevfssink_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstGnomeVFSSink",
&gnomevfssink_info, 0);
}
return gnomevfssink_type;
}
@ -151,38 +160,34 @@ gst_gnomevfssink_base_init (gpointer g_class)
}
static void
gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass)
gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass)
{
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_ELEMENT);
gst_element_class_install_std_props (
GST_ELEMENT_CLASS (klass),
"location", ARG_LOCATION, G_PARAM_READWRITE,
NULL);
gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
"location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
g_object_class_install_property (gobject_class,
ARG_HANDLE,
g_param_spec_pointer ("handle",
"GnomeVFSHandle",
"Handle for GnomeVFS",
G_PARAM_READWRITE));
ARG_HANDLE,
g_param_spec_pointer ("handle",
"GnomeVFSHandle", "Handle for GnomeVFS", G_PARAM_READWRITE));
gst_gnomevfssink_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstGnomeVFSSinkClass, 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 (GstGnomeVFSSinkClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK] =
g_signal_new ("erase-ask", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstGnomeVFSSinkClass, erase_ask), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
g_signal_new ("erase-ask", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstGnomeVFSSinkClass, erase_ask), NULL, NULL,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gobject_class->set_property = gst_gnomevfssink_set_property;
@ -191,14 +196,15 @@ gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass)
gstelement_class->change_state = gst_gnomevfssink_change_state;
/* gnome vfs engine init */
if (gnome_vfs_initialized() == FALSE)
gnome_vfs_init();
if (gnome_vfs_initialized () == FALSE)
gnome_vfs_init ();
}
static void
gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink)
static void
gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink)
{
GstPad *pad;
pad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (gnomevfssink), pad);
gst_pad_set_chain_function (pad, gst_gnomevfssink_chain);
@ -210,7 +216,8 @@ gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink)
}
static void
gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_gnomevfssink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstGnomeVFSSink *sink;
@ -237,16 +244,17 @@ gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *val
}
}
static void
gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void
gst_gnomevfssink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstGnomeVFSSink *sink;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_GNOMEVFSSINK (object));
sink = GST_GNOMEVFSSINK (object);
switch (prop_id) {
case ARG_LOCATION:
g_value_set_string (value, sink->filename);
@ -263,7 +271,7 @@ gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GP
}
static gboolean
gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
{
GnomeVFSResult result;
@ -271,22 +279,21 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
if (sink->filename) {
/* open the file */
result = gnome_vfs_create_uri(&(sink->handle), sink->uri,
GNOME_VFS_OPEN_WRITE, sink->erase,
GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE
| GNOME_VFS_PERM_GROUP_READ);
GST_DEBUG ("open: %s", gnome_vfs_result_to_string(result));
result = gnome_vfs_create_uri (&(sink->handle), sink->uri,
GNOME_VFS_OPEN_WRITE, sink->erase,
GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE
| GNOME_VFS_PERM_GROUP_READ);
GST_DEBUG ("open: %s", gnome_vfs_result_to_string (result));
if (result != GNOME_VFS_OK) {
if (sink->erase == FALSE) {
g_signal_emit (G_OBJECT (sink),
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK], 0,
sink->erase);
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK], 0, sink->erase);
}
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
(_("Could not open vfs file \"%s\" for writing."), sink->filename),
GST_ERROR_SYSTEM);
(_("Could not open vfs file \"%s\" for writing."), sink->filename),
GST_ERROR_SYSTEM);
return FALSE;
}
}
} else
g_return_val_if_fail (sink->handle != NULL, FALSE);
@ -296,7 +303,7 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
}
static void
gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
gst_gnomevfssink_close_file (GstGnomeVFSSink * sink)
{
GnomeVFSResult result;
@ -304,14 +311,14 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
if (sink->filename) {
/* close the file */
result = gnome_vfs_close(sink->handle);
result = gnome_vfs_close (sink->handle);
if (result != GNOME_VFS_OK)
GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
(_("Could not close vfs file \"%s\"."), sink->filename),
GST_ERROR_SYSTEM);
GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
(_("Could not close vfs file \"%s\"."), sink->filename),
GST_ERROR_SYSTEM);
}
GST_FLAG_UNSET (sink, GST_GNOMEVFSSINK_OPEN);
}
@ -322,8 +329,8 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
*
* take the buffer from the pad and write to file if it's open
*/
static void
gst_gnomevfssink_chain (GstPad *pad, GstData *_data)
static void
gst_gnomevfssink_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstGnomeVFSSink *sink;
@ -336,24 +343,26 @@ gst_gnomevfssink_chain (GstPad *pad, GstData *_data)
sink = GST_GNOMEVFSSINK (gst_pad_get_parent (pad));
if (GST_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN))
{
result = gnome_vfs_write(sink->handle, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE (buf), &bytes_written);
GST_DEBUG ("write: %s, written_bytes: %" G_GUINT64_FORMAT, gnome_vfs_result_to_string(result), bytes_written);
if (bytes_written < GST_BUFFER_SIZE (buf))
{
printf ("gnomevfssink : Warning : %d bytes should be written, only %" G_GUINT64_FORMAT " bytes written\n",
GST_BUFFER_SIZE (buf), bytes_written);
if (GST_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN)) {
result =
gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf), &bytes_written);
GST_DEBUG ("write: %s, written_bytes: %" G_GUINT64_FORMAT,
gnome_vfs_result_to_string (result), bytes_written);
if (bytes_written < GST_BUFFER_SIZE (buf)) {
printf ("gnomevfssink : Warning : %d bytes should be written, only %"
G_GUINT64_FORMAT " bytes written\n", GST_BUFFER_SIZE (buf),
bytes_written);
}
}
gst_buffer_unref (buf);
g_signal_emit (G_OBJECT (sink), gst_gnomevfssink_signals[SIGNAL_HANDOFF], 0,
sink);
sink);
}
static GstElementStateReturn
gst_gnomevfssink_change_state (GstElement *element)
gst_gnomevfssink_change_state (GstElement * element)
{
g_return_val_if_fail (GST_IS_GNOMEVFSSINK (element), GST_STATE_FAILURE);
@ -363,7 +372,7 @@ gst_gnomevfssink_change_state (GstElement *element)
} else {
if (!GST_FLAG_IS_SET (element, GST_GNOMEVFSSINK_OPEN)) {
if (!gst_gnomevfssink_open_file (GST_GNOMEVFSSINK (element)))
return GST_STATE_FAILURE;
return GST_STATE_FAILURE;
}
}
@ -372,4 +381,3 @@ gst_gnomevfssink_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -26,12 +26,12 @@
#include <ogg/ogg.h>
/* memcpy - if someone knows a way to get rid of it, please speak up
* note: the ogg docs even say you ned this... */
#include <string.h>
#include <string.h>
GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_debug);
#define GST_CAT_DEFAULT gst_ogg_demux_debug
#define GST_TYPE_OGG_DEMUX (gst_ogg_demux_get_type())
#define GST_TYPE_OGG_DEMUX (gst_ogg_demux_get_type())
#define GST_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_DEMUX, GstOggDemux))
#define GST_OGG_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_DEMUX, GstOggDemux))
#define GST_IS_OGG_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_DEMUX))
@ -40,7 +40,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_debug);
typedef struct _GstOggDemux GstOggDemux;
typedef struct _GstOggDemuxClass GstOggDemuxClass;
typedef enum {
typedef enum
{
/* just because you shouldn't make a valid enum value 0 */
GST_OGG_STATE_INAVLID,
/* just started, we need to decide if we should do setup */
@ -54,31 +55,35 @@ typedef enum {
} GstOggState;
/* all information needed for one ogg stream */
typedef struct {
GstPad * pad; /* reference for this pad is held by element we belong to */
typedef struct
{
GstPad *pad; /* reference for this pad is held by element we belong to */
gint serial;
ogg_stream_state stream;
guint64 offset; /* end offset of last buffer */
guint64 known_offset; /* last known offset */
gint64 packetno; /* number of next expected packet */
guint64 length; /* length of stream or 0 */
glong pages; /* number of pages in stream or 0 */
gint serial;
ogg_stream_state stream;
guint64 offset; /* end offset of last buffer */
guint64 known_offset; /* last known offset */
gint64 packetno; /* number of next expected packet */
guint flags;
guint64 length; /* length of stream or 0 */
glong pages; /* number of pages in stream or 0 */
guint flags;
} GstOggPad;
typedef enum {
GST_OGG_PAD_NEEDS_DISCONT = (1 << 0),
GST_OGG_PAD_NEEDS_FLUSH = (1 << 1)
typedef enum
{
GST_OGG_PAD_NEEDS_DISCONT = (1 << 0),
GST_OGG_PAD_NEEDS_FLUSH = (1 << 1)
}
GstOggPadFlags;
/* all information needed for one ogg chain (relevant for chained bitstreams) */
typedef struct {
GSList * pads; /* list of GstOggPad */
typedef struct
{
GSList *pads; /* list of GstOggPad */
} GstOggChain;
#define CURRENT_CHAIN(ogg) (&g_array_index ((ogg)->chains, GstOggChain, (ogg)->current_chain))
#define FOR_PAD_IN_CURRENT_CHAIN(ogg, _pad, ...) G_STMT_START{ \
GSList *_walk; \
@ -88,117 +93,108 @@ typedef struct {
} \
}G_STMT_END
typedef enum {
typedef enum
{
GST_OGG_FLAG_BOS = GST_ELEMENT_FLAG_LAST,
GST_OGG_FLAG_EOS,
GST_OGG_FLAG_WAIT_FOR_DISCONT
} GstOggFlag;
struct _GstOggDemux {
GstElement element;
struct _GstOggDemux
{
GstElement element;
/* pad */
GstPad * sinkpad;
GstPad *sinkpad;
/* state */
GstOggState state;
GArray * chains;
gint current_chain;
guint flags;
GstOggState state;
GArray *chains;
gint current_chain;
guint flags;
/* ogg stuff */
ogg_sync_state sync;
ogg_sync_state sync;
/* seeking */
GstOggPad * seek_pad;
guint64 seek_to;
GstOggPad *seek_pad;
guint64 seek_to;
};
struct _GstOggDemuxClass {
struct _GstOggDemuxClass
{
GstElementClass parent_class;
};
/* elementfactory information */
static GstElementDetails gst_ogg_demux_details = GST_ELEMENT_DETAILS (
"ogg demuxer",
"Codec/Demuxer",
"demux ogg streams (info about ogg: http://xiph.org)",
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
);
static GstElementDetails gst_ogg_demux_details =
GST_ELEMENT_DETAILS ("ogg demuxer",
"Codec/Demuxer",
"demux ogg streams (info about ogg: http://xiph.org)",
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
/* signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
/* FILL ME */
};
static GstStaticPadTemplate ogg_demux_src_template_factory =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY
);
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate ogg_demux_sink_template_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/ogg")
);
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/ogg")
);
static void gst_ogg_demux_finalize (GObject * object);
static void gst_ogg_demux_finalize (GObject * object);
static gboolean gst_ogg_demux_src_event (GstPad * pad,
GstEvent * event);
static const GstEventMask* gst_ogg_demux_get_event_masks (GstPad * pad);
static const GstQueryType* gst_ogg_demux_get_query_types (GstPad * pad);
static gboolean gst_ogg_demux_src_event (GstPad * pad, GstEvent * event);
static const GstEventMask *gst_ogg_demux_get_event_masks (GstPad * pad);
static const GstQueryType *gst_ogg_demux_get_query_types (GstPad * pad);
static gboolean gst_ogg_demux_src_query (GstPad * pad,
GstQueryType type,
GstFormat * format,
gint64 * value);
static gboolean gst_ogg_demux_src_query (GstPad * pad,
GstQueryType type, GstFormat * format, gint64 * value);
static void gst_ogg_demux_chain (GstPad * pad,
GstData * buffer);
static void gst_ogg_demux_chain (GstPad * pad, GstData * buffer);
static GstElementStateReturn gst_ogg_demux_change_state (GstElement * element);
static GstElementStateReturn gst_ogg_demux_change_state (GstElement * element);
static GstOggPad * gst_ogg_pad_new (GstOggDemux * ogg,
int serial_no);
static void gst_ogg_pad_remove (GstOggDemux * ogg,
GstOggPad * ogg_pad);
static void gst_ogg_pad_reset (GstOggDemux * ogg,
GstOggPad * pad);
static void gst_ogg_demux_push (GstOggDemux * ogg,
ogg_page * page);
static void gst_ogg_pad_push (GstOggDemux * ogg,
GstOggPad * ogg_pad);
static GstOggPad *gst_ogg_pad_new (GstOggDemux * ogg, int serial_no);
static void gst_ogg_pad_remove (GstOggDemux * ogg, GstOggPad * ogg_pad);
static void gst_ogg_pad_reset (GstOggDemux * ogg, GstOggPad * pad);
static void gst_ogg_demux_push (GstOggDemux * ogg, ogg_page * page);
static void gst_ogg_pad_push (GstOggDemux * ogg, GstOggPad * ogg_pad);
static GstCaps * gst_ogg_type_find (ogg_packet * packet);
static void gst_ogg_print (GstOggDemux * demux);
static GstCaps *gst_ogg_type_find (ogg_packet * packet);
static void gst_ogg_print (GstOggDemux * demux);
#define GST_OGG_SET_STATE(ogg, new_state) G_STMT_START{ \
GST_DEBUG_OBJECT (ogg, "setting state to %s", G_STRINGIFY (new_state)); \
ogg->state = new_state; \
}G_STMT_END
GST_BOILERPLATE (GstOggDemux, gst_ogg_demux, GstElement, GST_TYPE_ELEMENT)
static void
gst_ogg_demux_base_init (gpointer g_class)
static void gst_ogg_demux_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_ogg_demux_details);
gst_element_class_add_pad_template (element_class,
@ -207,33 +203,35 @@ gst_ogg_demux_base_init (gpointer g_class)
gst_static_pad_template_get (&ogg_demux_src_template_factory));
}
static void
gst_ogg_demux_class_init (GstOggDemuxClass *klass)
gst_ogg_demux_class_init (GstOggDemuxClass * klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gstelement_class->change_state = gst_ogg_demux_change_state;
gobject_class->finalize = gst_ogg_demux_finalize;
}
static void
gst_ogg_demux_init (GstOggDemux *ogg)
gst_ogg_demux_init (GstOggDemux * ogg)
{
/* create the sink pad */
ogg->sinkpad = gst_pad_new_from_template(
gst_static_pad_template_get (&ogg_demux_sink_template_factory), "sink");
ogg->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&ogg_demux_sink_template_factory), "sink");
gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad);
gst_pad_set_chain_function (ogg->sinkpad, GST_DEBUG_FUNCPTR (gst_ogg_demux_chain));
gst_pad_set_chain_function (ogg->sinkpad,
GST_DEBUG_FUNCPTR (gst_ogg_demux_chain));
/* initalize variables */
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_START);
ogg->chains = g_array_new (TRUE, TRUE, sizeof (GstOggChain));
ogg->current_chain = -1;
GST_FLAG_SET (ogg, GST_ELEMENT_EVENT_AWARE);
}
static void
gst_ogg_demux_finalize (GObject *object)
gst_ogg_demux_finalize (GObject * object)
{
GstOggDemux *ogg;
@ -245,18 +243,17 @@ gst_ogg_demux_finalize (GObject *object)
g_array_free (ogg->chains, TRUE);
}
static const GstEventMask*
gst_ogg_demux_get_event_masks (GstPad *pad)
static const GstEventMask *
gst_ogg_demux_get_event_masks (GstPad * pad)
{
static const GstEventMask gst_ogg_demux_src_event_masks[] = {
{ GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH },
{ 0, }
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
{0,}
};
return gst_ogg_demux_src_event_masks;
}
static const GstQueryType*
gst_ogg_demux_get_query_types (GstPad *pad)
static const GstQueryType *
gst_ogg_demux_get_query_types (GstPad * pad)
{
static const GstQueryType gst_ogg_demux_src_query_types[] = {
GST_QUERY_TOTAL,
@ -267,11 +264,11 @@ gst_ogg_demux_get_query_types (GstPad *pad)
}
static GstOggPad *
gst_ogg_get_pad_by_pad (GstOggDemux *ogg, GstPad *pad)
gst_ogg_get_pad_by_pad (GstOggDemux * ogg, GstPad * pad)
{
GSList *walk;
GstOggPad *cur;
if (ogg->current_chain == -1) {
GST_DEBUG_OBJECT (ogg, "no active chain, returning NULL");
return NULL;
@ -285,8 +282,8 @@ gst_ogg_get_pad_by_pad (GstOggDemux *ogg, GstPad *pad)
}
static gboolean
gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
gst_ogg_demux_src_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
gboolean res = FALSE;
GstOggDemux *ogg = GST_OGG_DEMUX (gst_pad_get_parent (pad));
@ -296,7 +293,7 @@ gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
return FALSE;
switch (type) {
case GST_QUERY_TOTAL: {
case GST_QUERY_TOTAL:{
if (*format == GST_FORMAT_DEFAULT) {
*value = cur->length;
res = TRUE;
@ -322,7 +319,7 @@ gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
* really slow.
*/
static gboolean
gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
gst_ogg_demux_src_event (GstPad * pad, GstEvent * event)
{
GstOggDemux *ogg;
GstOggPad *cur;
@ -331,12 +328,14 @@ gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
cur = gst_ogg_get_pad_by_pad (ogg, pad);
/* FIXME: optimize this so events from inactive chains work?
* in theory there shouldn't be an exisiting pad for inactive chains */
if (cur == NULL) goto error;
if (cur == NULL)
goto error;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
{
gint64 offset;
if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_DEFAULT)
goto error;
offset = GST_EVENT_SEEK_OFFSET (event);
@ -356,22 +355,23 @@ gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
goto error;
}
if (offset < cur->known_offset) {
GstEvent *restart = gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET | GST_EVENT_SEEK_FLAGS (event), 0);
GstEvent *restart =
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET |
GST_EVENT_SEEK_FLAGS (event), 0);
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad), restart))
goto error;
} else {
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
if (GST_PAD_IS_USABLE (pad->pad))
gst_pad_push (pad->pad, GST_DATA (gst_event_new (GST_EVENT_FLUSH)));
);
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad, if (GST_PAD_IS_USABLE (pad->pad))
gst_pad_push (pad->pad,
GST_DATA (gst_event_new (GST_EVENT_FLUSH))););
}
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_SEEK);
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;
);
GST_DEBUG_OBJECT (ogg, "initiating seeking to offset %"G_GUINT64_FORMAT, offset);
ogg->seek_pad = cur;
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;);
GST_DEBUG_OBJECT (ogg, "initiating seeking to offset %" G_GUINT64_FORMAT,
offset);
ogg->seek_pad = cur;
ogg->seek_to = offset;
gst_event_unref (event);
return TRUE;
@ -381,19 +381,19 @@ gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
}
g_assert_not_reached ();
error:
gst_event_unref (event);
return FALSE;
}
static void
gst_ogg_start_playing (GstOggDemux *ogg)
gst_ogg_start_playing (GstOggDemux * ogg)
{
GST_DEBUG_OBJECT (ogg, "got EOS in setup, changing to playback now");
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET, 0))) {
GST_ELEMENT_ERROR (ogg, CORE, SEEK, (NULL),
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET, 0))) {
GST_ELEMENT_ERROR (ogg, CORE, SEEK, (NULL),
("cannot seek to start after EOS"));
}
ogg->current_chain = 0;
@ -404,10 +404,10 @@ gst_ogg_start_playing (GstOggDemux *ogg)
}
static void
gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
gst_ogg_demux_handle_event (GstPad * pad, GstEvent * event)
{
GstOggDemux *ogg = GST_OGG_DEMUX (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
GST_DEBUG_OBJECT (ogg, "got a discont event");
@ -415,8 +415,7 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
gst_event_unref (event);
GST_FLAG_UNSET (ogg, GST_OGG_FLAG_WAIT_FOR_DISCONT);
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;
);
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;);
break;
case GST_EVENT_EOS:
if (ogg->state == GST_OGG_STATE_SETUP) {
@ -424,16 +423,19 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
} else {
guint i;
GSList *walk;
GST_DEBUG_OBJECT (ogg, "got EOS");
ogg->current_chain = -1;
for (i = 0; i < ogg->chains->len; i++) {
GstOggChain *chain = &g_array_index (ogg->chains, GstOggChain, i);
for (walk = chain->pads; walk; walk = g_slist_next (walk)) {
GstOggPad *pad = (GstOggPad *) walk->data;
if (pad->pad && GST_PAD_IS_USABLE (pad->pad)) {
gst_data_ref (GST_DATA (event));
gst_data_ref (GST_DATA (event));
gst_pad_push (pad->pad, GST_DATA (event));
}
}
}
}
gst_element_set_eos (GST_ELEMENT (ogg));
@ -449,15 +451,17 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
/* get the pad with the given serial in the current stream or NULL if none */
static GstOggPad *
gst_ogg_pad_get_in_current_chain (GstOggDemux *ogg, int serial)
gst_ogg_pad_get_in_current_chain (GstOggDemux * ogg, int serial)
{
GSList *walk;
if (ogg->current_chain == -1) return NULL;
if (ogg->current_chain == -1)
return NULL;
g_return_val_if_fail (ogg->current_chain < ogg->chains->len, NULL);
for (walk = CURRENT_CHAIN (ogg)->pads; walk; walk = g_slist_next (walk)) {
GstOggPad *pad = (GstOggPad *) walk->data;
if (pad->serial == serial)
return pad;
}
@ -465,7 +469,7 @@ gst_ogg_pad_get_in_current_chain (GstOggDemux *ogg, int serial)
}
static void
gst_ogg_add_chain (GstOggDemux *ogg)
gst_ogg_add_chain (GstOggDemux * ogg)
{
GST_LOG_OBJECT (ogg, "adding chain %u", ogg->chains->len);
ogg->current_chain = ogg->chains->len;
@ -473,7 +477,7 @@ gst_ogg_add_chain (GstOggDemux *ogg)
}
static void
gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
gst_ogg_demux_chain (GstPad * pad, GstData * buffer)
{
GstOggDemux *ogg;
guint8 *data;
@ -491,24 +495,25 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
if (GST_FLAG_IS_SET (ogg, GST_OGG_FLAG_WAIT_FOR_DISCONT)) {
GST_LOG_OBJECT (ogg, "waiting for discont event, discarding buffer");
gst_data_unref (buffer);
return;
return;
}
GST_LOG_OBJECT (ogg, "queueing buffer %p with offset %llu", buffer, GST_BUFFER_OFFSET (buffer));
data = (guint8 *) ogg_sync_buffer(&ogg->sync, GST_BUFFER_SIZE (buffer));
GST_LOG_OBJECT (ogg, "queueing buffer %p with offset %llu", buffer,
GST_BUFFER_OFFSET (buffer));
data = (guint8 *) ogg_sync_buffer (&ogg->sync, GST_BUFFER_SIZE (buffer));
memcpy (data, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
if (ogg_sync_wrote (&ogg->sync, GST_BUFFER_SIZE (buffer)) != 0) {
gst_data_unref (buffer);
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL), ("ogg_sync_wrote failed"));
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL),
("ogg_sync_wrote failed"));
return;
}
offset_end = GST_BUFFER_OFFSET_IS_VALID (buffer) ?
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) :
(guint64) -1;
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) : (guint64) - 1;
gst_data_unref (buffer);
while (pageout_ret != 0) {
ogg_page page;
pageout_ret = ogg_sync_pageout (&ogg->sync, &page);
switch (pageout_ret) {
case -1:
@ -519,7 +524,9 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
if (ogg->state == GST_OGG_STATE_SETUP) {
guint64 length;
GstFormat format = GST_FORMAT_BYTES;
if (!gst_pad_query (GST_PAD_PEER (ogg->sinkpad), GST_QUERY_TOTAL, &format, &length))
if (!gst_pad_query (GST_PAD_PEER (ogg->sinkpad), GST_QUERY_TOTAL,
&format, &length))
length = 0;
if (length <= offset_end) {
gst_ogg_start_playing (ogg);
@ -528,32 +535,42 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
}
break;
case 1:
GST_LOG_OBJECT (ogg, "processing ogg page (serial %d, packet %ld, granule pos %llu",
ogg_page_serialno (&page), ogg_page_pageno (&page), ogg_page_granulepos (&page));
GST_LOG_OBJECT (ogg,
"processing ogg page (serial %d, packet %ld, granule pos %llu",
ogg_page_serialno (&page), ogg_page_pageno (&page),
ogg_page_granulepos (&page));
switch (ogg->state) {
case GST_OGG_STATE_SETUP:
if (ogg_page_eos (&page)) {
GstOggPad *cur = gst_ogg_pad_get_in_current_chain (ogg, ogg_page_serialno (&page));
GstOggPad *cur = gst_ogg_pad_get_in_current_chain (ogg,
ogg_page_serialno (&page));
GST_FLAG_SET (ogg, GST_OGG_FLAG_EOS);
if (!cur) {
GST_ERROR_OBJECT (ogg, "unknown serial %d", ogg_page_serialno (&page));
GST_ERROR_OBJECT (ogg, "unknown serial %d",
ogg_page_serialno (&page));
} else {
cur->pages = ogg_page_pageno (&page);
cur->length = ogg_page_granulepos (&page);
}
} else {
if (GST_FLAG_IS_SET (ogg, GST_OGG_FLAG_EOS) && ogg_page_bos (&page)) {
if (GST_FLAG_IS_SET (ogg, GST_OGG_FLAG_EOS)
&& ogg_page_bos (&page)) {
gst_ogg_add_chain (ogg);
}
GST_FLAG_UNSET (ogg, GST_OGG_FLAG_EOS);
}
if (ogg_page_bos (&page)) {
if (gst_ogg_pad_get_in_current_chain (ogg, ogg_page_serialno (&page))) {
GST_ERROR_OBJECT (ogg, "multiple BOS page for serial %d (page %ld)",
if (gst_ogg_pad_get_in_current_chain (ogg,
ogg_page_serialno (&page))) {
GST_ERROR_OBJECT (ogg,
"multiple BOS page for serial %d (page %ld)",
ogg_page_serialno (&page), ogg_page_pageno (&page));
} else {
GstOggPad *pad = gst_ogg_pad_new (ogg, ogg_page_serialno (&page));
CURRENT_CHAIN (ogg)->pads = g_slist_prepend (CURRENT_CHAIN (ogg)->pads, pad);
GstOggPad *pad =
gst_ogg_pad_new (ogg, ogg_page_serialno (&page));
CURRENT_CHAIN (ogg)->pads =
g_slist_prepend (CURRENT_CHAIN (ogg)->pads, pad);
}
GST_FLAG_SET (ogg, GST_OGG_FLAG_BOS);
} else {
@ -562,12 +579,14 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
break;
case GST_OGG_STATE_START:
if (gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_END, 0))) {
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_END,
0))) {
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_SETUP);
GST_DEBUG_OBJECT (ogg, "stream can seek, try setup now");
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET, 0))) {
GST_ELEMENT_ERROR (ogg, CORE, SEEK, (NULL),
gst_event_new_seek (GST_FORMAT_BYTES |
GST_SEEK_METHOD_SET, 0))) {
GST_ELEMENT_ERROR (ogg, CORE, SEEK, (NULL),
("stream can seek to end, but not to start. Can't handle that."));
}
gst_ogg_add_chain (ogg);
@ -587,7 +606,8 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
}
break;
default:
GST_WARNING_OBJECT (ogg, "unknown return value %d from ogg_sync_pageout", pageout_ret);
GST_WARNING_OBJECT (ogg,
"unknown return value %d from ogg_sync_pageout", pageout_ret);
pageout_ret = 0;
break;
}
@ -596,42 +616,47 @@ out:
return;
}
static GstOggPad *
gst_ogg_pad_new (GstOggDemux *ogg, int serial)
gst_ogg_pad_new (GstOggDemux * ogg, int serial)
{
GstOggPad *ret = g_new0 (GstOggPad, 1);
GstTagList *list = gst_tag_list_new ();
ret->serial = serial;
if (ogg_stream_init (&ret->stream, serial) != 0) {
GST_ERROR_OBJECT (ogg, "Could not initialize ogg_stream struct for serial %d.", serial);
GST_ERROR_OBJECT (ogg,
"Could not initialize ogg_stream struct for serial %d.", serial);
g_free (ret);
return NULL;
}
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_SERIAL, serial, NULL);
gst_element_found_tags (GST_ELEMENT (ogg), list);
GST_LOG_OBJECT (ogg, "created new ogg src %p for stream with serial %d", ret, serial);
GST_LOG_OBJECT (ogg, "created new ogg src %p for stream with serial %d", ret,
serial);
return ret;
}
static void
gst_ogg_pad_remove (GstOggDemux *ogg, GstOggPad *pad)
gst_ogg_pad_remove (GstOggDemux * ogg, GstOggPad * pad)
{
if (pad->pad) {
/* FIXME:
* we do it in the EOS signal already - EOS handling needs to be better thought out.
* Correct way would be pushing EOS on eos page, but scheduler doesn't like that
if (GST_PAD_IS_USEABLE (pad->pad))
gst_pad_push (pad->pad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
*/
if (GST_PAD_IS_USEABLE (pad->pad))
gst_pad_push (pad->pad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
*/
gst_element_remove_pad (GST_ELEMENT (ogg), pad->pad);
}
if (ogg_stream_clear (&pad->stream) != 0)
GST_ERROR_OBJECT (ogg, "ogg_stream_clear (serial %d) did not return 0, ignoring this error", pad->serial);
GST_LOG_OBJECT (ogg, "free ogg src %p for stream with serial %d", pad, pad->serial);
GST_ERROR_OBJECT (ogg,
"ogg_stream_clear (serial %d) did not return 0, ignoring this error",
pad->serial);
GST_LOG_OBJECT (ogg, "free ogg src %p for stream with serial %d", pad,
pad->serial);
g_free (pad);
}
static void
gst_ogg_demux_push (GstOggDemux *ogg, ogg_page* page)
gst_ogg_demux_push (GstOggDemux * ogg, ogg_page * page)
{
GSList *walk;
GstOggPad *cur;
@ -648,42 +673,51 @@ br:
/* now we either have a stream (cur) or not */
if (ogg_page_bos (page)) {
if (cur) {
GST_DEBUG_OBJECT (ogg, "ogg page declared as BOS while stream %d already existed."
GST_DEBUG_OBJECT (ogg,
"ogg page declared as BOS while stream %d already existed."
"Possibly a seek happened.", cur->serial);
} else if (cur) {
GST_DEBUG_OBJECT (ogg, "reactivating deactivated stream %d.", cur->serial);
GST_DEBUG_OBJECT (ogg, "reactivating deactivated stream %d.",
cur->serial);
} else {
/* FIXME: monitor if we are still in creation stage? */
cur = gst_ogg_pad_new (ogg, ogg_page_serialno (page));
if (!cur) {
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL), ("Creating ogg_stream struct failed."));
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL),
("Creating ogg_stream struct failed."));
return;
}
if (ogg->current_chain == -1) {
/* add new one at the end */
gst_ogg_add_chain (ogg);
}
CURRENT_CHAIN (ogg)->pads = g_slist_prepend (CURRENT_CHAIN (ogg)->pads, cur);
CURRENT_CHAIN (ogg)->pads =
g_slist_prepend (CURRENT_CHAIN (ogg)->pads, cur);
}
}
if (cur == NULL) {
GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL), ("invalid ogg stream serial no"));
GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL),
("invalid ogg stream serial no"));
return;
}
if (ogg_stream_pagein (&cur->stream, page) != 0) {
GST_WARNING_OBJECT (ogg, "ogg stream choked on page (serial %d), resetting stream", cur->serial);
GST_WARNING_OBJECT (ogg,
"ogg stream choked on page (serial %d), resetting stream", cur->serial);
gst_ogg_pad_reset (ogg, cur);
return;
}
switch (ogg->state) {
case GST_OGG_STATE_SEEK:
GST_LOG_OBJECT (ogg, "in seek - offset now: %"G_GUINT64_FORMAT" (pad %d) - desired offset %"
G_GUINT64_FORMAT" (pad %d)", cur->known_offset, cur->serial,
ogg->seek_to, ogg->seek_pad->serial);
GST_LOG_OBJECT (ogg,
"in seek - offset now: %" G_GUINT64_FORMAT
" (pad %d) - desired offset %" G_GUINT64_FORMAT " (pad %d)",
cur->known_offset, cur->serial, ogg->seek_to, ogg->seek_pad->serial);
if (cur == ogg->seek_pad) {
if (ogg_page_granulepos (page) > ogg->seek_to) {
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_PLAY);
GST_DEBUG_OBJECT (ogg, "ended seek at offset %"G_GUINT64_FORMAT" (requested %"G_GUINT64_FORMAT, cur->known_offset, ogg->seek_to);
GST_DEBUG_OBJECT (ogg,
"ended seek at offset %" G_GUINT64_FORMAT " (requested %"
G_GUINT64_FORMAT, cur->known_offset, ogg->seek_to);
ogg->seek_pad = NULL;
ogg->seek_to = 0;
}
@ -701,17 +735,17 @@ br:
GST_DEBUG_OBJECT (ogg, "got EOS for stream with serial %d, sending EOS now",
cur->serial);
#if 0
/* Removing pads while PLAYING doesn't work with current schedulers */
/* remove from list, as this will never be called again */
/* Removing pads while PLAYING doesn't work with current schedulers */
/* remove from list, as this will never be called again */
gst_ogg_pad_remove (ogg, cur);
/* this is also not possible because sending EOS this way confuses the scheduler */
/* this is also not possible because sending EOS this way confuses the scheduler */
gst_pad_push (cur->pad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
#else
#endif
}
}
static void
gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
gst_ogg_pad_push (GstOggDemux * ogg, GstOggPad * pad)
{
ogg_packet packet;
int ret;
@ -725,26 +759,31 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
case -1:
gst_ogg_pad_reset (ogg, pad);
break;
case 1: {
case 1:{
/* only push data when playing, not during seek or similar */
if (ogg->state != GST_OGG_STATE_PLAY)
continue;
if (!pad->pad) {
GstCaps *caps = gst_ogg_type_find (&packet);
gchar *name = g_strdup_printf ("serial_%d", pad->serial);
if (caps == NULL) {
GST_WARNING_OBJECT (ogg, "couldn't find caps for stream with serial %d", pad->serial);
GST_WARNING_OBJECT (ogg,
"couldn't find caps for stream with serial %d", pad->serial);
caps = gst_caps_new_simple ("application/octet-stream", NULL);
}
pad->pad = gst_pad_new_from_template (
gst_static_pad_template_get (&ogg_demux_src_template_factory),
name);
pad->pad =
gst_pad_new_from_template (gst_static_pad_template_get
(&ogg_demux_src_template_factory), name);
g_free (name);
gst_pad_set_event_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event));
gst_pad_set_event_mask_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks));
gst_pad_set_query_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_query));
gst_pad_set_query_type_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_query_types));
gst_pad_set_event_function (pad->pad,
GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event));
gst_pad_set_event_mask_function (pad->pad,
GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks));
gst_pad_set_query_function (pad->pad,
GST_DEBUG_FUNCPTR (gst_ogg_demux_src_query));
gst_pad_set_query_type_function (pad->pad,
GST_DEBUG_FUNCPTR (gst_ogg_demux_get_query_types));
gst_pad_use_explicit_caps (pad->pad);
gst_pad_set_explicit_caps (pad->pad, caps);
gst_pad_set_active (pad->pad, TRUE);
@ -756,14 +795,18 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
pad->packetno = packet.packetno + 1;
}
/* send discont if needed */
if ((pad->flags & GST_OGG_PAD_NEEDS_DISCONT) && GST_PAD_IS_USABLE (pad->pad)) {
GstEvent *event = gst_event_new_discontinuous (FALSE,
GST_FORMAT_DEFAULT, pad->known_offset); /* FIXME: this might be wrong because we can only use the last known offset */
if ((pad->flags & GST_OGG_PAD_NEEDS_DISCONT)
&& GST_PAD_IS_USABLE (pad->pad)) {
GstEvent *event = gst_event_new_discontinuous (FALSE,
GST_FORMAT_DEFAULT, pad->known_offset); /* FIXME: this might be wrong because we can only use the last known offset */
gst_pad_push (pad->pad, GST_DATA (event));
pad->flags &= (~GST_OGG_PAD_NEEDS_DISCONT);
};
/* optimization: use a bufferpool containing the ogg packet? */
buf = gst_pad_alloc_buffer (pad->pad, GST_BUFFER_OFFSET_NONE, packet.bytes);
buf =
gst_pad_alloc_buffer (pad->pad, GST_BUFFER_OFFSET_NONE,
packet.bytes);
memcpy (buf->data, packet.packet, packet.bytes);
if (pad->offset != -1)
GST_BUFFER_OFFSET (buf) = pad->offset;
@ -775,14 +818,16 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
break;
}
default:
GST_ERROR_OBJECT (ogg, "invalid return value %d for ogg_stream_packetout, resetting stream", ret);
GST_ERROR_OBJECT (ogg,
"invalid return value %d for ogg_stream_packetout, resetting stream",
ret);
gst_ogg_pad_reset (ogg, pad);
break;
}
}
}
static void
gst_ogg_pad_reset (GstOggDemux *ogg, GstOggPad *pad)
gst_ogg_pad_reset (GstOggDemux * ogg, GstOggPad * pad)
{
ogg_stream_reset (&pad->stream);
pad->offset = GST_BUFFER_OFFSET_NONE;
@ -790,13 +835,14 @@ gst_ogg_pad_reset (GstOggDemux *ogg, GstOggPad *pad)
}
static void
gst_ogg_chains_clear (GstOggDemux *ogg)
gst_ogg_chains_clear (GstOggDemux * ogg)
{
gint i;
GSList *walk;
for (i = ogg->chains->len - 1; i >= 0; i--) {
GstOggChain *cur = &g_array_index (ogg->chains, GstOggChain, i);
for (walk = cur->pads; walk; walk = g_slist_next (walk)) {
gst_ogg_pad_remove (ogg, (GstOggPad *) walk->data);
}
@ -807,7 +853,7 @@ gst_ogg_chains_clear (GstOggDemux *ogg)
}
static GstElementStateReturn
gst_ogg_demux_change_state (GstElement *element)
gst_ogg_demux_change_state (GstElement * element)
{
GstOggDemux *ogg;
@ -846,16 +892,17 @@ gst_ogg_demux_change_state (GstElement *element)
* packet of an ogg stream must identify the stream. Therefore ogg can use a
* simplified approach at typefinding.
*/
typedef struct {
ogg_packet * packet;
guint best_probability;
GstCaps * caps;
typedef struct
{
ogg_packet *packet;
guint best_probability;
GstCaps *caps;
} OggTypeFind;
static guint8 *
ogg_find_peek (gpointer data, gint64 offset, guint size)
{
OggTypeFind *find = (OggTypeFind *) data;
if (offset + size <= find->packet->bytes) {
return ((guint8 *) find->packet->packet) + offset;
} else {
@ -863,40 +910,40 @@ ogg_find_peek (gpointer data, gint64 offset, guint size)
}
}
static void
ogg_find_suggest (gpointer data, guint probability, const GstCaps *caps)
ogg_find_suggest (gpointer data, guint probability, const GstCaps * caps)
{
OggTypeFind *find = (OggTypeFind *) data;
if (probability > find->best_probability) {
gst_caps_replace (&find->caps, gst_caps_copy (caps));
find->best_probability = probability;
}
}
static GstCaps *
gst_ogg_type_find (ogg_packet *packet)
gst_ogg_type_find (ogg_packet * packet)
{
GstTypeFind gst_find;
OggTypeFind find;
GList *walk, *type_list = NULL;
walk = type_list = gst_type_find_factory_get_list ();
find.packet = packet;
find.best_probability = 0;
find.caps = NULL;
gst_find.data = &find;
gst_find.peek = ogg_find_peek;
gst_find.suggest = ogg_find_suggest;
while (walk) {
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
gst_type_find_factory_call_function (factory, &gst_find);
if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
break;
walk = g_list_next (walk);
}
if (find.best_probability > 0)
return find.caps;
@ -904,38 +951,36 @@ gst_ogg_type_find (ogg_packet *packet)
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gst_ogg_demux_debug, "oggdemux", 0, "ogg demuxer");
return gst_element_register (plugin, "oggdemux", GST_RANK_PRIMARY, GST_TYPE_OGG_DEMUX);
return gst_element_register (plugin, "oggdemux", GST_RANK_PRIMARY,
GST_TYPE_OGG_DEMUX);
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"ogg",
"ogg stream manipulation (info about ogg: http://xiph.org)",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"ogg",
"ogg stream manipulation (info about ogg: http://xiph.org)",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
/* prints all info about the element */
static void
gst_ogg_print (GstOggDemux *ogg)
static void gst_ogg_print (GstOggDemux * ogg)
{
guint i;
GSList *walk;
for (i = 0; i < ogg->chains->len; i++) {
GstOggChain *chain = &g_array_index (ogg->chains, GstOggChain, i);
GST_INFO_OBJECT (ogg, "chain %d (%u streams):", i, g_slist_length (chain->pads));
GST_INFO_OBJECT (ogg, "chain %d (%u streams):", i,
g_slist_length (chain->pads));
for (walk = chain->pads; walk; walk = g_slist_next (walk)) {
GstOggPad *pad = (GstOggPad *) walk->data;
GST_INFO_OBJECT (ogg, " stream %d:", pad->serial);
GST_INFO_OBJECT (ogg, " length %"G_GUINT64_FORMAT, pad->length);
GST_INFO_OBJECT (ogg, " length %" G_GUINT64_FORMAT, pad->length);
GST_INFO_OBJECT (ogg, " pages %ld", pad->pages);
}
}

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,6 @@
#include <pango/pangoft2.h>
G_BEGIN_DECLS
#define GST_TYPE_TEXTOVERLAY (gst_textoverlay_get_type())
#define GST_TEXTOVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GST_TYPE_TEXTOVERLAY, GstTextOverlay))
@ -18,56 +17,60 @@ G_BEGIN_DECLS
GST_TYPE_TEXTOVERLAY))
#define GST_IS_TEXTOVERLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),\
GST_TYPE_TEXTOVERLAY))
typedef struct _GstTextOverlay GstTextOverlay;
typedef struct _GstTextOverlay GstTextOverlay;
typedef struct _GstTextOverlayClass GstTextOverlayClass;
typedef enum _GstTextOverlayVAlign GstTextOverlayVAlign;
typedef enum _GstTextOverlayHAlign GstTextOverlayHAlign;
enum _GstTextOverlayVAlign {
GST_TEXT_OVERLAY_VALIGN_BASELINE,
GST_TEXT_OVERLAY_VALIGN_BOTTOM,
GST_TEXT_OVERLAY_VALIGN_TOP,
enum _GstTextOverlayVAlign
{
GST_TEXT_OVERLAY_VALIGN_BASELINE,
GST_TEXT_OVERLAY_VALIGN_BOTTOM,
GST_TEXT_OVERLAY_VALIGN_TOP,
};
enum _GstTextOverlayHAlign {
GST_TEXT_OVERLAY_HALIGN_LEFT,
GST_TEXT_OVERLAY_HALIGN_CENTER,
GST_TEXT_OVERLAY_HALIGN_RIGHT,
enum _GstTextOverlayHAlign
{
GST_TEXT_OVERLAY_HALIGN_LEFT,
GST_TEXT_OVERLAY_HALIGN_CENTER,
GST_TEXT_OVERLAY_HALIGN_RIGHT,
};
struct _GstTextOverlay {
GstElement element;
struct _GstTextOverlay
{
GstElement element;
GstPad *video_sinkpad;
GstPad *text_sinkpad;
GstPad *srcpad;
gint width;
gint height;
PangoLayout *layout;
FT_Bitmap bitmap;
gint bitmap_buffer_size;
gint baseline_y;
GstTextOverlayVAlign valign;
GstTextOverlayHAlign halign;
gint x0;
gint y0;
GstBuffer *current_buffer;
GstBuffer *next_buffer;
gchar *default_text;
gboolean need_render;
GstPad *video_sinkpad;
GstPad *text_sinkpad;
GstPad *srcpad;
gint width;
gint height;
PangoLayout *layout;
FT_Bitmap bitmap;
gint bitmap_buffer_size;
gint baseline_y;
GstTextOverlayVAlign valign;
GstTextOverlayHAlign halign;
gint x0;
gint y0;
GstBuffer *current_buffer;
GstBuffer *next_buffer;
gchar *default_text;
gboolean need_render;
};
struct _GstTextOverlayClass {
GstElementClass parent_class;
struct _GstTextOverlayClass
{
GstElementClass parent_class;
PangoContext *pango_context;
PangoContext *pango_context;
};
GType gst_textoverlay_get_type(void) G_GNUC_CONST;
GType
gst_textoverlay_get_type (void)
G_GNUC_CONST;
G_END_DECLS
#endif /* __GST_TEXTOVERLAY_H */

View file

@ -45,25 +45,30 @@
/* GstTimeoverlay signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
/* FILL ME */
};
static void gst_timeoverlay_base_init (gpointer g_class);
static void gst_timeoverlay_class_init (gpointer g_class, gpointer class_data);
static void gst_timeoverlay_init (GTypeInstance *instance, gpointer g_class);
static void gst_timeoverlay_base_init (gpointer g_class);
static void gst_timeoverlay_class_init (gpointer g_class, gpointer class_data);
static void gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class);
static void gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_timeoverlay_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_timeoverlay_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_timeoverlay_planar411(GstVideofilter *videofilter, void *dest, void *src);
static void gst_timeoverlay_setup(GstVideofilter *videofilter);
static void gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest,
void *src);
static void gst_timeoverlay_setup (GstVideofilter * videofilter);
GType
gst_timeoverlay_get_type (void)
@ -72,44 +77,43 @@ gst_timeoverlay_get_type (void)
if (!timeoverlay_type) {
static const GTypeInfo timeoverlay_info = {
sizeof(GstTimeoverlayClass),
sizeof (GstTimeoverlayClass),
gst_timeoverlay_base_init,
NULL,
gst_timeoverlay_class_init,
NULL,
NULL,
sizeof(GstTimeoverlay),
sizeof (GstTimeoverlay),
0,
gst_timeoverlay_init,
};
timeoverlay_type = g_type_register_static(GST_TYPE_VIDEOFILTER,
"GstTimeoverlay", &timeoverlay_info, 0);
timeoverlay_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
"GstTimeoverlay", &timeoverlay_info, 0);
}
return timeoverlay_type;
}
static GstVideofilterFormat gst_timeoverlay_formats[] = {
{ "I420", 12, gst_timeoverlay_planar411, },
{"I420", 12, gst_timeoverlay_planar411,},
};
static void
gst_timeoverlay_base_init (gpointer g_class)
{
static GstElementDetails timeoverlay_details = GST_ELEMENT_DETAILS (
"Time Overlay",
"Filter/Editor/Video",
"Overlays the time on a video stream",
"David Schleef <ds@schleef.org>"
);
static GstElementDetails timeoverlay_details =
GST_ELEMENT_DETAILS ("Time Overlay",
"Filter/Editor/Video",
"Overlays the time on a video stream",
"David Schleef <ds@schleef.org>");
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
int i;
gst_element_class_set_details (element_class, &timeoverlay_details);
for(i=0;i<G_N_ELEMENTS(gst_timeoverlay_formats);i++){
gst_videofilter_class_add_format(videofilter_class,
for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) {
gst_videofilter_class_add_format (videofilter_class,
gst_timeoverlay_formats + i);
}
@ -126,10 +130,10 @@ gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
#if 0
g_object_class_install_property(gobject_class, ARG_METHOD,
g_param_spec_enum("method","method","method",
GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_METHOD,
g_param_spec_enum ("method", "method", "method",
GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
G_PARAM_READWRITE));
#endif
gobject_class->set_property = gst_timeoverlay_set_property;
@ -139,28 +143,29 @@ gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
}
static void
gst_timeoverlay_init (GTypeInstance *instance, gpointer g_class)
gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class)
{
GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance);
GstVideofilter *videofilter;
GST_DEBUG("gst_timeoverlay_init");
GST_DEBUG ("gst_timeoverlay_init");
videofilter = GST_VIDEOFILTER(timeoverlay);
videofilter = GST_VIDEOFILTER (timeoverlay);
/* do stuff */
}
static void
gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_timeoverlay_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstTimeoverlay *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_TIMEOVERLAY(object));
src = GST_TIMEOVERLAY(object);
g_return_if_fail (GST_IS_TIMEOVERLAY (object));
src = GST_TIMEOVERLAY (object);
GST_DEBUG("gst_timeoverlay_set_property");
GST_DEBUG ("gst_timeoverlay_set_property");
switch (prop_id) {
#if 0
case ARG_METHOD:
@ -173,13 +178,14 @@ gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *valu
}
static void
gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstTimeoverlay *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_TIMEOVERLAY(object));
src = GST_TIMEOVERLAY(object);
g_return_if_fail (GST_IS_TIMEOVERLAY (object));
src = GST_TIMEOVERLAY (object);
switch (prop_id) {
#if 0
@ -193,35 +199,29 @@ gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GPa
}
}
static gboolean plugin_init (GstPlugin *plugin)
static gboolean
plugin_init (GstPlugin * plugin)
{
if(!gst_library_load("gstvideofilter"))
if (!gst_library_load ("gstvideofilter"))
return FALSE;
return gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
GST_TYPE_TIMEOVERLAY);
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"timeoverlay",
"Time overlay",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"timeoverlay",
"Time overlay", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
static void gst_timeoverlay_setup(GstVideofilter *videofilter)
static void gst_timeoverlay_setup (GstVideofilter * videofilter)
{
GstTimeoverlay *timeoverlay;
PangoFontDescription *font_description;
PangoContext *context;
g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
timeoverlay = GST_TIMEOVERLAY(videofilter);
g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
timeoverlay = GST_TIMEOVERLAY (videofilter);
/* if any setup needs to be done, do it here */
@ -246,7 +246,8 @@ static void gst_timeoverlay_setup(GstVideofilter *videofilter)
}
static char *gst_timeoverlay_print_smpte_time(guint64 time)
static char *
gst_timeoverlay_print_smpte_time (guint64 time)
{
int hours;
int minutes;
@ -254,21 +255,21 @@ static char *gst_timeoverlay_print_smpte_time(guint64 time)
int ms;
double x;
x = rint((time + 500000)*1e-6);
x = rint ((time + 500000) * 1e-6);
hours = floor(x/(60*60*1000));
x -= hours*60*60*1000;
minutes = floor(x/(60*1000));
x -= minutes*60*1000;
seconds = floor(x/(1000));
x -= seconds*1000;
ms = rint(x);
hours = floor (x / (60 * 60 * 1000));
x -= hours * 60 * 60 * 1000;
minutes = floor (x / (60 * 1000));
x -= minutes * 60 * 1000;
seconds = floor (x / (1000));
x -= seconds * 1000;
ms = rint (x);
return g_strdup_printf("%02d:%02d:%02d.%03d",hours,minutes,seconds,ms);
return g_strdup_printf ("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
}
static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
void *dest, void *src)
static void
gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
{
GstTimeoverlay *timeoverlay;
int width;
@ -280,19 +281,21 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
char *string;
int i;
g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
timeoverlay = GST_TIMEOVERLAY(videofilter);
g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
timeoverlay = GST_TIMEOVERLAY (videofilter);
width = gst_videofilter_get_input_width(videofilter);
height = gst_videofilter_get_input_height(videofilter);
width = gst_videofilter_get_input_width (videofilter);
height = gst_videofilter_get_input_height (videofilter);
width = gst_videofilter_get_input_width(videofilter);
height = gst_videofilter_get_input_height(videofilter);
width = gst_videofilter_get_input_width (videofilter);
height = gst_videofilter_get_input_height (videofilter);
layout = pango_layout_new (timeoverlay->context);
string = gst_timeoverlay_print_smpte_time(GST_BUFFER_TIMESTAMP(videofilter->in_buf));
pango_layout_set_text (layout, string, strlen(string));
g_free(string);
string =
gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (videofilter->
in_buf));
pango_layout_set_text (layout, string, strlen (string));
g_free (string);
pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
pango_layout_set_width (layout, -1);
@ -303,15 +306,15 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
//hheight = 20;
memcpy(dest, src, videofilter->from_buf_size);
memcpy (dest, src, videofilter->from_buf_size);
for(i=0;i<b_height;i++){
memset(dest + i*width, 0, b_width);
for (i = 0; i < b_height; i++) {
memset (dest + i * width, 0, b_width);
}
for(i=0;i<b_height/2;i++){
memset(dest + width*height + i*(width/2), 128, b_width/2);
memset(dest + width*height + (width/2)*(height/2) + i*(width/2), 128,
b_width/2);
for (i = 0; i < b_height / 2; i++) {
memset (dest + width * height + i * (width / 2), 128, b_width / 2);
memset (dest + width * height + (width / 2) * (height / 2) +
i * (width / 2), 128, b_width / 2);
}
bitmap.rows = b_height;
bitmap.width = b_width;
@ -322,4 +325,3 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
pango_ft2_render_layout (&bitmap, layout, 0, 0);
}

View file

@ -29,7 +29,6 @@
G_BEGIN_DECLS
#define GST_TYPE_TIMEOVERLAY \
(gst_timeoverlay_get_type())
#define GST_TIMEOVERLAY(obj) \
@ -40,11 +39,11 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIMEOVERLAY))
#define GST_IS_TIMEOVERLAY_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIMEOVERLAY))
typedef struct _GstTimeoverlay GstTimeoverlay;
typedef struct _GstTimeoverlayClass GstTimeoverlayClass;
struct _GstTimeoverlay {
struct _GstTimeoverlay
{
GstVideofilter videofilter;
PangoFontDescription *font_description;
@ -52,13 +51,12 @@ struct _GstTimeoverlay {
};
struct _GstTimeoverlayClass {
struct _GstTimeoverlayClass
{
GstVideofilterClass parent_class;
};
GType gst_timeoverlay_get_type(void);
GType gst_timeoverlay_get_type (void);
G_END_DECLS
#endif /* __GST_TIMEOVERLAY_H__ */

View file

@ -41,21 +41,23 @@
typedef struct _GstTheoraDec GstTheoraDec;
typedef struct _GstTheoraDecClass GstTheoraDecClass;
struct _GstTheoraDec {
GstElement element;
struct _GstTheoraDec
{
GstElement element;
GstPad * sinkpad;
GstPad * srcpad;
GstPad *sinkpad;
GstPad *srcpad;
theora_state state;
theora_info info;
theora_comment comment;
guint packetno;
guint64 granulepos;
theora_state state;
theora_info info;
theora_comment comment;
guint packetno;
guint64 granulepos;
};
struct _GstTheoraDecClass {
struct _GstTheoraDecClass
{
GstElementClass parent_class;
};
@ -67,49 +69,37 @@ static GstElementDetails theora_dec_details = {
};
static GstStaticPadTemplate theora_dec_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"video/x-raw-yuv, "
"format = (fourcc) I420, "
"framerate = (double) [0, MAX], "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ]"
)
);
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv, "
"format = (fourcc) I420, "
"framerate = (double) [0, MAX], "
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
);
static GstStaticPadTemplate theora_dec_sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"video/x-theora"
)
);
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-theora")
);
GST_BOILERPLATE (GstTheoraDec, gst_theora_dec, GstElement, GST_TYPE_ELEMENT);
static void theora_dec_chain (GstPad * pad,
GstData * data);
static GstElementStateReturn
theora_dec_change_state (GstElement * element);
static gboolean theora_dec_src_event (GstPad * pad,
GstEvent * event);
static gboolean theora_dec_src_query (GstPad * pad,
GstQueryType query,
GstFormat * format,
gint64 * value);
static void theora_dec_chain (GstPad * pad, GstData * data);
static GstElementStateReturn theora_dec_change_state (GstElement * element);
static gboolean theora_dec_src_event (GstPad * pad, GstEvent * event);
static gboolean theora_dec_src_query (GstPad * pad,
GstQueryType query, GstFormat * format, gint64 * value);
static void
gst_theora_dec_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class,
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&theora_dec_src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&theora_dec_sink_factory));
@ -117,7 +107,7 @@ gst_theora_dec_base_init (gpointer g_class)
}
static void
gst_theora_dec_class_init (GstTheoraDecClass *klass)
gst_theora_dec_class_init (GstTheoraDecClass * klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
@ -125,15 +115,17 @@ gst_theora_dec_class_init (GstTheoraDecClass *klass)
}
static void
gst_theora_dec_init (GstTheoraDec *dec)
gst_theora_dec_init (GstTheoraDec * dec)
{
dec->sinkpad = gst_pad_new_from_template(
gst_static_pad_template_get (&theora_dec_sink_factory), "sink");
dec->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&theora_dec_sink_factory), "sink");
gst_pad_set_chain_function (dec->sinkpad, theora_dec_chain);
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
dec->srcpad = gst_pad_new_from_template(
gst_static_pad_template_get (&theora_dec_src_factory), "src");
dec->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&theora_dec_src_factory), "src");
gst_pad_use_explicit_caps (dec->srcpad);
gst_pad_set_event_function (dec->srcpad, theora_dec_src_event);
gst_pad_set_query_function (dec->srcpad, theora_dec_src_query);
@ -143,24 +135,28 @@ gst_theora_dec_init (GstTheoraDec *dec)
}
/* FIXME: copy from libtheora, theora should somehow make this available for seeking */
static int
_theora_ilog(unsigned int v){
int ret=0;
while(v){
static int
_theora_ilog (unsigned int v)
{
int ret = 0;
while (v) {
ret++;
v>>=1;
v >>= 1;
}
return(ret);
return (ret);
}
static gboolean
theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, guint64 *to)
theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
guint64 * to)
{
guint64 framecount;
guint ilog = _theora_ilog (dec->info.keyframe_frequency_force);
if (dec->packetno < 1) return FALSE;
if (dec->packetno < 1)
return FALSE;
/* granulepos is last ilog bits for counting pframes since last iframe and
* bits in front of that for the framenumber of the last iframe. */
framecount = from >> ilog;
@ -168,7 +164,9 @@ theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, g
switch (format) {
case GST_FORMAT_TIME:
*to = framecount = from * GST_SECOND * dec->info.fps_denominator / dec->info.fps_numerator;
*to = framecount =
from * GST_SECOND * dec->info.fps_denominator /
dec->info.fps_numerator;
break;
case GST_FORMAT_DEFAULT:
*to = framecount;
@ -184,15 +182,19 @@ theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, g
/* FIXME: we can only seek to keyframes... */
static gboolean
theora_dec_to_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, guint64 *to)
theora_dec_to_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
guint64 * to)
{
guint64 framecount;
if (dec->packetno < 1) return FALSE;
if (dec->packetno < 1)
return FALSE;
switch (format) {
case GST_FORMAT_TIME:
framecount = from * dec->info.fps_numerator / (GST_SECOND * dec->info.fps_denominator);
framecount =
from * dec->info.fps_numerator / (GST_SECOND *
dec->info.fps_denominator);
break;
case GST_FORMAT_DEFAULT:
framecount = from;
@ -208,25 +210,28 @@ theora_dec_to_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, gui
}
static gboolean
theora_dec_src_query (GstPad *pad, GstQueryType query, GstFormat *format, gint64 *value)
theora_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format,
gint64 * value)
{
gint64 granulepos;
GstTheoraDec *dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
GstFormat my_format = GST_FORMAT_DEFAULT;
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, &granulepos))
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
&granulepos))
return FALSE;
if (!theora_dec_from_granulepos (dec, *format, granulepos, value))
return FALSE;
GST_LOG_OBJECT (dec, "query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
GST_LOG_OBJECT (dec,
"query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
query, granulepos, *value, *format);
return TRUE;
}
static gboolean
theora_dec_src_event (GstPad *pad, GstEvent *event)
theora_dec_src_event (GstPad * pad, GstEvent * event)
{
gboolean res = TRUE;
GstTheoraDec *dec;
@ -234,15 +239,17 @@ theora_dec_src_event (GstPad *pad, GstEvent *event)
dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK: {
case GST_EVENT_SEEK:{
guint64 value;
res = theora_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
GST_EVENT_SEEK_OFFSET (event), &value);
res = theora_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
GST_EVENT_SEEK_OFFSET (event), &value);
if (res) {
GstEvent *real_seek = gst_event_new_seek (
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) | GST_FORMAT_DEFAULT,
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
GST_FORMAT_DEFAULT,
value);
res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek);
}
gst_event_unref (event);
@ -257,36 +264,46 @@ theora_dec_src_event (GstPad *pad, GstEvent *event)
}
static void
theora_dec_event (GstTheoraDec *dec, GstEvent *event)
theora_dec_event (GstTheoraDec * dec, GstEvent * event)
{
guint64 value, time, bytes;
GST_LOG_OBJECT (dec, "handling event");
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)) {
dec->granulepos = value;
GST_DEBUG_OBJECT (dec, "setting granuleposition to %"G_GUINT64_FORMAT" after discont\n", value);
GST_DEBUG_OBJECT (dec,
"setting granuleposition to %" G_GUINT64_FORMAT " after discont\n",
value);
} else {
GST_WARNING_OBJECT (dec,
GST_WARNING_OBJECT (dec,
"discont event didn't include offset, we might set it wrong now");
}
if (dec->packetno < 3) {
if (dec->granulepos != 0)
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("can't handle discont before parsing first 3 packets"));
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
("can't handle discont before parsing first 3 packets"));
dec->packetno = 0;
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, (guint64) 0,
GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE,
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
} else {
dec->packetno = 3;
/* if one of them works, all of them work */
if (theora_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos, &time) &&
theora_dec_from_granulepos (dec, GST_FORMAT_DEFAULT, dec->granulepos, &value) &&
theora_dec_from_granulepos (dec, GST_FORMAT_BYTES, dec->granulepos, &bytes)) {
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes, 0)));
if (theora_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
&time)
&& theora_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
dec->granulepos, &value)
&& theora_dec_from_granulepos (dec, GST_FORMAT_BYTES,
dec->granulepos, &bytes)) {
gst_pad_push (dec->srcpad,
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
0)));
} else {
GST_ERROR_OBJECT (dec, "failed to parse data for DISCONT event, not sending any");
GST_ERROR_OBJECT (dec,
"failed to parse data for DISCONT event, not sending any");
}
}
break;
@ -297,7 +314,7 @@ theora_dec_event (GstTheoraDec *dec, GstEvent *event)
}
static void
theora_dec_chain (GstPad *pad, GstData *data)
theora_dec_chain (GstPad * pad, GstData * data)
{
GstBuffer *buf;
GstTheoraDec *dec;
@ -314,21 +331,24 @@ theora_dec_chain (GstPad *pad, GstData *data)
packet.packet = GST_BUFFER_DATA (buf);
packet.bytes = GST_BUFFER_SIZE (buf);
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
packet.packetno = dec->packetno ++;
packet.packetno = dec->packetno++;
packet.b_o_s = (packet.packetno == 0) ? 1 : 0;
packet.e_o_s = 0;
/* switch depending on packet type */
if (packet.packet[0] & 0x80) {
/* header packet */
if (theora_decode_header (&dec->info, &dec->comment, &packet)) {
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
(NULL), ("couldn't read header packet"));
gst_data_unref (data);
return;
}
if (packet.packetno == 1) {
gchar *encoder = NULL;
GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf, "\201theora", 7, &encoder);
GstTagList *list =
gst_tag_list_from_vorbiscomment_buffer (buf, "\201theora", 7,
&encoder);
if (!list) {
GST_ERROR_OBJECT (dec, "failed to parse tags");
list = gst_tag_list_new ();
@ -343,14 +363,15 @@ theora_dec_chain (GstPad *pad, GstData *data)
gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, 0, list);
} else if (packet.packetno == 2) {
GstCaps *caps;
/* done */
theora_decode_init (&dec->state, &dec->info);
caps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
"framerate", G_TYPE_DOUBLE, ((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
"width", G_TYPE_INT, dec->info.width,
"height", G_TYPE_INT, dec->info.height,
NULL);
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
"framerate", G_TYPE_DOUBLE,
((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
"width", G_TYPE_INT, dec->info.width, "height", G_TYPE_INT,
dec->info.height, NULL);
gst_pad_set_explicit_caps (dec->srcpad, caps);
gst_caps_free (caps);
}
@ -359,44 +380,49 @@ theora_dec_chain (GstPad *pad, GstData *data)
GstBuffer *out;
guint8 *y, *v, *u;
guint i;
/* normal data packet */
#if 0
{
GTimeVal tv;
guint64 time;
g_get_current_time (&tv);
time = GST_TIMEVAL_TO_TIME (tv);
#endif
if (theora_decode_packetin (&dec->state, &packet)) {
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
(NULL), ("theora decoder did not read data packet"));
gst_data_unref (data);
return;
}
if (theora_decode_YUVout (&dec->state, &yuv) < 0) {
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
(NULL), ("couldn't read out YUV image"));
gst_data_unref (data);
return;
}
g_return_if_fail (yuv.y_width == dec->info.width);
g_return_if_fail (yuv.y_height == dec->info.height);
out = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
yuv.y_width * yuv.y_height * 12 / 8);
y = GST_BUFFER_DATA (out);
u = y + yuv.y_width * yuv.y_height;
v = u + yuv.y_width * yuv.y_height / 4;
for (i = 0; i < yuv.y_height; i++) {
memcpy (y + i * yuv.y_width, yuv.y + i * yuv.y_stride, yuv.y_width);
}
for (i = 0; i < yuv.y_height / 2; i++) {
memcpy (u + i * yuv.uv_width, yuv.u + i * yuv.uv_stride, yuv.uv_width);
memcpy (v + i * yuv.uv_width, yuv.v + i * yuv.uv_stride, yuv.uv_width);
}
GST_BUFFER_OFFSET (out) = dec->packetno - 4;
GST_BUFFER_OFFSET_END (out) = dec->packetno - 3;
GST_BUFFER_DURATION (out) = GST_SECOND * ((gdouble) dec->info.fps_denominator) / dec->info.fps_numerator;
GST_BUFFER_TIMESTAMP (out) = GST_BUFFER_OFFSET (out) * GST_BUFFER_DURATION (out);
if (theora_decode_packetin (&dec->state, &packet)) {
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
(NULL), ("theora decoder did not read data packet"));
gst_data_unref (data);
return;
}
if (theora_decode_YUVout (&dec->state, &yuv) < 0) {
GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
(NULL), ("couldn't read out YUV image"));
gst_data_unref (data);
return;
}
g_return_if_fail (yuv.y_width == dec->info.width);
g_return_if_fail (yuv.y_height == dec->info.height);
out = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
yuv.y_width * yuv.y_height * 12 / 8);
y = GST_BUFFER_DATA (out);
u = y + yuv.y_width * yuv.y_height;
v = u + yuv.y_width * yuv.y_height / 4;
for (i = 0; i < yuv.y_height; i++) {
memcpy (y + i * yuv.y_width, yuv.y + i * yuv.y_stride, yuv.y_width);
}
for (i = 0; i < yuv.y_height / 2; i++) {
memcpy (u + i * yuv.uv_width, yuv.u + i * yuv.uv_stride, yuv.uv_width);
memcpy (v + i * yuv.uv_width, yuv.v + i * yuv.uv_stride, yuv.uv_width);
}
GST_BUFFER_OFFSET (out) = dec->packetno - 4;
GST_BUFFER_OFFSET_END (out) = dec->packetno - 3;
GST_BUFFER_DURATION (out) =
GST_SECOND * ((gdouble) dec->info.fps_denominator) /
dec->info.fps_numerator;
GST_BUFFER_TIMESTAMP (out) =
GST_BUFFER_OFFSET (out) * GST_BUFFER_DURATION (out);
#if 0
g_get_current_time (&tv);
time = GST_TIMEVAL_TO_TIME (tv) - time;
@ -410,7 +436,7 @@ theora_dec_chain (GstPad *pad, GstData *data)
}
static GstElementStateReturn
theora_dec_change_state (GstElement *element)
theora_dec_change_state (GstElement * element)
{
GstTheoraDec *dec = GST_THEORA_DEC (element);
@ -443,24 +469,20 @@ theora_dec_change_state (GstElement *element)
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
if (!gst_library_load ("gsttags"))
return FALSE;
if (!gst_element_register (plugin, "theoradec", GST_RANK_SECONDARY, gst_theora_dec_get_type ()))
if (!gst_element_register (plugin, "theoradec", GST_RANK_SECONDARY,
gst_theora_dec_get_type ()))
return FALSE;
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gsttheora",
"Theora plugin library",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gsttheora",
"Theora plugin library",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)

View file

@ -27,7 +27,7 @@
GST_DEBUG_CATEGORY (vorbisdec_debug);
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
if (!gst_library_load ("gstbytestream"))
return FALSE;
@ -35,23 +35,21 @@ plugin_init (GstPlugin *plugin)
if (!gst_library_load ("gsttags"))
return FALSE;
if (!gst_element_register (plugin, "vorbisenc", GST_RANK_NONE, GST_TYPE_VORBISENC))
if (!gst_element_register (plugin, "vorbisenc", GST_RANK_NONE,
GST_TYPE_VORBISENC))
return FALSE;
if (!gst_element_register (plugin, "vorbisdec", GST_RANK_PRIMARY, gst_vorbis_dec_get_type ()))
if (!gst_element_register (plugin, "vorbisdec", GST_RANK_PRIMARY,
gst_vorbis_dec_get_type ()))
return FALSE;
GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "vorbisdec", 0, "vorbis decoding element");
GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "vorbisdec", 0,
"vorbis decoding element");
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"vorbis",
"Vorbis plugin library",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"vorbis",
"Vorbis plugin library",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)

View file

@ -36,68 +36,56 @@ static GstElementDetails vorbis_dec_details = {
};
/* Filter signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0
};
static GstStaticPadTemplate vorbis_dec_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-raw-float, "
"rate = (int) [ 11025, 48000 ], "
"channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, "
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-float, "
"rate = (int) [ 11025, 48000 ], "
"channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, "
/* no ifdef in macros, please
#ifdef GST_VORBIS_DEC_SEQUENTIAL
"layout = \"sequential\", "
#endif
*/
"width = (int) 32, "
"buffer-frames = (int) 0"
)
);
"width = (int) 32, " "buffer-frames = (int) 0")
);
static GstStaticPadTemplate vorbis_dec_sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-vorbis"
)
);
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-vorbis")
);
GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
static void vorbis_dec_chain (GstPad * pad,
GstData * data);
static GstElementStateReturn
vorbis_dec_change_state (GstElement * element);
static const GstFormat*
vorbis_dec_get_formats (GstPad *pad);
static gboolean vorbis_dec_src_event (GstPad * pad,
GstEvent * event);
static gboolean vorbis_dec_src_query (GstPad * pad,
GstQueryType query,
GstFormat * format,
gint64 * value);
static void vorbis_dec_chain (GstPad * pad, GstData * data);
static GstElementStateReturn vorbis_dec_change_state (GstElement * element);
static const GstFormat *vorbis_dec_get_formats (GstPad * pad);
static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
static gboolean vorbis_dec_src_query (GstPad * pad,
GstQueryType query, GstFormat * format, gint64 * value);
static void
gst_vorbis_dec_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class,
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&vorbis_dec_src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&vorbis_dec_sink_factory));
@ -105,7 +93,7 @@ gst_vorbis_dec_base_init (gpointer g_class)
}
static void
gst_vorbis_dec_class_init (GstVorbisDecClass *klass)
gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
@ -113,7 +101,7 @@ gst_vorbis_dec_class_init (GstVorbisDecClass *klass)
}
static const GstFormat *
vorbis_dec_get_formats (GstPad *pad)
vorbis_dec_get_formats (GstPad * pad)
{
static const GstFormat src_formats[] = {
GST_FORMAT_BYTES,
@ -130,7 +118,7 @@ vorbis_dec_get_formats (GstPad *pad)
}
static GstPadLinkReturn
vorbis_dec_link (GstPad *pad, const GstCaps *caps)
vorbis_dec_link (GstPad * pad, const GstCaps * caps)
{
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
@ -141,7 +129,7 @@ vorbis_dec_link (GstPad *pad, const GstCaps *caps)
}
static GstCaps *
vorbis_dec_getcaps (GstPad *pad)
vorbis_dec_getcaps (GstPad * pad)
{
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
@ -149,28 +137,28 @@ vorbis_dec_getcaps (GstPad *pad)
return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
return gst_caps_new_simple ("audio/x-raw-float",
"rate", G_TYPE_INT, dec->vi.rate,
"channels", G_TYPE_INT, dec->vi.channels,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"width", G_TYPE_INT, 32,
"rate", G_TYPE_INT, dec->vi.rate,
"channels", G_TYPE_INT, dec->vi.channels,
"endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
#ifdef GST_VORBIS_DEC_SEQUENTIAL
"layout", G_TYPE_STRING, "sequential",
"layout", G_TYPE_STRING, "sequential",
#endif
"buffer-frames", G_TYPE_INT, 0,
NULL);
"buffer-frames", G_TYPE_INT, 0, NULL);
}
static void
gst_vorbis_dec_init (GstVorbisDec *dec)
gst_vorbis_dec_init (GstVorbisDec * dec)
{
dec->sinkpad = gst_pad_new_from_template(
gst_static_pad_template_get (&vorbis_dec_sink_factory), "sink");
dec->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&vorbis_dec_sink_factory), "sink");
gst_pad_set_chain_function (dec->sinkpad, vorbis_dec_chain);
gst_pad_set_formats_function (dec->sinkpad, vorbis_dec_get_formats);
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
dec->srcpad = gst_pad_new_from_template(
gst_static_pad_template_get (&vorbis_dec_src_factory), "src");
dec->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&vorbis_dec_src_factory), "src");
gst_pad_set_link_function (dec->srcpad, vorbis_dec_link);
gst_pad_set_getcaps_function (dec->srcpad, vorbis_dec_getcaps);
gst_pad_set_event_function (dec->srcpad, vorbis_dec_src_event);
@ -183,10 +171,12 @@ gst_vorbis_dec_init (GstVorbisDec *dec)
/* FIXME: plug this to the pad convert function */
static gboolean
vorbis_dec_to_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, guint64 *to)
vorbis_dec_to_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
guint64 * to)
{
if (dec->packetno < 1) return FALSE;
if (dec->packetno < 1)
return FALSE;
switch (format) {
case GST_FORMAT_TIME:
*to = from * dec->vi.rate / GST_SECOND;
@ -203,10 +193,12 @@ vorbis_dec_to_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, gui
}
static gboolean
vorbis_dec_from_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, guint64 *to)
vorbis_dec_from_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
guint64 * to)
{
if (dec->packetno < 1) return FALSE;
if (dec->packetno < 1)
return FALSE;
switch (format) {
case GST_FORMAT_TIME:
*to = from * GST_SECOND / dec->vi.rate;
@ -224,39 +216,44 @@ vorbis_dec_from_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, g
static gboolean
vorbis_dec_src_query (GstPad *pad, GstQueryType query, GstFormat *format, gint64 *value)
vorbis_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format,
gint64 * value)
{
gint64 granulepos;
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
GstFormat my_format = GST_FORMAT_DEFAULT;
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, &granulepos))
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
&granulepos))
return FALSE;
if (!vorbis_dec_from_granulepos (dec, *format, granulepos, value))
return FALSE;
GST_LOG_OBJECT (dec, "query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
GST_LOG_OBJECT (dec,
"query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
query, granulepos, *value, *format);
return TRUE;
}
static gboolean
vorbis_dec_src_event (GstPad *pad, GstEvent *event)
vorbis_dec_src_event (GstPad * pad, GstEvent * event)
{
gboolean res = TRUE;
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK: {
case GST_EVENT_SEEK:{
guint64 value;
res = vorbis_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
GST_EVENT_SEEK_OFFSET (event), &value);
res = vorbis_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
GST_EVENT_SEEK_OFFSET (event), &value);
if (res) {
GstEvent *real_seek = gst_event_new_seek (
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) | GST_FORMAT_DEFAULT,
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
GST_FORMAT_DEFAULT,
value);
res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek);
}
gst_event_unref (event);
@ -270,36 +267,46 @@ vorbis_dec_src_event (GstPad *pad, GstEvent *event)
return res;
}
static void
vorbis_dec_event (GstVorbisDec *dec, GstEvent *event)
vorbis_dec_event (GstVorbisDec * dec, GstEvent * event)
{
guint64 value, time, bytes;
GST_LOG_OBJECT (dec, "handling event");
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)) {
dec->granulepos = value;
GST_DEBUG_OBJECT (dec, "setting granuleposition to %"G_GUINT64_FORMAT" after discont", value);
GST_DEBUG_OBJECT (dec,
"setting granuleposition to %" G_GUINT64_FORMAT " after discont",
value);
} else {
GST_WARNING_OBJECT (dec,
GST_WARNING_OBJECT (dec,
"discont event didn't include offset, we might set it wrong now");
}
if (dec->packetno < 3) {
if (dec->granulepos != 0)
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("can't handle discont before parsing first 3 packets"));
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
("can't handle discont before parsing first 3 packets"));
dec->packetno = 0;
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, (guint64) 0,
GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE,
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
} else {
dec->packetno = 3;
/* if one of them works, all of them work */
if (vorbis_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos, &time) &&
vorbis_dec_from_granulepos (dec, GST_FORMAT_DEFAULT, dec->granulepos, &value) &&
vorbis_dec_from_granulepos (dec, GST_FORMAT_BYTES, dec->granulepos, &bytes)) {
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes, 0)));
if (vorbis_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
&time)
&& vorbis_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
dec->granulepos, &value)
&& vorbis_dec_from_granulepos (dec, GST_FORMAT_BYTES,
dec->granulepos, &bytes)) {
gst_pad_push (dec->srcpad,
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
0)));
} else {
GST_ERROR_OBJECT (dec, "failed to parse data for DISCONT event, not sending any");
GST_ERROR_OBJECT (dec,
"failed to parse data for DISCONT event, not sending any");
}
#ifdef HAVE_VORBIS_SYNTHESIS_RESTART
vorbis_synthesis_restart (&dec->vd);
@ -313,11 +320,11 @@ vorbis_dec_event (GstVorbisDec *dec, GstEvent *event)
}
static void
vorbis_dec_chain (GstPad *pad, GstData *data)
vorbis_dec_chain (GstPad * pad, GstData * data)
{
GstBuffer *buf;
GstVorbisDec *vd;
ogg_packet packet; /* lol */
ogg_packet packet; /* lol */
vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
if (GST_IS_EVENT (data)) {
@ -330,26 +337,30 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
packet.packet = GST_BUFFER_DATA (buf);
packet.bytes = GST_BUFFER_SIZE (buf);
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
packet.packetno = vd->packetno ++;
packet.packetno = vd->packetno++;
/* switch depending on packet type */
if (packet.packet[0] & 1) {
/* header packet */
if (packet.packet[0] / 2 != packet.packetno) {
/* FIXME: just skip? */
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
(NULL), ("unexpected packet type %d, expected %d", (gint) packet.packet[0], (gint) packet.packetno));
(NULL), ("unexpected packet type %d, expected %d",
(gint) packet.packet[0], (gint) packet.packetno));
gst_data_unref (data);
return;
}
if (vorbis_synthesis_headerin (&vd->vi, &vd->vc, &packet)) {
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
(NULL), ("couldn't read header packet"));
gst_data_unref (data);
return;
}
if (packet.packetno == 1) {
gchar *encoder = NULL;
GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf, "\003vorbis", 7, &encoder);
GstTagList *list =
gst_tag_list_from_vorbiscomment_buffer (buf, "\003vorbis", 7,
&encoder);
if (!list) {
GST_ERROR_OBJECT (vd, "couldn't decode comments");
list = gst_tag_list_new ();
@ -362,13 +373,13 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_ENCODER_VERSION, vd->vi.version, NULL);
if (vd->vi.bitrate_upper > 0)
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_MAXIMUM_BITRATE, (guint) vd->vi.bitrate_upper, NULL);
if (vd->vi.bitrate_nominal > 0)
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_NOMINAL_BITRATE, (guint) vd->vi.bitrate_nominal, NULL);
if (vd->vi.bitrate_lower > 0)
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_MINIMUM_BITRATE, (guint) vd->vi.bitrate_lower, NULL);
gst_element_found_tags_for_pad (GST_ELEMENT (vd), vd->srcpad, 0, list);
} else if (packet.packetno == 2) {
@ -381,10 +392,10 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
} else {
float **pcm;
guint sample_count;
/* normal data packet */
if (vorbis_synthesis (&vd->vb, &packet)) {
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
(NULL), ("couldn't read data packet"));
gst_data_unref (data);
return;
@ -398,9 +409,10 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
sample_count = vorbis_synthesis_pcmout (&vd->vd, &pcm);
if (sample_count > 0) {
int i, j;
GstBuffer *out = gst_pad_alloc_buffer (vd->srcpad, GST_BUFFER_OFFSET_NONE,
GstBuffer *out = gst_pad_alloc_buffer (vd->srcpad, GST_BUFFER_OFFSET_NONE,
sample_count * vd->vi.channels * sizeof (float));
float *out_data = (float *) GST_BUFFER_DATA (out);
#ifdef GST_VORBIS_DEC_SEQUENTIAL
for (i = 0; i < vd->vi.channels; i++) {
memcpy (out_data, pcm[i], sample_count * sizeof (float));
@ -427,7 +439,7 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
}
static GstElementStateReturn
vorbis_dec_change_state (GstElement *element)
vorbis_dec_change_state (GstElement * element)
{
GstVorbisDec *vd = GST_VORBIS_DEC (element);

View file

@ -27,8 +27,9 @@
#include <vorbis/codec.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern "C"
{
#endif /* __cplusplus */
#define GST_TYPE_VORBIS_DEC \
@ -42,32 +43,34 @@ extern "C" {
#define GST_IS_VORBIS_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VORBIS_DEC))
typedef struct _GstVorbisDec GstVorbisDec;
typedef struct _GstVorbisDecClass GstVorbisDecClass;
typedef struct _GstVorbisDec GstVorbisDec;
typedef struct _GstVorbisDecClass GstVorbisDecClass;
struct _GstVorbisDec {
GstElement element;
struct _GstVorbisDec
{
GstElement element;
GstPad * sinkpad;
GstPad * srcpad;
GstPad *sinkpad;
GstPad *srcpad;
vorbis_dsp_state vd;
vorbis_info vi;
vorbis_comment vc;
vorbis_block vb;
guint packetno;
guint64 granulepos;
};
vorbis_dsp_state vd;
vorbis_info vi;
vorbis_comment vc;
vorbis_block vb;
guint packetno;
guint64 granulepos;
};
struct _GstVorbisDecClass {
GstElementClass parent_class;
};
struct _GstVorbisDecClass
{
GstElementClass parent_class;
};
GType gst_vorbis_dec_get_type(void);
GType gst_vorbis_dec_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* __GST_VORBIS_DEC_H__ */
#endif /* __GST_VORBIS_DEC_H__ */

View file

@ -37,8 +37,7 @@ GstElementDetails vorbisenc_details = {
"Ogg Vorbis encoder",
"Codec/Encoder/Audio",
"Encodes audio in OGG Vorbis format",
"Monty <monty@xiph.org>, "
"Wim Taymans <wim.taymans@chello.be>",
"Monty <monty@xiph.org>, " "Wim Taymans <wim.taymans@chello.be>",
};
/* VorbisEnc signals and args */
@ -60,8 +59,8 @@ enum
ARG_LAST_MESSAGE,
};
static const GstFormat*
gst_vorbisenc_get_formats (GstPad *pad)
static const GstFormat *
gst_vorbisenc_get_formats (GstPad * pad)
{
static const GstFormat src_formats[] = {
GST_FORMAT_BYTES,
@ -71,33 +70,33 @@ gst_vorbisenc_get_formats (GstPad *pad)
static const GstFormat sink_formats[] = {
GST_FORMAT_BYTES,
GST_FORMAT_DEFAULT,
GST_FORMAT_TIME,
GST_FORMAT_TIME,
0
};
return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
}
}
#define MAX_BITRATE_DEFAULT -1
#define BITRATE_DEFAULT -1
#define MIN_BITRATE_DEFAULT -1
#define QUALITY_DEFAULT 0.3
static void gst_vorbisenc_base_init (gpointer g_class);
static void gst_vorbisenc_class_init (VorbisEncClass *klass);
static void gst_vorbisenc_init (VorbisEnc *vorbisenc);
static void gst_vorbisenc_base_init (gpointer g_class);
static void gst_vorbisenc_class_init (VorbisEncClass * klass);
static void gst_vorbisenc_init (VorbisEnc * vorbisenc);
static void gst_vorbisenc_chain (GstPad *pad, GstData *_data);
static gboolean gst_vorbisenc_setup (VorbisEnc *vorbisenc);
static void gst_vorbisenc_chain (GstPad * pad, GstData * _data);
static gboolean gst_vorbisenc_setup (VorbisEnc * vorbisenc);
static void gst_vorbisenc_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_vorbisenc_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static GstElementStateReturn
gst_vorbisenc_change_state (GstElement *element);
static void gst_vorbisenc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_vorbisenc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static GstElementStateReturn gst_vorbisenc_change_state (GstElement * element);
static GstElementClass *parent_class = NULL;
/*static guint gst_vorbisenc_signals[LAST_SIGNAL] = { 0 }; */
GType
@ -107,7 +106,7 @@ vorbisenc_get_type (void)
if (!vorbisenc_type) {
static const GTypeInfo vorbisenc_info = {
sizeof (VorbisEncClass),
sizeof (VorbisEncClass),
gst_vorbisenc_base_init,
NULL,
(GClassInitFunc) gst_vorbisenc_class_init,
@ -122,32 +121,34 @@ vorbisenc_get_type (void)
NULL,
NULL
};
vorbisenc_type = g_type_register_static (GST_TYPE_ELEMENT, "VorbisEnc", &vorbisenc_info, 0);
g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER, &tag_setter_info);
vorbisenc_type =
g_type_register_static (GST_TYPE_ELEMENT, "VorbisEnc", &vorbisenc_info,
0);
g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
&tag_setter_info);
}
return vorbisenc_type;
}
static GstCaps*
static GstCaps *
vorbis_caps_factory (void)
{
return gst_caps_new_simple ("application/ogg", NULL);
}
static GstCaps*
static GstCaps *
raw_caps_factory (void)
{
return
gst_caps_new_simple ("audio/x-raw-int",
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE,
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"rate", GST_TYPE_INT_RANGE, 11025, 48000,
"channels", GST_TYPE_INT_RANGE, 1, 2,
NULL);
gst_caps_new_simple ("audio/x-raw-int",
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE,
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"rate", GST_TYPE_INT_RANGE, 11025, 48000,
"channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
}
static void
@ -159,14 +160,14 @@ gst_vorbisenc_base_init (gpointer g_class)
raw_caps = raw_caps_factory ();
vorbis_caps = vorbis_caps_factory ();
gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS,
raw_caps);
gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS,
vorbis_caps);
gst_element_class_add_pad_template (element_class, gst_vorbisenc_sink_template);
gst_element_class_add_pad_template (element_class, gst_vorbisenc_src_template);
gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, raw_caps);
gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS, vorbis_caps);
gst_element_class_add_pad_template (element_class,
gst_vorbisenc_sink_template);
gst_element_class_add_pad_template (element_class,
gst_vorbisenc_src_template);
gst_element_class_set_details (element_class, &vorbisenc_details);
}
@ -179,31 +180,32 @@ gst_vorbisenc_class_init (VorbisEncClass * klass)
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
g_param_spec_int ("max_bitrate", "Max bitrate",
" Specify a minimum bitrate (in bps). Useful for encoding for a fixed-size channel",
-1, G_MAXINT, MAX_BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
g_param_spec_int ("bitrate", "Bitrate", "Choose a bitrate to encode at. "
"Attempt to encode at a bitrate averaging this. Takes an argument in kbps.",
-1, G_MAXINT, BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
g_param_spec_int ("min_bitrate", "Min bitrate",
"Specify a maximum bitrate in bps. Useful for streaming applications.",
-1, G_MAXINT, MIN_BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
g_param_spec_float ("quality", "Quality",
"Specify quality instead of specifying a particular bitrate.",
0.0, 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SERIAL,
g_param_spec_int ("serial", "Serial", "Specify a serial number for the stream. (-1 is random)",
-1, G_MAXINT, -1, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
g_param_spec_boolean ("managed", "Managed", "Enable bitrate management engine",
FALSE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
g_param_spec_int ("max_bitrate", "Max bitrate",
" Specify a minimum bitrate (in bps). Useful for encoding for a fixed-size channel",
-1, G_MAXINT, MAX_BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
g_param_spec_int ("bitrate", "Bitrate", "Choose a bitrate to encode at. "
"Attempt to encode at a bitrate averaging this. Takes an argument in kbps.",
-1, G_MAXINT, BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
g_param_spec_int ("min_bitrate", "Min bitrate",
"Specify a maximum bitrate in bps. Useful for streaming applications.",
-1, G_MAXINT, MIN_BITRATE_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
g_param_spec_float ("quality", "Quality",
"Specify quality instead of specifying a particular bitrate.",
0.0, 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SERIAL,
g_param_spec_int ("serial", "Serial",
"Specify a serial number for the stream. (-1 is random)", -1,
G_MAXINT, -1, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
g_param_spec_boolean ("managed", "Managed",
"Enable bitrate management engine", FALSE, 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));
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
@ -222,8 +224,8 @@ gst_vorbisenc_sinkconnect (GstPad * pad, const GstCaps * caps)
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "channels", &vorbisenc->channels);
gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
gst_structure_get_int (structure, "channels", &vorbisenc->channels);
gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
gst_vorbisenc_setup (vorbisenc);
@ -234,8 +236,8 @@ gst_vorbisenc_sinkconnect (GstPad * pad, const GstCaps * caps)
}
static gboolean
gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value)
gst_vorbisenc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = TRUE;
VorbisEnc *vorbisenc;
@ -243,31 +245,29 @@ gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
if (vorbisenc->samples_in == 0 ||
vorbisenc->bytes_out == 0 ||
vorbisenc->frequency == 0)
if (vorbisenc->samples_in == 0 ||
vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0)
return FALSE;
avg = (vorbisenc->bytes_out * vorbisenc->frequency)/
(vorbisenc->samples_in);
avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_TIME:
*dest_value = src_value * GST_SECOND / avg;
break;
default:
res = FALSE;
case GST_FORMAT_TIME:
*dest_value = src_value * GST_SECOND / avg;
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
*dest_value = src_value * avg / GST_SECOND;
break;
default:
res = FALSE;
case GST_FORMAT_BYTES:
*dest_value = src_value * avg / GST_SECOND;
break;
default:
res = FALSE;
}
break;
default:
@ -277,8 +277,8 @@ gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
}
static gboolean
gst_vorbisenc_convert_sink (GstPad *pad, GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value)
gst_vorbisenc_convert_sink (GstPad * pad, GstFormat src_format,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = TRUE;
guint scale = 1;
@ -286,54 +286,54 @@ gst_vorbisenc_convert_sink (GstPad *pad, GstFormat src_format, gint64 src_value,
VorbisEnc *vorbisenc;
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
bytes_per_sample = vorbisenc->channels * 2;
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_DEFAULT:
case GST_FORMAT_DEFAULT:
if (bytes_per_sample == 0)
return FALSE;
return FALSE;
*dest_value = src_value / bytes_per_sample;
break;
case GST_FORMAT_TIME:
break;
case GST_FORMAT_TIME:
{
gint byterate = bytes_per_sample * vorbisenc->frequency;
gint byterate = bytes_per_sample * vorbisenc->frequency;
if (byterate == 0)
return FALSE;
return FALSE;
*dest_value = src_value * GST_SECOND / byterate;
break;
break;
}
default:
res = FALSE;
default:
res = FALSE;
}
break;
case GST_FORMAT_DEFAULT:
switch (*dest_format) {
case GST_FORMAT_BYTES:
case GST_FORMAT_BYTES:
*dest_value = src_value * bytes_per_sample;
break;
case GST_FORMAT_TIME:
case GST_FORMAT_TIME:
if (vorbisenc->frequency == 0)
return FALSE;
return FALSE;
*dest_value = src_value * GST_SECOND / vorbisenc->frequency;
break;
default:
res = FALSE;
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
case GST_FORMAT_BYTES:
scale = bytes_per_sample;
/* fallthrough */
case GST_FORMAT_DEFAULT:
case GST_FORMAT_DEFAULT:
*dest_value = src_value * scale * vorbisenc->frequency / GST_SECOND;
break;
default:
res = FALSE;
break;
default:
res = FALSE;
}
break;
default:
@ -342,8 +342,8 @@ gst_vorbisenc_convert_sink (GstPad *pad, GstFormat src_format, gint64 src_value,
return res;
}
static const GstQueryType*
gst_vorbisenc_get_query_types (GstPad *pad)
static const GstQueryType *
gst_vorbisenc_get_query_types (GstPad * pad)
{
static const GstQueryType gst_vorbisenc_src_query_types[] = {
GST_QUERY_TOTAL,
@ -354,12 +354,12 @@ gst_vorbisenc_get_query_types (GstPad *pad)
}
static gboolean
gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
gst_vorbisenc_src_query (GstPad * pad, GstQueryType type,
GstFormat * format, gint64 * value)
{
gboolean res = TRUE;
VorbisEnc *vorbisenc;
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
switch (type) {
@ -368,32 +368,31 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
switch (*format) {
case GST_FORMAT_BYTES:
case GST_FORMAT_TIME:
{
{
gint64 peer_value;
const GstFormat *peer_formats;
const GstFormat *peer_formats;
res = FALSE;
peer_formats = gst_pad_get_formats (GST_PAD_PEER (vorbisenc->sinkpad));
peer_formats =
gst_pad_get_formats (GST_PAD_PEER (vorbisenc->sinkpad));
while (peer_formats && *peer_formats && !res) {
GstFormat peer_format = *peer_formats;
/* do the probe */
if (gst_pad_query (GST_PAD_PEER (vorbisenc->sinkpad), GST_QUERY_TOTAL,
&peer_format, &peer_value))
{
GstFormat conv_format;
if (gst_pad_query (GST_PAD_PEER (vorbisenc->sinkpad),
GST_QUERY_TOTAL, &peer_format, &peer_value)) {
GstFormat conv_format;
/* convert to TIME */
conv_format = GST_FORMAT_TIME;
conv_format = GST_FORMAT_TIME;
res = gst_pad_convert (vorbisenc->sinkpad,
peer_format, peer_value,
&conv_format, value);
peer_format, peer_value, &conv_format, value);
/* and to final format */
res &= gst_pad_convert (pad,
GST_FORMAT_TIME, *value,
format, value);
GST_FORMAT_TIME, *value, format, value);
}
peer_formats++;
}
@ -411,8 +410,7 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
{
/* we only know about our samples, convert to requested format */
res = gst_pad_convert (pad,
GST_FORMAT_BYTES, vorbisenc->bytes_out,
format, value);
GST_FORMAT_BYTES, vorbisenc->bytes_out, format, value);
break;
}
}
@ -427,18 +425,26 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
static void
gst_vorbisenc_init (VorbisEnc * vorbisenc)
{
vorbisenc->sinkpad = gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
vorbisenc->sinkpad =
gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
gst_pad_set_chain_function (vorbisenc->sinkpad, gst_vorbisenc_chain);
gst_pad_set_link_function (vorbisenc->sinkpad, gst_vorbisenc_sinkconnect);
gst_pad_set_convert_function (vorbisenc->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_sink));
gst_pad_set_formats_function (vorbisenc->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
gst_pad_set_convert_function (vorbisenc->sinkpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_sink));
gst_pad_set_formats_function (vorbisenc->sinkpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
vorbisenc->srcpad = gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
gst_pad_set_query_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
gst_pad_set_query_type_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
gst_pad_set_convert_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_src));
gst_pad_set_formats_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
vorbisenc->srcpad =
gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
gst_pad_set_query_function (vorbisenc->srcpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
gst_pad_set_query_type_function (vorbisenc->srcpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
gst_pad_set_convert_function (vorbisenc->srcpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_src));
gst_pad_set_formats_function (vorbisenc->srcpad,
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
vorbisenc->channels = -1;
@ -452,20 +458,21 @@ gst_vorbisenc_init (VorbisEnc * vorbisenc)
vorbisenc->quality_set = FALSE;
vorbisenc->serial = -1;
vorbisenc->last_message = NULL;
vorbisenc->setup = FALSE;
vorbisenc->eos = FALSE;
vorbisenc->header_sent = FALSE;
vorbisenc->tags = gst_tag_list_new ();
/* we're chained and we can deal with events */
GST_FLAG_SET (vorbisenc, GST_ELEMENT_EVENT_AWARE);
}
static gchar *
gst_vorbisenc_get_tag_value (const GstTagList *list, const gchar *tag, int index)
gst_vorbisenc_get_tag_value (const GstTagList * list, const gchar * tag,
int index)
{
gchar *vorbisvalue = NULL;
@ -474,32 +481,35 @@ gst_vorbisenc_get_tag_value (const GstTagList *list, const gchar *tag, int index
}
/* get tag name right */
if ((strcmp (tag, GST_TAG_TRACK_NUMBER) == 0)
|| (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0)
|| (strcmp (tag, GST_TAG_TRACK_COUNT) == 0)
if ((strcmp (tag, GST_TAG_TRACK_NUMBER) == 0)
|| (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0)
|| (strcmp (tag, GST_TAG_TRACK_COUNT) == 0)
|| (strcmp (tag, GST_TAG_ALBUM_VOLUME_COUNT) == 0)) {
guint track_no;
g_assert (gst_tag_list_get_uint_index (list, tag, index, &track_no));
vorbisvalue = g_strdup_printf ("%u", track_no);
} else if (strcmp (tag, GST_TAG_DATE) == 0) {
/* FIXME: how are dates represented in vorbis files? */
GDate *date;
guint u;
g_assert (gst_tag_list_get_uint_index (list, tag, index, &u));
date = g_date_new_julian (u);
vorbisvalue = g_strdup_printf ("%04d-%02d-%02d", (gint) g_date_get_year (date),
(gint) g_date_get_month (date), (gint) g_date_get_day (date));
vorbisvalue =
g_strdup_printf ("%04d-%02d-%02d", (gint) g_date_get_year (date),
(gint) g_date_get_month (date), (gint) g_date_get_day (date));
g_date_free (date);
} else if (gst_tag_get_type (tag) == G_TYPE_STRING) {
g_assert (gst_tag_list_get_string_index (list, tag, index, &vorbisvalue));
g_assert (gst_tag_list_get_string_index (list, tag, index, &vorbisvalue));
}
return vorbisvalue;
}
static void
gst_vorbisenc_metadata_set1 (const GstTagList *list, const gchar *tag, gpointer vorbisenc)
gst_vorbisenc_metadata_set1 (const GstTagList * list, const gchar * tag,
gpointer vorbisenc)
{
const gchar *vorbistag = NULL;
gchar *vorbisvalue = NULL;
@ -514,38 +524,40 @@ gst_vorbisenc_metadata_set1 (const GstTagList *list, const gchar *tag, gpointer
count = gst_tag_list_get_tag_size (list, tag);
for (i = 0; i < count; i++) {
vorbisvalue = gst_vorbisenc_get_tag_value (list, tag, i);
if (vorbisvalue != NULL) {
vorbis_comment_add_tag (&enc->vc, g_strdup (vorbistag), vorbisvalue);
}
}
}
static void
gst_vorbisenc_set_metadata (VorbisEnc *vorbisenc)
static void
gst_vorbisenc_set_metadata (VorbisEnc * vorbisenc)
{
GstTagList *copy;
GstTagList *copy;
const GstTagList *user_tags;
user_tags = gst_tag_setter_get_list (GST_TAG_SETTER (vorbisenc));
if (!(vorbisenc->tags || user_tags))
return;
copy = gst_tag_list_merge (user_tags, vorbisenc->tags, gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
copy =
gst_tag_list_merge (user_tags, vorbisenc->tags,
gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
vorbis_comment_init (&vorbisenc->vc);
gst_tag_list_foreach (copy, gst_vorbisenc_metadata_set1, vorbisenc);
gst_tag_list_free (copy);
}
static gchar*
get_constraints_string (VorbisEnc *vorbisenc)
static gchar *
get_constraints_string (VorbisEnc * vorbisenc)
{
gint min = vorbisenc->min_bitrate;
gint max = vorbisenc->max_bitrate;
gchar *result;
if (min > 0 && max > 0)
result = g_strdup_printf ("(min %d bps, max %d bps)", min,max);
result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
else if (min > 0)
result = g_strdup_printf ("(min %d bps, no max)", min);
else if (max > 0)
@ -557,7 +569,7 @@ get_constraints_string (VorbisEnc *vorbisenc)
}
static void
update_start_message (VorbisEnc *vorbisenc)
update_start_message (VorbisEnc * vorbisenc)
{
gchar *constraints;
@ -566,37 +578,34 @@ update_start_message (VorbisEnc *vorbisenc)
if (vorbisenc->bitrate > 0) {
if (vorbisenc->managed) {
constraints = get_constraints_string (vorbisenc);
vorbisenc->last_message =
g_strdup_printf ("encoding at average bitrate %d bps %s",
vorbisenc->bitrate, constraints);
vorbisenc->last_message =
g_strdup_printf ("encoding at average bitrate %d bps %s",
vorbisenc->bitrate, constraints);
g_free (constraints);
} else {
vorbisenc->last_message =
g_strdup_printf
("encoding at approximate bitrate %d bps (VBR encoding enabled)",
vorbisenc->bitrate);
}
else {
vorbisenc->last_message =
g_strdup_printf ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
vorbisenc->bitrate);
}
}
else {
} else {
if (vorbisenc->quality_set) {
if (vorbisenc->managed) {
constraints = get_constraints_string (vorbisenc);
vorbisenc->last_message =
g_strdup_printf ("encoding at quality level %2.2f using constrained VBR %s",
vorbisenc->quality, constraints);
g_free (constraints);
constraints = get_constraints_string (vorbisenc);
vorbisenc->last_message =
g_strdup_printf
("encoding at quality level %2.2f using constrained VBR %s",
vorbisenc->quality, constraints);
g_free (constraints);
} else {
vorbisenc->last_message =
g_strdup_printf ("encoding at quality level %2.2f",
vorbisenc->quality);
}
else {
vorbisenc->last_message =
g_strdup_printf ("encoding at quality level %2.2f",
vorbisenc->quality);
}
}
else {
} else {
constraints = get_constraints_string (vorbisenc);
vorbisenc->last_message =
g_strdup_printf ("encoding using bitrate management %s",
constraints);
vorbisenc->last_message =
g_strdup_printf ("encoding using bitrate management %s", constraints);
g_free (constraints);
}
}
@ -605,34 +614,34 @@ update_start_message (VorbisEnc *vorbisenc)
}
static gboolean
gst_vorbisenc_setup (VorbisEnc *vorbisenc)
gst_vorbisenc_setup (VorbisEnc * vorbisenc)
{
gint serial;
if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0 && vorbisenc->max_bitrate < 0) {
if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
&& vorbisenc->max_bitrate < 0) {
vorbisenc->quality_set = TRUE;
}
update_start_message (vorbisenc);
/* choose an encoding mode */
/* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
vorbis_info_init (&vorbisenc->vi);
if(vorbisenc->quality_set){
if (vorbis_encode_setup_vbr (&vorbisenc->vi,
vorbisenc->channels,
vorbisenc->frequency,
vorbisenc->quality))
{
g_warning ("vorbisenc: initialisation failed: invalid parameters for quality");
vorbis_info_clear(&vorbisenc->vi);
return FALSE;
if (vorbisenc->quality_set) {
if (vorbis_encode_setup_vbr (&vorbisenc->vi,
vorbisenc->channels, vorbisenc->frequency, vorbisenc->quality)) {
g_warning
("vorbisenc: initialisation failed: invalid parameters for quality");
vorbis_info_clear (&vorbisenc->vi);
return FALSE;
}
/* do we have optional hard quality restrictions? */
if(vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0){
if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
struct ovectl_ratemanage_arg ai;
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
/* the bitrates are in kHz */
@ -642,29 +651,27 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
}
}
else {
if (vorbis_encode_setup_managed (&vorbisenc->vi,
vorbisenc->channels,
vorbisenc->frequency,
vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1,
vorbisenc->bitrate,
vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1))
{
g_warning("vorbisenc: initialisation failed: invalid parameters for bitrate\n");
vorbis_info_clear(&vorbisenc->vi);
} else {
if (vorbis_encode_setup_managed (&vorbisenc->vi,
vorbisenc->channels,
vorbisenc->frequency,
vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1,
vorbisenc->bitrate,
vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1)) {
g_warning
("vorbisenc: initialisation failed: invalid parameters for bitrate\n");
vorbis_info_clear (&vorbisenc->vi);
return FALSE;
}
}
if(vorbisenc->managed && vorbisenc->bitrate < 0) {
vorbis_encode_ctl(&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
}
else if(!vorbisenc->managed) {
if (vorbisenc->managed && vorbisenc->bitrate < 0) {
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
} else if (!vorbisenc->managed) {
/* Turn off management entirely (if it was turned on). */
vorbis_encode_ctl(&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
}
vorbis_encode_setup_init(&vorbisenc->vi);
vorbis_encode_setup_init (&vorbisenc->vi);
/* set up the analysis state and auxiliary encoding storage */
vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
@ -676,8 +683,7 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
if (vorbisenc->serial < 0) {
srand (time (NULL));
serial = rand ();
}
else {
} else {
serial = vorbisenc->serial;
}
@ -689,34 +695,29 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
}
static void
gst_vorbisenc_write_page (VorbisEnc *vorbisenc, ogg_page *page)
gst_vorbisenc_write_page (VorbisEnc * vorbisenc, ogg_page * page)
{
GstBuffer *outbuf;
outbuf = gst_buffer_new_and_alloc (page->header_len +
page->body_len);
outbuf = gst_buffer_new_and_alloc (page->header_len + page->body_len);
memcpy (GST_BUFFER_DATA (outbuf), page->header,
page->header_len);
memcpy (GST_BUFFER_DATA (outbuf) + page->header_len,
page->body,
page->body_len);
memcpy (GST_BUFFER_DATA (outbuf), page->header, page->header_len);
memcpy (GST_BUFFER_DATA (outbuf) + page->header_len,
page->body, page->body_len);
GST_DEBUG ("vorbisenc: encoded buffer of %d bytes",
GST_BUFFER_SIZE (outbuf));
GST_DEBUG ("vorbisenc: encoded buffer of %d bytes", GST_BUFFER_SIZE (outbuf));
vorbisenc->bytes_out += GST_BUFFER_SIZE (outbuf);
if (GST_PAD_IS_USABLE (vorbisenc->srcpad)) {
gst_pad_push (vorbisenc->srcpad, GST_DATA (outbuf));
}
else {
} else {
gst_buffer_unref (outbuf);
}
}
static void
gst_vorbisenc_chain (GstPad * pad, GstData *_data)
gst_vorbisenc_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
VorbisEnc *vorbisenc;
@ -732,17 +733,17 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
/* end of file. this can be done implicitly in the mainline,
but it's easier to see here in non-clever fashion.
Tell the library we're at end of stream so that it can handle
the last frame and mark end of stream in the output properly */
vorbis_analysis_wrote (&vorbisenc->vd, 0);
/* end of file. this can be done implicitly in the mainline,
but it's easier to see here in non-clever fashion.
Tell the library we're at end of stream so that it can handle
the last frame and mark end of stream in the output properly */
vorbis_analysis_wrote (&vorbisenc->vd, 0);
gst_event_unref (event);
break;
case GST_EVENT_TAG:
if (vorbisenc->tags) {
gst_tag_list_insert (vorbisenc->tags, gst_event_tag_get_list (event),
gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
gst_tag_list_insert (vorbisenc->tags, gst_event_tag_get_list (event),
gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
} else {
g_assert_not_reached ();
}
@ -750,10 +751,9 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
return;
default:
gst_pad_event_default (pad, event);
return;
return;
}
}
else {
} else {
gint16 *data;
gulong size;
gulong i, j;
@ -761,34 +761,37 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
if (!vorbisenc->setup) {
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL), ("encoder not initialized (input is not audio?)"));
GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
("encoder not initialized (input is not audio?)"));
return;
}
if (!vorbisenc->header_sent) {
gint result;
/* Vorbis streams begin with three headers; the initial header (with
most of the codec setup parameters) which is mandated by the Ogg
bitstream spec. The second header holds any comment fields. The
third header holds the bitstream codebook. We merely need to
make the headers, then pass them to libvorbis one at a time;
libvorbis handles the additional Ogg bitstream constraints */
most of the codec setup parameters) which is mandated by the Ogg
bitstream spec. The second header holds any comment fields. The
third header holds the bitstream codebook. We merely need to
make the headers, then pass them to libvorbis one at a time;
libvorbis handles the additional Ogg bitstream constraints */
ogg_packet header;
ogg_packet header_comm;
ogg_packet header_code;
gst_vorbisenc_set_metadata (vorbisenc);
vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header, &header_comm, &header_code);
ogg_stream_packetin (&vorbisenc->os, &header); /* automatically placed in its own page */
vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
&header_comm, &header_code);
ogg_stream_packetin (&vorbisenc->os, &header); /* automatically placed in its own page */
ogg_stream_packetin (&vorbisenc->os, &header_comm);
ogg_stream_packetin (&vorbisenc->os, &header_code);
while ((result = ogg_stream_flush(&vorbisenc->os, &vorbisenc->og))) {
while ((result = ogg_stream_flush (&vorbisenc->os, &vorbisenc->og))) {
gst_vorbisenc_write_page (vorbisenc, &vorbisenc->og);
}
vorbisenc->header_sent = TRUE;
}
/* data to encode */
data = (gint16 *) GST_BUFFER_DATA (buf);
size = GST_BUFFER_SIZE (buf) / (vorbisenc->channels * 2);
@ -818,8 +821,8 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
/* analysis */
vorbis_analysis (&vorbisenc->vb, NULL);
vorbis_bitrate_addblock(&vorbisenc->vb);
vorbis_bitrate_addblock (&vorbisenc->vb);
while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &vorbisenc->op)) {
/* weld the packet into the bitstream */
@ -827,18 +830,18 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
/* write out pages (if any) */
while (!vorbisenc->eos) {
int result = ogg_stream_pageout (&vorbisenc->os, &vorbisenc->og);
int result = ogg_stream_pageout (&vorbisenc->os, &vorbisenc->og);
if (result == 0)
if (result == 0)
break;
gst_vorbisenc_write_page (vorbisenc, &vorbisenc->og);
/* this could be set above, but for illustrative purposes, I do
it here (to show that vorbis does know where the stream ends) */
if (ogg_page_eos (&vorbisenc->og)) {
/* this could be set above, but for illustrative purposes, I do
it here (to show that vorbis does know where the stream ends) */
if (ogg_page_eos (&vorbisenc->og)) {
vorbisenc->eos = 1;
}
}
}
}
}
@ -855,7 +858,8 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
}
static void
gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
VorbisEnc *vorbisenc;
@ -893,8 +897,8 @@ gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value, GPa
}
static void
gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec)
gst_vorbisenc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
VorbisEnc *vorbisenc;
@ -910,9 +914,9 @@ gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * valu
vorbisenc->max_bitrate = g_value_get_int (value);
if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
vorbisenc->managed = TRUE;
vorbisenc->managed = TRUE;
else
vorbisenc->managed = FALSE;
vorbisenc->managed = FALSE;
if (old_value != vorbisenc->managed)
g_object_notify (object, "managed");
@ -927,9 +931,9 @@ gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * valu
vorbisenc->min_bitrate = g_value_get_int (value);
if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
vorbisenc->managed = TRUE;
vorbisenc->managed = TRUE;
else
vorbisenc->managed = FALSE;
vorbisenc->managed = FALSE;
if (old_value != vorbisenc->managed)
g_object_notify (object, "managed");
@ -938,9 +942,9 @@ gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * valu
case ARG_QUALITY:
vorbisenc->quality = g_value_get_float (value);
if (vorbisenc->quality >= 0.0)
vorbisenc->quality_set = TRUE;
vorbisenc->quality_set = TRUE;
else
vorbisenc->quality_set = FALSE;
vorbisenc->quality_set = FALSE;
break;
case ARG_SERIAL:
vorbisenc->serial = g_value_get_int (value);
@ -955,10 +959,10 @@ gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * valu
}
static GstElementStateReturn
gst_vorbisenc_change_state (GstElement *element)
gst_vorbisenc_change_state (GstElement * element)
{
VorbisEnc *vorbisenc = GST_VORBISENC (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
@ -983,4 +987,3 @@ gst_vorbisenc_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}

View file

@ -27,8 +27,9 @@
#include <vorbis/codec.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern "C"
{
#endif /* __cplusplus */
#define GST_TYPE_VORBISENC \
(vorbisenc_get_type())
@ -41,60 +42,61 @@ extern "C" {
#define GST_IS_VORBISENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VORBISENC))
typedef struct _VorbisEnc VorbisEnc;
typedef struct _VorbisEncClass VorbisEncClass;
typedef struct _VorbisEnc VorbisEnc;
typedef struct _VorbisEncClass VorbisEncClass;
struct _VorbisEnc {
GstElement element;
struct _VorbisEnc
{
GstElement element;
GstPad *sinkpad,
*srcpad;
GstPad *sinkpad, *srcpad;
ogg_stream_state os; /* take physical pages, weld into a logical
stream of packets */
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
ogg_packet op; /* one raw packet of data for decode */
ogg_stream_state os; /* take physical pages, weld into a logical
stream of packets */
ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
ogg_packet op; /* one raw packet of data for decode */
vorbis_info vi; /* struct that stores all the static vorbis bitstream
settings */
vorbis_comment vc; /* struct that stores all the user comments */
vorbis_info vi; /* struct that stores all the static vorbis bitstream
settings */
vorbis_comment vc; /* struct that stores all the user comments */
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
gboolean eos;
gboolean eos;
gboolean managed;
gint bitrate;
gint min_bitrate;
gint max_bitrate;
gfloat quality;
gboolean quality_set;
gint serial;
gboolean managed;
gint bitrate;
gint min_bitrate;
gint max_bitrate;
gfloat quality;
gboolean quality_set;
gint serial;
gint channels;
gint frequency;
gint channels;
gint frequency;
guint64 samples_in;
guint64 bytes_out;
guint64 samples_in;
guint64 bytes_out;
GstTagList * tags;
GstTagList *tags;
gboolean setup;
gboolean header_sent;
gchar *last_message;
};
gboolean setup;
gboolean header_sent;
gchar *last_message;
};
struct _VorbisEncClass {
GstElementClass parent_class;
};
struct _VorbisEncClass
{
GstElementClass parent_class;
};
GType vorbisenc_get_type(void);
GType vorbisenc_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* __VORBISENC_H__ */
#endif /* __VORBISENC_H__ */

View file

@ -26,7 +26,7 @@
#include <gst/gststructure.h>
int
gst_audio_frame_byte_size (GstPad* pad)
gst_audio_frame_byte_size (GstPad * pad)
{
/* calculate byte size of an audio frame
* this should be moved closer to the gstreamer core
@ -45,20 +45,20 @@ gst_audio_frame_byte_size (GstPad* pad)
if (caps == NULL) {
/* ERROR: could not get caps of pad */
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return 0;
}
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "channels", &channels);
return (width / 8) * channels;
return (width / 8) * channels;
}
long
gst_audio_frame_length (GstPad* pad, GstBuffer* buf)
gst_audio_frame_length (GstPad * pad, GstBuffer * buf)
/* calculate length of buffer in frames
* this should be moved closer to the gstreamer core
* and be implemented for every mime type IMO
@ -72,13 +72,13 @@ gst_audio_frame_length (GstPad* pad, GstBuffer* buf)
/* error */
return 0;
/* FIXME: this function assumes the buffer size to be a whole multiple
* of the frame byte size
* of the frame byte size
*/
return GST_BUFFER_SIZE (buf) / frame_byte_size;
}
long
gst_audio_frame_rate (GstPad *pad)
gst_audio_frame_rate (GstPad * pad)
/*
* calculate frame rate (based on caps of pad)
* returns 0 if failed, rate if success
@ -93,19 +93,18 @@ gst_audio_frame_rate (GstPad *pad)
if (caps == NULL) {
/* ERROR: could not get caps of pad */
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return 0;
}
else {
} else {
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "rate", &rate);
gst_structure_get_int (structure, "rate", &rate);
return rate;
}
}
double
gst_audio_length (GstPad* pad, GstBuffer* buf)
double
gst_audio_length (GstPad * pad, GstBuffer * buf)
{
/* calculate length in seconds
* of audio buffer buf
@ -125,20 +124,17 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
g_assert (GST_IS_BUFFER (buf));
/* get caps of pad */
caps = GST_PAD_CAPS (pad);
if (caps == NULL)
{
if (caps == NULL) {
/* ERROR: could not get caps of pad */
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
length = 0.0;
}
else
{
} else {
structure = gst_caps_get_structure (caps, 0);
bytes = GST_BUFFER_SIZE (buf);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "channels", &channels);
gst_structure_get_int (structure, "rate", &rate);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "channels", &channels);
gst_structure_get_int (structure, "rate", &rate);
g_assert (bytes != 0);
g_assert (width != 0);
@ -150,8 +146,8 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
return length;
}
long
gst_audio_highest_sample_value (GstPad* pad)
long
gst_audio_highest_sample_value (GstPad * pad)
/* calculate highest possible sample value
* based on capabilities of pad
*/
@ -160,25 +156,25 @@ gst_audio_highest_sample_value (GstPad* pad)
gint width = 0;
const GstCaps *caps = NULL;
GstStructure *structure;
caps = GST_PAD_CAPS (pad);
if (caps == NULL)
{
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
if (caps == NULL) {
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
}
structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_boolean (structure, "signed", &is_signed);
if (is_signed) --width;
gst_structure_get_int (structure, "width", &width);
gst_structure_get_boolean (structure, "signed", &is_signed);
if (is_signed)
--width;
/* example : 16 bit, signed : samples between -32768 and 32767 */
return ((long) (1 << width));
}
gboolean
gst_audio_is_buffer_framed (GstPad* pad, GstBuffer* buf)
gboolean
gst_audio_is_buffer_framed (GstPad * pad, GstBuffer * buf)
/* check if the buffer size is a whole multiple of the frame size */
{
if (GST_BUFFER_SIZE (buf) % gst_audio_frame_byte_size (pad) == 0)
@ -199,8 +195,8 @@ gst_audio_is_buffer_framed (GstPad* pad, GstBuffer* buf)
* number of list values, and each of the values, terminating with NULL
*/
static void
_gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
GType type, int number, ...)
_gst_audio_structure_set_list (GstStructure * structure,
const gchar * fieldname, GType type, int number, ...)
{
va_list varargs;
GValue value = { 0 };
@ -214,27 +210,27 @@ _gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
va_start (varargs, number);
for (j = 0; j < number; ++j)
{
for (j = 0; j < number; ++j) {
int i;
gboolean b;
GValue list_value = { 0 };
switch (type)
{
switch (type) {
case G_TYPE_INT:
i = va_arg (varargs, int);
g_value_init (&list_value, G_TYPE_INT);
g_value_set_int (&list_value, i);
break;
i = va_arg (varargs, int);
g_value_init (&list_value, G_TYPE_INT);
g_value_set_int (&list_value, i);
break;
case G_TYPE_BOOLEAN:
b = va_arg (varargs, gboolean);
g_value_init (&list_value, G_TYPE_BOOLEAN);
g_value_set_boolean (&list_value, b);
break;
default:
g_warning ("_gst_audio_structure_set_list: LIST of given type not implemented.");
b = va_arg (varargs, gboolean);
g_value_init (&list_value, G_TYPE_BOOLEAN);
g_value_set_boolean (&list_value, b);
break;
default:
g_warning
("_gst_audio_structure_set_list: LIST of given type not implemented.");
}
g_array_append_val (array, list_value);
@ -244,38 +240,38 @@ _gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
}
void
gst_audio_structure_set_int (GstStructure *structure, GstAudioFieldFlag flag)
gst_audio_structure_set_int (GstStructure * structure, GstAudioFieldFlag flag)
{
if (flag & GST_AUDIO_FIELD_RATE)
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
NULL);
if (flag & GST_AUDIO_FIELD_CHANNELS)
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
NULL);
if (flag & GST_AUDIO_FIELD_ENDIANNESS)
_gst_audio_structure_set_list (structure, "endianness", G_TYPE_INT, 2, G_LITTLE_ENDIAN, G_BIG_ENDIAN, NULL);
_gst_audio_structure_set_list (structure, "endianness", G_TYPE_INT, 2,
G_LITTLE_ENDIAN, G_BIG_ENDIAN, NULL);
if (flag & GST_AUDIO_FIELD_WIDTH)
_gst_audio_structure_set_list (structure, "width", G_TYPE_INT, 3, 8, 16, 32, NULL);
_gst_audio_structure_set_list (structure, "width", G_TYPE_INT, 3, 8, 16, 32,
NULL);
if (flag & GST_AUDIO_FIELD_DEPTH)
gst_structure_set (structure, "depth", GST_TYPE_INT_RANGE, 1, 32, NULL);
if (flag & GST_AUDIO_FIELD_SIGNED)
_gst_audio_structure_set_list (structure, "signed", G_TYPE_BOOLEAN, 2, TRUE, FALSE, NULL);
_gst_audio_structure_set_list (structure, "signed", G_TYPE_BOOLEAN, 2, TRUE,
FALSE, NULL);
if (flag & GST_AUDIO_FIELD_BUFFER_FRAMES)
gst_structure_set (structure, "buffer-frames", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
gst_structure_set (structure, "buffer-frames", GST_TYPE_INT_RANGE, 1,
G_MAXINT, NULL);
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudio",
"Support services for audio plugins",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
);
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudio",
"Support services for audio plugins",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN);

View file

@ -26,7 +26,6 @@
#define __GST_AUDIO_AUDIO_H__
G_BEGIN_DECLS
/* For people that are looking at this source: the purpose of these defines is
* to make GstCaps a bit easier, in that you don't have to know all of the
* properties that need to be defined. you can just use these macros. currently
@ -50,9 +49,7 @@ G_BEGIN_DECLS
*
* Andy Wingo, 18 August 2001
* Thomas, 6 September 2002 */
#define GST_AUDIO_DEF_RATE 44100
#define GST_AUDIO_INT_PAD_TEMPLATE_CAPS \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
@ -60,9 +57,7 @@ G_BEGIN_DECLS
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) { 8, 16, 32 }, " \
"depth = (int) [ 1, 32 ], " \
"signed = (boolean) { true, false }"
"signed = (boolean) { true, false }"
/* "standard" int audio is native order, 16 bit stereo. */
#define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS \
"audio/x-raw-int, " \
@ -71,8 +66,7 @@ G_BEGIN_DECLS
"endianness = (int) BYTE_ORDER, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (boolean) true"
"signed = (boolean) true"
#define GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS \
"audio/x-raw-float, " \
"rate = (int) [ 1, MAX ], " \
@ -80,7 +74,6 @@ G_BEGIN_DECLS
"endianness = (int) { LITTLE_ENDIAN , BIG_ENDIAN }, " \
"width = (int) { 32, 64 }, " \
"buffer-frames = (int) [ 1, MAX]"
/* "standard" float audio is native order, 32 bit mono. */
#define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS \
"audio/x-raw-float, " \
@ -88,43 +81,42 @@ G_BEGIN_DECLS
"channels = (int) 1, " \
"endianness = (int) BYTE_ORDER, " \
"buffer-frames = (int) [ 1, MAX]"
/*
* this library defines and implements some helper functions for audio
* handling
*/
/* get byte size of audio frame (based on caps of pad */
int gst_audio_frame_byte_size (GstPad* pad);
int gst_audio_frame_byte_size (GstPad * pad);
/* get length in frames of buffer */
long gst_audio_frame_length (GstPad* pad, GstBuffer* buf);
long gst_audio_frame_length (GstPad * pad, GstBuffer * buf);
/* get frame rate based on caps */
long gst_audio_frame_rate (GstPad *pad);
long gst_audio_frame_rate (GstPad * pad);
/* calculate length in seconds of audio buffer buf based on caps of pad */
double gst_audio_length (GstPad* pad, GstBuffer* buf);
double gst_audio_length (GstPad * pad, GstBuffer * buf);
/* calculate highest possible sample value based on capabilities of pad */
long gst_audio_highest_sample_value (GstPad* pad);
long gst_audio_highest_sample_value (GstPad * pad);
/* check if the buffer size is a whole multiple of the frame size */
gboolean gst_audio_is_buffer_framed (GstPad* pad, GstBuffer* buf);
gboolean gst_audio_is_buffer_framed (GstPad * pad, GstBuffer * buf);
/* functions useful for _getcaps functions */
typedef enum {
GST_AUDIO_FIELD_RATE = (1 << 0),
GST_AUDIO_FIELD_CHANNELS = (1 << 1),
GST_AUDIO_FIELD_ENDIANNESS = (1 << 2),
GST_AUDIO_FIELD_WIDTH = (1 << 3),
GST_AUDIO_FIELD_DEPTH = (1 << 4),
GST_AUDIO_FIELD_SIGNED = (1 << 5),
typedef enum
{
GST_AUDIO_FIELD_RATE = (1 << 0),
GST_AUDIO_FIELD_CHANNELS = (1 << 1),
GST_AUDIO_FIELD_ENDIANNESS = (1 << 2),
GST_AUDIO_FIELD_WIDTH = (1 << 3),
GST_AUDIO_FIELD_DEPTH = (1 << 4),
GST_AUDIO_FIELD_SIGNED = (1 << 5),
GST_AUDIO_FIELD_BUFFER_FRAMES = (1 << 6)
} GstAudioFieldFlag;
void gst_audio_structure_set_int (GstStructure *structure, GstAudioFieldFlag flag);
void gst_audio_structure_set_int (GstStructure * structure,
GstAudioFieldFlag flag);
G_END_DECLS
#endif /* __GST_AUDIO_AUDIO_H__ */

View file

@ -26,23 +26,24 @@
#include "audioclock.h"
static void gst_audio_clock_class_init (GstAudioClockClass *klass);
static void gst_audio_clock_init (GstAudioClock *clock);
static void gst_audio_clock_class_init (GstAudioClockClass * klass);
static void gst_audio_clock_init (GstAudioClock * clock);
static GstClockTime gst_audio_clock_get_internal_time (GstClock *clock);
static GstClockReturn gst_audio_clock_id_wait_async (GstClock *clock,
GstClockEntry *entry);
static void gst_audio_clock_id_unschedule (GstClock *clock,
GstClockEntry *entry);
static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock);
static GstClockReturn gst_audio_clock_id_wait_async (GstClock * clock,
GstClockEntry * entry);
static void gst_audio_clock_id_unschedule (GstClock * clock,
GstClockEntry * entry);
static GstSystemClockClass *parent_class = NULL;
/* static guint gst_audio_clock_signals[LAST_SIGNAL] = { 0 }; */
GType
gst_audio_clock_get_type (void)
{
{
static GType clock_type = 0;
if (!clock_type) {
static const GTypeInfo clock_info = {
sizeof (GstAudioClockClass),
@ -57,32 +58,32 @@ gst_audio_clock_get_type (void)
NULL
};
clock_type = g_type_register_static (GST_TYPE_SYSTEM_CLOCK, "GstAudioClock",
&clock_info, 0);
&clock_info, 0);
}
return clock_type;
}
static void
gst_audio_clock_class_init (GstAudioClockClass *klass)
gst_audio_clock_class_init (GstAudioClockClass * klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstClockClass *gstclock_class;
gobject_class = (GObjectClass*) klass;
gstobject_class = (GstObjectClass*) klass;
gstclock_class = (GstClockClass*) klass;
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
gstclock_class = (GstClockClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_SYSTEM_CLOCK);
gstclock_class->get_internal_time = gst_audio_clock_get_internal_time;
gstclock_class->wait_async = gst_audio_clock_id_wait_async;
gstclock_class->unschedule = gst_audio_clock_id_unschedule;
gstclock_class->get_internal_time = gst_audio_clock_get_internal_time;
gstclock_class->wait_async = gst_audio_clock_id_wait_async;
gstclock_class->unschedule = gst_audio_clock_id_unschedule;
}
static void
gst_audio_clock_init (GstAudioClock *clock)
gst_audio_clock_init (GstAudioClock * clock)
{
gst_object_set_name (GST_OBJECT (clock), "GstAudioClock");
@ -90,20 +91,22 @@ gst_audio_clock_init (GstAudioClock *clock)
clock->prev2 = 0;
}
GstClock*
gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func, gpointer user_data)
GstClock *
gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func,
gpointer user_data)
{
GstAudioClock *aclock = GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, NULL));
GstAudioClock *aclock =
GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, NULL));
aclock->func = func;
aclock->user_data = user_data;
aclock->adjust = 0;
return (GstClock*)aclock;
return (GstClock *) aclock;
}
void
gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
gst_audio_clock_set_active (GstAudioClock * aclock, gboolean active)
{
GstClockTime time;
GstClock *clock;
@ -117,8 +120,9 @@ gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
aclock->adjust = time - aclock->func (clock, aclock->user_data);
} else {
GTimeVal timeval;
g_get_current_time (&timeval);
aclock->adjust = GST_TIMEVAL_TO_TIME (timeval) - time;
}
@ -126,22 +130,22 @@ gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
}
static GstClockTime
gst_audio_clock_get_internal_time (GstClock *clock)
gst_audio_clock_get_internal_time (GstClock * clock)
{
GstAudioClock *aclock = GST_AUDIO_CLOCK (clock);
if (aclock->active) {
return aclock->func (clock, aclock->user_data) + aclock->adjust;
} else {
GTimeVal timeval;
g_get_current_time (&timeval);
return GST_TIMEVAL_TO_TIME (timeval);
}
}
void
gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time)
gst_audio_clock_update_time (GstAudioClock * aclock, GstClockTime time)
{
/* I don't know of a purpose in updating these; perhaps they can be removed */
aclock->prev2 = aclock->prev1;
@ -150,43 +154,41 @@ gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time)
/* FIXME: the wait_async subsystem should be made threadsafe, but I don't want
* to lock and unlock a mutex on every iteration... */
while (aclock->async_entries) {
GstClockEntry *entry = (GstClockEntry*)aclock->async_entries->data;
GstClockEntry *entry = (GstClockEntry *) aclock->async_entries->data;
if (entry->time > time)
break;
entry->func ((GstClock*)aclock, time, entry, entry->user_data);
entry->func ((GstClock *) aclock, time, entry, entry->user_data);
aclock->async_entries = g_slist_delete_link (aclock->async_entries,
aclock->async_entries);
aclock->async_entries);
/* do I need to free the entry? */
}
}
static gint
compare_clock_entries (GstClockEntry *entry1, GstClockEntry *entry2)
compare_clock_entries (GstClockEntry * entry1, GstClockEntry * entry2)
{
return entry1->time - entry2->time;
}
static GstClockReturn
gst_audio_clock_id_wait_async (GstClock *clock, GstClockEntry *entry)
gst_audio_clock_id_wait_async (GstClock * clock, GstClockEntry * entry)
{
GstAudioClock *aclock = (GstAudioClock*)clock;
GstAudioClock *aclock = (GstAudioClock *) clock;
aclock->async_entries = g_slist_insert_sorted (aclock->async_entries,
entry,
(GCompareFunc)compare_clock_entries);
entry, (GCompareFunc) compare_clock_entries);
/* is this the proper return val? */
return GST_CLOCK_EARLY;
}
static void
gst_audio_clock_id_unschedule (GstClock *clock, GstClockEntry *entry)
gst_audio_clock_id_unschedule (GstClock * clock, GstClockEntry * entry)
{
GstAudioClock *aclock = (GstAudioClock*)clock;
aclock->async_entries = g_slist_remove (aclock->async_entries,
entry);
GstAudioClock *aclock = (GstAudioClock *) clock;
aclock->async_entries = g_slist_remove (aclock->async_entries, entry);
}

View file

@ -27,7 +27,6 @@
#include <gst/gstsystemclock.h>
G_BEGIN_DECLS
#define GST_TYPE_AUDIO_CLOCK \
(gst_audio_clock_get_type())
#define GST_AUDIO_CLOCK(obj) \
@ -38,14 +37,15 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_CLOCK))
#define GST_IS_AUDIO_CLOCK_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_CLOCK))
typedef struct _GstAudioClock GstAudioClock;
typedef struct _GstAudioClockClass GstAudioClockClass;
typedef GstClockTime (*GstAudioClockGetTimeFunc) (GstClock *clock, gpointer user_data);
typedef GstClockTime (*GstAudioClockGetTimeFunc) (GstClock * clock,
gpointer user_data);
struct _GstAudioClock {
struct _GstAudioClock
{
GstSystemClock clock;
GstClockTime prev1, prev2;
@ -63,19 +63,19 @@ struct _GstAudioClock {
gpointer _gst_reserved[GST_PADDING];
};
struct _GstAudioClockClass {
struct _GstAudioClockClass
{
GstSystemClockClass parent_class;
gpointer _gst_reserved[GST_PADDING];
};
GType gst_audio_clock_get_type (void);
GstClock* gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func,
gpointer user_data);
void gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active);
GType gst_audio_clock_get_type (void);
GstClock *gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func,
gpointer user_data);
void gst_audio_clock_set_active (GstAudioClock * aclock, gboolean active);
void gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time);
void gst_audio_clock_update_time (GstAudioClock * aclock, GstClockTime time);
G_END_DECLS
#endif /* __GST_AUDIO_CLOCK_H__ */

View file

@ -29,26 +29,30 @@
/* GstAudiofilter signals and args */
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
ARG_METHOD,
/* FILL ME */
};
static void gst_audiofilter_base_init (gpointer g_class);
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data);
static void gst_audiofilter_init (GTypeInstance *instance, gpointer g_class);
static void gst_audiofilter_base_init (gpointer g_class);
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data);
static void gst_audiofilter_init (GTypeInstance * instance, gpointer g_class);
static void gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_audiofilter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_audiofilter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_audiofilter_chain (GstPad *pad, GstData *_data);
GstCaps * gst_audiofilter_class_get_capslist(GstAudiofilterClass *klass);
static void gst_audiofilter_chain (GstPad * pad, GstData * _data);
GstCaps *gst_audiofilter_class_get_capslist (GstAudiofilterClass * klass);
static GstElementClass *parent_class = NULL;
@ -59,23 +63,24 @@ gst_audiofilter_get_type (void)
if (!audiofilter_type) {
static const GTypeInfo audiofilter_info = {
sizeof(GstAudiofilterClass),
sizeof (GstAudiofilterClass),
gst_audiofilter_base_init,
NULL,
gst_audiofilter_class_init,
NULL,
NULL,
sizeof(GstAudiofilter),
sizeof (GstAudiofilter),
0,
gst_audiofilter_init,
};
audiofilter_type = g_type_register_static(GST_TYPE_ELEMENT,
audiofilter_type = g_type_register_static (GST_TYPE_ELEMENT,
"GstAudiofilter", &audiofilter_info, G_TYPE_FLAG_ABSTRACT);
}
return audiofilter_type;
}
static void gst_audiofilter_base_init (gpointer g_class)
static void
gst_audiofilter_base_init (gpointer g_class)
{
static GstElementDetails audiofilter_details = {
"Audio filter base class",
@ -89,24 +94,25 @@ static void gst_audiofilter_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &audiofilter_details);
}
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
static void
gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstAudiofilterClass *klass;
klass = (GstAudiofilterClass *)g_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
klass = (GstAudiofilterClass *) g_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gobject_class->set_property = gst_audiofilter_set_property;
gobject_class->get_property = gst_audiofilter_get_property;
}
static GstPadLinkReturn
gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
gst_audiofilter_link (GstPad * pad, const GstCaps * caps)
{
GstAudiofilter *audiofilter;
GstPadLinkReturn ret;
@ -114,11 +120,10 @@ gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
GstStructure *structure;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG("gst_audiofilter_link");
GST_DEBUG ("gst_audiofilter_link");
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
audiofilter_class = GST_AUDIOFILTER_CLASS (
G_OBJECT_GET_CLASS (audiofilter));
audiofilter_class = GST_AUDIOFILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
if (pad == audiofilter->srcpad) {
link_ret = gst_pad_try_set_caps (audiofilter->sinkpad, caps);
@ -135,53 +140,55 @@ gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
if (strcmp (gst_structure_get_name (structure), "audio/x-raw-int") == 0) {
ret = gst_structure_get_int (structure, "depth", &audiofilter->depth);
ret &= gst_structure_get_int (structure, "width", &audiofilter->width);
ret &= gst_structure_get_int (structure, "channels", &audiofilter->channels);
ret &=
gst_structure_get_int (structure, "channels", &audiofilter->channels);
} else if (strcmp (gst_structure_get_name (structure), "audio/x-raw-float")
== 0) {
} else {
g_assert_not_reached();
g_assert_not_reached ();
}
ret &= gst_structure_get_int (structure, "rate", &audiofilter->rate);
audiofilter->bytes_per_sample = (audiofilter->width/8) *
audiofilter->channels;
audiofilter->bytes_per_sample = (audiofilter->width / 8) *
audiofilter->channels;
if (audiofilter_class->setup) (audiofilter_class->setup) (audiofilter);
if (audiofilter_class->setup)
(audiofilter_class->setup) (audiofilter);
return GST_PAD_LINK_OK;
}
static void
gst_audiofilter_init (GTypeInstance *instance, gpointer g_class)
gst_audiofilter_init (GTypeInstance * instance, gpointer g_class)
{
GstAudiofilter *audiofilter = GST_AUDIOFILTER (instance);
GstPadTemplate *pad_template;
GST_DEBUG("gst_audiofilter_init");
GST_DEBUG ("gst_audiofilter_init");
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
"sink");
g_return_if_fail(pad_template != NULL);
audiofilter->sinkpad = gst_pad_new_from_template(pad_template, "sink");
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->sinkpad);
gst_pad_set_chain_function(audiofilter->sinkpad,gst_audiofilter_chain);
gst_pad_set_link_function(audiofilter->sinkpad,gst_audiofilter_link);
gst_pad_set_getcaps_function(audiofilter->sinkpad,gst_pad_proxy_getcaps);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
g_return_if_fail (pad_template != NULL);
audiofilter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->sinkpad);
gst_pad_set_chain_function (audiofilter->sinkpad, gst_audiofilter_chain);
gst_pad_set_link_function (audiofilter->sinkpad, gst_audiofilter_link);
gst_pad_set_getcaps_function (audiofilter->sinkpad, gst_pad_proxy_getcaps);
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
"src");
g_return_if_fail(pad_template != NULL);
audiofilter->srcpad = gst_pad_new_from_template(pad_template, "src");
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->srcpad);
gst_pad_set_link_function(audiofilter->srcpad,gst_audiofilter_link);
gst_pad_set_getcaps_function(audiofilter->srcpad,gst_pad_proxy_getcaps);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
g_return_if_fail (pad_template != NULL);
audiofilter->srcpad = gst_pad_new_from_template (pad_template, "src");
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->srcpad);
gst_pad_set_link_function (audiofilter->srcpad, gst_audiofilter_link);
gst_pad_set_getcaps_function (audiofilter->srcpad, gst_pad_proxy_getcaps);
audiofilter->inited = FALSE;
}
static void
gst_audiofilter_chain (GstPad *pad, GstData *data)
gst_audiofilter_chain (GstPad * pad, GstData * data)
{
GstBuffer *inbuf = GST_BUFFER (data);
GstAudiofilter *audiofilter;
@ -196,60 +203,60 @@ gst_audiofilter_chain (GstPad *pad, GstData *data)
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
//g_return_if_fail (audiofilter->inited);
audiofilter_class = GST_AUDIOFILTER_CLASS (
G_OBJECT_GET_CLASS (audiofilter));
audiofilter_class = GST_AUDIOFILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
GST_DEBUG ("gst_audiofilter_chain: got buffer of %d bytes in '%s'",
GST_BUFFER_SIZE(inbuf), GST_OBJECT_NAME (audiofilter));
if(audiofilter->passthru){
gst_pad_push(audiofilter->srcpad, data);
GST_BUFFER_SIZE (inbuf), GST_OBJECT_NAME (audiofilter));
if (audiofilter->passthru) {
gst_pad_push (audiofilter->srcpad, data);
return;
}
audiofilter->size = GST_BUFFER_SIZE (inbuf);
audiofilter->n_samples = audiofilter->size / audiofilter->bytes_per_sample;
if (gst_data_is_writable(data)) {
if (gst_data_is_writable (data)) {
if (audiofilter_class->filter_inplace) {
(audiofilter_class->filter_inplace) (audiofilter, inbuf);
outbuf = inbuf;
} else {
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
gst_buffer_unref(inbuf);
gst_buffer_unref (inbuf);
}
} else {
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
if (audiofilter_class->filter) {
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
} else {
memcpy(GST_BUFFER_DATA(outbuf), GST_BUFFER_DATA(inbuf),
GST_BUFFER_SIZE(inbuf));
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
GST_BUFFER_SIZE (inbuf));
(audiofilter_class->filter_inplace) (audiofilter, outbuf);
}
gst_buffer_unref(inbuf);
gst_buffer_unref (inbuf);
}
gst_pad_push(audiofilter->srcpad, GST_DATA (outbuf));
gst_pad_push (audiofilter->srcpad, GST_DATA (outbuf));
}
static void
gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_audiofilter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstAudiofilter *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER(object));
src = GST_AUDIOFILTER(object);
g_return_if_fail (GST_IS_AUDIOFILTER (object));
src = GST_AUDIOFILTER (object);
GST_DEBUG("gst_audiofilter_set_property");
GST_DEBUG ("gst_audiofilter_set_property");
switch (prop_id) {
default:
break;
@ -257,13 +264,14 @@ gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *valu
}
static void
gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_audiofilter_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstAudiofilter *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER(object));
src = GST_AUDIOFILTER(object);
g_return_if_fail (GST_IS_AUDIOFILTER (object));
src = GST_AUDIOFILTER (object);
switch (prop_id) {
default:
@ -272,37 +280,31 @@ gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GPa
}
}
void gst_audiofilter_class_add_pad_templates (
GstAudiofilterClass *audiofilter_class, const GstCaps *caps)
void
gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *
audiofilter_class, const GstCaps * caps)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (audiofilter_class);
audiofilter_class->caps = gst_caps_copy(caps);
audiofilter_class->caps = gst_caps_copy (caps);
gst_element_class_add_pad_template (element_class,
gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_caps_copy(caps)));
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_caps_copy (caps)));
gst_element_class_add_pad_template (element_class,
gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_copy(caps)));
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_copy (caps)));
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter",
"Audio filter parent class",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter",
"Audio filter parent class",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)

View file

@ -25,17 +25,15 @@
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct _GstAudiofilter GstAudiofilter;
G_BEGIN_DECLS typedef struct _GstAudiofilter GstAudiofilter;
typedef struct _GstAudiofilterClass GstAudiofilterClass;
typedef void (*GstAudiofilterFilterFunc)(GstAudiofilter *filter,
GstBuffer *outbuf, GstBuffer *inbuf);
typedef void (*GstAudiofilterInplaceFilterFunc)(GstAudiofilter *filter,
GstBuffer *buffer);
typedef void (*GstAudiofilterFilterFunc) (GstAudiofilter * filter,
GstBuffer * outbuf, GstBuffer * inbuf);
typedef void (*GstAudiofilterInplaceFilterFunc) (GstAudiofilter * filter,
GstBuffer * buffer);
typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter *filter);
typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter * filter);
#define GST_TYPE_AUDIOFILTER \
@ -49,10 +47,11 @@ typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter *filter);
#define GST_IS_AUDIOFILTER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER))
struct _GstAudiofilter {
struct _GstAudiofilter
{
GstElement element;
GstPad *sinkpad,*srcpad;
GstPad *sinkpad, *srcpad;
/* audio state */
gboolean inited;
@ -68,7 +67,8 @@ struct _GstAudiofilter {
int bytes_per_sample;
};
struct _GstAudiofilterClass {
struct _GstAudiofilterClass
{
GstElementClass parent_class;
GstCaps *caps;
@ -77,11 +77,10 @@ struct _GstAudiofilterClass {
GstAudiofilterFilterFunc filter;
};
GType gst_audiofilter_get_type(void);
GType gst_audiofilter_get_type (void);
void gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *audiofilterclass, const GstCaps *caps);
void gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *
audiofilterclass, const GstCaps * caps);
G_END_DECLS
#endif /* __GST_AUDIOFILTER_H__ */

View file

@ -48,37 +48,47 @@ typedef struct _GstAudiofilterTemplateClass GstAudiofilterTemplateClass;
#define GST_IS_AUDIOFILTER_TEMPLATE_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER_TEMPLATE))
struct _GstAudiofilterTemplate {
struct _GstAudiofilterTemplate
{
GstAudiofilter audiofilter;
};
struct _GstAudiofilterTemplateClass {
struct _GstAudiofilterTemplateClass
{
GstAudiofilterClass parent_class;
};
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum {
enum
{
ARG_0,
/* FILL ME */
};
static void gst_audiofilter_template_base_init (gpointer g_class);
static void gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data);
static void gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class);
static void gst_audiofilter_template_base_init (gpointer g_class);
static void gst_audiofilter_template_class_init (gpointer g_class,
gpointer class_data);
static void gst_audiofilter_template_init (GTypeInstance * instance,
gpointer g_class);
static void gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_audiofilter_template_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_audiofilter_template_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_audiofilter_template_setup (GstAudiofilter *audiofilter);
static void gst_audiofilter_template_filter (GstAudiofilter *audiofilter, GstBuffer *outbuf, GstBuffer *inbuf);
static void gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter, GstBuffer *buf);
static void gst_audiofilter_template_setup (GstAudiofilter * audiofilter);
static void gst_audiofilter_template_filter (GstAudiofilter * audiofilter,
GstBuffer * outbuf, GstBuffer * inbuf);
static void gst_audiofilter_template_filter_inplace (GstAudiofilter *
audiofilter, GstBuffer * buf);
GType
gst_audiofilter_template_get_type (void)
@ -87,23 +97,24 @@ gst_audiofilter_template_get_type (void)
if (!audiofilter_template_type) {
static const GTypeInfo audiofilter_template_info = {
sizeof(GstAudiofilterTemplateClass),
sizeof (GstAudiofilterTemplateClass),
gst_audiofilter_template_base_init,
NULL,
gst_audiofilter_template_class_init,
NULL,
gst_audiofilter_template_init,
sizeof(GstAudiofilterTemplate),
sizeof (GstAudiofilterTemplate),
0,
NULL,
};
audiofilter_template_type = g_type_register_static(GST_TYPE_AUDIOFILTER,
audiofilter_template_type = g_type_register_static (GST_TYPE_AUDIOFILTER,
"GstAudiofilterTemplate", &audiofilter_template_info, 0);
}
return audiofilter_template_type;
}
static void gst_audiofilter_template_base_init (gpointer g_class)
static void
gst_audiofilter_template_base_init (gpointer g_class)
{
static GstElementDetails audiofilter_template_details = {
"Audio filter template",
@ -128,16 +139,16 @@ gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data)
GstAudiofilterTemplateClass *klass;
GstAudiofilterClass *audiofilter_class;
klass = (GstAudiofilterTemplateClass *)g_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
audiofilter_class = (GstAudiofilterClass *)g_class;
klass = (GstAudiofilterTemplateClass *) g_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
audiofilter_class = (GstAudiofilterClass *) g_class;
#if 0
g_object_class_install_property(gobject_class, ARG_METHOD,
g_param_spec_enum("method","method","method",
GST_TYPE_AUDIOTEMPLATE_METHOD, GST_AUDIOTEMPLATE_METHOD_1,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_METHOD,
g_param_spec_enum ("method", "method", "method",
GST_TYPE_AUDIOTEMPLATE_METHOD, GST_AUDIOTEMPLATE_METHOD_1,
G_PARAM_READWRITE));
#endif
gobject_class->set_property = gst_audiofilter_template_set_property;
@ -146,11 +157,11 @@ gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data)
audiofilter_class->setup = gst_audiofilter_template_setup;
audiofilter_class->filter = gst_audiofilter_template_filter;
audiofilter_class->filter_inplace = gst_audiofilter_template_filter_inplace;
audiofilter_class->filter = NULL;
audiofilter_class->filter = NULL;
}
static void
gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class)
gst_audiofilter_template_init (GTypeInstance * instance, gpointer g_class)
{
//GstAudiofilterTemplate *audiofilter_template = GST_AUDIOFILTER_TEMPLATE (instance);
//GstAudiofilter *audiofilter = GST_AUDIOFILTER (instance);
@ -162,15 +173,16 @@ gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class)
}
static void
gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
gst_audiofilter_template_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstAudiofilterTemplate *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER_TEMPLATE(object));
src = GST_AUDIOFILTER_TEMPLATE(object);
g_return_if_fail (GST_IS_AUDIOFILTER_TEMPLATE (object));
src = GST_AUDIOFILTER_TEMPLATE (object);
GST_DEBUG("gst_audiofilter_template_set_property");
GST_DEBUG ("gst_audiofilter_template_set_property");
switch (prop_id) {
default:
break;
@ -178,13 +190,14 @@ gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GVa
}
static void
gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
gst_audiofilter_template_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstAudiofilterTemplate *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER_TEMPLATE(object));
src = GST_AUDIOFILTER_TEMPLATE(object);
g_return_if_fail (GST_IS_AUDIOFILTER_TEMPLATE (object));
src = GST_AUDIOFILTER_TEMPLATE (object);
switch (prop_id) {
default:
@ -194,7 +207,7 @@ gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *v
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
if (!gst_library_load ("gstaudiofilter"))
return FALSE;
@ -203,20 +216,13 @@ plugin_init (GstPlugin *plugin)
GST_TYPE_AUDIOFILTER_TEMPLATE);
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter_template",
"Audio filter template",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter_template",
"Audio filter template",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
static void
gst_audiofilter_template_setup (GstAudiofilter *audiofilter)
static void gst_audiofilter_template_setup (GstAudiofilter * audiofilter)
{
GstAudiofilterTemplate *audiofilter_template;
@ -234,8 +240,8 @@ gst_audiofilter_template_setup (GstAudiofilter *audiofilter)
* with a minimum of memory copies. */
static void
gst_audiofilter_template_filter (GstAudiofilter *audiofilter,
GstBuffer *outbuf, GstBuffer *inbuf)
gst_audiofilter_template_filter (GstAudiofilter * audiofilter,
GstBuffer * outbuf, GstBuffer * inbuf)
{
GstAudiofilterTemplate *audiofilter_template;
@ -245,13 +251,12 @@ gst_audiofilter_template_filter (GstAudiofilter *audiofilter,
/* do something interesting here. This simply copies the source
* to the destination. */
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
audiofilter->size);
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf), audiofilter->size);
}
static void
gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter,
GstBuffer *buf)
gst_audiofilter_template_filter_inplace (GstAudiofilter * audiofilter,
GstBuffer * buf)
{
GstAudiofilterTemplate *audiofilter_template;
@ -262,4 +267,3 @@ gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter,
* to the destination. */
}

View file

@ -27,12 +27,13 @@
#include "colorbalance.h"
#include "colorbalance-marshal.h"
enum {
enum
{
VALUE_CHANGED,
LAST_SIGNAL
};
static void gst_color_balance_class_init (GstColorBalanceClass *klass);
static void gst_color_balance_class_init (GstColorBalanceClass * klass);
static guint gst_color_balance_signals[LAST_SIGNAL] = { 0 };
@ -55,35 +56,33 @@ gst_color_balance_get_type (void)
};
gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE,
"GstColorBalance",
&gst_color_balance_info, 0);
"GstColorBalance", &gst_color_balance_info, 0);
g_type_interface_add_prerequisite (gst_color_balance_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_color_balance_type;
}
static void
gst_color_balance_class_init (GstColorBalanceClass *klass)
gst_color_balance_class_init (GstColorBalanceClass * klass)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_color_balance_signals[VALUE_CHANGED] =
g_signal_new ("value-changed",
GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
NULL, NULL,
gst_color_balance_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2,
GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
g_signal_new ("value-changed",
GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
NULL, NULL,
gst_color_balance_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2, GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
initialized = TRUE;
}
klass->balance_type = GST_COLOR_BALANCE_SOFTWARE;
/* default virtual functions */
klass->list_channels = NULL;
klass->set_value = NULL;
@ -91,7 +90,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
}
const GList *
gst_color_balance_list_channels (GstColorBalance *balance)
gst_color_balance_list_channels (GstColorBalance * balance)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -103,9 +102,8 @@ gst_color_balance_list_channels (GstColorBalance *balance)
}
void
gst_color_balance_set_value (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value)
gst_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -115,8 +113,8 @@ gst_color_balance_set_value (GstColorBalance *balance,
}
gint
gst_color_balance_get_value (GstColorBalance *balance,
GstColorBalanceChannel *channel)
gst_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel * channel)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -128,13 +126,11 @@ gst_color_balance_get_value (GstColorBalance *balance,
}
void
gst_color_balance_value_changed (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value)
gst_color_balance_value_changed (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value)
{
g_signal_emit (G_OBJECT (balance),
gst_color_balance_signals[VALUE_CHANGED],
0, channel, value);
gst_color_balance_signals[VALUE_CHANGED], 0, channel, value);
g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
}

View file

@ -27,7 +27,6 @@
#include <gst/colorbalance/colorbalance-enumtypes.h>
G_BEGIN_DECLS
#define GST_TYPE_COLOR_BALANCE \
(gst_color_balance_get_type ())
#define GST_COLOR_BALANCE(obj) \
@ -42,55 +41,48 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE))
#define GST_COLOR_BALANCE_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass))
#define GST_COLOR_BALANCE_TYPE(klass) (klass->balance_type)
typedef struct _GstColorBalance GstColorBalance;
typedef enum
{
GST_COLOR_BALANCE_HARDWARE,
GST_COLOR_BALANCE_SOFTWARE
} GstColorBalanceType;
typedef struct _GstColorBalanceClass {
typedef struct _GstColorBalanceClass
{
GTypeInterface klass;
GstColorBalanceType balance_type;
/* virtual functions */
const GList * (* list_channels) (GstColorBalance *balance);
void (* set_value) (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
gint (* get_value) (GstColorBalance *balance,
GstColorBalanceChannel *channel);
/* virtual functions */
const GList *(*list_channels) (GstColorBalance * balance);
void (*set_value) (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gint (*get_value) (GstColorBalance * balance,
GstColorBalanceChannel * channel);
/* signals */
void (* value_changed) (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
void (*value_changed) (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceClass;
GType gst_color_balance_get_type (void);
GType gst_color_balance_get_type (void);
/* virtual class function wrappers */
const GList *
gst_color_balance_list_channels (GstColorBalance *balance);
void gst_color_balance_set_value (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
gint gst_color_balance_get_value (GstColorBalance *balance,
GstColorBalanceChannel *channel);
const GList *gst_color_balance_list_channels (GstColorBalance * balance);
void gst_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gint gst_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel * channel);
/* trigger signal */
void gst_color_balance_value_changed (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
void gst_color_balance_value_changed (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
G_END_DECLS
#endif /* __GST_COLOR_BALANCE_H__ */

View file

@ -25,15 +25,17 @@
#include "colorbalancechannel.h"
enum {
enum
{
/* FILL ME */
SIGNAL_VALUE_CHANGED,
LAST_SIGNAL
};
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass);
static void gst_color_balance_channel_init (GstColorBalanceChannel *balance);
static void gst_color_balance_channel_dispose (GObject *object);
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *
klass);
static void gst_color_balance_channel_init (GstColorBalanceChannel * balance);
static void gst_color_balance_channel_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
@ -59,46 +61,44 @@ gst_color_balance_channel_get_type (void)
gst_color_balance_channel_type =
g_type_register_static (G_TYPE_OBJECT,
"GstColorBalanceChannel",
&color_balance_channel_info, 0);
"GstColorBalanceChannel", &color_balance_channel_info, 0);
}
return gst_color_balance_channel_type;
}
static void
gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
gst_color_balance_channel_class_init (GstColorBalanceChannelClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
signals[SIGNAL_VALUE_CHANGED] =
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
value_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
value_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
object_klass->dispose = gst_color_balance_channel_dispose;
}
static void
gst_color_balance_channel_init (GstColorBalanceChannel *channel)
gst_color_balance_channel_init (GstColorBalanceChannel * channel)
{
channel->label = NULL;
channel->min_value = channel->max_value = 0;
}
static void
gst_color_balance_channel_dispose (GObject *object)
gst_color_balance_channel_dispose (GObject * object)
{
GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object);
if (channel->label)
g_free (channel->label);
channel->label = NULL;
if (parent_class->dispose)

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_COLOR_BALANCE_CHANNEL \
(gst_color_balance_channel_get_type ())
#define GST_COLOR_BALANCE_CHANNEL(obj) \
@ -38,27 +37,25 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL))
#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL))
typedef struct _GstColorBalanceChannel {
typedef struct _GstColorBalanceChannel
{
GObject parent;
gchar *label;
gint min_value,
max_value;
gchar *label;
gint min_value, max_value;
} GstColorBalanceChannel;
typedef struct _GstColorBalanceChannelClass {
typedef struct _GstColorBalanceChannelClass
{
GObjectClass parent;
/* signals */
void (* value_changed) (GstColorBalanceChannel *channel,
gint value);
void (*value_changed) (GstColorBalanceChannel * channel, gint value);
gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceChannelClass;
GType gst_color_balance_channel_get_type (void);
GType gst_color_balance_channel_get_type (void);
G_END_DECLS
#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */

View file

@ -29,53 +29,46 @@
#include <glib/gtypes.h>
G_BEGIN_DECLS
#if (HAVE_LRINT && HAVE_LRINTF)
/* These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to
** engage them. If optimisation is enabled, these functions will be
** inlined. With optimisation switched off, you have to link in the
** maths library using -lm.
*/
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#define gst_cast_float(x) ((gint)lrintf(x))
#define gst_cast_double(x) ((gint)lrint(x))
/* These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to
** engage them. If optimisation is enabled, these functions will be
** inlined. With optimisation switched off, you have to link in the
** maths library using -lm.
*/
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#define gst_cast_float(x) ((gint)lrintf(x))
#define gst_cast_double(x) ((gint)lrint(x))
#else
/* use a standard c cast, but do rounding correctly */
#define gst_cast_float(x) ((gint)floor((x)+0.5))
#define gst_cast_double(x) ((gint)floor((x)+0.5))
/* use a standard c cast, but do rounding correctly */
#define gst_cast_float(x) ((gint)floor((x)+0.5))
#define gst_cast_double(x) ((gint)floor((x)+0.5))
#endif
inline static gfloat
GFLOAT_SWAP_LE_BE(gfloat in)
GFLOAT_SWAP_LE_BE (gfloat in)
{
gint32 swap;
gfloat out;
memcpy(&swap, &in, 4);
memcpy (&swap, &in, 4);
swap = GUINT32_SWAP_LE_BE_CONSTANT (swap);
memcpy(&out, &swap, 4);
memcpy (&out, &swap, 4);
return out;
}
inline static gdouble
GDOUBLE_SWAP_LE_BE(gdouble in)
GDOUBLE_SWAP_LE_BE (gdouble in)
{
gint64 swap;
gdouble out;
memcpy(&swap, &in, 8);
memcpy (&swap, &in, 8);
swap = GUINT64_SWAP_LE_BE_CONSTANT (swap);
memcpy(&out, &swap, 8);
memcpy (&out, &swap, 8);
return out;
}
@ -101,6 +94,4 @@ GDOUBLE_SWAP_LE_BE(gdouble in)
#define GDOUBLE_FROM_BE(val) (GDOUBLE_TO_BE (val))
G_END_DECLS
#endif /* __FLOATCAST_H__ */

View file

@ -31,7 +31,7 @@
#error "GST_GCONF_DIR is not defined !"
#endif
static GConfClient *_gst_gconf_client = NULL; /* GConf connection */
static GConfClient *_gst_gconf_client = NULL; /* GConf connection */
/* internal functions */
@ -48,7 +48,7 @@ gst_gconf_get_client (void)
/* go through a bin, finding the one pad that is unconnected in the given
* * direction, and return that pad */
static GstPad *
gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
{
GstPad *pad = NULL;
GList *elements = NULL;
@ -57,22 +57,19 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
elements = (GList *) gst_bin_get_list (bin);
/* traverse all elements looking for unconnected pads */
while (elements && pad == NULL)
{
while (elements && pad == NULL) {
element = GST_ELEMENT (elements->data);
pads = gst_element_get_pad_list (element);
while (pads)
{
while (pads) {
/* check if the direction matches */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction)
{
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL)
{
/* found it ! */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
/* found it ! */
pad = GST_PAD (pads->data);
}
}
if (pad) break; /* found one already */
if (pad)
break; /* found one already */
pads = g_list_next (pads);
}
elements = g_list_next (elements);
@ -91,7 +88,7 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
* Returns: a #gchar string containing @key's value.
*/
gchar *
gst_gconf_get_string (const gchar *key)
gst_gconf_get_string (const gchar * key)
{
GError *error = NULL;
gchar *value = NULL;
@ -101,8 +98,7 @@ gst_gconf_get_string (const gchar *key)
value = gconf_client_get_string (gst_gconf_get_client (), full_key, &error);
g_free (full_key);
if (error)
{
if (error) {
g_print ("gst_gconf_get_string: error: %s\n", error->message);
g_error_free (error);
}
@ -118,14 +114,13 @@ gst_gconf_get_string (const gchar *key)
* Set GConf key @key to string value @value.
*/
void
gst_gconf_set_string (const gchar *key, const gchar *value)
gst_gconf_set_string (const gchar * key, const gchar * value)
{
GError *error = NULL;
gchar *full_key = g_strdup_printf ("%s/%s", GST_GCONF_DIR, key);
gconf_client_set_string (gst_gconf_get_client (), full_key, value, &error);
if (error)
{
if (error) {
g_print ("gst_gconf_set_string: error: %s\n", error->message);
g_error_free (error);
}
@ -141,7 +136,7 @@ gst_gconf_set_string (const gchar *key, const gchar *value)
* Returns: a #GstElement containing the rendered bin.
*/
GstElement *
gst_gconf_render_bin_from_description (const gchar *description)
gst_gconf_render_bin_from_description (const gchar * description)
{
GstElement *bin = NULL;
GstPad *pad = NULL;
@ -152,19 +147,18 @@ gst_gconf_render_bin_from_description (const gchar *description)
desc = g_strdup_printf ("bin.( %s )", description);
bin = GST_ELEMENT (gst_parse_launch (desc, &error));
g_free (desc);
if (error)
{
if (error) {
g_print ("DEBUG: gstgconf: error parsing pipeline %s\n%s\n",
description, error->message);
description, error->message);
g_error_free (error);
return NULL;
}
/* find pads and ghost them if necessary */
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))){
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))) {
gst_element_add_ghost_pad (bin, pad, "src");
}
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK))){
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK))) {
gst_element_add_ghost_pad (bin, pad, "sink");
}
return bin;
@ -179,11 +173,11 @@ gst_gconf_render_bin_from_description (const gchar *description)
* Returns: a #GstElement containing the rendered bin.
*/
GstElement *
gst_gconf_render_bin_from_key (const gchar *key)
gst_gconf_render_bin_from_key (const gchar * key)
{
GstElement *bin = NULL;
gchar *value;
value = gst_gconf_get_string (key);
if (value)
bin = gst_gconf_render_bin_from_description (value);
@ -203,10 +197,10 @@ GstElement *
gst_gconf_get_default_audio_sink (void)
{
GstElement *ret = gst_gconf_render_bin_from_key ("default/audiosink");
if (!ret) {
ret = gst_element_factory_make ("osssink", NULL);
if (!ret)
g_warning ("No GConf default audio sink key and osssink doesn't work");
else
@ -229,10 +223,10 @@ GstElement *
gst_gconf_get_default_video_sink (void)
{
GstElement *ret = gst_gconf_render_bin_from_key ("default/videosink");
if (!ret) {
ret = gst_element_factory_make ("ximagesink", NULL);
if (!ret)
g_warning ("No GConf default video sink key and ximagesink doesn't work");
else
@ -255,10 +249,10 @@ GstElement *
gst_gconf_get_default_audio_src (void)
{
GstElement *ret = gst_gconf_render_bin_from_key ("default/audiosrc");
if (!ret) {
ret = gst_element_factory_make ("osssrc", NULL);
if (!ret)
g_warning ("No GConf default audio src key and osssrc doesn't work");
else
@ -282,10 +276,10 @@ GstElement *
gst_gconf_get_default_video_src (void)
{
GstElement *ret = gst_gconf_render_bin_from_key ("default/videosrc");
if (!ret) {
ret = gst_element_factory_make ("videotestsrc", NULL);
if (!ret)
g_warning ("No GConf default video src key and videotestrc doesn't work");
else
@ -308,16 +302,16 @@ GstElement *
gst_gconf_get_default_visualization_element (void)
{
GstElement *ret = gst_gconf_render_bin_from_key ("default/visualization");
if (!ret) {
ret = gst_element_factory_make ("goom", NULL);
if (!ret)
g_warning ("No GConf default visualization plugin key and goom doesn't work");
g_warning
("No GConf default visualization plugin key and goom doesn't work");
else
g_print ("GConf visualization plugin not found, using goom\n");
}
return ret;
}

View file

@ -27,17 +27,16 @@
#include <gst/gst.h>
#include <gconf/gconf-client.h>
gchar * gst_gconf_get_string (const gchar *key);
void gst_gconf_set_string (const gchar *key,
const gchar *value);
gchar *gst_gconf_get_string (const gchar * key);
void gst_gconf_set_string (const gchar * key, const gchar * value);
GstElement * gst_gconf_render_bin_from_key (const gchar *key);
GstElement * gst_gconf_render_bin_from_description (const gchar *description);
GstElement *gst_gconf_render_bin_from_key (const gchar * key);
GstElement *gst_gconf_render_bin_from_description (const gchar * description);
GstElement * gst_gconf_get_default_video_sink (void);
GstElement * gst_gconf_get_default_audio_sink (void);
GstElement * gst_gconf_get_default_video_src (void);
GstElement * gst_gconf_get_default_audio_src (void);
GstElement * gst_gconf_get_default_visualization_element (void);
GstElement *gst_gconf_get_default_video_sink (void);
GstElement *gst_gconf_get_default_audio_sink (void);
GstElement *gst_gconf_get_default_video_src (void);
GstElement *gst_gconf_get_default_audio_src (void);
GstElement *gst_gconf_get_default_visualization_element (void);
#endif /* GST_GCONF_H */

View file

@ -22,13 +22,13 @@
int
main (int argc, char *argv[])
{
printf ("Default video sink : %s\n",
gst_gconf_get_string ("default/videosink"));
printf ("Default audio sink : %s\n",
gst_gconf_get_string ("default/audiosink"));
printf ("Default video src : %s\n",
gst_gconf_get_string ("default/videosrc"));
printf ("Default audio src : %s\n",
gst_gconf_get_string ("default/audiosrc"));
printf ("Default video sink : %s\n",
gst_gconf_get_string ("default/videosink"));
printf ("Default audio sink : %s\n",
gst_gconf_get_string ("default/audiosink"));
printf ("Default video src : %s\n",
gst_gconf_get_string ("default/videosrc"));
printf ("Default audio src : %s\n",
gst_gconf_get_string ("default/audiosrc"));
return 0;
}

View file

@ -22,8 +22,8 @@
#ifndef __GST_I18N_PLUGIN_H__
#define __GST_I18N_PLUGIN_H__
#include <locale.h> /* some people need it and some people don't */
#include "gettext.h" /* included with gettext distribution and copied */
#include <locale.h> /* some people need it and some people don't */
#include "gettext.h" /* included with gettext distribution and copied */
#ifndef GETTEXT_PACKAGE
#error You must define GETTEXT_PACKAGE before including this header.

View file

@ -16,7 +16,7 @@ typedef DCTELEM DCTBLOCK[DCTSIZE2];
typedef long INT32; /* must be at least 32 bits */
extern void gst_idct_int_idct();
extern void gst_idct_int_idct ();
extern void gst_idct_init_fast_int_idct (void);
extern void gst_idct_fast_int_idct (short *block);
@ -27,6 +27,5 @@ extern void gst_idct_mmx32_idct (short *block);
extern void gst_idct_sse_idct (short *block);
#endif /* HAVE_LIBMMX */
extern void gst_idct_init_float_idct(void);
extern void gst_idct_init_float_idct (void);
extern void gst_idct_float_idct (short *block);

View file

@ -45,17 +45,17 @@
/* this code assumes >> to be a two's-complement arithmetic */
/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
#include "dct.h"
/* private data */
static short iclip[1024]; /* clipping table */
static short iclip[1024]; /* clipping table */
static short *iclp;
/* private prototypes */
@ -72,57 +72,58 @@ static void idctcol (short *blk);
* c[1..7] = 128*sqrt(2)
*/
static void idctrow(blk)
short *blk;
static void
idctrow (blk)
short *blk;
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
/* shortcut */
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
{
blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
if (!((x1 = blk[4] << 11) | (x2 = blk[6]) | (x3 = blk[2]) |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) {
blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] =
blk[0] << 3;
return;
}
x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
x0 = (blk[0] << 11) + 128; /* for proper rounding in the fourth stage */
/* first stage */
x8 = W7*(x4+x5);
x4 = x8 + (W1-W7)*x4;
x5 = x8 - (W1+W7)*x5;
x8 = W3*(x6+x7);
x6 = x8 - (W3-W5)*x6;
x7 = x8 - (W3+W5)*x7;
x8 = W7 * (x4 + x5);
x4 = x8 + (W1 - W7) * x4;
x5 = x8 - (W1 + W7) * x5;
x8 = W3 * (x6 + x7);
x6 = x8 - (W3 - W5) * x6;
x7 = x8 - (W3 + W5) * x7;
/* second stage */
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2);
x2 = x1 - (W2+W6)*x2;
x3 = x1 + (W2-W6)*x3;
x1 = W6 * (x3 + x2);
x2 = x1 - (W2 + W6) * x2;
x3 = x1 + (W2 - W6) * x3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;
/* third stage */
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;
x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */
blk[0] = (x7+x1)>>8;
blk[1] = (x3+x2)>>8;
blk[2] = (x0+x4)>>8;
blk[3] = (x8+x6)>>8;
blk[4] = (x8-x6)>>8;
blk[5] = (x0-x4)>>8;
blk[6] = (x3-x2)>>8;
blk[7] = (x7-x1)>>8;
blk[0] = (x7 + x1) >> 8;
blk[1] = (x3 + x2) >> 8;
blk[2] = (x0 + x4) >> 8;
blk[3] = (x8 + x6) >> 8;
blk[4] = (x8 - x6) >> 8;
blk[5] = (x0 - x4) >> 8;
blk[6] = (x3 - x2) >> 8;
blk[7] = (x7 - x1) >> 8;
}
/* column (vertical) IDCT
@ -134,78 +135,81 @@ short *blk;
* where: c[0] = 1/1024
* c[1..7] = (1/1024)*sqrt(2)
*/
static void idctcol(blk)
short *blk;
static void
idctcol (blk)
short *blk;
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
/* shortcut */
if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
(x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
{
blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
iclp[(blk[8*0]+32)>>6];
if (!((x1 = (blk[8 * 4] << 8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) |
(x4 = blk[8 * 1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 =
blk[8 * 3]))) {
blk[8 * 0] = blk[8 * 1] = blk[8 * 2] = blk[8 * 3] = blk[8 * 4] =
blk[8 * 5] = blk[8 * 6] = blk[8 * 7] = iclp[(blk[8 * 0] + 32) >> 6];
return;
}
x0 = (blk[8*0]<<8) + 8192;
x0 = (blk[8 * 0] << 8) + 8192;
/* first stage */
x8 = W7*(x4+x5) + 4;
x4 = (x8+(W1-W7)*x4)>>3;
x5 = (x8-(W1+W7)*x5)>>3;
x8 = W3*(x6+x7) + 4;
x6 = (x8-(W3-W5)*x6)>>3;
x7 = (x8-(W3+W5)*x7)>>3;
x8 = W7 * (x4 + x5) + 4;
x4 = (x8 + (W1 - W7) * x4) >> 3;
x5 = (x8 - (W1 + W7) * x5) >> 3;
x8 = W3 * (x6 + x7) + 4;
x6 = (x8 - (W3 - W5) * x6) >> 3;
x7 = (x8 - (W3 + W5) * x7) >> 3;
/* second stage */
x8 = x0 + x1;
x0 -= x1;
x1 = W6*(x3+x2) + 4;
x2 = (x1-(W2+W6)*x2)>>3;
x3 = (x1+(W2-W6)*x3)>>3;
x1 = W6 * (x3 + x2) + 4;
x2 = (x1 - (W2 + W6) * x2) >> 3;
x3 = (x1 + (W2 - W6) * x3) >> 3;
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
x5 -= x7;
/* third stage */
x7 = x8 + x3;
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
x2 = (181*(x4+x5)+128)>>8;
x4 = (181*(x4-x5)+128)>>8;
x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */
blk[8*0] = iclp[(x7+x1)>>14];
blk[8*1] = iclp[(x3+x2)>>14];
blk[8*2] = iclp[(x0+x4)>>14];
blk[8*3] = iclp[(x8+x6)>>14];
blk[8*4] = iclp[(x8-x6)>>14];
blk[8*5] = iclp[(x0-x4)>>14];
blk[8*6] = iclp[(x3-x2)>>14];
blk[8*7] = iclp[(x7-x1)>>14];
blk[8 * 0] = iclp[(x7 + x1) >> 14];
blk[8 * 1] = iclp[(x3 + x2) >> 14];
blk[8 * 2] = iclp[(x0 + x4) >> 14];
blk[8 * 3] = iclp[(x8 + x6) >> 14];
blk[8 * 4] = iclp[(x8 - x6) >> 14];
blk[8 * 5] = iclp[(x0 - x4) >> 14];
blk[8 * 6] = iclp[(x3 - x2) >> 14];
blk[8 * 7] = iclp[(x7 - x1) >> 14];
}
/* two dimensional inverse discrete cosine transform */
void gst_idct_fast_int_idct(block)
short *block;
void
gst_idct_fast_int_idct (block)
short *block;
{
int i;
for (i=0; i<8; i++)
idctrow(block+8*i);
for (i = 0; i < 8; i++)
idctrow (block + 8 * i);
for (i=0; i<8; i++)
idctcol(block+i);
for (i = 0; i < 8; i++)
idctcol (block + i);
}
void gst_idct_init_fast_int_idct()
void
gst_idct_init_fast_int_idct ()
{
int i;
iclp = iclip+512;
for (i= -512; i<512; i++)
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
iclp = iclip + 512;
for (i = -512; i < 512; i++)
iclp[i] = (i < -256) ? -256 : ((i > 255) ? 255 : i);
}

View file

@ -56,51 +56,51 @@ static double gst_idct_float_c[8][8];
/* initialize DCT coefficient matrix */
void gst_idct_init_float_idct()
void
gst_idct_init_float_idct ()
{
int freq, time;
double scale;
for (freq=0; freq < 8; freq++)
{
scale = (freq == 0) ? sqrt(0.125) : 0.5;
for (time=0; time<8; time++)
gst_idct_float_c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
for (freq = 0; freq < 8; freq++) {
scale = (freq == 0) ? sqrt (0.125) : 0.5;
for (time = 0; time < 8; time++)
gst_idct_float_c[freq][time] =
scale * cos ((PI / 8.0) * freq * (time + 0.5));
}
}
/* perform IDCT matrix multiply for 8x8 coefficient block */
void gst_idct_float_idct(block)
short *block;
void
gst_idct_float_idct (block)
short *block;
{
int i, j, k, v;
double partial_product;
double tmp[64];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
{
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++) {
partial_product = 0.0;
for (k=0; k<8; k++)
partial_product+= gst_idct_float_c[k][j]*block[8*i+k];
for (k = 0; k < 8; k++)
partial_product += gst_idct_float_c[k][j] * block[8 * i + k];
tmp[8*i+j] = partial_product;
tmp[8 * i + j] = partial_product;
}
/* Transpose operation is integrated into address mapping by switching
loop order of i and j */
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
for (j = 0; j < 8; j++)
for (i = 0; i < 8; i++) {
partial_product = 0.0;
for (k=0; k<8; k++)
partial_product+= gst_idct_float_c[k][i]*tmp[8*k+j];
for (k = 0; k < 8; k++)
partial_product += gst_idct_float_c[k][i] * tmp[8 * k + j];
v = (int) floor(partial_product+0.5);
block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v);
v = (int) floor (partial_product + 0.5);
block[8 * i + j] = (v < -256) ? -256 : ((v > 255) ? 255 : v);
}
}

View file

@ -25,24 +25,25 @@
#include <gst/idct/idct.h>
#include "dct.h"
static void gst_idct_int_sparse_idct(short *data);
static void gst_idct_int_sparse_idct (short *data);
GstIDCT *gst_idct_new(GstIDCTMethod method)
GstIDCT *
gst_idct_new (GstIDCTMethod method)
{
GstIDCT *new = g_malloc(sizeof(GstIDCT));
GstIDCT *new = g_malloc (sizeof (GstIDCT));
new->need_transpose = FALSE;
if (method == GST_IDCT_DEFAULT) {
#ifdef HAVE_LIBMMX
if (gst_cpu_get_flags() & GST_CPU_FLAG_MMX) {
if (gst_cpu_get_flags () & GST_CPU_FLAG_MMX) {
method = GST_IDCT_MMX;
}
/* disabled for now
if (gst_cpu_get_flags() & GST_CPU_FLAG_SSE) {
method = GST_IDCT_SSE;
}
*/
if (gst_cpu_get_flags() & GST_CPU_FLAG_SSE) {
method = GST_IDCT_SSE;
}
*/
else
#endif /* HAVE_LIBMMX */
{
@ -53,49 +54,50 @@ GstIDCT *gst_idct_new(GstIDCTMethod method)
new->convert_sparse = gst_idct_int_sparse_idct;
switch (method) {
case GST_IDCT_FAST_INT:
GST_INFO ( "using fast_int_idct");
gst_idct_init_fast_int_idct();
new->convert = gst_idct_fast_int_idct;
break;
case GST_IDCT_INT:
GST_INFO ( "using int_idct");
new->convert = gst_idct_int_idct;
break;
case GST_IDCT_FLOAT:
GST_INFO ( "using float_idct");
gst_idct_init_float_idct();
new->convert = gst_idct_float_idct;
break;
case GST_IDCT_FAST_INT:
GST_INFO ("using fast_int_idct");
gst_idct_init_fast_int_idct ();
new->convert = gst_idct_fast_int_idct;
break;
case GST_IDCT_INT:
GST_INFO ("using int_idct");
new->convert = gst_idct_int_idct;
break;
case GST_IDCT_FLOAT:
GST_INFO ("using float_idct");
gst_idct_init_float_idct ();
new->convert = gst_idct_float_idct;
break;
#ifdef HAVE_LIBMMX
case GST_IDCT_MMX:
GST_INFO ( "using MMX_idct");
new->convert = gst_idct_mmx_idct;
new->need_transpose = TRUE;
break;
case GST_IDCT_MMX32:
GST_INFO ( "using MMX32_idct");
new->convert = gst_idct_mmx32_idct;
new->need_transpose = TRUE;
break;
case GST_IDCT_SSE:
GST_INFO ( "using SSE_idct");
new->convert = gst_idct_sse_idct;
new->need_transpose = TRUE;
break;
case GST_IDCT_MMX:
GST_INFO ("using MMX_idct");
new->convert = gst_idct_mmx_idct;
new->need_transpose = TRUE;
break;
case GST_IDCT_MMX32:
GST_INFO ("using MMX32_idct");
new->convert = gst_idct_mmx32_idct;
new->need_transpose = TRUE;
break;
case GST_IDCT_SSE:
GST_INFO ("using SSE_idct");
new->convert = gst_idct_sse_idct;
new->need_transpose = TRUE;
break;
#endif /* HAVE_LIBMMX */
default:
GST_INFO ( "method not supported");
g_free(new);
return NULL;
default:
GST_INFO ("method not supported");
g_free (new);
return NULL;
}
return new;
}
static void gst_idct_int_sparse_idct(short *data)
static void
gst_idct_int_sparse_idct (short *data)
{
short val;
gint32 v, *dp = (guint32 *)data;
gint32 v, *dp = (guint32 *) data;
v = *data;
@ -104,43 +106,61 @@ static void gst_idct_int_sparse_idct(short *data)
val += (8 >> 1);
val /= 8;
val = -val;
}
else {
} else {
val = (v + (8 >> 1)) / 8;
}
v = (( val & 0xffff) | (val << 16));
v = ((val & 0xffff) | (val << 16));
dp[0] = v; dp[1] = v; dp[2] = v; dp[3] = v;
dp[4] = v; dp[5] = v; dp[6] = v; dp[7] = v;
dp[8] = v; dp[9] = v; dp[10] = v; dp[11] = v;
dp[12] = v; dp[13] = v; dp[14] = v; dp[15] = v;
dp[16] = v; dp[17] = v; dp[18] = v; dp[19] = v;
dp[20] = v; dp[21] = v; dp[22] = v; dp[23] = v;
dp[24] = v; dp[25] = v; dp[26] = v; dp[27] = v;
dp[28] = v; dp[29] = v; dp[30] = v; dp[31] = v;
dp[0] = v;
dp[1] = v;
dp[2] = v;
dp[3] = v;
dp[4] = v;
dp[5] = v;
dp[6] = v;
dp[7] = v;
dp[8] = v;
dp[9] = v;
dp[10] = v;
dp[11] = v;
dp[12] = v;
dp[13] = v;
dp[14] = v;
dp[15] = v;
dp[16] = v;
dp[17] = v;
dp[18] = v;
dp[19] = v;
dp[20] = v;
dp[21] = v;
dp[22] = v;
dp[23] = v;
dp[24] = v;
dp[25] = v;
dp[26] = v;
dp[27] = v;
dp[28] = v;
dp[29] = v;
dp[30] = v;
dp[31] = v;
}
void gst_idct_destroy(GstIDCT *idct)
void
gst_idct_destroy (GstIDCT * idct)
{
g_return_if_fail(idct != NULL);
g_return_if_fail (idct != NULL);
g_free(idct);
g_free (idct);
}
static gboolean
plugin_init (GstPlugin *plugin)
plugin_init (GstPlugin * plugin)
{
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstidct",
"Accelerated IDCT routines",
plugin_init,
VERSION,
GST_LICENSE,
GST_PACKAGE,
GST_ORIGIN
)
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstidct",
"Accelerated IDCT routines",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)

View file

@ -23,22 +23,24 @@
#include <glib.h>
typedef enum {
GST_IDCT_DEFAULT,
GST_IDCT_INT,
GST_IDCT_FAST_INT,
GST_IDCT_FLOAT,
GST_IDCT_MMX,
typedef enum
{
GST_IDCT_DEFAULT,
GST_IDCT_INT,
GST_IDCT_FAST_INT,
GST_IDCT_FLOAT,
GST_IDCT_MMX,
GST_IDCT_MMX32,
GST_IDCT_SSE,
} GstIDCTMethod;
typedef struct _GstIDCT GstIDCT;
typedef void (*GstIDCTFunction) (gshort *block);
typedef void (*GstIDCTFunction) (gshort * block);
#define GST_IDCT_TRANSPOSE(idct) ((idct)->need_transpose)
struct _GstIDCT {
struct _GstIDCT
{
/* private */
GstIDCTFunction convert;
GstIDCTFunction convert_sparse;
@ -46,9 +48,10 @@ struct _GstIDCT {
};
GstIDCT *gst_idct_new(GstIDCTMethod method);
GstIDCT *gst_idct_new (GstIDCTMethod method);
#define gst_idct_convert(idct, blocks) (idct)->convert((blocks))
#define gst_idct_convert_sparse(idct, blocks) (idct)->convert_sparse((blocks))
void gst_idct_destroy(GstIDCT *idct);
void gst_idct_destroy (GstIDCT * idct);
#endif /* __GST_IDCT_H__ */

View file

@ -27,9 +27,9 @@
void usage (char *msg);
long ieeerand (long L, long H);
void dct_init(void);
void ref_fdct(DCTELEM block[8][8]);
void ref_idct(DCTELEM block[8][8]);
void dct_init (void);
void ref_fdct (DCTELEM block[8][8]);
void ref_idct (DCTELEM block[8][8]);
/* error stat accumulators -- assume initialized to 0 */
@ -38,47 +38,49 @@ long sumsqerrs[DCTSIZE2];
int maxerr[DCTSIZE2];
char * meets (double val, double limit)
char *
meets (double val, double limit)
{
return ((fabs(val) <= limit) ? "meets" : "FAILS");
return ((fabs (val) <= limit) ? "meets" : "FAILS");
}
int
main(int argc, char **argv)
main (int argc, char **argv)
{
long minpix, maxpix, sign;
long curiter, niters;
int i, j;
double max, total;
int method;
DCTELEM block[DCTSIZE2]; /* random source data */
DCTELEM refcoefs[DCTSIZE2]; /* coefs from reference FDCT */
DCTELEM refout[DCTSIZE2]; /* output from reference IDCT */
DCTELEM testout[DCTSIZE2]; /* output from test IDCT */
GstIDCT *idct;
guint64 tscstart, tscmin = ~0, tscmax = 0;
guint64 tscstop;
DCTELEM block[DCTSIZE2]; /* random source data */
DCTELEM refcoefs[DCTSIZE2]; /* coefs from reference FDCT */
DCTELEM refout[DCTSIZE2]; /* output from reference IDCT */
DCTELEM testout[DCTSIZE2]; /* output from test IDCT */
GstIDCT *idct;
guint64 tscstart, tscmin = ~0, tscmax = 0;
guint64 tscstop;
/* Argument parsing --- not very bulletproof at all */
if (argc != 6) usage(NULL);
if (argc != 6)
usage (NULL);
method = atoi(argv[1]);
minpix = atoi(argv[2]);
maxpix = atoi(argv[3]);
sign = atoi(argv[4]);
niters = atol(argv[5]);
method = atoi (argv[1]);
minpix = atoi (argv[2]);
maxpix = atoi (argv[3]);
sign = atoi (argv[4]);
niters = atol (argv[5]);
gst_library_load("gstidct");
gst_library_load ("gstidct");
idct = gst_idct_new(method);
idct = gst_idct_new (method);
if (idct == 0) {
printf("method not available\n\n\n");
printf ("method not available\n\n\n");
return 0;
}
dct_init();
dct_init ();
/* Loop once per generated random-data block */
@ -86,164 +88,186 @@ main(int argc, char **argv)
/* generate a pseudo-random block of data */
for (i = 0; i < DCTSIZE2; i++)
block[i] = (DCTELEM) (ieeerand(-minpix,maxpix) * sign);
block[i] = (DCTELEM) (ieeerand (-minpix, maxpix) * sign);
/* perform reference FDCT */
memcpy(refcoefs, block, sizeof(DCTELEM)*DCTSIZE2);
ref_fdct((DCTELEM **) &refcoefs);
memcpy (refcoefs, block, sizeof (DCTELEM) * DCTSIZE2);
ref_fdct ((DCTELEM **) & refcoefs);
/* clip */
for (i = 0; i < DCTSIZE2; i++) {
if (refcoefs[i] < -2048) refcoefs[i] = -2048;
else if (refcoefs[i] > 2047) refcoefs[i] = 2047;
if (refcoefs[i] < -2048)
refcoefs[i] = -2048;
else if (refcoefs[i] > 2047)
refcoefs[i] = 2047;
}
/* perform reference IDCT */
memcpy(refout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
ref_idct(refout);
memcpy (refout, refcoefs, sizeof (DCTELEM) * DCTSIZE2);
ref_idct (refout);
/* clip */
for (i = 0; i < DCTSIZE2; i++) {
if (refout[i] < -256) refout[i] = -256;
else if (refout[i] > 255) refout[i] = 255;
if (refout[i] < -256)
refout[i] = -256;
else if (refout[i] > 255)
refout[i] = 255;
}
/* perform test IDCT */
if (GST_IDCT_TRANSPOSE(idct)) {
if (GST_IDCT_TRANSPOSE (idct)) {
for (j = 0; j < DCTSIZE; j++) {
for (i = 0; i < DCTSIZE; i++) {
testout[i*DCTSIZE+j] = refcoefs[j*DCTSIZE+i];
}
}
}
else {
memcpy(testout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
}
for (i = 0; i < DCTSIZE; i++) {
testout[i * DCTSIZE + j] = refcoefs[j * DCTSIZE + i];
}
}
} else {
memcpy (testout, refcoefs, sizeof (DCTELEM) * DCTSIZE2);
}
gst_trace_read_tsc(&tscstart);
gst_idct_convert(idct, testout);
gst_trace_read_tsc(&tscstop);
/*printf("time %llu, %llu %lld\n", tscstart, tscstop, tscstop-tscstart); */
if (tscstop - tscstart < tscmin) tscmin = tscstop-tscstart;
if (tscstop - tscstart > tscmax) tscmax = tscstop-tscstart;
gst_trace_read_tsc (&tscstart);
gst_idct_convert (idct, testout);
gst_trace_read_tsc (&tscstop);
/*printf("time %llu, %llu %lld\n", tscstart, tscstop, tscstop-tscstart); */
if (tscstop - tscstart < tscmin)
tscmin = tscstop - tscstart;
if (tscstop - tscstart > tscmax)
tscmax = tscstop - tscstart;
/* clip */
for (i = 0; i < DCTSIZE2; i++) {
if (testout[i] < -256) testout[i] = -256;
else if (testout[i] > 255) testout[i] = 255;
if (testout[i] < -256)
testout[i] = -256;
else if (testout[i] > 255)
testout[i] = 255;
}
/* accumulate error stats */
for (i = 0; i < DCTSIZE2; i++) {
register int err = testout[i] - refout[i];
sumerrs[i] += err;
sumsqerrs[i] += err * err;
if (err < 0) err = -err;
if (maxerr[i] < err) maxerr[i] = err;
if (err < 0)
err = -err;
if (maxerr[i] < err)
maxerr[i] = err;
}
if (curiter % 100 == 99) {
fprintf(stderr, ".");
fflush(stderr);
fprintf (stderr, ".");
fflush (stderr);
}
}
fprintf(stderr, "\n");
fprintf (stderr, "\n");
/* print results */
printf("IEEE test conditions: -L = %ld, +H = %ld, sign = %ld, #iters = %ld\n",
minpix, maxpix, sign, niters);
printf
("IEEE test conditions: -L = %ld, +H = %ld, sign = %ld, #iters = %ld\n",
minpix, maxpix, sign, niters);
printf("Speed, min time %lld, max %lld\n", tscmin, tscmax);
printf ("Speed, min time %lld, max %lld\n", tscmin, tscmax);
printf("Peak absolute values of errors:\n");
printf ("Peak absolute values of errors:\n");
for (i = 0, j = 0; i < DCTSIZE2; i++) {
if (j < maxerr[i]) j = maxerr[i];
printf("%4d", maxerr[i]);
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
if (j < maxerr[i])
j = maxerr[i];
printf ("%4d", maxerr[i]);
if ((i % DCTSIZE) == DCTSIZE - 1)
printf ("\n");
}
printf("Worst peak error = %d (%s spec limit 1)\n\n", j,
meets((double) j, 1.0));
printf ("Worst peak error = %d (%s spec limit 1)\n\n", j,
meets ((double) j, 1.0));
printf("Mean square errors:\n");
printf ("Mean square errors:\n");
max = total = 0.0;
for (i = 0; i < DCTSIZE2; i++) {
double err = (double) sumsqerrs[i] / ((double) niters);
double err = (double) sumsqerrs[i] / ((double) niters);
total += (double) sumsqerrs[i];
if (max < err) max = err;
printf(" %8.4f", err);
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
if (max < err)
max = err;
printf (" %8.4f", err);
if ((i % DCTSIZE) == DCTSIZE - 1)
printf ("\n");
}
printf("Worst pmse = %.6f (%s spec limit 0.06)\n", max, meets(max, 0.06));
total /= (double) (64*niters);
printf("Overall mse = %.6f (%s spec limit 0.02)\n\n", total,
meets(total, 0.02));
printf ("Worst pmse = %.6f (%s spec limit 0.06)\n", max, meets (max, 0.06));
total /= (double) (64 * niters);
printf ("Overall mse = %.6f (%s spec limit 0.02)\n\n", total,
meets (total, 0.02));
printf("Mean errors:\n");
printf ("Mean errors:\n");
max = total = 0.0;
for (i = 0; i < DCTSIZE2; i++) {
double err = (double) sumerrs[i] / ((double) niters);
double err = (double) sumerrs[i] / ((double) niters);
total += (double) sumerrs[i];
printf(" %8.4f", err);
if (err < 0.0) err = -err;
if (max < err) max = err;
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
printf (" %8.4f", err);
if (err < 0.0)
err = -err;
if (max < err)
max = err;
if ((i % DCTSIZE) == DCTSIZE - 1)
printf ("\n");
}
printf("Worst mean error = %.6f (%s spec limit 0.015)\n", max,
meets(max, 0.015));
total /= (double) (64*niters);
printf("Overall mean error = %.6f (%s spec limit 0.0015)\n\n", total,
meets(total, 0.0015));
printf ("Worst mean error = %.6f (%s spec limit 0.015)\n", max,
meets (max, 0.015));
total /= (double) (64 * niters);
printf ("Overall mean error = %.6f (%s spec limit 0.0015)\n\n", total,
meets (total, 0.0015));
/* test for 0 input giving 0 output */
memset(testout, 0, sizeof(DCTELEM)*DCTSIZE2);
gst_idct_convert(idct, testout);
for (i = 0, j=0; i < DCTSIZE2; i++) {
memset (testout, 0, sizeof (DCTELEM) * DCTSIZE2);
gst_idct_convert (idct, testout);
for (i = 0, j = 0; i < DCTSIZE2; i++) {
if (testout[i]) {
printf("Position %d of IDCT(0) = %d (FAILS)\n", i, testout[i]);
printf ("Position %d of IDCT(0) = %d (FAILS)\n", i, testout[i]);
j++;
}
}
printf("%d elements of IDCT(0) were not zero\n\n\n", j);
printf ("%d elements of IDCT(0) were not zero\n\n\n", j);
exit(0);
exit (0);
return 0;
}
void usage (char *msg)
void
usage (char *msg)
{
if (msg != NULL)
fprintf(stderr, "\nerror: %s\n", msg);
fprintf (stderr, "\nerror: %s\n", msg);
fprintf(stderr, "\n");
fprintf(stderr, "usage: ieeetest minpix maxpix sign niters\n");
fprintf(stderr, "\n");
fprintf(stderr, " test = 1 - 5\n");
fprintf(stderr, " minpix = -L value per IEEE spec\n");
fprintf(stderr, " maxpix = H value per IEEE spec\n");
fprintf(stderr, " sign = +1 for normal, -1 to run negated test\n");
fprintf(stderr, " niters = # iterations (10000 for full test)\n");
fprintf(stderr, "\n");
fprintf (stderr, "\n");
fprintf (stderr, "usage: ieeetest minpix maxpix sign niters\n");
fprintf (stderr, "\n");
fprintf (stderr, " test = 1 - 5\n");
fprintf (stderr, " minpix = -L value per IEEE spec\n");
fprintf (stderr, " maxpix = H value per IEEE spec\n");
fprintf (stderr, " sign = +1 for normal, -1 to run negated test\n");
fprintf (stderr, " niters = # iterations (10000 for full test)\n");
fprintf (stderr, "\n");
exit(1);
exit (1);
}
/* Pseudo-random generator specified by IEEE 1180 */
long ieeerand (long L, long H)
long
ieeerand (long L, long H)
{
static long randx = 1;
static double z = (double) 0x7fffffff;
long i,j;
long i, j;
double x;
randx = (randx * 1103515245) + 12345;
i = randx & 0x7ffffffe;
x = ((double) i) / z;
x *= (L+H+1);
x *= (L + H + 1);
j = x;
return j-L;
return j - L;
}
@ -256,33 +280,35 @@ double coslu[8][8];
/* Routine to initialise the cosine lookup table */
void dct_init(void)
void
dct_init (void)
{
int a,b;
int a, b;
double tmp;
for(a=0;a<8;a++)
for(b=0;b<8;b++) {
tmp = cos((double)((a+a+1)*b) * (3.14159265358979323846 / 16.0));
if(b==0)
tmp /= sqrt(2.0);
for (a = 0; a < 8; a++)
for (b = 0; b < 8; b++) {
tmp = cos ((double) ((a + a + 1) * b) * (3.14159265358979323846 / 16.0));
if (b == 0)
tmp /= sqrt (2.0);
coslu[a][b] = tmp * 0.5;
}
}
void ref_fdct (DCTELEM block[8][8])
void
ref_fdct (DCTELEM block[8][8])
{
int x,y,u,v;
int x, y, u, v;
double tmp, tmp2;
double res[8][8];
for (v=0; v<8; v++) {
for (u=0; u<8; u++) {
for (v = 0; v < 8; v++) {
for (u = 0; u < 8; u++) {
tmp = 0.0;
for (y=0; y<8; y++) {
for (y = 0; y < 8; y++) {
tmp2 = 0.0;
for (x=0; x<8; x++) {
for (x = 0; x < 8; x++) {
tmp2 += (double) block[y][x] * coslu[x][u];
}
tmp += coslu[y][v] * tmp2;
@ -291,11 +317,11 @@ void ref_fdct (DCTELEM block[8][8])
}
}
for (v=0; v<8; v++) {
for (u=0; u<8; u++) {
for (v = 0; v < 8; v++) {
for (u = 0; u < 8; u++) {
tmp = res[v][u];
if (tmp < 0.0) {
x = - ((int) (0.5 - tmp));
x = -((int) (0.5 - tmp));
} else {
x = (int) (tmp + 0.5);
}
@ -305,18 +331,19 @@ void ref_fdct (DCTELEM block[8][8])
}
void ref_idct (DCTELEM block[8][8])
void
ref_idct (DCTELEM block[8][8])
{
int x,y,u,v;
int x, y, u, v;
double tmp, tmp2;
double res[8][8];
for (y=0; y<8; y++) {
for (x=0; x<8; x++) {
for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) {
tmp = 0.0;
for (v=0; v<8; v++) {
for (v = 0; v < 8; v++) {
tmp2 = 0.0;
for (u=0; u<8; u++) {
for (u = 0; u < 8; u++) {
tmp2 += (double) block[v][u] * coslu[x][u];
}
tmp += coslu[y][v] * tmp2;
@ -325,11 +352,11 @@ void ref_idct (DCTELEM block[8][8])
}
}
for (v=0; v<8; v++) {
for (u=0; u<8; u++) {
for (v = 0; v < 8; v++) {
for (u = 0; u < 8; u++) {
tmp = res[v][u];
if (tmp < 0.0) {
x = - ((int) (0.5 - tmp));
x = -((int) (0.5 - tmp));
} else {
x = (int) (tmp + 0.5);
}

View file

@ -51,10 +51,8 @@
*/
#if DCTSIZE != 8
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
Sorry, this code only copes with 8 x8 DCTs. /* deliberate syntax err */
#endif
/*
* A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT
* on each column. Direct algorithms are also available, but they are
@ -90,7 +88,6 @@
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
* shows that the values given below are the most effective.
*/
#ifdef EIGHT_BIT_SAMPLES
#define CONST_BITS 13
#define PASS1_BITS 2
@ -98,22 +95,16 @@
#define CONST_BITS 13
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
#endif
#define ONE ((INT32) 1)
#define CONST_SCALE (ONE << CONST_BITS)
/* Convert a positive real constant to an integer scaled by CONST_SCALE. */
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
* causing a lot of useless floating-point operations at run time.
* To get around this we use the following pre-calculated constants.
* If you change CONST_BITS you may want to add appropriate values.
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
*/
#if CONST_BITS == 13
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
@ -141,15 +132,11 @@
#define FIX_2_562915447 FIX(2.562915447)
#define FIX_3_072711026 FIX(3.072711026)
#endif
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* For 8-bit samples with the recommended scaling, all the variable
* and constant values involved are no more than 16 bits wide, so a
@ -160,7 +147,6 @@
* combination of casts.
* NB: for 12-bit samples, a full 32-bit multiplication will be needed.
*/
#ifdef EIGHT_BIT_SAMPLES
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT16) (const)))
@ -169,17 +155,13 @@
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT32) (const)))
#endif
#endif
#ifndef MULTIPLY /* default definition */
#define MULTIPLY(var,const) ((var) * (const))
#endif
/*
* Perform the inverse DCT on one block of coefficients.
*/
void
void
gst_idct_int_idct (DCTBLOCK data)
{
INT32 tmp0, tmp1, tmp2, tmp3;
@ -187,14 +169,13 @@ gst_idct_int_idct (DCTBLOCK data)
INT32 z1, z2, z3, z4, z5;
register DCTELEM *dataptr;
int rowctr;
SHIFT_TEMPS
/* Pass 1: process rows. */
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
/* furthermore, we scale the results by 2**PASS1_BITS. */
dataptr = data;
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
/* Pass 1: process rows. */
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
/* furthermore, we scale the results by 2**PASS1_BITS. */
dataptr = data;
for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
/* Due to quantization, we will usually find that many of the input
* coefficients are zero, especially the AC terms. We can exploit this
* by short-circuiting the IDCT calculation for any row in which all
@ -205,10 +186,10 @@ gst_idct_int_idct (DCTBLOCK data)
*/
if ((dataptr[1] | dataptr[2] | dataptr[3] | dataptr[4] |
dataptr[5] | dataptr[6] | dataptr[7]) == 0) {
dataptr[5] | dataptr[6] | dataptr[7]) == 0) {
/* AC terms all zero */
DCTELEM dcval = (DCTELEM) (dataptr[0] << PASS1_BITS);
dataptr[0] = dcval;
dataptr[1] = dcval;
dataptr[2] = dcval;
@ -217,7 +198,7 @@ gst_idct_int_idct (DCTBLOCK data)
dataptr[5] = dcval;
dataptr[6] = dcval;
dataptr[7] = dcval;
dataptr += DCTSIZE; /* advance pointer to next row */
continue;
}
@ -228,9 +209,9 @@ gst_idct_int_idct (DCTBLOCK data)
z2 = (INT32) dataptr[2];
z3 = (INT32) dataptr[6];
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
tmp0 = ((INT32) dataptr[0] + (INT32) dataptr[4]) << CONST_BITS;
tmp1 = ((INT32) dataptr[0] - (INT32) dataptr[4]) << CONST_BITS;
@ -239,7 +220,7 @@ gst_idct_int_idct (DCTBLOCK data)
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
*/
@ -253,20 +234,20 @@ gst_idct_int_idct (DCTBLOCK data)
z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY (tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY (tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5;
z4 += z5;
tmp0 += z1 + z3;
tmp1 += z2 + z4;
tmp2 += z2 + z3;
@ -274,14 +255,14 @@ gst_idct_int_idct (DCTBLOCK data)
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
dataptr[0] = (DCTELEM) DESCALE (tmp10 + tmp3, CONST_BITS - PASS1_BITS);
dataptr[7] = (DCTELEM) DESCALE (tmp10 - tmp3, CONST_BITS - PASS1_BITS);
dataptr[1] = (DCTELEM) DESCALE (tmp11 + tmp2, CONST_BITS - PASS1_BITS);
dataptr[6] = (DCTELEM) DESCALE (tmp11 - tmp2, CONST_BITS - PASS1_BITS);
dataptr[2] = (DCTELEM) DESCALE (tmp12 + tmp1, CONST_BITS - PASS1_BITS);
dataptr[5] = (DCTELEM) DESCALE (tmp12 - tmp1, CONST_BITS - PASS1_BITS);
dataptr[3] = (DCTELEM) DESCALE (tmp13 + tmp0, CONST_BITS - PASS1_BITS);
dataptr[4] = (DCTELEM) DESCALE (tmp13 - tmp0, CONST_BITS - PASS1_BITS);
dataptr += DCTSIZE; /* advance pointer to next row */
}
@ -291,7 +272,7 @@ gst_idct_int_idct (DCTBLOCK data)
/* and also undo the PASS1_BITS scaling. */
dataptr = data;
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
/* Columns of zeroes can be exploited in the same way as we did with rows.
* However, the row calculation has created many nonzero AC terms, so the
* simplification applies less often (typically 5% to 10% of the time).
@ -301,21 +282,21 @@ gst_idct_int_idct (DCTBLOCK data)
*/
#ifndef NO_ZERO_COLUMN_TEST
if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] |
dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] |
dataptr[DCTSIZE*7]) == 0) {
if ((dataptr[DCTSIZE * 1] | dataptr[DCTSIZE * 2] | dataptr[DCTSIZE * 3] |
dataptr[DCTSIZE * 4] | dataptr[DCTSIZE * 5] | dataptr[DCTSIZE * 6] |
dataptr[DCTSIZE * 7]) == 0) {
/* AC terms all zero */
DCTELEM dcval = (DCTELEM) DESCALE((INT32) dataptr[0], PASS1_BITS+3);
dataptr[DCTSIZE*0] = dcval;
dataptr[DCTSIZE*1] = dcval;
dataptr[DCTSIZE*2] = dcval;
dataptr[DCTSIZE*3] = dcval;
dataptr[DCTSIZE*4] = dcval;
dataptr[DCTSIZE*5] = dcval;
dataptr[DCTSIZE*6] = dcval;
dataptr[DCTSIZE*7] = dcval;
DCTELEM dcval = (DCTELEM) DESCALE ((INT32) dataptr[0], PASS1_BITS + 3);
dataptr[DCTSIZE * 0] = dcval;
dataptr[DCTSIZE * 1] = dcval;
dataptr[DCTSIZE * 2] = dcval;
dataptr[DCTSIZE * 3] = dcval;
dataptr[DCTSIZE * 4] = dcval;
dataptr[DCTSIZE * 5] = dcval;
dataptr[DCTSIZE * 6] = dcval;
dataptr[DCTSIZE * 7] = dcval;
dataptr++; /* advance pointer to next column */
continue;
}
@ -324,48 +305,52 @@ gst_idct_int_idct (DCTBLOCK data)
/* Even part: reverse the even part of the forward DCT. */
/* The rotator is sqrt(2)*c(-6). */
z2 = (INT32) dataptr[DCTSIZE*2];
z3 = (INT32) dataptr[DCTSIZE*6];
z2 = (INT32) dataptr[DCTSIZE * 2];
z3 = (INT32) dataptr[DCTSIZE * 6];
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
tmp0 = ((INT32) dataptr[DCTSIZE*0] + (INT32) dataptr[DCTSIZE*4]) << CONST_BITS;
tmp1 = ((INT32) dataptr[DCTSIZE*0] - (INT32) dataptr[DCTSIZE*4]) << CONST_BITS;
tmp0 =
((INT32) dataptr[DCTSIZE * 0] +
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
tmp1 =
((INT32) dataptr[DCTSIZE * 0] -
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
*/
tmp0 = (INT32) dataptr[DCTSIZE*7];
tmp1 = (INT32) dataptr[DCTSIZE*5];
tmp2 = (INT32) dataptr[DCTSIZE*3];
tmp3 = (INT32) dataptr[DCTSIZE*1];
tmp0 = (INT32) dataptr[DCTSIZE * 7];
tmp1 = (INT32) dataptr[DCTSIZE * 5];
tmp2 = (INT32) dataptr[DCTSIZE * 3];
tmp3 = (INT32) dataptr[DCTSIZE * 1];
z1 = tmp0 + tmp3;
z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY (tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY (tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5;
z4 += z5;
tmp0 += z1 + z3;
tmp1 += z2 + z4;
tmp2 += z2 + z3;
@ -373,23 +358,23 @@ gst_idct_int_idct (DCTBLOCK data)
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0,
CONST_BITS+PASS1_BITS+3);
dataptr[DCTSIZE * 0] = (DCTELEM) DESCALE (tmp10 + tmp3,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 7] = (DCTELEM) DESCALE (tmp10 - tmp3,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 1] = (DCTELEM) DESCALE (tmp11 + tmp2,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 6] = (DCTELEM) DESCALE (tmp11 - tmp2,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 2] = (DCTELEM) DESCALE (tmp12 + tmp1,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 5] = (DCTELEM) DESCALE (tmp12 - tmp1,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 3] = (DCTELEM) DESCALE (tmp13 + tmp0,
CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE * 4] = (DCTELEM) DESCALE (tmp13 - tmp0,
CONST_BITS + PASS1_BITS + 3);
dataptr++; /* advance pointer to next column */
}
}

File diff suppressed because it is too large Load diff

View file

@ -27,12 +27,13 @@
#include "colorbalance.h"
#include "colorbalance-marshal.h"
enum {
enum
{
VALUE_CHANGED,
LAST_SIGNAL
};
static void gst_color_balance_class_init (GstColorBalanceClass *klass);
static void gst_color_balance_class_init (GstColorBalanceClass * klass);
static guint gst_color_balance_signals[LAST_SIGNAL] = { 0 };
@ -55,35 +56,33 @@ gst_color_balance_get_type (void)
};
gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE,
"GstColorBalance",
&gst_color_balance_info, 0);
"GstColorBalance", &gst_color_balance_info, 0);
g_type_interface_add_prerequisite (gst_color_balance_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_color_balance_type;
}
static void
gst_color_balance_class_init (GstColorBalanceClass *klass)
gst_color_balance_class_init (GstColorBalanceClass * klass)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_color_balance_signals[VALUE_CHANGED] =
g_signal_new ("value-changed",
GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
NULL, NULL,
gst_color_balance_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2,
GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
g_signal_new ("value-changed",
GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
NULL, NULL,
gst_color_balance_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2, GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
initialized = TRUE;
}
klass->balance_type = GST_COLOR_BALANCE_SOFTWARE;
/* default virtual functions */
klass->list_channels = NULL;
klass->set_value = NULL;
@ -91,7 +90,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
}
const GList *
gst_color_balance_list_channels (GstColorBalance *balance)
gst_color_balance_list_channels (GstColorBalance * balance)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -103,9 +102,8 @@ gst_color_balance_list_channels (GstColorBalance *balance)
}
void
gst_color_balance_set_value (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value)
gst_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -115,8 +113,8 @@ gst_color_balance_set_value (GstColorBalance *balance,
}
gint
gst_color_balance_get_value (GstColorBalance *balance,
GstColorBalanceChannel *channel)
gst_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel * channel)
{
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -128,13 +126,11 @@ gst_color_balance_get_value (GstColorBalance *balance,
}
void
gst_color_balance_value_changed (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value)
gst_color_balance_value_changed (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value)
{
g_signal_emit (G_OBJECT (balance),
gst_color_balance_signals[VALUE_CHANGED],
0, channel, value);
gst_color_balance_signals[VALUE_CHANGED], 0, channel, value);
g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
}

View file

@ -27,7 +27,6 @@
#include <gst/colorbalance/colorbalance-enumtypes.h>
G_BEGIN_DECLS
#define GST_TYPE_COLOR_BALANCE \
(gst_color_balance_get_type ())
#define GST_COLOR_BALANCE(obj) \
@ -42,55 +41,48 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE))
#define GST_COLOR_BALANCE_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass))
#define GST_COLOR_BALANCE_TYPE(klass) (klass->balance_type)
typedef struct _GstColorBalance GstColorBalance;
typedef enum
{
GST_COLOR_BALANCE_HARDWARE,
GST_COLOR_BALANCE_SOFTWARE
} GstColorBalanceType;
typedef struct _GstColorBalanceClass {
typedef struct _GstColorBalanceClass
{
GTypeInterface klass;
GstColorBalanceType balance_type;
/* virtual functions */
const GList * (* list_channels) (GstColorBalance *balance);
void (* set_value) (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
gint (* get_value) (GstColorBalance *balance,
GstColorBalanceChannel *channel);
/* virtual functions */
const GList *(*list_channels) (GstColorBalance * balance);
void (*set_value) (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gint (*get_value) (GstColorBalance * balance,
GstColorBalanceChannel * channel);
/* signals */
void (* value_changed) (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
void (*value_changed) (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceClass;
GType gst_color_balance_get_type (void);
GType gst_color_balance_get_type (void);
/* virtual class function wrappers */
const GList *
gst_color_balance_list_channels (GstColorBalance *balance);
void gst_color_balance_set_value (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
gint gst_color_balance_get_value (GstColorBalance *balance,
GstColorBalanceChannel *channel);
const GList *gst_color_balance_list_channels (GstColorBalance * balance);
void gst_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
gint gst_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel * channel);
/* trigger signal */
void gst_color_balance_value_changed (GstColorBalance *balance,
GstColorBalanceChannel *channel,
gint value);
void gst_color_balance_value_changed (GstColorBalance * balance,
GstColorBalanceChannel * channel, gint value);
G_END_DECLS
#endif /* __GST_COLOR_BALANCE_H__ */

View file

@ -25,15 +25,17 @@
#include "colorbalancechannel.h"
enum {
enum
{
/* FILL ME */
SIGNAL_VALUE_CHANGED,
LAST_SIGNAL
};
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass);
static void gst_color_balance_channel_init (GstColorBalanceChannel *balance);
static void gst_color_balance_channel_dispose (GObject *object);
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *
klass);
static void gst_color_balance_channel_init (GstColorBalanceChannel * balance);
static void gst_color_balance_channel_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
@ -59,46 +61,44 @@ gst_color_balance_channel_get_type (void)
gst_color_balance_channel_type =
g_type_register_static (G_TYPE_OBJECT,
"GstColorBalanceChannel",
&color_balance_channel_info, 0);
"GstColorBalanceChannel", &color_balance_channel_info, 0);
}
return gst_color_balance_channel_type;
}
static void
gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
gst_color_balance_channel_class_init (GstColorBalanceChannelClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
signals[SIGNAL_VALUE_CHANGED] =
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
value_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
value_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
object_klass->dispose = gst_color_balance_channel_dispose;
}
static void
gst_color_balance_channel_init (GstColorBalanceChannel *channel)
gst_color_balance_channel_init (GstColorBalanceChannel * channel)
{
channel->label = NULL;
channel->min_value = channel->max_value = 0;
}
static void
gst_color_balance_channel_dispose (GObject *object)
gst_color_balance_channel_dispose (GObject * object)
{
GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object);
if (channel->label)
g_free (channel->label);
channel->label = NULL;
if (parent_class->dispose)

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_COLOR_BALANCE_CHANNEL \
(gst_color_balance_channel_get_type ())
#define GST_COLOR_BALANCE_CHANNEL(obj) \
@ -38,27 +37,25 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL))
#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL))
typedef struct _GstColorBalanceChannel {
typedef struct _GstColorBalanceChannel
{
GObject parent;
gchar *label;
gint min_value,
max_value;
gchar *label;
gint min_value, max_value;
} GstColorBalanceChannel;
typedef struct _GstColorBalanceChannelClass {
typedef struct _GstColorBalanceChannelClass
{
GObjectClass parent;
/* signals */
void (* value_changed) (GstColorBalanceChannel *channel,
gint value);
void (*value_changed) (GstColorBalanceChannel * channel, gint value);
gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceChannelClass;
GType gst_color_balance_channel_get_type (void);
GType gst_color_balance_channel_get_type (void);
G_END_DECLS
#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */

View file

@ -26,14 +26,15 @@
#include "mixer.h"
#include "mixer-marshal.h"
enum {
enum
{
MUTE_TOGGLED,
RECORD_TOGGLED,
VOLUME_CHANGED,
LAST_SIGNAL
};
static void gst_mixer_class_init (GstMixerClass *klass);
static void gst_mixer_class_init (GstMixerClass * klass);
static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
@ -56,48 +57,47 @@ gst_mixer_get_type (void)
};
gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE,
"GstMixer",
&gst_mixer_info, 0);
"GstMixer", &gst_mixer_info, 0);
g_type_interface_add_prerequisite (gst_mixer_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_mixer_type;
}
static void
gst_mixer_class_init (GstMixerClass *klass)
gst_mixer_class_init (GstMixerClass * klass)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_mixer_signals[RECORD_TOGGLED] =
g_signal_new ("record-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, record_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
g_signal_new ("record-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, record_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
gst_mixer_signals[MUTE_TOGGLED] =
g_signal_new ("mute-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
g_signal_new ("mute-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
gst_mixer_signals[VOLUME_CHANGED] =
g_signal_new ("volume-changed",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, volume_changed),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
g_signal_new ("volume-changed",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, volume_changed),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
initialized = TRUE;
}
klass->mixer_type = GST_MIXER_SOFTWARE;
/* default virtual functions */
klass->list_tracks = NULL;
klass->set_volume = NULL;
@ -119,7 +119,7 @@ gst_mixer_class_init (GstMixerClass *klass)
*/
const GList *
gst_mixer_list_tracks (GstMixer *mixer)
gst_mixer_list_tracks (GstMixer * mixer)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -146,9 +146,7 @@ gst_mixer_list_tracks (GstMixer *mixer)
*/
void
gst_mixer_set_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -169,9 +167,7 @@ gst_mixer_set_volume (GstMixer *mixer,
*/
void
gst_mixer_get_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -198,9 +194,7 @@ gst_mixer_get_volume (GstMixer *mixer,
*/
void
gst_mixer_set_mute (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute)
gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -223,9 +217,7 @@ gst_mixer_set_mute (GstMixer *mixer,
*/
void
gst_mixer_set_record (GstMixer *mixer,
GstMixerTrack *track,
gboolean record)
gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -235,43 +227,30 @@ gst_mixer_set_record (GstMixer *mixer,
}
void
gst_mixer_mute_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute)
gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[MUTE_TOGGLED], 0,
track, mute);
gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
g_signal_emit_by_name (G_OBJECT (track),
"mute_toggled",
mute);
g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
}
void
gst_mixer_record_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean record)
gst_mixer_record_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean record)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[RECORD_TOGGLED], 0,
track, record);
gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
g_signal_emit_by_name (G_OBJECT (track),
"record_toggled",
record);
g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
}
void
gst_mixer_volume_changed (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_volume_changed (GstMixer * mixer,
GstMixerTrack * track, gint * volumes)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[VOLUME_CHANGED], 0,
track, volumes);
gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
g_signal_emit_by_name (G_OBJECT (track),
"volume_changed",
volumes);
g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
}

View file

@ -27,7 +27,6 @@
#include <gst/mixer/mixer-enumtypes.h>
G_BEGIN_DECLS
#define GST_TYPE_MIXER \
(gst_mixer_get_type ())
#define GST_MIXER(obj) \
@ -40,9 +39,7 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
#define GST_MIXER_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass))
#define GST_MIXER_TYPE(klass) (klass->mixer_type)
typedef struct _GstMixer GstMixer;
typedef enum
@ -51,70 +48,52 @@ typedef enum
GST_MIXER_SOFTWARE
} GstMixerType;
typedef struct _GstMixerClass {
typedef struct _GstMixerClass
{
GTypeInterface klass;
GstMixerType mixer_type;
/* virtual functions */
const GList * (* list_tracks) (GstMixer *mixer);
const GList *(*list_tracks) (GstMixer * mixer);
void (* set_volume) (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void (* get_volume) (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void (*set_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
void (*get_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
void (* set_mute) (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void (* set_record) (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
void (*set_mute) (GstMixer * mixer, GstMixerTrack * track, gboolean mute);
void (*set_record) (GstMixer * mixer, GstMixerTrack * track, gboolean record);
/* signals */
void (* mute_toggled) (GstMixer *mixer,
GstMixerTrack *channel,
gboolean mute);
void (* record_toggled) (GstMixer *mixer,
GstMixerTrack *channel,
gboolean record);
void (* volume_changed) (GstMixer *mixer,
GstMixerTrack *channel,
gint *volumes);
void (*mute_toggled) (GstMixer * mixer,
GstMixerTrack * channel, gboolean mute);
void (*record_toggled) (GstMixer * mixer,
GstMixerTrack * channel, gboolean record);
void (*volume_changed) (GstMixer * mixer,
GstMixerTrack * channel, gint * volumes);
gpointer _gst_reserved[GST_PADDING];
} GstMixerClass;
GType gst_mixer_get_type (void);
GType gst_mixer_get_type (void);
/* virtual class function wrappers */
const GList * gst_mixer_list_tracks (GstMixer *mixer);
void gst_mixer_set_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_get_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_set_mute (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void gst_mixer_set_record (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
const GList *gst_mixer_list_tracks (GstMixer * mixer);
void gst_mixer_set_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
void gst_mixer_get_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
void gst_mixer_set_mute (GstMixer * mixer,
GstMixerTrack * track, gboolean mute);
void gst_mixer_set_record (GstMixer * mixer,
GstMixerTrack * track, gboolean record);
/* trigger signals */
void gst_mixer_mute_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void gst_mixer_record_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
void gst_mixer_volume_changed (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_mute_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean mute);
void gst_mixer_record_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean record);
void gst_mixer_volume_changed (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
G_END_DECLS
#endif /* __GST_MIXER_H__ */

View file

@ -25,7 +25,8 @@
#include "mixertrack.h"
enum {
enum
{
/* FILL ME */
SIGNAL_VOLUME_CHANGED,
SIGNAL_RECORD_TOGGLED,
@ -33,9 +34,9 @@ enum {
LAST_SIGNAL
};
static void gst_mixer_track_class_init (GstMixerTrackClass *klass);
static void gst_mixer_track_init (GstMixerTrack *mixer);
static void gst_mixer_track_dispose (GObject *object);
static void gst_mixer_track_class_init (GstMixerTrackClass * klass);
static void gst_mixer_track_init (GstMixerTrack * mixer);
static void gst_mixer_track_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
@ -61,47 +62,46 @@ gst_mixer_track_get_type (void)
gst_mixer_track_type =
g_type_register_static (G_TYPE_OBJECT,
"GstMixerTrack",
&mixer_track_info, 0);
"GstMixerTrack", &mixer_track_info, 0);
}
return gst_mixer_track_type;
}
static void
gst_mixer_track_class_init (GstMixerTrackClass *klass)
gst_mixer_track_class_init (GstMixerTrackClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
signals[SIGNAL_RECORD_TOGGLED] =
g_signal_new ("record_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
record_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
g_signal_new ("record_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
record_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
signals[SIGNAL_MUTE_TOGGLED] =
g_signal_new ("mute_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
mute_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
g_signal_new ("mute_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
mute_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
signals[SIGNAL_VOLUME_CHANGED] =
g_signal_new ("volume_changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
volume_changed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
g_signal_new ("volume_changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
volume_changed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
object_klass->dispose = gst_mixer_track_dispose;
}
static void
gst_mixer_track_init (GstMixerTrack *channel)
gst_mixer_track_init (GstMixerTrack * channel)
{
channel->label = NULL;
channel->min_volume = channel->max_volume = 0;
@ -110,7 +110,7 @@ gst_mixer_track_init (GstMixerTrack *channel)
}
static void
gst_mixer_track_dispose (GObject *object)
gst_mixer_track_dispose (GObject * object)
{
GstMixerTrack *channel = GST_MIXER_TRACK (object);

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_MIXER_TRACK \
(gst_mixer_track_get_type ())
#define GST_MIXER_TRACK(obj) \
@ -38,7 +37,6 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK))
#define GST_IS_MIXER_TRACK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK))
/*
* Naming:
*
@ -54,45 +52,41 @@ G_BEGIN_DECLS
* mixer, which means that setting this track will change
* the hearable volume on any output.
*/
typedef enum {
GST_MIXER_TRACK_INPUT = (1<<0),
GST_MIXER_TRACK_OUTPUT = (1<<1),
GST_MIXER_TRACK_MUTE = (1<<2),
GST_MIXER_TRACK_RECORD = (1<<3),
GST_MIXER_TRACK_MASTER = (1<<4),
GST_MIXER_TRACK_SOFTWARE = (1<<5)
typedef enum
{
GST_MIXER_TRACK_INPUT = (1 << 0),
GST_MIXER_TRACK_OUTPUT = (1 << 1),
GST_MIXER_TRACK_MUTE = (1 << 2),
GST_MIXER_TRACK_RECORD = (1 << 3),
GST_MIXER_TRACK_MASTER = (1 << 4),
GST_MIXER_TRACK_SOFTWARE = (1 << 5)
} GstMixerTrackFlags;
#define GST_MIXER_TRACK_HAS_FLAG(channel, flag) \
((channel)->flags & flag)
typedef struct _GstMixerTrack {
GObject parent;
typedef struct _GstMixerTrack
{
GObject parent;
gchar *label;
gchar *label;
GstMixerTrackFlags flags;
gint num_channels,
min_volume,
max_volume;
gint num_channels, min_volume, max_volume;
} GstMixerTrack;
typedef struct _GstMixerTrackClass {
typedef struct _GstMixerTrackClass
{
GObjectClass parent;
/* signals */
void (* mute_toggled) (GstMixerTrack *channel,
gboolean mute);
void (* record_toggled) (GstMixerTrack *channel,
gboolean record);
void (* volume_changed) (GstMixerTrack *channel,
gint *volumes);
void (*mute_toggled) (GstMixerTrack * channel, gboolean mute);
void (*record_toggled) (GstMixerTrack * channel, gboolean record);
void (*volume_changed) (GstMixerTrack * channel, gint * volumes);
gpointer _gst_reserved[GST_PADDING];
} GstMixerTrackClass;
GType gst_mixer_track_get_type (void);
GType gst_mixer_track_get_type (void);
G_END_DECLS
#endif /* __GST_MIXER_TRACK_H__ */

View file

@ -25,7 +25,7 @@
#include <gst/navigation/navigation.h>
static void gst_navigation_class_init (GstNavigationInterface *iface);
static void gst_navigation_class_init (GstNavigationInterface * iface);
GType
gst_navigation_get_type (void)
@ -46,22 +46,21 @@ gst_navigation_get_type (void)
};
gst_navigation_type = g_type_register_static (G_TYPE_INTERFACE,
"GstNavigation",
&gst_navigation_info, 0);
"GstNavigation", &gst_navigation_info, 0);
}
return gst_navigation_type;
}
static void
gst_navigation_class_init (GstNavigationInterface *iface)
gst_navigation_class_init (GstNavigationInterface * iface)
{
/* default virtual functions */
iface->send_event = NULL;
}
void
gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
gst_navigation_send_event (GstNavigation * navigation, GstStructure * structure)
{
GstNavigationInterface *iface = GST_NAVIGATION_GET_IFACE (navigation);
@ -71,25 +70,20 @@ gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
}
void
gst_navigation_send_key_event (GstNavigation *navigation, const char *event,
const char *key)
gst_navigation_send_key_event (GstNavigation * navigation, const char *event,
const char *key)
{
gst_navigation_send_event (navigation, gst_structure_new (
"application/x-gst-navigation",
"event", G_TYPE_STRING, event,
"key", G_TYPE_STRING, key, NULL));
gst_navigation_send_event (navigation,
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
event, "key", G_TYPE_STRING, key, NULL));
}
void
gst_navigation_send_mouse_event (GstNavigation *navigation, const char *event,
int button, double x, double y)
gst_navigation_send_mouse_event (GstNavigation * navigation, const char *event,
int button, double x, double y)
{
gst_navigation_send_event (navigation, gst_structure_new (
"application/x-gst-navigation",
"event", G_TYPE_STRING, event,
"button", G_TYPE_INT, button,
"pointer_x", G_TYPE_DOUBLE, x,
"pointer_y", G_TYPE_DOUBLE, y, NULL));
gst_navigation_send_event (navigation,
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
event, "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x,
"pointer_y", G_TYPE_DOUBLE, y, NULL));
}

View file

@ -26,7 +26,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_NAVIGATION \
(gst_navigation_get_type ())
#define GST_NAVIGATION(obj) \
@ -35,28 +34,28 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION))
#define GST_NAVIGATION_GET_IFACE(obj) \
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface))
typedef struct _GstNavigation GstNavigation;
typedef struct _GstNavigationInterface {
typedef struct _GstNavigationInterface
{
GTypeInterface g_iface;
/* virtual functions */
void (*send_event) (GstNavigation *navigation, GstStructure *structure);
void (*send_event) (GstNavigation * navigation, GstStructure * structure);
gpointer _gst_reserved[GST_PADDING];
} GstNavigationInterface;
GType gst_navigation_get_type (void);
GType gst_navigation_get_type (void);
/* virtual class function wrappers */
void gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure);
void gst_navigation_send_event (GstNavigation * navigation,
GstStructure * structure);
void gst_navigation_send_key_event (GstNavigation *navigation,
const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation *navigation,
const char *event, int button, double x, double y);
void gst_navigation_send_key_event (GstNavigation * navigation,
const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation * navigation,
const char *event, int button, double x, double y);
G_END_DECLS
#endif /* __GST_NAVIGATION_H__ */

View file

@ -27,12 +27,13 @@
#include "propertyprobe.h"
enum {
enum
{
SIGNAL_PROBE_NEEDED,
LAST_SIGNAL
};
static void gst_property_probe_iface_init (GstPropertyProbeInterface *iface);
static void gst_property_probe_iface_init (GstPropertyProbeInterface * iface);
static guint gst_property_probe_signals[LAST_SIGNAL] = { 0 };
@ -56,30 +57,29 @@ gst_property_probe_get_type (void)
gst_property_probe_type =
g_type_register_static (G_TYPE_INTERFACE,
"GstPropertyProbe",
&gst_property_probe_info, 0);
"GstPropertyProbe", &gst_property_probe_info, 0);
}
return gst_property_probe_type;
}
static void
gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
gst_property_probe_iface_init (GstPropertyProbeInterface * iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_property_probe_signals[SIGNAL_PROBE_NEEDED] =
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPropertyProbeInterface, probe_needed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPropertyProbeInterface,
probe_needed), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
initialized = TRUE;
}
/* default virtual functions */
iface->get_properties = NULL;
iface->get_values = NULL;
iface->get_values = NULL;
}
/**
@ -93,23 +93,22 @@ gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
*/
const GList *
gst_property_probe_get_properties (GstPropertyProbe *probe)
gst_property_probe_get_properties (GstPropertyProbe * probe)
{
GstPropertyProbeInterface *iface;
g_return_val_if_fail (probe != NULL, NULL);
iface = GST_PROPERTY_PROBE_GET_IFACE (probe);
if (iface->get_properties)
return iface->get_properties (probe);
return NULL;
}
const GParamSpec *
gst_property_probe_get_property (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_get_property (GstPropertyProbe * probe, const gchar * name)
{
const GList *pspecs = gst_property_probe_get_properties (probe);
@ -129,8 +128,8 @@ gst_property_probe_get_property (GstPropertyProbe *probe,
}
void
gst_property_probe_probe_property (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_probe_property (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -156,8 +155,8 @@ gst_property_probe_probe_property (GstPropertyProbe *probe,
*/
void
gst_property_probe_probe_property_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_probe_property_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -188,8 +187,8 @@ gst_property_probe_probe_property_name (GstPropertyProbe *probe,
*/
gboolean
gst_property_probe_needs_probe (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_needs_probe (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -215,8 +214,8 @@ gst_property_probe_needs_probe (GstPropertyProbe *probe,
*/
gboolean
gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -242,10 +241,10 @@ gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
*
* Returns: A list of valid values for the given property.
*/
GValueArray *
gst_property_probe_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -271,8 +270,8 @@ gst_property_probe_get_values (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_get_values_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_get_values_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -301,8 +300,8 @@ gst_property_probe_get_values_name (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -328,8 +327,8 @@ gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_probe_and_get_values_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_PROPERTY_PROBE \
(gst_property_probe_get_type ())
#define GST_PROPERTY_PROBE(obj) \
@ -34,64 +33,59 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROPERTY_PROBE))
#define GST_PROPERTY_PROBE_GET_IFACE(obj) \
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_PROPERTY_PROBE, GstPropertyProbeInterface))
typedef struct _GstPropertyProbe GstPropertyProbe; /* dummy typedef */
typedef struct _GstPropertyProbe GstPropertyProbe; /* dummy typedef */
typedef struct _GstPropertyProbeInterface {
typedef struct _GstPropertyProbeInterface
{
GTypeInterface klass;
/* signals */
void (*probe_needed) (GstPropertyProbe *probe,
const GParamSpec *pspec);
void (*probe_needed) (GstPropertyProbe * probe, const GParamSpec * pspec);
/* virtual functions */
const GList * (*get_properties) (GstPropertyProbe *probe);
gboolean (*needs_probe) (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec);
void (*probe_property) (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec);
GValueArray * (*get_values) (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec);
const GList *(*get_properties) (GstPropertyProbe * probe);
gboolean (*needs_probe) (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec);
void (*probe_property) (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec);
GValueArray *(*get_values) (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec);
gpointer _gst_reserved[GST_PADDING];
} GstPropertyProbeInterface;
GType gst_property_probe_get_type (void);
GType gst_property_probe_get_type (void);
/* virtual class function wrappers */
/* returns list of GParamSpecs */
const GList * gst_property_probe_get_properties (GstPropertyProbe *probe);
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe *probe,
const gchar *name);
const GList *gst_property_probe_get_properties (GstPropertyProbe * probe);
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe * probe,
const gchar * name);
/* probe one property */
void gst_property_probe_probe_property (GstPropertyProbe *probe,
const GParamSpec *pspec);
void gst_property_probe_probe_property_name (GstPropertyProbe *probe,
const gchar *name);
void gst_property_probe_probe_property (GstPropertyProbe * probe,
const GParamSpec * pspec);
void gst_property_probe_probe_property_name (GstPropertyProbe * probe,
const gchar * name);
/* do we need a probe? */
gboolean gst_property_probe_needs_probe (GstPropertyProbe *probe,
const GParamSpec *pspec);
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
const gchar *name);
gboolean gst_property_probe_needs_probe (GstPropertyProbe * probe,
const GParamSpec * pspec);
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
const gchar * name);
/* returns list of GValues */
GValueArray * gst_property_probe_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec);
GValueArray * gst_property_probe_get_values_name (GstPropertyProbe *probe,
const gchar *name);
GValueArray *gst_property_probe_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec);
GValueArray *gst_property_probe_get_values_name (GstPropertyProbe * probe,
const gchar * name);
/* sugar */
GValueArray * gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec);
GValueArray * gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
const gchar *name);
GValueArray *gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec);
GValueArray *gst_property_probe_probe_and_get_values_name (GstPropertyProbe *
probe, const gchar * name);
G_END_DECLS
#endif /* __GST_PROPERTY_PROBE_H__ */

View file

@ -28,7 +28,8 @@
#include <string.h>
enum {
enum
{
NORM_CHANGED,
CHANNEL_CHANGED,
FREQUENCY_CHANGED,
@ -36,7 +37,7 @@ enum {
LAST_SIGNAL
};
static void gst_tuner_class_init (GstTunerClass *klass);
static void gst_tuner_class_init (GstTunerClass * klass);
static guint gst_tuner_signals[LAST_SIGNAL] = { 0 };
@ -59,49 +60,47 @@ gst_tuner_get_type (void)
};
gst_tuner_type = g_type_register_static (G_TYPE_INTERFACE,
"GstTuner",
&gst_tuner_info, 0);
"GstTuner", &gst_tuner_info, 0);
g_type_interface_add_prerequisite (gst_tuner_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_tuner_type;
}
static void
gst_tuner_class_init (GstTunerClass *klass)
gst_tuner_class_init (GstTunerClass * klass)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_tuner_signals[NORM_CHANGED] =
g_signal_new ("norm-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, norm_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
GST_TYPE_TUNER_NORM);
g_signal_new ("norm-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, norm_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_TUNER_NORM);
gst_tuner_signals[CHANNEL_CHANGED] =
g_signal_new ("channel-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, channel_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
GST_TYPE_TUNER_CHANNEL);
g_signal_new ("channel-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, channel_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
GST_TYPE_TUNER_CHANNEL);
gst_tuner_signals[FREQUENCY_CHANGED] =
g_signal_new ("frequency-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, frequency_changed),
NULL, NULL,
gst_tuner_marshal_VOID__OBJECT_ULONG, G_TYPE_NONE, 2,
GST_TYPE_TUNER_CHANNEL, G_TYPE_ULONG);
g_signal_new ("frequency-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, frequency_changed),
NULL, NULL,
gst_tuner_marshal_VOID__OBJECT_ULONG, G_TYPE_NONE, 2,
GST_TYPE_TUNER_CHANNEL, G_TYPE_ULONG);
gst_tuner_signals[SIGNAL_CHANGED] =
g_signal_new ("signal-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, signal_changed),
NULL, NULL,
gst_tuner_marshal_VOID__OBJECT_INT, G_TYPE_NONE, 2,
GST_TYPE_TUNER_CHANNEL, G_TYPE_INT);
g_signal_new ("signal-changed",
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerClass, signal_changed),
NULL, NULL,
gst_tuner_marshal_VOID__OBJECT_INT, G_TYPE_NONE, 2,
GST_TYPE_TUNER_CHANNEL, G_TYPE_INT);
initialized = TRUE;
}
@ -131,7 +130,7 @@ gst_tuner_class_init (GstTunerClass *klass)
*/
const GList *
gst_tuner_list_channels (GstTuner *tuner)
gst_tuner_list_channels (GstTuner * tuner)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -151,8 +150,7 @@ gst_tuner_list_channels (GstTuner *tuner)
*/
void
gst_tuner_set_channel (GstTuner *tuner,
GstTunerChannel *channel)
gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -171,7 +169,7 @@ gst_tuner_set_channel (GstTuner *tuner,
*/
GstTunerChannel *
gst_tuner_get_channel (GstTuner *tuner)
gst_tuner_get_channel (GstTuner * tuner)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -194,7 +192,7 @@ gst_tuner_get_channel (GstTuner *tuner)
*/
const GList *
gst_tuner_list_norms (GstTuner *tuner)
gst_tuner_list_norms (GstTuner * tuner)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -214,8 +212,7 @@ gst_tuner_list_norms (GstTuner *tuner)
*/
void
gst_tuner_set_norm (GstTuner *tuner,
GstTunerNorm *norm)
gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -235,7 +232,7 @@ gst_tuner_set_norm (GstTuner *tuner,
*/
GstTunerNorm *
gst_tuner_get_norm (GstTuner *tuner)
gst_tuner_get_norm (GstTuner * tuner)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
@ -259,14 +256,13 @@ gst_tuner_get_norm (GstTuner *tuner)
*/
void
gst_tuner_set_frequency (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency)
gst_tuner_set_frequency (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
GST_TUNER_CHANNEL_FREQUENCY));
GST_TUNER_CHANNEL_FREQUENCY));
if (klass->set_frequency) {
klass->set_frequency (tuner, channel, frequency);
@ -285,13 +281,12 @@ gst_tuner_set_frequency (GstTuner *tuner,
*/
gulong
gst_tuner_get_frequency (GstTuner *tuner,
GstTunerChannel *channel)
gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
GST_TUNER_CHANNEL_FREQUENCY), 0);
GST_TUNER_CHANNEL_FREQUENCY), 0);
if (klass->get_frequency) {
return klass->get_frequency (tuner, channel);
@ -315,13 +310,12 @@ gst_tuner_get_frequency (GstTuner *tuner,
*/
gint
gst_tuner_signal_strength (GstTuner *tuner,
GstTunerChannel *channel)
gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel)
{
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
GST_TUNER_CHANNEL_FREQUENCY), 0);
GST_TUNER_CHANNEL_FREQUENCY), 0);
if (klass->signal_strength) {
return klass->signal_strength (tuner, channel);
@ -331,8 +325,7 @@ gst_tuner_signal_strength (GstTuner *tuner,
}
GstTunerNorm *
gst_tuner_find_norm_by_name (GstTuner *tuner,
gchar *norm)
gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm)
{
GList *walk;
@ -349,8 +342,7 @@ gst_tuner_find_norm_by_name (GstTuner *tuner,
}
GstTunerChannel *
gst_tuner_find_channel_by_name (GstTuner *tuner,
gchar *channel)
gst_tuner_find_channel_by_name (GstTuner * tuner, gchar * channel)
{
GList *walk;
@ -367,59 +359,46 @@ gst_tuner_find_channel_by_name (GstTuner *tuner,
}
void
gst_tuner_channel_changed (GstTuner *tuner,
GstTunerChannel *channel)
gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel)
{
g_return_if_fail (GST_IS_TUNER (tuner));
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
g_signal_emit (G_OBJECT (tuner),
gst_tuner_signals[CHANNEL_CHANGED], 0,
channel);
gst_tuner_signals[CHANNEL_CHANGED], 0, channel);
}
void
gst_tuner_norm_changed (GstTuner *tuner,
GstTunerNorm *norm)
gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm)
{
g_return_if_fail (GST_IS_TUNER (tuner));
g_return_if_fail (GST_IS_TUNER_NORM (norm));
g_signal_emit (G_OBJECT (tuner),
gst_tuner_signals[NORM_CHANGED], 0,
norm);
g_signal_emit (G_OBJECT (tuner), gst_tuner_signals[NORM_CHANGED], 0, norm);
}
void
gst_tuner_frequency_changed (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency)
gst_tuner_frequency_changed (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency)
{
g_return_if_fail (GST_IS_TUNER (tuner));
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
g_signal_emit (G_OBJECT (tuner),
gst_tuner_signals[FREQUENCY_CHANGED], 0,
channel, frequency);
gst_tuner_signals[FREQUENCY_CHANGED], 0, channel, frequency);
g_signal_emit_by_name (G_OBJECT (channel),
"frequency_changed",
frequency);
g_signal_emit_by_name (G_OBJECT (channel), "frequency_changed", frequency);
}
void
gst_tuner_signal_changed (GstTuner *tuner,
GstTunerChannel *channel,
gint signal)
gst_tuner_signal_changed (GstTuner * tuner,
GstTunerChannel * channel, gint signal)
{
g_return_if_fail (GST_IS_TUNER (tuner));
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
g_signal_emit (G_OBJECT (tuner),
gst_tuner_signals[SIGNAL_CHANGED], 0,
channel, signal);
gst_tuner_signals[SIGNAL_CHANGED], 0, channel, signal);
g_signal_emit_by_name (G_OBJECT (channel),
"signal_changed",
signal);
g_signal_emit_by_name (G_OBJECT (channel), "signal_changed", signal);
}

View file

@ -28,7 +28,6 @@
#include <gst/tuner/tuner-enumtypes.h>
G_BEGIN_DECLS
#define GST_TYPE_TUNER \
(gst_tuner_get_type ())
#define GST_TUNER(obj) \
@ -41,87 +40,65 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER))
#define GST_TUNER_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TUNER, GstTunerClass))
typedef struct _GstTuner GstTuner;
typedef struct _GstTunerClass {
typedef struct _GstTunerClass
{
GTypeInterface klass;
/* virtual functions */
const GList * (* list_channels) (GstTuner *tuner);
void (* set_channel) (GstTuner *tuner,
GstTunerChannel *channel);
GstTunerChannel *
(* get_channel) (GstTuner *tuner);
const GList *(*list_channels) (GstTuner * tuner);
void (*set_channel) (GstTuner * tuner, GstTunerChannel * channel);
GstTunerChannel *(*get_channel) (GstTuner * tuner);
const GList * (* list_norms) (GstTuner *tuner);
void (* set_norm) (GstTuner *tuner,
GstTunerNorm *norm);
GstTunerNorm *(* get_norm) (GstTuner *tuner);
const GList *(*list_norms) (GstTuner * tuner);
void (*set_norm) (GstTuner * tuner, GstTunerNorm * norm);
GstTunerNorm *(*get_norm) (GstTuner * tuner);
void (* set_frequency) (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency);
gulong (* get_frequency) (GstTuner *tuner,
GstTunerChannel *channel);
gint (* signal_strength) (GstTuner *tuner,
GstTunerChannel *channel);
void (*set_frequency) (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency);
gulong (*get_frequency) (GstTuner * tuner, GstTunerChannel * channel);
gint (*signal_strength) (GstTuner * tuner, GstTunerChannel * channel);
/* signals */
void (*channel_changed) (GstTuner *tuner,
GstTunerChannel *channel);
void (*norm_changed) (GstTuner *tuner,
GstTunerNorm *norm);
void (*frequency_changed) (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency);
void (*signal_changed) (GstTuner *tuner,
GstTunerChannel *channel,
gint signal);
void (*channel_changed) (GstTuner * tuner, GstTunerChannel * channel);
void (*norm_changed) (GstTuner * tuner, GstTunerNorm * norm);
void (*frequency_changed) (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency);
void (*signal_changed) (GstTuner * tuner,
GstTunerChannel * channel, gint signal);
gpointer _gst_reserved[GST_PADDING];
} GstTunerClass;
GType gst_tuner_get_type (void);
GType gst_tuner_get_type (void);
/* virtual class function wrappers */
const GList * gst_tuner_list_channels (GstTuner *tuner);
void gst_tuner_set_channel (GstTuner *tuner,
GstTunerChannel *channel);
GstTunerChannel *
gst_tuner_get_channel (GstTuner *tuner);
const GList *gst_tuner_list_channels (GstTuner * tuner);
void gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel);
GstTunerChannel *gst_tuner_get_channel (GstTuner * tuner);
const GList * gst_tuner_list_norms (GstTuner *tuner);
void gst_tuner_set_norm (GstTuner *tuner,
GstTunerNorm *channel);
GstTunerNorm * gst_tuner_get_norm (GstTuner *tuner);
const GList *gst_tuner_list_norms (GstTuner * tuner);
void gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * channel);
GstTunerNorm *gst_tuner_get_norm (GstTuner * tuner);
void gst_tuner_set_frequency (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency);
gulong gst_tuner_get_frequency (GstTuner *tuner,
GstTunerChannel *channel);
gint gst_tuner_signal_strength (GstTuner *tuner,
GstTunerChannel *channel);
void gst_tuner_set_frequency (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency);
gulong gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel);
gint gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel);
/* helper functions */
GstTunerNorm * gst_tuner_find_norm_by_name (GstTuner *tuner,
gchar *norm);
GstTunerChannel *gst_tuner_find_channel_by_name (GstTuner *tuner,
gchar *channel);
GstTunerNorm *gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm);
GstTunerChannel *gst_tuner_find_channel_by_name (GstTuner * tuner,
gchar * channel);
/* trigger signals */
void gst_tuner_channel_changed (GstTuner *tuner,
GstTunerChannel *channel);
void gst_tuner_norm_changed (GstTuner *tuner,
GstTunerNorm *norm);
void gst_tuner_frequency_changed (GstTuner *tuner,
GstTunerChannel *channel,
gulong frequency);
void gst_tuner_signal_changed (GstTuner *tuner,
GstTunerChannel *channel,
gint signal);
void gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel);
void gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm);
void gst_tuner_frequency_changed (GstTuner * tuner,
GstTunerChannel * channel, gulong frequency);
void gst_tuner_signal_changed (GstTuner * tuner,
GstTunerChannel * channel, gint signal);
G_END_DECLS
#endif /* __GST_TUNER_H__ */

View file

@ -25,16 +25,17 @@
#include "tunerchannel.h"
enum {
enum
{
/* FILL ME */
SIGNAL_FREQUENCY_CHANGED,
SIGNAL_SIGNAL_CHANGED,
LAST_SIGNAL
};
static void gst_tuner_channel_class_init (GstTunerChannelClass *klass);
static void gst_tuner_channel_init (GstTunerChannel *channel);
static void gst_tuner_channel_dispose (GObject *object);
static void gst_tuner_channel_class_init (GstTunerChannelClass * klass);
static void gst_tuner_channel_init (GstTunerChannel * channel);
static void gst_tuner_channel_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
@ -60,40 +61,37 @@ gst_tuner_channel_get_type (void)
gst_tuner_channel_type =
g_type_register_static (G_TYPE_OBJECT,
"GstTunerChannel",
&tuner_channel_info, 0);
"GstTunerChannel", &tuner_channel_info, 0);
}
return gst_tuner_channel_type;
}
static void
gst_tuner_channel_class_init (GstTunerChannelClass *klass)
gst_tuner_channel_class_init (GstTunerChannelClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
signals[SIGNAL_FREQUENCY_CHANGED] =
g_signal_new ("frequency-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerChannelClass,
frequency_changed),
NULL, NULL, g_cclosure_marshal_VOID__ULONG,
G_TYPE_NONE, 1, G_TYPE_ULONG);
g_signal_new ("frequency-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerChannelClass,
frequency_changed),
NULL, NULL, g_cclosure_marshal_VOID__ULONG, G_TYPE_NONE, 1, G_TYPE_ULONG);
signals[SIGNAL_SIGNAL_CHANGED] =
g_signal_new ("signal-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerChannelClass,
signal_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
g_signal_new ("signal-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstTunerChannelClass,
signal_changed),
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
object_klass->dispose = gst_tuner_channel_dispose;
}
static void
gst_tuner_channel_init (GstTunerChannel *channel)
gst_tuner_channel_init (GstTunerChannel * channel)
{
channel->label = NULL;
channel->flags = 0;
@ -102,7 +100,7 @@ gst_tuner_channel_init (GstTunerChannel *channel)
}
static void
gst_tuner_channel_dispose (GObject *object)
gst_tuner_channel_dispose (GObject * object)
{
GstTunerChannel *channel = GST_TUNER_CHANNEL (object);

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_TUNER_CHANNEL \
(gst_tuner_channel_get_type ())
#define GST_TUNER_CHANNEL(obj) \
@ -38,42 +37,39 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_CHANNEL))
#define GST_IS_TUNER_CHANNEL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_CHANNEL))
typedef enum {
GST_TUNER_CHANNEL_INPUT = (1<<0),
GST_TUNER_CHANNEL_OUTPUT = (1<<1),
GST_TUNER_CHANNEL_FREQUENCY = (1<<2),
GST_TUNER_CHANNEL_AUDIO = (1<<3),
typedef enum
{
GST_TUNER_CHANNEL_INPUT = (1 << 0),
GST_TUNER_CHANNEL_OUTPUT = (1 << 1),
GST_TUNER_CHANNEL_FREQUENCY = (1 << 2),
GST_TUNER_CHANNEL_AUDIO = (1 << 3),
} GstTunerChannelFlags;
#define GST_TUNER_CHANNEL_HAS_FLAG(channel, flag) \
((channel)->flags & flag)
typedef struct _GstTunerChannel {
GObject parent;
typedef struct _GstTunerChannel
{
GObject parent;
gchar *label;
gchar *label;
GstTunerChannelFlags flags;
gulong min_frequency,
max_frequency;
gint min_signal,
max_signal;
gulong min_frequency, max_frequency;
gint min_signal, max_signal;
} GstTunerChannel;
typedef struct _GstTunerChannelClass {
typedef struct _GstTunerChannelClass
{
GObjectClass parent;
/* signals */
void (*frequency_changed) (GstTunerChannel *channel,
gulong frequency);
void (*signal_changed) (GstTunerChannel *channel,
gint signal);
void (*frequency_changed) (GstTunerChannel * channel, gulong frequency);
void (*signal_changed) (GstTunerChannel * channel, gint signal);
gpointer _gst_reserved[GST_PADDING];
} GstTunerChannelClass;
GType gst_tuner_channel_get_type (void);
GType gst_tuner_channel_get_type (void);
G_END_DECLS
#endif /* __GST_TUNER_CHANNEL_H__ */

View file

@ -25,16 +25,18 @@
#include "tunernorm.h"
enum {
enum
{
/* FILL ME */
LAST_SIGNAL
};
static void gst_tuner_norm_class_init (GstTunerNormClass *klass);
static void gst_tuner_norm_init (GstTunerNorm *norm);
static void gst_tuner_norm_dispose (GObject *object);
static void gst_tuner_norm_class_init (GstTunerNormClass * klass);
static void gst_tuner_norm_init (GstTunerNorm * norm);
static void gst_tuner_norm_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
/*static guint signals[LAST_SIGNAL] = { 0 };*/
GType
@ -58,15 +60,14 @@ gst_tuner_norm_get_type (void)
gst_tuner_norm_type =
g_type_register_static (G_TYPE_OBJECT,
"GstTunerNorm",
&tuner_norm_info, 0);
"GstTunerNorm", &tuner_norm_info, 0);
}
return gst_tuner_norm_type;
}
static void
gst_tuner_norm_class_init (GstTunerNormClass *klass)
gst_tuner_norm_class_init (GstTunerNormClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
@ -76,14 +77,14 @@ gst_tuner_norm_class_init (GstTunerNormClass *klass)
}
static void
gst_tuner_norm_init (GstTunerNorm *norm)
gst_tuner_norm_init (GstTunerNorm * norm)
{
norm->label = NULL;
norm->fps = 0.;
}
static void
gst_tuner_norm_dispose (GObject *object)
gst_tuner_norm_dispose (GObject * object)
{
GstTunerNorm *norm = GST_TUNER_NORM (object);

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_TUNER_NORM \
(gst_tuner_norm_get_type ())
#define GST_TUNER_NORM(obj) \
@ -36,22 +35,22 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_NORM))
#define GST_IS_TUNER_NORM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_NORM))
typedef struct _GstTunerNorm {
typedef struct _GstTunerNorm
{
GObject parent;
gchar *label;
gfloat fps;
gchar *label;
gfloat fps;
} GstTunerNorm;
typedef struct _GstTunerNormClass {
typedef struct _GstTunerNormClass
{
GObjectClass parent;
gpointer _gst_reserved[GST_PADDING];
} GstTunerNormClass;
GType gst_tuner_norm_get_type (void);
GType gst_tuner_norm_get_type (void);
G_END_DECLS
#endif /* __GST_TUNER_NORM_H__ */

View file

@ -25,7 +25,8 @@
#include "xoverlay.h"
enum {
enum
{
HAVE_XWINDOW_ID,
DESIRED_SIZE,
LAST_SIGNAL
@ -54,44 +55,40 @@ gst_x_overlay_get_type (void)
};
gst_x_overlay_type = g_type_register_static (G_TYPE_INTERFACE,
"GstXOverlay",
&gst_x_overlay_info, 0);
"GstXOverlay", &gst_x_overlay_info, 0);
g_type_interface_add_prerequisite (gst_x_overlay_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_x_overlay_type;
}
/* FIXME: evil hack, we should figure out our marshal handling in this interfaces some day */
extern void gst_marshal_VOID__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values,
const GValue *param_values, gpointer invocation_hint, gpointer marshal_data);
extern void gst_marshal_VOID__INT_INT (GClosure * closure,
GValue * return_value, guint n_param_values, const GValue * param_values,
gpointer invocation_hint, gpointer marshal_data);
static void
gst_x_overlay_base_init (gpointer g_class)
{
GstXOverlayClass *overlay_class = (GstXOverlayClass *) g_class;
static gboolean initialized = FALSE;
if (! initialized)
{
gst_x_overlay_signals[HAVE_XWINDOW_ID] =
g_signal_new ("have-xwindow-id",
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstXOverlayClass, have_xwindow_id),
NULL, NULL,
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1,
G_TYPE_INT);
gst_x_overlay_signals[DESIRED_SIZE] =
g_signal_new ("desired-size-changed",
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstXOverlayClass, desired_size),
NULL, NULL,
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_INT);
initialized = TRUE;
}
if (!initialized) {
gst_x_overlay_signals[HAVE_XWINDOW_ID] =
g_signal_new ("have-xwindow-id",
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstXOverlayClass, have_xwindow_id),
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
gst_x_overlay_signals[DESIRED_SIZE] =
g_signal_new ("desired-size-changed",
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstXOverlayClass, desired_size),
NULL, NULL,
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
initialized = TRUE;
}
overlay_class->set_xwindow_id = NULL;
}
@ -107,7 +104,7 @@ gst_x_overlay_base_init (gpointer g_class)
* stop using that window and create an internal one.
*/
void
gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
gst_x_overlay_set_xwindow_id (GstXOverlay * overlay, gulong xwindow_id)
{
GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay);
@ -126,13 +123,13 @@ gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
* This function should be used by video overlay developpers.
*/
void
gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
gst_x_overlay_got_xwindow_id (GstXOverlay * overlay, gulong xwindow_id)
{
g_return_if_fail (overlay != NULL);
g_return_if_fail (GST_IS_X_OVERLAY (overlay));
g_signal_emit (G_OBJECT (overlay),
gst_x_overlay_signals[HAVE_XWINDOW_ID], 0, (gint) xwindow_id);
gst_x_overlay_signals[HAVE_XWINDOW_ID], 0, (gint) xwindow_id);
}
/**
@ -145,18 +142,20 @@ gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
* size, width and height are set to 0.
*/
void
gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *height)
gst_x_overlay_get_desired_size (GstXOverlay * overlay, guint * width,
guint * height)
{
guint width_tmp, height_tmp;
GstXOverlayClass *klass;
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE ((overlay), GST_TYPE_X_OVERLAY));
klass = GST_X_OVERLAY_GET_CLASS (overlay);
if (klass->get_desired_size && GST_IS_X_OVERLAY (overlay)) {
/* this ensures that elements don't need to check width and height for NULL
but apps may use NULL */
klass->get_desired_size (overlay, width ? width : &width_tmp, height ? height : &height_tmp);
klass->get_desired_size (overlay, width ? width : &width_tmp,
height ? height : &height_tmp);
} else {
if (width)
*width = 0;
@ -176,12 +175,13 @@ gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *heigh
* This function should be used by video overlay developpers.
*/
void
gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
gst_x_overlay_got_desired_size (GstXOverlay * overlay, guint width,
guint height)
{
g_return_if_fail (GST_IS_X_OVERLAY (overlay));
g_signal_emit (G_OBJECT (overlay),
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
gst_x_overlay_signals[DESIRED_SIZE], 0, width, height);
}
/**
@ -192,7 +192,7 @@ gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
* in the drawable even if the pipeline is PAUSED.
*/
void
gst_x_overlay_expose (GstXOverlay *overlay)
gst_x_overlay_expose (GstXOverlay * overlay)
{
GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay);

View file

@ -26,7 +26,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_X_OVERLAY \
(gst_x_overlay_get_type ())
#define GST_X_OVERLAY(obj) \
@ -40,42 +39,38 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_X_OVERLAY))
#define GST_X_OVERLAY_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_X_OVERLAY, GstXOverlayClass))
typedef struct _GstXOverlay GstXOverlay;
typedef struct _GstXOverlayClass {
typedef struct _GstXOverlayClass
{
GTypeInterface klass;
/* virtual functions */
void (* set_xwindow_id) (GstXOverlay *overlay,
gulong xwindow_id);
void (*set_xwindow_id) (GstXOverlay * overlay, gulong xwindow_id);
/* optional virtual functions */
void (* get_desired_size) (GstXOverlay *overlay,
guint *width,
guint *height);
void (* expose) (GstXOverlay *overlay);
void (*get_desired_size) (GstXOverlay * overlay,
guint * width, guint * height);
void (*expose) (GstXOverlay * overlay);
/* signals */
void (*have_xwindow_id) (GstXOverlay *overlay,
gulong xwindow_id);
void (* desired_size) (GstXOverlay *overlay,
guint width,
guint height);
void (*have_xwindow_id) (GstXOverlay * overlay, gulong xwindow_id);
void (*desired_size) (GstXOverlay * overlay, guint width, guint height);
gpointer _gst_reserved[GST_PADDING];
} GstXOverlayClass;
GType gst_x_overlay_get_type (void);
GType gst_x_overlay_get_type (void);
/* virtual class function wrappers */
void gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
void gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *height);
void gst_x_overlay_expose (GstXOverlay *overlay);
void gst_x_overlay_set_xwindow_id (GstXOverlay * overlay, gulong xwindow_id);
void gst_x_overlay_get_desired_size (GstXOverlay * overlay, guint * width,
guint * height);
void gst_x_overlay_expose (GstXOverlay * overlay);
/* public methods to fire signals */
void gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
void gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height);
void gst_x_overlay_got_xwindow_id (GstXOverlay * overlay, gulong xwindow_id);
void gst_x_overlay_got_desired_size (GstXOverlay * overlay, guint width,
guint height);
G_END_DECLS
#endif /* __GST_X_OVERLAY_H__ */

View file

@ -49,9 +49,10 @@ gmi_stream_new (void)
}
void
gmi_stream_free (GstMediaInfoStream *stream)
gmi_stream_free (GstMediaInfoStream * stream)
{
if (stream->mime) g_free (stream->mime);
if (stream->mime)
g_free (stream->mime);
/* FIXME: free tracks */
g_free (stream);
}
@ -78,7 +79,8 @@ gmi_track_new (void)
/* callbacks */
static void
have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstMediaInfoPriv *priv)
have_type_callback (GstElement * typefind, guint probability, GstCaps * type,
GstMediaInfoPriv * priv)
{
GstStructure *str;
const gchar *mime;
@ -90,8 +92,7 @@ have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstM
/* FIXME: this code doesn't yet work, test it later */
#ifdef DONTWORK
if (strcmp (mime, "application/x-id3") == 0)
{
if (strcmp (mime, "application/x-id3") == 0) {
/* dig a little deeper */
GST_DEBUG ("dealing with id3, digging deeper");
gst_element_set_state (priv->pipeline, GST_STATE_READY);
@ -102,70 +103,72 @@ have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstM
if (priv->decontainer == NULL)
/* FIXME: signal error */
g_warning ("Couldn't create id3tag");
if (!gst_element_link_many (priv->source, priv->decontainer, priv->typefind, NULL));
g_warning ("Couldn't link in id3tag");
if (!gst_element_link_many (priv->source, priv->decontainer, priv->typefind,
NULL));
g_warning ("Couldn't link in id3tag");
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
== GST_STATE_FAILURE)
g_warning ("Couldn't set to playing");
}
#endif
}
void
deep_notify_callback (GObject *object, GstObject *origin,
GParamSpec *pspec, GstMediaInfoPriv *priv)
deep_notify_callback (GObject * object, GstObject * origin,
GParamSpec * pspec, GstMediaInfoPriv * priv)
{
GValue value = { 0, };
/* we only care about pad notifies */
if (!GST_IS_PAD (origin)) return;
if (!GST_IS_PAD (origin))
return;
/*
GST_DEBUG ("DEBUG: deep_notify: have notify of %s from object %s:%s !",
pspec->name, gst_element_get_name (gst_pad_get_parent (GST_PAD (origin))),
gst_object_get_name (origin));
*/
else if (strcmp (pspec->name, "caps") == 0)
{
GST_DEBUG ("DEBUG: deep_notify: have notify of %s from object %s:%s !",
pspec->name, gst_element_get_name (gst_pad_get_parent (GST_PAD (origin))),
gst_object_get_name (origin));
*/
else if (strcmp (pspec->name, "caps") == 0) {
/* check if we're getting it from fakesink */
if (GST_IS_PAD (origin) && GST_PAD_PARENT (origin) == priv->fakesink)
{
if (GST_IS_PAD (origin) && GST_PAD_PARENT (origin) == priv->fakesink) {
GST_DEBUG ("have caps on fakesink pad !");
g_value_init (&value, pspec->value_type);
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
priv->format = g_value_peek_pointer (&value);
GST_DEBUG ("caps: %" GST_PTR_FORMAT, priv->format);
}
else GST_DEBUG ("ignoring caps on object %s:%s",
gst_object_get_name (gst_object_get_parent (origin)),
gst_object_get_name (origin));
}
else if (strcmp (pspec->name, "offset") == 0)
{
} else
GST_DEBUG ("ignoring caps on object %s:%s",
gst_object_get_name (gst_object_get_parent (origin)),
gst_object_get_name (origin));
} else if (strcmp (pspec->name, "offset") == 0) {
/* we REALLY ignore offsets, we hate them */
}
//else GST_DEBUG ("ignoring notify of %s", pspec->name);
//else GST_DEBUG ("ignoring notify of %s", pspec->name);
}
typedef struct {
typedef struct
{
guint meta;
guint encoded;
} TagFlagScore;
static void
tag_flag_score (const GstTagList *list, const gchar *tag, gpointer user_data)
tag_flag_score (const GstTagList * list, const gchar * tag, gpointer user_data)
{
TagFlagScore *score = (TagFlagScore *) user_data;
GstTagFlag flag;
flag = gst_tag_get_flag (tag);
if (flag == GST_TAG_FLAG_META) score->meta++;
if (flag == GST_TAG_FLAG_ENCODED) score->encoded++;
if (flag == GST_TAG_FLAG_META)
score->meta++;
if (flag == GST_TAG_FLAG_ENCODED)
score->encoded++;
}
void
found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, GstMediaInfoPriv *priv)
found_tag_callback (GObject * pipeline, GstElement * source, GstTagList * tags,
GstMediaInfoPriv * priv)
{
TagFlagScore score;
@ -179,20 +182,18 @@ found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, Gst
gst_tag_list_foreach (tags, tag_flag_score, &score);
if (score.meta > score.encoded)
{
if (score.meta > score.encoded) {
GST_DEBUG ("found tags from decoder, adding them as metadata");
priv->metadata = gst_tag_list_copy (tags);
}
else
{
} else {
GST_DEBUG ("found tags, adding them as streaminfo");
priv->streaminfo = gst_tag_list_copy (tags);
}
}
void
error_callback (GObject *element, GstElement *source, GError *error, gchar *debug, GstMediaInfoPriv *priv)
error_callback (GObject * element, GstElement * source, GError * error,
gchar * debug, GstMediaInfoPriv * priv)
{
g_print ("ERROR: %s\n", error->message);
g_error_free (error);
@ -202,7 +203,7 @@ error_callback (GObject *element, GstElement *source, GError *error, gchar *debu
/* General GError creation */
static void
gst_media_info_error_create (GError **error, const gchar *message)
gst_media_info_error_create (GError ** error, const gchar * message)
{
/* check if caller wanted an error reported */
if (error == NULL)
@ -214,15 +215,14 @@ gst_media_info_error_create (GError **error, const gchar *message)
/* GError creation when element is missing */
static void
gst_media_info_error_element (const gchar *element, GError **error)
gst_media_info_error_element (const gchar * element, GError ** error)
{
gchar *message;
message = g_strdup_printf ("The %s element could not be found. "
"This element is essential for reading. "
"Please install the right plug-in and verify "
"that it works by running 'gst-inspect %s'",
element, element);
"This element is essential for reading. "
"Please install the right plug-in and verify "
"that it works by running 'gst-inspect %s'", element, element);
gst_media_info_error_create (error, message);
g_free (message);
return;
@ -230,7 +230,7 @@ gst_media_info_error_element (const gchar *element, GError **error)
/* initialise priv; done the first time */
gboolean
gmip_init (GstMediaInfoPriv *priv, GError **error)
gmip_init (GstMediaInfoPriv * priv, GError ** error)
{
#define GST_MEDIA_INFO_MAKE_OR_ERROR(el, factory, name, error) \
G_STMT_START { \
@ -257,7 +257,7 @@ G_STMT_START { \
/* called at the beginning of each use cycle */
/* reset info to a state where it can be used to query for media info */
void
gmip_reset (GstMediaInfoPriv *priv)
gmip_reset (GstMediaInfoPriv * priv)
{
#define STRING_RESET(string) \
@ -266,8 +266,8 @@ G_STMT_START { \
string = NULL; \
} G_STMT_END
STRING_RESET(priv->pipeline_desc);
STRING_RESET(priv->location);
STRING_RESET (priv->pipeline_desc);
STRING_RESET (priv->location);
#undef STRING_RESET
#define CAPS_RESET(target) \
@ -275,8 +275,8 @@ G_STMT_START { \
if (target) gst_caps_free (target); \
target = NULL; \
} G_STMT_END
CAPS_RESET(priv->type);
CAPS_RESET(priv->format);
CAPS_RESET (priv->type);
CAPS_RESET (priv->format);
#undef CAPS_RESET
#define TAGS_RESET(target) \
@ -285,12 +285,11 @@ G_STMT_START { \
gst_tag_list_free (target); \
target = NULL; \
} G_STMT_END
TAGS_RESET(priv->metadata);
TAGS_RESET(priv->streaminfo);
TAGS_RESET (priv->metadata);
TAGS_RESET (priv->streaminfo);
#undef TAGS_RESET
if (priv->stream)
{
if (priv->stream) {
gmi_stream_free (priv->stream);
priv->stream = NULL;
}
@ -302,7 +301,7 @@ G_STMT_START { \
/* seek to a track and reset metadata and streaminfo structs */
gboolean
gmi_seek_to_track (GstMediaInfo *info, long track)
gmi_seek_to_track (GstMediaInfo * info, long track)
{
GstEvent *event;
GstFormat track_format = 0;
@ -311,32 +310,28 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
/* FIXME: consider more nicks as "track" */
track_format = gst_format_get_by_nick ("logical_stream");
if (track_format == 0) return FALSE;
if (track_format == 0)
return FALSE;
GST_DEBUG ("Track format: %d", track_format);
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
== GST_STATE_FAILURE)
g_warning ("Couldn't set to play");
g_assert (GST_IS_PAD (info->priv->decoder_pad));
event = gst_event_new_seek (track_format |
GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH,
track);
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, track);
res = gst_pad_send_event (info->priv->decoder_pad, event);
if (!res)
{
if (!res) {
g_warning ("seek to logical track on pad %s:%s failed",
GST_DEBUG_PAD_NAME(info->priv->decoder_pad));
GST_DEBUG_PAD_NAME (info->priv->decoder_pad));
return FALSE;
}
/* clear structs because of the seek */
if (priv->metadata)
{
if (priv->metadata) {
gst_tag_list_free (priv->metadata);
priv->metadata = NULL;
}
if (priv->streaminfo)
{
if (priv->streaminfo) {
gst_tag_list_free (priv->streaminfo);
priv->streaminfo = NULL;
}
@ -345,7 +340,7 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
/* set the mime type on the media info getter */
gboolean
gmi_set_mime (GstMediaInfo *info, const char *mime)
gmi_set_mime (GstMediaInfo * info, const char *mime)
{
gchar *desc = NULL;
GError *error = NULL;
@ -354,31 +349,45 @@ gmi_set_mime (GstMediaInfo *info, const char *mime)
/* FIXME: please figure out proper mp3 mimetypes */
if ((strcmp (mime, "application/x-ogg") == 0) ||
(strcmp (mime, "application/ogg") == 0))
desc = g_strdup_printf ("%s name=source ! oggdemux ! vorbisdec name=decoder ! fakesink name=sink", priv->source_name);
else if ((strcmp (mime, "audio/mpeg") == 0) ||
(strcmp (mime, "audio/x-mp3") == 0) ||
(strcmp (mime, "audio/mp3") == 0) ||
(strcmp (mime, "application/x-id3") == 0) ||
(strcmp (mime, "audio/x-id3") == 0))
desc = g_strdup_printf ("%s name=source ! id3tag ! mad name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
else if ((strcmp (mime, "application/x-flac") == 0) ||
(strcmp (mime, "audio/x-flac") == 0))
desc = g_strdup_printf ("%s name=source ! flacdec name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
else if ((strcmp (mime, "audio/wav") == 0) ||
(strcmp (mime, "audio/x-wav") == 0))
desc = g_strdup_printf ("%s ! wavparse name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
else if (strcmp (mime, "audio/x-mod") == 0 ||
strcmp (mime, "audio/x-s3m") == 0 ||
strcmp (mime, "audio/x-xm") == 0 ||
strcmp (mime, "audio/x-it") == 0)
desc = g_strdup_printf ("%s name=source ! modplug name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
else return FALSE;
desc =
g_strdup_printf
("%s name=source ! oggdemux ! vorbisdec name=decoder ! fakesink name=sink",
priv->source_name);
else if ((strcmp (mime, "audio/mpeg") == 0)
|| (strcmp (mime, "audio/x-mp3") == 0)
|| (strcmp (mime, "audio/mp3") == 0)
|| (strcmp (mime, "application/x-id3") == 0)
|| (strcmp (mime, "audio/x-id3") == 0))
desc =
g_strdup_printf
("%s name=source ! id3tag ! mad name=decoder ! audio/x-raw-int ! fakesink name=sink",
priv->source_name);
else if ((strcmp (mime, "application/x-flac") == 0)
|| (strcmp (mime, "audio/x-flac") == 0))
desc =
g_strdup_printf
("%s name=source ! flacdec name=decoder ! audio/x-raw-int ! fakesink name=sink",
priv->source_name);
else if ((strcmp (mime, "audio/wav") == 0)
|| (strcmp (mime, "audio/x-wav") == 0))
desc =
g_strdup_printf
("%s ! wavparse name=decoder ! audio/x-raw-int ! fakesink name=sink",
priv->source_name);
else if (strcmp (mime, "audio/x-mod") == 0
|| strcmp (mime, "audio/x-s3m") == 0 || strcmp (mime, "audio/x-xm") == 0
|| strcmp (mime, "audio/x-it") == 0)
desc =
g_strdup_printf
("%s name=source ! modplug name=decoder ! audio/x-raw-int ! fakesink name=sink",
priv->source_name);
else
return FALSE;
GST_DEBUG ("using description %s", desc);
priv->pipeline_desc = desc;
priv->pipeline = gst_parse_launch (desc, &error);
if (error)
{
if (error) {
g_warning ("Error parsing pipeline description: %s\n", error->message);
g_error_free (error);
return FALSE;
@ -398,25 +407,27 @@ gmi_set_mime (GstMediaInfo *info, const char *mime)
/* get the "decoder" source pad */
priv->decoder_pad = gst_element_get_pad (priv->decoder, "src");
g_assert (GST_IS_PAD (priv->decoder_pad));
GST_DEBUG ("decoder pad: %s:%s", gst_object_get_name (gst_object_get_parent (GST_OBJECT (priv->decoder_pad))), gst_pad_get_name (priv->decoder_pad));
GST_DEBUG ("decoder pad: %s:%s",
gst_object_get_name (gst_object_get_parent (GST_OBJECT (priv->
decoder_pad))), gst_pad_get_name (priv->decoder_pad));
/* attach notify handler */
g_signal_connect (G_OBJECT (info->priv->pipeline), "deep_notify",
G_CALLBACK (deep_notify_callback), info->priv);
g_signal_connect (G_OBJECT (info->priv->pipeline), "found-tag", G_CALLBACK (found_tag_callback), info->priv);
G_CALLBACK (deep_notify_callback), info->priv);
g_signal_connect (G_OBJECT (info->priv->pipeline), "found-tag",
G_CALLBACK (found_tag_callback), info->priv);
g_signal_connect (G_OBJECT (info->priv->pipeline), "error",
G_CALLBACK (error_callback), info->priv);
G_CALLBACK (error_callback), info->priv);
return TRUE;
}
/* clear the decoding pipeline */
void
gmi_clear_decoder (GstMediaInfo *info)
gmi_clear_decoder (GstMediaInfo * info)
{
if (info->priv->pipeline)
{
GST_DEBUG("Unreffing pipeline");
if (info->priv->pipeline) {
GST_DEBUG ("Unreffing pipeline");
gst_object_unref (GST_OBJECT (info->priv->pipeline));
}
info->priv->pipeline = NULL;
@ -430,7 +441,7 @@ gmi_clear_decoder (GstMediaInfo *info)
/* prepare for typefind, move from NULL to TYPEFIND */
gboolean
gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
gmip_find_type_pre (GstMediaInfoPriv * priv, GError ** error)
{
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -440,23 +451,21 @@ gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
* just use it through this function only */
priv->pipeline = gst_pipeline_new ("pipeline-typefind");
if (!GST_IS_PIPELINE (priv->pipeline))
{
if (!GST_IS_PIPELINE (priv->pipeline)) {
gst_media_info_error_create (error, "Internal GStreamer error.");
return FALSE;
}
gst_bin_add (GST_BIN (priv->pipeline), priv->typefind);
GST_MEDIA_INFO_MAKE_OR_ERROR (priv->source, priv->source_name, "source",
error);
error);
g_object_set (G_OBJECT (priv->source), "location", priv->location, NULL);
gst_bin_add (GST_BIN (priv->pipeline), priv->source);
if (!gst_element_link (priv->source, priv->typefind))
g_warning ("Couldn't connect source and typefind\n");
g_signal_connect (G_OBJECT (priv->typefind), "have-type",
G_CALLBACK (have_type_callback), priv);
G_CALLBACK (have_type_callback), priv);
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
{
== GST_STATE_FAILURE) {
g_warning ("Couldn't set to play");
return FALSE;
}
@ -467,24 +476,20 @@ gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
/* finish off typefind */
gboolean
gmip_find_type_post (GstMediaInfoPriv *priv)
gmip_find_type_post (GstMediaInfoPriv * priv)
{
/*clear up typefind */
gst_element_set_state (priv->pipeline, GST_STATE_READY);
if (priv->decontainer)
{
if (priv->decontainer) {
gst_element_unlink (priv->source, priv->decontainer);
gst_element_unlink (priv->decontainer, priv->typefind);
gst_bin_remove (GST_BIN (priv->pipeline), priv->decontainer);
}
else
{
} else {
gst_element_unlink (priv->source, priv->typefind);
}
gst_bin_remove (GST_BIN (priv->pipeline), priv->typefind);
if (priv->type == NULL)
{
if (priv->type == NULL) {
g_warning ("iteration ended, type not found !\n");
return FALSE;
}
@ -495,25 +500,23 @@ gmip_find_type_post (GstMediaInfoPriv *priv)
/* complete version */
gboolean
gmip_find_type (GstMediaInfoPriv *priv, GError ** error)
gmip_find_type (GstMediaInfoPriv * priv, GError ** error)
{
if (!gmip_find_type_pre (priv, error))
return FALSE;
GST_DEBUG ("gmip_find_type: iterating");
while ((priv->type == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG("+");
GMI_DEBUG("\n");
while ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
return gmip_find_type_post (priv);
}
/* FIXME: why not have these functions work on priv types ? */
gboolean
gmip_find_stream_pre (GstMediaInfoPriv *priv)
gmip_find_stream_pre (GstMediaInfoPriv * priv)
{
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
{
== GST_STATE_FAILURE) {
g_warning ("Couldn't set to play");
return FALSE;
}
@ -522,7 +525,7 @@ gmip_find_stream_pre (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_stream_post (GstMediaInfoPriv *priv)
gmip_find_stream_post (GstMediaInfoPriv * priv)
{
GstMediaInfoStream *stream = priv->stream;
const GstFormat *formats;
@ -541,8 +544,7 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
/* get supported formats on decoder pad */
formats = gst_pad_get_formats (priv->decoder_pad);
while (*formats)
{
while (*formats) {
const GstFormatDefinition *definition;
format = *formats;
@ -551,16 +553,13 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
definition = gst_format_get_details (*formats);
GST_DEBUG ("trying to figure out length for format %s", definition->nick);
res = gst_pad_query (priv->decoder_pad, GST_QUERY_TOTAL,
&format, &value);
res = gst_pad_query (priv->decoder_pad, GST_QUERY_TOTAL, &format, &value);
if (res)
{
switch (format)
{
case GST_FORMAT_TIME:
stream->length_time = value;
GST_DEBUG (" total %s: %lld", definition->nick, value);
if (res) {
switch (format) {
case GST_FORMAT_TIME:
stream->length_time = value;
GST_DEBUG (" total %s: %lld", definition->nick, value);
break;
case GST_FORMAT_DEFAULT:
case GST_FORMAT_BYTES:
@ -568,35 +567,33 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
default:
/* separation is necessary because track_format doesn't resolve to
* int */
if (format == track_format)
{
if (format == track_format) {
stream->length_tracks = value;
GST_DEBUG (" total %s: %lld", definition->nick, value);
}
else
GST_DEBUG (" total %s: %lld", definition->nick, value);
} else
GST_DEBUG ("unhandled format %s", definition->nick);
}
}
else
} else
GST_DEBUG ("query didn't return result for %s", definition->nick);
formats++;
}
if (stream->length_tracks == 0) stream->length_tracks = 1;
if (stream->length_tracks == 0)
stream->length_tracks = 1;
/* now get number of bytes from the sink pad to get the bitrate */
format = GST_FORMAT_BYTES;
g_assert (GST_IS_PAD (priv->source_pad));
res = gst_pad_query (priv->source_pad, GST_QUERY_TOTAL,
&format, &value);
if (!res) g_warning ("Failed to query on sink pad !");
res = gst_pad_query (priv->source_pad, GST_QUERY_TOTAL, &format, &value);
if (!res)
g_warning ("Failed to query on sink pad !");
bytes = value;
GST_DEBUG ("bitrate calc: bytes gotten: %ld", bytes);
if (bytes)
{
if (bytes) {
double seconds = (double) stream->length_time / GST_SECOND;
double bits = bytes * 8;
stream->bitrate = (long) (bits / seconds);
}
GST_DEBUG ("moving to STATE_METADATA\n");
@ -607,7 +604,7 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
/* get properties of complete physical stream
* and return them in pre-alloced stream struct in priv->stream */
gboolean
gmip_find_stream (GstMediaInfoPriv *priv)
gmip_find_stream (GstMediaInfoPriv * priv)
{
GST_DEBUG ("mip_find_stream start");
@ -615,16 +612,13 @@ gmip_find_stream (GstMediaInfoPriv *priv)
/* iterate until caps are found */
/* FIXME: this should be done through the plugin sending some signal
* that it is ready for queries */
while (gst_bin_iterate (GST_BIN (priv->pipeline)) &&
priv->format == NULL)
;
while (gst_bin_iterate (GST_BIN (priv->pipeline)) && priv->format == NULL);
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
== GST_STATE_FAILURE)
== GST_STATE_FAILURE)
g_warning ("Couldn't set to paused");
if (priv->format == NULL)
{
GMI_DEBUG("gmip_find_stream: couldn't get caps !");
if (priv->format == NULL) {
GMI_DEBUG ("gmip_find_stream: couldn't get caps !");
return FALSE;
}
return gmip_find_stream_post (priv);
@ -632,14 +626,13 @@ gmip_find_stream (GstMediaInfoPriv *priv)
/* find metadata encoded in media and store in priv->metadata */
gboolean
gmip_find_track_metadata_pre (GstMediaInfoPriv *priv)
gmip_find_track_metadata_pre (GstMediaInfoPriv * priv)
{
/* FIXME: this is a hack to set max allowed iterations for metadata
* querying - we should make gst smarter by itself instead */
priv->metadata_iters = 0;
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
{
== GST_STATE_FAILURE) {
g_warning ("Couldn't set to play");
return FALSE;
}
@ -647,10 +640,10 @@ gmip_find_track_metadata_pre (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_metadata_post (GstMediaInfoPriv *priv)
gmip_find_track_metadata_post (GstMediaInfoPriv * priv)
{
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
== GST_STATE_FAILURE)
== GST_STATE_FAILURE)
return FALSE;
priv->current_track->metadata = priv->metadata;
priv->metadata = NULL;
@ -658,14 +651,13 @@ gmip_find_track_metadata_post (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_metadata (GstMediaInfoPriv *priv)
gmip_find_track_metadata (GstMediaInfoPriv * priv)
{
gmip_find_track_metadata_pre (priv);
GST_DEBUG ("gmip_find_metadata: iterating");
while ((priv->metadata == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG("+");
GMI_DEBUG("\n");
while ((priv->metadata == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_metadata_post (priv);
return TRUE;
@ -674,11 +666,10 @@ gmip_find_track_metadata (GstMediaInfoPriv *priv)
/* find streaminfo found by decoder and store in priv->streaminfo */
/* FIXME: this is an exact copy, so reuse this function instead */
gboolean
gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv)
gmip_find_track_streaminfo_pre (GstMediaInfoPriv * priv)
{
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
{
== GST_STATE_FAILURE) {
g_warning ("Couldn't set to play");
return FALSE;
}
@ -686,7 +677,7 @@ gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
gmip_find_track_streaminfo_post (GstMediaInfoPriv * priv)
{
GstFormat format, track_format;
@ -694,33 +685,26 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
/* now add total length to this, and maybe even bitrate ? FIXME */
track_format = gst_format_get_by_nick ("logical_stream");
if (track_format == 0)
{
if (track_format == 0) {
g_print ("FIXME: implement getting length of whole track\n");
}
else
{
} else {
/* which one are we at ? */
long track_num;
gint64 value_start, value_end;
gboolean res;
res = gst_pad_query (priv->decoder_pad, GST_QUERY_POSITION,
&track_format, &value_start);
if (res)
{
&track_format, &value_start);
if (res) {
format = GST_FORMAT_TIME;
track_num = value_start;
GST_DEBUG ("we are currently at %ld", track_num);
res = gst_pad_convert (priv->decoder_pad,
track_format, track_num,
&format, &value_start);
res = gst_pad_convert (priv->decoder_pad,
track_format, track_num, &format, &value_start);
res &= gst_pad_convert (priv->decoder_pad,
track_format, track_num + 1,
&format, &value_end);
if (res)
{
/* substract to get the length */
track_format, track_num + 1, &format, &value_end);
if (res) {
/* substract to get the length */
GST_DEBUG ("start %lld, end %lld", value_start, value_end);
value_end -= value_start;
/* FIXME: check units; this is in seconds */
@ -737,14 +721,14 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_streaminfo (GstMediaInfoPriv *priv)
gmip_find_track_streaminfo (GstMediaInfoPriv * priv)
{
gmip_find_track_streaminfo_pre (priv);
GST_DEBUG ("DEBUG: gmip_find_streaminfo: iterating");
while ((priv->streaminfo == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG("+");
GMI_DEBUG("\n");
gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_streaminfo_post (priv);
return TRUE;
@ -752,11 +736,10 @@ gmip_find_track_streaminfo (GstMediaInfoPriv *priv)
/* find format found by decoder and store in priv->format */
gboolean
gmip_find_track_format_pre (GstMediaInfoPriv *priv)
gmip_find_track_format_pre (GstMediaInfoPriv * priv)
{
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
== GST_STATE_FAILURE)
{
== GST_STATE_FAILURE) {
g_warning ("Couldn't set to play");
return FALSE;
}
@ -764,10 +747,10 @@ gmip_find_track_format_pre (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_format_post (GstMediaInfoPriv *priv)
gmip_find_track_format_post (GstMediaInfoPriv * priv)
{
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
== GST_STATE_FAILURE)
== GST_STATE_FAILURE)
return FALSE;
priv->current_track->format = priv->format;
priv->format = NULL;
@ -775,17 +758,14 @@ gmip_find_track_format_post (GstMediaInfoPriv *priv)
}
gboolean
gmip_find_track_format (GstMediaInfoPriv *priv)
gmip_find_track_format (GstMediaInfoPriv * priv)
{
gmip_find_track_format_pre (priv);
GST_DEBUG ("DEBUG: gmip_find_format: iterating");
while ((priv->format == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG("+");
GMI_DEBUG("\n");
while ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_format_post (priv);
return TRUE;
}

View file

@ -72,69 +72,65 @@ struct GstMediaInfoPriv
gint metadata_iters;
GstTagList *streaminfo;
GstElement *pipeline; /* will be != NULL during collection */
gchar *pipeline_desc; /* will be != NULL during collection */
GstElement *fakesink; /* so we can get caps from the
decoder sink pad */
gchar *source_name; /* type of element used as source */
GstElement *pipeline; /* will be != NULL during collection */
gchar *pipeline_desc; /* will be != NULL during collection */
GstElement *fakesink; /* so we can get caps from the
decoder sink pad */
gchar *source_name; /* type of element used as source */
GstElement *source;
GstPad *source_pad; /* pad for querying encoded caps */
GstPad *source_pad; /* pad for querying encoded caps */
GstElement *decoder;
GstPad *decoder_pad; /* pad for querying decoded caps */
GstElement *decontainer; /* element to typefind in containers */
GstPad *decoder_pad; /* pad for querying decoded caps */
GstElement *decontainer; /* element to typefind in containers */
GstMediaInfoState state; /* current state of state machine */
gchar *location; /* location set on the info object */
guint16 flags; /* flags supplied for detection */
GstMediaInfoTrack *current_track; /* track pointer under inspection */
glong current_track_num; /* current track under inspection */
GstMediaInfoState state; /* current state of state machine */
gchar *location; /* location set on the info object */
guint16 flags; /* flags supplied for detection */
GstMediaInfoTrack *current_track; /* track pointer under inspection */
glong current_track_num; /* current track under inspection */
GstMediaInfoStream *stream; /* total stream properties */
char *cache; /* location of cache */
GstMediaInfoStream *stream; /* total stream properties */
char *cache; /* location of cache */
GError *error; /* error for creation problems */
GError *error; /* error for creation problems */
};
/* declarations */
GstMediaInfoStream *
gmi_stream_new (void);
void gmi_stream_free (GstMediaInfoStream *stream);
GstMediaInfoStream *gmi_stream_new (void);
void gmi_stream_free (GstMediaInfoStream * stream);
GstMediaInfoTrack *
gmi_track_new (void);
GstMediaInfoTrack *gmi_track_new (void);
void gmip_reset (GstMediaInfoPriv *priv);
gboolean gmip_init (GstMediaInfoPriv *priv, GError **error);
void gmip_reset (GstMediaInfoPriv * priv);
gboolean gmip_init (GstMediaInfoPriv * priv, GError ** error);
void gmi_clear_decoder (GstMediaInfo *info);
void gmi_clear_decoder (GstMediaInfo * info);
gboolean gmi_seek_to_track (GstMediaInfo *info,
long track);
gboolean gmi_seek_to_track (GstMediaInfo * info, long track);
gboolean gmi_set_mime (GstMediaInfo *info,
const char *mime);
gboolean gmi_set_mime (GstMediaInfo * info, const char *mime);
void deep_notify_callback (GObject *object,
GstObject *origin,
GParamSpec *pspec,
GstMediaInfoPriv *priv);
void found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, GstMediaInfoPriv *priv);
void error_callback (GObject *element, GstElement *source, GError *error, gchar *debug, GstMediaInfoPriv *priv);
void deep_notify_callback (GObject * object,
GstObject * origin, GParamSpec * pspec, GstMediaInfoPriv * priv);
void found_tag_callback (GObject * pipeline, GstElement * source,
GstTagList * tags, GstMediaInfoPriv * priv);
void error_callback (GObject * element, GstElement * source, GError * error,
gchar * debug, GstMediaInfoPriv * priv);
gboolean gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error);
gboolean gmip_find_type_post (GstMediaInfoPriv *priv);
gboolean gmip_find_type (GstMediaInfoPriv *priv, GError **error);
gboolean gmip_find_stream_pre (GstMediaInfoPriv *priv);
gboolean gmip_find_stream_post (GstMediaInfoPriv *priv);
gboolean gmip_find_stream (GstMediaInfoPriv *priv);
gboolean gmip_find_track_metadata_pre (GstMediaInfoPriv *priv);
gboolean gmip_find_track_metadata_post (GstMediaInfoPriv *priv);
gboolean gmip_find_track_metadata (GstMediaInfoPriv *priv);
gboolean gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv);
gboolean gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv);
gboolean gmip_find_track_streaminfo (GstMediaInfoPriv *priv);
gboolean gmip_find_track_format_pre (GstMediaInfoPriv *priv);
gboolean gmip_find_track_format_post (GstMediaInfoPriv *priv);
gboolean gmip_find_track_format (GstMediaInfoPriv *priv);
gboolean gmip_find_type_pre (GstMediaInfoPriv * priv, GError ** error);
gboolean gmip_find_type_post (GstMediaInfoPriv * priv);
gboolean gmip_find_type (GstMediaInfoPriv * priv, GError ** error);
gboolean gmip_find_stream_pre (GstMediaInfoPriv * priv);
gboolean gmip_find_stream_post (GstMediaInfoPriv * priv);
gboolean gmip_find_stream (GstMediaInfoPriv * priv);
gboolean gmip_find_track_metadata_pre (GstMediaInfoPriv * priv);
gboolean gmip_find_track_metadata_post (GstMediaInfoPriv * priv);
gboolean gmip_find_track_metadata (GstMediaInfoPriv * priv);
gboolean gmip_find_track_streaminfo_pre (GstMediaInfoPriv * priv);
gboolean gmip_find_track_streaminfo_post (GstMediaInfoPriv * priv);
gboolean gmip_find_track_streaminfo (GstMediaInfoPriv * priv);
gboolean gmip_find_track_format_pre (GstMediaInfoPriv * priv);
gboolean gmip_find_track_format_post (GstMediaInfoPriv * priv);
gboolean gmip_find_track_format (GstMediaInfoPriv * priv);
#endif /* __GST_MEDIA_INFO_PRIV_H__ */

View file

@ -5,7 +5,7 @@
#include "media-info.h"
static void
print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
{
gint i, count;
@ -17,8 +17,8 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
g_assert (gst_tag_list_get_string_index (list, tag, i, &str));
} else {
str = g_strdup_value_contents (
gst_tag_list_get_value_index (list, tag, i));
str =
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
}
if (i == 0) {
@ -32,7 +32,7 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
}
static void
info_print (GstMediaInfoStream *stream)
info_print (GstMediaInfoStream * stream)
{
int i;
GList *p;
@ -40,17 +40,15 @@ info_print (GstMediaInfoStream *stream)
g_print ("- mime type: %s\n", stream->mime);
g_print ("- length: %.3f seconds\n",
(gdouble) stream->length_time / GST_SECOND);
(gdouble) stream->length_time / GST_SECOND);
g_print ("- bitrate: %.3f kbps\n", stream->bitrate / 1000.0);
g_print ("- number of tracks: %ld\n", stream->length_tracks);
p = stream->tracks;
if (p == NULL)
{
if (p == NULL) {
g_print ("- no track information, probably an error\n");
return;
}
for (i = 0; i < stream->length_tracks; ++i)
{
for (i = 0; i < stream->length_tracks; ++i) {
g_print ("- track %d\n", i);
track = (GstMediaInfoTrack *) p->data;
g_print (" - metadata:\n");
@ -80,16 +78,14 @@ main (int argc, char *argv[])
gst_init (&argc, &argv);
info = gst_media_info_new (&error);
if (error != NULL)
{
if (error != NULL) {
g_print ("Error creating media-info object: %s\n", error->message);
g_error_free (error);
return -1;
}
g_assert (G_IS_OBJECT (info));
if (!gst_media_info_set_source (info, "gnomevfssrc", &error))
{
if (!gst_media_info_set_source (info, "gnomevfssrc", &error)) {
g_print ("Could not set gnomevfssrc as a source\n");
g_print ("reason: %s\n", error->message);
g_error_free (error);
@ -97,19 +93,18 @@ main (int argc, char *argv[])
}
g_print ("stream: %p, &stream: %p\n", stream, &stream);
for (i = 1; i < argc; ++i)
{
for (i = 1; i < argc; ++i) {
/*
stream = gst_media_info_read (info, argv[i], GST_MEDIA_INFO_ALL);
*/
stream = gst_media_info_read (info, argv[i], GST_MEDIA_INFO_ALL);
*/
gst_media_info_read_with_idler (info, argv[i], GST_MEDIA_INFO_ALL, &error);
while (gst_media_info_read_idler (info, &stream, &error) && stream == NULL)
/* keep idling */ g_print ("+");
/* keep idling */
g_print ("+");
g_print ("\nFILE: %s\n", argv[i]);
g_print ("stream: %p, &stream: %p\n", stream, &stream);
if (error)
{
if (error) {
g_print ("Error reading media info: %s\n", error->message);
g_error_free (error);
}

View file

@ -26,12 +26,11 @@
#include "media-info.h"
#include "media-info-priv.h"
static void gst_media_info_class_init (GstMediaInfoClass *klass);
static void gst_media_info_instance_init (GstMediaInfo *info);
static void gst_media_info_class_init (GstMediaInfoClass * klass);
static void gst_media_info_instance_init (GstMediaInfo * info);
static void gst_media_info_get_property (GObject *object, guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gst_media_info_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean _media_info_inited = FALSE;
@ -64,6 +63,7 @@ GQuark
gst_media_info_error_quark (void)
{
static GQuark quark = 0;
if (quark == 0)
quark = g_quark_from_static_string ("gst-media-info-error-quark");
return quark;
@ -86,11 +86,12 @@ GST_DEBUG_CATEGORY (gst_media_info_debug);
void
gst_media_info_init (void)
{
if (_media_info_inited) return;
if (_media_info_inited)
return;
/* register our debugging category */
GST_DEBUG_CATEGORY_INIT (gst_media_info_debug, "GST_MEDIA_INFO", 0,
"GStreamer media-info library");
"GStreamer media-info library");
GST_DEBUG ("Initialized media-info library");
_media_info_inited = TRUE;
}
@ -99,8 +100,8 @@ GType
gst_media_info_get_type (void)
{
static GType gst_media_info_type = 0;
if (!gst_media_info_type)
{
if (!gst_media_info_type) {
static const GTypeInfo gst_media_info_info = {
sizeof (GstMediaInfoClass),
(GBaseInitFunc) NULL,
@ -113,14 +114,13 @@ gst_media_info_get_type (void)
NULL
};
gst_media_info_type = g_type_register_static (G_TYPE_OBJECT,
"GstMediaInfo",
&gst_media_info_info, 0);
"GstMediaInfo", &gst_media_info_info, 0);
}
return gst_media_info_type;
}
static void
gst_media_info_class_init (GstMediaInfoClass *klass)
gst_media_info_class_init (GstMediaInfoClass * klass)
{
GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
@ -129,36 +129,36 @@ gst_media_info_class_init (GstMediaInfoClass *klass)
/*
object_class->finalize = gst_media_info_finalize;
object_class->dispose = gst_media_info_dispose;
*/
object_class->finalize = gst_media_info_finalize;
object_class->dispose = gst_media_info_dispose;
*/
/*
g_object_class->set_property = gst_media_info_set_property;
*/
g_object_class->set_property = gst_media_info_set_property;
*/
g_object_class->get_property = gst_media_info_get_property;
klass->media_info_signal = NULL;
gst_media_info_signals [MEDIA_INFO_SIGNAL] =
g_signal_new ("media-info",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMediaInfoClass, media_info_signal),
NULL, NULL,
gst_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gst_media_info_signals[MEDIA_INFO_SIGNAL] =
g_signal_new ("media-info",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMediaInfoClass, media_info_signal),
NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
static void
gst_media_info_instance_init (GstMediaInfo *info)
gst_media_info_instance_init (GstMediaInfo * info)
{
GError **error;
info->priv = g_new0 (GstMediaInfoPriv, 1);
error = &info->priv->error;
if (!_media_info_inited) { gst_media_info_init (); }
if (!_media_info_inited) {
gst_media_info_init ();
}
gmip_init (info->priv, error);
gmip_reset (info->priv);
@ -166,13 +166,12 @@ gst_media_info_instance_init (GstMediaInfo *info)
/* get/set */
static void
gst_media_info_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
gst_media_info_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstMediaInfo *info = GST_MEDIA_INFO (object);
switch (prop_id)
{
switch (prop_id) {
case PROP_SOURCE:
g_value_set_string (value, info->priv->source_name);
break;
@ -183,21 +182,17 @@ gst_media_info_get_property (GObject *object, guint prop_id,
}
GstMediaInfo *
gst_media_info_new (GError **error)
gst_media_info_new (GError ** error)
{
GstMediaInfo *info = g_object_new (GST_MEDIA_INFO_TYPE, NULL);
if (info->priv->error)
{
if (error)
{
if (info->priv->error) {
if (error) {
*error = info->priv->error;
info->priv->error = NULL;
}
else
{
} else {
g_warning ("Error creating GstMediaInfo object.\n%s",
info->priv->error->message);
info->priv->error->message);
g_error_free (info->priv->error);
}
}
@ -208,7 +203,8 @@ gst_media_info_new (GError **error)
* public methods
*/
gboolean
gst_media_info_set_source (GstMediaInfo *info, const char *source, GError **error)
gst_media_info_set_source (GstMediaInfo * info, const char *source,
GError ** error)
{
info->priv->source_name = g_strdup (source);
return TRUE;
@ -221,12 +217,12 @@ gst_media_info_set_source (GstMediaInfo *info, const char *source, GError **erro
* previous one is done ?
*/
void
gst_media_info_read_with_idler (GstMediaInfo *info, const char *location,
guint16 flags, GError **error)
gst_media_info_read_with_idler (GstMediaInfo * info, const char *location,
guint16 flags, GError ** error)
{
GstMediaInfoPriv *priv = info->priv;
gmip_reset (info->priv); /* reset all structs */
gmip_reset (info->priv); /* reset all structs */
priv->location = g_strdup (location);
priv->flags = flags;
}
@ -236,12 +232,14 @@ gst_media_info_read_with_idler (GstMediaInfo *info, const char *location,
* returns: TRUE if it was able to idle, FALSE if there was an error
*/
gboolean
gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GError **error)
gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
GError ** error)
{
GstMediaInfoPriv *priv;
/* if it's NULL then we're sure something went wrong higher up) */
if (info == NULL) return FALSE;
if (info == NULL)
return FALSE;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
priv = info->priv;
@ -249,15 +247,13 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
g_assert (streamp != NULL);
g_assert (priv);
switch (priv->state)
{
switch (priv->state) {
case GST_MEDIA_INFO_STATE_NULL:
/* make sure we have a source */
if (!priv->source_name)
{
*error = g_error_new (GST_MEDIA_INFO_ERROR, 0,
"No source set on media info.");
return FALSE;
if (!priv->source_name) {
*error = g_error_new (GST_MEDIA_INFO_ERROR, 0,
"No source set on media info.");
return FALSE;
}
/* need to find type */
@ -269,29 +265,27 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
gchar *mime;
GST_LOG ("STATE_TYPEFIND");
if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
{
if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
GST_DEBUG ("iterating while in STATE_TYPEFIND");
GMI_DEBUG("?");
return TRUE;
GMI_DEBUG ("?");
return TRUE;
}
if (priv->type == NULL)
{
g_warning ("Couldn't find type\n");
if (priv->type == NULL) {
g_warning ("Couldn't find type\n");
return FALSE;
}
/* do the state transition */
GST_DEBUG ("doing find_type_post");
gmip_find_type_post (priv);
GST_DEBUG ("finding out mime type");
mime = g_strdup (gst_structure_get_name (
gst_caps_get_structure(priv->type, 0)));
mime =
g_strdup (gst_structure_get_name (gst_caps_get_structure (priv->type,
0)));
GST_DEBUG ("found out mime type: %s", mime);
if (!gmi_set_mime (info, mime))
{
/* FIXME: pop up error */
GST_DEBUG ("no decoder pipeline found for mime %s", mime);
return FALSE;
if (!gmi_set_mime (info, mime)) {
/* FIXME: pop up error */
GST_DEBUG ("no decoder pipeline found for mime %s", mime);
return FALSE;
}
priv->stream = gmi_stream_new ();
GST_DEBUG ("new stream: %p", priv->stream);
@ -303,14 +297,12 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
case GST_MEDIA_INFO_STATE_STREAM:
{
GST_LOG ("STATE_STREAM");
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
{
GMI_DEBUG("?");
return TRUE;
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
GMI_DEBUG ("?");
return TRUE;
}
if (priv->format == NULL)
{
g_warning ("Couldn't find format\n");
if (priv->format == NULL) {
g_warning ("Couldn't find format\n");
return FALSE;
}
/* do state transition; stream -> first track metadata */
@ -320,26 +312,25 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
gmip_find_track_metadata_pre (priv);
return TRUE;
}
/* these ones are repeated per track */
/* these ones are repeated per track */
case GST_MEDIA_INFO_STATE_METADATA:
{
if ((priv->metadata == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)) &&
priv->metadata_iters < MAX_METADATA_ITERS)
{
GMI_DEBUG("?");
priv->metadata_iters < MAX_METADATA_ITERS) {
GMI_DEBUG ("?");
priv->metadata_iters++;
return TRUE;
return TRUE;
}
if (priv->metadata_iters == MAX_METADATA_ITERS)
g_print ("iterated a few times, didn't find metadata\n");
if (priv->metadata == NULL)
{
g_print ("iterated a few times, didn't find metadata\n");
if (priv->metadata == NULL) {
/* this is not a permanent failure */
GST_DEBUG ("Couldn't find metadata");
GST_DEBUG ("Couldn't find metadata");
}
GST_DEBUG ("found metadata of track %ld", priv->current_track_num);
if (!gmip_find_track_metadata_post (priv)) return FALSE;
if (!gmip_find_track_metadata_post (priv))
return FALSE;
GST_DEBUG ("METADATA: going to STREAMINFO\n");
priv->state = GST_MEDIA_INFO_STATE_STREAMINFO;
return gmip_find_track_streaminfo_pre (priv);
@ -347,53 +338,47 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
case GST_MEDIA_INFO_STATE_STREAMINFO:
{
if ((priv->streaminfo == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
{
GMI_DEBUG("?");
return TRUE;
gst_bin_iterate (GST_BIN (priv->pipeline))) {
GMI_DEBUG ("?");
return TRUE;
}
if (priv->streaminfo == NULL)
{
if (priv->streaminfo == NULL) {
/* this is not a permanent failure */
GST_DEBUG ("Couldn't find streaminfo");
}
else
GST_DEBUG ("found streaminfo of track %ld", priv->current_track_num);
if (!gmip_find_track_streaminfo_post (priv)) return FALSE;
GST_DEBUG ("Couldn't find streaminfo");
} else
GST_DEBUG ("found streaminfo of track %ld", priv->current_track_num);
if (!gmip_find_track_streaminfo_post (priv))
return FALSE;
priv->state = GST_MEDIA_INFO_STATE_FORMAT;
return gmip_find_track_format_pre (priv);
}
case GST_MEDIA_INFO_STATE_FORMAT:
{
if ((priv->format == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
{
GMI_DEBUG("?");
return TRUE;
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
GMI_DEBUG ("?");
return TRUE;
}
if (priv->format == NULL)
{
g_warning ("Couldn't find format\n");
if (priv->format == NULL) {
g_warning ("Couldn't find format\n");
return FALSE;
}
GST_DEBUG ("found format of track %ld", priv->current_track_num);
if (!gmip_find_track_format_post (priv)) return FALSE;
if (!gmip_find_track_format_post (priv))
return FALSE;
/* save the track info */
priv->stream->tracks = g_list_append (priv->stream->tracks,
priv->current_track);
priv->current_track);
/* these alloc'd data types have been handed off */
priv->current_track = NULL;
priv->location = NULL;
/* now see if we need to seek to a next track or not */
priv->current_track_num++;
if (priv->current_track_num < priv->stream->length_tracks)
{
gmi_seek_to_track (info, priv->current_track_num);
priv->current_track = gmi_track_new ();
if (!gmip_find_track_metadata_pre (priv))
{
if (priv->current_track_num < priv->stream->length_tracks) {
gmi_seek_to_track (info, priv->current_track_num);
priv->current_track = gmi_track_new ();
if (!gmip_find_track_metadata_pre (priv)) {
g_free (priv->current_track);
return FALSE;
return FALSE;
}
priv->state = GST_MEDIA_INFO_STATE_METADATA;
return TRUE;
@ -407,24 +392,26 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
}
case GST_MEDIA_INFO_STATE_DONE:
return TRUE;
default:
default:
g_warning ("don't know what to do\n");
return FALSE;
}
}
}
/* main function
* read all possible info from the file pointed to by location
* use flags to limit the type of information searched for */
GstMediaInfoStream *
gst_media_info_read (GstMediaInfo *info, const char *location, guint16 flags, GError **error)
gst_media_info_read (GstMediaInfo * info, const char *location, guint16 flags,
GError ** error)
{
GstMediaInfoStream *stream = NULL;
gst_media_info_read_with_idler (info, location, flags, error);
if (*error) return FALSE;
if (*error)
return FALSE;
while (gst_media_info_read_idler (info, &stream, error) && stream == NULL)
/* keep looping */;
/* keep looping */ ;
if (*error)
return NULL;

View file

@ -23,11 +23,9 @@
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct GstMediaInfoPriv GstMediaInfoPriv;
typedef struct _GstMediaInfo GstMediaInfo;
typedef struct _GstMediaInfoClass GstMediaInfoClass;
G_BEGIN_DECLS typedef struct GstMediaInfoPriv GstMediaInfoPriv;
typedef struct _GstMediaInfo GstMediaInfo;
typedef struct _GstMediaInfoClass GstMediaInfoClass;
struct _GstMediaInfo
{
@ -43,8 +41,9 @@ struct _GstMediaInfoClass
GObjectClass parent_class;
/* signals */
void (*media_info_signal) (GstMediaInfo *gst_media_info);
void (*error_signal) (GstMediaInfo *gst_media_info, GError *error, const gchar *debug);
void (*media_info_signal) (GstMediaInfo * gst_media_info);
void (*error_signal) (GstMediaInfo * gst_media_info, GError * error,
const gchar * debug);
gpointer _gst_reserved[GST_PADDING];
};
@ -100,34 +99,25 @@ typedef struct
#define GST_MEDIA_INFO_FORMAT 1 << 5
#define GST_MEDIA_INFO_ALL ((1 << 6) - 1)
GQuark gst_media_info_error_quark (void);
GQuark gst_media_info_error_quark (void);
void gst_media_info_init (void);
GType gst_media_info_get_type (void);
void gst_media_info_init (void);
GType gst_media_info_get_type (void);
GstMediaInfo * gst_media_info_new (GError **error);
GstMediaInfo *gst_media_info_new (GError ** error);
gboolean gst_media_info_set_source (GstMediaInfo * info,
const char *source, GError ** error);
void gst_media_info_read_with_idler (GstMediaInfo * media_info,
const char *location, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
gboolean gst_media_info_read_idler (GstMediaInfo * media_info,
GstMediaInfoStream ** streamp, GError ** error);
GstMediaInfoStream *gst_media_info_read (GstMediaInfo * media_info,
const char *location, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
gboolean gst_media_info_read_many (GstMediaInfo * media_info,
GList * locations, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
GstCaps *gst_media_info_get_next (GstMediaInfo * media_info, GError ** error);
gboolean gst_media_info_set_source (GstMediaInfo *info,
const char *source,
GError **error);
void gst_media_info_read_with_idler (GstMediaInfo *media_info,
const char *location,
guint16 GST_MEDIA_INFO_FLAGS,
GError **error);
gboolean gst_media_info_read_idler (GstMediaInfo *media_info,
GstMediaInfoStream **streamp,
GError **error);
GstMediaInfoStream *
gst_media_info_read (GstMediaInfo *media_info,
const char *location,
guint16 GST_MEDIA_INFO_FLAGS,
GError **error);
gboolean gst_media_info_read_many (GstMediaInfo *media_info,
GList *locations,
guint16 GST_MEDIA_INFO_FLAGS,
GError **error);
GstCaps * gst_media_info_get_next (GstMediaInfo *media_info,
GError **error);
/*
* FIXME: reset ?
gboolean gst_media_info_write (GstMediaInfo *media_info,
@ -136,5 +126,4 @@ gboolean gst_media_info_write (GstMediaInfo *media_info,
*/
G_END_DECLS
#endif /* __GST_MEDIA_INFO_H__ */

View file

@ -26,14 +26,15 @@
#include "mixer.h"
#include "mixer-marshal.h"
enum {
enum
{
MUTE_TOGGLED,
RECORD_TOGGLED,
VOLUME_CHANGED,
LAST_SIGNAL
};
static void gst_mixer_class_init (GstMixerClass *klass);
static void gst_mixer_class_init (GstMixerClass * klass);
static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
@ -56,48 +57,47 @@ gst_mixer_get_type (void)
};
gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE,
"GstMixer",
&gst_mixer_info, 0);
"GstMixer", &gst_mixer_info, 0);
g_type_interface_add_prerequisite (gst_mixer_type,
GST_TYPE_IMPLEMENTS_INTERFACE);
GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_mixer_type;
}
static void
gst_mixer_class_init (GstMixerClass *klass)
gst_mixer_class_init (GstMixerClass * klass)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_mixer_signals[RECORD_TOGGLED] =
g_signal_new ("record-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, record_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
g_signal_new ("record-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, record_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
gst_mixer_signals[MUTE_TOGGLED] =
g_signal_new ("mute-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
g_signal_new ("mute-toggled",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
gst_mixer_signals[VOLUME_CHANGED] =
g_signal_new ("volume-changed",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, volume_changed),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
g_signal_new ("volume-changed",
GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerClass, volume_changed),
NULL, NULL,
gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
initialized = TRUE;
}
klass->mixer_type = GST_MIXER_SOFTWARE;
/* default virtual functions */
klass->list_tracks = NULL;
klass->set_volume = NULL;
@ -119,7 +119,7 @@ gst_mixer_class_init (GstMixerClass *klass)
*/
const GList *
gst_mixer_list_tracks (GstMixer *mixer)
gst_mixer_list_tracks (GstMixer * mixer)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -146,9 +146,7 @@ gst_mixer_list_tracks (GstMixer *mixer)
*/
void
gst_mixer_set_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -169,9 +167,7 @@ gst_mixer_set_volume (GstMixer *mixer,
*/
void
gst_mixer_get_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -198,9 +194,7 @@ gst_mixer_get_volume (GstMixer *mixer,
*/
void
gst_mixer_set_mute (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute)
gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -223,9 +217,7 @@ gst_mixer_set_mute (GstMixer *mixer,
*/
void
gst_mixer_set_record (GstMixer *mixer,
GstMixerTrack *track,
gboolean record)
gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
{
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
@ -235,43 +227,30 @@ gst_mixer_set_record (GstMixer *mixer,
}
void
gst_mixer_mute_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute)
gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[MUTE_TOGGLED], 0,
track, mute);
gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
g_signal_emit_by_name (G_OBJECT (track),
"mute_toggled",
mute);
g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
}
void
gst_mixer_record_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean record)
gst_mixer_record_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean record)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[RECORD_TOGGLED], 0,
track, record);
gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
g_signal_emit_by_name (G_OBJECT (track),
"record_toggled",
record);
g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
}
void
gst_mixer_volume_changed (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes)
gst_mixer_volume_changed (GstMixer * mixer,
GstMixerTrack * track, gint * volumes)
{
g_signal_emit (G_OBJECT (mixer),
gst_mixer_signals[VOLUME_CHANGED], 0,
track, volumes);
gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
g_signal_emit_by_name (G_OBJECT (track),
"volume_changed",
volumes);
g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
}

View file

@ -27,7 +27,6 @@
#include <gst/mixer/mixer-enumtypes.h>
G_BEGIN_DECLS
#define GST_TYPE_MIXER \
(gst_mixer_get_type ())
#define GST_MIXER(obj) \
@ -40,9 +39,7 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
#define GST_MIXER_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass))
#define GST_MIXER_TYPE(klass) (klass->mixer_type)
typedef struct _GstMixer GstMixer;
typedef enum
@ -51,70 +48,52 @@ typedef enum
GST_MIXER_SOFTWARE
} GstMixerType;
typedef struct _GstMixerClass {
typedef struct _GstMixerClass
{
GTypeInterface klass;
GstMixerType mixer_type;
/* virtual functions */
const GList * (* list_tracks) (GstMixer *mixer);
const GList *(*list_tracks) (GstMixer * mixer);
void (* set_volume) (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void (* get_volume) (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void (*set_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
void (*get_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
void (* set_mute) (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void (* set_record) (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
void (*set_mute) (GstMixer * mixer, GstMixerTrack * track, gboolean mute);
void (*set_record) (GstMixer * mixer, GstMixerTrack * track, gboolean record);
/* signals */
void (* mute_toggled) (GstMixer *mixer,
GstMixerTrack *channel,
gboolean mute);
void (* record_toggled) (GstMixer *mixer,
GstMixerTrack *channel,
gboolean record);
void (* volume_changed) (GstMixer *mixer,
GstMixerTrack *channel,
gint *volumes);
void (*mute_toggled) (GstMixer * mixer,
GstMixerTrack * channel, gboolean mute);
void (*record_toggled) (GstMixer * mixer,
GstMixerTrack * channel, gboolean record);
void (*volume_changed) (GstMixer * mixer,
GstMixerTrack * channel, gint * volumes);
gpointer _gst_reserved[GST_PADDING];
} GstMixerClass;
GType gst_mixer_get_type (void);
GType gst_mixer_get_type (void);
/* virtual class function wrappers */
const GList * gst_mixer_list_tracks (GstMixer *mixer);
void gst_mixer_set_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_get_volume (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_set_mute (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void gst_mixer_set_record (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
const GList *gst_mixer_list_tracks (GstMixer * mixer);
void gst_mixer_set_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
void gst_mixer_get_volume (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
void gst_mixer_set_mute (GstMixer * mixer,
GstMixerTrack * track, gboolean mute);
void gst_mixer_set_record (GstMixer * mixer,
GstMixerTrack * track, gboolean record);
/* trigger signals */
void gst_mixer_mute_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean mute);
void gst_mixer_record_toggled (GstMixer *mixer,
GstMixerTrack *track,
gboolean record);
void gst_mixer_volume_changed (GstMixer *mixer,
GstMixerTrack *track,
gint *volumes);
void gst_mixer_mute_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean mute);
void gst_mixer_record_toggled (GstMixer * mixer,
GstMixerTrack * track, gboolean record);
void gst_mixer_volume_changed (GstMixer * mixer,
GstMixerTrack * track, gint * volumes);
G_END_DECLS
#endif /* __GST_MIXER_H__ */

View file

@ -25,7 +25,8 @@
#include "mixertrack.h"
enum {
enum
{
/* FILL ME */
SIGNAL_VOLUME_CHANGED,
SIGNAL_RECORD_TOGGLED,
@ -33,9 +34,9 @@ enum {
LAST_SIGNAL
};
static void gst_mixer_track_class_init (GstMixerTrackClass *klass);
static void gst_mixer_track_init (GstMixerTrack *mixer);
static void gst_mixer_track_dispose (GObject *object);
static void gst_mixer_track_class_init (GstMixerTrackClass * klass);
static void gst_mixer_track_init (GstMixerTrack * mixer);
static void gst_mixer_track_dispose (GObject * object);
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
@ -61,47 +62,46 @@ gst_mixer_track_get_type (void)
gst_mixer_track_type =
g_type_register_static (G_TYPE_OBJECT,
"GstMixerTrack",
&mixer_track_info, 0);
"GstMixerTrack", &mixer_track_info, 0);
}
return gst_mixer_track_type;
}
static void
gst_mixer_track_class_init (GstMixerTrackClass *klass)
gst_mixer_track_class_init (GstMixerTrackClass * klass)
{
GObjectClass *object_klass = (GObjectClass *) klass;
parent_class = g_type_class_ref (G_TYPE_OBJECT);
signals[SIGNAL_RECORD_TOGGLED] =
g_signal_new ("record_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
record_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
g_signal_new ("record_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
record_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
signals[SIGNAL_MUTE_TOGGLED] =
g_signal_new ("mute_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
mute_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
g_signal_new ("mute_toggled", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
mute_toggled),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
signals[SIGNAL_VOLUME_CHANGED] =
g_signal_new ("volume_changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
volume_changed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
g_signal_new ("volume_changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstMixerTrackClass,
volume_changed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
object_klass->dispose = gst_mixer_track_dispose;
}
static void
gst_mixer_track_init (GstMixerTrack *channel)
gst_mixer_track_init (GstMixerTrack * channel)
{
channel->label = NULL;
channel->min_volume = channel->max_volume = 0;
@ -110,7 +110,7 @@ gst_mixer_track_init (GstMixerTrack *channel)
}
static void
gst_mixer_track_dispose (GObject *object)
gst_mixer_track_dispose (GObject * object)
{
GstMixerTrack *channel = GST_MIXER_TRACK (object);

View file

@ -25,7 +25,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_MIXER_TRACK \
(gst_mixer_track_get_type ())
#define GST_MIXER_TRACK(obj) \
@ -38,7 +37,6 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK))
#define GST_IS_MIXER_TRACK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK))
/*
* Naming:
*
@ -54,45 +52,41 @@ G_BEGIN_DECLS
* mixer, which means that setting this track will change
* the hearable volume on any output.
*/
typedef enum {
GST_MIXER_TRACK_INPUT = (1<<0),
GST_MIXER_TRACK_OUTPUT = (1<<1),
GST_MIXER_TRACK_MUTE = (1<<2),
GST_MIXER_TRACK_RECORD = (1<<3),
GST_MIXER_TRACK_MASTER = (1<<4),
GST_MIXER_TRACK_SOFTWARE = (1<<5)
typedef enum
{
GST_MIXER_TRACK_INPUT = (1 << 0),
GST_MIXER_TRACK_OUTPUT = (1 << 1),
GST_MIXER_TRACK_MUTE = (1 << 2),
GST_MIXER_TRACK_RECORD = (1 << 3),
GST_MIXER_TRACK_MASTER = (1 << 4),
GST_MIXER_TRACK_SOFTWARE = (1 << 5)
} GstMixerTrackFlags;
#define GST_MIXER_TRACK_HAS_FLAG(channel, flag) \
((channel)->flags & flag)
typedef struct _GstMixerTrack {
GObject parent;
typedef struct _GstMixerTrack
{
GObject parent;
gchar *label;
gchar *label;
GstMixerTrackFlags flags;
gint num_channels,
min_volume,
max_volume;
gint num_channels, min_volume, max_volume;
} GstMixerTrack;
typedef struct _GstMixerTrackClass {
typedef struct _GstMixerTrackClass
{
GObjectClass parent;
/* signals */
void (* mute_toggled) (GstMixerTrack *channel,
gboolean mute);
void (* record_toggled) (GstMixerTrack *channel,
gboolean record);
void (* volume_changed) (GstMixerTrack *channel,
gint *volumes);
void (*mute_toggled) (GstMixerTrack * channel, gboolean mute);
void (*record_toggled) (GstMixerTrack * channel, gboolean record);
void (*volume_changed) (GstMixerTrack * channel, gint * volumes);
gpointer _gst_reserved[GST_PADDING];
} GstMixerTrackClass;
GType gst_mixer_track_get_type (void);
GType gst_mixer_track_get_type (void);
G_END_DECLS
#endif /* __GST_MIXER_TRACK_H__ */

View file

@ -25,7 +25,7 @@
#include <gst/navigation/navigation.h>
static void gst_navigation_class_init (GstNavigationInterface *iface);
static void gst_navigation_class_init (GstNavigationInterface * iface);
GType
gst_navigation_get_type (void)
@ -46,22 +46,21 @@ gst_navigation_get_type (void)
};
gst_navigation_type = g_type_register_static (G_TYPE_INTERFACE,
"GstNavigation",
&gst_navigation_info, 0);
"GstNavigation", &gst_navigation_info, 0);
}
return gst_navigation_type;
}
static void
gst_navigation_class_init (GstNavigationInterface *iface)
gst_navigation_class_init (GstNavigationInterface * iface)
{
/* default virtual functions */
iface->send_event = NULL;
}
void
gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
gst_navigation_send_event (GstNavigation * navigation, GstStructure * structure)
{
GstNavigationInterface *iface = GST_NAVIGATION_GET_IFACE (navigation);
@ -71,25 +70,20 @@ gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
}
void
gst_navigation_send_key_event (GstNavigation *navigation, const char *event,
const char *key)
gst_navigation_send_key_event (GstNavigation * navigation, const char *event,
const char *key)
{
gst_navigation_send_event (navigation, gst_structure_new (
"application/x-gst-navigation",
"event", G_TYPE_STRING, event,
"key", G_TYPE_STRING, key, NULL));
gst_navigation_send_event (navigation,
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
event, "key", G_TYPE_STRING, key, NULL));
}
void
gst_navigation_send_mouse_event (GstNavigation *navigation, const char *event,
int button, double x, double y)
gst_navigation_send_mouse_event (GstNavigation * navigation, const char *event,
int button, double x, double y)
{
gst_navigation_send_event (navigation, gst_structure_new (
"application/x-gst-navigation",
"event", G_TYPE_STRING, event,
"button", G_TYPE_INT, button,
"pointer_x", G_TYPE_DOUBLE, x,
"pointer_y", G_TYPE_DOUBLE, y, NULL));
gst_navigation_send_event (navigation,
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
event, "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x,
"pointer_y", G_TYPE_DOUBLE, y, NULL));
}

View file

@ -26,7 +26,6 @@
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_NAVIGATION \
(gst_navigation_get_type ())
#define GST_NAVIGATION(obj) \
@ -35,28 +34,28 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION))
#define GST_NAVIGATION_GET_IFACE(obj) \
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface))
typedef struct _GstNavigation GstNavigation;
typedef struct _GstNavigationInterface {
typedef struct _GstNavigationInterface
{
GTypeInterface g_iface;
/* virtual functions */
void (*send_event) (GstNavigation *navigation, GstStructure *structure);
void (*send_event) (GstNavigation * navigation, GstStructure * structure);
gpointer _gst_reserved[GST_PADDING];
} GstNavigationInterface;
GType gst_navigation_get_type (void);
GType gst_navigation_get_type (void);
/* virtual class function wrappers */
void gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure);
void gst_navigation_send_event (GstNavigation * navigation,
GstStructure * structure);
void gst_navigation_send_key_event (GstNavigation *navigation,
const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation *navigation,
const char *event, int button, double x, double y);
void gst_navigation_send_key_event (GstNavigation * navigation,
const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation * navigation,
const char *event, int button, double x, double y);
G_END_DECLS
#endif /* __GST_NAVIGATION_H__ */

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_PLAY_H__
#define __GST_PLAY_H__
@ -46,51 +46,43 @@ typedef enum
typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass;
typedef struct _GstPlayPrivate GstPlayPrivate;
struct _GstPlay
{
GstPipeline pipeline;
GstPlayPrivate *priv;
gpointer _gst_reserved[GST_PADDING];
};
struct _GstPlayClass
{
GstPipelineClass parent_class;
void (*time_tick) (GstPlay *play, gint64 time_nanos);
void (*stream_length) (GstPlay *play, gint64 length_nanos);
void (*have_video_size) (GstPlay *play, gint width, gint height);
void (*time_tick) (GstPlay * play, gint64 time_nanos);
void (*stream_length) (GstPlay * play, gint64 length_nanos);
void (*have_video_size) (GstPlay * play, gint width, gint height);
gpointer _gst_reserved[GST_PADDING];
};
GType gst_play_get_type (void);
GstPlay * gst_play_new (GError **error);
GType gst_play_get_type (void);
GstPlay *gst_play_new (GError ** error);
gboolean gst_play_set_data_src (GstPlay *play,
GstElement *data_src);
gboolean gst_play_set_video_sink (GstPlay *play,
GstElement *video_sink);
gboolean gst_play_set_audio_sink (GstPlay *play,
GstElement *audio_sink);
gboolean gst_play_set_data_src (GstPlay * play, GstElement * data_src);
gboolean gst_play_set_video_sink (GstPlay * play, GstElement * video_sink);
gboolean gst_play_set_audio_sink (GstPlay * play, GstElement * audio_sink);
gboolean gst_play_set_visualization (GstPlay *play,
GstElement *element);
gboolean gst_play_connect_visualization (GstPlay *play,
gboolean connect);
gboolean gst_play_set_visualization (GstPlay * play, GstElement * element);
gboolean gst_play_connect_visualization (GstPlay * play, gboolean connect);
gboolean gst_play_set_location (GstPlay *play,
const char *location);
char * gst_play_get_location (GstPlay *play);
gboolean gst_play_set_location (GstPlay * play, const char *location);
char *gst_play_get_location (GstPlay * play);
gboolean gst_play_seek_to_time (GstPlay *play,
gint64 time_nanos);
gboolean gst_play_seek_to_time (GstPlay * play, gint64 time_nanos);
GstElement * gst_play_get_sink_element (GstPlay *play,
GstElement *element,
GstPlaySinkType sink_type);
GstElement *gst_play_get_sink_element (GstPlay * play,
GstElement * element, GstPlaySinkType sink_type);
#endif /* __GST_PLAY_H__ */

View file

@ -27,12 +27,13 @@
#include "propertyprobe.h"
enum {
enum
{
SIGNAL_PROBE_NEEDED,
LAST_SIGNAL
};
static void gst_property_probe_iface_init (GstPropertyProbeInterface *iface);
static void gst_property_probe_iface_init (GstPropertyProbeInterface * iface);
static guint gst_property_probe_signals[LAST_SIGNAL] = { 0 };
@ -56,30 +57,29 @@ gst_property_probe_get_type (void)
gst_property_probe_type =
g_type_register_static (G_TYPE_INTERFACE,
"GstPropertyProbe",
&gst_property_probe_info, 0);
"GstPropertyProbe", &gst_property_probe_info, 0);
}
return gst_property_probe_type;
}
static void
gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
gst_property_probe_iface_init (GstPropertyProbeInterface * iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
gst_property_probe_signals[SIGNAL_PROBE_NEEDED] =
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPropertyProbeInterface, probe_needed),
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPropertyProbeInterface,
probe_needed), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
initialized = TRUE;
}
/* default virtual functions */
iface->get_properties = NULL;
iface->get_values = NULL;
iface->get_values = NULL;
}
/**
@ -93,23 +93,22 @@ gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
*/
const GList *
gst_property_probe_get_properties (GstPropertyProbe *probe)
gst_property_probe_get_properties (GstPropertyProbe * probe)
{
GstPropertyProbeInterface *iface;
g_return_val_if_fail (probe != NULL, NULL);
iface = GST_PROPERTY_PROBE_GET_IFACE (probe);
if (iface->get_properties)
return iface->get_properties (probe);
return NULL;
}
const GParamSpec *
gst_property_probe_get_property (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_get_property (GstPropertyProbe * probe, const gchar * name)
{
const GList *pspecs = gst_property_probe_get_properties (probe);
@ -129,8 +128,8 @@ gst_property_probe_get_property (GstPropertyProbe *probe,
}
void
gst_property_probe_probe_property (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_probe_property (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -156,8 +155,8 @@ gst_property_probe_probe_property (GstPropertyProbe *probe,
*/
void
gst_property_probe_probe_property_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_probe_property_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -188,8 +187,8 @@ gst_property_probe_probe_property_name (GstPropertyProbe *probe,
*/
gboolean
gst_property_probe_needs_probe (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_needs_probe (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -215,8 +214,8 @@ gst_property_probe_needs_probe (GstPropertyProbe *probe,
*/
gboolean
gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -242,10 +241,10 @@ gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
*
* Returns: A list of valid values for the given property.
*/
GValueArray *
gst_property_probe_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -271,8 +270,8 @@ gst_property_probe_get_values (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_get_values_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_get_values_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;
@ -301,8 +300,8 @@ gst_property_probe_get_values_name (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
const GParamSpec *pspec)
gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
const GParamSpec * pspec)
{
GstPropertyProbeInterface *iface;
@ -328,8 +327,8 @@ gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
*/
GValueArray *
gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
const gchar *name)
gst_property_probe_probe_and_get_values_name (GstPropertyProbe * probe,
const gchar * name)
{
const GParamSpec *pspec;

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