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> 2004-03-14 Benjamin Otte <otte@gnome.org>
* gst/modplug/gstmodplug.cc: * gst/modplug/gstmodplug.cc:

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,7 +16,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -28,38 +28,36 @@ static GMainLoop *loop = NULL;
static void static void
got_eos (GstElement *pipeline) got_eos (GstElement * pipeline)
{ {
g_main_loop_quit (loop); g_main_loop_quit (loop);
} }
static gboolean static gboolean
idle_iterate (GstElement *pipeline) idle_iterate (GstElement * pipeline)
{ {
gst_bin_iterate (GST_BIN (pipeline)); gst_bin_iterate (GST_BIN (pipeline));
return (GST_STATE (GST_ELEMENT (pipeline)) == GST_STATE_PLAYING); return (GST_STATE (GST_ELEMENT (pipeline)) == GST_STATE_PLAYING);
} }
static gboolean static gboolean
switch_timer (GstElement *video_switch) switch_timer (GstElement * video_switch)
{ {
gint nb_sources, active_source; gint nb_sources, active_source;
g_object_get (G_OBJECT (video_switch), "nb_sources", &nb_sources, NULL); g_object_get (G_OBJECT (video_switch), "nb_sources", &nb_sources, NULL);
g_object_get (G_OBJECT (video_switch), "active_source", g_object_get (G_OBJECT (video_switch), "active_source", &active_source, NULL);
&active_source, NULL);
active_source++;
active_source ++;
if (active_source > nb_sources - 1) if (active_source > nb_sources - 1)
active_source = 0; active_source = 0;
g_object_set (G_OBJECT (video_switch), "active_source", g_object_set (G_OBJECT (video_switch), "active_source", active_source, NULL);
active_source, NULL);
g_message ("current number of sources : %d, active source %d", 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); return (GST_STATE (GST_ELEMENT (video_switch)) == GST_STATE_PLAYING);
} }
@ -72,7 +70,7 @@ main (int argc, char *argv[])
gst_init (&argc, &argv); gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
pipeline = gst_pipeline_new ("pipeline"); pipeline = gst_pipeline_new ("pipeline");
src1 = gst_element_factory_make ("videotestsrc", "src1"); src1 = gst_element_factory_make ("videotestsrc", "src1");
g_object_set (G_OBJECT (src1), "pattern", 0, NULL); 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); g_object_set (G_OBJECT (src2), "pattern", 1, NULL);
video_switch = gst_element_factory_make ("switch", "video_switch"); video_switch = gst_element_factory_make ("switch", "video_switch");
video_sink = gst_element_factory_make ("ximagesink", "video_sink"); video_sink = gst_element_factory_make ("ximagesink", "video_sink");
gst_bin_add_many (GST_BIN (pipeline), src1, src2, video_switch, 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 (src1, video_switch);
gst_element_link (src2, video_switch); gst_element_link (src2, video_switch);
gst_element_link (video_switch, video_sink); gst_element_link (video_switch, video_sink);
g_signal_connect (G_OBJECT (pipeline), "eos", g_signal_connect (G_OBJECT (pipeline), "eos", G_CALLBACK (got_eos), NULL);
G_CALLBACK (got_eos), NULL);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
g_idle_add ((GSourceFunc) idle_iterate, pipeline); g_idle_add ((GSourceFunc) idle_iterate, pipeline);
g_timeout_add (2000, (GSourceFunc) switch_timer, video_switch); g_timeout_add (2000, (GSourceFunc) switch_timer, video_switch);
g_main_loop_run (loop); g_main_loop_run (loop);
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
/* unref */ /* unref */
gst_object_unref (GST_OBJECT (pipeline)); 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_MIN_RATE 8000
#define GST_ALSA_MAX_RATE 192000 #define GST_ALSA_MAX_RATE 192000
#define GST_ALSA_MAX_TRACKS 64 /* we don't support more than 64 tracks */ #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_CHANNELS 32 /* tracks can have up to 32 channels */
/* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for /* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for
GST_ALSA_MAX_CHANNELS comes from alsa/mixer.h. */ 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) #define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10)
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_ALSA(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa)) #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_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_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(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_IS_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA))
#define GST_TYPE_ALSA (gst_alsa_get_type()) #define GST_TYPE_ALSA (gst_alsa_get_type())
enum
enum { {
GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST, GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST,
GST_ALSA_RUNNING, GST_ALSA_RUNNING,
GST_ALSA_CAPS_NEGO, GST_ALSA_CAPS_NEGO,
GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3, GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3,
}; };
typedef enum { typedef enum
{
GST_ALSA_CAPS_PAUSE = 0, GST_ALSA_CAPS_PAUSE = 0,
GST_ALSA_CAPS_RESUME, GST_ALSA_CAPS_RESUME,
GST_ALSA_CAPS_SYNC_START GST_ALSA_CAPS_SYNC_START
/* add more */ /* add more */
} GstAlsaPcmCaps; } GstAlsaPcmCaps;
#define GST_ALSA_CAPS_IS_SET(obj, flag) (GST_ALSA (obj)->pcm_caps & (1<<(flag))) #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 _GstAlsa GstAlsa;
typedef struct _GstAlsaClass GstAlsaClass; 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 { typedef struct
snd_pcm_format_t format; {
guint rate; snd_pcm_format_t format;
gint channels; guint rate;
gint channels;
} GstAlsaFormat; } GstAlsaFormat;
struct _GstAlsa { struct _GstAlsa
GstElement parent; {
GstElement parent;
/* array of GstAlsaPads */ /* array of GstAlsaPads */
GstPad * pad[GST_ALSA_MAX_TRACKS]; GstPad *pad[GST_ALSA_MAX_TRACKS];
gchar * device; gchar *device;
snd_pcm_t * handle; snd_pcm_t *handle;
snd_pcm_info_t * info; snd_pcm_info_t *info;
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */ guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
snd_output_t * out; snd_output_t *out;
GstAlsaFormat * format; /* NULL if undefined */ GstAlsaFormat *format; /* NULL if undefined */
gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */ gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */
GstAlsaTransmitFunction transmit; GstAlsaTransmitFunction transmit;
/* latency / performance parameters */ /* latency / performance parameters */
snd_pcm_uframes_t period_size; snd_pcm_uframes_t period_size;
unsigned int period_count; unsigned int period_count;
gboolean autorecover; gboolean autorecover;
/* clocking */ /* clocking */
GstAlsaClock * clock; /* our provided clock */ GstAlsaClock *clock; /* our provided clock */
snd_pcm_uframes_t transmitted; /* samples transmitted since last sync snd_pcm_uframes_t transmitted; /* samples transmitted since last sync
This thing actually is our master clock. This thing actually is our master clock.
We will event insert silent samples or We will event insert silent samples or
drop some to sync to incoming timestamps. drop some to sync to incoming timestamps.
*/ */
GstClockTime max_discont; /* max difference between current GstClockTime max_discont; /* max difference between current
playback timestamp and buffers timestamps playback timestamp and buffers timestamps
*/ */
}; };
struct _GstAlsaClass { struct _GstAlsaClass
GstElementClass parent_class; {
GstElementClass parent_class;
snd_pcm_stream_t stream; snd_pcm_stream_t stream;
/* different transmit functions */ /* different transmit functions */
GstAlsaTransmitFunction transmit_mmap; GstAlsaTransmitFunction transmit_mmap;
GstAlsaTransmitFunction transmit_rw; GstAlsaTransmitFunction transmit_rw;
/* autodetected devices available */ /* autodetected devices available */
GList *devices; GList *devices;
@ -175,36 +179,29 @@ struct _GstAlsaClass {
GType gst_alsa_get_type (void); GType gst_alsa_get_type (void);
void gst_alsa_set_eos (GstAlsa * this); void gst_alsa_set_eos (GstAlsa * this);
GstPadLinkReturn gst_alsa_link (GstPad * pad, GstPadLinkReturn gst_alsa_link (GstPad * pad, const GstCaps * caps);
const GstCaps * caps); GstCaps *gst_alsa_get_caps (GstPad * pad);
GstCaps * gst_alsa_get_caps (GstPad * pad); GstCaps *gst_alsa_fixate (GstPad * pad, const GstCaps * caps);
GstCaps * gst_alsa_fixate (GstPad * pad, GstCaps *gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels);
const GstCaps * caps);
GstCaps * gst_alsa_caps (snd_pcm_format_t format,
gint rate,
gint channels);
/* audio processing functions */ /* audio processing functions */
inline snd_pcm_sframes_t gst_alsa_update_avail (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_pcm_wait (GstAlsa * this);
inline gboolean gst_alsa_start (GstAlsa * this); inline gboolean gst_alsa_start (GstAlsa * this);
gboolean gst_alsa_xrun_recovery (GstAlsa * this); gboolean gst_alsa_xrun_recovery (GstAlsa * this);
/* format conversions */ /* format conversions */
inline snd_pcm_uframes_t gst_alsa_timestamp_to_samples (GstAlsa * this, inline snd_pcm_uframes_t gst_alsa_timestamp_to_samples (GstAlsa * this,
GstClockTime time); GstClockTime time);
inline GstClockTime gst_alsa_samples_to_timestamp (GstAlsa * this, inline GstClockTime gst_alsa_samples_to_timestamp (GstAlsa * this,
snd_pcm_uframes_t samples); snd_pcm_uframes_t samples);
inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this, inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this,
guint bytes); guint bytes);
inline guint gst_alsa_samples_to_bytes (GstAlsa * this, inline guint gst_alsa_samples_to_bytes (GstAlsa * this,
snd_pcm_uframes_t samples); snd_pcm_uframes_t samples);
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this, inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this, guint bytes);
guint bytes); inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this, GstClockTime time);
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this,
GstClockTime time);
G_END_DECLS G_END_DECLS
#endif /* __GST_ALSA_H__ */ #endif /* __GST_ALSA_H__ */

View file

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

View file

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

View file

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

View file

@ -24,28 +24,27 @@
#include <gst/mixer/mixer.h> #include <gst/mixer/mixer.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer)) #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_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(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_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()) #define GST_TYPE_ALSA_MIXER (gst_alsa_mixer_get_type())
typedef struct _GstAlsaMixer GstAlsaMixer; typedef struct _GstAlsaMixer GstAlsaMixer;
typedef struct _GstAlsaMixerClass GstAlsaMixerClass; typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
struct _GstAlsaMixer { struct _GstAlsaMixer
GstAlsa parent; {
GList * tracklist; /* list of available tracks */ GstAlsa parent;
snd_mixer_t * mixer_handle; GList *tracklist; /* list of available tracks */
snd_mixer_t *mixer_handle;
}; };
struct _GstAlsaMixerClass { struct _GstAlsaMixerClass
GstAlsaClass parent; {
GstAlsaClass parent;
}; };
GType gst_alsa_mixer_get_type (void); GType gst_alsa_mixer_get_type (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_ALSA_MIXER_H__ */ #endif /* __GST_ALSA_MIXER_H__ */

View file

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

View file

@ -23,35 +23,32 @@
#include <gst/mixer/mixertrack.h> #include <gst/mixer/mixertrack.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_ALSA_MIXER_TRACK_TYPE (gst_alsa_mixer_track_get_type ()) #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(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_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(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_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()) #define GST_TYPE_ALSA_MIXER_TRACK (gst_alsa_mixer_track_get_type())
typedef struct _GstAlsaMixerTrack GstAlsaMixerTrack; typedef struct _GstAlsaMixerTrack GstAlsaMixerTrack;
typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass; typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
struct _GstAlsaMixerTrack { struct _GstAlsaMixerTrack
GstMixerTrack parent; {
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */ GstMixerTrack parent;
gint track_num; snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
gint min_rec_volume, max_rec_volume; gint track_num;
gint volumes[GST_ALSA_MAX_CHANNELS]; gint min_rec_volume, max_rec_volume;
gint volumes[GST_ALSA_MAX_CHANNELS];
}; };
struct _GstAlsaMixerTrackClass { struct _GstAlsaMixerTrackClass
{
GstMixerTrackClass parent; GstMixerTrackClass parent;
}; };
GType gst_alsa_mixer_track_get_type (void); GType gst_alsa_mixer_track_get_type (void);
GstMixerTrack * gst_alsa_mixer_track_new (snd_mixer_elem_t * element, GstMixerTrack *gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
gint track_num, gint track_num, gint channels, gint flags);
gint channels,
gint flags);
G_END_DECLS G_END_DECLS
#endif /* __GST_ALSA_MIXER_TRACK_H__ */ #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"); 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; 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; 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 FALSE;
return TRUE; return TRUE;
} }
GST_PLUGIN_DEFINE ( GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MAJOR, GST_VERSION_MINOR,
GST_VERSION_MINOR, "alsa",
"alsa", "ALSA plugin library",
"ALSA plugin library", plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)

View file

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

View file

@ -25,35 +25,34 @@
#include "gstalsa.h" #include "gstalsa.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SINK, GstAlsaSink)) #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_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(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_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()) #define GST_TYPE_ALSA_SINK (gst_alsa_sink_get_type())
typedef struct _GstAlsaSink GstAlsaSink; typedef struct _GstAlsaSink GstAlsaSink;
typedef struct _GstAlsaSinkClass GstAlsaSinkClass; typedef struct _GstAlsaSinkClass GstAlsaSinkClass;
struct _GstAlsaSink { struct _GstAlsaSink
GstAlsa parent; {
GstAlsa parent;
/* array of the data on the channels */ /* array of the data on the channels */
guint8 *data[GST_ALSA_MAX_TRACKS]; /* pointer into buffer */ guint8 *data[GST_ALSA_MAX_TRACKS]; /* pointer into buffer */
guint size[GST_ALSA_MAX_TRACKS]; /* sink: bytes left in buffer */ guint size[GST_ALSA_MAX_TRACKS]; /* sink: bytes left in buffer */
GstBuffer *buf[GST_ALSA_MAX_TRACKS]; /* current 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), 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 */ 1 = data should be freed, use buffer after that */
}; };
struct _GstAlsaSinkClass { struct _GstAlsaSinkClass
{
GstAlsaClass parent_class; GstAlsaClass parent_class;
}; };
GType gst_alsa_sink_get_type (void); 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 G_END_DECLS
#endif /* __GST_ALSA_SINK_H__ */ #endif /* __GST_ALSA_SINK_H__ */

View file

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

View file

@ -25,29 +25,28 @@
#include "gstalsa.h" #include "gstalsa.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_ALSA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SRC, GstAlsaSrc)) #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_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(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_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()) #define GST_TYPE_ALSA_SRC (gst_alsa_src_get_type())
typedef struct _GstAlsaSrc GstAlsaSrc; typedef struct _GstAlsaSrc GstAlsaSrc;
typedef struct _GstAlsaSrcClass GstAlsaSrcClass; typedef struct _GstAlsaSrcClass GstAlsaSrcClass;
struct _GstAlsaSrc { struct _GstAlsaSrc
GstAlsa parent; {
GstBuffer *buf[GST_ALSA_MAX_TRACKS]; GstAlsa parent;
GstBuffer *buf[GST_ALSA_MAX_TRACKS];
}; };
struct _GstAlsaSrcClass { struct _GstAlsaSrcClass
{
GstAlsaClass parent_class; GstAlsaClass parent_class;
}; };
GType gst_alsa_src_get_type (void); 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 G_END_DECLS
#endif /* __GST_ALSA_SRC_H__ */ #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> #include <gst/gst.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
#endif /* __cplusplus */ {
#endif /* __cplusplus */
#define size16 gint16 #define size16 gint16
#define size32 gint32 #define size32 gint32
#ifdef CDPARANOIA_HEADERS_IN_DIR #ifdef CDPARANOIA_HEADERS_IN_DIR
#include <cdda/cdda_interface.h> #include <cdda/cdda_interface.h>
#include <cdda/cdda_paranoia.h> #include <cdda/cdda_paranoia.h>
#else #else
#include <cdda_interface.h> #include <cdda_interface.h>
#include <cdda_paranoia.h> #include <cdda_paranoia.h>
#endif #endif
/*#define CDPARANOIA_BASEOFFSET 0xf1d2 */ /*#define CDPARANOIA_BASEOFFSET 0xf1d2 */
@ -57,69 +58,72 @@ extern "C" {
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDPARANOIA)) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDPARANOIA))
/* NOTE: per-element flags start with 16 for now */ /* NOTE: per-element flags start with 16 for now */
typedef enum { typedef enum
CDPARANOIA_OPEN = GST_ELEMENT_FLAG_LAST, {
CDPARANOIA_OPEN = GST_ELEMENT_FLAG_LAST,
CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
} CDParanoiaFlags; } CDParanoiaFlags;
typedef struct _CDParanoia CDParanoia; typedef struct _CDParanoia CDParanoia;
typedef struct _CDParanoiaClass CDParanoiaClass; typedef struct _CDParanoiaClass CDParanoiaClass;
struct _CDParanoia { struct _CDParanoia
GstElement element; {
/* pads */ GstElement element;
GstPad *srcpad; /* pads */
GstPad *srcpad;
/* Index */ /* Index */
GstIndex *index; GstIndex *index;
int index_id; 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;
cdrom_drive *d; gchar *device;
cdrom_paranoia *p; 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; cdrom_drive *d;
gint segment_start_sector; cdrom_paranoia *p;
gint segment_end_sector;
gint first_sector; gint cur_sector;
gint last_sector; gint segment_start_sector;
gint segment_end_sector;
/* hacks by Gordon Irving */ gint first_sector;
gchar discid[20]; gint last_sector;
gint64 offsets[MAXTRK];
gint64 total_seconds;
gint seq; /* hacks by Gordon Irving */
gboolean discont_pending; gchar discid[20];
}; gint64 offsets[MAXTRK];
gint64 total_seconds;
struct _CDParanoiaClass { gint seq;
GstElementClass parent_class; gboolean discont_pending;
};
/* signal callbacks */ struct _CDParanoiaClass
void (*smilie_change) (CDParanoia *cdparanoia, gchar *smilie); {
void (*transport_error) (CDParanoia *cdparanoia, gint offset); GstElementClass parent_class;
void (*uncorrected_error) (CDParanoia *cdparanoia, gint offset);
};
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 #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __CDPARANOIA_H__ */ #endif /* __CDPARANOIA_H__ */

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

@ -27,7 +27,7 @@
GST_DEBUG_CATEGORY (vorbisdec_debug); GST_DEBUG_CATEGORY (vorbisdec_debug);
static gboolean static gboolean
plugin_init (GstPlugin *plugin) plugin_init (GstPlugin * plugin)
{ {
if (!gst_library_load ("gstbytestream")) if (!gst_library_load ("gstbytestream"))
return FALSE; return FALSE;
@ -35,23 +35,21 @@ plugin_init (GstPlugin *plugin)
if (!gst_library_load ("gsttags")) if (!gst_library_load ("gsttags"))
return FALSE; 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; 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; 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; return TRUE;
} }
GST_PLUGIN_DEFINE ( GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MAJOR, GST_VERSION_MINOR,
GST_VERSION_MINOR, "vorbis",
"vorbis", "Vorbis plugin library",
"Vorbis plugin library", plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN)

View file

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

View file

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

View file

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

View file

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

View file

@ -26,7 +26,6 @@
#define __GST_AUDIO_AUDIO_H__ #define __GST_AUDIO_AUDIO_H__
G_BEGIN_DECLS G_BEGIN_DECLS
/* For people that are looking at this source: the purpose of these defines is /* 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 * 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 * 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 * Andy Wingo, 18 August 2001
* Thomas, 6 September 2002 */ * Thomas, 6 September 2002 */
#define GST_AUDIO_DEF_RATE 44100 #define GST_AUDIO_DEF_RATE 44100
#define GST_AUDIO_INT_PAD_TEMPLATE_CAPS \ #define GST_AUDIO_INT_PAD_TEMPLATE_CAPS \
"audio/x-raw-int, " \ "audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \ "rate = (int) [ 1, MAX ], " \
@ -60,9 +57,7 @@ G_BEGIN_DECLS
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) { 8, 16, 32 }, " \ "width = (int) { 8, 16, 32 }, " \
"depth = (int) [ 1, 32 ], " \ "depth = (int) [ 1, 32 ], " \
"signed = (boolean) { true, false }" "signed = (boolean) { true, false }"
/* "standard" int audio is native order, 16 bit stereo. */ /* "standard" int audio is native order, 16 bit stereo. */
#define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS \ #define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS \
"audio/x-raw-int, " \ "audio/x-raw-int, " \
@ -71,8 +66,7 @@ G_BEGIN_DECLS
"endianness = (int) BYTE_ORDER, " \ "endianness = (int) BYTE_ORDER, " \
"width = (int) 16, " \ "width = (int) 16, " \
"depth = (int) 16, " \ "depth = (int) 16, " \
"signed = (boolean) true" "signed = (boolean) true"
#define GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS \ #define GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS \
"audio/x-raw-float, " \ "audio/x-raw-float, " \
"rate = (int) [ 1, MAX ], " \ "rate = (int) [ 1, MAX ], " \
@ -80,7 +74,6 @@ G_BEGIN_DECLS
"endianness = (int) { LITTLE_ENDIAN , BIG_ENDIAN }, " \ "endianness = (int) { LITTLE_ENDIAN , BIG_ENDIAN }, " \
"width = (int) { 32, 64 }, " \ "width = (int) { 32, 64 }, " \
"buffer-frames = (int) [ 1, MAX]" "buffer-frames = (int) [ 1, MAX]"
/* "standard" float audio is native order, 32 bit mono. */ /* "standard" float audio is native order, 32 bit mono. */
#define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS \ #define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS \
"audio/x-raw-float, " \ "audio/x-raw-float, " \
@ -88,43 +81,42 @@ G_BEGIN_DECLS
"channels = (int) 1, " \ "channels = (int) 1, " \
"endianness = (int) BYTE_ORDER, " \ "endianness = (int) BYTE_ORDER, " \
"buffer-frames = (int) [ 1, MAX]" "buffer-frames = (int) [ 1, MAX]"
/* /*
* this library defines and implements some helper functions for audio * this library defines and implements some helper functions for audio
* handling * handling
*/ */
/* get byte size of audio frame (based on caps of pad */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* functions useful for _getcaps functions */
typedef enum { typedef enum
GST_AUDIO_FIELD_RATE = (1 << 0), {
GST_AUDIO_FIELD_CHANNELS = (1 << 1), GST_AUDIO_FIELD_RATE = (1 << 0),
GST_AUDIO_FIELD_ENDIANNESS = (1 << 2), GST_AUDIO_FIELD_CHANNELS = (1 << 1),
GST_AUDIO_FIELD_WIDTH = (1 << 3), GST_AUDIO_FIELD_ENDIANNESS = (1 << 2),
GST_AUDIO_FIELD_DEPTH = (1 << 4), GST_AUDIO_FIELD_WIDTH = (1 << 3),
GST_AUDIO_FIELD_SIGNED = (1 << 5), GST_AUDIO_FIELD_DEPTH = (1 << 4),
GST_AUDIO_FIELD_SIGNED = (1 << 5),
GST_AUDIO_FIELD_BUFFER_FRAMES = (1 << 6) GST_AUDIO_FIELD_BUFFER_FRAMES = (1 << 6)
} GstAudioFieldFlag; } GstAudioFieldFlag;
void gst_audio_structure_set_int (GstStructure *structure, GstAudioFieldFlag flag); void gst_audio_structure_set_int (GstStructure * structure,
GstAudioFieldFlag flag);
G_END_DECLS G_END_DECLS
#endif /* __GST_AUDIO_AUDIO_H__ */ #endif /* __GST_AUDIO_AUDIO_H__ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -22,8 +22,8 @@
#ifndef __GST_I18N_PLUGIN_H__ #ifndef __GST_I18N_PLUGIN_H__
#define __GST_I18N_PLUGIN_H__ #define __GST_I18N_PLUGIN_H__
#include <locale.h> /* some people need it and some people don't */ #include <locale.h> /* some people need it and some people don't */
#include "gettext.h" /* included with gettext distribution and copied */ #include "gettext.h" /* included with gettext distribution and copied */
#ifndef GETTEXT_PACKAGE #ifndef GETTEXT_PACKAGE
#error You must define GETTEXT_PACKAGE before including this header. #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 */ 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_init_fast_int_idct (void);
extern void gst_idct_fast_int_idct (short *block); 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); extern void gst_idct_sse_idct (short *block);
#endif /* HAVE_LIBMMX */ #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); extern void gst_idct_float_idct (short *block);

View file

@ -45,17 +45,17 @@
/* this code assumes >> to be a two's-complement arithmetic */ /* this code assumes >> to be a two's-complement arithmetic */
/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */ #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */ #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */ #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */ #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */ #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */ #define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
#include "dct.h" #include "dct.h"
/* private data */ /* private data */
static short iclip[1024]; /* clipping table */ static short iclip[1024]; /* clipping table */
static short *iclp; static short *iclp;
/* private prototypes */ /* private prototypes */
@ -72,57 +72,58 @@ static void idctcol (short *blk);
* c[1..7] = 128*sqrt(2) * c[1..7] = 128*sqrt(2)
*/ */
static void idctrow(blk) static void
short *blk; idctrow (blk)
short *blk;
{ {
int x0, x1, x2, x3, x4, x5, x6, x7, x8; int x0, x1, x2, x3, x4, x5, x6, x7, x8;
/* shortcut */ /* shortcut */
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) | if (!((x1 = blk[4] << 11) | (x2 = blk[6]) | (x3 = blk[2]) |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) (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]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; blk[0] << 3;
return; 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 */ /* first stage */
x8 = W7*(x4+x5); x8 = W7 * (x4 + x5);
x4 = x8 + (W1-W7)*x4; x4 = x8 + (W1 - W7) * x4;
x5 = x8 - (W1+W7)*x5; x5 = x8 - (W1 + W7) * x5;
x8 = W3*(x6+x7); x8 = W3 * (x6 + x7);
x6 = x8 - (W3-W5)*x6; x6 = x8 - (W3 - W5) * x6;
x7 = x8 - (W3+W5)*x7; x7 = x8 - (W3 + W5) * x7;
/* second stage */ /* second stage */
x8 = x0 + x1; x8 = x0 + x1;
x0 -= x1; x0 -= x1;
x1 = W6*(x3+x2); x1 = W6 * (x3 + x2);
x2 = x1 - (W2+W6)*x2; x2 = x1 - (W2 + W6) * x2;
x3 = x1 + (W2-W6)*x3; x3 = x1 + (W2 - W6) * x3;
x1 = x4 + x6; x1 = x4 + x6;
x4 -= x6; x4 -= x6;
x6 = x5 + x7; x6 = x5 + x7;
x5 -= x7; x5 -= x7;
/* third stage */ /* third stage */
x7 = x8 + x3; x7 = x8 + x3;
x8 -= x3; x8 -= x3;
x3 = x0 + x2; x3 = x0 + x2;
x0 -= x2; x0 -= x2;
x2 = (181*(x4+x5)+128)>>8; x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181*(x4-x5)+128)>>8; x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */ /* fourth stage */
blk[0] = (x7+x1)>>8; blk[0] = (x7 + x1) >> 8;
blk[1] = (x3+x2)>>8; blk[1] = (x3 + x2) >> 8;
blk[2] = (x0+x4)>>8; blk[2] = (x0 + x4) >> 8;
blk[3] = (x8+x6)>>8; blk[3] = (x8 + x6) >> 8;
blk[4] = (x8-x6)>>8; blk[4] = (x8 - x6) >> 8;
blk[5] = (x0-x4)>>8; blk[5] = (x0 - x4) >> 8;
blk[6] = (x3-x2)>>8; blk[6] = (x3 - x2) >> 8;
blk[7] = (x7-x1)>>8; blk[7] = (x7 - x1) >> 8;
} }
/* column (vertical) IDCT /* column (vertical) IDCT
@ -134,78 +135,81 @@ short *blk;
* where: c[0] = 1/1024 * where: c[0] = 1/1024
* c[1..7] = (1/1024)*sqrt(2) * c[1..7] = (1/1024)*sqrt(2)
*/ */
static void idctcol(blk) static void
short *blk; idctcol (blk)
short *blk;
{ {
int x0, x1, x2, x3, x4, x5, x6, x7, x8; int x0, x1, x2, x3, x4, x5, x6, x7, x8;
/* shortcut */ /* shortcut */
if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) | 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]))) (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]= blk[8 * 0] = blk[8 * 1] = blk[8 * 2] = blk[8 * 3] = blk[8 * 4] =
iclp[(blk[8*0]+32)>>6]; blk[8 * 5] = blk[8 * 6] = blk[8 * 7] = iclp[(blk[8 * 0] + 32) >> 6];
return; return;
} }
x0 = (blk[8*0]<<8) + 8192; x0 = (blk[8 * 0] << 8) + 8192;
/* first stage */ /* first stage */
x8 = W7*(x4+x5) + 4; x8 = W7 * (x4 + x5) + 4;
x4 = (x8+(W1-W7)*x4)>>3; x4 = (x8 + (W1 - W7) * x4) >> 3;
x5 = (x8-(W1+W7)*x5)>>3; x5 = (x8 - (W1 + W7) * x5) >> 3;
x8 = W3*(x6+x7) + 4; x8 = W3 * (x6 + x7) + 4;
x6 = (x8-(W3-W5)*x6)>>3; x6 = (x8 - (W3 - W5) * x6) >> 3;
x7 = (x8-(W3+W5)*x7)>>3; x7 = (x8 - (W3 + W5) * x7) >> 3;
/* second stage */ /* second stage */
x8 = x0 + x1; x8 = x0 + x1;
x0 -= x1; x0 -= x1;
x1 = W6*(x3+x2) + 4; x1 = W6 * (x3 + x2) + 4;
x2 = (x1-(W2+W6)*x2)>>3; x2 = (x1 - (W2 + W6) * x2) >> 3;
x3 = (x1+(W2-W6)*x3)>>3; x3 = (x1 + (W2 - W6) * x3) >> 3;
x1 = x4 + x6; x1 = x4 + x6;
x4 -= x6; x4 -= x6;
x6 = x5 + x7; x6 = x5 + x7;
x5 -= x7; x5 -= x7;
/* third stage */ /* third stage */
x7 = x8 + x3; x7 = x8 + x3;
x8 -= x3; x8 -= x3;
x3 = x0 + x2; x3 = x0 + x2;
x0 -= x2; x0 -= x2;
x2 = (181*(x4+x5)+128)>>8; x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181*(x4-x5)+128)>>8; x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */ /* fourth stage */
blk[8*0] = iclp[(x7+x1)>>14]; blk[8 * 0] = iclp[(x7 + x1) >> 14];
blk[8*1] = iclp[(x3+x2)>>14]; blk[8 * 1] = iclp[(x3 + x2) >> 14];
blk[8*2] = iclp[(x0+x4)>>14]; blk[8 * 2] = iclp[(x0 + x4) >> 14];
blk[8*3] = iclp[(x8+x6)>>14]; blk[8 * 3] = iclp[(x8 + x6) >> 14];
blk[8*4] = iclp[(x8-x6)>>14]; blk[8 * 4] = iclp[(x8 - x6) >> 14];
blk[8*5] = iclp[(x0-x4)>>14]; blk[8 * 5] = iclp[(x0 - x4) >> 14];
blk[8*6] = iclp[(x3-x2)>>14]; blk[8 * 6] = iclp[(x3 - x2) >> 14];
blk[8*7] = iclp[(x7-x1)>>14]; blk[8 * 7] = iclp[(x7 - x1) >> 14];
} }
/* two dimensional inverse discrete cosine transform */ /* two dimensional inverse discrete cosine transform */
void gst_idct_fast_int_idct(block) void
short *block; gst_idct_fast_int_idct (block)
short *block;
{ {
int i; int i;
for (i=0; i<8; i++) for (i = 0; i < 8; i++)
idctrow(block+8*i); idctrow (block + 8 * i);
for (i=0; i<8; i++) for (i = 0; i < 8; i++)
idctcol(block+i); idctcol (block + i);
} }
void gst_idct_init_fast_int_idct() void
gst_idct_init_fast_int_idct ()
{ {
int i; int i;
iclp = iclip+512; iclp = iclip + 512;
for (i= -512; i<512; i++) for (i = -512; i < 512; i++)
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : 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 */ /* initialize DCT coefficient matrix */
void gst_idct_init_float_idct() void
gst_idct_init_float_idct ()
{ {
int freq, time; int freq, time;
double scale; double scale;
for (freq=0; freq < 8; freq++) for (freq = 0; freq < 8; freq++) {
{ scale = (freq == 0) ? sqrt (0.125) : 0.5;
scale = (freq == 0) ? sqrt(0.125) : 0.5; for (time = 0; time < 8; time++)
for (time=0; time<8; time++) gst_idct_float_c[freq][time] =
gst_idct_float_c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5)); scale * cos ((PI / 8.0) * freq * (time + 0.5));
} }
} }
/* perform IDCT matrix multiply for 8x8 coefficient block */ /* perform IDCT matrix multiply for 8x8 coefficient block */
void gst_idct_float_idct(block) void
short *block; gst_idct_float_idct (block)
short *block;
{ {
int i, j, k, v; int i, j, k, v;
double partial_product; double partial_product;
double tmp[64]; double tmp[64];
for (i=0; i<8; i++) for (i = 0; i < 8; i++)
for (j=0; j<8; j++) for (j = 0; j < 8; j++) {
{
partial_product = 0.0; partial_product = 0.0;
for (k=0; k<8; k++) for (k = 0; k < 8; k++)
partial_product+= gst_idct_float_c[k][j]*block[8*i+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 /* Transpose operation is integrated into address mapping by switching
loop order of i and j */ loop order of i and j */
for (j=0; j<8; j++) for (j = 0; j < 8; j++)
for (i=0; i<8; i++) for (i = 0; i < 8; i++) {
{
partial_product = 0.0; partial_product = 0.0;
for (k=0; k<8; k++) for (k = 0; k < 8; k++)
partial_product+= gst_idct_float_c[k][i]*tmp[8*k+j]; partial_product += gst_idct_float_c[k][i] * tmp[8 * k + j];
v = (int) floor(partial_product+0.5); v = (int) floor (partial_product + 0.5);
block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v); block[8 * i + j] = (v < -256) ? -256 : ((v > 255) ? 255 : v);
} }
} }

View file

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

View file

@ -23,22 +23,24 @@
#include <glib.h> #include <glib.h>
typedef enum { typedef enum
GST_IDCT_DEFAULT, {
GST_IDCT_INT, GST_IDCT_DEFAULT,
GST_IDCT_FAST_INT, GST_IDCT_INT,
GST_IDCT_FLOAT, GST_IDCT_FAST_INT,
GST_IDCT_MMX, GST_IDCT_FLOAT,
GST_IDCT_MMX,
GST_IDCT_MMX32, GST_IDCT_MMX32,
GST_IDCT_SSE, GST_IDCT_SSE,
} GstIDCTMethod; } GstIDCTMethod;
typedef struct _GstIDCT GstIDCT; typedef struct _GstIDCT GstIDCT;
typedef void (*GstIDCTFunction) (gshort *block); typedef void (*GstIDCTFunction) (gshort * block);
#define GST_IDCT_TRANSPOSE(idct) ((idct)->need_transpose) #define GST_IDCT_TRANSPOSE(idct) ((idct)->need_transpose)
struct _GstIDCT { struct _GstIDCT
{
/* private */ /* private */
GstIDCTFunction convert; GstIDCTFunction convert;
GstIDCTFunction convert_sparse; 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(idct, blocks) (idct)->convert((blocks))
#define gst_idct_convert_sparse(idct, blocks) (idct)->convert_sparse((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__ */ #endif /* __GST_IDCT_H__ */

View file

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

View file

@ -51,10 +51,8 @@
*/ */
#if DCTSIZE != 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 #endif
/* /*
* A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT * 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 * 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 * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
* shows that the values given below are the most effective. * shows that the values given below are the most effective.
*/ */
#ifdef EIGHT_BIT_SAMPLES #ifdef EIGHT_BIT_SAMPLES
#define CONST_BITS 13 #define CONST_BITS 13
#define PASS1_BITS 2 #define PASS1_BITS 2
@ -98,22 +95,16 @@
#define CONST_BITS 13 #define CONST_BITS 13
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ #define PASS1_BITS 1 /* lose a little precision to avoid overflow */
#endif #endif
#define ONE ((INT32) 1) #define ONE ((INT32) 1)
#define CONST_SCALE (ONE << CONST_BITS) #define CONST_SCALE (ONE << CONST_BITS)
/* Convert a positive real constant to an integer scaled by CONST_SCALE. */ /* Convert a positive real constant to an integer scaled by CONST_SCALE. */
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) #define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
* causing a lot of useless floating-point operations at run time. * causing a lot of useless floating-point operations at run time.
* To get around this we use the following pre-calculated constants. * To get around this we use the following pre-calculated constants.
* If you change CONST_BITS you may want to add appropriate values. * 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...) * (With a reasonable C compiler, you can just rely on the FIX() macro...)
*/ */
#if CONST_BITS == 13 #if CONST_BITS == 13
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ #define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ #define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
@ -141,15 +132,11 @@
#define FIX_2_562915447 FIX(2.562915447) #define FIX_2_562915447 FIX(2.562915447)
#define FIX_3_072711026 FIX(3.072711026) #define FIX_3_072711026 FIX(3.072711026)
#endif #endif
/* Descale and correctly round an INT32 value that's scaled by N bits. /* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X. * the fudge factor is correct for either sign of X.
*/ */
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) #define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* For 8-bit samples with the recommended scaling, all the variable * For 8-bit samples with the recommended scaling, all the variable
* and constant values involved are no more than 16 bits wide, so a * and constant values involved are no more than 16 bits wide, so a
@ -160,7 +147,6 @@
* combination of casts. * combination of casts.
* NB: for 12-bit samples, a full 32-bit multiplication will be needed. * NB: for 12-bit samples, a full 32-bit multiplication will be needed.
*/ */
#ifdef EIGHT_BIT_SAMPLES #ifdef EIGHT_BIT_SAMPLES
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ #ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT16) (const))) #define MULTIPLY(var,const) (((INT16) (var)) * ((INT16) (const)))
@ -169,17 +155,13 @@
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT32) (const))) #define MULTIPLY(var,const) (((INT16) (var)) * ((INT32) (const)))
#endif #endif
#endif #endif
#ifndef MULTIPLY /* default definition */ #ifndef MULTIPLY /* default definition */
#define MULTIPLY(var,const) ((var) * (const)) #define MULTIPLY(var,const) ((var) * (const))
#endif #endif
/* /*
* Perform the inverse DCT on one block of coefficients. * Perform the inverse DCT on one block of coefficients.
*/ */
void
void
gst_idct_int_idct (DCTBLOCK data) gst_idct_int_idct (DCTBLOCK data)
{ {
INT32 tmp0, tmp1, tmp2, tmp3; INT32 tmp0, tmp1, tmp2, tmp3;
@ -187,14 +169,13 @@ gst_idct_int_idct (DCTBLOCK data)
INT32 z1, z2, z3, z4, z5; INT32 z1, z2, z3, z4, z5;
register DCTELEM *dataptr; register DCTELEM *dataptr;
int rowctr; int rowctr;
SHIFT_TEMPS SHIFT_TEMPS
/* Pass 1: process rows. */
/* Pass 1: process rows. */ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */ /* furthermore, we scale the results by 2**PASS1_BITS. */
/* furthermore, we scale the results by 2**PASS1_BITS. */ dataptr = data;
for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
dataptr = data;
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
/* Due to quantization, we will usually find that many of the input /* Due to quantization, we will usually find that many of the input
* coefficients are zero, especially the AC terms. We can exploit this * coefficients are zero, especially the AC terms. We can exploit this
* by short-circuiting the IDCT calculation for any row in which all * 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] | 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 */ /* AC terms all zero */
DCTELEM dcval = (DCTELEM) (dataptr[0] << PASS1_BITS); DCTELEM dcval = (DCTELEM) (dataptr[0] << PASS1_BITS);
dataptr[0] = dcval; dataptr[0] = dcval;
dataptr[1] = dcval; dataptr[1] = dcval;
dataptr[2] = dcval; dataptr[2] = dcval;
@ -217,7 +198,7 @@ gst_idct_int_idct (DCTBLOCK data)
dataptr[5] = dcval; dataptr[5] = dcval;
dataptr[6] = dcval; dataptr[6] = dcval;
dataptr[7] = dcval; dataptr[7] = dcval;
dataptr += DCTSIZE; /* advance pointer to next row */ dataptr += DCTSIZE; /* advance pointer to next row */
continue; continue;
} }
@ -228,9 +209,9 @@ gst_idct_int_idct (DCTBLOCK data)
z2 = (INT32) dataptr[2]; z2 = (INT32) dataptr[2];
z3 = (INT32) dataptr[6]; z3 = (INT32) dataptr[6];
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
tmp0 = ((INT32) dataptr[0] + (INT32) dataptr[4]) << CONST_BITS; tmp0 = ((INT32) dataptr[0] + (INT32) dataptr[4]) << CONST_BITS;
tmp1 = ((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; tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2; tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its /* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. * 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; z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2; z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3; z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* 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) */ tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* 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) */ z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5; z3 += z5;
z4 += z5; z4 += z5;
tmp0 += z1 + z3; tmp0 += z1 + z3;
tmp1 += z2 + z4; tmp1 += z2 + z4;
tmp2 += z2 + z3; tmp2 += z2 + z3;
@ -274,14 +255,14 @@ gst_idct_int_idct (DCTBLOCK data)
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, 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[7] = (DCTELEM) DESCALE (tmp10 - tmp3, CONST_BITS - PASS1_BITS);
dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, 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[6] = (DCTELEM) DESCALE (tmp11 - tmp2, CONST_BITS - PASS1_BITS);
dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, 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[5] = (DCTELEM) DESCALE (tmp12 - tmp1, CONST_BITS - PASS1_BITS);
dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, 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[4] = (DCTELEM) DESCALE (tmp13 - tmp0, CONST_BITS - PASS1_BITS);
dataptr += DCTSIZE; /* advance pointer to next row */ dataptr += DCTSIZE; /* advance pointer to next row */
} }
@ -291,7 +272,7 @@ gst_idct_int_idct (DCTBLOCK data)
/* and also undo the PASS1_BITS scaling. */ /* and also undo the PASS1_BITS scaling. */
dataptr = data; 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. /* 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 * However, the row calculation has created many nonzero AC terms, so the
* simplification applies less often (typically 5% to 10% of the time). * 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 #ifndef NO_ZERO_COLUMN_TEST
if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] | if ((dataptr[DCTSIZE * 1] | dataptr[DCTSIZE * 2] | dataptr[DCTSIZE * 3] |
dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] | dataptr[DCTSIZE * 4] | dataptr[DCTSIZE * 5] | dataptr[DCTSIZE * 6] |
dataptr[DCTSIZE*7]) == 0) { dataptr[DCTSIZE * 7]) == 0) {
/* AC terms all zero */ /* AC terms all zero */
DCTELEM dcval = (DCTELEM) DESCALE((INT32) dataptr[0], PASS1_BITS+3); DCTELEM dcval = (DCTELEM) DESCALE ((INT32) dataptr[0], PASS1_BITS + 3);
dataptr[DCTSIZE*0] = dcval; dataptr[DCTSIZE * 0] = dcval;
dataptr[DCTSIZE*1] = dcval; dataptr[DCTSIZE * 1] = dcval;
dataptr[DCTSIZE*2] = dcval; dataptr[DCTSIZE * 2] = dcval;
dataptr[DCTSIZE*3] = dcval; dataptr[DCTSIZE * 3] = dcval;
dataptr[DCTSIZE*4] = dcval; dataptr[DCTSIZE * 4] = dcval;
dataptr[DCTSIZE*5] = dcval; dataptr[DCTSIZE * 5] = dcval;
dataptr[DCTSIZE*6] = dcval; dataptr[DCTSIZE * 6] = dcval;
dataptr[DCTSIZE*7] = dcval; dataptr[DCTSIZE * 7] = dcval;
dataptr++; /* advance pointer to next column */ dataptr++; /* advance pointer to next column */
continue; continue;
} }
@ -324,48 +305,52 @@ gst_idct_int_idct (DCTBLOCK data)
/* Even part: reverse the even part of the forward DCT. */ /* Even part: reverse the even part of the forward DCT. */
/* The rotator is sqrt(2)*c(-6). */ /* The rotator is sqrt(2)*c(-6). */
z2 = (INT32) dataptr[DCTSIZE*2]; z2 = (INT32) dataptr[DCTSIZE * 2];
z3 = (INT32) dataptr[DCTSIZE*6]; z3 = (INT32) dataptr[DCTSIZE * 6];
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
tmp0 = ((INT32) dataptr[DCTSIZE*0] + (INT32) dataptr[DCTSIZE*4]) << CONST_BITS; tmp0 =
tmp1 = ((INT32) dataptr[DCTSIZE*0] - (INT32) dataptr[DCTSIZE*4]) << CONST_BITS; ((INT32) dataptr[DCTSIZE * 0] +
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
tmp1 =
((INT32) dataptr[DCTSIZE * 0] -
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
tmp10 = tmp0 + tmp3; tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3; tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2; tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its /* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
*/ */
tmp0 = (INT32) dataptr[DCTSIZE*7]; tmp0 = (INT32) dataptr[DCTSIZE * 7];
tmp1 = (INT32) dataptr[DCTSIZE*5]; tmp1 = (INT32) dataptr[DCTSIZE * 5];
tmp2 = (INT32) dataptr[DCTSIZE*3]; tmp2 = (INT32) dataptr[DCTSIZE * 3];
tmp3 = (INT32) dataptr[DCTSIZE*1]; tmp3 = (INT32) dataptr[DCTSIZE * 1];
z1 = tmp0 + tmp3; z1 = tmp0 + tmp3;
z2 = tmp1 + tmp2; z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2; z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3; z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* 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) */ tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* 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) */ z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5; z3 += z5;
z4 += z5; z4 += z5;
tmp0 += z1 + z3; tmp0 += z1 + z3;
tmp1 += z2 + z4; tmp1 += z2 + z4;
tmp2 += z2 + z3; tmp2 += z2 + z3;
@ -373,23 +358,23 @@ gst_idct_int_idct (DCTBLOCK data)
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3, dataptr[DCTSIZE * 0] = (DCTELEM) DESCALE (tmp10 + tmp3,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3, dataptr[DCTSIZE * 7] = (DCTELEM) DESCALE (tmp10 - tmp3,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2, dataptr[DCTSIZE * 1] = (DCTELEM) DESCALE (tmp11 + tmp2,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2, dataptr[DCTSIZE * 6] = (DCTELEM) DESCALE (tmp11 - tmp2,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1, dataptr[DCTSIZE * 2] = (DCTELEM) DESCALE (tmp12 + tmp1,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1, dataptr[DCTSIZE * 5] = (DCTELEM) DESCALE (tmp12 - tmp1,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0, dataptr[DCTSIZE * 3] = (DCTELEM) DESCALE (tmp13 + tmp0,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0, dataptr[DCTSIZE * 4] = (DCTELEM) DESCALE (tmp13 - tmp0,
CONST_BITS+PASS1_BITS+3); CONST_BITS + PASS1_BITS + 3);
dataptr++; /* advance pointer to next column */ 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.h"
#include "colorbalance-marshal.h" #include "colorbalance-marshal.h"
enum { enum
{
VALUE_CHANGED, VALUE_CHANGED,
LAST_SIGNAL 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 }; 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, gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE,
"GstColorBalance", "GstColorBalance", &gst_color_balance_info, 0);
&gst_color_balance_info, 0);
g_type_interface_add_prerequisite (gst_color_balance_type, g_type_interface_add_prerequisite (gst_color_balance_type,
GST_TYPE_IMPLEMENTS_INTERFACE); GST_TYPE_IMPLEMENTS_INTERFACE);
} }
return gst_color_balance_type; return gst_color_balance_type;
} }
static void static void
gst_color_balance_class_init (GstColorBalanceClass *klass) gst_color_balance_class_init (GstColorBalanceClass * klass)
{ {
static gboolean initialized = FALSE; static gboolean initialized = FALSE;
if (!initialized) { if (!initialized) {
gst_color_balance_signals[VALUE_CHANGED] = gst_color_balance_signals[VALUE_CHANGED] =
g_signal_new ("value-changed", g_signal_new ("value-changed",
GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST, GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed), G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
NULL, NULL, NULL, NULL,
gst_color_balance_marshal_VOID__OBJECT_INT, gst_color_balance_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2, G_TYPE_NONE, 2, GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
initialized = TRUE; initialized = TRUE;
} }
klass->balance_type = GST_COLOR_BALANCE_SOFTWARE; klass->balance_type = GST_COLOR_BALANCE_SOFTWARE;
/* default virtual functions */ /* default virtual functions */
klass->list_channels = NULL; klass->list_channels = NULL;
klass->set_value = NULL; klass->set_value = NULL;
@ -91,7 +90,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
} }
const GList * const GList *
gst_color_balance_list_channels (GstColorBalance *balance) gst_color_balance_list_channels (GstColorBalance * balance)
{ {
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -103,9 +102,8 @@ gst_color_balance_list_channels (GstColorBalance *balance)
} }
void void
gst_color_balance_set_value (GstColorBalance *balance, gst_color_balance_set_value (GstColorBalance * balance,
GstColorBalanceChannel *channel, GstColorBalanceChannel * channel, gint value)
gint value)
{ {
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -115,8 +113,8 @@ gst_color_balance_set_value (GstColorBalance *balance,
} }
gint gint
gst_color_balance_get_value (GstColorBalance *balance, gst_color_balance_get_value (GstColorBalance * balance,
GstColorBalanceChannel *channel) GstColorBalanceChannel * channel)
{ {
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
@ -128,13 +126,11 @@ gst_color_balance_get_value (GstColorBalance *balance,
} }
void void
gst_color_balance_value_changed (GstColorBalance *balance, gst_color_balance_value_changed (GstColorBalance * balance,
GstColorBalanceChannel *channel, GstColorBalanceChannel * channel, gint value)
gint value)
{ {
g_signal_emit (G_OBJECT (balance), g_signal_emit (G_OBJECT (balance),
gst_color_balance_signals[VALUE_CHANGED], gst_color_balance_signals[VALUE_CHANGED], 0, channel, value);
0, channel, value);
g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value); g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -23,11 +23,9 @@
#include <gst/gst.h> #include <gst/gst.h>
G_BEGIN_DECLS G_BEGIN_DECLS typedef struct GstMediaInfoPriv GstMediaInfoPriv;
typedef struct _GstMediaInfo GstMediaInfo;
typedef struct GstMediaInfoPriv GstMediaInfoPriv; typedef struct _GstMediaInfoClass GstMediaInfoClass;
typedef struct _GstMediaInfo GstMediaInfo;
typedef struct _GstMediaInfoClass GstMediaInfoClass;
struct _GstMediaInfo struct _GstMediaInfo
{ {
@ -43,8 +41,9 @@ struct _GstMediaInfoClass
GObjectClass parent_class; GObjectClass parent_class;
/* signals */ /* signals */
void (*media_info_signal) (GstMediaInfo *gst_media_info); void (*media_info_signal) (GstMediaInfo * gst_media_info);
void (*error_signal) (GstMediaInfo *gst_media_info, GError *error, const gchar *debug); void (*error_signal) (GstMediaInfo * gst_media_info, GError * error,
const gchar * debug);
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
@ -100,34 +99,25 @@ typedef struct
#define GST_MEDIA_INFO_FORMAT 1 << 5 #define GST_MEDIA_INFO_FORMAT 1 << 5
#define GST_MEDIA_INFO_ALL ((1 << 6) - 1) #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); void gst_media_info_init (void);
GType gst_media_info_get_type (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 ? * FIXME: reset ?
gboolean gst_media_info_write (GstMediaInfo *media_info, gboolean gst_media_info_write (GstMediaInfo *media_info,
@ -136,5 +126,4 @@ gboolean gst_media_info_write (GstMediaInfo *media_info,
*/ */
G_END_DECLS G_END_DECLS
#endif /* __GST_MEDIA_INFO_H__ */ #endif /* __GST_MEDIA_INFO_H__ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -26,7 +26,6 @@
#include <gst/gst.h> #include <gst/gst.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_NAVIGATION \ #define GST_TYPE_NAVIGATION \
(gst_navigation_get_type ()) (gst_navigation_get_type ())
#define GST_NAVIGATION(obj) \ #define GST_NAVIGATION(obj) \
@ -35,28 +34,28 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION)) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION))
#define GST_NAVIGATION_GET_IFACE(obj) \ #define GST_NAVIGATION_GET_IFACE(obj) \
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface)) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface))
typedef struct _GstNavigation GstNavigation; typedef struct _GstNavigation GstNavigation;
typedef struct _GstNavigationInterface { typedef struct _GstNavigationInterface
{
GTypeInterface g_iface; GTypeInterface g_iface;
/* virtual functions */ /* virtual functions */
void (*send_event) (GstNavigation *navigation, GstStructure *structure); void (*send_event) (GstNavigation * navigation, GstStructure * structure);
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
} GstNavigationInterface; } GstNavigationInterface;
GType gst_navigation_get_type (void); GType gst_navigation_get_type (void);
/* virtual class function wrappers */ /* 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, void gst_navigation_send_key_event (GstNavigation * navigation,
const char *event, const char *key); const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation *navigation, void gst_navigation_send_mouse_event (GstNavigation * navigation,
const char *event, int button, double x, double y); const char *event, int button, double x, double y);
G_END_DECLS G_END_DECLS
#endif /* __GST_NAVIGATION_H__ */ #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, * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#ifndef __GST_PLAY_H__ #ifndef __GST_PLAY_H__
#define __GST_PLAY_H__ #define __GST_PLAY_H__
@ -46,51 +46,43 @@ typedef enum
typedef struct _GstPlay GstPlay; typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass; typedef struct _GstPlayClass GstPlayClass;
typedef struct _GstPlayPrivate GstPlayPrivate; typedef struct _GstPlayPrivate GstPlayPrivate;
struct _GstPlay struct _GstPlay
{ {
GstPipeline pipeline; GstPipeline pipeline;
GstPlayPrivate *priv; GstPlayPrivate *priv;
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
struct _GstPlayClass struct _GstPlayClass
{ {
GstPipelineClass parent_class; GstPipelineClass parent_class;
void (*time_tick) (GstPlay *play, gint64 time_nanos); void (*time_tick) (GstPlay * play, gint64 time_nanos);
void (*stream_length) (GstPlay *play, gint64 length_nanos); void (*stream_length) (GstPlay * play, gint64 length_nanos);
void (*have_video_size) (GstPlay *play, gint width, gint height); void (*have_video_size) (GstPlay * play, gint width, gint height);
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
GType gst_play_get_type (void); GType gst_play_get_type (void);
GstPlay * gst_play_new (GError **error); GstPlay *gst_play_new (GError ** error);
gboolean gst_play_set_data_src (GstPlay *play, gboolean gst_play_set_data_src (GstPlay * play, GstElement * data_src);
GstElement *data_src); gboolean gst_play_set_video_sink (GstPlay * play, GstElement * video_sink);
gboolean gst_play_set_video_sink (GstPlay *play, gboolean gst_play_set_audio_sink (GstPlay * play, GstElement * audio_sink);
GstElement *video_sink);
gboolean gst_play_set_audio_sink (GstPlay *play,
GstElement *audio_sink);
gboolean gst_play_set_visualization (GstPlay *play, gboolean gst_play_set_visualization (GstPlay * play, GstElement * element);
GstElement *element); gboolean gst_play_connect_visualization (GstPlay * play, gboolean connect);
gboolean gst_play_connect_visualization (GstPlay *play,
gboolean connect);
gboolean gst_play_set_location (GstPlay *play, gboolean gst_play_set_location (GstPlay * play, const char *location);
const char *location); char *gst_play_get_location (GstPlay * play);
char * gst_play_get_location (GstPlay *play);
gboolean gst_play_seek_to_time (GstPlay *play, gboolean gst_play_seek_to_time (GstPlay * play, gint64 time_nanos);
gint64 time_nanos);
GstElement * gst_play_get_sink_element (GstPlay *play, GstElement *gst_play_get_sink_element (GstPlay * play,
GstElement *element, GstElement * element, GstPlaySinkType sink_type);
GstPlaySinkType sink_type);
#endif /* __GST_PLAY_H__ */ #endif /* __GST_PLAY_H__ */

View file

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

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