mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-26 09:50:39 +00:00
gst-indent
Original commit message from CVS: gst-indent
This commit is contained in:
parent
e9bef8b9bd
commit
4df3f18839
|
@ -1,3 +1,7 @@
|
|||
2004-03-14 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* *.c, *.h: run gst-indent
|
||||
|
||||
2004-03-14 Benjamin Otte <otte@gnome.org>
|
||||
|
||||
* gst/modplug/gstmodplug.cc:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* connection would use the I420 format (assuming Xv is enabled) */
|
||||
|
||||
static void
|
||||
new_pad_func (GstElement *element, GstPad *newpad, gpointer data)
|
||||
new_pad_func (GstElement * element, GstPad * newpad, gpointer data)
|
||||
{
|
||||
GstElement *pipeline = (GstElement *) data;
|
||||
GstElement *queue = gst_bin_get_by_name (GST_BIN (pipeline), "queue");
|
||||
|
@ -19,7 +19,7 @@ new_pad_func (GstElement *element, GstPad *newpad, gpointer data)
|
|||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *filesrc;
|
||||
|
@ -44,7 +44,8 @@ main (gint argc, gchar *argv[])
|
|||
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
|
||||
demux = gst_element_factory_make ("mpegdemux", "demux");
|
||||
g_return_val_if_fail (demux, -1);
|
||||
g_signal_connect (G_OBJECT (demux), "new_pad", G_CALLBACK (new_pad_func), pipeline);
|
||||
g_signal_connect (G_OBJECT (demux), "new_pad", G_CALLBACK (new_pad_func),
|
||||
pipeline);
|
||||
|
||||
thread = gst_thread_new ("thread");
|
||||
queue = gst_element_factory_make ("queue", "queue");
|
||||
|
@ -70,10 +71,8 @@ main (gint argc, gchar *argv[])
|
|||
gst_element_link (mpeg2dec, "src", colorspace, "sink");
|
||||
/* force RGB data passing between colorspace and xvideosink */
|
||||
res = gst_element_link_filtered (colorspace, "src", xvideosink, "sink",
|
||||
GST_CAPS_NEW (
|
||||
"filtercaps",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
|
||||
GST_CAPS_NEW ("filtercaps",
|
||||
"video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
|
||||
));
|
||||
if (!res) {
|
||||
g_print ("could not connect colorspace and xvideosink\n");
|
||||
|
|
|
@ -47,17 +47,18 @@ struct _filter_data
|
|||
typedef struct _filter_data _filter_data_t;
|
||||
|
||||
/* internal prototypes when they can't be avoided */
|
||||
void cb_remove_and_destroy (GtkWidget *widget, gpointer user_data);
|
||||
void cb_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 (GtkRange * range, GstDParam * dparam);
|
||||
|
||||
/* GStreamer helper functions go here */
|
||||
|
||||
/* go through a bin, finding the one pad that is unconnected in the given
|
||||
* direction, and return a ghost pad */
|
||||
GstPad *
|
||||
gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction,
|
||||
gchar *name)
|
||||
gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction,
|
||||
gchar * name)
|
||||
{
|
||||
GstPad *pad = NULL;
|
||||
GList *elements = NULL;
|
||||
|
@ -67,24 +68,21 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction,
|
|||
g_print ("DEBUG: find_unconnected start\n");
|
||||
elements = (GList *) gst_bin_get_list (bin);
|
||||
/* traverse all elements looking for unconnected pads */
|
||||
while (elements && pad == NULL)
|
||||
{
|
||||
while (elements && pad == NULL) {
|
||||
element = GST_ELEMENT (elements->data);
|
||||
g_print ("DEBUG: looking in element %s\n", gst_element_get_name (element));
|
||||
pads = gst_element_get_pad_list (element);
|
||||
while (pads)
|
||||
{
|
||||
while (pads) {
|
||||
/* check if the direction matches */
|
||||
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction)
|
||||
{
|
||||
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL)
|
||||
{
|
||||
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
|
||||
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
|
||||
/* found it ! */
|
||||
g_print ("DEBUG: found an unconnected pad !\n");
|
||||
pad = GST_PAD (pads->data);
|
||||
}
|
||||
}
|
||||
if (pad) break; /* found one already */
|
||||
if (pad)
|
||||
break; /* found one already */
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
elements = g_list_next (elements);
|
||||
|
@ -99,7 +97,7 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction,
|
|||
}
|
||||
|
||||
void
|
||||
ui_feedback_add_text (_filter_ui_t *ui, const gchar *text)
|
||||
ui_feedback_add_text (_filter_ui_t * ui, const gchar * text)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
|
||||
|
@ -108,7 +106,7 @@ ui_feedback_add_text (_filter_ui_t *ui, const gchar *text)
|
|||
}
|
||||
|
||||
void
|
||||
ui_feedback_add (_filter_ui_t *ui, const gchar *format, ...)
|
||||
ui_feedback_add (_filter_ui_t * ui, const gchar * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
gchar *buffer = NULL;
|
||||
|
@ -121,7 +119,7 @@ ui_feedback_add (_filter_ui_t *ui, const gchar *format, ...)
|
|||
}
|
||||
|
||||
void
|
||||
ui_feedback_clear (_filter_ui_t *ui)
|
||||
ui_feedback_clear (_filter_ui_t * ui)
|
||||
{
|
||||
gtk_text_buffer_set_text (ui->fb_buffer, "", 0);
|
||||
}
|
||||
|
@ -129,7 +127,7 @@ ui_feedback_clear (_filter_ui_t *ui)
|
|||
/* create the control widget using the element's dynparams
|
||||
* control is a vbox which we need to empty first */
|
||||
void
|
||||
ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
|
||||
ui_control_create (GstElement * element, GtkWidget * control, _filter_ui_t * ui)
|
||||
{
|
||||
GtkWidget *hbox = NULL;
|
||||
GtkWidget *widget = NULL;
|
||||
|
@ -150,51 +148,44 @@ ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
|
|||
gtk_container_add (GTK_CONTAINER (control), widget);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
if ((dpman = gst_dpman_get_manager (element)))
|
||||
{
|
||||
if ((dpman = gst_dpman_get_manager (element))) {
|
||||
ui_feedback_add (ui, "Found Dynamic Parameters on filter element.\n");
|
||||
specs = gst_dpman_list_dparam_specs (dpman);
|
||||
for (i = 0; specs[i] != NULL; ++i)
|
||||
{
|
||||
for (i = 0; specs[i] != NULL; ++i) {
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
widget = gtk_label_new (g_param_spec_get_name (specs[i]));
|
||||
gtk_container_add (GTK_CONTAINER (hbox), widget);
|
||||
gtk_widget_show (widget);
|
||||
switch (G_PARAM_SPEC_VALUE_TYPE (specs[i]))
|
||||
{
|
||||
switch (G_PARAM_SPEC_VALUE_TYPE (specs[i])) {
|
||||
case G_TYPE_INT64:
|
||||
widget = gtk_hscale_new_with_range (
|
||||
(gdouble) (((GParamSpecInt64*)specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecInt64*)specs[i])->maximum),
|
||||
1.0);
|
||||
(gdouble) (((GParamSpecInt64 *) specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecInt64 *) specs[i])->maximum), 1.0);
|
||||
gtk_range_set_value (GTK_RANGE (widget),
|
||||
(gdouble) ((GParamSpecInt64*)specs[i])->default_value);
|
||||
(gdouble) ((GParamSpecInt64 *) specs[i])->default_value);
|
||||
break;
|
||||
|
||||
case G_TYPE_INT:
|
||||
widget = gtk_hscale_new_with_range (
|
||||
(gdouble) (((GParamSpecInt*)specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecInt*)specs[i])->maximum),
|
||||
1.0);
|
||||
(gdouble) (((GParamSpecInt *) specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecInt *) specs[i])->maximum), 1.0);
|
||||
gtk_range_set_value (GTK_RANGE (widget),
|
||||
(gdouble) ((GParamSpecInt*)specs[i])->default_value);
|
||||
(gdouble) ((GParamSpecInt *) specs[i])->default_value);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
widget = gtk_hscale_new_with_range (
|
||||
(gdouble) (((GParamSpecFloat*)specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecFloat*)specs[i])->maximum),
|
||||
0.00001);
|
||||
(gdouble) (((GParamSpecFloat *) specs[i])->minimum),
|
||||
(gdouble) (((GParamSpecFloat *) specs[i])->maximum), 0.00001);
|
||||
gtk_range_set_value (GTK_RANGE (widget),
|
||||
(gdouble) ((GParamSpecFloat*)specs[i])->default_value);
|
||||
(gdouble) ((GParamSpecFloat *) specs[i])->default_value);
|
||||
break;
|
||||
}
|
||||
/* create the dparam object */
|
||||
dparam = gst_dpsmooth_new (G_PARAM_SPEC_VALUE_TYPE (specs[i]));
|
||||
g_object_set (G_OBJECT (dparam), "update_period", 2000000LL, NULL);
|
||||
g_assert (gst_dpman_attach_dparam (dpman,
|
||||
(gchar *) g_param_spec_get_name (specs[i]),
|
||||
dparam));
|
||||
gst_dpman_set_mode(dpman, "asynchronous");
|
||||
(gchar *) g_param_spec_get_name (specs[i]), dparam));
|
||||
gst_dpman_set_mode (dpman, "asynchronous");
|
||||
g_signal_connect (widget, "value-changed",
|
||||
G_CALLBACK (cb_dynparm_value_changed), dparam);
|
||||
cb_dynparm_value_changed (GTK_RANGE (widget), dparam);
|
||||
|
@ -209,7 +200,7 @@ ui_control_create (GstElement *element, GtkWidget *control, _filter_ui_t *ui)
|
|||
|
||||
/* all the pretty callbacks gather here please */
|
||||
void
|
||||
cb_remove_and_destroy (GtkWidget *widget, gpointer user_data)
|
||||
cb_remove_and_destroy (GtkWidget * widget, gpointer user_data)
|
||||
{
|
||||
GtkContainer *container = GTK_CONTAINER (user_data);
|
||||
|
||||
|
@ -220,13 +211,14 @@ cb_remove_and_destroy (GtkWidget *widget, gpointer user_data)
|
|||
|
||||
/* when the scale associated with a dparam changes, respond */
|
||||
void
|
||||
cb_dynparm_value_changed (GtkRange *range, GstDParam *dparam)
|
||||
cb_dynparm_value_changed (GtkRange * range, GstDParam * dparam)
|
||||
{
|
||||
/*
|
||||
GstDParam *dparam = GST_DPARAM (user_data);
|
||||
GtkHScale *adj = GTK_HSCALE (widget);
|
||||
*/
|
||||
gdouble value = 0.0;
|
||||
|
||||
g_assert (GST_IS_DPARAM (dparam));
|
||||
g_assert (GTK_IS_RANGE (range));
|
||||
|
||||
|
@ -234,41 +226,36 @@ cb_dynparm_value_changed (GtkRange *range, GstDParam *dparam)
|
|||
|
||||
g_print ("DEBUG: setting value to %f\n", value);
|
||||
|
||||
switch (G_PARAM_SPEC_VALUE_TYPE (GST_DPARAM_PARAM_SPEC (dparam)))
|
||||
{
|
||||
switch (G_PARAM_SPEC_VALUE_TYPE (GST_DPARAM_PARAM_SPEC (dparam))) {
|
||||
case G_TYPE_INT64:
|
||||
g_object_set (G_OBJECT (dparam), "value_int64",
|
||||
(gint64) value, NULL);
|
||||
g_object_set (G_OBJECT (dparam), "value_int64", (gint64) value, NULL);
|
||||
break;
|
||||
|
||||
case G_TYPE_INT:
|
||||
g_object_set (G_OBJECT (dparam), "value_int",
|
||||
(gint) value, NULL);
|
||||
g_object_set (G_OBJECT (dparam), "value_int", (gint) value, NULL);
|
||||
break;
|
||||
|
||||
case G_TYPE_FLOAT:
|
||||
g_object_set (G_OBJECT (dparam), "value_float",
|
||||
(gfloat) value, NULL);
|
||||
g_object_set (G_OBJECT (dparam), "value_float", (gfloat) value, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cb_entry_activate (GtkEntry *entry, gpointer user_data)
|
||||
cb_entry_activate (GtkEntry * entry, gpointer user_data)
|
||||
{
|
||||
g_print ("DEBUG: oi ! you activated an entry !\n");
|
||||
g_print ("DEBUG: pipeline: %s\n", gtk_entry_get_text (entry));
|
||||
}
|
||||
|
||||
void
|
||||
cb_play_clicked (GtkButton *button, gpointer *user_data)
|
||||
cb_play_clicked (GtkButton * button, gpointer * user_data)
|
||||
{
|
||||
_filter_data_t *fd = (_filter_data_t *) user_data;
|
||||
|
||||
g_return_if_fail (GST_IS_PIPELINE (fd->pipeline));
|
||||
if (GST_STATE (fd->pipeline) == GST_STATE_PLAYING)
|
||||
{
|
||||
if (GST_STATE (fd->pipeline) == GST_STATE_PLAYING) {
|
||||
ui_feedback_add (fd->ui, "Pipeline is already playing !\n");
|
||||
return;
|
||||
}
|
||||
|
@ -276,12 +263,11 @@ cb_play_clicked (GtkButton *button, gpointer *user_data)
|
|||
}
|
||||
|
||||
void
|
||||
cb_stop_clicked (GtkButton *button, gpointer *user_data)
|
||||
cb_stop_clicked (GtkButton * button, gpointer * user_data)
|
||||
{
|
||||
_filter_data_t *fd = (_filter_data_t *) user_data;
|
||||
|
||||
if (GST_STATE (fd->pipeline) != GST_STATE_PLAYING)
|
||||
{
|
||||
if (GST_STATE (fd->pipeline) != GST_STATE_PLAYING) {
|
||||
ui_feedback_add (fd->ui, "Pipeline is not playing !\n");
|
||||
return;
|
||||
}
|
||||
|
@ -289,7 +275,7 @@ cb_stop_clicked (GtkButton *button, gpointer *user_data)
|
|||
}
|
||||
|
||||
void
|
||||
cb_parse_clicked (GtkButton *button, gpointer *user_data)
|
||||
cb_parse_clicked (GtkButton * button, gpointer * user_data)
|
||||
{
|
||||
_filter_data_t *fd = (_filter_data_t *) user_data;
|
||||
GtkCombo *filter = GTK_COMBO (fd->ui->filter);
|
||||
|
@ -299,44 +285,49 @@ cb_parse_clicked (GtkButton *button, gpointer *user_data)
|
|||
g_print ("DEBUG: you pressed parse.\n");
|
||||
ui_feedback_clear (fd->ui);
|
||||
ui_feedback_add (fd->ui, "Parsing pipeline ...\n");
|
||||
if (fd->input_pipe) g_free (fd->input_pipe);
|
||||
if (fd->output_pipe) g_free (fd->output_pipe);
|
||||
if (fd->filter_element) g_free (fd->filter_element);
|
||||
if (fd->input_pipe)
|
||||
g_free (fd->input_pipe);
|
||||
if (fd->output_pipe)
|
||||
g_free (fd->output_pipe);
|
||||
if (fd->filter_element)
|
||||
g_free (fd->filter_element);
|
||||
fd->input_pipe = g_strdup_printf ("bin.( %s )",
|
||||
gtk_entry_get_text (GTK_ENTRY (fd->ui->input)));
|
||||
fd->output_pipe = g_strdup_printf ("bin.( %s )",
|
||||
gtk_entry_get_text (GTK_ENTRY (fd->ui->output)));
|
||||
/* gtkcombo.h says I can access the entry field directly */
|
||||
fd->filter_element = g_strdup (gtk_entry_get_text (GTK_ENTRY (filter->entry)));
|
||||
g_print ("Input pipeline :\t%s (%d)\n", fd->input_pipe, (int)strlen (fd->input_pipe));
|
||||
g_print ("Filter element :\t%s (%d)\n", fd->filter_element, (int)strlen (fd->filter_element));
|
||||
g_print ("Output pipeline :\t%s (%d)\n", fd->output_pipe, (int)strlen (fd->output_pipe));
|
||||
fd->filter_element =
|
||||
g_strdup (gtk_entry_get_text (GTK_ENTRY (filter->entry)));
|
||||
g_print ("Input pipeline :\t%s (%d)\n", fd->input_pipe,
|
||||
(int) strlen (fd->input_pipe));
|
||||
g_print ("Filter element :\t%s (%d)\n", fd->filter_element,
|
||||
(int) strlen (fd->filter_element));
|
||||
g_print ("Output pipeline :\t%s (%d)\n", fd->output_pipe,
|
||||
(int) strlen (fd->output_pipe));
|
||||
|
||||
/* try to create in and out bins */
|
||||
if (strlen (fd->input_pipe) == 0)
|
||||
{
|
||||
if (strlen (fd->input_pipe) == 0) {
|
||||
ui_feedback_add (fd->ui, "Error : try setting an input pipe.\n");
|
||||
return;
|
||||
}
|
||||
if (fd->input) gst_object_unref (GST_OBJECT (fd->input));
|
||||
if (fd->input)
|
||||
gst_object_unref (GST_OBJECT (fd->input));
|
||||
fd->input = GST_ELEMENT (gst_parse_launch (fd->input_pipe, &error));
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
ui_feedback_add (fd->ui, "Error : parsing input pipeline : %s\n",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen (fd->output_pipe) == 0)
|
||||
{
|
||||
if (strlen (fd->output_pipe) == 0) {
|
||||
ui_feedback_add (fd->ui, "Error : try setting an output pipe.\n");
|
||||
return;
|
||||
}
|
||||
if (fd->output) gst_object_unref (GST_OBJECT (fd->output));
|
||||
if (fd->output)
|
||||
gst_object_unref (GST_OBJECT (fd->output));
|
||||
fd->output = GST_ELEMENT (gst_parse_launch (fd->output_pipe, &error));
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
ui_feedback_add (fd->ui, "Error : parsing output pipeline : %s\n",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
|
@ -344,10 +335,10 @@ cb_parse_clicked (GtkButton *button, gpointer *user_data)
|
|||
}
|
||||
|
||||
/* try to create filter */
|
||||
if (fd->filter) gst_object_unref (GST_OBJECT (fd->filter));
|
||||
if (fd->filter)
|
||||
gst_object_unref (GST_OBJECT (fd->filter));
|
||||
fd->filter = gst_element_factory_make (fd->filter_element, "filter");
|
||||
if (fd->filter == NULL)
|
||||
{
|
||||
if (fd->filter == NULL) {
|
||||
ui_feedback_add (fd->ui, "Error : could not create element %s\n",
|
||||
fd->filter_element);
|
||||
return;
|
||||
|
@ -361,22 +352,19 @@ cb_parse_clicked (GtkButton *button, gpointer *user_data)
|
|||
|
||||
/* add the players to it */
|
||||
gst_bin_add_many (GST_BIN (fd->pipeline),
|
||||
fd->input, fd->filter,
|
||||
fd->output, NULL);
|
||||
fd->input, fd->filter, fd->output, NULL);
|
||||
|
||||
/* connect filter to input and output bin */
|
||||
src_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->input), GST_PAD_SRC,
|
||||
"source");
|
||||
if (src_pad == NULL)
|
||||
{
|
||||
if (src_pad == NULL) {
|
||||
ui_feedback_add (fd->ui,
|
||||
"Error : could not find an unconnected source pad !\n");
|
||||
return;
|
||||
}
|
||||
sink_pad = gst_bin_find_unconnected_pad (GST_BIN (fd->output), GST_PAD_SINK,
|
||||
"sink");
|
||||
if (sink_pad == NULL)
|
||||
{
|
||||
if (sink_pad == NULL) {
|
||||
ui_feedback_add (fd->ui,
|
||||
"Error : could not find an unconnected sink pad !\n");
|
||||
return;
|
||||
|
@ -386,7 +374,8 @@ cb_parse_clicked (GtkButton *button, gpointer *user_data)
|
|||
|
||||
gst_element_link_many (fd->input, fd->filter, fd->output, NULL);
|
||||
|
||||
if (fd->pipe_string) g_free (fd->pipe_string);
|
||||
if (fd->pipe_string)
|
||||
g_free (fd->pipe_string);
|
||||
fd->pipe_string = g_strdup_printf ("%s ! %s ! %s", fd->input_pipe,
|
||||
fd->filter_element, fd->output_pipe);
|
||||
g_print ("Pipeline : %s\n", fd->pipe_string);
|
||||
|
@ -409,7 +398,7 @@ get_filter_choices (void)
|
|||
}
|
||||
|
||||
void
|
||||
init_data (_filter_data_t *fd)
|
||||
init_data (_filter_data_t * fd)
|
||||
{
|
||||
fd->input_pipe = NULL;
|
||||
fd->output_pipe = NULL;
|
||||
|
@ -426,7 +415,7 @@ init_data (_filter_data_t *fd)
|
|||
}
|
||||
|
||||
void
|
||||
create_ui (_filter_ui_t *fui, _filter_data_t *fd)
|
||||
create_ui (_filter_ui_t * fui, _filter_data_t * fd)
|
||||
{
|
||||
GtkWidget *widget; /* temporary widget */
|
||||
GtkWidget *vbox; /* temporary vbox */
|
||||
|
@ -465,7 +454,7 @@ create_ui (_filter_ui_t *fui, _filter_data_t *fd)
|
|||
/* feedback widget */
|
||||
fui->fb_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (fui->feedback));
|
||||
gtk_text_buffer_set_text (fui->fb_buffer,
|
||||
"Hello, and welcome to the GStreamer filter demo app !\n"\
|
||||
"Hello, and welcome to the GStreamer filter demo app !\n"
|
||||
"I'll be your feedback window for today.\n", -1);
|
||||
|
||||
/* selection widget */
|
||||
|
@ -527,4 +516,3 @@ main (int argc, char *argv[])
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static GMainLoop *loop = NULL;
|
|||
static gint64 length = 0;
|
||||
|
||||
static void
|
||||
print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
||||
print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
|
||||
{
|
||||
gint i, count;
|
||||
|
||||
|
@ -35,8 +35,8 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
|||
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
|
||||
g_assert (gst_tag_list_get_string_index (list, tag, i, &str));
|
||||
} else {
|
||||
str = g_strdup_value_contents (
|
||||
gst_tag_list_get_value_index (list, tag, i));
|
||||
str =
|
||||
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
|
@ -50,46 +50,46 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
|||
}
|
||||
|
||||
static void
|
||||
got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list)
|
||||
got_found_tag (GstPlay * play, GstElement * source, GstTagList * tag_list)
|
||||
{
|
||||
gst_tag_list_foreach (tag_list, print_tag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
got_time_tick (GstPlay *play, gint64 time_nanos)
|
||||
got_time_tick (GstPlay * play, gint64 time_nanos)
|
||||
{
|
||||
g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
|
||||
}
|
||||
|
||||
static void
|
||||
got_stream_length (GstPlay *play, gint64 length_nanos)
|
||||
got_stream_length (GstPlay * play, gint64 length_nanos)
|
||||
{
|
||||
g_print ("got length %llu\n", length_nanos);
|
||||
length = length_nanos;
|
||||
}
|
||||
|
||||
static void
|
||||
got_video_size (GstPlay *play, gint width, gint height)
|
||||
got_video_size (GstPlay * play, gint width, gint height)
|
||||
{
|
||||
g_print ("got video size %d, %d\n", width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
got_eos (GstPlay *play)
|
||||
got_eos (GstPlay * play)
|
||||
{
|
||||
g_print ("End Of Stream\n");
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
seek_timer (GstPlay *play)
|
||||
seek_timer (GstPlay * play)
|
||||
{
|
||||
gst_play_seek_to_time (play, length / 2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_iterate (GstPlay *play)
|
||||
idle_iterate (GstPlay * play)
|
||||
{
|
||||
gst_bin_iterate (GST_BIN (play));
|
||||
return (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING);
|
||||
|
@ -114,8 +114,7 @@ main (int argc, char *argv[])
|
|||
|
||||
/* Creating the GstPlay object */
|
||||
play = gst_play_new (&error);
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_print ("Error: could not create play object:\n%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return 1;
|
||||
|
@ -149,8 +148,7 @@ main (int argc, char *argv[])
|
|||
G_CALLBACK (got_found_tag), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "error",
|
||||
G_CALLBACK (gst_element_default_error), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "eos",
|
||||
G_CALLBACK (got_eos), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "eos", G_CALLBACK (got_eos), NULL);
|
||||
|
||||
/* Change state to PLAYING */
|
||||
gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
|
||||
|
|
|
@ -24,7 +24,7 @@ static gboolean verbose = FALSE;
|
|||
static gboolean quiet = FALSE;
|
||||
|
||||
static void
|
||||
entry_added (GstIndex *index, GstIndexEntry *entry)
|
||||
entry_added (GstIndex * index, GstIndexEntry * entry)
|
||||
{
|
||||
switch (entry->type) {
|
||||
case GST_INDEX_ENTRY_ID:
|
||||
|
@ -33,14 +33,14 @@ entry_added (GstIndex *index, GstIndexEntry *entry)
|
|||
break;
|
||||
case GST_INDEX_ENTRY_FORMAT:
|
||||
g_print ("%d: registered format %d for %s\n", entry->id,
|
||||
GST_INDEX_FORMAT_FORMAT (entry),
|
||||
GST_INDEX_FORMAT_KEY (entry));
|
||||
GST_INDEX_FORMAT_FORMAT (entry), GST_INDEX_FORMAT_KEY (entry));
|
||||
break;
|
||||
case GST_INDEX_ENTRY_ASSOCIATION:
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_print ("%p, %d: %08x ", entry, entry->id, GST_INDEX_ASSOC_FLAGS (entry));
|
||||
g_print ("%p, %d: %08x ", entry, entry->id,
|
||||
GST_INDEX_ASSOC_FLAGS (entry));
|
||||
for (i = 0; i < GST_INDEX_NASSOCS (entry); i++) {
|
||||
g_print ("%d %lld ", GST_INDEX_ASSOC_FORMAT (entry, i),
|
||||
GST_INDEX_ASSOC_VALUE (entry, i));
|
||||
|
@ -63,7 +63,7 @@ typedef struct
|
|||
} dyn_link;
|
||||
|
||||
static void
|
||||
dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
|
||||
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
|
||||
{
|
||||
dyn_link *link = (dyn_link *) data;
|
||||
|
||||
|
@ -77,12 +77,9 @@ dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
|
|||
}
|
||||
|
||||
static void
|
||||
setup_dynamic_linking (GstElement *pipeline,
|
||||
GstElement *element,
|
||||
const gchar *padname,
|
||||
GstPad *target,
|
||||
GstElement *bin,
|
||||
GstIndex *index)
|
||||
setup_dynamic_linking (GstElement * pipeline,
|
||||
GstElement * element,
|
||||
const gchar * padname, GstPad * target, GstElement * bin, GstIndex * index)
|
||||
{
|
||||
dyn_link *link;
|
||||
|
||||
|
@ -93,11 +90,12 @@ setup_dynamic_linking (GstElement *pipeline,
|
|||
link->pipeline = pipeline;
|
||||
link->index = index;
|
||||
|
||||
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link), link);
|
||||
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
|
||||
link);
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mpeg_systems_pipeline (const gchar *path, GstIndex *index)
|
||||
static GstElement *
|
||||
make_mpeg_systems_pipeline (const gchar * path, GstIndex * index)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *demux;
|
||||
|
@ -121,8 +119,8 @@ make_mpeg_systems_pipeline (const gchar *path, GstIndex *index)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mpeg_decoder_pipeline (const gchar *path, GstIndex *index)
|
||||
static GstElement *
|
||||
make_mpeg_decoder_pipeline (const gchar * path, GstIndex * index)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *demux;
|
||||
|
@ -147,15 +145,13 @@ make_mpeg_decoder_pipeline (const gchar *path, GstIndex *index)
|
|||
gst_bin_add (GST_BIN (video_bin), video_decoder);
|
||||
|
||||
setup_dynamic_linking (pipeline, demux, "video_00",
|
||||
gst_element_get_pad (video_decoder, "sink"),
|
||||
video_bin, index);
|
||||
gst_element_get_pad (video_decoder, "sink"), video_bin, index);
|
||||
|
||||
audio_bin = gst_bin_new ("audio_bin");
|
||||
audio_decoder = gst_element_factory_make ("mad", "audio_decoder");
|
||||
|
||||
setup_dynamic_linking (pipeline, demux, "audio_00",
|
||||
gst_element_get_pad (audio_decoder, "sink"),
|
||||
audio_bin, index);
|
||||
gst_element_get_pad (audio_decoder, "sink"), audio_bin, index);
|
||||
|
||||
gst_bin_add (GST_BIN (audio_bin), audio_decoder);
|
||||
|
||||
|
@ -167,7 +163,7 @@ make_mpeg_decoder_pipeline (const gchar *path, GstIndex *index)
|
|||
}
|
||||
|
||||
static void
|
||||
print_progress (GstPad *pad)
|
||||
print_progress (GstPad * pad)
|
||||
{
|
||||
gint i = 0;
|
||||
gchar status[53];
|
||||
|
@ -185,10 +181,10 @@ print_progress (GstPad *pad)
|
|||
}
|
||||
|
||||
for (i = 0; i < percent; i++) {
|
||||
status[i+1] = '=';
|
||||
status[i + 1] = '=';
|
||||
}
|
||||
for (i = percent; i < 50; i++) {
|
||||
status[i+1] = ' ';
|
||||
status[i + 1] = ' ';
|
||||
}
|
||||
status[51] = '|';
|
||||
status[52] = 0;
|
||||
|
@ -197,7 +193,7 @@ print_progress (GstPad *pad)
|
|||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src;
|
||||
|
@ -208,9 +204,9 @@ main (gint argc, gchar *argv[])
|
|||
gboolean res;
|
||||
GstElement *sink;
|
||||
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},
|
||||
{ "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},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
@ -220,7 +216,7 @@ main (gint argc, gchar *argv[])
|
|||
" type can be: 0 mpeg_systems\n"
|
||||
" 1 mpeg_decoder\n"
|
||||
" -v : report added index entries\n"
|
||||
" -q : don't print progress\n" , argv[0]);
|
||||
" -q : don't print progress\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -228,7 +224,8 @@ main (gint argc, gchar *argv[])
|
|||
index = gst_index_factory_make ("memindex");
|
||||
if (index) {
|
||||
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);
|
||||
}
|
||||
|
@ -259,7 +256,7 @@ main (gint argc, gchar *argv[])
|
|||
/* prepare for iteration */
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
g_print ("indexing %s...\n", argv [2]);
|
||||
g_print ("indexing %s...\n", argv[2]);
|
||||
/* run through the complete stream to let it generate an index */
|
||||
while (gst_bin_iterate (GST_BIN (pipeline))) {
|
||||
if (!quiet && (count % 1000 == 0)) {
|
||||
|
@ -299,10 +296,9 @@ main (gint argc, gchar *argv[])
|
|||
gst_element_link_pads (src, "src", sink, "sink");
|
||||
gst_bin_add (GST_BIN (pipeline), sink);
|
||||
|
||||
g_print ("seeking %s...\n", argv [2]);
|
||||
g_print ("seeking %s...\n", argv[2]);
|
||||
event = gst_event_new_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH, 5 * GST_SECOND);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, 5 * GST_SECOND);
|
||||
|
||||
res = gst_pad_send_event (pad, event);
|
||||
if (!res) {
|
||||
|
@ -322,4 +318,3 @@ main (gint argc, gchar *argv[])
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <string.h>
|
||||
|
||||
static void
|
||||
get_position_info (GstElement *cdparanoia)
|
||||
get_position_info (GstElement * cdparanoia)
|
||||
{
|
||||
GstFormat track_format;
|
||||
const GstFormat *formats;
|
||||
|
@ -24,14 +24,13 @@ get_position_info (GstElement *cdparanoia)
|
|||
definition = gst_format_get_details (*formats);
|
||||
|
||||
format = *formats;
|
||||
res = gst_pad_query (pad, GST_QUERY_POSITION,
|
||||
&format, &position);
|
||||
res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &position);
|
||||
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
position /= GST_SECOND;
|
||||
g_print ("%s: %lld:%02lld", definition->nick, position/60, position%60);
|
||||
}
|
||||
else {
|
||||
g_print ("%s: %lld:%02lld", definition->nick, position / 60,
|
||||
position % 60);
|
||||
} else {
|
||||
g_print ("%s: %lld", definition->nick, position);
|
||||
}
|
||||
|
||||
|
@ -44,7 +43,7 @@ get_position_info (GstElement *cdparanoia)
|
|||
}
|
||||
|
||||
static void
|
||||
get_track_info (GstElement *cdparanoia)
|
||||
get_track_info (GstElement * cdparanoia)
|
||||
{
|
||||
GstFormat track_format;
|
||||
gint64 total_tracks = 0, total_time = 0;
|
||||
|
@ -70,22 +69,20 @@ get_track_info (GstElement *cdparanoia)
|
|||
definition = gst_format_get_details (*formats);
|
||||
|
||||
format = *formats;
|
||||
res = gst_pad_query (pad, GST_QUERY_TOTAL,
|
||||
&format, &total);
|
||||
res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &total);
|
||||
if (res) {
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
total /= GST_SECOND;
|
||||
g_print ("%s total: %lld:%02lld\n", definition->nick, total/60, total%60);
|
||||
}
|
||||
else
|
||||
g_print ("%s total: %lld:%02lld\n", definition->nick, total / 60,
|
||||
total % 60);
|
||||
} else
|
||||
g_print ("%s total: %lld\n", definition->nick, total);
|
||||
|
||||
if (format == track_format)
|
||||
total_tracks = total;
|
||||
else if (format == GST_FORMAT_TIME)
|
||||
total_time = total;
|
||||
}
|
||||
else
|
||||
} else
|
||||
g_print ("failed to get %s total\n", definition->nick);
|
||||
|
||||
formats++;
|
||||
|
@ -102,11 +99,9 @@ get_track_info (GstElement *cdparanoia)
|
|||
GstFormat format;
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
res = gst_pad_convert (pad, track_format, i,
|
||||
&format, &time);
|
||||
res = gst_pad_convert (pad, track_format, i, &format, &time);
|
||||
time /= GST_SECOND;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
time = total_time;
|
||||
res = TRUE;
|
||||
}
|
||||
|
@ -118,13 +113,11 @@ get_track_info (GstElement *cdparanoia)
|
|||
gint64 length = time - time_count;
|
||||
|
||||
g_print ("track %d: %lld:%02lld -> %lld:%02lld, length: %lld:%02lld\n",
|
||||
i-1,
|
||||
i - 1,
|
||||
time_count / 60, time_count % 60,
|
||||
time / 60, time % 60,
|
||||
length / 60, length % 60);
|
||||
time / 60, time % 60, length / 60, length % 60);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("could not get time for track %d\n", i);
|
||||
}
|
||||
|
||||
|
@ -177,9 +170,7 @@ main (int argc, char **argv)
|
|||
g_print ("playing from track 3\n");
|
||||
/* seek to track3 */
|
||||
event = gst_event_new_seek (track_format |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH,
|
||||
3);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, 3);
|
||||
|
||||
res = gst_pad_send_event (pad, event);
|
||||
if (!res)
|
||||
|
@ -199,8 +190,7 @@ main (int argc, char **argv)
|
|||
/* seek to some seconds */
|
||||
event = gst_event_new_segment_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH,
|
||||
25 * GST_SECOND, 29 * GST_SECOND);
|
||||
GST_SEEK_FLAG_FLUSH, 25 * GST_SECOND, 29 * GST_SECOND);
|
||||
res = gst_pad_send_event (pad, event);
|
||||
if (!res)
|
||||
g_warning ("seek failed");
|
||||
|
|
|
@ -15,7 +15,7 @@ static guint update_id;
|
|||
|
||||
#define UPDATE_INTERVAL 500
|
||||
|
||||
static GstElement*
|
||||
static GstElement *
|
||||
make_cdaudio_pipeline (void)
|
||||
{
|
||||
GstElement *cdaudio;
|
||||
|
@ -28,9 +28,8 @@ make_cdaudio_pipeline (void)
|
|||
return cdaudio;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
format_value (GtkScale *scale,
|
||||
gdouble value)
|
||||
static gchar *
|
||||
format_value (GtkScale * scale, gdouble value)
|
||||
{
|
||||
gint64 real;
|
||||
gint64 seconds;
|
||||
|
@ -41,9 +40,7 @@ format_value (GtkScale *scale,
|
|||
subseconds = (gint64) real / (GST_SECOND / 100);
|
||||
|
||||
return g_strdup_printf ("%02lld:%02lld:%02lld",
|
||||
seconds/60,
|
||||
seconds%60,
|
||||
subseconds%100);
|
||||
seconds / 60, seconds % 60, subseconds % 100);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -52,13 +49,12 @@ typedef struct
|
|||
const GstFormat format;
|
||||
} seek_format;
|
||||
|
||||
static seek_format seek_formats[] =
|
||||
{
|
||||
{ "tim", GST_FORMAT_TIME },
|
||||
{ "byt", GST_FORMAT_BYTES },
|
||||
{ "buf", GST_FORMAT_BUFFERS },
|
||||
{ "def", GST_FORMAT_DEFAULT },
|
||||
{ NULL, 0 },
|
||||
static seek_format seek_formats[] = {
|
||||
{"tim", GST_FORMAT_TIME},
|
||||
{"byt", GST_FORMAT_BYTES},
|
||||
{"buf", GST_FORMAT_BUFFERS},
|
||||
{"def", GST_FORMAT_DEFAULT},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
|
||||
|
@ -81,8 +77,7 @@ query_durations ()
|
|||
res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -111,8 +106,7 @@ query_positions ()
|
|||
res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -134,6 +128,7 @@ update_scale (gpointer data)
|
|||
|
||||
if (seekable_elements) {
|
||||
GstElement *element = GST_ELEMENT (seekable_elements->data);
|
||||
|
||||
gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
|
||||
}
|
||||
if (clock)
|
||||
|
@ -141,7 +136,8 @@ update_scale (gpointer data)
|
|||
|
||||
if (stats) {
|
||||
if (clock)
|
||||
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
|
||||
g_print ("clock: %13llu (%s)\n", position,
|
||||
gst_object_get_name (GST_OBJECT (clock)));
|
||||
query_durations ();
|
||||
query_positions ();
|
||||
}
|
||||
|
@ -167,7 +163,7 @@ iterate (gpointer data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||
gtk_timeout_remove (update_id);
|
||||
|
@ -176,7 +172,7 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
|
||||
gboolean res;
|
||||
|
@ -188,8 +184,7 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
|
||||
g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable));
|
||||
s_event = gst_event_new_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH, real);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, real);
|
||||
|
||||
res = gst_element_send_event (seekable, s_event);
|
||||
|
||||
|
@ -199,7 +194,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -211,7 +207,8 @@ play_cb (GtkButton * button, gpointer data)
|
|||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,10 +234,9 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *hbox, *vbox,
|
||||
*play_button, *pause_button, *stop_button,
|
||||
*hscale;
|
||||
*play_button, *pause_button, *stop_button, *hscale;
|
||||
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},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
@ -250,8 +246,10 @@ main (int argc, char **argv)
|
|||
|
||||
pipeline = make_cdaudio_pipeline ();
|
||||
|
||||
g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
|
||||
g_signal_connect (pipeline, "deep_notify",
|
||||
G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
|
||||
NULL);
|
||||
|
||||
/* initialize gui elements ... */
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
@ -261,16 +259,17 @@ main (int argc, char **argv)
|
|||
pause_button = gtk_button_new_with_label ("pause");
|
||||
stop_button = gtk_button_new_with_label ("stop");
|
||||
|
||||
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
adjustment =
|
||||
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
hscale = gtk_hscale_new (adjustment);
|
||||
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
|
||||
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"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);
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"format_value", G_CALLBACK (format_value), pipeline);
|
||||
|
||||
/* do the packing stuff ... */
|
||||
|
@ -283,9 +282,12 @@ main (int argc, char **argv)
|
|||
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
|
||||
|
||||
/* connect things ... */
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
|
||||
|
||||
/* show the gui. */
|
||||
|
|
|
@ -31,20 +31,19 @@ typedef struct
|
|||
} dyn_link;
|
||||
|
||||
static GstElement *
|
||||
gst_element_factory_make_or_warn (gchar *type, gchar *name)
|
||||
gst_element_factory_make_or_warn (gchar * type, gchar * name)
|
||||
{
|
||||
GstElement *element = gst_element_factory_make (type, name);
|
||||
|
||||
if (!element) {
|
||||
g_warning ("Failed to create element %s of type %s",
|
||||
name, type);
|
||||
g_warning ("Failed to create element %s of type %s", name, type);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
static void
|
||||
dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
|
||||
dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
|
||||
{
|
||||
dyn_link *connect = (dyn_link *) data;
|
||||
|
||||
|
@ -60,7 +59,8 @@ dynamic_link (GstPadTemplate *templ, GstPad *newpad, gpointer data)
|
|||
}
|
||||
|
||||
static void
|
||||
setup_dynamic_link (GstElement *element, const gchar *padname, GstPad *target, GstElement *bin)
|
||||
setup_dynamic_link (GstElement * element, const gchar * padname,
|
||||
GstPad * target, GstElement * bin)
|
||||
{
|
||||
dyn_link *connect;
|
||||
|
||||
|
@ -69,11 +69,12 @@ setup_dynamic_link (GstElement *element, const gchar *padname, GstPad *target, G
|
|||
connect->target = target;
|
||||
connect->bin = bin;
|
||||
|
||||
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link), connect);
|
||||
g_signal_connect (G_OBJECT (element), "new_pad", G_CALLBACK (dynamic_link),
|
||||
connect);
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mod_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_mod_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink;
|
||||
|
@ -103,8 +104,8 @@ make_mod_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_dv_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_dv_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink, *videosink;
|
||||
|
@ -140,8 +141,8 @@ make_dv_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_wav_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_wav_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink;
|
||||
|
@ -171,8 +172,8 @@ make_wav_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_flac_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_flac_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink;
|
||||
|
@ -202,8 +203,8 @@ make_flac_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_sid_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_sid_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink;
|
||||
|
@ -233,8 +234,8 @@ make_sid_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_parse_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_parse_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *parser, *fakesink;
|
||||
|
@ -265,8 +266,8 @@ make_parse_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_vorbis_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_vorbis_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink;
|
||||
|
@ -296,8 +297,8 @@ make_vorbis_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mp3_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_mp3_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *osssink, *queue, *audio_thread;
|
||||
|
@ -335,12 +336,13 @@ make_mp3_pipeline (const gchar *location)
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_avi_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_avi_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline, *audio_bin, *video_bin;
|
||||
GstElement *src, *demux, *a_decoder, *v_decoder, *audiosink, *videosink;
|
||||
GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue = NULL, *video_thread = NULL;
|
||||
GstElement *a_queue = NULL, *audio_thread = NULL, *v_queue =
|
||||
NULL, *video_thread = NULL;
|
||||
GstPad *seekable;
|
||||
|
||||
pipeline = gst_pipeline_new ("app");
|
||||
|
@ -369,12 +371,14 @@ make_avi_pipeline (const gchar *location)
|
|||
gst_bin_add (GST_BIN (audio_thread), audiosink);
|
||||
gst_element_set_state (audio_bin, GST_STATE_PAUSED);
|
||||
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
|
||||
"sink"), audio_bin);
|
||||
|
||||
seekable = gst_element_get_pad (a_queue, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
|
||||
video_bin = gst_bin_new ("v_decoder_bin");
|
||||
//v_decoder = gst_element_factory_make_or_warn ("identity", "v_dec");
|
||||
|
@ -395,18 +399,20 @@ make_avi_pipeline (const gchar *location)
|
|||
|
||||
gst_element_set_state (video_bin, GST_STATE_PAUSED);
|
||||
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
|
||||
"sink"), video_bin);
|
||||
|
||||
seekable = gst_element_get_pad (v_queue, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mpeg_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_mpeg_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline, *audio_bin, *video_bin;
|
||||
GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
|
||||
|
@ -441,12 +447,14 @@ make_mpeg_pipeline (const gchar *location)
|
|||
gst_bin_add (GST_BIN (audio_thread), a_queue);
|
||||
gst_bin_add (GST_BIN (audio_thread), audiosink);
|
||||
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
|
||||
"sink"), audio_bin);
|
||||
|
||||
seekable = gst_element_get_pad (a_queue, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
|
||||
video_bin = gst_bin_new ("v_decoder_bin");
|
||||
v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
|
||||
|
@ -461,18 +469,20 @@ make_mpeg_pipeline (const gchar *location)
|
|||
gst_bin_add_many (GST_BIN (video_bin), v_decoder, video_thread, NULL);
|
||||
gst_bin_add_many (GST_BIN (video_thread), v_queue, v_filter, videosink, NULL);
|
||||
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
|
||||
"sink"), video_bin);
|
||||
|
||||
seekable = gst_element_get_pad (v_queue, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_mpegnt_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_mpegnt_pipeline (const gchar * location)
|
||||
{
|
||||
GstElement *pipeline, *audio_bin, *video_bin;
|
||||
GstElement *src, *demux, *a_decoder, *v_decoder, *v_filter;
|
||||
|
@ -508,12 +518,14 @@ make_mpegnt_pipeline (const gchar *location)
|
|||
gst_bin_add (GST_BIN (audio_thread), a_queue);
|
||||
gst_bin_add (GST_BIN (audio_thread), audiosink);
|
||||
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder, "sink"), audio_bin);
|
||||
setup_dynamic_link (demux, "audio_00", gst_element_get_pad (a_decoder,
|
||||
"sink"), audio_bin);
|
||||
|
||||
seekable = gst_element_get_pad (a_queue, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (a_decoder, "sink"));
|
||||
|
||||
video_bin = gst_bin_new ("v_decoder_bin");
|
||||
v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec");
|
||||
|
@ -523,25 +535,26 @@ make_mpegnt_pipeline (const gchar *location)
|
|||
|
||||
gst_bin_add_many (GST_BIN (video_bin), v_decoder, v_filter, videosink, NULL);
|
||||
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder, "sink"), video_bin);
|
||||
setup_dynamic_link (demux, "video_00", gst_element_get_pad (v_decoder,
|
||||
"sink"), video_bin);
|
||||
|
||||
seekable = gst_element_get_pad (v_decoder, "src");
|
||||
seekable_pads = g_list_prepend (seekable_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, seekable);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (v_decoder, "sink"));
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static GstElement*
|
||||
make_playerbin_pipeline (const gchar *location)
|
||||
static GstElement *
|
||||
make_playerbin_pipeline (const gchar * location)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
format_value (GtkScale *scale,
|
||||
gdouble value)
|
||||
static gchar *
|
||||
format_value (GtkScale * scale, gdouble value)
|
||||
{
|
||||
gint64 real;
|
||||
gint64 seconds;
|
||||
|
@ -552,9 +565,7 @@ format_value (GtkScale *scale,
|
|||
subseconds = (gint64) real / (GST_SECOND / 100);
|
||||
|
||||
return g_strdup_printf ("%02lld:%02lld:%02lld",
|
||||
seconds/60,
|
||||
seconds%60,
|
||||
subseconds%100);
|
||||
seconds / 60, seconds % 60, subseconds % 100);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -563,13 +574,12 @@ typedef struct
|
|||
const GstFormat format;
|
||||
} seek_format;
|
||||
|
||||
static seek_format seek_formats[] =
|
||||
{
|
||||
{ "tim", GST_FORMAT_TIME },
|
||||
{ "byt", GST_FORMAT_BYTES },
|
||||
{ "buf", GST_FORMAT_BUFFERS },
|
||||
{ "def", GST_FORMAT_DEFAULT },
|
||||
{ NULL, 0 },
|
||||
static seek_format seek_formats[] = {
|
||||
{"tim", GST_FORMAT_TIME},
|
||||
{"byt", GST_FORMAT_BYTES},
|
||||
{"buf", GST_FORMAT_BUFFERS},
|
||||
{"def", GST_FORMAT_DEFAULT},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
|
@ -588,12 +598,9 @@ query_rates (void)
|
|||
|
||||
format = seek_formats[i].format;
|
||||
|
||||
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND,
|
||||
&format, &value))
|
||||
{
|
||||
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
|
||||
|
@ -624,8 +631,7 @@ query_durations ()
|
|||
res = gst_pad_query (pad, GST_QUERY_TOTAL, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -655,8 +661,7 @@ query_positions ()
|
|||
res = gst_pad_query (pad, GST_QUERY_POSITION, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -679,12 +684,14 @@ update_scale (gpointer data)
|
|||
|
||||
if (seekable_pads) {
|
||||
GstPad *pad = GST_PAD (seekable_pads->data);
|
||||
|
||||
gst_pad_query (pad, GST_QUERY_TOTAL, &format, &duration);
|
||||
}
|
||||
position = gst_clock_get_time (clock);
|
||||
|
||||
if (stats) {
|
||||
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
|
||||
g_print ("clock: %13llu (%s)\n", position,
|
||||
gst_object_get_name (GST_OBJECT (clock)));
|
||||
query_durations ();
|
||||
query_positions ();
|
||||
query_rates ();
|
||||
|
@ -711,7 +718,7 @@ iterate (gpointer data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||
gtk_timeout_remove (update_id);
|
||||
|
@ -720,20 +727,22 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
|
||||
gboolean res;
|
||||
GstEvent *s_event;
|
||||
|
||||
#ifdef PAD_SEEK
|
||||
GList *walk = seekable_pads;
|
||||
|
||||
while (walk) {
|
||||
GstPad *seekable = GST_PAD (walk->data);
|
||||
|
||||
g_print ("seek to %lld on pad %s:%s\n", real, GST_DEBUG_PAD_NAME (seekable));
|
||||
s_event = gst_event_new_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
g_print ("seek to %lld on pad %s:%s\n", real,
|
||||
GST_DEBUG_PAD_NAME (seekable));
|
||||
s_event =
|
||||
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH, real);
|
||||
|
||||
res = gst_pad_send_event (seekable, s_event);
|
||||
|
@ -746,9 +755,10 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
while (walk) {
|
||||
GstElement *seekable = GST_ELEMENT (walk->data);
|
||||
|
||||
g_print ("seek to %lld on element %s\n", real, gst_element_get_name (seekable));
|
||||
s_event = gst_event_new_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
g_print ("seek to %lld on element %s\n", real,
|
||||
gst_element_get_name (seekable));
|
||||
s_event =
|
||||
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH, real);
|
||||
|
||||
res = gst_element_send_event (seekable, s_event);
|
||||
|
@ -759,7 +769,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -770,7 +781,8 @@ play_cb (GtkButton * button, gpointer data)
|
|||
if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) {
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,23 +807,23 @@ stop_cb (GtkButton * button, gpointer data)
|
|||
typedef struct
|
||||
{
|
||||
gchar *name;
|
||||
GstElement* (*func) (const gchar *location);
|
||||
GstElement *(*func) (const gchar * location);
|
||||
} Pipeline;
|
||||
|
||||
static Pipeline pipelines[] = {
|
||||
{ "mp3", make_mp3_pipeline },
|
||||
{ "avi", make_avi_pipeline },
|
||||
{ "mpeg1", make_mpeg_pipeline },
|
||||
{ "mpegparse", make_parse_pipeline },
|
||||
{ "vorbis", make_vorbis_pipeline },
|
||||
{ "sid", make_sid_pipeline },
|
||||
{ "flac", make_flac_pipeline },
|
||||
{ "wav", make_wav_pipeline },
|
||||
{ "mod", make_mod_pipeline },
|
||||
{ "dv", make_dv_pipeline },
|
||||
{ "mpeg1nothreads", make_mpegnt_pipeline },
|
||||
{ "playerbin", make_playerbin_pipeline },
|
||||
{ NULL, NULL},
|
||||
{"mp3", make_mp3_pipeline},
|
||||
{"avi", make_avi_pipeline},
|
||||
{"mpeg1", make_mpeg_pipeline},
|
||||
{"mpegparse", make_parse_pipeline},
|
||||
{"vorbis", make_vorbis_pipeline},
|
||||
{"sid", make_sid_pipeline},
|
||||
{"flac", make_flac_pipeline},
|
||||
{"wav", make_wav_pipeline},
|
||||
{"mod", make_mod_pipeline},
|
||||
{"dv", make_dv_pipeline},
|
||||
{"mpeg1nothreads", make_mpegnt_pipeline},
|
||||
{"playerbin", make_playerbin_pipeline},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
#define NUM_TYPES ((sizeof (pipelines) / sizeof (Pipeline)) - 1)
|
||||
|
@ -833,11 +845,10 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *hbox, *vbox,
|
||||
*play_button, *pause_button, *stop_button,
|
||||
*hscale;
|
||||
*play_button, *pause_button, *stop_button, *hscale;
|
||||
struct poptOption options[] = {
|
||||
{ "stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
|
||||
"Show pad stats", NULL },
|
||||
{"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
|
||||
"Show pad stats", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
gint type;
|
||||
|
@ -868,16 +879,17 @@ main (int argc, char **argv)
|
|||
pause_button = gtk_button_new_with_label ("pause");
|
||||
stop_button = gtk_button_new_with_label ("stop");
|
||||
|
||||
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
adjustment =
|
||||
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
hscale = gtk_hscale_new (adjustment);
|
||||
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
|
||||
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"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);
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"format_value", G_CALLBACK (format_value), pipeline);
|
||||
|
||||
/* do the packing stuff ... */
|
||||
|
@ -890,16 +902,21 @@ main (int argc, char **argv)
|
|||
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
|
||||
|
||||
/* connect things ... */
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
|
||||
|
||||
/* show the gui. */
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
g_signal_connect (pipeline, "deep_notify", G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), NULL);
|
||||
g_signal_connect (pipeline, "deep_notify",
|
||||
G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
|
||||
NULL);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
|
|
|
@ -19,16 +19,16 @@ static guint update_id;
|
|||
|
||||
#define UPDATE_INTERVAL 500
|
||||
|
||||
static GstElement*
|
||||
make_spider_pipeline (const gchar *location, gboolean thread)
|
||||
static GstElement *
|
||||
make_spider_pipeline (const gchar * location, gboolean thread)
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *src, *decoder, *audiosink, *videosink, *a_thread, *v_thread, *a_queue, *v_queue;
|
||||
GstElement *src, *decoder, *audiosink, *videosink, *a_thread, *v_thread,
|
||||
*a_queue, *v_queue;
|
||||
|
||||
if (thread) {
|
||||
pipeline = gst_thread_new ("app");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pipeline = gst_pipeline_new ("app");
|
||||
}
|
||||
|
||||
|
@ -64,15 +64,16 @@ make_spider_pipeline (const gchar *location, gboolean thread)
|
|||
|
||||
seekable_elements = g_list_prepend (seekable_elements, videosink);
|
||||
seekable_elements = g_list_prepend (seekable_elements, audiosink);
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (audiosink, "sink"));
|
||||
rate_pads = g_list_prepend (rate_pads, gst_element_get_pad (videosink, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (audiosink, "sink"));
|
||||
rate_pads =
|
||||
g_list_prepend (rate_pads, gst_element_get_pad (videosink, "sink"));
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
format_value (GtkScale *scale,
|
||||
gdouble value)
|
||||
static gchar *
|
||||
format_value (GtkScale * scale, gdouble value)
|
||||
{
|
||||
gint64 real;
|
||||
gint64 seconds;
|
||||
|
@ -83,9 +84,7 @@ format_value (GtkScale *scale,
|
|||
subseconds = (gint64) real / (GST_SECOND / 100);
|
||||
|
||||
return g_strdup_printf ("%02lld:%02lld:%02lld",
|
||||
seconds/60,
|
||||
seconds%60,
|
||||
subseconds%100);
|
||||
seconds / 60, seconds % 60, subseconds % 100);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -94,13 +93,12 @@ typedef struct
|
|||
const GstFormat format;
|
||||
} seek_format;
|
||||
|
||||
static seek_format seek_formats[] =
|
||||
{
|
||||
{ "tim", GST_FORMAT_TIME },
|
||||
{ "byt", GST_FORMAT_BYTES },
|
||||
{ "buf", GST_FORMAT_BUFFERS },
|
||||
{ "def", GST_FORMAT_DEFAULT },
|
||||
{ NULL, 0 },
|
||||
static seek_format seek_formats[] = {
|
||||
{"tim", GST_FORMAT_TIME},
|
||||
{"byt", GST_FORMAT_BYTES},
|
||||
{"buf", GST_FORMAT_BUFFERS},
|
||||
{"def", GST_FORMAT_DEFAULT},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
|
@ -119,12 +117,9 @@ query_rates (void)
|
|||
|
||||
format = seek_formats[i].format;
|
||||
|
||||
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND,
|
||||
&format, &value))
|
||||
{
|
||||
if (gst_pad_convert (pad, GST_FORMAT_TIME, GST_SECOND, &format, &value)) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
|
||||
|
@ -155,8 +150,7 @@ query_durations ()
|
|||
res = gst_element_query (element, GST_QUERY_TOTAL, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -185,8 +179,7 @@ query_positions ()
|
|||
res = gst_element_query (element, GST_QUERY_POSITION, &format, &value);
|
||||
if (res) {
|
||||
g_print ("%s %13lld | ", seek_formats[i].name, value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_print ("%s %13.13s | ", seek_formats[i].name, "*NA*");
|
||||
}
|
||||
i++;
|
||||
|
@ -208,12 +201,14 @@ update_scale (gpointer data)
|
|||
|
||||
if (seekable_elements) {
|
||||
GstElement *element = GST_ELEMENT (seekable_elements->data);
|
||||
|
||||
gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
|
||||
}
|
||||
position = gst_clock_get_time (clock);
|
||||
|
||||
if (stats) {
|
||||
g_print ("clock: %13llu (%s)\n", position, gst_object_get_name (GST_OBJECT (clock)));
|
||||
g_print ("clock: %13llu (%s)\n", position,
|
||||
gst_object_get_name (GST_OBJECT (clock)));
|
||||
query_durations ();
|
||||
query_positions ();
|
||||
query_rates ();
|
||||
|
@ -239,7 +234,7 @@ iterate (gpointer data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||
gtk_timeout_remove (update_id);
|
||||
|
@ -248,7 +243,7 @@ start_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
|
||||
gboolean res;
|
||||
|
@ -260,8 +255,7 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
|
||||
g_print ("seek to %lld on element %s\n", real, GST_ELEMENT_NAME (seekable));
|
||||
s_event = gst_event_new_seek (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH, real);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, real);
|
||||
|
||||
res = gst_element_send_event (seekable, s_event);
|
||||
|
||||
|
@ -271,7 +265,8 @@ stop_seek (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
|||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -283,7 +278,8 @@ play_cb (GtkButton * button, gpointer data)
|
|||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
if (!GST_FLAG_IS_SET (pipeline, GST_BIN_SELF_SCHEDULABLE))
|
||||
gtk_idle_add ((GtkFunction) iterate, pipeline);
|
||||
update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
update_id =
|
||||
gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,13 +305,12 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *hbox, *vbox,
|
||||
*play_button, *pause_button, *stop_button,
|
||||
*hscale;
|
||||
*play_button, *pause_button, *stop_button, *hscale;
|
||||
gboolean threaded = FALSE;
|
||||
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},
|
||||
{"stats", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &stats, 0,
|
||||
{"stats", 's', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &stats, 0,
|
||||
"Show element stats", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
@ -338,16 +333,17 @@ main (int argc, char **argv)
|
|||
pause_button = gtk_button_new_with_label ("pause");
|
||||
stop_button = gtk_button_new_with_label ("stop");
|
||||
|
||||
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
adjustment =
|
||||
GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
|
||||
hscale = gtk_hscale_new (adjustment);
|
||||
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
|
||||
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"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);
|
||||
gtk_signal_connect(GTK_OBJECT(hscale),
|
||||
gtk_signal_connect (GTK_OBJECT (hscale),
|
||||
"format_value", G_CALLBACK (format_value), pipeline);
|
||||
|
||||
/* do the packing stuff ... */
|
||||
|
@ -360,9 +356,12 @@ main (int argc, char **argv)
|
|||
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
|
||||
|
||||
/* connect things ... */
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), pipeline);
|
||||
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
|
||||
pipeline);
|
||||
g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
|
||||
|
||||
/* show the gui. */
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
static gboolean ready = FALSE;
|
||||
|
||||
struct probe_context {
|
||||
struct probe_context
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GstElement *element;
|
||||
GstPad *pad;
|
||||
|
@ -18,20 +19,22 @@ struct probe_context {
|
|||
};
|
||||
|
||||
static void
|
||||
print_caps (GstCaps *caps)
|
||||
print_caps (GstCaps * caps)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = gst_caps_to_string (caps);
|
||||
g_print(" %s\n", s);
|
||||
g_print (" %s\n", s);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
static void
|
||||
print_format (GstCaps *caps)
|
||||
print_format (GstCaps * caps)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = gst_caps_to_string (caps);
|
||||
g_print(" format: %s\n", s);
|
||||
g_print (" format: %s\n", s);
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
|
@ -62,34 +65,30 @@ print_lbs_info (struct probe_context *context, gint stream)
|
|||
|
||||
/* get start and end position of this stream */
|
||||
res = gst_pad_convert (context->pad,
|
||||
context->ls_format, stream,
|
||||
&format, &value_start);
|
||||
context->ls_format, stream, &format, &value_start);
|
||||
res &= gst_pad_convert (context->pad,
|
||||
context->ls_format, stream + 1,
|
||||
&format, &value_end);
|
||||
context->ls_format, stream + 1, &format, &value_end);
|
||||
|
||||
if (res) {
|
||||
/* substract to get the length */
|
||||
value_end -= value_start;
|
||||
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
value_end /= (GST_SECOND/100);
|
||||
value_end /= (GST_SECOND / 100);
|
||||
g_print (" %s: %lld:%02lld.%02lld\n", definition->nick,
|
||||
value_end/6000, (value_end/100)%60, (value_end%100));
|
||||
}
|
||||
else {
|
||||
value_end / 6000, (value_end / 100) % 60, (value_end % 100));
|
||||
} else {
|
||||
g_print (" %s: %lld\n", definition->nick, value_end);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
g_print (" could not get logical stream %s\n", definition->nick);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deep_notify (GObject *object, GstObject *origin,
|
||||
GParamSpec *pspec, gpointer data)
|
||||
deep_notify (GObject * object, GstObject * origin,
|
||||
GParamSpec * pspec, gpointer data)
|
||||
{
|
||||
struct probe_context *context = (struct probe_context *) data;
|
||||
GValue value = { 0, };
|
||||
|
@ -99,8 +98,7 @@ deep_notify (GObject *object, GstObject *origin,
|
|||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
|
||||
context->metadata = g_value_peek_pointer (&value);
|
||||
}
|
||||
else if (!strcmp (pspec->name, "streaminfo")) {
|
||||
} else if (!strcmp (pspec->name, "streaminfo")) {
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
|
||||
|
@ -127,9 +125,7 @@ collect_logical_stream_properties (struct probe_context *context, gint stream)
|
|||
|
||||
/* seek to stream */
|
||||
event = gst_event_new_seek (context->ls_format |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH,
|
||||
stream);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, stream);
|
||||
res = gst_pad_send_event (context->pad, event);
|
||||
if (!res) {
|
||||
g_warning ("seek to logical track failed");
|
||||
|
@ -141,7 +137,8 @@ collect_logical_stream_properties (struct probe_context *context, gint stream)
|
|||
ready = FALSE;
|
||||
while (gst_bin_iterate (GST_BIN (context->pipeline)) && !ready) {
|
||||
count++;
|
||||
if (count > 10) break;
|
||||
if (count > 10)
|
||||
break;
|
||||
}
|
||||
|
||||
print_caps (context->metadata);
|
||||
|
@ -177,18 +174,16 @@ collect_stream_properties (struct probe_context *context)
|
|||
format = *formats;
|
||||
formats++;
|
||||
|
||||
res = gst_pad_query (context->pad, GST_QUERY_TOTAL,
|
||||
&format, &value);
|
||||
res = gst_pad_query (context->pad, GST_QUERY_TOTAL, &format, &value);
|
||||
|
||||
definition = gst_format_get_details (format);
|
||||
|
||||
if (res) {
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
value /= (GST_SECOND/100);
|
||||
value /= (GST_SECOND / 100);
|
||||
g_print (" total %s: %lld:%02lld.%02lld\n", definition->nick,
|
||||
value/6000, (value/100)%60, (value%100));
|
||||
}
|
||||
else {
|
||||
value / 6000, (value / 100) % 60, (value % 100));
|
||||
} else {
|
||||
if (format == context->ls_format)
|
||||
context->total_ls = value;
|
||||
g_print (" total %s: %lld\n", definition->nick, value);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *pipeline;
|
||||
GError *error = NULL;
|
||||
|
@ -46,7 +46,8 @@ main (gint argc, gchar *argv[])
|
|||
pipeline = GST_ELEMENT (gst_parse_launch (description, &error));
|
||||
if (!pipeline) {
|
||||
if (error)
|
||||
g_print ("ERROR: pipeline could not be constructed: %s\n", error->message);
|
||||
g_print ("ERROR: pipeline could not be constructed: %s\n",
|
||||
error->message);
|
||||
else
|
||||
g_print ("ERROR: pipeline could not be constructed\n");
|
||||
return -1;
|
||||
|
@ -71,12 +72,10 @@ main (gint argc, gchar *argv[])
|
|||
|
||||
format = GST_FORMAT_TIME;
|
||||
/* get the position */
|
||||
gst_pad_query (enc_src, GST_QUERY_POSITION,
|
||||
&format, &position);
|
||||
gst_pad_query (enc_src, GST_QUERY_POSITION, &format, &position);
|
||||
|
||||
/* get the total duration */
|
||||
gst_pad_query (enc_src, GST_QUERY_TOTAL,
|
||||
&format, &duration);
|
||||
gst_pad_query (enc_src, GST_QUERY_TOTAL, &format, &duration);
|
||||
|
||||
format = GST_FORMAT_BYTES;
|
||||
/* see how many bytes are genereated per 8 seconds (== bitrate) */
|
||||
|
@ -88,13 +87,11 @@ main (gint argc, gchar *argv[])
|
|||
|
||||
g_print ("[%2dm %.2ds] of [%2dm %.2ds], "
|
||||
"src avg bitrate: %lld, dest avg birate: %lld, ratio [%02.2f] \r",
|
||||
(gint)(position / (GST_SECOND * 60)),
|
||||
(gint)(position / (GST_SECOND)) % 60,
|
||||
(gint)(duration / (GST_SECOND * 60)),
|
||||
(gint)(duration / (GST_SECOND)) % 60,
|
||||
bitrate_dec,
|
||||
bitrate_enc,
|
||||
(gfloat)bitrate_dec/bitrate_enc);
|
||||
(gint) (position / (GST_SECOND * 60)),
|
||||
(gint) (position / (GST_SECOND)) % 60,
|
||||
(gint) (duration / (GST_SECOND * 60)),
|
||||
(gint) (duration / (GST_SECOND)) % 60,
|
||||
bitrate_dec, bitrate_enc, (gfloat) bitrate_dec / bitrate_enc);
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
|
|
|
@ -28,34 +28,32 @@ static GMainLoop *loop = NULL;
|
|||
|
||||
|
||||
static void
|
||||
got_eos (GstElement *pipeline)
|
||||
got_eos (GstElement * pipeline)
|
||||
{
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_iterate (GstElement *pipeline)
|
||||
idle_iterate (GstElement * pipeline)
|
||||
{
|
||||
gst_bin_iterate (GST_BIN (pipeline));
|
||||
return (GST_STATE (GST_ELEMENT (pipeline)) == GST_STATE_PLAYING);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
switch_timer (GstElement *video_switch)
|
||||
switch_timer (GstElement * video_switch)
|
||||
{
|
||||
gint nb_sources, active_source;
|
||||
|
||||
g_object_get (G_OBJECT (video_switch), "nb_sources", &nb_sources, NULL);
|
||||
g_object_get (G_OBJECT (video_switch), "active_source",
|
||||
&active_source, NULL);
|
||||
g_object_get (G_OBJECT (video_switch), "active_source", &active_source, NULL);
|
||||
|
||||
active_source ++;
|
||||
active_source++;
|
||||
|
||||
if (active_source > nb_sources - 1)
|
||||
active_source = 0;
|
||||
|
||||
g_object_set (G_OBJECT (video_switch), "active_source",
|
||||
active_source, NULL);
|
||||
g_object_set (G_OBJECT (video_switch), "active_source", active_source, NULL);
|
||||
|
||||
g_message ("current number of sources : %d, active source %d",
|
||||
nb_sources, active_source);
|
||||
|
@ -88,8 +86,7 @@ main (int argc, char *argv[])
|
|||
gst_element_link (src2, video_switch);
|
||||
gst_element_link (video_switch, video_sink);
|
||||
|
||||
g_signal_connect (G_OBJECT (pipeline), "eos",
|
||||
G_CALLBACK (got_eos), NULL);
|
||||
g_signal_connect (G_OBJECT (pipeline), "eos", G_CALLBACK (got_eos), NULL);
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -84,22 +84,22 @@ GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
|
|||
#define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10)
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa))
|
||||
#define GST_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA, GstAlsaClass))
|
||||
#define GST_ALSA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ALSA, GstAlsaClass))
|
||||
#define GST_IS_ALSA(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA))
|
||||
#define GST_IS_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA))
|
||||
#define GST_TYPE_ALSA (gst_alsa_get_type())
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST,
|
||||
GST_ALSA_RUNNING,
|
||||
GST_ALSA_CAPS_NEGO,
|
||||
GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_ALSA_CAPS_PAUSE = 0,
|
||||
GST_ALSA_CAPS_RESUME,
|
||||
GST_ALSA_CAPS_SYNC_START
|
||||
|
@ -118,27 +118,30 @@ typedef struct _GstAlsaClockClass GstAlsaClockClass;
|
|||
typedef struct _GstAlsa GstAlsa;
|
||||
typedef struct _GstAlsaClass GstAlsaClass;
|
||||
|
||||
typedef int (*GstAlsaTransmitFunction) (GstAlsa *this, snd_pcm_sframes_t *avail);
|
||||
typedef int (*GstAlsaTransmitFunction) (GstAlsa * this,
|
||||
snd_pcm_sframes_t * avail);
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
snd_pcm_format_t format;
|
||||
guint rate;
|
||||
gint channels;
|
||||
} GstAlsaFormat;
|
||||
|
||||
struct _GstAlsa {
|
||||
struct _GstAlsa
|
||||
{
|
||||
GstElement parent;
|
||||
|
||||
/* array of GstAlsaPads */
|
||||
GstPad * pad[GST_ALSA_MAX_TRACKS];
|
||||
GstPad *pad[GST_ALSA_MAX_TRACKS];
|
||||
|
||||
gchar * device;
|
||||
snd_pcm_t * handle;
|
||||
snd_pcm_info_t * info;
|
||||
gchar *device;
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_info_t *info;
|
||||
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
|
||||
snd_output_t * out;
|
||||
snd_output_t *out;
|
||||
|
||||
GstAlsaFormat * format; /* NULL if undefined */
|
||||
GstAlsaFormat *format; /* NULL if undefined */
|
||||
gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */
|
||||
GstAlsaTransmitFunction transmit;
|
||||
|
||||
|
@ -149,7 +152,7 @@ struct _GstAlsa {
|
|||
gboolean autorecover;
|
||||
|
||||
/* clocking */
|
||||
GstAlsaClock * clock; /* our provided clock */
|
||||
GstAlsaClock *clock; /* our provided clock */
|
||||
snd_pcm_uframes_t transmitted; /* samples transmitted since last sync
|
||||
This thing actually is our master clock.
|
||||
We will event insert silent samples or
|
||||
|
@ -160,7 +163,8 @@ struct _GstAlsa {
|
|||
*/
|
||||
};
|
||||
|
||||
struct _GstAlsaClass {
|
||||
struct _GstAlsaClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
snd_pcm_stream_t stream;
|
||||
|
@ -176,14 +180,10 @@ struct _GstAlsaClass {
|
|||
GType gst_alsa_get_type (void);
|
||||
|
||||
void gst_alsa_set_eos (GstAlsa * this);
|
||||
GstPadLinkReturn gst_alsa_link (GstPad * pad,
|
||||
const GstCaps * caps);
|
||||
GstCaps * gst_alsa_get_caps (GstPad * pad);
|
||||
GstCaps * gst_alsa_fixate (GstPad * pad,
|
||||
const GstCaps * caps);
|
||||
GstCaps * gst_alsa_caps (snd_pcm_format_t format,
|
||||
gint rate,
|
||||
gint channels);
|
||||
GstPadLinkReturn gst_alsa_link (GstPad * pad, const GstCaps * caps);
|
||||
GstCaps *gst_alsa_get_caps (GstPad * pad);
|
||||
GstCaps *gst_alsa_fixate (GstPad * pad, const GstCaps * caps);
|
||||
GstCaps *gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels);
|
||||
|
||||
/* audio processing functions */
|
||||
inline snd_pcm_sframes_t gst_alsa_update_avail (GstAlsa * this);
|
||||
|
@ -200,11 +200,8 @@ inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this,
|
|||
guint bytes);
|
||||
inline guint gst_alsa_samples_to_bytes (GstAlsa * this,
|
||||
snd_pcm_uframes_t samples);
|
||||
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this,
|
||||
guint bytes);
|
||||
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this,
|
||||
GstClockTime time);
|
||||
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this, guint bytes);
|
||||
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this, GstClockTime time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_H__ */
|
||||
|
|
|
@ -26,18 +26,17 @@
|
|||
#include "gstalsaclock.h"
|
||||
|
||||
/* clock functions */
|
||||
static void gst_alsa_clock_class_init (gpointer g_class,
|
||||
gpointer class_data);
|
||||
static void gst_alsa_clock_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_alsa_clock_init (GstAlsaClock * clock);
|
||||
|
||||
static GstClockTime gst_alsa_clock_get_internal_time (GstClock * clock);
|
||||
static guint64 gst_alsa_clock_get_resolution (GstClock * clock);
|
||||
static GstClockEntryStatus gst_alsa_clock_wait (GstClock * clock,
|
||||
GstClockEntry * entry);
|
||||
static void gst_alsa_clock_unlock (GstClock * clock,
|
||||
GstClockEntry * entry);
|
||||
static void gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry);
|
||||
|
||||
static GstClockClass *clock_parent_class = NULL;
|
||||
|
||||
static GstClockClass * clock_parent_class = NULL;
|
||||
/* static guint gst_alsa_clock_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
GType
|
||||
|
@ -72,9 +71,9 @@ gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
|
|||
GstAlsaClockClass *klass;
|
||||
|
||||
klass = (GstAlsaClockClass *) g_class;
|
||||
gobject_class = (GObjectClass*) klass;
|
||||
gstobject_class = (GstObjectClass*) klass;
|
||||
gstclock_class = (GstClockClass*) klass;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstobject_class = (GstObjectClass *) klass;
|
||||
gstclock_class = (GstClockClass *) klass;
|
||||
|
||||
clock_parent_class = g_type_class_ref (GST_TYPE_CLOCK);
|
||||
|
||||
|
@ -84,16 +83,19 @@ gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
|
|||
gstclock_class->unlock = gst_alsa_clock_unlock;
|
||||
}
|
||||
static void
|
||||
gst_alsa_clock_init (GstAlsaClock *clock)
|
||||
gst_alsa_clock_init (GstAlsaClock * clock)
|
||||
{
|
||||
gst_object_set_name (GST_OBJECT (clock), "GstAlsaClock");
|
||||
|
||||
clock->start_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
GstAlsaClock*
|
||||
gst_alsa_clock_new (gchar *name, GstAlsaClockGetTimeFunc get_time, GstAlsa *owner)
|
||||
|
||||
GstAlsaClock *
|
||||
gst_alsa_clock_new (gchar * name, GstAlsaClockGetTimeFunc get_time,
|
||||
GstAlsa * owner)
|
||||
{
|
||||
GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
|
||||
GstAlsaClock *alsa_clock =
|
||||
GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
|
||||
|
||||
g_assert (alsa_clock);
|
||||
|
||||
|
@ -106,8 +108,9 @@ gst_alsa_clock_new (gchar *name, GstAlsaClockGetTimeFunc get_time, GstAlsa *owne
|
|||
|
||||
return alsa_clock;
|
||||
}
|
||||
|
||||
void
|
||||
gst_alsa_clock_start (GstAlsaClock *clock)
|
||||
gst_alsa_clock_start (GstAlsaClock * clock)
|
||||
{
|
||||
g_assert (!GST_CLOCK_TIME_IS_VALID (clock->start_time));
|
||||
|
||||
|
@ -119,18 +122,22 @@ gst_alsa_clock_start (GstAlsaClock *clock)
|
|||
}
|
||||
}
|
||||
void
|
||||
gst_alsa_clock_stop (GstAlsaClock *clock)
|
||||
gst_alsa_clock_stop (GstAlsaClock * clock)
|
||||
{
|
||||
GTimeVal timeval;
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
|
||||
g_assert (GST_CLOCK_TIME_IS_VALID (clock->start_time));
|
||||
|
||||
clock->adjust += GST_TIMEVAL_TO_TIME (timeval) - gst_clock_get_event_time (GST_CLOCK (clock));
|
||||
clock->adjust +=
|
||||
GST_TIMEVAL_TO_TIME (timeval) -
|
||||
gst_clock_get_event_time (GST_CLOCK (clock));
|
||||
clock->start_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
static GstClockTime
|
||||
gst_alsa_clock_get_internal_time (GstClock *clock)
|
||||
gst_alsa_clock_get_internal_time (GstClock * clock)
|
||||
{
|
||||
GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (clock);
|
||||
|
||||
|
@ -138,12 +145,13 @@ gst_alsa_clock_get_internal_time (GstClock *clock)
|
|||
return alsa_clock->get_time (alsa_clock->owner) + alsa_clock->start_time;
|
||||
} else {
|
||||
GTimeVal timeval;
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
return GST_TIMEVAL_TO_TIME (timeval) + alsa_clock->adjust;
|
||||
}
|
||||
}
|
||||
static guint64
|
||||
gst_alsa_clock_get_resolution (GstClock *clock)
|
||||
gst_alsa_clock_get_resolution (GstClock * clock)
|
||||
{
|
||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
||||
|
||||
|
@ -155,7 +163,7 @@ gst_alsa_clock_get_resolution (GstClock *clock)
|
|||
}
|
||||
}
|
||||
static GstClockEntryStatus
|
||||
gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
|
||||
gst_alsa_clock_wait (GstClock * clock, GstClockEntry * entry)
|
||||
{
|
||||
GstClockTime target, entry_time;
|
||||
GstClockTimeDiff diff;
|
||||
|
@ -168,8 +176,9 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
|
|||
return GST_CLOCK_ENTRY_EARLY;
|
||||
|
||||
if (diff > clock->max_diff) {
|
||||
GST_INFO_OBJECT (this, "GstAlsaClock: abnormal clock request diff: %" G_GINT64_FORMAT") >"
|
||||
" %"G_GINT64_FORMAT, diff, clock->max_diff);
|
||||
GST_INFO_OBJECT (this,
|
||||
"GstAlsaClock: abnormal clock request diff: %" G_GINT64_FORMAT ") >"
|
||||
" %" G_GINT64_FORMAT, diff, clock->max_diff);
|
||||
return GST_CLOCK_ENTRY_EARLY;
|
||||
}
|
||||
|
||||
|
@ -182,16 +191,16 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
|
|||
|
||||
while (gst_alsa_clock_get_internal_time (clock) < target &&
|
||||
this->last_unlock < entry_time) {
|
||||
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC / GST_SECOND);
|
||||
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC /
|
||||
GST_SECOND);
|
||||
}
|
||||
|
||||
return entry->status;
|
||||
}
|
||||
static void
|
||||
gst_alsa_clock_unlock (GstClock *clock, GstClockEntry *entry)
|
||||
gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry)
|
||||
{
|
||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
||||
|
||||
this->last_unlock = this->get_time (this->owner);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,38 +25,36 @@
|
|||
#include "gstalsa.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_CLOCK,GstAlsaClock))
|
||||
#define GST_ALSA_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_CLOCK,GstAlsaClockClass))
|
||||
#define GST_IS_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_CLOCK))
|
||||
#define GST_IS_ALSA_CLOCK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_CLOCK))
|
||||
#define GST_TYPE_ALSA_CLOCK (gst_alsa_clock_get_type())
|
||||
|
||||
typedef GstClockTime (*GstAlsaClockGetTimeFunc) (GstAlsa *);
|
||||
|
||||
struct _GstAlsaClock {
|
||||
struct _GstAlsaClock
|
||||
{
|
||||
GstSystemClock parent;
|
||||
|
||||
GstAlsaClockGetTimeFunc get_time;
|
||||
GstAlsa * owner;
|
||||
GstAlsa *owner;
|
||||
|
||||
GstClockTimeDiff adjust; /* adjustment to real clock (recalculated when stopping) */
|
||||
GstClockTime start_time; /* time when the stream started (NONE when stopped) */
|
||||
GstClockTime last_unlock; /* time of last unlock request */
|
||||
};
|
||||
|
||||
struct _GstAlsaClockClass {
|
||||
struct _GstAlsaClockClass
|
||||
{
|
||||
GstSystemClockClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_alsa_clock_get_type (void);
|
||||
GstAlsaClock * gst_alsa_clock_new (gchar * name,
|
||||
GstAlsaClockGetTimeFunc func,
|
||||
GstAlsa * owner);
|
||||
GstAlsaClock *gst_alsa_clock_new (gchar * name,
|
||||
GstAlsaClockGetTimeFunc func, GstAlsa * owner);
|
||||
|
||||
void gst_alsa_clock_start (GstAlsaClock * clock);
|
||||
void gst_alsa_clock_stop (GstAlsaClock * clock);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_CLOCK_H__ */
|
||||
|
|
|
@ -24,20 +24,18 @@
|
|||
#include "gstalsamixer.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_alsa_mixer_details = GST_ELEMENT_DETAILS (
|
||||
"Alsa Mixer",
|
||||
static GstElementDetails gst_alsa_mixer_details =
|
||||
GST_ELEMENT_DETAILS ("Alsa Mixer",
|
||||
"Generic/Audio",
|
||||
"Control sound input and output levels with ALSA",
|
||||
"Leif Johnson <leif@ambient.2y.net>"
|
||||
);
|
||||
"Leif Johnson <leif@ambient.2y.net>");
|
||||
|
||||
static void gst_alsa_interface_init (GstImplementsInterfaceClass *klass);
|
||||
static void gst_alsa_interface_init (GstImplementsInterfaceClass * klass);
|
||||
|
||||
static void gst_alsa_mixer_class_init (gpointer g_class,
|
||||
gpointer class_data);
|
||||
static void gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_alsa_mixer_init (GstAlsaMixer * mixer);
|
||||
static void gst_alsa_mixer_dispose (GObject * object);
|
||||
static void gst_alsa_mixer_interface_init (GstMixerClass* klass);
|
||||
static void gst_alsa_mixer_interface_init (GstMixerClass * klass);
|
||||
static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface,
|
||||
GType iface_type);
|
||||
|
||||
|
@ -48,21 +46,17 @@ static void gst_alsa_mixer_build_list (GstAlsaMixer * mixer);
|
|||
static void gst_alsa_mixer_free_list (GstAlsaMixer * mixer);
|
||||
|
||||
/* interface implementation */
|
||||
static const GList * gst_alsa_mixer_list_tracks (GstMixer * mixer);
|
||||
static const GList *gst_alsa_mixer_list_tracks (GstMixer * mixer);
|
||||
|
||||
static void gst_alsa_mixer_set_volume (GstMixer * mixer,
|
||||
GstMixerTrack* track,
|
||||
gint * volumes);
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
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,
|
||||
GstMixerTrack* track,
|
||||
gboolean record);
|
||||
GstMixerTrack * track, gboolean record);
|
||||
static void gst_alsa_mixer_set_mute (GstMixer * mixer,
|
||||
GstMixerTrack* track,
|
||||
gboolean mute);
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
|
||||
/*** GOBJECT STUFF ************************************************************/
|
||||
|
||||
|
@ -96,10 +90,14 @@ gst_alsa_mixer_get_type (void)
|
|||
NULL,
|
||||
};
|
||||
|
||||
alsa_mixer_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info, 0);
|
||||
alsa_mixer_type =
|
||||
g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info,
|
||||
0);
|
||||
|
||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE, &alsa_iface_info);
|
||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER, &alsa_mixer_iface_info);
|
||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE,
|
||||
&alsa_iface_info);
|
||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER,
|
||||
&alsa_mixer_iface_info);
|
||||
}
|
||||
|
||||
return alsa_mixer_type;
|
||||
|
@ -112,7 +110,7 @@ gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data)
|
|||
GstElementClass *element_class;
|
||||
GstAlsaClass *klass;
|
||||
|
||||
klass = (GstAlsaClass *)g_class;
|
||||
klass = (GstAlsaClass *) g_class;
|
||||
object_class = (GObjectClass *) g_class;
|
||||
element_class = (GstElementClass *) g_class;
|
||||
|
||||
|
@ -132,38 +130,37 @@ gst_alsa_mixer_init (GstAlsaMixer * mixer)
|
|||
gint err;
|
||||
GstAlsa *alsa = GST_ALSA (mixer);
|
||||
|
||||
mixer->mixer_handle = (snd_mixer_t *) -1;
|
||||
mixer->mixer_handle = (snd_mixer_t *) - 1;
|
||||
|
||||
/* open and initialize the mixer device */
|
||||
err = snd_mixer_open(&mixer->mixer_handle, 0);
|
||||
err = snd_mixer_open (&mixer->mixer_handle, 0);
|
||||
if (err < 0 || mixer->mixer_handle == NULL) {
|
||||
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot open mixer device.");
|
||||
mixer->mixer_handle = (snd_mixer_t *) -1;
|
||||
mixer->mixer_handle = (snd_mixer_t *) - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((err = snd_mixer_attach(mixer->mixer_handle, alsa->device)) < 0) {
|
||||
if ((err = snd_mixer_attach (mixer->mixer_handle, alsa->device)) < 0) {
|
||||
GST_ERROR_OBJECT (GST_OBJECT (mixer),
|
||||
"Cannot attach mixer to sound device `%s'.",
|
||||
alsa->device);
|
||||
"Cannot attach mixer to sound device `%s'.", alsa->device);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = snd_mixer_selem_register(mixer->mixer_handle, NULL, NULL)) < 0) {
|
||||
if ((err = snd_mixer_selem_register (mixer->mixer_handle, NULL, NULL)) < 0) {
|
||||
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot register mixer elements.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = snd_mixer_load(mixer->mixer_handle)) < 0) {
|
||||
if ((err = snd_mixer_load (mixer->mixer_handle)) < 0) {
|
||||
GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot load mixer settings.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
error:
|
||||
snd_mixer_close (mixer->mixer_handle);
|
||||
mixer->mixer_handle = (snd_mixer_t *) -1;
|
||||
mixer->mixer_handle = (snd_mixer_t *) - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -171,22 +168,23 @@ gst_alsa_mixer_dispose (GObject * object)
|
|||
{
|
||||
GstAlsaMixer *mixer = GST_ALSA_MIXER (object);
|
||||
|
||||
if (((gint) mixer->mixer_handle) == -1) return;
|
||||
if (((gint) mixer->mixer_handle) == -1)
|
||||
return;
|
||||
|
||||
snd_mixer_close (mixer->mixer_handle);
|
||||
mixer->mixer_handle = (snd_mixer_t *) -1;
|
||||
mixer->mixer_handle = (snd_mixer_t *) - 1;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_alsa_interface_init (GstImplementsInterfaceClass *klass)
|
||||
gst_alsa_interface_init (GstImplementsInterfaceClass * klass)
|
||||
{
|
||||
klass->supported = gst_alsa_mixer_supported;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_interface_init (GstMixerClass *klass)
|
||||
gst_alsa_mixer_interface_init (GstMixerClass * klass)
|
||||
{
|
||||
GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
|
||||
|
||||
|
@ -199,7 +197,7 @@ gst_alsa_mixer_interface_init (GstMixerClass *klass)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_alsa_mixer_supported (GstImplementsInterface *iface, GType iface_type)
|
||||
gst_alsa_mixer_supported (GstImplementsInterface * iface, GType iface_type)
|
||||
{
|
||||
g_assert (iface_type == GST_TYPE_MIXER);
|
||||
|
||||
|
@ -207,7 +205,7 @@ gst_alsa_mixer_supported (GstImplementsInterface *iface, GType iface_type)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
|
||||
gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
|
||||
{
|
||||
gint i, count;
|
||||
snd_mixer_elem_t *element;
|
||||
|
@ -215,22 +213,23 @@ gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
|
|||
|
||||
g_return_if_fail (((gint) mixer->mixer_handle) != -1);
|
||||
|
||||
count = snd_mixer_get_count(mixer->mixer_handle);
|
||||
element = snd_mixer_first_elem(mixer->mixer_handle);
|
||||
count = snd_mixer_get_count (mixer->mixer_handle);
|
||||
element = snd_mixer_first_elem (mixer->mixer_handle);
|
||||
|
||||
/* build track list */
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
gint channels = 0;
|
||||
|
||||
if (! snd_mixer_selem_is_active(element)) continue;
|
||||
if (!snd_mixer_selem_is_active (element))
|
||||
continue;
|
||||
|
||||
/* find out if this element can be an input */
|
||||
|
||||
if (snd_mixer_selem_has_capture_channel(element, 0) ||
|
||||
snd_mixer_selem_has_capture_switch(element) ||
|
||||
snd_mixer_selem_is_capture_mono(element)) {
|
||||
while (snd_mixer_selem_has_capture_channel(element, channels))
|
||||
if (snd_mixer_selem_has_capture_channel (element, 0) ||
|
||||
snd_mixer_selem_has_capture_switch (element) ||
|
||||
snd_mixer_selem_is_capture_mono (element)) {
|
||||
while (snd_mixer_selem_has_capture_channel (element, channels))
|
||||
channels++;
|
||||
|
||||
track = gst_alsa_mixer_track_new
|
||||
|
@ -242,10 +241,10 @@ gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
|
|||
|
||||
channels = 0;
|
||||
|
||||
if (snd_mixer_selem_has_playback_channel(element, 0) ||
|
||||
snd_mixer_selem_has_playback_switch(element) ||
|
||||
snd_mixer_selem_is_playback_mono(element)) {
|
||||
while (snd_mixer_selem_has_playback_channel(element, channels))
|
||||
if (snd_mixer_selem_has_playback_channel (element, 0) ||
|
||||
snd_mixer_selem_has_playback_switch (element) ||
|
||||
snd_mixer_selem_is_playback_mono (element)) {
|
||||
while (snd_mixer_selem_has_playback_channel (element, channels))
|
||||
channels++;
|
||||
|
||||
track = gst_alsa_mixer_track_new
|
||||
|
@ -253,12 +252,12 @@ gst_alsa_mixer_build_list (GstAlsaMixer *mixer)
|
|||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
|
||||
element = snd_mixer_elem_next(element);
|
||||
element = snd_mixer_elem_next (element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_free_list (GstAlsaMixer *mixer)
|
||||
gst_alsa_mixer_free_list (GstAlsaMixer * mixer)
|
||||
{
|
||||
g_return_if_fail (((gint) mixer->mixer_handle) != -1);
|
||||
|
||||
|
@ -270,7 +269,7 @@ gst_alsa_mixer_free_list (GstAlsaMixer *mixer)
|
|||
/*** GSTREAMER FUNCTIONS ******************************************************/
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_alsa_mixer_change_state (GstElement *element)
|
||||
gst_alsa_mixer_change_state (GstElement * element)
|
||||
{
|
||||
GstAlsaMixer *this;
|
||||
|
||||
|
@ -279,11 +278,13 @@ gst_alsa_mixer_change_state (GstElement *element)
|
|||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_NULL_TO_READY:
|
||||
gst_alsa_mixer_build_list (this); break;
|
||||
gst_alsa_mixer_build_list (this);
|
||||
break;
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
gst_alsa_mixer_free_list (this); break;
|
||||
gst_alsa_mixer_free_list (this);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
|
@ -295,7 +296,7 @@ gst_alsa_mixer_change_state (GstElement *element)
|
|||
/*** INTERFACE IMPLEMENTATION *************************************************/
|
||||
|
||||
static const GList *
|
||||
gst_alsa_mixer_list_tracks (GstMixer *mixer)
|
||||
gst_alsa_mixer_list_tracks (GstMixer * mixer)
|
||||
{
|
||||
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
|
||||
|
||||
|
@ -305,9 +306,8 @@ gst_alsa_mixer_list_tracks (GstMixer *mixer)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_get_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_alsa_mixer_get_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
gint i;
|
||||
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
|
||||
|
@ -321,11 +321,12 @@ gst_alsa_mixer_get_volume (GstMixer *mixer,
|
|||
} else {
|
||||
for (i = 0; i < track->num_channels; i++) {
|
||||
long tmp;
|
||||
if (snd_mixer_selem_has_playback_channel(alsa_track->element, i)) {
|
||||
snd_mixer_selem_get_playback_volume(alsa_track->element, i, &tmp);
|
||||
|
||||
if (snd_mixer_selem_has_playback_channel (alsa_track->element, i)) {
|
||||
snd_mixer_selem_get_playback_volume (alsa_track->element, i, &tmp);
|
||||
volumes[i] = (gint) tmp;
|
||||
} else if (snd_mixer_selem_has_capture_channel(alsa_track->element, i)) {
|
||||
snd_mixer_selem_get_capture_volume(alsa_track->element, i, &tmp);
|
||||
} else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i)) {
|
||||
snd_mixer_selem_get_capture_volume (alsa_track->element, i, &tmp);
|
||||
volumes[i] = (gint) tmp;
|
||||
}
|
||||
}
|
||||
|
@ -333,9 +334,8 @@ gst_alsa_mixer_get_volume (GstMixer *mixer,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_set_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_alsa_mixer_set_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
gint i;
|
||||
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
|
||||
|
@ -344,12 +344,14 @@ gst_alsa_mixer_set_volume (GstMixer *mixer,
|
|||
g_return_if_fail (((gint) alsa_mixer->mixer_handle) != -1);
|
||||
|
||||
/* only set the volume with ALSA lib if the track isn't muted. */
|
||||
if (! (track->flags & GST_MIXER_TRACK_MUTE)) {
|
||||
if (!(track->flags & GST_MIXER_TRACK_MUTE)) {
|
||||
for (i = 0; i < track->num_channels; i++) {
|
||||
if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume(alsa_track->element, i, (long) volumes[i]);
|
||||
else if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume(alsa_track->element, i, (long) volumes[i]);
|
||||
if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume (alsa_track->element, i,
|
||||
(long) volumes[i]);
|
||||
else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume (alsa_track->element, i,
|
||||
(long) volumes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,9 +360,7 @@ gst_alsa_mixer_set_volume (GstMixer *mixer,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_set_mute (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute)
|
||||
gst_alsa_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
gint i;
|
||||
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
|
||||
|
@ -372,29 +372,28 @@ gst_alsa_mixer_set_mute (GstMixer *mixer,
|
|||
track->flags |= GST_MIXER_TRACK_MUTE;
|
||||
|
||||
for (i = 0; i < track->num_channels; i++) {
|
||||
if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume(alsa_track->element, i, 0);
|
||||
else if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume(alsa_track->element, i, 0);
|
||||
if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume (alsa_track->element, i, 0);
|
||||
else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume (alsa_track->element, i, 0);
|
||||
}
|
||||
} else {
|
||||
track->flags &= ~GST_MIXER_TRACK_MUTE;
|
||||
|
||||
for (i = 0; i < track->num_channels; i++) {
|
||||
if (snd_mixer_selem_has_capture_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume(alsa_track->element, i,
|
||||
if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_capture_volume (alsa_track->element, i,
|
||||
alsa_track->volumes[i]);
|
||||
else if (snd_mixer_selem_has_playback_channel(alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume(alsa_track->element, i,
|
||||
else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
|
||||
snd_mixer_selem_set_playback_volume (alsa_track->element, i,
|
||||
alsa_track->volumes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_set_record (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record)
|
||||
gst_alsa_mixer_set_record (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
|
||||
|
||||
|
|
|
@ -24,28 +24,27 @@
|
|||
#include <gst/mixer/mixer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer))
|
||||
#define GST_ALSA_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER,GstAlsaMixerClass))
|
||||
#define GST_IS_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER))
|
||||
#define GST_IS_ALSA_MIXER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER))
|
||||
#define GST_TYPE_ALSA_MIXER (gst_alsa_mixer_get_type())
|
||||
|
||||
typedef struct _GstAlsaMixer GstAlsaMixer;
|
||||
typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
|
||||
|
||||
struct _GstAlsaMixer {
|
||||
struct _GstAlsaMixer
|
||||
{
|
||||
GstAlsa parent;
|
||||
GList * tracklist; /* list of available tracks */
|
||||
snd_mixer_t * mixer_handle;
|
||||
GList *tracklist; /* list of available tracks */
|
||||
snd_mixer_t *mixer_handle;
|
||||
};
|
||||
|
||||
struct _GstAlsaMixerClass {
|
||||
struct _GstAlsaMixerClass
|
||||
{
|
||||
GstAlsaClass parent;
|
||||
};
|
||||
|
||||
GType gst_alsa_mixer_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_MIXER_H__ */
|
||||
|
|
|
@ -47,7 +47,9 @@ gst_alsa_mixer_track_get_type (void)
|
|||
(GInstanceInitFunc) gst_alsa_mixer_track_init,
|
||||
};
|
||||
|
||||
track_type = g_type_register_static (GST_TYPE_MIXER_TRACK, "GstAlsaMixerTrack", &track_info, 0);
|
||||
track_type =
|
||||
g_type_register_static (GST_TYPE_MIXER_TRACK, "GstAlsaMixerTrack",
|
||||
&track_info, 0);
|
||||
}
|
||||
|
||||
return track_type;
|
||||
|
@ -61,14 +63,13 @@ gst_alsa_mixer_track_class_init (gpointer g_class, gpointer class_data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_mixer_track_init (GstAlsaMixerTrack *alsa_track)
|
||||
{ }
|
||||
gst_alsa_mixer_track_init (GstAlsaMixerTrack * alsa_track)
|
||||
{
|
||||
}
|
||||
|
||||
GstMixerTrack *
|
||||
gst_alsa_mixer_track_new (snd_mixer_elem_t *element,
|
||||
gint track_num,
|
||||
gint channels,
|
||||
gint flags)
|
||||
gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
|
||||
gint track_num, gint channels, gint flags)
|
||||
{
|
||||
gint i;
|
||||
long min, max;
|
||||
|
@ -77,28 +78,29 @@ gst_alsa_mixer_track_new (snd_mixer_elem_t *element,
|
|||
GstAlsaMixerTrack *alsa_track = (GstAlsaMixerTrack *) track;
|
||||
|
||||
/* set basic information */
|
||||
track->label = g_strdup_printf("%s", snd_mixer_selem_get_name(element));
|
||||
track->label = g_strdup_printf ("%s", snd_mixer_selem_get_name (element));
|
||||
track->num_channels = channels;
|
||||
track->flags = flags;
|
||||
alsa_track->element = element;
|
||||
alsa_track->track_num = track_num;
|
||||
|
||||
/* set volume information */
|
||||
snd_mixer_selem_get_playback_volume_range(element, &min, &max);
|
||||
snd_mixer_selem_get_playback_volume_range (element, &min, &max);
|
||||
track->min_volume = (gint) min;
|
||||
track->max_volume = (gint) max;
|
||||
|
||||
snd_mixer_selem_get_capture_volume_range(element, &min, &max);
|
||||
snd_mixer_selem_get_capture_volume_range (element, &min, &max);
|
||||
alsa_track->min_rec_volume = (gint) min;
|
||||
alsa_track->max_rec_volume = (gint) max;
|
||||
|
||||
for (i = 0; i < channels; i++) {
|
||||
long tmp;
|
||||
if (snd_mixer_selem_has_playback_channel(element, i)) {
|
||||
snd_mixer_selem_get_playback_volume(element, i, &tmp);
|
||||
|
||||
if (snd_mixer_selem_has_playback_channel (element, i)) {
|
||||
snd_mixer_selem_get_playback_volume (element, i, &tmp);
|
||||
alsa_track->volumes[i] = (gint) tmp;
|
||||
} else if (snd_mixer_selem_has_capture_channel(element, i)) {
|
||||
snd_mixer_selem_get_capture_volume(element, i, &tmp);
|
||||
} else if (snd_mixer_selem_has_capture_channel (element, i)) {
|
||||
snd_mixer_selem_get_capture_volume (element, i, &tmp);
|
||||
alsa_track->volumes[i] = (gint) tmp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,18 +23,17 @@
|
|||
#include <gst/mixer/mixertrack.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA_MIXER_TRACK_TYPE (gst_alsa_mixer_track_get_type ())
|
||||
#define GST_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrack))
|
||||
#define GST_ALSA_MIXER_TRACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrackClass))
|
||||
#define GST_IS_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER_TRACK))
|
||||
#define GST_IS_ALSA_MIXER_TRACK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_TRACK))
|
||||
#define GST_TYPE_ALSA_MIXER_TRACK (gst_alsa_mixer_track_get_type())
|
||||
|
||||
typedef struct _GstAlsaMixerTrack GstAlsaMixerTrack;
|
||||
typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
|
||||
|
||||
struct _GstAlsaMixerTrack {
|
||||
struct _GstAlsaMixerTrack
|
||||
{
|
||||
GstMixerTrack parent;
|
||||
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
|
||||
gint track_num;
|
||||
|
@ -42,16 +41,14 @@ struct _GstAlsaMixerTrack {
|
|||
gint volumes[GST_ALSA_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct _GstAlsaMixerTrackClass {
|
||||
struct _GstAlsaMixerTrackClass
|
||||
{
|
||||
GstMixerTrackClass parent;
|
||||
};
|
||||
|
||||
GType gst_alsa_mixer_track_get_type (void);
|
||||
GstMixerTrack * gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
|
||||
gint track_num,
|
||||
gint channels,
|
||||
gint flags);
|
||||
GstMixerTrack *gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
|
||||
gint track_num, gint channels, gint flags);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_MIXER_TRACK_H__ */
|
||||
|
|
|
@ -34,24 +34,21 @@ plugin_init (GstPlugin * plugin)
|
|||
{
|
||||
GST_DEBUG_CATEGORY_INIT (alsa_debug, "alsa", 0, "alsa plugins");
|
||||
|
||||
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE, GST_TYPE_ALSA_MIXER))
|
||||
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
|
||||
GST_TYPE_ALSA_MIXER))
|
||||
return FALSE;
|
||||
if (!gst_element_register (plugin, "alsasrc", GST_RANK_NONE, GST_TYPE_ALSA_SRC))
|
||||
if (!gst_element_register (plugin, "alsasrc", GST_RANK_NONE,
|
||||
GST_TYPE_ALSA_SRC))
|
||||
return FALSE;
|
||||
if (!gst_element_register (plugin, "alsasink", GST_RANK_NONE, GST_TYPE_ALSA_SINK))
|
||||
if (!gst_element_register (plugin, "alsasink", GST_RANK_NONE,
|
||||
GST_TYPE_ALSA_SINK))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"alsa",
|
||||
"ALSA plugin library",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"LGPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -27,31 +27,25 @@
|
|||
#include "gstalsaclock.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_alsa_sink_details = GST_ELEMENT_DETAILS (
|
||||
"Alsa Sink",
|
||||
static GstElementDetails gst_alsa_sink_details =
|
||||
GST_ELEMENT_DETAILS ("Alsa Sink",
|
||||
"Sink/Audio",
|
||||
"Output to a sound card via ALSA",
|
||||
"Thomas Nyberg <thomas@codefactory.se>, "
|
||||
"Andy Wingo <apwingo@eos.ncsu.edu>, "
|
||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
|
||||
);
|
||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
|
||||
|
||||
static GstPadTemplate * gst_alsa_sink_pad_factory (void);
|
||||
static GstPadTemplate * gst_alsa_sink_request_pad_factory(void);
|
||||
static GstPadTemplate *gst_alsa_sink_pad_factory (void);
|
||||
static GstPadTemplate *gst_alsa_sink_request_pad_factory (void);
|
||||
static void gst_alsa_sink_base_init (gpointer g_class);
|
||||
static void gst_alsa_sink_class_init (gpointer g_klass,
|
||||
gpointer class_data);
|
||||
static void gst_alsa_sink_class_init (gpointer g_klass, gpointer class_data);
|
||||
static void gst_alsa_sink_init (GstAlsaSink * this);
|
||||
static inline void gst_alsa_sink_flush_one_pad (GstAlsaSink * sink,
|
||||
gint i);
|
||||
static inline void gst_alsa_sink_flush_one_pad (GstAlsaSink * sink, gint i);
|
||||
static void gst_alsa_sink_flush_pads (GstAlsaSink * sink);
|
||||
static int gst_alsa_sink_mmap (GstAlsa * this,
|
||||
snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_sink_write (GstAlsa * this,
|
||||
snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_sink_mmap (GstAlsa * this, snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_sink_write (GstAlsa * this, snd_pcm_sframes_t * avail);
|
||||
static void gst_alsa_sink_loop (GstElement * element);
|
||||
static gboolean gst_alsa_sink_check_event (GstAlsaSink * sink,
|
||||
gint pad_nr);
|
||||
static 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);
|
||||
|
@ -81,6 +75,7 @@ gst_alsa_sink_request_pad_factory (void)
|
|||
|
||||
return template;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_alsa_sink_get_type (void)
|
||||
{
|
||||
|
@ -99,7 +94,9 @@ gst_alsa_sink_get_type (void)
|
|||
(GInstanceInitFunc) gst_alsa_sink_init,
|
||||
};
|
||||
|
||||
alsa_sink_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaSink", &alsa_sink_info, 0);
|
||||
alsa_sink_type =
|
||||
g_type_register_static (GST_TYPE_ALSA, "GstAlsaSink", &alsa_sink_info,
|
||||
0);
|
||||
}
|
||||
return alsa_sink_type;
|
||||
}
|
||||
|
@ -109,8 +106,10 @@ gst_alsa_sink_base_init (gpointer g_class)
|
|||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_add_pad_template (element_class, gst_alsa_sink_pad_factory ());
|
||||
gst_element_class_add_pad_template (element_class, gst_alsa_sink_request_pad_factory ());
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_alsa_sink_pad_factory ());
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_alsa_sink_request_pad_factory ());
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_alsa_sink_details);
|
||||
}
|
||||
|
@ -138,17 +137,19 @@ gst_alsa_sink_class_init (gpointer g_class, gpointer class_data)
|
|||
element_class->change_state = gst_alsa_sink_change_state;
|
||||
}
|
||||
static void
|
||||
gst_alsa_sink_init (GstAlsaSink *sink)
|
||||
gst_alsa_sink_init (GstAlsaSink * sink)
|
||||
{
|
||||
GstAlsa *this = GST_ALSA (sink);
|
||||
|
||||
this->pad[0] = gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
|
||||
this->pad[0] =
|
||||
gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
|
||||
gst_pad_set_link_function (this->pad[0], gst_alsa_link);
|
||||
gst_pad_set_getcaps_function (this->pad[0], gst_alsa_get_caps);
|
||||
gst_pad_set_fixate_function (this->pad[0], gst_alsa_fixate);
|
||||
gst_element_add_pad (GST_ELEMENT (this), this->pad[0]);
|
||||
|
||||
this->clock = gst_alsa_clock_new ("alsasinkclock", gst_alsa_sink_get_time, this);
|
||||
this->clock =
|
||||
gst_alsa_clock_new ("alsasinkclock", gst_alsa_sink_get_time, this);
|
||||
/* we hold a ref to our clock until we're disposed */
|
||||
gst_object_ref (GST_OBJECT (this->clock));
|
||||
gst_object_sink (GST_OBJECT (this->clock));
|
||||
|
@ -157,7 +158,7 @@ gst_alsa_sink_init (GstAlsaSink *sink)
|
|||
}
|
||||
|
||||
static inline void
|
||||
gst_alsa_sink_flush_one_pad (GstAlsaSink *sink, gint i)
|
||||
gst_alsa_sink_flush_one_pad (GstAlsaSink * sink, gint i)
|
||||
{
|
||||
switch (sink->behaviour[i]) {
|
||||
case 0:
|
||||
|
@ -179,7 +180,7 @@ gst_alsa_sink_flush_one_pad (GstAlsaSink *sink, gint i)
|
|||
}
|
||||
}
|
||||
static void
|
||||
gst_alsa_sink_flush_pads (GstAlsaSink *sink)
|
||||
gst_alsa_sink_flush_pads (GstAlsaSink * sink)
|
||||
{
|
||||
gint i;
|
||||
|
||||
|
@ -189,9 +190,10 @@ gst_alsa_sink_flush_pads (GstAlsaSink *sink)
|
|||
gst_alsa_sink_flush_one_pad (sink, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* TRUE, if everything should continue */
|
||||
static gboolean
|
||||
gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
|
||||
gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr)
|
||||
{
|
||||
gboolean cont = TRUE;
|
||||
GstEvent *event = GST_EVENT (sink->buf[pad_nr]);
|
||||
|
@ -216,21 +218,25 @@ gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
|
|||
}
|
||||
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)) {
|
||||
} 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)) {
|
||||
} 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!");
|
||||
GST_ERROR_OBJECT (this,
|
||||
"couldn't extract time from discont event. Bad things might happen!");
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GST_INFO_OBJECT (this, "got an unknown event (Type: %d)", GST_EVENT_TYPE (event));
|
||||
GST_INFO_OBJECT (this, "got an unknown event (Type: %d)",
|
||||
GST_EVENT_TYPE (event));
|
||||
break;
|
||||
}
|
||||
gst_event_unref (event);
|
||||
|
@ -242,7 +248,7 @@ gst_alsa_sink_check_event (GstAlsaSink *sink, gint pad_nr)
|
|||
return cont;
|
||||
}
|
||||
static int
|
||||
gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
||||
gst_alsa_sink_mmap (GstAlsa * this, snd_pcm_sframes_t * avail)
|
||||
{
|
||||
snd_pcm_uframes_t offset;
|
||||
const snd_pcm_channel_area_t *dst;
|
||||
|
@ -251,7 +257,7 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
int i, err, width = snd_pcm_format_physical_width (this->format->format);
|
||||
|
||||
/* areas points to the memory areas that belong to gstreamer. */
|
||||
src = g_malloc0 (this->format->channels * sizeof(snd_pcm_channel_area_t));
|
||||
src = g_malloc0 (this->format->channels * sizeof (snd_pcm_channel_area_t));
|
||||
|
||||
if (((GstElement *) this)->numpads == 1) {
|
||||
/* interleaved */
|
||||
|
@ -274,7 +280,9 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_areas_copy (dst, offset, src, 0, this->format->channels, *avail, this->format->format)) < 0) {
|
||||
if ((err =
|
||||
snd_pcm_areas_copy (dst, offset, src, 0, this->format->channels,
|
||||
*avail, this->format->format)) < 0) {
|
||||
snd_pcm_mmap_commit (this->handle, offset, 0);
|
||||
GST_ERROR_OBJECT (this, "data copy failed: %s", snd_strerror (err));
|
||||
return -1;
|
||||
|
@ -287,7 +295,7 @@ gst_alsa_sink_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
return err;
|
||||
}
|
||||
static int
|
||||
gst_alsa_sink_write (GstAlsa *this, snd_pcm_sframes_t *avail)
|
||||
gst_alsa_sink_write (GstAlsa * this, snd_pcm_sframes_t * avail)
|
||||
{
|
||||
GstAlsaSink *sink = GST_ALSA_SINK (this);
|
||||
void *channels[this->format->channels];
|
||||
|
@ -314,7 +322,7 @@ gst_alsa_sink_write (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
return err;
|
||||
}
|
||||
static void
|
||||
gst_alsa_sink_loop (GstElement *element)
|
||||
gst_alsa_sink_loop (GstElement * element)
|
||||
{
|
||||
snd_pcm_sframes_t avail, avail2, copied, sample_diff, max_discont;
|
||||
snd_pcm_uframes_t samplestamp, time_sample;
|
||||
|
@ -328,8 +336,10 @@ gst_alsa_sink_loop (GstElement *element)
|
|||
sink_restart:
|
||||
|
||||
avail = gst_alsa_update_avail (this);
|
||||
if (avail == -EPIPE) goto sink_restart;
|
||||
if (avail < 0) return;
|
||||
if (avail == -EPIPE)
|
||||
goto sink_restart;
|
||||
if (avail < 0)
|
||||
return;
|
||||
if (avail > 0) {
|
||||
|
||||
/* Not enough space. We grab data nonetheless and sleep afterwards */
|
||||
|
@ -355,9 +365,13 @@ sink_restart:
|
|||
GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
|
||||
("ALSA format not negotiated"));
|
||||
}
|
||||
samplestamp = gst_alsa_timestamp_to_samples (this, GST_BUFFER_TIMESTAMP (sink->buf[i]));
|
||||
samplestamp =
|
||||
gst_alsa_timestamp_to_samples (this,
|
||||
GST_BUFFER_TIMESTAMP (sink->buf[i]));
|
||||
max_discont = gst_alsa_timestamp_to_samples (this, this->max_discont);
|
||||
time_sample = gst_alsa_timestamp_to_samples (this, gst_element_get_time (GST_ELEMENT (this)));
|
||||
time_sample =
|
||||
gst_alsa_timestamp_to_samples (this,
|
||||
gst_element_get_time (GST_ELEMENT (this)));
|
||||
snd_pcm_delay (this->handle, &sample_diff);
|
||||
/* actual diff = buffer samplestamp - played - to_play */
|
||||
sample_diff = samplestamp - time_sample - sample_diff;
|
||||
|
@ -366,7 +380,7 @@ sink_restart:
|
|||
(-max_discont <= sample_diff && sample_diff <= max_discont)) {
|
||||
|
||||
/* difference between expected and current is < GST_ALSA_DEVIATION */
|
||||
no_difference:
|
||||
no_difference:
|
||||
sink->size[i] = sink->buf[i]->size;
|
||||
sink->data[i] = sink->buf[i]->data;
|
||||
sink->behaviour[i] = 0;
|
||||
|
@ -374,30 +388,41 @@ no_difference:
|
|||
/* there are empty samples in front of us, fill them with silence */
|
||||
int samples = MIN (bytes, sample_diff) *
|
||||
(element->numpads == 1 ? this->format->channels : 1);
|
||||
int size = samples * snd_pcm_format_physical_width (this->format->format) / 8;
|
||||
GST_INFO_OBJECT (this, "Allocating %d bytes (%ld samples) now to resync: sample %ld expected, but got %ld",
|
||||
int size =
|
||||
samples * snd_pcm_format_physical_width (this->format->format) /
|
||||
8;
|
||||
GST_INFO_OBJECT (this,
|
||||
"Allocating %d bytes (%ld samples) now to resync: sample %ld expected, but got %ld",
|
||||
size, MIN (bytes, sample_diff), time_sample, samplestamp);
|
||||
sink->data[i] = g_try_malloc (size);
|
||||
if (!sink->data[i]) {
|
||||
GST_WARNING_OBJECT (this, "error allocating %d bytes, buffers unsynced now.", size);
|
||||
GST_WARNING_OBJECT (this,
|
||||
"error allocating %d bytes, buffers unsynced now.", size);
|
||||
goto no_difference;
|
||||
}
|
||||
sink->size[i] = size;
|
||||
if (0 != snd_pcm_format_set_silence (this->format->format, sink->data[i], samples)) {
|
||||
GST_WARNING_OBJECT (this, "error silencing buffer, enjoy the noise.");
|
||||
if (0 != snd_pcm_format_set_silence (this->format->format,
|
||||
sink->data[i], samples)) {
|
||||
GST_WARNING_OBJECT (this,
|
||||
"error silencing buffer, enjoy the noise.");
|
||||
}
|
||||
sink->behaviour[i] = 1;
|
||||
} else if (gst_alsa_samples_to_bytes (this, -sample_diff) >= sink->buf[i]->size) {
|
||||
GST_INFO_OBJECT (this, "Skipping %lu samples to resync (complete buffer): sample %ld expected, but got %ld",
|
||||
gst_alsa_bytes_to_samples (this, sink->buf[i]->size), time_sample, samplestamp);
|
||||
} else if (gst_alsa_samples_to_bytes (this,
|
||||
-sample_diff) >= sink->buf[i]->size) {
|
||||
GST_INFO_OBJECT (this,
|
||||
"Skipping %lu samples to resync (complete buffer): sample %ld expected, but got %ld",
|
||||
gst_alsa_bytes_to_samples (this, sink->buf[i]->size), time_sample,
|
||||
samplestamp);
|
||||
/* this buffer is way behind */
|
||||
gst_buffer_unref (sink->buf[i]);
|
||||
sink->buf[i] = NULL;
|
||||
continue;
|
||||
} else if (sample_diff < 0) {
|
||||
gint difference = gst_alsa_samples_to_bytes (this, -samplestamp);
|
||||
GST_INFO_OBJECT (this, "Skipping %lu samples to resync: sample %ld expected, but got %ld",
|
||||
(gulong) -sample_diff, time_sample, samplestamp);
|
||||
|
||||
GST_INFO_OBJECT (this,
|
||||
"Skipping %lu samples to resync: sample %ld expected, but got %ld",
|
||||
(gulong) - sample_diff, time_sample, samplestamp);
|
||||
/* this buffer is only a bit behind */
|
||||
sink->size[i] = sink->buf[i]->size - difference;
|
||||
sink->data[i] = sink->buf[i]->data + difference;
|
||||
|
@ -412,11 +437,16 @@ no_difference:
|
|||
avail = MIN (avail, gst_alsa_bytes_to_samples (this, bytes));
|
||||
|
||||
/* wait until the hw buffer has enough space */
|
||||
while (gst_element_get_state (element) == GST_STATE_PLAYING && (avail2 = gst_alsa_update_avail (this)) < avail) {
|
||||
if (avail2 <= -EPIPE) goto sink_restart;
|
||||
if (avail2 < 0) return;
|
||||
if (avail2 < avail && snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING)
|
||||
if (!gst_alsa_start (this)) return;
|
||||
while (gst_element_get_state (element) == GST_STATE_PLAYING
|
||||
&& (avail2 = gst_alsa_update_avail (this)) < avail) {
|
||||
if (avail2 <= -EPIPE)
|
||||
goto sink_restart;
|
||||
if (avail2 < 0)
|
||||
return;
|
||||
if (avail2 < avail
|
||||
&& snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING)
|
||||
if (!gst_alsa_start (this))
|
||||
return;
|
||||
if (gst_alsa_pcm_wait (this) == FALSE)
|
||||
return;
|
||||
}
|
||||
|
@ -441,14 +471,15 @@ no_difference:
|
|||
}
|
||||
}
|
||||
|
||||
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING && snd_pcm_avail_update (this->handle) == 0) {
|
||||
if (snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING
|
||||
&& snd_pcm_avail_update (this->handle) == 0) {
|
||||
gst_alsa_start (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_alsa_sink_change_state (GstElement *element)
|
||||
gst_alsa_sink_change_state (GstElement * element)
|
||||
{
|
||||
GstAlsaSink *sink;
|
||||
|
||||
|
@ -467,7 +498,7 @@ gst_alsa_sink_change_state (GstElement *element)
|
|||
case GST_STATE_READY_TO_NULL:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS (sink_parent_class)->change_state)
|
||||
|
@ -477,14 +508,14 @@ gst_alsa_sink_change_state (GstElement *element)
|
|||
}
|
||||
|
||||
static GstClockTime
|
||||
gst_alsa_sink_get_time (GstAlsa *this)
|
||||
gst_alsa_sink_get_time (GstAlsa * this)
|
||||
{
|
||||
snd_pcm_sframes_t delay;
|
||||
|
||||
if (snd_pcm_delay (this->handle, &delay) == 0 && this->format) {
|
||||
return GST_SECOND * (GstClockTime) (this->transmitted > delay ? this->transmitted - delay : 0) / this->format->rate;
|
||||
return GST_SECOND * (GstClockTime) (this->transmitted >
|
||||
delay ? this->transmitted - delay : 0) / this->format->rate;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,17 +25,16 @@
|
|||
#include "gstalsa.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SINK, GstAlsaSink))
|
||||
#define GST_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA_SINK, GstAlsaSinkClass))
|
||||
#define GST_IS_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA_SINK))
|
||||
#define GST_IS_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA_SINK))
|
||||
#define GST_TYPE_ALSA_SINK (gst_alsa_sink_get_type())
|
||||
|
||||
typedef struct _GstAlsaSink GstAlsaSink;
|
||||
typedef struct _GstAlsaSinkClass GstAlsaSinkClass;
|
||||
|
||||
struct _GstAlsaSink {
|
||||
struct _GstAlsaSink
|
||||
{
|
||||
GstAlsa parent;
|
||||
|
||||
/* array of the data on the channels */
|
||||
|
@ -46,14 +45,14 @@ struct _GstAlsaSink {
|
|||
1 = data should be freed, use buffer after that */
|
||||
};
|
||||
|
||||
struct _GstAlsaSinkClass {
|
||||
struct _GstAlsaSinkClass
|
||||
{
|
||||
GstAlsaClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_alsa_sink_get_type (void);
|
||||
|
||||
gboolean gst_alsa_sink_factory_init (GstPlugin *plugin);
|
||||
gboolean gst_alsa_sink_factory_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_SINK_H__ */
|
||||
|
|
|
@ -27,24 +27,19 @@
|
|||
#include "gstalsaclock.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_alsa_src_details = GST_ELEMENT_DETAILS (
|
||||
"Alsa Src",
|
||||
static GstElementDetails gst_alsa_src_details = GST_ELEMENT_DETAILS ("Alsa Src",
|
||||
"Source/Audio",
|
||||
"Read from a sound card via ALSA",
|
||||
"Thomas Nyberg <thomas@codefactory.se>, "
|
||||
"Andy Wingo <apwingo@eos.ncsu.edu>, "
|
||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
|
||||
);
|
||||
"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_class_init (gpointer g_class,
|
||||
gpointer class_data);
|
||||
static void gst_alsa_src_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_alsa_src_init (GstAlsaSrc * this);
|
||||
static int gst_alsa_src_mmap (GstAlsa * this,
|
||||
snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_src_read (GstAlsa * this,
|
||||
snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_src_mmap (GstAlsa * this, snd_pcm_sframes_t * avail);
|
||||
static int gst_alsa_src_read (GstAlsa * this, snd_pcm_sframes_t * avail);
|
||||
static void gst_alsa_src_loop (GstElement * element);
|
||||
static void gst_alsa_src_flush (GstAlsaSrc * src);
|
||||
static GstElementStateReturn gst_alsa_src_change_state (GstElement * element);
|
||||
|
@ -83,7 +78,8 @@ gst_alsa_src_get_type (void)
|
|||
(GInstanceInitFunc) gst_alsa_src_init,
|
||||
};
|
||||
|
||||
alsa_src_type = g_type_register_static (GST_TYPE_ALSA, "GstAlsaSrc", &alsa_src_info, 0);
|
||||
alsa_src_type =
|
||||
g_type_register_static (GST_TYPE_ALSA, "GstAlsaSrc", &alsa_src_info, 0);
|
||||
}
|
||||
return alsa_src_type;
|
||||
}
|
||||
|
@ -93,7 +89,8 @@ gst_alsa_src_base_init (gpointer g_class)
|
|||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_add_pad_template (element_class, gst_alsa_src_pad_factory ());
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_alsa_src_pad_factory ());
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_alsa_src_details);
|
||||
}
|
||||
|
@ -121,7 +118,7 @@ gst_alsa_src_class_init (gpointer g_class, gpointer class_data)
|
|||
element_class->change_state = gst_alsa_src_change_state;
|
||||
}
|
||||
static void
|
||||
gst_alsa_src_init (GstAlsaSrc *src)
|
||||
gst_alsa_src_init (GstAlsaSrc * src)
|
||||
{
|
||||
GstAlsa *this = GST_ALSA (src);
|
||||
|
||||
|
@ -130,7 +127,8 @@ gst_alsa_src_init (GstAlsaSrc *src)
|
|||
gst_pad_set_getcaps_function (this->pad[0], gst_alsa_get_caps);
|
||||
gst_element_add_pad (GST_ELEMENT (this), this->pad[0]);
|
||||
|
||||
this->clock = gst_alsa_clock_new ("alsasrcclock", gst_alsa_src_get_time, this);
|
||||
this->clock =
|
||||
gst_alsa_clock_new ("alsasrcclock", gst_alsa_src_get_time, this);
|
||||
/* we hold a ref to our clock until we're disposed */
|
||||
gst_object_ref (GST_OBJECT (this->clock));
|
||||
gst_object_sink (GST_OBJECT (this->clock));
|
||||
|
@ -138,7 +136,7 @@ gst_alsa_src_init (GstAlsaSrc *src)
|
|||
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
|
||||
}
|
||||
static int
|
||||
gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
||||
gst_alsa_src_mmap (GstAlsa * this, snd_pcm_sframes_t * avail)
|
||||
{
|
||||
snd_pcm_uframes_t offset;
|
||||
snd_pcm_channel_area_t *dst;
|
||||
|
@ -147,7 +145,7 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
GstAlsaSrc *alsa_src = GST_ALSA_SRC (this);
|
||||
|
||||
/* areas points to the memory areas that belong to gstreamer. */
|
||||
dst = g_malloc0 (this->format->channels * sizeof(snd_pcm_channel_area_t));
|
||||
dst = g_malloc0 (this->format->channels * sizeof (snd_pcm_channel_area_t));
|
||||
|
||||
if (((GstElement *) this)->numpads == 1) {
|
||||
/* interleaved */
|
||||
|
@ -169,7 +167,10 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
GST_ERROR_OBJECT (this, "mmap failed: %s", snd_strerror (err));
|
||||
return -1;
|
||||
}
|
||||
if (*avail > 0 && (err = snd_pcm_areas_copy (dst, 0, src, offset, this->format->channels, *avail, this->format->format)) < 0) {
|
||||
if (*avail > 0
|
||||
&& (err =
|
||||
snd_pcm_areas_copy (dst, 0, src, offset, this->format->channels,
|
||||
*avail, this->format->format)) < 0) {
|
||||
snd_pcm_mmap_commit (this->handle, offset, 0);
|
||||
GST_ERROR_OBJECT (this, "data copy failed: %s", snd_strerror (err));
|
||||
return -1;
|
||||
|
@ -182,7 +183,7 @@ gst_alsa_src_mmap (GstAlsa *this, snd_pcm_sframes_t *avail)
|
|||
return err;
|
||||
}
|
||||
static int
|
||||
gst_alsa_src_read (GstAlsa *this, snd_pcm_sframes_t *avail)
|
||||
gst_alsa_src_read (GstAlsa * this, snd_pcm_sframes_t * avail)
|
||||
{
|
||||
void *channels[this->format->channels];
|
||||
int err, i;
|
||||
|
@ -224,8 +225,9 @@ gst_alsa_src_adjust_rate (gint rate, gboolean aggressive)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
|
||||
gst_alsa_src_set_caps (GstAlsaSrc * src, gboolean aggressive)
|
||||
{
|
||||
GstCaps *all_caps, *caps;
|
||||
GstStructure *structure, *walk;
|
||||
|
@ -236,19 +238,21 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
|
|||
GstAlsa *this = GST_ALSA (src);
|
||||
|
||||
all_caps = gst_alsa_get_caps (this->pad[0]);
|
||||
if (all_caps == NULL) return FALSE;
|
||||
if (all_caps == NULL)
|
||||
return FALSE;
|
||||
/* now intersect this with all caps of the peers... */
|
||||
for (i = 0; i < GST_ELEMENT (src)->numpads; i++) {
|
||||
all_caps = gst_caps_intersect (all_caps, gst_pad_get_allowed_caps (this->pad[i]));
|
||||
all_caps =
|
||||
gst_caps_intersect (all_caps, gst_pad_get_allowed_caps (this->pad[i]));
|
||||
if (all_caps == NULL) {
|
||||
GST_DEBUG ("No compatible caps found in alsasrc (%s)", GST_ELEMENT_NAME (this));
|
||||
GST_DEBUG ("No compatible caps found in alsasrc (%s)",
|
||||
GST_ELEMENT_NAME (this));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* construct caps */
|
||||
caps = gst_caps_new_simple ("audio/x-raw-int",
|
||||
NULL);
|
||||
caps = gst_caps_new_simple ("audio/x-raw-int", NULL);
|
||||
g_assert (gst_caps_get_size (caps) == 1);
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
|
@ -267,21 +271,27 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
|
|||
gst_structure_set (structure,
|
||||
"endianness", G_TYPE_INT, endian,
|
||||
"width", G_TYPE_INT, width,
|
||||
"depth", G_TYPE_INT, depth,
|
||||
"signed", G_TYPE_BOOLEAN, sign,
|
||||
NULL);
|
||||
"depth", G_TYPE_INT, depth, "signed", G_TYPE_BOOLEAN, sign, NULL);
|
||||
|
||||
min_rate = gst_value_get_int_range_min (gst_structure_get_value (walk, "rate"));
|
||||
max_rate = gst_value_get_int_range_max (gst_structure_get_value (walk, "rate"));
|
||||
min_channels = gst_value_get_int_range_min (gst_structure_get_value (walk, "channels"));
|
||||
max_channels = gst_value_get_int_range_max (gst_structure_get_value (walk, "channels"));
|
||||
min_rate =
|
||||
gst_value_get_int_range_min (gst_structure_get_value (walk, "rate"));
|
||||
max_rate =
|
||||
gst_value_get_int_range_max (gst_structure_get_value (walk, "rate"));
|
||||
min_channels =
|
||||
gst_value_get_int_range_min (gst_structure_get_value (walk,
|
||||
"channels"));
|
||||
max_channels =
|
||||
gst_value_get_int_range_max (gst_structure_get_value (walk,
|
||||
"channels"));
|
||||
for (rate = max_rate;; rate--) {
|
||||
if ((rate = gst_alsa_src_adjust_rate (rate, aggressive)) < min_rate)
|
||||
break;
|
||||
gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
|
||||
for (channels = aggressive ? max_channels : MIN (max_channels, 2); channels >= min_channels; channels--) {
|
||||
for (channels = aggressive ? max_channels : MIN (max_channels, 2);
|
||||
channels >= min_channels; channels--) {
|
||||
gst_structure_set (structure, "channels", G_TYPE_INT, channels, NULL);
|
||||
GST_DEBUG ("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d",
|
||||
GST_DEBUG
|
||||
("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d",
|
||||
sign ? "" : "un", endian, width, depth, channels, rate);
|
||||
if (gst_pad_try_set_caps (this->pad[0], caps) != GST_PAD_LINK_REFUSED)
|
||||
gst_alsa_link (this->pad[0], caps);
|
||||
|
@ -299,9 +309,10 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* we transmit buffers of period_size frames */
|
||||
static void
|
||||
gst_alsa_src_loop (GstElement *element)
|
||||
gst_alsa_src_loop (GstElement * element)
|
||||
{
|
||||
snd_pcm_sframes_t avail, copied;
|
||||
gint i;
|
||||
|
@ -318,9 +329,11 @@ gst_alsa_src_loop (GstElement *element)
|
|||
}
|
||||
|
||||
while ((avail = gst_alsa_update_avail (this)) < this->period_size) {
|
||||
if (avail == -EPIPE) continue;
|
||||
if (avail < 0) return;
|
||||
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING) {
|
||||
if (avail == -EPIPE)
|
||||
continue;
|
||||
if (avail < 0)
|
||||
return;
|
||||
if (snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING) {
|
||||
if (!gst_alsa_start (this))
|
||||
return;
|
||||
continue;
|
||||
|
@ -345,8 +358,10 @@ gst_alsa_src_loop (GstElement *element)
|
|||
return;
|
||||
if (copied != this->period_size)
|
||||
GST_BUFFER_SIZE (src->buf[i]) = gst_alsa_samples_to_bytes (this, copied);
|
||||
GST_BUFFER_TIMESTAMP (src->buf[i]) = gst_alsa_samples_to_timestamp (this, this->transmitted);
|
||||
GST_BUFFER_DURATION (src->buf[i]) = gst_alsa_samples_to_timestamp (this, copied);
|
||||
GST_BUFFER_TIMESTAMP (src->buf[i]) =
|
||||
gst_alsa_samples_to_timestamp (this, this->transmitted);
|
||||
GST_BUFFER_DURATION (src->buf[i]) =
|
||||
gst_alsa_samples_to_timestamp (this, copied);
|
||||
gst_pad_push (this->pad[i], GST_DATA (src->buf[i]));
|
||||
src->buf[i] = NULL;
|
||||
}
|
||||
|
@ -354,7 +369,7 @@ gst_alsa_src_loop (GstElement *element)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_alsa_src_flush (GstAlsaSrc *src)
|
||||
gst_alsa_src_flush (GstAlsaSrc * src)
|
||||
{
|
||||
gint i;
|
||||
|
||||
|
@ -366,7 +381,7 @@ gst_alsa_src_flush (GstAlsaSrc *src)
|
|||
}
|
||||
}
|
||||
static GstElementStateReturn
|
||||
gst_alsa_src_change_state (GstElement *element)
|
||||
gst_alsa_src_change_state (GstElement * element)
|
||||
{
|
||||
GstAlsaSrc *src;
|
||||
|
||||
|
@ -385,7 +400,7 @@ gst_alsa_src_change_state (GstElement *element)
|
|||
case GST_STATE_READY_TO_NULL:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS (src_parent_class)->change_state)
|
||||
|
@ -395,7 +410,7 @@ gst_alsa_src_change_state (GstElement *element)
|
|||
}
|
||||
|
||||
static GstClockTime
|
||||
gst_alsa_src_get_time (GstAlsa *this)
|
||||
gst_alsa_src_get_time (GstAlsa * this)
|
||||
{
|
||||
snd_pcm_sframes_t delay;
|
||||
|
||||
|
@ -405,4 +420,3 @@ gst_alsa_src_get_time (GstAlsa *this)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,29 +25,28 @@
|
|||
#include "gstalsa.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_ALSA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA_SRC, GstAlsaSrc))
|
||||
#define GST_ALSA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA_SRC, GstAlsaSrcClass))
|
||||
#define GST_IS_ALSA_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA_SRC))
|
||||
#define GST_IS_ALSA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA_SRC))
|
||||
#define GST_TYPE_ALSA_SRC (gst_alsa_src_get_type())
|
||||
|
||||
typedef struct _GstAlsaSrc GstAlsaSrc;
|
||||
typedef struct _GstAlsaSrcClass GstAlsaSrcClass;
|
||||
|
||||
struct _GstAlsaSrc {
|
||||
struct _GstAlsaSrc
|
||||
{
|
||||
GstAlsa parent;
|
||||
GstBuffer *buf[GST_ALSA_MAX_TRACKS];
|
||||
};
|
||||
|
||||
struct _GstAlsaSrcClass {
|
||||
struct _GstAlsaSrcClass
|
||||
{
|
||||
GstAlsaClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_alsa_src_get_type (void);
|
||||
|
||||
gboolean gst_alsa_src_factory_init (GstPlugin *plugin);
|
||||
gboolean gst_alsa_src_factory_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ALSA_SRC_H__ */
|
||||
|
|
|
@ -53,21 +53,19 @@ static GstElementDetails cdparanoia_details = {
|
|||
};
|
||||
|
||||
static GstStaticPadTemplate cdparanoia_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
"audio/x-raw-int, "
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"signed = (boolean) true, "
|
||||
"width = (int) 16, "
|
||||
"depth = (int) 16, "
|
||||
"rate = (int) 44100, "
|
||||
"channels = (int) 2, "
|
||||
"chunksize = (int) " G_STRINGIFY(CD_FRAMESIZE_RAW)
|
||||
"chunksize = (int) " G_STRINGIFY (CD_FRAMESIZE_RAW)
|
||||
)
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
/********** Define useful types for non-programmatic interfaces **********/
|
||||
|
@ -77,14 +75,15 @@ gst_paranoia_mode_get_type (void)
|
|||
{
|
||||
static GType paranoia_mode_type = 0;
|
||||
static GEnumValue paranoia_modes[] = {
|
||||
{ PARANOIA_MODE_DISABLE, "0", "Disable paranoid checking"},
|
||||
{ PARANOIA_MODE_OVERLAP, "4", "cdda2wav-style overlap checking"},
|
||||
{ PARANOIA_MODE_FULL, "255", "Full paranoia"},
|
||||
{PARANOIA_MODE_DISABLE, "0", "Disable paranoid checking"},
|
||||
{PARANOIA_MODE_OVERLAP, "4", "cdda2wav-style overlap checking"},
|
||||
{PARANOIA_MODE_FULL, "255", "Full paranoia"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
if (!paranoia_mode_type) {
|
||||
paranoia_mode_type = g_enum_register_static ("GstParanoiaMode", paranoia_modes);
|
||||
paranoia_mode_type =
|
||||
g_enum_register_static ("GstParanoiaMode", paranoia_modes);
|
||||
}
|
||||
return paranoia_mode_type;
|
||||
}
|
||||
|
@ -95,13 +94,14 @@ gst_paranoia_endian_get_type (void)
|
|||
{
|
||||
static GType paranoia_endian_type = 0;
|
||||
static GEnumValue paranoia_endians[] = {
|
||||
{ 0, "0", "treat drive as little endian"},
|
||||
{ 1, "1", "treat drive as big endian"},
|
||||
{ 0, NULL, NULL},
|
||||
{0, "0", "treat drive as little endian"},
|
||||
{1, "1", "treat drive as big endian"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
if (!paranoia_endian_type) {
|
||||
paranoia_endian_type = g_enum_register_static ("GstParanoiaEndian", paranoia_endians);
|
||||
paranoia_endian_type =
|
||||
g_enum_register_static ("GstParanoiaEndian", paranoia_endians);
|
||||
}
|
||||
return paranoia_endian_type;
|
||||
}
|
||||
|
@ -135,34 +135,29 @@ enum
|
|||
};
|
||||
|
||||
static void cdparanoia_base_init (gpointer g_class);
|
||||
static void cdparanoia_class_init (CDParanoiaClass *klass);
|
||||
static void cdparanoia_init (CDParanoia *cdparanoia);
|
||||
static void cdparanoia_class_init (CDParanoiaClass * klass);
|
||||
static void cdparanoia_init (CDParanoia * cdparanoia);
|
||||
|
||||
static void cdparanoia_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static void cdparanoia_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
static void cdparanoia_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void cdparanoia_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstData* cdparanoia_get (GstPad *pad);
|
||||
static gboolean cdparanoia_event (GstPad *pad, GstEvent *event);
|
||||
static const GstEventMask*
|
||||
cdparanoia_get_event_mask (GstPad *pad);
|
||||
static const GstFormat*
|
||||
cdparanoia_get_formats (GstPad *pad);
|
||||
static gboolean cdparanoia_convert (GstPad *pad,
|
||||
static GstData *cdparanoia_get (GstPad * pad);
|
||||
static gboolean cdparanoia_event (GstPad * pad, GstEvent * event);
|
||||
static const GstEventMask *cdparanoia_get_event_mask (GstPad * pad);
|
||||
static const GstFormat *cdparanoia_get_formats (GstPad * pad);
|
||||
static gboolean cdparanoia_convert (GstPad * pad,
|
||||
GstFormat src_format,
|
||||
gint64 src_value,
|
||||
GstFormat *dest_format,
|
||||
gint64 *dest_value);
|
||||
static gboolean cdparanoia_query (GstPad *pad, GstQueryType type,
|
||||
GstFormat *format, gint64 *value);
|
||||
static const GstQueryType*
|
||||
cdparanoia_get_query_types (GstPad *pad);
|
||||
static void cdparanoia_set_index (GstElement *element, GstIndex *index);
|
||||
static GstIndex *cdparanoia_get_index (GstElement *element);
|
||||
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
|
||||
static gboolean cdparanoia_query (GstPad * pad, GstQueryType type,
|
||||
GstFormat * format, gint64 * value);
|
||||
static const GstQueryType *cdparanoia_get_query_types (GstPad * pad);
|
||||
static void cdparanoia_set_index (GstElement * element, GstIndex * index);
|
||||
static GstIndex *cdparanoia_get_index (GstElement * element);
|
||||
|
||||
|
||||
static GstElementStateReturn cdparanoia_change_state (GstElement *element);
|
||||
static GstElementStateReturn cdparanoia_change_state (GstElement * element);
|
||||
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
@ -189,7 +184,9 @@ cdparanoia_get_type (void)
|
|||
(GInstanceInitFunc) cdparanoia_init,
|
||||
};
|
||||
|
||||
cdparanoia_type = g_type_register_static (GST_TYPE_ELEMENT, "CDParanoia", &cdparanoia_info, 0);
|
||||
cdparanoia_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "CDParanoia",
|
||||
&cdparanoia_info, 0);
|
||||
|
||||
/* Register the track format */
|
||||
track_format = gst_format_register ("track", "CD track");
|
||||
|
@ -210,7 +207,7 @@ cdparanoia_base_init (gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
cdparanoia_class_init (CDParanoiaClass *klass)
|
||||
cdparanoia_class_init (CDParanoiaClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -224,61 +221,63 @@ cdparanoia_class_init (CDParanoiaClass *klass)
|
|||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
cdparanoia_signals[SMILIE_CHANGE] =
|
||||
g_signal_new ("smilie-change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (CDParanoiaClass, smilie_change), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
g_signal_new ("smilie-change", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CDParanoiaClass, smilie_change), NULL,
|
||||
NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
cdparanoia_signals[TRANSPORT_ERROR] =
|
||||
g_signal_new ("transport-error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (CDParanoiaClass, transport_error), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
g_signal_new ("transport-error", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CDParanoiaClass, transport_error),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
cdparanoia_signals[UNCORRECTED_ERROR] =
|
||||
g_signal_new ("uncorrected-error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (CDParanoiaClass, uncorrected_error), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
g_signal_new ("uncorrected-error", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CDParanoiaClass, uncorrected_error),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
|
||||
g_param_spec_string ("location", "location", "location",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GENERIC_DEVICE,
|
||||
g_param_spec_string ("generic_device", "Generic device", "Use specified generic scsi device",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
g_param_spec_string ("generic_device", "Generic device",
|
||||
"Use specified generic scsi device", NULL, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEFAULT_SECTORS,
|
||||
g_param_spec_int ("default_sectors", "Default sectors",
|
||||
"Force default number of sectors in read to n sectors",
|
||||
-1, 100, -1, G_PARAM_READWRITE));
|
||||
"Force default number of sectors in read to n sectors", -1, 100, -1,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SEARCH_OVERLAP,
|
||||
g_param_spec_int ("search_overlap", "Search overlap",
|
||||
"Force minimum overlap search during verification to n sectors",
|
||||
-1, 75, -1, G_PARAM_READWRITE));
|
||||
"Force minimum overlap search during verification to n sectors", -1,
|
||||
75, -1, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ENDIAN,
|
||||
g_param_spec_enum ("endian", "Endian", "Force endian on drive",
|
||||
GST_TYPE_PARANOIA_ENDIAN, 0, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_READ_SPEED,
|
||||
g_param_spec_int ("read_speed", "Read speed", "Read from device at specified speed",
|
||||
G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOC_OFFSET,
|
||||
g_param_spec_int("toc_offset", "TOC offset", "Add <n> sectors to the values reported",
|
||||
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOC_BIAS,
|
||||
g_param_spec_boolean("toc_bias", "TOC bias",
|
||||
g_param_spec_int ("read_speed", "Read speed",
|
||||
"Read from device at specified speed", G_MININT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOC_OFFSET,
|
||||
g_param_spec_int ("toc_offset", "TOC offset",
|
||||
"Add <n> sectors to the values reported", G_MININT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOC_BIAS,
|
||||
g_param_spec_boolean ("toc_bias", "TOC bias",
|
||||
"Assume that the beginning offset of track 1 as reported in the TOC "
|
||||
"will be addressed as LBA 0. Necessary for some Toshiba drives to "
|
||||
"get track boundaries",
|
||||
TRUE,G_PARAM_READWRITE));
|
||||
"get track boundaries", TRUE, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NEVER_SKIP,
|
||||
g_param_spec_int ("never_skip", "Never skip",
|
||||
"never accept any less than perfect data reconstruction (don't allow "
|
||||
"'V's) but if [n] is given, skip after [n] retries without progress.",
|
||||
0, G_MAXINT, 0, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ABORT_ON_SKIP,
|
||||
g_param_spec_boolean ("abort_on_skip", "Abort on skip", "Abort on imperfect reads/skips",
|
||||
TRUE, G_PARAM_READWRITE));
|
||||
g_param_spec_boolean ("abort_on_skip", "Abort on skip",
|
||||
"Abort on imperfect reads/skips", TRUE, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARANOIA_MODE,
|
||||
g_param_spec_enum ("paranoia_mode", "Paranoia mode", "Type of checking to perform",
|
||||
GST_TYPE_PARANOIA_MODE, 0, G_PARAM_READWRITE));
|
||||
g_param_spec_enum ("paranoia_mode", "Paranoia mode",
|
||||
"Type of checking to perform", GST_TYPE_PARANOIA_MODE, 0,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DISCID,
|
||||
g_param_spec_string ("discid", "discid", "The dics id",
|
||||
NULL, G_PARAM_READABLE));
|
||||
g_param_spec_string ("discid", "discid", "The dics id", NULL,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
gobject_class->set_property = cdparanoia_set_property;
|
||||
gobject_class->get_property = cdparanoia_get_property;
|
||||
|
@ -289,17 +288,19 @@ cdparanoia_class_init (CDParanoiaClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
cdparanoia_init (CDParanoia *cdparanoia)
|
||||
cdparanoia_init (CDParanoia * cdparanoia)
|
||||
{
|
||||
cdparanoia->srcpad =
|
||||
gst_pad_new_from_template (
|
||||
gst_static_pad_template_get (&cdparanoia_src_template), "src");
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&cdparanoia_src_template), "src");
|
||||
gst_pad_set_get_function (cdparanoia->srcpad, cdparanoia_get);
|
||||
gst_pad_set_event_function (cdparanoia->srcpad, cdparanoia_event);
|
||||
gst_pad_set_event_mask_function (cdparanoia->srcpad, cdparanoia_get_event_mask);
|
||||
gst_pad_set_event_mask_function (cdparanoia->srcpad,
|
||||
cdparanoia_get_event_mask);
|
||||
gst_pad_set_convert_function (cdparanoia->srcpad, cdparanoia_convert);
|
||||
gst_pad_set_query_function (cdparanoia->srcpad, cdparanoia_query);
|
||||
gst_pad_set_query_type_function (cdparanoia->srcpad, cdparanoia_get_query_types);
|
||||
gst_pad_set_query_type_function (cdparanoia->srcpad,
|
||||
cdparanoia_get_query_types);
|
||||
gst_pad_set_formats_function (cdparanoia->srcpad, cdparanoia_get_formats);
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (cdparanoia), cdparanoia->srcpad);
|
||||
|
@ -322,7 +323,8 @@ cdparanoia_init (CDParanoia *cdparanoia)
|
|||
|
||||
|
||||
static void
|
||||
cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
cdparanoia_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
CDParanoia *src;
|
||||
|
||||
|
@ -387,7 +389,8 @@ cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GP
|
|||
}
|
||||
|
||||
static void
|
||||
cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
cdparanoia_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
CDParanoia *src;
|
||||
|
||||
|
@ -437,7 +440,8 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
|
|||
* See cdparanoia/interface/common-interface.c:FixupTOC
|
||||
*/
|
||||
if (src->d && src->d->cd_extra)
|
||||
g_warning("DiscID on multisession discs might be broken. Use at own risk.");
|
||||
g_warning
|
||||
("DiscID on multisession discs might be broken. Use at own risk.");
|
||||
g_value_set_string (value, src->discid);
|
||||
break;
|
||||
default:
|
||||
|
@ -452,7 +456,7 @@ cdparanoia_callback (long inpos, int function)
|
|||
}
|
||||
|
||||
static GstData *
|
||||
cdparanoia_get (GstPad *pad)
|
||||
cdparanoia_get (GstPad * pad)
|
||||
{
|
||||
CDParanoia *src;
|
||||
GstBuffer *buf;
|
||||
|
@ -467,8 +471,7 @@ cdparanoia_get (GstPad *pad)
|
|||
|
||||
buf = GST_BUFFER (gst_event_new (GST_EVENT_EOS));
|
||||
gst_element_set_eos (GST_ELEMENT (src));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gint16 *cdda_buf;
|
||||
gint64 timestamp;
|
||||
GstFormat format;
|
||||
|
@ -479,8 +482,7 @@ cdparanoia_get (GstPad *pad)
|
|||
/* convert the sequence sector number to a timestamp */
|
||||
format = GST_FORMAT_TIME;
|
||||
timestamp = 0LL;
|
||||
gst_pad_convert (src->srcpad, sector_format, src->seq,
|
||||
&format, ×tamp);
|
||||
gst_pad_convert (src->srcpad, sector_format, src->seq, &format, ×tamp);
|
||||
|
||||
/* have to copy the buffer for now since we don't own it... */
|
||||
/* FIXME must ask monty about allowing ownership transfer */
|
||||
|
@ -512,7 +514,7 @@ toc_msf;
|
|||
/* cdparanoia provides the toc in lba format dang we need it in msf so
|
||||
* we have to convert it */
|
||||
static inline void
|
||||
lba_to_msf (const gint lba, byte *m, byte *s, byte *f)
|
||||
lba_to_msf (const gint lba, byte * m, byte * s, byte * f)
|
||||
{
|
||||
gint lba2 = lba;
|
||||
|
||||
|
@ -527,12 +529,13 @@ lba_to_msf (const gint lba, byte *m, byte *s, byte *f)
|
|||
}
|
||||
|
||||
static void
|
||||
lba_toc_to_msf_toc (TOC *lba_toc, toc_msf *msf_toc, gint tracks)
|
||||
lba_toc_to_msf_toc (TOC * lba_toc, toc_msf * msf_toc, gint tracks)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i <= tracks; i++)
|
||||
lba_to_msf (lba_toc[i].dwStartSector, &msf_toc[i].m, &msf_toc[i].s, &msf_toc[i].f);
|
||||
lba_to_msf (lba_toc[i].dwStartSector, &msf_toc[i].m, &msf_toc[i].s,
|
||||
&msf_toc[i].f);
|
||||
}
|
||||
|
||||
/* the cddb hash function */
|
||||
|
@ -550,7 +553,7 @@ cddb_sum (gint n)
|
|||
}
|
||||
|
||||
static void
|
||||
cddb_discid (gchar *discid, toc_msf *toc, gint tracks)
|
||||
cddb_discid (gchar * discid, toc_msf * toc, gint tracks)
|
||||
{
|
||||
guint i = 0, t = 0, n = 0;
|
||||
|
||||
|
@ -565,7 +568,8 @@ cddb_discid (gchar *discid, toc_msf *toc, gint tracks)
|
|||
|
||||
/* get all the cddb info at once */
|
||||
static void
|
||||
get_cddb_info (TOC *toc, gint tracks, gchar *discid, gint64 *offsets, gint64 *total_seconds)
|
||||
get_cddb_info (TOC * toc, gint tracks, gchar * discid, gint64 * offsets,
|
||||
gint64 * total_seconds)
|
||||
{
|
||||
toc_msf msf_toc[MAXTRK];
|
||||
gint i;
|
||||
|
@ -583,7 +587,7 @@ get_cddb_info (TOC *toc, gint tracks, gchar *discid, gint64 *offsets, gint64 *to
|
|||
}
|
||||
|
||||
static void
|
||||
add_index_associations (CDParanoia *src)
|
||||
add_index_associations (CDParanoia * src)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -595,14 +599,15 @@ add_index_associations (CDParanoia *src)
|
|||
GST_ASSOCIATION_FLAG_KEY_UNIT,
|
||||
track_format, i,
|
||||
sector_format, sector,
|
||||
GST_FORMAT_TIME, (gint64) (((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100),
|
||||
GST_FORMAT_BYTES, (gint64) (sector << 2),
|
||||
GST_FORMAT_DEFAULT, (gint64) ((CD_FRAMESIZE_RAW >> 2) * sector),
|
||||
NULL);
|
||||
GST_FORMAT_TIME,
|
||||
(gint64) (((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100),
|
||||
GST_FORMAT_BYTES, (gint64) (sector << 2), GST_FORMAT_DEFAULT,
|
||||
(gint64) ((CD_FRAMESIZE_RAW >> 2) * sector), NULL);
|
||||
#if 0
|
||||
g_print ("Added association for track %d\n", i + 1);
|
||||
g_print ("Sector: %lld\n", sector);
|
||||
g_print ("Time: %lld\n", (gint64) (((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100));
|
||||
g_print ("Time: %lld\n",
|
||||
(gint64) (((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100));
|
||||
g_print ("Bytes: %lld\n", (gint64) (sector << 2));
|
||||
g_print ("Units: %lld\n", (gint64) ((CD_FRAMESIZE_RAW >> 2) * sector));
|
||||
g_print ("-----------\n");
|
||||
|
@ -612,7 +617,7 @@ add_index_associations (CDParanoia *src)
|
|||
|
||||
/* open the file, necessary to go to RUNNING state */
|
||||
static gboolean
|
||||
cdparanoia_open (CDParanoia *src)
|
||||
cdparanoia_open (CDParanoia * src)
|
||||
{
|
||||
gint i;
|
||||
gint paranoia_mode;
|
||||
|
@ -635,8 +640,7 @@ cdparanoia_open (CDParanoia *src)
|
|||
/* fail if the device couldn't be found */
|
||||
if (src->d == NULL) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
|
||||
(_("Could not open CD device for reading.")),
|
||||
("cdda_identify failed"));
|
||||
(_("Could not open CD device for reading.")), ("cdda_identify failed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -652,8 +656,7 @@ cdparanoia_open (CDParanoia *src)
|
|||
/* open the disc */
|
||||
if (cdda_open (src->d)) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
|
||||
(_("Could not open CD device for reading.")),
|
||||
("cdda_open failed"));
|
||||
(_("Could not open CD device for reading.")), ("cdda_open failed"));
|
||||
cdda_close (src->d);
|
||||
src->d = NULL;
|
||||
return FALSE;
|
||||
|
@ -723,7 +726,7 @@ cdparanoia_open (CDParanoia *src)
|
|||
|
||||
/* close the file */
|
||||
static void
|
||||
cdparanoia_close (CDParanoia *src)
|
||||
cdparanoia_close (CDParanoia * src)
|
||||
{
|
||||
g_return_if_fail (GST_FLAG_IS_SET (src, CDPARANOIA_OPEN));
|
||||
|
||||
|
@ -740,7 +743,7 @@ cdparanoia_close (CDParanoia *src)
|
|||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
cdparanoia_change_state (GstElement *element)
|
||||
cdparanoia_change_state (GstElement * element)
|
||||
{
|
||||
CDParanoia *cdparanoia;
|
||||
|
||||
|
@ -780,17 +783,13 @@ cdparanoia_change_state (GstElement *element)
|
|||
}
|
||||
|
||||
static const GstEventMask *
|
||||
cdparanoia_get_event_mask (GstPad *pad)
|
||||
cdparanoia_get_event_mask (GstPad * pad)
|
||||
{
|
||||
static const GstEventMask masks[] = {
|
||||
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_METHOD_CUR |
|
||||
GST_SEEK_METHOD_END |
|
||||
GST_SEEK_FLAG_FLUSH },
|
||||
GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
|
||||
{GST_EVENT_SEEK_SEGMENT, GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_METHOD_CUR |
|
||||
GST_SEEK_METHOD_END |
|
||||
GST_SEEK_FLAG_FLUSH },
|
||||
GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH},
|
||||
{0,}
|
||||
};
|
||||
|
||||
|
@ -798,7 +797,7 @@ cdparanoia_get_event_mask (GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
cdparanoia_event (GstPad *pad, GstEvent *event)
|
||||
cdparanoia_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
CDParanoia *src;
|
||||
gboolean res = TRUE;
|
||||
|
@ -871,8 +870,7 @@ cdparanoia_event (GstPad *pad, GstEvent *event)
|
|||
|
||||
src->segment_start_sector = seg_start_sector;
|
||||
src->cur_sector = src->segment_start_sector;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -882,8 +880,7 @@ cdparanoia_event (GstPad *pad, GstEvent *event)
|
|||
src->segment_end_sector = seg_end_sector;
|
||||
}
|
||||
GST_DEBUG ("configured for %d -> %d sectors\n",
|
||||
src->segment_start_sector,
|
||||
src->segment_end_sector);
|
||||
src->segment_start_sector, src->segment_end_sector);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -900,7 +897,7 @@ cdparanoia_event (GstPad *pad, GstEvent *event)
|
|||
}
|
||||
|
||||
static const GstFormat *
|
||||
cdparanoia_get_formats (GstPad *pad)
|
||||
cdparanoia_get_formats (GstPad * pad)
|
||||
{
|
||||
static GstFormat formats[] = {
|
||||
GST_FORMAT_TIME,
|
||||
|
@ -918,9 +915,9 @@ cdparanoia_get_formats (GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
cdparanoia_convert (GstPad *pad,
|
||||
cdparanoia_convert (GstPad * pad,
|
||||
GstFormat src_format, gint64 src_value,
|
||||
GstFormat *dest_format, gint64 *dest_value)
|
||||
GstFormat * dest_format, gint64 * dest_value)
|
||||
{
|
||||
CDParanoia *src;
|
||||
|
||||
|
@ -940,16 +937,15 @@ cdparanoia_convert (GstPad *pad,
|
|||
break;
|
||||
default:
|
||||
if (*dest_format == track_format || *dest_format == sector_format) {
|
||||
gint sector = (src_value * 44100) / ((CD_FRAMESIZE_RAW >> 2) * GST_SECOND);
|
||||
gint sector =
|
||||
(src_value * 44100) / ((CD_FRAMESIZE_RAW >> 2) * GST_SECOND);
|
||||
|
||||
if (*dest_format == sector_format) {
|
||||
*dest_value = sector;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*dest_value = cdda_sector_gettrack (src->d, sector) - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -970,12 +966,10 @@ cdparanoia_convert (GstPad *pad,
|
|||
|
||||
if (*dest_format == track_format) {
|
||||
*dest_value = cdda_sector_gettrack (src->d, sector) - 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*dest_value = sector;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -990,11 +984,9 @@ cdparanoia_convert (GstPad *pad,
|
|||
return FALSE;
|
||||
|
||||
sector = cdda_track_firstsector (src->d, src_value + 1);
|
||||
}
|
||||
else if (src_format == sector_format) {
|
||||
} else if (src_format == sector_format) {
|
||||
sector = src_value;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1010,15 +1002,13 @@ cdparanoia_convert (GstPad *pad,
|
|||
default:
|
||||
if (*dest_format == sector_format) {
|
||||
*dest_value = sector;
|
||||
}
|
||||
else if (*dest_format == track_format) {
|
||||
} else if (*dest_format == track_format) {
|
||||
/* if we go past the last sector, make sure to report the last track */
|
||||
if (sector > src->last_sector)
|
||||
*dest_value = cdda_sector_gettrack (src->d, src->last_sector);
|
||||
else
|
||||
*dest_value = cdda_sector_gettrack (src->d, sector) - 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
@ -1030,8 +1020,8 @@ cdparanoia_convert (GstPad *pad,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static const GstQueryType*
|
||||
cdparanoia_get_query_types (GstPad *pad)
|
||||
static const GstQueryType *
|
||||
cdparanoia_get_query_types (GstPad * pad)
|
||||
{
|
||||
static const GstQueryType src_query_types[] = {
|
||||
GST_QUERY_TOTAL,
|
||||
|
@ -1044,8 +1034,8 @@ cdparanoia_get_query_types (GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
cdparanoia_query (GstPad *pad, GstQueryType type,
|
||||
GstFormat *format, gint64 *value)
|
||||
cdparanoia_query (GstPad * pad, GstQueryType type,
|
||||
GstFormat * format, gint64 * value)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
CDParanoia *src;
|
||||
|
@ -1061,24 +1051,20 @@ cdparanoia_query (GstPad *pad, GstQueryType type,
|
|||
/* we take the last sector + 1 so that we also have the full
|
||||
* size of that last sector */
|
||||
res = gst_pad_convert (src->srcpad,
|
||||
sector_format, src->last_sector + 1,
|
||||
format, value);
|
||||
sector_format, src->last_sector + 1, format, value);
|
||||
break;
|
||||
case GST_QUERY_POSITION:
|
||||
/* bring our current sector to the requested format */
|
||||
res = gst_pad_convert (src->srcpad,
|
||||
sector_format, src->cur_sector,
|
||||
format, value);
|
||||
sector_format, src->cur_sector, format, value);
|
||||
break;
|
||||
case GST_QUERY_START:
|
||||
res = gst_pad_convert (src->srcpad,
|
||||
sector_format, src->segment_start_sector,
|
||||
format, value);
|
||||
sector_format, src->segment_start_sector, format, value);
|
||||
break;
|
||||
case GST_QUERY_SEGMENT_END:
|
||||
res = gst_pad_convert (src->srcpad,
|
||||
sector_format, src->segment_end_sector,
|
||||
format, value);
|
||||
sector_format, src->segment_end_sector, format, value);
|
||||
break;
|
||||
default:
|
||||
res = FALSE;
|
||||
|
@ -1088,8 +1074,7 @@ cdparanoia_query (GstPad *pad, GstQueryType type,
|
|||
}
|
||||
|
||||
static void
|
||||
cdparanoia_set_index (GstElement *element,
|
||||
GstIndex *index)
|
||||
cdparanoia_set_index (GstElement * element, GstIndex * index)
|
||||
{
|
||||
CDParanoia *cdparanoia;
|
||||
|
||||
|
@ -1104,7 +1089,7 @@ cdparanoia_set_index (GstElement *element,
|
|||
}
|
||||
|
||||
static GstIndex *
|
||||
cdparanoia_get_index (GstElement *element)
|
||||
cdparanoia_get_index (GstElement * element)
|
||||
{
|
||||
CDParanoia *cdparanoia;
|
||||
|
||||
|
@ -1114,21 +1099,17 @@ cdparanoia_get_index (GstElement *element)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_element_register (plugin, "cdparanoia", GST_RANK_NONE, GST_TYPE_CDPARANOIA))
|
||||
if (!gst_element_register (plugin, "cdparanoia", GST_RANK_NONE,
|
||||
GST_TYPE_CDPARANOIA))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"cdparanoia",
|
||||
"Read audio from CD in paranoid mode",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"GPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN)
|
||||
plugin_init, VERSION, "GPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -26,18 +26,19 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define size16 gint16
|
||||
#define size32 gint32
|
||||
|
||||
#ifdef CDPARANOIA_HEADERS_IN_DIR
|
||||
#include <cdda/cdda_interface.h>
|
||||
#include <cdda/cdda_paranoia.h>
|
||||
#include <cdda/cdda_interface.h>
|
||||
#include <cdda/cdda_paranoia.h>
|
||||
#else
|
||||
#include <cdda_interface.h>
|
||||
#include <cdda_paranoia.h>
|
||||
#include <cdda_interface.h>
|
||||
#include <cdda_paranoia.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -57,16 +58,18 @@ extern "C" {
|
|||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDPARANOIA))
|
||||
|
||||
/* NOTE: per-element flags start with 16 for now */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
CDPARANOIA_OPEN = GST_ELEMENT_FLAG_LAST,
|
||||
|
||||
CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2,
|
||||
} CDParanoiaFlags;
|
||||
CDPARANOIA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
|
||||
} CDParanoiaFlags;
|
||||
|
||||
typedef struct _CDParanoia CDParanoia;
|
||||
typedef struct _CDParanoiaClass CDParanoiaClass;
|
||||
typedef struct _CDParanoia CDParanoia;
|
||||
typedef struct _CDParanoiaClass CDParanoiaClass;
|
||||
|
||||
struct _CDParanoia {
|
||||
struct _CDParanoia
|
||||
{
|
||||
GstElement element;
|
||||
/* pads */
|
||||
GstPad *srcpad;
|
||||
|
@ -104,18 +107,19 @@ struct _CDParanoia {
|
|||
|
||||
gint seq;
|
||||
gboolean discont_pending;
|
||||
};
|
||||
};
|
||||
|
||||
struct _CDParanoiaClass {
|
||||
struct _CDParanoiaClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* signal callbacks */
|
||||
void (*smilie_change) (CDParanoia *cdparanoia, gchar *smilie);
|
||||
void (*transport_error) (CDParanoia *cdparanoia, gint offset);
|
||||
void (*uncorrected_error) (CDParanoia *cdparanoia, gint offset);
|
||||
};
|
||||
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);
|
||||
GType cdparanoia_get_type (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,15 +29,14 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
static gboolean
|
||||
plugin_init(GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
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_RANK_SECONDARY, gst_gnomevfssink_get_type())) {
|
||||
GST_RANK_SECONDARY, gst_gnomevfssink_get_type ())) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
|
@ -46,15 +45,8 @@ plugin_init(GstPlugin *plugin)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gnomevfs",
|
||||
"elements to access the Gnome vfs",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
GST_LICENSE,
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -23,13 +23,9 @@
|
|||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType gst_gnomevfssink_get_type (void);
|
||||
G_BEGIN_DECLS GType gst_gnomevfssink_get_type (void);
|
||||
GType gst_gnomevfssrc_get_type (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GNOME_VFS_H__ */
|
||||
|
|
|
@ -51,13 +51,15 @@
|
|||
typedef struct _GstGnomeVFSSink GstGnomeVFSSink;
|
||||
typedef struct _GstGnomeVFSSinkClass GstGnomeVFSSinkClass;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_GNOMEVFSSINK_OPEN = GST_ELEMENT_FLAG_LAST,
|
||||
|
||||
GST_GNOMEVFSSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
|
||||
} GstGnomeVFSSinkFlags;
|
||||
|
||||
struct _GstGnomeVFSSink {
|
||||
struct _GstGnomeVFSSink
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
/* filename */
|
||||
|
@ -70,32 +72,34 @@ struct _GstGnomeVFSSink {
|
|||
gboolean erase;
|
||||
};
|
||||
|
||||
struct _GstGnomeVFSSinkClass {
|
||||
struct _GstGnomeVFSSinkClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*handoff) (GstElement *element,GstPad *pad);
|
||||
void (*erase_ask) (GstElement *element,GstPad *pad);
|
||||
void (*handoff) (GstElement * element, GstPad * pad);
|
||||
void (*erase_ask) (GstElement * element, GstPad * pad);
|
||||
};
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_gnomevfssink_details = GST_ELEMENT_DETAILS (
|
||||
"GnomeVFS Sink",
|
||||
static GstElementDetails gst_gnomevfssink_details =
|
||||
GST_ELEMENT_DETAILS ("GnomeVFS Sink",
|
||||
"Sink/File",
|
||||
"Write stream to a GnomeVFS URI",
|
||||
"Bastien Nocera <hadess@hadess.net>"
|
||||
);
|
||||
"Bastien Nocera <hadess@hadess.net>");
|
||||
|
||||
|
||||
/* GnomeVFSSink signals and args */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_HANDOFF,
|
||||
SIGNAL_ERASE_ASK,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_LOCATION,
|
||||
ARG_HANDLE,
|
||||
|
@ -104,18 +108,21 @@ enum {
|
|||
|
||||
|
||||
static void gst_gnomevfssink_base_init (gpointer g_class);
|
||||
static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass);
|
||||
static void gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink);
|
||||
static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass);
|
||||
static void gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink);
|
||||
|
||||
static void gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
static void gst_gnomevfssink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gnomevfssink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_gnomevfssink_open_file (GstGnomeVFSSink *sink);
|
||||
static void gst_gnomevfssink_close_file (GstGnomeVFSSink *sink);
|
||||
static gboolean gst_gnomevfssink_open_file (GstGnomeVFSSink * sink);
|
||||
static void gst_gnomevfssink_close_file (GstGnomeVFSSink * sink);
|
||||
|
||||
static void gst_gnomevfssink_chain (GstPad *pad,GstData *_data);
|
||||
static void gst_gnomevfssink_chain (GstPad * pad, GstData * _data);
|
||||
|
||||
static GstElementStateReturn gst_gnomevfssink_change_state (GstElement *element);
|
||||
static GstElementStateReturn gst_gnomevfssink_change_state (GstElement *
|
||||
element);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static guint gst_gnomevfssink_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -127,17 +134,19 @@ gst_gnomevfssink_get_type (void)
|
|||
|
||||
if (!gnomevfssink_type) {
|
||||
static const GTypeInfo gnomevfssink_info = {
|
||||
sizeof(GstGnomeVFSSinkClass),
|
||||
sizeof (GstGnomeVFSSinkClass),
|
||||
gst_gnomevfssink_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc)gst_gnomevfssink_class_init,
|
||||
(GClassInitFunc) gst_gnomevfssink_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GstGnomeVFSSink),
|
||||
sizeof (GstGnomeVFSSink),
|
||||
0,
|
||||
(GInstanceInitFunc)gst_gnomevfssink_init,
|
||||
(GInstanceInitFunc) gst_gnomevfssink_init,
|
||||
};
|
||||
gnomevfssink_type = g_type_register_static (GST_TYPE_ELEMENT, "GstGnomeVFSSink", &gnomevfssink_info, 0);
|
||||
gnomevfssink_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstGnomeVFSSink",
|
||||
&gnomevfssink_info, 0);
|
||||
}
|
||||
return gnomevfssink_type;
|
||||
}
|
||||
|
@ -151,36 +160,32 @@ gst_gnomevfssink_base_init (gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass)
|
||||
gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
|
||||
gst_element_class_install_std_props (
|
||||
GST_ELEMENT_CLASS (klass),
|
||||
"location", ARG_LOCATION, G_PARAM_READWRITE,
|
||||
NULL);
|
||||
gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
|
||||
"location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
ARG_HANDLE,
|
||||
g_param_spec_pointer ("handle",
|
||||
"GnomeVFSHandle",
|
||||
"Handle for GnomeVFS",
|
||||
G_PARAM_READWRITE));
|
||||
"GnomeVFSHandle", "Handle for GnomeVFS", G_PARAM_READWRITE));
|
||||
|
||||
gst_gnomevfssink_signals[SIGNAL_HANDOFF] =
|
||||
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
|
||||
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstGnomeVFSSinkClass, handoff), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||
|
||||
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK] =
|
||||
g_signal_new ("erase-ask", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
|
||||
g_signal_new ("erase-ask", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstGnomeVFSSinkClass, erase_ask), NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||
|
||||
|
@ -191,14 +196,15 @@ gst_gnomevfssink_class_init (GstGnomeVFSSinkClass *klass)
|
|||
gstelement_class->change_state = gst_gnomevfssink_change_state;
|
||||
|
||||
/* gnome vfs engine init */
|
||||
if (gnome_vfs_initialized() == FALSE)
|
||||
gnome_vfs_init();
|
||||
if (gnome_vfs_initialized () == FALSE)
|
||||
gnome_vfs_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink)
|
||||
gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink)
|
||||
{
|
||||
GstPad *pad;
|
||||
|
||||
pad = gst_pad_new ("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad (GST_ELEMENT (gnomevfssink), pad);
|
||||
gst_pad_set_chain_function (pad, gst_gnomevfssink_chain);
|
||||
|
@ -210,7 +216,8 @@ gst_gnomevfssink_init (GstGnomeVFSSink *gnomevfssink)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
gst_gnomevfssink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstGnomeVFSSink *sink;
|
||||
|
||||
|
@ -238,7 +245,8 @@ gst_gnomevfssink_set_property (GObject *object, guint prop_id, const GValue *val
|
|||
}
|
||||
|
||||
static void
|
||||
gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
gst_gnomevfssink_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstGnomeVFSSink *sink;
|
||||
|
||||
|
@ -263,7 +271,7 @@ gst_gnomevfssink_get_property (GObject *object, guint prop_id, GValue *value, GP
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
|
||||
gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
|
||||
{
|
||||
GnomeVFSResult result;
|
||||
|
||||
|
@ -271,16 +279,15 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
|
|||
|
||||
if (sink->filename) {
|
||||
/* 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_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE
|
||||
| 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 (sink->erase == FALSE) {
|
||||
g_signal_emit (G_OBJECT (sink),
|
||||
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK], 0,
|
||||
sink->erase);
|
||||
gst_gnomevfssink_signals[SIGNAL_ERASE_ASK], 0, sink->erase);
|
||||
}
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
|
||||
(_("Could not open vfs file \"%s\" for writing."), sink->filename),
|
||||
|
@ -296,7 +303,7 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink *sink)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
|
||||
gst_gnomevfssink_close_file (GstGnomeVFSSink * sink)
|
||||
{
|
||||
GnomeVFSResult result;
|
||||
|
||||
|
@ -304,7 +311,7 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
|
|||
|
||||
if (sink->filename) {
|
||||
/* close the file */
|
||||
result = gnome_vfs_close(sink->handle);
|
||||
result = gnome_vfs_close (sink->handle);
|
||||
|
||||
if (result != GNOME_VFS_OK)
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
|
||||
|
@ -323,7 +330,7 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink *sink)
|
|||
* take the buffer from the pad and write to file if it's open
|
||||
*/
|
||||
static void
|
||||
gst_gnomevfssink_chain (GstPad *pad, GstData *_data)
|
||||
gst_gnomevfssink_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstGnomeVFSSink *sink;
|
||||
|
@ -336,14 +343,16 @@ gst_gnomevfssink_chain (GstPad *pad, GstData *_data)
|
|||
|
||||
sink = GST_GNOMEVFSSINK (gst_pad_get_parent (pad));
|
||||
|
||||
if (GST_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN))
|
||||
{
|
||||
result = gnome_vfs_write(sink->handle, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE (buf), &bytes_written);
|
||||
GST_DEBUG ("write: %s, written_bytes: %" G_GUINT64_FORMAT, gnome_vfs_result_to_string(result), bytes_written);
|
||||
if (bytes_written < GST_BUFFER_SIZE (buf))
|
||||
{
|
||||
printf ("gnomevfssink : Warning : %d bytes should be written, only %" G_GUINT64_FORMAT " bytes written\n",
|
||||
GST_BUFFER_SIZE (buf), bytes_written);
|
||||
if (GST_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN)) {
|
||||
result =
|
||||
gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
|
||||
GST_BUFFER_SIZE (buf), &bytes_written);
|
||||
GST_DEBUG ("write: %s, written_bytes: %" G_GUINT64_FORMAT,
|
||||
gnome_vfs_result_to_string (result), bytes_written);
|
||||
if (bytes_written < GST_BUFFER_SIZE (buf)) {
|
||||
printf ("gnomevfssink : Warning : %d bytes should be written, only %"
|
||||
G_GUINT64_FORMAT " bytes written\n", GST_BUFFER_SIZE (buf),
|
||||
bytes_written);
|
||||
}
|
||||
}
|
||||
gst_buffer_unref (buf);
|
||||
|
@ -353,7 +362,7 @@ gst_gnomevfssink_chain (GstPad *pad, GstData *_data)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -372,4 +381,3 @@ gst_gnomevfssink_change_state (GstElement *element)
|
|||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -40,7 +40,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_ogg_demux_debug);
|
|||
typedef struct _GstOggDemux GstOggDemux;
|
||||
typedef struct _GstOggDemuxClass GstOggDemuxClass;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
/* just because you shouldn't make a valid enum value 0 */
|
||||
GST_OGG_STATE_INAVLID,
|
||||
/* just started, we need to decide if we should do setup */
|
||||
|
@ -54,8 +55,9 @@ typedef enum {
|
|||
} GstOggState;
|
||||
|
||||
/* all information needed for one ogg stream */
|
||||
typedef struct {
|
||||
GstPad * pad; /* reference for this pad is held by element we belong to */
|
||||
typedef struct
|
||||
{
|
||||
GstPad *pad; /* reference for this pad is held by element we belong to */
|
||||
|
||||
gint serial;
|
||||
ogg_stream_state stream;
|
||||
|
@ -69,16 +71,19 @@ typedef struct {
|
|||
guint flags;
|
||||
} GstOggPad;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_OGG_PAD_NEEDS_DISCONT = (1 << 0),
|
||||
GST_OGG_PAD_NEEDS_FLUSH = (1 << 1)
|
||||
}
|
||||
GstOggPadFlags;
|
||||
|
||||
/* all information needed for one ogg chain (relevant for chained bitstreams) */
|
||||
typedef struct {
|
||||
GSList * pads; /* list of GstOggPad */
|
||||
typedef struct
|
||||
{
|
||||
GSList *pads; /* list of GstOggPad */
|
||||
} GstOggChain;
|
||||
|
||||
#define CURRENT_CHAIN(ogg) (&g_array_index ((ogg)->chains, GstOggChain, (ogg)->current_chain))
|
||||
#define FOR_PAD_IN_CURRENT_CHAIN(ogg, _pad, ...) G_STMT_START{ \
|
||||
GSList *_walk; \
|
||||
|
@ -88,21 +93,23 @@ typedef struct {
|
|||
} \
|
||||
}G_STMT_END
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_OGG_FLAG_BOS = GST_ELEMENT_FLAG_LAST,
|
||||
GST_OGG_FLAG_EOS,
|
||||
GST_OGG_FLAG_WAIT_FOR_DISCONT
|
||||
} GstOggFlag;
|
||||
|
||||
struct _GstOggDemux {
|
||||
struct _GstOggDemux
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
/* pad */
|
||||
GstPad * sinkpad;
|
||||
GstPad *sinkpad;
|
||||
|
||||
/* state */
|
||||
GstOggState state;
|
||||
GArray * chains;
|
||||
GArray *chains;
|
||||
gint current_chain;
|
||||
guint flags;
|
||||
|
||||
|
@ -110,80 +117,70 @@ struct _GstOggDemux {
|
|||
ogg_sync_state sync;
|
||||
|
||||
/* seeking */
|
||||
GstOggPad * seek_pad;
|
||||
GstOggPad *seek_pad;
|
||||
guint64 seek_to;
|
||||
};
|
||||
|
||||
struct _GstOggDemuxClass {
|
||||
struct _GstOggDemuxClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_ogg_demux_details = GST_ELEMENT_DETAILS (
|
||||
"ogg demuxer",
|
||||
static GstElementDetails gst_ogg_demux_details =
|
||||
GST_ELEMENT_DETAILS ("ogg demuxer",
|
||||
"Codec/Demuxer",
|
||||
"demux ogg streams (info about ogg: http://xiph.org)",
|
||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>"
|
||||
);
|
||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
|
||||
|
||||
|
||||
/* signals and args */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate ogg_demux_src_template_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_SOMETIMES,
|
||||
GST_STATIC_CAPS_ANY
|
||||
);
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GstStaticPadTemplate ogg_demux_sink_template_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/ogg")
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
static void gst_ogg_demux_finalize (GObject * object);
|
||||
|
||||
static gboolean gst_ogg_demux_src_event (GstPad * pad,
|
||||
GstEvent * event);
|
||||
static const GstEventMask* gst_ogg_demux_get_event_masks (GstPad * pad);
|
||||
static const GstQueryType* gst_ogg_demux_get_query_types (GstPad * pad);
|
||||
static gboolean gst_ogg_demux_src_event (GstPad * pad, GstEvent * event);
|
||||
static const GstEventMask *gst_ogg_demux_get_event_masks (GstPad * pad);
|
||||
static const GstQueryType *gst_ogg_demux_get_query_types (GstPad * pad);
|
||||
|
||||
static gboolean gst_ogg_demux_src_query (GstPad * pad,
|
||||
GstQueryType type,
|
||||
GstFormat * format,
|
||||
gint64 * value);
|
||||
GstQueryType type, GstFormat * format, gint64 * value);
|
||||
|
||||
static void gst_ogg_demux_chain (GstPad * pad,
|
||||
GstData * buffer);
|
||||
static void gst_ogg_demux_chain (GstPad * pad, GstData * buffer);
|
||||
|
||||
static GstElementStateReturn gst_ogg_demux_change_state (GstElement * element);
|
||||
|
||||
static GstOggPad * gst_ogg_pad_new (GstOggDemux * ogg,
|
||||
int serial_no);
|
||||
static void gst_ogg_pad_remove (GstOggDemux * ogg,
|
||||
GstOggPad * ogg_pad);
|
||||
static void gst_ogg_pad_reset (GstOggDemux * ogg,
|
||||
GstOggPad * pad);
|
||||
static void gst_ogg_demux_push (GstOggDemux * ogg,
|
||||
ogg_page * page);
|
||||
static void gst_ogg_pad_push (GstOggDemux * ogg,
|
||||
GstOggPad * ogg_pad);
|
||||
static GstOggPad *gst_ogg_pad_new (GstOggDemux * ogg, int serial_no);
|
||||
static void gst_ogg_pad_remove (GstOggDemux * ogg, GstOggPad * ogg_pad);
|
||||
static void gst_ogg_pad_reset (GstOggDemux * ogg, GstOggPad * pad);
|
||||
static void gst_ogg_demux_push (GstOggDemux * ogg, ogg_page * page);
|
||||
static void gst_ogg_pad_push (GstOggDemux * ogg, GstOggPad * ogg_pad);
|
||||
|
||||
static GstCaps * gst_ogg_type_find (ogg_packet * packet);
|
||||
static GstCaps *gst_ogg_type_find (ogg_packet * packet);
|
||||
|
||||
static void gst_ogg_print (GstOggDemux * demux);
|
||||
|
||||
|
@ -194,8 +191,7 @@ static void gst_ogg_print (GstOggDemux * demux);
|
|||
|
||||
GST_BOILERPLATE (GstOggDemux, gst_ogg_demux, GstElement, GST_TYPE_ELEMENT)
|
||||
|
||||
static void
|
||||
gst_ogg_demux_base_init (gpointer g_class)
|
||||
static void gst_ogg_demux_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
|
@ -207,7 +203,7 @@ gst_ogg_demux_base_init (gpointer g_class)
|
|||
gst_static_pad_template_get (&ogg_demux_src_template_factory));
|
||||
}
|
||||
static void
|
||||
gst_ogg_demux_class_init (GstOggDemuxClass *klass)
|
||||
gst_ogg_demux_class_init (GstOggDemuxClass * klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
@ -217,13 +213,15 @@ gst_ogg_demux_class_init (GstOggDemuxClass *klass)
|
|||
gobject_class->finalize = gst_ogg_demux_finalize;
|
||||
}
|
||||
static void
|
||||
gst_ogg_demux_init (GstOggDemux *ogg)
|
||||
gst_ogg_demux_init (GstOggDemux * ogg)
|
||||
{
|
||||
/* create the sink pad */
|
||||
ogg->sinkpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&ogg_demux_sink_template_factory), "sink");
|
||||
ogg->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&ogg_demux_sink_template_factory), "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad);
|
||||
gst_pad_set_chain_function (ogg->sinkpad, GST_DEBUG_FUNCPTR (gst_ogg_demux_chain));
|
||||
gst_pad_set_chain_function (ogg->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_ogg_demux_chain));
|
||||
|
||||
/* initalize variables */
|
||||
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_START);
|
||||
|
@ -233,7 +231,7 @@ gst_ogg_demux_init (GstOggDemux *ogg)
|
|||
GST_FLAG_SET (ogg, GST_ELEMENT_EVENT_AWARE);
|
||||
}
|
||||
static void
|
||||
gst_ogg_demux_finalize (GObject *object)
|
||||
gst_ogg_demux_finalize (GObject * object)
|
||||
{
|
||||
GstOggDemux *ogg;
|
||||
|
||||
|
@ -245,18 +243,17 @@ gst_ogg_demux_finalize (GObject *object)
|
|||
g_array_free (ogg->chains, TRUE);
|
||||
}
|
||||
|
||||
static const GstEventMask*
|
||||
gst_ogg_demux_get_event_masks (GstPad *pad)
|
||||
static const GstEventMask *
|
||||
gst_ogg_demux_get_event_masks (GstPad * pad)
|
||||
{
|
||||
static const GstEventMask gst_ogg_demux_src_event_masks[] = {
|
||||
{ GST_EVENT_SEEK, GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH },
|
||||
{ 0, }
|
||||
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
|
||||
{0,}
|
||||
};
|
||||
return gst_ogg_demux_src_event_masks;
|
||||
}
|
||||
static const GstQueryType*
|
||||
gst_ogg_demux_get_query_types (GstPad *pad)
|
||||
static const GstQueryType *
|
||||
gst_ogg_demux_get_query_types (GstPad * pad)
|
||||
{
|
||||
static const GstQueryType gst_ogg_demux_src_query_types[] = {
|
||||
GST_QUERY_TOTAL,
|
||||
|
@ -267,7 +264,7 @@ gst_ogg_demux_get_query_types (GstPad *pad)
|
|||
}
|
||||
|
||||
static GstOggPad *
|
||||
gst_ogg_get_pad_by_pad (GstOggDemux *ogg, GstPad *pad)
|
||||
gst_ogg_get_pad_by_pad (GstOggDemux * ogg, GstPad * pad)
|
||||
{
|
||||
GSList *walk;
|
||||
GstOggPad *cur;
|
||||
|
@ -285,8 +282,8 @@ gst_ogg_get_pad_by_pad (GstOggDemux *ogg, GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
|
||||
GstFormat *format, gint64 *value)
|
||||
gst_ogg_demux_src_query (GstPad * pad, GstQueryType type,
|
||||
GstFormat * format, gint64 * value)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstOggDemux *ogg = GST_OGG_DEMUX (gst_pad_get_parent (pad));
|
||||
|
@ -296,7 +293,7 @@ gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
|
|||
return FALSE;
|
||||
|
||||
switch (type) {
|
||||
case GST_QUERY_TOTAL: {
|
||||
case GST_QUERY_TOTAL:{
|
||||
if (*format == GST_FORMAT_DEFAULT) {
|
||||
*value = cur->length;
|
||||
res = TRUE;
|
||||
|
@ -322,7 +319,7 @@ gst_ogg_demux_src_query (GstPad *pad, GstQueryType type,
|
|||
* really slow.
|
||||
*/
|
||||
static gboolean
|
||||
gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
|
||||
gst_ogg_demux_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstOggDemux *ogg;
|
||||
GstOggPad *cur;
|
||||
|
@ -331,12 +328,14 @@ gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
|
|||
cur = gst_ogg_get_pad_by_pad (ogg, pad);
|
||||
/* FIXME: optimize this so events from inactive chains work?
|
||||
* in theory there shouldn't be an exisiting pad for inactive chains */
|
||||
if (cur == NULL) goto error;
|
||||
if (cur == NULL)
|
||||
goto error;
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_DEFAULT)
|
||||
goto error;
|
||||
offset = GST_EVENT_SEEK_OFFSET (event);
|
||||
|
@ -356,21 +355,22 @@ gst_ogg_demux_src_event (GstPad *pad, GstEvent *event)
|
|||
goto error;
|
||||
}
|
||||
if (offset < cur->known_offset) {
|
||||
GstEvent *restart = gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET | GST_EVENT_SEEK_FLAGS (event), 0);
|
||||
GstEvent *restart =
|
||||
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET |
|
||||
GST_EVENT_SEEK_FLAGS (event), 0);
|
||||
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad), restart))
|
||||
goto error;
|
||||
} else {
|
||||
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
|
||||
if (GST_PAD_IS_USABLE (pad->pad))
|
||||
gst_pad_push (pad->pad, GST_DATA (gst_event_new (GST_EVENT_FLUSH)));
|
||||
);
|
||||
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad, if (GST_PAD_IS_USABLE (pad->pad))
|
||||
gst_pad_push (pad->pad,
|
||||
GST_DATA (gst_event_new (GST_EVENT_FLUSH))););
|
||||
}
|
||||
|
||||
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_SEEK);
|
||||
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
|
||||
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;
|
||||
);
|
||||
GST_DEBUG_OBJECT (ogg, "initiating seeking to offset %"G_GUINT64_FORMAT, offset);
|
||||
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;);
|
||||
GST_DEBUG_OBJECT (ogg, "initiating seeking to offset %" G_GUINT64_FORMAT,
|
||||
offset);
|
||||
ogg->seek_pad = cur;
|
||||
ogg->seek_to = offset;
|
||||
gst_event_unref (event);
|
||||
|
@ -388,7 +388,7 @@ error:
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ogg_start_playing (GstOggDemux *ogg)
|
||||
gst_ogg_start_playing (GstOggDemux * ogg)
|
||||
{
|
||||
GST_DEBUG_OBJECT (ogg, "got EOS in setup, changing to playback now");
|
||||
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
|
||||
|
@ -404,7 +404,7 @@ gst_ogg_start_playing (GstOggDemux *ogg)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
|
||||
gst_ogg_demux_handle_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstOggDemux *ogg = GST_OGG_DEMUX (gst_pad_get_parent (pad));
|
||||
|
||||
|
@ -415,8 +415,7 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
|
|||
gst_event_unref (event);
|
||||
GST_FLAG_UNSET (ogg, GST_OGG_FLAG_WAIT_FOR_DISCONT);
|
||||
FOR_PAD_IN_CURRENT_CHAIN (ogg, pad,
|
||||
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;
|
||||
);
|
||||
pad->flags |= GST_OGG_PAD_NEEDS_DISCONT;);
|
||||
break;
|
||||
case GST_EVENT_EOS:
|
||||
if (ogg->state == GST_OGG_STATE_SETUP) {
|
||||
|
@ -424,12 +423,15 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
|
|||
} else {
|
||||
guint i;
|
||||
GSList *walk;
|
||||
|
||||
GST_DEBUG_OBJECT (ogg, "got EOS");
|
||||
ogg->current_chain = -1;
|
||||
for (i = 0; i < ogg->chains->len; i++) {
|
||||
GstOggChain *chain = &g_array_index (ogg->chains, GstOggChain, i);
|
||||
|
||||
for (walk = chain->pads; walk; walk = g_slist_next (walk)) {
|
||||
GstOggPad *pad = (GstOggPad *) walk->data;
|
||||
|
||||
if (pad->pad && GST_PAD_IS_USABLE (pad->pad)) {
|
||||
gst_data_ref (GST_DATA (event));
|
||||
gst_pad_push (pad->pad, GST_DATA (event));
|
||||
|
@ -449,15 +451,17 @@ gst_ogg_demux_handle_event (GstPad *pad, GstEvent *event)
|
|||
|
||||
/* get the pad with the given serial in the current stream or NULL if none */
|
||||
static GstOggPad *
|
||||
gst_ogg_pad_get_in_current_chain (GstOggDemux *ogg, int serial)
|
||||
gst_ogg_pad_get_in_current_chain (GstOggDemux * ogg, int serial)
|
||||
{
|
||||
GSList *walk;
|
||||
|
||||
if (ogg->current_chain == -1) return NULL;
|
||||
if (ogg->current_chain == -1)
|
||||
return NULL;
|
||||
g_return_val_if_fail (ogg->current_chain < ogg->chains->len, NULL);
|
||||
|
||||
for (walk = CURRENT_CHAIN (ogg)->pads; walk; walk = g_slist_next (walk)) {
|
||||
GstOggPad *pad = (GstOggPad *) walk->data;
|
||||
|
||||
if (pad->serial == serial)
|
||||
return pad;
|
||||
}
|
||||
|
@ -465,7 +469,7 @@ gst_ogg_pad_get_in_current_chain (GstOggDemux *ogg, int serial)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ogg_add_chain (GstOggDemux *ogg)
|
||||
gst_ogg_add_chain (GstOggDemux * ogg)
|
||||
{
|
||||
GST_LOG_OBJECT (ogg, "adding chain %u", ogg->chains->len);
|
||||
ogg->current_chain = ogg->chains->len;
|
||||
|
@ -473,7 +477,7 @@ gst_ogg_add_chain (GstOggDemux *ogg)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
||||
gst_ogg_demux_chain (GstPad * pad, GstData * buffer)
|
||||
{
|
||||
GstOggDemux *ogg;
|
||||
guint8 *data;
|
||||
|
@ -494,17 +498,18 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
|||
return;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (ogg, "queueing buffer %p with offset %llu", buffer, GST_BUFFER_OFFSET (buffer));
|
||||
data = (guint8 *) ogg_sync_buffer(&ogg->sync, GST_BUFFER_SIZE (buffer));
|
||||
GST_LOG_OBJECT (ogg, "queueing buffer %p with offset %llu", buffer,
|
||||
GST_BUFFER_OFFSET (buffer));
|
||||
data = (guint8 *) ogg_sync_buffer (&ogg->sync, GST_BUFFER_SIZE (buffer));
|
||||
memcpy (data, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
|
||||
if (ogg_sync_wrote (&ogg->sync, GST_BUFFER_SIZE (buffer)) != 0) {
|
||||
gst_data_unref (buffer);
|
||||
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL), ("ogg_sync_wrote failed"));
|
||||
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL),
|
||||
("ogg_sync_wrote failed"));
|
||||
return;
|
||||
}
|
||||
offset_end = GST_BUFFER_OFFSET_IS_VALID (buffer) ?
|
||||
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) :
|
||||
(guint64) -1;
|
||||
GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) : (guint64) - 1;
|
||||
gst_data_unref (buffer);
|
||||
while (pageout_ret != 0) {
|
||||
ogg_page page;
|
||||
|
@ -519,7 +524,9 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
|||
if (ogg->state == GST_OGG_STATE_SETUP) {
|
||||
guint64 length;
|
||||
GstFormat format = GST_FORMAT_BYTES;
|
||||
if (!gst_pad_query (GST_PAD_PEER (ogg->sinkpad), GST_QUERY_TOTAL, &format, &length))
|
||||
|
||||
if (!gst_pad_query (GST_PAD_PEER (ogg->sinkpad), GST_QUERY_TOTAL,
|
||||
&format, &length))
|
||||
length = 0;
|
||||
if (length <= offset_end) {
|
||||
gst_ogg_start_playing (ogg);
|
||||
|
@ -528,32 +535,42 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
|||
}
|
||||
break;
|
||||
case 1:
|
||||
GST_LOG_OBJECT (ogg, "processing ogg page (serial %d, packet %ld, granule pos %llu",
|
||||
ogg_page_serialno (&page), ogg_page_pageno (&page), ogg_page_granulepos (&page));
|
||||
GST_LOG_OBJECT (ogg,
|
||||
"processing ogg page (serial %d, packet %ld, granule pos %llu",
|
||||
ogg_page_serialno (&page), ogg_page_pageno (&page),
|
||||
ogg_page_granulepos (&page));
|
||||
switch (ogg->state) {
|
||||
case GST_OGG_STATE_SETUP:
|
||||
if (ogg_page_eos (&page)) {
|
||||
GstOggPad *cur = gst_ogg_pad_get_in_current_chain (ogg, ogg_page_serialno (&page));
|
||||
GstOggPad *cur = gst_ogg_pad_get_in_current_chain (ogg,
|
||||
ogg_page_serialno (&page));
|
||||
|
||||
GST_FLAG_SET (ogg, GST_OGG_FLAG_EOS);
|
||||
if (!cur) {
|
||||
GST_ERROR_OBJECT (ogg, "unknown serial %d", ogg_page_serialno (&page));
|
||||
GST_ERROR_OBJECT (ogg, "unknown serial %d",
|
||||
ogg_page_serialno (&page));
|
||||
} else {
|
||||
cur->pages = ogg_page_pageno (&page);
|
||||
cur->length = ogg_page_granulepos (&page);
|
||||
}
|
||||
} else {
|
||||
if (GST_FLAG_IS_SET (ogg, GST_OGG_FLAG_EOS) && ogg_page_bos (&page)) {
|
||||
if (GST_FLAG_IS_SET (ogg, GST_OGG_FLAG_EOS)
|
||||
&& ogg_page_bos (&page)) {
|
||||
gst_ogg_add_chain (ogg);
|
||||
}
|
||||
GST_FLAG_UNSET (ogg, GST_OGG_FLAG_EOS);
|
||||
}
|
||||
if (ogg_page_bos (&page)) {
|
||||
if (gst_ogg_pad_get_in_current_chain (ogg, ogg_page_serialno (&page))) {
|
||||
GST_ERROR_OBJECT (ogg, "multiple BOS page for serial %d (page %ld)",
|
||||
if (gst_ogg_pad_get_in_current_chain (ogg,
|
||||
ogg_page_serialno (&page))) {
|
||||
GST_ERROR_OBJECT (ogg,
|
||||
"multiple BOS page for serial %d (page %ld)",
|
||||
ogg_page_serialno (&page), ogg_page_pageno (&page));
|
||||
} else {
|
||||
GstOggPad *pad = gst_ogg_pad_new (ogg, ogg_page_serialno (&page));
|
||||
CURRENT_CHAIN (ogg)->pads = g_slist_prepend (CURRENT_CHAIN (ogg)->pads, pad);
|
||||
GstOggPad *pad =
|
||||
gst_ogg_pad_new (ogg, ogg_page_serialno (&page));
|
||||
CURRENT_CHAIN (ogg)->pads =
|
||||
g_slist_prepend (CURRENT_CHAIN (ogg)->pads, pad);
|
||||
}
|
||||
GST_FLAG_SET (ogg, GST_OGG_FLAG_BOS);
|
||||
} else {
|
||||
|
@ -562,11 +579,13 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
|||
break;
|
||||
case GST_OGG_STATE_START:
|
||||
if (gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
|
||||
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_END, 0))) {
|
||||
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_END,
|
||||
0))) {
|
||||
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_SETUP);
|
||||
GST_DEBUG_OBJECT (ogg, "stream can seek, try setup now");
|
||||
if (!gst_pad_send_event (GST_PAD_PEER (ogg->sinkpad),
|
||||
gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_SET, 0))) {
|
||||
gst_event_new_seek (GST_FORMAT_BYTES |
|
||||
GST_SEEK_METHOD_SET, 0))) {
|
||||
GST_ELEMENT_ERROR (ogg, CORE, SEEK, (NULL),
|
||||
("stream can seek to end, but not to start. Can't handle that."));
|
||||
}
|
||||
|
@ -587,7 +606,8 @@ gst_ogg_demux_chain (GstPad *pad, GstData *buffer)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
GST_WARNING_OBJECT (ogg, "unknown return value %d from ogg_sync_pageout", pageout_ret);
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"unknown return value %d from ogg_sync_pageout", pageout_ret);
|
||||
pageout_ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -596,25 +616,27 @@ out:
|
|||
return;
|
||||
}
|
||||
static GstOggPad *
|
||||
gst_ogg_pad_new (GstOggDemux *ogg, int serial)
|
||||
gst_ogg_pad_new (GstOggDemux * ogg, int serial)
|
||||
{
|
||||
GstOggPad *ret = g_new0 (GstOggPad, 1);
|
||||
GstTagList *list = gst_tag_list_new ();
|
||||
|
||||
ret->serial = serial;
|
||||
if (ogg_stream_init (&ret->stream, serial) != 0) {
|
||||
GST_ERROR_OBJECT (ogg, "Could not initialize ogg_stream struct for serial %d.", serial);
|
||||
GST_ERROR_OBJECT (ogg,
|
||||
"Could not initialize ogg_stream struct for serial %d.", serial);
|
||||
g_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_SERIAL, serial, NULL);
|
||||
gst_element_found_tags (GST_ELEMENT (ogg), list);
|
||||
GST_LOG_OBJECT (ogg, "created new ogg src %p for stream with serial %d", ret, serial);
|
||||
GST_LOG_OBJECT (ogg, "created new ogg src %p for stream with serial %d", ret,
|
||||
serial);
|
||||
|
||||
return ret;
|
||||
}
|
||||
static void
|
||||
gst_ogg_pad_remove (GstOggDemux *ogg, GstOggPad *pad)
|
||||
gst_ogg_pad_remove (GstOggDemux * ogg, GstOggPad * pad)
|
||||
{
|
||||
if (pad->pad) {
|
||||
/* FIXME:
|
||||
|
@ -626,12 +648,15 @@ gst_ogg_pad_remove (GstOggDemux *ogg, GstOggPad *pad)
|
|||
gst_element_remove_pad (GST_ELEMENT (ogg), pad->pad);
|
||||
}
|
||||
if (ogg_stream_clear (&pad->stream) != 0)
|
||||
GST_ERROR_OBJECT (ogg, "ogg_stream_clear (serial %d) did not return 0, ignoring this error", pad->serial);
|
||||
GST_LOG_OBJECT (ogg, "free ogg src %p for stream with serial %d", pad, pad->serial);
|
||||
GST_ERROR_OBJECT (ogg,
|
||||
"ogg_stream_clear (serial %d) did not return 0, ignoring this error",
|
||||
pad->serial);
|
||||
GST_LOG_OBJECT (ogg, "free ogg src %p for stream with serial %d", pad,
|
||||
pad->serial);
|
||||
g_free (pad);
|
||||
}
|
||||
static void
|
||||
gst_ogg_demux_push (GstOggDemux *ogg, ogg_page* page)
|
||||
gst_ogg_demux_push (GstOggDemux * ogg, ogg_page * page)
|
||||
{
|
||||
GSList *walk;
|
||||
GstOggPad *cur;
|
||||
|
@ -648,42 +673,51 @@ br:
|
|||
/* now we either have a stream (cur) or not */
|
||||
if (ogg_page_bos (page)) {
|
||||
if (cur) {
|
||||
GST_DEBUG_OBJECT (ogg, "ogg page declared as BOS while stream %d already existed."
|
||||
GST_DEBUG_OBJECT (ogg,
|
||||
"ogg page declared as BOS while stream %d already existed."
|
||||
"Possibly a seek happened.", cur->serial);
|
||||
} else if (cur) {
|
||||
GST_DEBUG_OBJECT (ogg, "reactivating deactivated stream %d.", cur->serial);
|
||||
GST_DEBUG_OBJECT (ogg, "reactivating deactivated stream %d.",
|
||||
cur->serial);
|
||||
} else {
|
||||
/* FIXME: monitor if we are still in creation stage? */
|
||||
cur = gst_ogg_pad_new (ogg, ogg_page_serialno (page));
|
||||
if (!cur) {
|
||||
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL), ("Creating ogg_stream struct failed."));
|
||||
GST_ELEMENT_ERROR (ogg, LIBRARY, TOO_LAZY, (NULL),
|
||||
("Creating ogg_stream struct failed."));
|
||||
return;
|
||||
}
|
||||
if (ogg->current_chain == -1) {
|
||||
/* add new one at the end */
|
||||
gst_ogg_add_chain (ogg);
|
||||
}
|
||||
CURRENT_CHAIN (ogg)->pads = g_slist_prepend (CURRENT_CHAIN (ogg)->pads, cur);
|
||||
CURRENT_CHAIN (ogg)->pads =
|
||||
g_slist_prepend (CURRENT_CHAIN (ogg)->pads, cur);
|
||||
}
|
||||
}
|
||||
if (cur == NULL) {
|
||||
GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL), ("invalid ogg stream serial no"));
|
||||
GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL),
|
||||
("invalid ogg stream serial no"));
|
||||
return;
|
||||
}
|
||||
if (ogg_stream_pagein (&cur->stream, page) != 0) {
|
||||
GST_WARNING_OBJECT (ogg, "ogg stream choked on page (serial %d), resetting stream", cur->serial);
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"ogg stream choked on page (serial %d), resetting stream", cur->serial);
|
||||
gst_ogg_pad_reset (ogg, cur);
|
||||
return;
|
||||
}
|
||||
switch (ogg->state) {
|
||||
case GST_OGG_STATE_SEEK:
|
||||
GST_LOG_OBJECT (ogg, "in seek - offset now: %"G_GUINT64_FORMAT" (pad %d) - desired offset %"
|
||||
G_GUINT64_FORMAT" (pad %d)", cur->known_offset, cur->serial,
|
||||
ogg->seek_to, ogg->seek_pad->serial);
|
||||
GST_LOG_OBJECT (ogg,
|
||||
"in seek - offset now: %" G_GUINT64_FORMAT
|
||||
" (pad %d) - desired offset %" G_GUINT64_FORMAT " (pad %d)",
|
||||
cur->known_offset, cur->serial, ogg->seek_to, ogg->seek_pad->serial);
|
||||
if (cur == ogg->seek_pad) {
|
||||
if (ogg_page_granulepos (page) > ogg->seek_to) {
|
||||
GST_OGG_SET_STATE (ogg, GST_OGG_STATE_PLAY);
|
||||
GST_DEBUG_OBJECT (ogg, "ended seek at offset %"G_GUINT64_FORMAT" (requested %"G_GUINT64_FORMAT, cur->known_offset, ogg->seek_to);
|
||||
GST_DEBUG_OBJECT (ogg,
|
||||
"ended seek at offset %" G_GUINT64_FORMAT " (requested %"
|
||||
G_GUINT64_FORMAT, cur->known_offset, ogg->seek_to);
|
||||
ogg->seek_pad = NULL;
|
||||
ogg->seek_to = 0;
|
||||
}
|
||||
|
@ -711,7 +745,7 @@ br:
|
|||
}
|
||||
}
|
||||
static void
|
||||
gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
|
||||
gst_ogg_pad_push (GstOggDemux * ogg, GstOggPad * pad)
|
||||
{
|
||||
ogg_packet packet;
|
||||
int ret;
|
||||
|
@ -725,7 +759,7 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
|
|||
case -1:
|
||||
gst_ogg_pad_reset (ogg, pad);
|
||||
break;
|
||||
case 1: {
|
||||
case 1:{
|
||||
/* only push data when playing, not during seek or similar */
|
||||
if (ogg->state != GST_OGG_STATE_PLAY)
|
||||
continue;
|
||||
|
@ -734,17 +768,22 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
|
|||
gchar *name = g_strdup_printf ("serial_%d", pad->serial);
|
||||
|
||||
if (caps == NULL) {
|
||||
GST_WARNING_OBJECT (ogg, "couldn't find caps for stream with serial %d", pad->serial);
|
||||
GST_WARNING_OBJECT (ogg,
|
||||
"couldn't find caps for stream with serial %d", pad->serial);
|
||||
caps = gst_caps_new_simple ("application/octet-stream", NULL);
|
||||
}
|
||||
pad->pad = gst_pad_new_from_template (
|
||||
gst_static_pad_template_get (&ogg_demux_src_template_factory),
|
||||
name);
|
||||
pad->pad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&ogg_demux_src_template_factory), name);
|
||||
g_free (name);
|
||||
gst_pad_set_event_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event));
|
||||
gst_pad_set_event_mask_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks));
|
||||
gst_pad_set_query_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_query));
|
||||
gst_pad_set_query_type_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_query_types));
|
||||
gst_pad_set_event_function (pad->pad,
|
||||
GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event));
|
||||
gst_pad_set_event_mask_function (pad->pad,
|
||||
GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks));
|
||||
gst_pad_set_query_function (pad->pad,
|
||||
GST_DEBUG_FUNCPTR (gst_ogg_demux_src_query));
|
||||
gst_pad_set_query_type_function (pad->pad,
|
||||
GST_DEBUG_FUNCPTR (gst_ogg_demux_get_query_types));
|
||||
gst_pad_use_explicit_caps (pad->pad);
|
||||
gst_pad_set_explicit_caps (pad->pad, caps);
|
||||
gst_pad_set_active (pad->pad, TRUE);
|
||||
|
@ -756,14 +795,18 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
|
|||
pad->packetno = packet.packetno + 1;
|
||||
}
|
||||
/* send discont if needed */
|
||||
if ((pad->flags & GST_OGG_PAD_NEEDS_DISCONT) && GST_PAD_IS_USABLE (pad->pad)) {
|
||||
if ((pad->flags & GST_OGG_PAD_NEEDS_DISCONT)
|
||||
&& GST_PAD_IS_USABLE (pad->pad)) {
|
||||
GstEvent *event = gst_event_new_discontinuous (FALSE,
|
||||
GST_FORMAT_DEFAULT, pad->known_offset); /* FIXME: this might be wrong because we can only use the last known offset */
|
||||
|
||||
gst_pad_push (pad->pad, GST_DATA (event));
|
||||
pad->flags &= (~GST_OGG_PAD_NEEDS_DISCONT);
|
||||
};
|
||||
/* optimization: use a bufferpool containing the ogg packet? */
|
||||
buf = gst_pad_alloc_buffer (pad->pad, GST_BUFFER_OFFSET_NONE, packet.bytes);
|
||||
buf =
|
||||
gst_pad_alloc_buffer (pad->pad, GST_BUFFER_OFFSET_NONE,
|
||||
packet.bytes);
|
||||
memcpy (buf->data, packet.packet, packet.bytes);
|
||||
if (pad->offset != -1)
|
||||
GST_BUFFER_OFFSET (buf) = pad->offset;
|
||||
|
@ -775,14 +818,16 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
GST_ERROR_OBJECT (ogg, "invalid return value %d for ogg_stream_packetout, resetting stream", ret);
|
||||
GST_ERROR_OBJECT (ogg,
|
||||
"invalid return value %d for ogg_stream_packetout, resetting stream",
|
||||
ret);
|
||||
gst_ogg_pad_reset (ogg, pad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void
|
||||
gst_ogg_pad_reset (GstOggDemux *ogg, GstOggPad *pad)
|
||||
gst_ogg_pad_reset (GstOggDemux * ogg, GstOggPad * pad)
|
||||
{
|
||||
ogg_stream_reset (&pad->stream);
|
||||
pad->offset = GST_BUFFER_OFFSET_NONE;
|
||||
|
@ -790,13 +835,14 @@ gst_ogg_pad_reset (GstOggDemux *ogg, GstOggPad *pad)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ogg_chains_clear (GstOggDemux *ogg)
|
||||
gst_ogg_chains_clear (GstOggDemux * ogg)
|
||||
{
|
||||
gint i;
|
||||
GSList *walk;
|
||||
|
||||
for (i = ogg->chains->len - 1; i >= 0; i--) {
|
||||
GstOggChain *cur = &g_array_index (ogg->chains, GstOggChain, i);
|
||||
|
||||
for (walk = cur->pads; walk; walk = g_slist_next (walk)) {
|
||||
gst_ogg_pad_remove (ogg, (GstOggPad *) walk->data);
|
||||
}
|
||||
|
@ -807,7 +853,7 @@ gst_ogg_chains_clear (GstOggDemux *ogg)
|
|||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_ogg_demux_change_state (GstElement *element)
|
||||
gst_ogg_demux_change_state (GstElement * element)
|
||||
{
|
||||
GstOggDemux *ogg;
|
||||
|
||||
|
@ -846,10 +892,11 @@ gst_ogg_demux_change_state (GstElement *element)
|
|||
* packet of an ogg stream must identify the stream. Therefore ogg can use a
|
||||
* simplified approach at typefinding.
|
||||
*/
|
||||
typedef struct {
|
||||
ogg_packet * packet;
|
||||
typedef struct
|
||||
{
|
||||
ogg_packet *packet;
|
||||
guint best_probability;
|
||||
GstCaps * caps;
|
||||
GstCaps *caps;
|
||||
} OggTypeFind;
|
||||
static guint8 *
|
||||
ogg_find_peek (gpointer data, gint64 offset, guint size)
|
||||
|
@ -863,7 +910,7 @@ ogg_find_peek (gpointer data, gint64 offset, guint size)
|
|||
}
|
||||
}
|
||||
static void
|
||||
ogg_find_suggest (gpointer data, guint probability, const GstCaps *caps)
|
||||
ogg_find_suggest (gpointer data, guint probability, const GstCaps * caps)
|
||||
{
|
||||
OggTypeFind *find = (OggTypeFind *) data;
|
||||
|
||||
|
@ -873,7 +920,7 @@ ogg_find_suggest (gpointer data, guint probability, const GstCaps *caps)
|
|||
}
|
||||
}
|
||||
static GstCaps *
|
||||
gst_ogg_type_find (ogg_packet *packet)
|
||||
gst_ogg_type_find (ogg_packet * packet)
|
||||
{
|
||||
GstTypeFind gst_find;
|
||||
OggTypeFind find;
|
||||
|
@ -904,38 +951,36 @@ gst_ogg_type_find (ogg_packet *packet)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (gst_ogg_demux_debug, "oggdemux", 0, "ogg demuxer");
|
||||
|
||||
return gst_element_register (plugin, "oggdemux", GST_RANK_PRIMARY, GST_TYPE_OGG_DEMUX);
|
||||
return gst_element_register (plugin, "oggdemux", GST_RANK_PRIMARY,
|
||||
GST_TYPE_OGG_DEMUX);
|
||||
}
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"ogg",
|
||||
"ogg stream manipulation (info about ogg: http://xiph.org)",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
GST_LICENSE,
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
|
||||
|
||||
/* prints all info about the element */
|
||||
static void
|
||||
gst_ogg_print (GstOggDemux *ogg)
|
||||
static void gst_ogg_print (GstOggDemux * ogg)
|
||||
{
|
||||
guint i;
|
||||
GSList *walk;
|
||||
|
||||
for (i = 0; i < ogg->chains->len; i++) {
|
||||
GstOggChain *chain = &g_array_index (ogg->chains, GstOggChain, i);
|
||||
GST_INFO_OBJECT (ogg, "chain %d (%u streams):", i, g_slist_length (chain->pads));
|
||||
|
||||
GST_INFO_OBJECT (ogg, "chain %d (%u streams):", i,
|
||||
g_slist_length (chain->pads));
|
||||
for (walk = chain->pads; walk; walk = g_slist_next (walk)) {
|
||||
GstOggPad *pad = (GstOggPad *) walk->data;
|
||||
|
||||
GST_INFO_OBJECT (ogg, " stream %d:", pad->serial);
|
||||
GST_INFO_OBJECT (ogg, " length %"G_GUINT64_FORMAT, pad->length);
|
||||
GST_INFO_OBJECT (ogg, " length %" G_GUINT64_FORMAT, pad->length);
|
||||
GST_INFO_OBJECT (ogg, " pages %ld", pad->pages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ static GstElementDetails textoverlay_details = {
|
|||
"Gustavo J. A. M. Carneiro <gjc@inescporto.pt>"
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_TEXT,
|
||||
ARG_VALIGN,
|
||||
|
@ -29,72 +30,66 @@ enum {
|
|||
|
||||
|
||||
static GstStaticPadTemplate textoverlay_src_template_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
||||
"format = (fourcc) I420, "
|
||||
"width = (int) [ 1, MAX ], "
|
||||
"height = (int) [ 1, MAX ]")
|
||||
);
|
||||
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate video_sink_template_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"video_sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("video_sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
||||
"format = (fourcc) I420, "
|
||||
"width = (int) [ 1, MAX ], "
|
||||
"height = (int) [ 1, MAX ]")
|
||||
);
|
||||
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate text_sink_template_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"text_sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("text_sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("text/x-pango-markup; text/plain")
|
||||
);
|
||||
);
|
||||
|
||||
static void gst_textoverlay_base_init (gpointer g_class);
|
||||
static void gst_textoverlay_class_init(GstTextOverlayClass *klass);
|
||||
static void gst_textoverlay_init(GstTextOverlay *overlay);
|
||||
static void gst_textoverlay_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gst_textoverlay_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static GstElementStateReturn gst_textoverlay_change_state(GstElement *element);
|
||||
static void gst_textoverlay_finalize(GObject *object);
|
||||
static void gst_textoverlay_class_init (GstTextOverlayClass * klass);
|
||||
static void gst_textoverlay_init (GstTextOverlay * overlay);
|
||||
static void gst_textoverlay_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_textoverlay_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
static GstElementStateReturn gst_textoverlay_change_state (GstElement *
|
||||
element);
|
||||
static void gst_textoverlay_finalize (GObject * object);
|
||||
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
/*static guint gst_textoverlay_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
|
||||
GType
|
||||
gst_textoverlay_get_type(void)
|
||||
gst_textoverlay_get_type (void)
|
||||
{
|
||||
static GType textoverlay_type = 0;
|
||||
|
||||
if (!textoverlay_type) {
|
||||
static const GTypeInfo textoverlay_info = {
|
||||
sizeof(GstTextOverlayClass),
|
||||
sizeof (GstTextOverlayClass),
|
||||
gst_textoverlay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc)gst_textoverlay_class_init,
|
||||
(GClassInitFunc) gst_textoverlay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GstTextOverlay),
|
||||
sizeof (GstTextOverlay),
|
||||
0,
|
||||
(GInstanceInitFunc)gst_textoverlay_init,
|
||||
(GInstanceInitFunc) gst_textoverlay_init,
|
||||
};
|
||||
textoverlay_type = g_type_register_static(GST_TYPE_ELEMENT, "GstTextOverlay",
|
||||
textoverlay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstTextOverlay",
|
||||
&textoverlay_info, 0);
|
||||
}
|
||||
return textoverlay_type;
|
||||
|
@ -116,73 +111,69 @@ gst_textoverlay_base_init (gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_textoverlay_class_init(GstTextOverlayClass *klass)
|
||||
gst_textoverlay_class_init (GstTextOverlayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent(klass);
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = gst_textoverlay_finalize;
|
||||
gobject_class->set_property = gst_textoverlay_set_property;
|
||||
gobject_class->get_property = gst_textoverlay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_textoverlay_change_state;
|
||||
klass->pango_context = pango_ft2_get_context(72, 72);
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TEXT,
|
||||
g_param_spec_string("text", "text",
|
||||
klass->pango_context = pango_ft2_get_context (72, 72);
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEXT,
|
||||
g_param_spec_string ("text", "text",
|
||||
"Text to be display,"
|
||||
" in pango markup format.",
|
||||
"", G_PARAM_WRITABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VALIGN,
|
||||
g_param_spec_string("valign", "vertical alignment",
|
||||
" in pango markup format.", "", G_PARAM_WRITABLE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VALIGN,
|
||||
g_param_spec_string ("valign", "vertical alignment",
|
||||
"Vertical alignment of the text. "
|
||||
"Can be either 'baseline', 'bottom', or 'top'",
|
||||
"baseline", G_PARAM_WRITABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HALIGN,
|
||||
g_param_spec_string("halign", "horizontal alignment",
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HALIGN,
|
||||
g_param_spec_string ("halign", "horizontal alignment",
|
||||
"Horizontal alignment of the text. "
|
||||
"Can be either 'left', 'right', or 'center'",
|
||||
"center", G_PARAM_WRITABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_X0,
|
||||
g_param_spec_int("x0", "X position",
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_X0,
|
||||
g_param_spec_int ("x0", "X position",
|
||||
"Initial X position."
|
||||
" Horizontal aligment takes this point"
|
||||
" as reference.",
|
||||
G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_Y0,
|
||||
g_param_spec_int("y0", "Y position",
|
||||
" as reference.", G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_Y0,
|
||||
g_param_spec_int ("y0", "Y position",
|
||||
"Initial Y position."
|
||||
" Vertical aligment takes this point"
|
||||
" as reference.",
|
||||
G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE));
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FONT_DESC,
|
||||
g_param_spec_string("font-desc", "font description",
|
||||
" as reference.", G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FONT_DESC,
|
||||
g_param_spec_string ("font-desc", "font description",
|
||||
"Pango font description of font "
|
||||
"to be used for rendering. "
|
||||
"See documentation of "
|
||||
"pango_font_description_from_string"
|
||||
" for syntax.",
|
||||
"", G_PARAM_WRITABLE));
|
||||
" for syntax.", "", G_PARAM_WRITABLE));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
resize_bitmap(GstTextOverlay *overlay, int width, int height)
|
||||
resize_bitmap (GstTextOverlay * overlay, int width, int height)
|
||||
{
|
||||
FT_Bitmap *bitmap = &overlay->bitmap;
|
||||
int pitch = (width|3) + 1;
|
||||
int size = pitch*height;
|
||||
int pitch = (width | 3) + 1;
|
||||
int size = pitch * height;
|
||||
|
||||
/* no need to keep reallocating; just keep the maximum size so far */
|
||||
if (size <= overlay->bitmap_buffer_size) {
|
||||
bitmap->rows = height;
|
||||
bitmap->width = width;
|
||||
bitmap->pitch = pitch;
|
||||
memset(bitmap->buffer, 0, overlay->bitmap_buffer_size);
|
||||
memset (bitmap->buffer, 0, overlay->bitmap_buffer_size);
|
||||
return;
|
||||
}
|
||||
if (!bitmap->buffer) {
|
||||
|
@ -191,24 +182,24 @@ resize_bitmap(GstTextOverlay *overlay, int width, int height)
|
|||
bitmap->num_grays = 256;
|
||||
}
|
||||
if (bitmap->buffer)
|
||||
bitmap->buffer = g_realloc(bitmap->buffer, size);
|
||||
bitmap->buffer = g_realloc (bitmap->buffer, size);
|
||||
else
|
||||
bitmap->buffer = g_malloc(size);
|
||||
bitmap->buffer = g_malloc (size);
|
||||
bitmap->rows = height;
|
||||
bitmap->width = width;
|
||||
bitmap->pitch = pitch;
|
||||
memset(bitmap->buffer, 0, size);
|
||||
memset (bitmap->buffer, 0, size);
|
||||
overlay->bitmap_buffer_size = size;
|
||||
}
|
||||
|
||||
static void
|
||||
render_text(GstTextOverlay *overlay)
|
||||
render_text (GstTextOverlay * overlay)
|
||||
{
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
|
||||
pango_layout_get_pixel_extents(overlay->layout, &ink_rect, &logical_rect);
|
||||
resize_bitmap(overlay, ink_rect.width, ink_rect.height + ink_rect.y);
|
||||
pango_ft2_render_layout(&overlay->bitmap, overlay->layout, 0, 0);
|
||||
pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
|
||||
resize_bitmap (overlay, ink_rect.width, ink_rect.height + ink_rect.y);
|
||||
pango_ft2_render_layout (&overlay->bitmap, overlay->layout, 0, 0);
|
||||
overlay->baseline_y = ink_rect.y;
|
||||
}
|
||||
|
||||
|
@ -220,33 +211,33 @@ render_text(GstTextOverlay *overlay)
|
|||
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_textoverlay_video_sinkconnect(GstPad *pad, const GstCaps *caps)
|
||||
gst_textoverlay_video_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
GstTextOverlay *overlay;
|
||||
GstStructure *structure;
|
||||
|
||||
overlay = GST_TEXTOVERLAY(gst_pad_get_parent(pad));
|
||||
overlay = GST_TEXTOVERLAY (gst_pad_get_parent (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
overlay->width = overlay->height = 0;
|
||||
gst_structure_get_int (structure, "width", &overlay->width);
|
||||
gst_structure_get_int (structure, "height", &overlay->height);
|
||||
|
||||
return gst_pad_try_set_caps(overlay->srcpad, caps);
|
||||
return gst_pad_try_set_caps (overlay->srcpad, caps);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_text_overlay_blit_yuv420(GstTextOverlay *overlay, FT_Bitmap *bitmap,
|
||||
guchar *pixbuf, int x0, int y0)
|
||||
gst_text_overlay_blit_yuv420 (GstTextOverlay * overlay, FT_Bitmap * bitmap,
|
||||
guchar * pixbuf, int x0, int y0)
|
||||
{
|
||||
int y; /* text bitmap coordinates */
|
||||
int x1, y1; /* video buffer coordinates */
|
||||
int rowinc, bit_rowinc, uv_rowinc;
|
||||
guchar *p, *bitp, *u_p;
|
||||
int video_width = overlay->width, video_height = overlay->height;
|
||||
int bitmap_x0 = x0 < 1? -(x0 - 1) : 1; /* 1 pixel border */
|
||||
int bitmap_y0 = y0 < 1? -(y0 - 1) : 1; /* 1 pixel border */
|
||||
int bitmap_x0 = x0 < 1 ? -(x0 - 1) : 1; /* 1 pixel border */
|
||||
int bitmap_y0 = y0 < 1 ? -(y0 - 1) : 1; /* 1 pixel border */
|
||||
int bitmap_width = bitmap->width - bitmap_x0;
|
||||
int bitmap_height = bitmap->rows - bitmap_y0;
|
||||
int u_plane_size;
|
||||
|
@ -261,21 +252,22 @@ gst_text_overlay_blit_yuv420(GstTextOverlay *overlay, FT_Bitmap *bitmap,
|
|||
rowinc = video_width - bitmap_width;
|
||||
uv_rowinc = video_width / 2 - bitmap_width / 2;
|
||||
bit_rowinc = bitmap->pitch - bitmap_width;
|
||||
u_plane_size = (video_width / 2)*(video_height / 2);
|
||||
u_plane_size = (video_width / 2) * (video_height / 2);
|
||||
|
||||
y1 = y0 + bitmap_y0;
|
||||
x1 = x0 + bitmap_x0;
|
||||
p = pixbuf + video_width*y1 + x1;
|
||||
bitp = bitmap->buffer + bitmap->pitch*bitmap_y0 + bitmap_x0;
|
||||
for (y = bitmap_y0; y < bitmap_height; y++){
|
||||
p = pixbuf + video_width * y1 + x1;
|
||||
bitp = bitmap->buffer + bitmap->pitch * bitmap_y0 + bitmap_x0;
|
||||
for (y = bitmap_y0; y < bitmap_height; y++) {
|
||||
int n;
|
||||
for(n=bitmap_width; n>0; --n){
|
||||
|
||||
for (n = bitmap_width; n > 0; --n) {
|
||||
v = *bitp;
|
||||
if (v) {
|
||||
p[-1] = CLAMP(p[-1] - v, 0, 255);
|
||||
p[ 1] = CLAMP(p[ 1] - v, 0, 255);
|
||||
p[-video_width] = CLAMP(p[-video_width] - v, 0, 255);
|
||||
p[ video_width] = CLAMP(p[ video_width] - v, 0, 255);
|
||||
p[-1] = CLAMP (p[-1] - v, 0, 255);
|
||||
p[1] = CLAMP (p[1] - v, 0, 255);
|
||||
p[-video_width] = CLAMP (p[-video_width] - v, 0, 255);
|
||||
p[video_width] = CLAMP (p[video_width] - v, 0, 255);
|
||||
}
|
||||
p++;
|
||||
bitp++;
|
||||
|
@ -287,17 +279,20 @@ gst_text_overlay_blit_yuv420(GstTextOverlay *overlay, FT_Bitmap *bitmap,
|
|||
y = bitmap_y0;
|
||||
y1 = y0 + bitmap_y0;
|
||||
x1 = x0 + bitmap_x0;
|
||||
bitp = bitmap->buffer + bitmap->pitch*bitmap_y0 + bitmap_x0;
|
||||
p = pixbuf + video_width*y1 + x1;
|
||||
u_p = pixbuf + video_width*video_height + (video_width >> 1)*(y1 >> 1) + (x1 >> 1);
|
||||
bitp = bitmap->buffer + bitmap->pitch * bitmap_y0 + bitmap_x0;
|
||||
p = pixbuf + video_width * y1 + x1;
|
||||
u_p =
|
||||
pixbuf + video_width * video_height + (video_width >> 1) * (y1 >> 1) +
|
||||
(x1 >> 1);
|
||||
skip_y = 0;
|
||||
skip_x = 0;
|
||||
|
||||
for ( ; y < bitmap_height; y++){
|
||||
for (; y < bitmap_height; y++) {
|
||||
int n;
|
||||
|
||||
x1 = x0 + bitmap_x0;
|
||||
skip_x = 0;
|
||||
for(n = bitmap_width; n>0; --n){
|
||||
for (n = bitmap_width; n > 0; --n) {
|
||||
v = *bitp;
|
||||
if (v) {
|
||||
*p = v;
|
||||
|
@ -307,7 +302,8 @@ gst_text_overlay_blit_yuv420(GstTextOverlay *overlay, FT_Bitmap *bitmap,
|
|||
}
|
||||
if (!skip_y) {
|
||||
skip_x = !skip_x;
|
||||
if (!skip_x) u_p++;
|
||||
if (!skip_x)
|
||||
u_p++;
|
||||
}
|
||||
p++;
|
||||
bitp++;
|
||||
|
@ -316,32 +312,31 @@ gst_text_overlay_blit_yuv420(GstTextOverlay *overlay, FT_Bitmap *bitmap,
|
|||
p += rowinc;
|
||||
bitp += bit_rowinc;
|
||||
skip_y = !skip_y;
|
||||
u_p += skip_y? uv_rowinc : 0;
|
||||
u_p += skip_y ? uv_rowinc : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_textoverlay_video_chain(GstPad *pad, GstData *_data)
|
||||
gst_textoverlay_video_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstTextOverlay *overlay;
|
||||
guchar *pixbuf;
|
||||
gint x0, y0;
|
||||
|
||||
g_return_if_fail(pad != NULL);
|
||||
g_return_if_fail(GST_IS_PAD(pad));
|
||||
g_return_if_fail(buf != NULL);
|
||||
overlay = GST_TEXTOVERLAY(gst_pad_get_parent(pad));
|
||||
g_return_if_fail(overlay != NULL);
|
||||
g_return_if_fail(GST_IS_TEXTOVERLAY(overlay));
|
||||
g_return_if_fail (pad != NULL);
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
g_return_if_fail (buf != NULL);
|
||||
overlay = GST_TEXTOVERLAY (gst_pad_get_parent (pad));
|
||||
g_return_if_fail (overlay != NULL);
|
||||
g_return_if_fail (GST_IS_TEXTOVERLAY (overlay));
|
||||
|
||||
pixbuf = GST_BUFFER_DATA(buf);
|
||||
pixbuf = GST_BUFFER_DATA (buf);
|
||||
|
||||
x0 = overlay->x0;
|
||||
y0 = overlay->y0;
|
||||
switch (overlay->valign)
|
||||
{
|
||||
switch (overlay->valign) {
|
||||
case GST_TEXT_OVERLAY_VALIGN_BOTTOM:
|
||||
y0 += overlay->bitmap.rows;
|
||||
break;
|
||||
|
@ -352,8 +347,7 @@ gst_textoverlay_video_chain(GstPad *pad, GstData *_data)
|
|||
break;
|
||||
}
|
||||
|
||||
switch (overlay->halign)
|
||||
{
|
||||
switch (overlay->halign) {
|
||||
case GST_TEXT_OVERLAY_HALIGN_LEFT:
|
||||
break;
|
||||
case GST_TEXT_OVERLAY_HALIGN_RIGHT:
|
||||
|
@ -365,9 +359,9 @@ gst_textoverlay_video_chain(GstPad *pad, GstData *_data)
|
|||
}
|
||||
|
||||
if (overlay->bitmap.buffer)
|
||||
gst_text_overlay_blit_yuv420(overlay, &overlay->bitmap, pixbuf, x0, y0);
|
||||
gst_text_overlay_blit_yuv420 (overlay, &overlay->bitmap, pixbuf, x0, y0);
|
||||
|
||||
gst_pad_push(overlay->srcpad, GST_DATA (buf));
|
||||
gst_pad_push (overlay->srcpad, GST_DATA (buf));
|
||||
}
|
||||
|
||||
#define PAST_END(buffer, time) \
|
||||
|
@ -377,18 +371,18 @@ gst_textoverlay_video_chain(GstPad *pad, GstData *_data)
|
|||
< (time))
|
||||
|
||||
static void
|
||||
gst_textoverlay_loop(GstElement *element)
|
||||
gst_textoverlay_loop (GstElement * element)
|
||||
{
|
||||
GstTextOverlay *overlay;
|
||||
GstBuffer *video_frame;
|
||||
guint64 now;
|
||||
|
||||
g_return_if_fail(element != NULL);
|
||||
g_return_if_fail(GST_IS_TEXTOVERLAY(element));
|
||||
overlay = GST_TEXTOVERLAY(element);
|
||||
g_return_if_fail (element != NULL);
|
||||
g_return_if_fail (GST_IS_TEXTOVERLAY (element));
|
||||
overlay = GST_TEXTOVERLAY (element);
|
||||
|
||||
video_frame = GST_BUFFER (gst_pad_pull(overlay->video_sinkpad));
|
||||
now = GST_BUFFER_TIMESTAMP(video_frame);
|
||||
video_frame = GST_BUFFER (gst_pad_pull (overlay->video_sinkpad));
|
||||
now = GST_BUFFER_TIMESTAMP (video_frame);
|
||||
|
||||
/*
|
||||
* This state machine has a bug that can't be resolved easily.
|
||||
|
@ -401,75 +395,74 @@ gst_textoverlay_loop(GstElement *element)
|
|||
* buffer timestamps and durations correctly. (I think)
|
||||
*/
|
||||
|
||||
while (overlay->next_buffer == NULL){
|
||||
GST_DEBUG("attempting to pull a buffer");
|
||||
while (overlay->next_buffer == NULL) {
|
||||
GST_DEBUG ("attempting to pull a buffer");
|
||||
|
||||
/* read all text buffers until we get one "in the future" */
|
||||
if(!GST_PAD_IS_USABLE(overlay->text_sinkpad)){
|
||||
if (!GST_PAD_IS_USABLE (overlay->text_sinkpad)) {
|
||||
break;
|
||||
}
|
||||
overlay->next_buffer = GST_BUFFER (gst_pad_pull(overlay->text_sinkpad));
|
||||
overlay->next_buffer = GST_BUFFER (gst_pad_pull (overlay->text_sinkpad));
|
||||
if (!overlay->next_buffer)
|
||||
break;
|
||||
|
||||
if (PAST_END(overlay->next_buffer, now)){
|
||||
gst_buffer_unref(overlay->next_buffer);
|
||||
if (PAST_END (overlay->next_buffer, now)) {
|
||||
gst_buffer_unref (overlay->next_buffer);
|
||||
overlay->next_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (overlay->next_buffer &&
|
||||
(GST_BUFFER_TIMESTAMP(overlay->next_buffer) <= now ||
|
||||
GST_BUFFER_TIMESTAMP(overlay->next_buffer) == GST_CLOCK_TIME_NONE)){
|
||||
GST_DEBUG("using new buffer");
|
||||
(GST_BUFFER_TIMESTAMP (overlay->next_buffer) <= now ||
|
||||
GST_BUFFER_TIMESTAMP (overlay->next_buffer) == GST_CLOCK_TIME_NONE)) {
|
||||
GST_DEBUG ("using new buffer");
|
||||
|
||||
if (overlay->current_buffer){
|
||||
if (overlay->current_buffer) {
|
||||
gst_buffer_unref (overlay->current_buffer);
|
||||
}
|
||||
overlay->current_buffer = overlay->next_buffer;
|
||||
overlay->next_buffer = NULL;
|
||||
|
||||
GST_DEBUG ( "rendering '%*s'",
|
||||
GST_BUFFER_SIZE(overlay->current_buffer),
|
||||
GST_BUFFER_DATA(overlay->current_buffer));
|
||||
pango_layout_set_markup(overlay->layout,
|
||||
GST_BUFFER_DATA(overlay->current_buffer),
|
||||
GST_BUFFER_SIZE(overlay->current_buffer));
|
||||
render_text(overlay);
|
||||
GST_DEBUG ("rendering '%*s'",
|
||||
GST_BUFFER_SIZE (overlay->current_buffer),
|
||||
GST_BUFFER_DATA (overlay->current_buffer));
|
||||
pango_layout_set_markup (overlay->layout,
|
||||
GST_BUFFER_DATA (overlay->current_buffer),
|
||||
GST_BUFFER_SIZE (overlay->current_buffer));
|
||||
render_text (overlay);
|
||||
overlay->need_render = FALSE;
|
||||
}
|
||||
|
||||
if (overlay->current_buffer && PAST_END(overlay->current_buffer, now)){
|
||||
GST_DEBUG("dropping old buffer");
|
||||
if (overlay->current_buffer && PAST_END (overlay->current_buffer, now)) {
|
||||
GST_DEBUG ("dropping old buffer");
|
||||
|
||||
gst_buffer_unref(overlay->current_buffer);
|
||||
gst_buffer_unref (overlay->current_buffer);
|
||||
overlay->current_buffer = NULL;
|
||||
|
||||
overlay->need_render = TRUE;
|
||||
}
|
||||
|
||||
if(overlay->need_render){
|
||||
GST_DEBUG ( "rendering '%s'", overlay->default_text);
|
||||
pango_layout_set_markup(overlay->layout,
|
||||
overlay->default_text, strlen(overlay->default_text));
|
||||
render_text(overlay);
|
||||
if (overlay->need_render) {
|
||||
GST_DEBUG ("rendering '%s'", overlay->default_text);
|
||||
pango_layout_set_markup (overlay->layout,
|
||||
overlay->default_text, strlen (overlay->default_text));
|
||||
render_text (overlay);
|
||||
|
||||
overlay->need_render = FALSE;
|
||||
}
|
||||
|
||||
gst_textoverlay_video_chain(overlay->srcpad, GST_DATA (video_frame));
|
||||
gst_textoverlay_video_chain (overlay->srcpad, GST_DATA (video_frame));
|
||||
}
|
||||
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_textoverlay_change_state(GstElement *element)
|
||||
gst_textoverlay_change_state (GstElement * element)
|
||||
{
|
||||
GstTextOverlay *overlay;
|
||||
|
||||
overlay = GST_TEXTOVERLAY(element);
|
||||
overlay = GST_TEXTOVERLAY (element);
|
||||
|
||||
switch (GST_STATE_TRANSITION(element))
|
||||
{
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
break;
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
|
@ -478,126 +471,133 @@ gst_textoverlay_change_state(GstElement *element)
|
|||
break;
|
||||
}
|
||||
|
||||
parent_class->change_state(element);
|
||||
parent_class->change_state (element);
|
||||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_textoverlay_finalize(GObject *object)
|
||||
gst_textoverlay_finalize (GObject * object)
|
||||
{
|
||||
GstTextOverlay *overlay = GST_TEXTOVERLAY(object);
|
||||
GstTextOverlay *overlay = GST_TEXTOVERLAY (object);
|
||||
|
||||
if (overlay->layout) {
|
||||
g_object_unref(overlay->layout);
|
||||
g_object_unref (overlay->layout);
|
||||
overlay->layout = NULL;
|
||||
}
|
||||
if (overlay->bitmap.buffer) {
|
||||
g_free(overlay->bitmap.buffer);
|
||||
g_free (overlay->bitmap.buffer);
|
||||
overlay->bitmap.buffer = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->finalize(object);
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_textoverlay_init(GstTextOverlay *overlay)
|
||||
gst_textoverlay_init (GstTextOverlay * overlay)
|
||||
{
|
||||
/* video sink */
|
||||
overlay->video_sinkpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&video_sink_template_factory), "video_sink");
|
||||
overlay->video_sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&video_sink_template_factory), "video_sink");
|
||||
/* gst_pad_set_chain_function(overlay->video_sinkpad, gst_textoverlay_video_chain); */
|
||||
gst_pad_set_link_function(overlay->video_sinkpad, gst_textoverlay_video_sinkconnect);
|
||||
gst_element_add_pad(GST_ELEMENT(overlay), overlay->video_sinkpad);
|
||||
gst_pad_set_link_function (overlay->video_sinkpad,
|
||||
gst_textoverlay_video_sinkconnect);
|
||||
gst_element_add_pad (GST_ELEMENT (overlay), overlay->video_sinkpad);
|
||||
|
||||
/* text sink */
|
||||
overlay->text_sinkpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&text_sink_template_factory), "text_sink");
|
||||
overlay->text_sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&text_sink_template_factory), "text_sink");
|
||||
/* gst_pad_set_link_function(overlay->text_sinkpad, gst_textoverlay_text_sinkconnect); */
|
||||
gst_element_add_pad(GST_ELEMENT(overlay), overlay->text_sinkpad);
|
||||
gst_element_add_pad (GST_ELEMENT (overlay), overlay->text_sinkpad);
|
||||
|
||||
/* (video) source */
|
||||
overlay->srcpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&textoverlay_src_template_factory), "src");
|
||||
gst_element_add_pad(GST_ELEMENT(overlay), overlay->srcpad);
|
||||
overlay->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&textoverlay_src_template_factory), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (overlay), overlay->srcpad);
|
||||
|
||||
overlay->layout = pango_layout_new(GST_TEXTOVERLAY_GET_CLASS(overlay)->pango_context);
|
||||
memset(&overlay->bitmap, 0, sizeof(overlay->bitmap));
|
||||
overlay->layout =
|
||||
pango_layout_new (GST_TEXTOVERLAY_GET_CLASS (overlay)->pango_context);
|
||||
memset (&overlay->bitmap, 0, sizeof (overlay->bitmap));
|
||||
|
||||
overlay->halign = GST_TEXT_OVERLAY_HALIGN_CENTER;
|
||||
overlay->valign = GST_TEXT_OVERLAY_VALIGN_BASELINE;
|
||||
overlay->x0 = overlay->y0 = 0;
|
||||
|
||||
overlay->default_text = g_strdup("");
|
||||
overlay->default_text = g_strdup ("");
|
||||
overlay->need_render = TRUE;
|
||||
|
||||
gst_element_set_loop_function(GST_ELEMENT(overlay), gst_textoverlay_loop);
|
||||
gst_element_set_loop_function (GST_ELEMENT (overlay), gst_textoverlay_loop);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_textoverlay_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
gst_textoverlay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstTextOverlay *overlay;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_TEXTOVERLAY(object));
|
||||
overlay = GST_TEXTOVERLAY(object);
|
||||
g_return_if_fail (GST_IS_TEXTOVERLAY (object));
|
||||
overlay = GST_TEXTOVERLAY (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
switch (prop_id) {
|
||||
|
||||
case ARG_TEXT:
|
||||
if(overlay->default_text){
|
||||
g_free(overlay->default_text);
|
||||
if (overlay->default_text) {
|
||||
g_free (overlay->default_text);
|
||||
}
|
||||
overlay->default_text = g_strdup(g_value_get_string(value));
|
||||
overlay->default_text = g_strdup (g_value_get_string (value));
|
||||
overlay->need_render = TRUE;
|
||||
break;
|
||||
|
||||
case ARG_VALIGN:
|
||||
if (strcasecmp(g_value_get_string(value), "baseline") == 0)
|
||||
if (strcasecmp (g_value_get_string (value), "baseline") == 0)
|
||||
overlay->valign = GST_TEXT_OVERLAY_VALIGN_BASELINE;
|
||||
else if (strcasecmp(g_value_get_string(value), "bottom") == 0)
|
||||
else if (strcasecmp (g_value_get_string (value), "bottom") == 0)
|
||||
overlay->valign = GST_TEXT_OVERLAY_VALIGN_BOTTOM;
|
||||
else if (strcasecmp(g_value_get_string(value), "top") == 0)
|
||||
else if (strcasecmp (g_value_get_string (value), "top") == 0)
|
||||
overlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
|
||||
else
|
||||
g_warning("Invalid 'valign' property value: %s",
|
||||
g_value_get_string(value));
|
||||
g_warning ("Invalid 'valign' property value: %s",
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case ARG_HALIGN:
|
||||
if (strcasecmp(g_value_get_string(value), "left") == 0)
|
||||
if (strcasecmp (g_value_get_string (value), "left") == 0)
|
||||
overlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
|
||||
else if (strcasecmp(g_value_get_string(value), "right") == 0)
|
||||
else if (strcasecmp (g_value_get_string (value), "right") == 0)
|
||||
overlay->halign = GST_TEXT_OVERLAY_HALIGN_RIGHT;
|
||||
else if (strcasecmp(g_value_get_string(value), "center") == 0)
|
||||
else if (strcasecmp (g_value_get_string (value), "center") == 0)
|
||||
overlay->halign = GST_TEXT_OVERLAY_HALIGN_CENTER;
|
||||
else
|
||||
g_warning("Invalid 'halign' property value: %s",
|
||||
g_value_get_string(value));
|
||||
g_warning ("Invalid 'halign' property value: %s",
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case ARG_X0:
|
||||
overlay->x0 = g_value_get_int(value);
|
||||
overlay->x0 = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case ARG_Y0:
|
||||
overlay->y0 = g_value_get_int(value);
|
||||
overlay->y0 = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case ARG_FONT_DESC:
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
desc = pango_font_description_from_string(g_value_get_string(value));
|
||||
|
||||
desc = pango_font_description_from_string (g_value_get_string (value));
|
||||
if (desc) {
|
||||
g_message("font description set: %s", g_value_get_string(value));
|
||||
pango_layout_set_font_description(overlay->layout, desc);
|
||||
pango_font_description_free(desc);
|
||||
render_text(overlay);
|
||||
g_message ("font description set: %s", g_value_get_string (value));
|
||||
pango_layout_set_font_description (overlay->layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
render_text (overlay);
|
||||
} else
|
||||
g_warning("font description parse failed: %s", g_value_get_string(value));
|
||||
g_warning ("font description parse failed: %s",
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -607,40 +607,35 @@ gst_textoverlay_set_property(GObject *object, guint prop_id, const GValue *value
|
|||
}
|
||||
|
||||
static void
|
||||
gst_textoverlay_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
gst_textoverlay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstTextOverlay *overlay;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_TEXTOVERLAY(object));
|
||||
overlay = GST_TEXTOVERLAY(object);
|
||||
g_return_if_fail (GST_IS_TEXTOVERLAY (object));
|
||||
overlay = GST_TEXTOVERLAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init(GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_element_register (plugin, "textoverlay", GST_RANK_PRIMARY, GST_TYPE_TEXTOVERLAY))
|
||||
if (!gst_element_register (plugin, "textoverlay", GST_RANK_PRIMARY,
|
||||
GST_TYPE_TEXTOVERLAY))
|
||||
return FALSE;
|
||||
|
||||
/*texttestsrc_plugin_init(module, plugin);*/
|
||||
/*subparse_plugin_init(module, plugin);*/
|
||||
/*texttestsrc_plugin_init(module, plugin); */
|
||||
/*subparse_plugin_init(module, plugin); */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"textoverlay",
|
||||
"Text overlay",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"GPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN)
|
||||
|
||||
"Text overlay", plugin_init, VERSION, "GPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <pango/pangoft2.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TEXTOVERLAY (gst_textoverlay_get_type())
|
||||
#define GST_TEXTOVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
GST_TYPE_TEXTOVERLAY, GstTextOverlay))
|
||||
|
@ -18,27 +17,29 @@ G_BEGIN_DECLS
|
|||
GST_TYPE_TEXTOVERLAY))
|
||||
#define GST_IS_TEXTOVERLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),\
|
||||
GST_TYPE_TEXTOVERLAY))
|
||||
|
||||
typedef struct _GstTextOverlay GstTextOverlay;
|
||||
typedef struct _GstTextOverlayClass GstTextOverlayClass;
|
||||
|
||||
typedef enum _GstTextOverlayVAlign GstTextOverlayVAlign;
|
||||
typedef enum _GstTextOverlayHAlign GstTextOverlayHAlign;
|
||||
|
||||
enum _GstTextOverlayVAlign {
|
||||
enum _GstTextOverlayVAlign
|
||||
{
|
||||
GST_TEXT_OVERLAY_VALIGN_BASELINE,
|
||||
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_RIGHT,
|
||||
};
|
||||
|
||||
|
||||
struct _GstTextOverlay {
|
||||
struct _GstTextOverlay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *video_sinkpad;
|
||||
|
@ -60,14 +61,16 @@ struct _GstTextOverlay {
|
|||
gboolean need_render;
|
||||
};
|
||||
|
||||
struct _GstTextOverlayClass {
|
||||
struct _GstTextOverlayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
PangoContext *pango_context;
|
||||
};
|
||||
|
||||
GType gst_textoverlay_get_type(void) G_GNUC_CONST;
|
||||
GType
|
||||
gst_textoverlay_get_type (void)
|
||||
G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TEXTOVERLAY_H */
|
||||
|
|
|
@ -45,25 +45,30 @@
|
|||
|
||||
|
||||
/* GstTimeoverlay signals and args */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static void gst_timeoverlay_base_init (gpointer g_class);
|
||||
static void gst_timeoverlay_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_timeoverlay_init (GTypeInstance *instance, gpointer g_class);
|
||||
static void gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class);
|
||||
|
||||
static void gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
static void gst_timeoverlay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_timeoverlay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_timeoverlay_planar411(GstVideofilter *videofilter, void *dest, void *src);
|
||||
static void gst_timeoverlay_setup(GstVideofilter *videofilter);
|
||||
static void gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest,
|
||||
void *src);
|
||||
static void gst_timeoverlay_setup (GstVideofilter * videofilter);
|
||||
|
||||
GType
|
||||
gst_timeoverlay_get_type (void)
|
||||
|
@ -72,44 +77,43 @@ gst_timeoverlay_get_type (void)
|
|||
|
||||
if (!timeoverlay_type) {
|
||||
static const GTypeInfo timeoverlay_info = {
|
||||
sizeof(GstTimeoverlayClass),
|
||||
sizeof (GstTimeoverlayClass),
|
||||
gst_timeoverlay_base_init,
|
||||
NULL,
|
||||
gst_timeoverlay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GstTimeoverlay),
|
||||
sizeof (GstTimeoverlay),
|
||||
0,
|
||||
gst_timeoverlay_init,
|
||||
};
|
||||
timeoverlay_type = g_type_register_static(GST_TYPE_VIDEOFILTER,
|
||||
timeoverlay_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
|
||||
"GstTimeoverlay", &timeoverlay_info, 0);
|
||||
}
|
||||
return timeoverlay_type;
|
||||
}
|
||||
|
||||
static GstVideofilterFormat gst_timeoverlay_formats[] = {
|
||||
{ "I420", 12, gst_timeoverlay_planar411, },
|
||||
{"I420", 12, gst_timeoverlay_planar411,},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
gst_timeoverlay_base_init (gpointer g_class)
|
||||
{
|
||||
static GstElementDetails timeoverlay_details = GST_ELEMENT_DETAILS (
|
||||
"Time Overlay",
|
||||
static GstElementDetails timeoverlay_details =
|
||||
GST_ELEMENT_DETAILS ("Time Overlay",
|
||||
"Filter/Editor/Video",
|
||||
"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);
|
||||
GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
|
||||
int i;
|
||||
|
||||
gst_element_class_set_details (element_class, &timeoverlay_details);
|
||||
|
||||
for(i=0;i<G_N_ELEMENTS(gst_timeoverlay_formats);i++){
|
||||
gst_videofilter_class_add_format(videofilter_class,
|
||||
for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) {
|
||||
gst_videofilter_class_add_format (videofilter_class,
|
||||
gst_timeoverlay_formats + i);
|
||||
}
|
||||
|
||||
|
@ -126,8 +130,8 @@ gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
|
|||
videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
|
||||
|
||||
#if 0
|
||||
g_object_class_install_property(gobject_class, ARG_METHOD,
|
||||
g_param_spec_enum("method","method","method",
|
||||
g_object_class_install_property (gobject_class, ARG_METHOD,
|
||||
g_param_spec_enum ("method", "method", "method",
|
||||
GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
|
||||
G_PARAM_READWRITE));
|
||||
#endif
|
||||
|
@ -139,28 +143,29 @@ gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_timeoverlay_init (GTypeInstance *instance, gpointer g_class)
|
||||
gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class)
|
||||
{
|
||||
GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance);
|
||||
GstVideofilter *videofilter;
|
||||
|
||||
GST_DEBUG("gst_timeoverlay_init");
|
||||
GST_DEBUG ("gst_timeoverlay_init");
|
||||
|
||||
videofilter = GST_VIDEOFILTER(timeoverlay);
|
||||
videofilter = GST_VIDEOFILTER (timeoverlay);
|
||||
|
||||
/* do stuff */
|
||||
}
|
||||
|
||||
static void
|
||||
gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
gst_timeoverlay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstTimeoverlay *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_TIMEOVERLAY(object));
|
||||
src = GST_TIMEOVERLAY(object);
|
||||
g_return_if_fail (GST_IS_TIMEOVERLAY (object));
|
||||
src = GST_TIMEOVERLAY (object);
|
||||
|
||||
GST_DEBUG("gst_timeoverlay_set_property");
|
||||
GST_DEBUG ("gst_timeoverlay_set_property");
|
||||
switch (prop_id) {
|
||||
#if 0
|
||||
case ARG_METHOD:
|
||||
|
@ -173,13 +178,14 @@ gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *valu
|
|||
}
|
||||
|
||||
static void
|
||||
gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstTimeoverlay *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_TIMEOVERLAY(object));
|
||||
src = GST_TIMEOVERLAY(object);
|
||||
g_return_if_fail (GST_IS_TIMEOVERLAY (object));
|
||||
src = GST_TIMEOVERLAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
#if 0
|
||||
|
@ -193,35 +199,29 @@ gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GPa
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean plugin_init (GstPlugin *plugin)
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if(!gst_library_load("gstvideofilter"))
|
||||
if (!gst_library_load ("gstvideofilter"))
|
||||
return FALSE;
|
||||
|
||||
return gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
|
||||
GST_TYPE_TIMEOVERLAY);
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"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;
|
||||
PangoFontDescription *font_description;
|
||||
PangoContext *context;
|
||||
|
||||
g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
|
||||
timeoverlay = GST_TIMEOVERLAY(videofilter);
|
||||
g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
|
||||
timeoverlay = GST_TIMEOVERLAY (videofilter);
|
||||
|
||||
/* if any setup needs to be done, do it here */
|
||||
|
||||
|
@ -246,7 +246,8 @@ static void gst_timeoverlay_setup(GstVideofilter *videofilter)
|
|||
|
||||
}
|
||||
|
||||
static char *gst_timeoverlay_print_smpte_time(guint64 time)
|
||||
static char *
|
||||
gst_timeoverlay_print_smpte_time (guint64 time)
|
||||
{
|
||||
int hours;
|
||||
int minutes;
|
||||
|
@ -254,21 +255,21 @@ static char *gst_timeoverlay_print_smpte_time(guint64 time)
|
|||
int ms;
|
||||
double x;
|
||||
|
||||
x = rint((time + 500000)*1e-6);
|
||||
x = rint ((time + 500000) * 1e-6);
|
||||
|
||||
hours = floor(x/(60*60*1000));
|
||||
x -= hours*60*60*1000;
|
||||
minutes = floor(x/(60*1000));
|
||||
x -= minutes*60*1000;
|
||||
seconds = floor(x/(1000));
|
||||
x -= seconds*1000;
|
||||
ms = rint(x);
|
||||
hours = floor (x / (60 * 60 * 1000));
|
||||
x -= hours * 60 * 60 * 1000;
|
||||
minutes = floor (x / (60 * 1000));
|
||||
x -= minutes * 60 * 1000;
|
||||
seconds = floor (x / (1000));
|
||||
x -= seconds * 1000;
|
||||
ms = rint (x);
|
||||
|
||||
return g_strdup_printf("%02d:%02d:%02d.%03d",hours,minutes,seconds,ms);
|
||||
return g_strdup_printf ("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
|
||||
}
|
||||
|
||||
static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
|
||||
void *dest, void *src)
|
||||
static void
|
||||
gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
|
||||
{
|
||||
GstTimeoverlay *timeoverlay;
|
||||
int width;
|
||||
|
@ -280,19 +281,21 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
|
|||
char *string;
|
||||
int i;
|
||||
|
||||
g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
|
||||
timeoverlay = GST_TIMEOVERLAY(videofilter);
|
||||
g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
|
||||
timeoverlay = GST_TIMEOVERLAY (videofilter);
|
||||
|
||||
width = gst_videofilter_get_input_width(videofilter);
|
||||
height = gst_videofilter_get_input_height(videofilter);
|
||||
width = gst_videofilter_get_input_width (videofilter);
|
||||
height = gst_videofilter_get_input_height (videofilter);
|
||||
|
||||
width = gst_videofilter_get_input_width(videofilter);
|
||||
height = gst_videofilter_get_input_height(videofilter);
|
||||
width = gst_videofilter_get_input_width (videofilter);
|
||||
height = gst_videofilter_get_input_height (videofilter);
|
||||
|
||||
layout = pango_layout_new (timeoverlay->context);
|
||||
string = gst_timeoverlay_print_smpte_time(GST_BUFFER_TIMESTAMP(videofilter->in_buf));
|
||||
pango_layout_set_text (layout, string, strlen(string));
|
||||
g_free(string);
|
||||
string =
|
||||
gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (videofilter->
|
||||
in_buf));
|
||||
pango_layout_set_text (layout, string, strlen (string));
|
||||
g_free (string);
|
||||
|
||||
pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
|
||||
pango_layout_set_width (layout, -1);
|
||||
|
@ -303,15 +306,15 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
|
|||
|
||||
//hheight = 20;
|
||||
|
||||
memcpy(dest, src, videofilter->from_buf_size);
|
||||
memcpy (dest, src, videofilter->from_buf_size);
|
||||
|
||||
for(i=0;i<b_height;i++){
|
||||
memset(dest + i*width, 0, b_width);
|
||||
for (i = 0; i < b_height; i++) {
|
||||
memset (dest + i * width, 0, b_width);
|
||||
}
|
||||
for(i=0;i<b_height/2;i++){
|
||||
memset(dest + width*height + i*(width/2), 128, b_width/2);
|
||||
memset(dest + width*height + (width/2)*(height/2) + i*(width/2), 128,
|
||||
b_width/2);
|
||||
for (i = 0; i < b_height / 2; i++) {
|
||||
memset (dest + width * height + i * (width / 2), 128, b_width / 2);
|
||||
memset (dest + width * height + (width / 2) * (height / 2) +
|
||||
i * (width / 2), 128, b_width / 2);
|
||||
}
|
||||
bitmap.rows = b_height;
|
||||
bitmap.width = b_width;
|
||||
|
@ -322,4 +325,3 @@ static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
|
|||
|
||||
pango_ft2_render_layout (&bitmap, layout, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TIMEOVERLAY \
|
||||
(gst_timeoverlay_get_type())
|
||||
#define GST_TIMEOVERLAY(obj) \
|
||||
|
@ -40,11 +39,11 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIMEOVERLAY))
|
||||
#define GST_IS_TIMEOVERLAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIMEOVERLAY))
|
||||
|
||||
typedef struct _GstTimeoverlay GstTimeoverlay;
|
||||
typedef struct _GstTimeoverlayClass GstTimeoverlayClass;
|
||||
|
||||
struct _GstTimeoverlay {
|
||||
struct _GstTimeoverlay
|
||||
{
|
||||
GstVideofilter videofilter;
|
||||
|
||||
PangoFontDescription *font_description;
|
||||
|
@ -52,13 +51,12 @@ struct _GstTimeoverlay {
|
|||
|
||||
};
|
||||
|
||||
struct _GstTimeoverlayClass {
|
||||
struct _GstTimeoverlayClass
|
||||
{
|
||||
GstVideofilterClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_timeoverlay_get_type(void);
|
||||
GType gst_timeoverlay_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TIMEOVERLAY_H__ */
|
||||
|
||||
|
|
|
@ -41,11 +41,12 @@
|
|||
typedef struct _GstTheoraDec GstTheoraDec;
|
||||
typedef struct _GstTheoraDecClass GstTheoraDecClass;
|
||||
|
||||
struct _GstTheoraDec {
|
||||
struct _GstTheoraDec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
theora_state state;
|
||||
theora_info info;
|
||||
|
@ -55,7 +56,8 @@ struct _GstTheoraDec {
|
|||
guint64 granulepos;
|
||||
};
|
||||
|
||||
struct _GstTheoraDecClass {
|
||||
struct _GstTheoraDecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
|
@ -67,41 +69,29 @@ static GstElementDetails theora_dec_details = {
|
|||
};
|
||||
|
||||
static GstStaticPadTemplate theora_dec_src_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
"video/x-raw-yuv, "
|
||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
||||
"format = (fourcc) I420, "
|
||||
"framerate = (double) [0, MAX], "
|
||||
"width = (int) [ 1, MAX ], "
|
||||
"height = (int) [ 1, MAX ]"
|
||||
)
|
||||
);
|
||||
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate theora_dec_sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
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);
|
||||
|
||||
static void theora_dec_chain (GstPad * pad,
|
||||
GstData * data);
|
||||
static GstElementStateReturn
|
||||
theora_dec_change_state (GstElement * element);
|
||||
static gboolean theora_dec_src_event (GstPad * pad,
|
||||
GstEvent * event);
|
||||
static void theora_dec_chain (GstPad * pad, GstData * data);
|
||||
static GstElementStateReturn theora_dec_change_state (GstElement * element);
|
||||
static gboolean theora_dec_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean theora_dec_src_query (GstPad * pad,
|
||||
GstQueryType query,
|
||||
GstFormat * format,
|
||||
gint64 * value);
|
||||
GstQueryType query, GstFormat * format, gint64 * value);
|
||||
|
||||
|
||||
static void
|
||||
|
@ -117,7 +107,7 @@ gst_theora_dec_base_init (gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_theora_dec_class_init (GstTheoraDecClass *klass)
|
||||
gst_theora_dec_class_init (GstTheoraDecClass * klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
|
@ -125,15 +115,17 @@ gst_theora_dec_class_init (GstTheoraDecClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_theora_dec_init (GstTheoraDec *dec)
|
||||
gst_theora_dec_init (GstTheoraDec * dec)
|
||||
{
|
||||
dec->sinkpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&theora_dec_sink_factory), "sink");
|
||||
dec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&theora_dec_sink_factory), "sink");
|
||||
gst_pad_set_chain_function (dec->sinkpad, theora_dec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
|
||||
|
||||
dec->srcpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&theora_dec_src_factory), "src");
|
||||
dec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&theora_dec_src_factory), "src");
|
||||
gst_pad_use_explicit_caps (dec->srcpad);
|
||||
gst_pad_set_event_function (dec->srcpad, theora_dec_src_event);
|
||||
gst_pad_set_query_function (dec->srcpad, theora_dec_src_query);
|
||||
|
@ -144,22 +136,26 @@ gst_theora_dec_init (GstTheoraDec *dec)
|
|||
|
||||
/* FIXME: copy from libtheora, theora should somehow make this available for seeking */
|
||||
static int
|
||||
_theora_ilog(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
_theora_ilog (unsigned int v)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (v) {
|
||||
ret++;
|
||||
v>>=1;
|
||||
v >>= 1;
|
||||
}
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, guint64 *to)
|
||||
theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
|
||||
guint64 * to)
|
||||
{
|
||||
guint64 framecount;
|
||||
guint ilog = _theora_ilog (dec->info.keyframe_frequency_force);
|
||||
|
||||
if (dec->packetno < 1) return FALSE;
|
||||
if (dec->packetno < 1)
|
||||
return FALSE;
|
||||
|
||||
/* granulepos is last ilog bits for counting pframes since last iframe and
|
||||
* bits in front of that for the framenumber of the last iframe. */
|
||||
|
@ -168,7 +164,9 @@ theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, g
|
|||
|
||||
switch (format) {
|
||||
case GST_FORMAT_TIME:
|
||||
*to = framecount = from * GST_SECOND * dec->info.fps_denominator / dec->info.fps_numerator;
|
||||
*to = framecount =
|
||||
from * GST_SECOND * dec->info.fps_denominator /
|
||||
dec->info.fps_numerator;
|
||||
break;
|
||||
case GST_FORMAT_DEFAULT:
|
||||
*to = framecount;
|
||||
|
@ -184,15 +182,19 @@ theora_dec_from_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, g
|
|||
|
||||
/* FIXME: we can only seek to keyframes... */
|
||||
static gboolean
|
||||
theora_dec_to_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, guint64 *to)
|
||||
theora_dec_to_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
|
||||
guint64 * to)
|
||||
{
|
||||
guint64 framecount;
|
||||
|
||||
if (dec->packetno < 1) return FALSE;
|
||||
if (dec->packetno < 1)
|
||||
return FALSE;
|
||||
|
||||
switch (format) {
|
||||
case GST_FORMAT_TIME:
|
||||
framecount = from * dec->info.fps_numerator / (GST_SECOND * dec->info.fps_denominator);
|
||||
framecount =
|
||||
from * dec->info.fps_numerator / (GST_SECOND *
|
||||
dec->info.fps_denominator);
|
||||
break;
|
||||
case GST_FORMAT_DEFAULT:
|
||||
framecount = from;
|
||||
|
@ -208,25 +210,28 @@ theora_dec_to_granulepos (GstTheoraDec *dec, GstFormat format, guint64 from, gui
|
|||
}
|
||||
|
||||
static gboolean
|
||||
theora_dec_src_query (GstPad *pad, GstQueryType query, GstFormat *format, gint64 *value)
|
||||
theora_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format,
|
||||
gint64 * value)
|
||||
{
|
||||
gint64 granulepos;
|
||||
GstTheoraDec *dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
|
||||
GstFormat my_format = GST_FORMAT_DEFAULT;
|
||||
|
||||
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, &granulepos))
|
||||
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
|
||||
&granulepos))
|
||||
return FALSE;
|
||||
|
||||
if (!theora_dec_from_granulepos (dec, *format, granulepos, value))
|
||||
return FALSE;
|
||||
|
||||
GST_LOG_OBJECT (dec, "query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
|
||||
GST_LOG_OBJECT (dec,
|
||||
"query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
|
||||
query, granulepos, *value, *format);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theora_dec_src_event (GstPad *pad, GstEvent *event)
|
||||
theora_dec_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstTheoraDec *dec;
|
||||
|
@ -234,15 +239,17 @@ theora_dec_src_event (GstPad *pad, GstEvent *event)
|
|||
dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK: {
|
||||
case GST_EVENT_SEEK:{
|
||||
guint64 value;
|
||||
|
||||
res = theora_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event), &value);
|
||||
if (res) {
|
||||
GstEvent *real_seek = gst_event_new_seek (
|
||||
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) | GST_FORMAT_DEFAULT,
|
||||
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
|
||||
GST_FORMAT_DEFAULT,
|
||||
value);
|
||||
|
||||
res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek);
|
||||
}
|
||||
gst_event_unref (event);
|
||||
|
@ -257,7 +264,7 @@ theora_dec_src_event (GstPad *pad, GstEvent *event)
|
|||
}
|
||||
|
||||
static void
|
||||
theora_dec_event (GstTheoraDec *dec, GstEvent *event)
|
||||
theora_dec_event (GstTheoraDec * dec, GstEvent * event)
|
||||
{
|
||||
guint64 value, time, bytes;
|
||||
|
||||
|
@ -266,27 +273,37 @@ theora_dec_event (GstTheoraDec *dec, GstEvent *event)
|
|||
case GST_EVENT_DISCONTINUOUS:
|
||||
if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)) {
|
||||
dec->granulepos = value;
|
||||
GST_DEBUG_OBJECT (dec, "setting granuleposition to %"G_GUINT64_FORMAT" after discont\n", value);
|
||||
GST_DEBUG_OBJECT (dec,
|
||||
"setting granuleposition to %" G_GUINT64_FORMAT " after discont\n",
|
||||
value);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (dec,
|
||||
"discont event didn't include offset, we might set it wrong now");
|
||||
}
|
||||
if (dec->packetno < 3) {
|
||||
if (dec->granulepos != 0)
|
||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("can't handle discont before parsing first 3 packets"));
|
||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
|
||||
("can't handle discont before parsing first 3 packets"));
|
||||
dec->packetno = 0;
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, (guint64) 0,
|
||||
GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE,
|
||||
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
|
||||
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
|
||||
} else {
|
||||
dec->packetno = 3;
|
||||
/* if one of them works, all of them work */
|
||||
if (theora_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos, &time) &&
|
||||
theora_dec_from_granulepos (dec, GST_FORMAT_DEFAULT, dec->granulepos, &value) &&
|
||||
theora_dec_from_granulepos (dec, GST_FORMAT_BYTES, dec->granulepos, &bytes)) {
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
|
||||
GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes, 0)));
|
||||
if (theora_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
|
||||
&time)
|
||||
&& theora_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
|
||||
dec->granulepos, &value)
|
||||
&& theora_dec_from_granulepos (dec, GST_FORMAT_BYTES,
|
||||
dec->granulepos, &bytes)) {
|
||||
gst_pad_push (dec->srcpad,
|
||||
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
|
||||
0)));
|
||||
} else {
|
||||
GST_ERROR_OBJECT (dec, "failed to parse data for DISCONT event, not sending any");
|
||||
GST_ERROR_OBJECT (dec,
|
||||
"failed to parse data for DISCONT event, not sending any");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -297,7 +314,7 @@ theora_dec_event (GstTheoraDec *dec, GstEvent *event)
|
|||
}
|
||||
|
||||
static void
|
||||
theora_dec_chain (GstPad *pad, GstData *data)
|
||||
theora_dec_chain (GstPad * pad, GstData * data)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GstTheoraDec *dec;
|
||||
|
@ -314,7 +331,7 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
packet.packet = GST_BUFFER_DATA (buf);
|
||||
packet.bytes = GST_BUFFER_SIZE (buf);
|
||||
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
|
||||
packet.packetno = dec->packetno ++;
|
||||
packet.packetno = dec->packetno++;
|
||||
packet.b_o_s = (packet.packetno == 0) ? 1 : 0;
|
||||
packet.e_o_s = 0;
|
||||
/* switch depending on packet type */
|
||||
|
@ -328,7 +345,10 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
}
|
||||
if (packet.packetno == 1) {
|
||||
gchar *encoder = NULL;
|
||||
GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf, "\201theora", 7, &encoder);
|
||||
GstTagList *list =
|
||||
gst_tag_list_from_vorbiscomment_buffer (buf, "\201theora", 7,
|
||||
&encoder);
|
||||
|
||||
if (!list) {
|
||||
GST_ERROR_OBJECT (dec, "failed to parse tags");
|
||||
list = gst_tag_list_new ();
|
||||
|
@ -343,14 +363,15 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, 0, list);
|
||||
} else if (packet.packetno == 2) {
|
||||
GstCaps *caps;
|
||||
|
||||
/* done */
|
||||
theora_decode_init (&dec->state, &dec->info);
|
||||
caps = gst_caps_new_simple ("video/x-raw-yuv",
|
||||
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
|
||||
"framerate", G_TYPE_DOUBLE, ((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
|
||||
"width", G_TYPE_INT, dec->info.width,
|
||||
"height", G_TYPE_INT, dec->info.height,
|
||||
NULL);
|
||||
"framerate", G_TYPE_DOUBLE,
|
||||
((gdouble) dec->info.fps_numerator) / dec->info.fps_denominator,
|
||||
"width", G_TYPE_INT, dec->info.width, "height", G_TYPE_INT,
|
||||
dec->info.height, NULL);
|
||||
gst_pad_set_explicit_caps (dec->srcpad, caps);
|
||||
gst_caps_free (caps);
|
||||
}
|
||||
|
@ -359,11 +380,13 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
GstBuffer *out;
|
||||
guint8 *y, *v, *u;
|
||||
guint i;
|
||||
|
||||
/* normal data packet */
|
||||
#if 0
|
||||
{
|
||||
GTimeVal tv;
|
||||
guint64 time;
|
||||
|
||||
g_get_current_time (&tv);
|
||||
time = GST_TIMEVAL_TO_TIME (tv);
|
||||
#endif
|
||||
|
@ -395,8 +418,11 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
}
|
||||
GST_BUFFER_OFFSET (out) = dec->packetno - 4;
|
||||
GST_BUFFER_OFFSET_END (out) = dec->packetno - 3;
|
||||
GST_BUFFER_DURATION (out) = GST_SECOND * ((gdouble) dec->info.fps_denominator) / dec->info.fps_numerator;
|
||||
GST_BUFFER_TIMESTAMP (out) = GST_BUFFER_OFFSET (out) * GST_BUFFER_DURATION (out);
|
||||
GST_BUFFER_DURATION (out) =
|
||||
GST_SECOND * ((gdouble) dec->info.fps_denominator) /
|
||||
dec->info.fps_numerator;
|
||||
GST_BUFFER_TIMESTAMP (out) =
|
||||
GST_BUFFER_OFFSET (out) * GST_BUFFER_DURATION (out);
|
||||
#if 0
|
||||
g_get_current_time (&tv);
|
||||
time = GST_TIMEVAL_TO_TIME (tv) - time;
|
||||
|
@ -410,7 +436,7 @@ theora_dec_chain (GstPad *pad, GstData *data)
|
|||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
theora_dec_change_state (GstElement *element)
|
||||
theora_dec_change_state (GstElement * element)
|
||||
{
|
||||
GstTheoraDec *dec = GST_THEORA_DEC (element);
|
||||
|
||||
|
@ -443,24 +469,20 @@ theora_dec_change_state (GstElement *element)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_library_load ("gsttags"))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_element_register (plugin, "theoradec", GST_RANK_SECONDARY, gst_theora_dec_get_type ()))
|
||||
if (!gst_element_register (plugin, "theoradec", GST_RANK_SECONDARY,
|
||||
gst_theora_dec_get_type ()))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gsttheora",
|
||||
"Theora plugin library",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"LGPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN)
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
GST_DEBUG_CATEGORY (vorbisdec_debug);
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_library_load ("gstbytestream"))
|
||||
return FALSE;
|
||||
|
@ -35,23 +35,21 @@ plugin_init (GstPlugin *plugin)
|
|||
if (!gst_library_load ("gsttags"))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_element_register (plugin, "vorbisenc", GST_RANK_NONE, GST_TYPE_VORBISENC))
|
||||
if (!gst_element_register (plugin, "vorbisenc", GST_RANK_NONE,
|
||||
GST_TYPE_VORBISENC))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_element_register (plugin, "vorbisdec", GST_RANK_PRIMARY, gst_vorbis_dec_get_type ()))
|
||||
if (!gst_element_register (plugin, "vorbisdec", GST_RANK_PRIMARY,
|
||||
gst_vorbis_dec_get_type ()))
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "vorbisdec", 0, "vorbis decoding element");
|
||||
GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "vorbisdec", 0,
|
||||
"vorbis decoding element");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"vorbis",
|
||||
"Vorbis plugin library",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"LGPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN)
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -36,60 +36,48 @@ static GstElementDetails vorbis_dec_details = {
|
|||
};
|
||||
|
||||
/* Filter signals and args */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate vorbis_dec_src_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
"audio/x-raw-float, "
|
||||
GST_STATIC_CAPS ("audio/x-raw-float, "
|
||||
"rate = (int) [ 11025, 48000 ], "
|
||||
"channels = (int) [ 1, 2 ], "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, "
|
||||
/* no ifdef in macros, please
|
||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
||||
"layout = \"sequential\", "
|
||||
#endif
|
||||
*/
|
||||
"width = (int) 32, "
|
||||
"buffer-frames = (int) 0"
|
||||
)
|
||||
);
|
||||
"width = (int) 32, " "buffer-frames = (int) 0")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate vorbis_dec_sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
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);
|
||||
|
||||
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 void vorbis_dec_chain (GstPad * pad, GstData * data);
|
||||
static GstElementStateReturn vorbis_dec_change_state (GstElement * element);
|
||||
static const GstFormat *vorbis_dec_get_formats (GstPad * pad);
|
||||
|
||||
static gboolean vorbis_dec_src_event (GstPad * pad,
|
||||
GstEvent * event);
|
||||
static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean vorbis_dec_src_query (GstPad * pad,
|
||||
GstQueryType query,
|
||||
GstFormat * format,
|
||||
gint64 * value);
|
||||
GstQueryType query, GstFormat * format, gint64 * value);
|
||||
|
||||
|
||||
static void
|
||||
|
@ -105,7 +93,7 @@ gst_vorbis_dec_base_init (gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbis_dec_class_init (GstVorbisDecClass *klass)
|
||||
gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
|
@ -113,7 +101,7 @@ gst_vorbis_dec_class_init (GstVorbisDecClass *klass)
|
|||
}
|
||||
|
||||
static const GstFormat *
|
||||
vorbis_dec_get_formats (GstPad *pad)
|
||||
vorbis_dec_get_formats (GstPad * pad)
|
||||
{
|
||||
static const GstFormat src_formats[] = {
|
||||
GST_FORMAT_BYTES,
|
||||
|
@ -130,7 +118,7 @@ vorbis_dec_get_formats (GstPad *pad)
|
|||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
vorbis_dec_link (GstPad *pad, const GstCaps *caps)
|
||||
vorbis_dec_link (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
|
@ -141,7 +129,7 @@ vorbis_dec_link (GstPad *pad, const GstCaps *caps)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
vorbis_dec_getcaps (GstPad *pad)
|
||||
vorbis_dec_getcaps (GstPad * pad)
|
||||
{
|
||||
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
|
@ -151,26 +139,26 @@ vorbis_dec_getcaps (GstPad *pad)
|
|||
return gst_caps_new_simple ("audio/x-raw-float",
|
||||
"rate", G_TYPE_INT, dec->vi.rate,
|
||||
"channels", G_TYPE_INT, dec->vi.channels,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"width", G_TYPE_INT, 32,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
|
||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
||||
"layout", G_TYPE_STRING, "sequential",
|
||||
#endif
|
||||
"buffer-frames", G_TYPE_INT, 0,
|
||||
NULL);
|
||||
"buffer-frames", G_TYPE_INT, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vorbis_dec_init (GstVorbisDec *dec)
|
||||
gst_vorbis_dec_init (GstVorbisDec * dec)
|
||||
{
|
||||
dec->sinkpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&vorbis_dec_sink_factory), "sink");
|
||||
dec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&vorbis_dec_sink_factory), "sink");
|
||||
gst_pad_set_chain_function (dec->sinkpad, vorbis_dec_chain);
|
||||
gst_pad_set_formats_function (dec->sinkpad, vorbis_dec_get_formats);
|
||||
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
|
||||
|
||||
dec->srcpad = gst_pad_new_from_template(
|
||||
gst_static_pad_template_get (&vorbis_dec_src_factory), "src");
|
||||
dec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&vorbis_dec_src_factory), "src");
|
||||
gst_pad_set_link_function (dec->srcpad, vorbis_dec_link);
|
||||
gst_pad_set_getcaps_function (dec->srcpad, vorbis_dec_getcaps);
|
||||
gst_pad_set_event_function (dec->srcpad, vorbis_dec_src_event);
|
||||
|
@ -183,9 +171,11 @@ gst_vorbis_dec_init (GstVorbisDec *dec)
|
|||
|
||||
/* FIXME: plug this to the pad convert function */
|
||||
static gboolean
|
||||
vorbis_dec_to_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, guint64 *to)
|
||||
vorbis_dec_to_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
|
||||
guint64 * to)
|
||||
{
|
||||
if (dec->packetno < 1) return FALSE;
|
||||
if (dec->packetno < 1)
|
||||
return FALSE;
|
||||
|
||||
switch (format) {
|
||||
case GST_FORMAT_TIME:
|
||||
|
@ -203,9 +193,11 @@ vorbis_dec_to_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, gui
|
|||
}
|
||||
|
||||
static gboolean
|
||||
vorbis_dec_from_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, guint64 *to)
|
||||
vorbis_dec_from_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
|
||||
guint64 * to)
|
||||
{
|
||||
if (dec->packetno < 1) return FALSE;
|
||||
if (dec->packetno < 1)
|
||||
return FALSE;
|
||||
|
||||
switch (format) {
|
||||
case GST_FORMAT_TIME:
|
||||
|
@ -224,39 +216,44 @@ vorbis_dec_from_granulepos (GstVorbisDec *dec, GstFormat format, guint64 from, g
|
|||
|
||||
|
||||
static gboolean
|
||||
vorbis_dec_src_query (GstPad *pad, GstQueryType query, GstFormat *format, gint64 *value)
|
||||
vorbis_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format,
|
||||
gint64 * value)
|
||||
{
|
||||
gint64 granulepos;
|
||||
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
GstFormat my_format = GST_FORMAT_DEFAULT;
|
||||
|
||||
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, &granulepos))
|
||||
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
|
||||
&granulepos))
|
||||
return FALSE;
|
||||
|
||||
if (!vorbis_dec_from_granulepos (dec, *format, granulepos, value))
|
||||
return FALSE;
|
||||
|
||||
GST_LOG_OBJECT (dec, "query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
|
||||
GST_LOG_OBJECT (dec,
|
||||
"query %u: peer returned granulepos: %llu - we return %llu (format %u)\n",
|
||||
query, granulepos, *value, *format);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vorbis_dec_src_event (GstPad *pad, GstEvent *event)
|
||||
vorbis_dec_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK: {
|
||||
case GST_EVENT_SEEK:{
|
||||
guint64 value;
|
||||
|
||||
res = vorbis_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event), &value);
|
||||
if (res) {
|
||||
GstEvent *real_seek = gst_event_new_seek (
|
||||
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) | GST_FORMAT_DEFAULT,
|
||||
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
|
||||
GST_FORMAT_DEFAULT,
|
||||
value);
|
||||
|
||||
res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek);
|
||||
}
|
||||
gst_event_unref (event);
|
||||
|
@ -270,7 +267,7 @@ vorbis_dec_src_event (GstPad *pad, GstEvent *event)
|
|||
return res;
|
||||
}
|
||||
static void
|
||||
vorbis_dec_event (GstVorbisDec *dec, GstEvent *event)
|
||||
vorbis_dec_event (GstVorbisDec * dec, GstEvent * event)
|
||||
{
|
||||
guint64 value, time, bytes;
|
||||
|
||||
|
@ -279,27 +276,37 @@ vorbis_dec_event (GstVorbisDec *dec, GstEvent *event)
|
|||
case GST_EVENT_DISCONTINUOUS:
|
||||
if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)) {
|
||||
dec->granulepos = value;
|
||||
GST_DEBUG_OBJECT (dec, "setting granuleposition to %"G_GUINT64_FORMAT" after discont", value);
|
||||
GST_DEBUG_OBJECT (dec,
|
||||
"setting granuleposition to %" G_GUINT64_FORMAT " after discont",
|
||||
value);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (dec,
|
||||
"discont event didn't include offset, we might set it wrong now");
|
||||
}
|
||||
if (dec->packetno < 3) {
|
||||
if (dec->granulepos != 0)
|
||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("can't handle discont before parsing first 3 packets"));
|
||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
|
||||
("can't handle discont before parsing first 3 packets"));
|
||||
dec->packetno = 0;
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, (guint64) 0,
|
||||
GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE,
|
||||
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
|
||||
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
|
||||
} else {
|
||||
dec->packetno = 3;
|
||||
/* if one of them works, all of them work */
|
||||
if (vorbis_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos, &time) &&
|
||||
vorbis_dec_from_granulepos (dec, GST_FORMAT_DEFAULT, dec->granulepos, &value) &&
|
||||
vorbis_dec_from_granulepos (dec, GST_FORMAT_BYTES, dec->granulepos, &bytes)) {
|
||||
gst_pad_push (dec->srcpad, GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
|
||||
GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes, 0)));
|
||||
if (vorbis_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
|
||||
&time)
|
||||
&& vorbis_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
|
||||
dec->granulepos, &value)
|
||||
&& vorbis_dec_from_granulepos (dec, GST_FORMAT_BYTES,
|
||||
dec->granulepos, &bytes)) {
|
||||
gst_pad_push (dec->srcpad,
|
||||
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
|
||||
time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
|
||||
0)));
|
||||
} else {
|
||||
GST_ERROR_OBJECT (dec, "failed to parse data for DISCONT event, not sending any");
|
||||
GST_ERROR_OBJECT (dec,
|
||||
"failed to parse data for DISCONT event, not sending any");
|
||||
}
|
||||
#ifdef HAVE_VORBIS_SYNTHESIS_RESTART
|
||||
vorbis_synthesis_restart (&dec->vd);
|
||||
|
@ -313,7 +320,7 @@ vorbis_dec_event (GstVorbisDec *dec, GstEvent *event)
|
|||
}
|
||||
|
||||
static void
|
||||
vorbis_dec_chain (GstPad *pad, GstData *data)
|
||||
vorbis_dec_chain (GstPad * pad, GstData * data)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GstVorbisDec *vd;
|
||||
|
@ -330,14 +337,15 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
|
|||
packet.packet = GST_BUFFER_DATA (buf);
|
||||
packet.bytes = GST_BUFFER_SIZE (buf);
|
||||
packet.granulepos = GST_BUFFER_OFFSET_END (buf);
|
||||
packet.packetno = vd->packetno ++;
|
||||
packet.packetno = vd->packetno++;
|
||||
/* switch depending on packet type */
|
||||
if (packet.packet[0] & 1) {
|
||||
/* header packet */
|
||||
if (packet.packet[0] / 2 != packet.packetno) {
|
||||
/* FIXME: just skip? */
|
||||
GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
|
||||
(NULL), ("unexpected packet type %d, expected %d", (gint) packet.packet[0], (gint) packet.packetno));
|
||||
(NULL), ("unexpected packet type %d, expected %d",
|
||||
(gint) packet.packet[0], (gint) packet.packetno));
|
||||
gst_data_unref (data);
|
||||
return;
|
||||
}
|
||||
|
@ -349,7 +357,10 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
|
|||
}
|
||||
if (packet.packetno == 1) {
|
||||
gchar *encoder = NULL;
|
||||
GstTagList *list = gst_tag_list_from_vorbiscomment_buffer (buf, "\003vorbis", 7, &encoder);
|
||||
GstTagList *list =
|
||||
gst_tag_list_from_vorbiscomment_buffer (buf, "\003vorbis", 7,
|
||||
&encoder);
|
||||
|
||||
if (!list) {
|
||||
GST_ERROR_OBJECT (vd, "couldn't decode comments");
|
||||
list = gst_tag_list_new ();
|
||||
|
@ -401,6 +412,7 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
|
|||
GstBuffer *out = gst_pad_alloc_buffer (vd->srcpad, GST_BUFFER_OFFSET_NONE,
|
||||
sample_count * vd->vi.channels * sizeof (float));
|
||||
float *out_data = (float *) GST_BUFFER_DATA (out);
|
||||
|
||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
||||
for (i = 0; i < vd->vi.channels; i++) {
|
||||
memcpy (out_data, pcm[i], sample_count * sizeof (float));
|
||||
|
@ -427,7 +439,7 @@ vorbis_dec_chain (GstPad *pad, GstData *data)
|
|||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
vorbis_dec_change_state (GstElement *element)
|
||||
vorbis_dec_change_state (GstElement * element)
|
||||
{
|
||||
GstVorbisDec *vd = GST_VORBIS_DEC (element);
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#include <vorbis/codec.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
@ -42,14 +43,15 @@ extern "C" {
|
|||
#define GST_IS_VORBIS_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VORBIS_DEC))
|
||||
|
||||
typedef struct _GstVorbisDec GstVorbisDec;
|
||||
typedef struct _GstVorbisDecClass GstVorbisDecClass;
|
||||
typedef struct _GstVorbisDec GstVorbisDec;
|
||||
typedef struct _GstVorbisDecClass GstVorbisDecClass;
|
||||
|
||||
struct _GstVorbisDec {
|
||||
struct _GstVorbisDec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_info vi;
|
||||
|
@ -57,13 +59,14 @@ struct _GstVorbisDec {
|
|||
vorbis_block vb;
|
||||
guint packetno;
|
||||
guint64 granulepos;
|
||||
};
|
||||
};
|
||||
|
||||
struct _GstVorbisDecClass {
|
||||
struct _GstVorbisDecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
};
|
||||
|
||||
GType gst_vorbis_dec_get_type(void);
|
||||
GType gst_vorbis_dec_get_type (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ GstElementDetails vorbisenc_details = {
|
|||
"Ogg Vorbis encoder",
|
||||
"Codec/Encoder/Audio",
|
||||
"Encodes audio in OGG Vorbis format",
|
||||
"Monty <monty@xiph.org>, "
|
||||
"Wim Taymans <wim.taymans@chello.be>",
|
||||
"Monty <monty@xiph.org>, " "Wim Taymans <wim.taymans@chello.be>",
|
||||
};
|
||||
|
||||
/* VorbisEnc signals and args */
|
||||
|
@ -60,8 +59,8 @@ enum
|
|||
ARG_LAST_MESSAGE,
|
||||
};
|
||||
|
||||
static const GstFormat*
|
||||
gst_vorbisenc_get_formats (GstPad *pad)
|
||||
static const GstFormat *
|
||||
gst_vorbisenc_get_formats (GstPad * pad)
|
||||
{
|
||||
static const GstFormat src_formats[] = {
|
||||
GST_FORMAT_BYTES,
|
||||
|
@ -84,20 +83,20 @@ gst_vorbisenc_get_formats (GstPad *pad)
|
|||
#define QUALITY_DEFAULT 0.3
|
||||
|
||||
static void gst_vorbisenc_base_init (gpointer g_class);
|
||||
static void gst_vorbisenc_class_init (VorbisEncClass *klass);
|
||||
static void gst_vorbisenc_init (VorbisEnc *vorbisenc);
|
||||
static void gst_vorbisenc_class_init (VorbisEncClass * klass);
|
||||
static void gst_vorbisenc_init (VorbisEnc * vorbisenc);
|
||||
|
||||
static void gst_vorbisenc_chain (GstPad *pad, GstData *_data);
|
||||
static gboolean gst_vorbisenc_setup (VorbisEnc *vorbisenc);
|
||||
static void gst_vorbisenc_chain (GstPad * pad, GstData * _data);
|
||||
static gboolean gst_vorbisenc_setup (VorbisEnc * vorbisenc);
|
||||
|
||||
static void gst_vorbisenc_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
static void gst_vorbisenc_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static GstElementStateReturn
|
||||
gst_vorbisenc_change_state (GstElement *element);
|
||||
static void gst_vorbisenc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_vorbisenc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static GstElementStateReturn gst_vorbisenc_change_state (GstElement * element);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
/*static guint gst_vorbisenc_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
GType
|
||||
|
@ -123,20 +122,23 @@ vorbisenc_get_type (void)
|
|||
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,
|
||||
0);
|
||||
|
||||
g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER, &tag_setter_info);
|
||||
g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
|
||||
&tag_setter_info);
|
||||
}
|
||||
return vorbisenc_type;
|
||||
}
|
||||
|
||||
static GstCaps*
|
||||
static GstCaps *
|
||||
vorbis_caps_factory (void)
|
||||
{
|
||||
return gst_caps_new_simple ("application/ogg", NULL);
|
||||
}
|
||||
|
||||
static GstCaps*
|
||||
static GstCaps *
|
||||
raw_caps_factory (void)
|
||||
{
|
||||
return
|
||||
|
@ -146,8 +148,7 @@ raw_caps_factory (void)
|
|||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"rate", GST_TYPE_INT_RANGE, 11025, 48000,
|
||||
"channels", GST_TYPE_INT_RANGE, 1, 2,
|
||||
NULL);
|
||||
"channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -160,13 +161,13 @@ gst_vorbisenc_base_init (gpointer g_class)
|
|||
vorbis_caps = vorbis_caps_factory ();
|
||||
|
||||
gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
raw_caps);
|
||||
GST_PAD_ALWAYS, raw_caps);
|
||||
gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
vorbis_caps);
|
||||
gst_element_class_add_pad_template (element_class, gst_vorbisenc_sink_template);
|
||||
gst_element_class_add_pad_template (element_class, gst_vorbisenc_src_template);
|
||||
GST_PAD_ALWAYS, vorbis_caps);
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_vorbisenc_sink_template);
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_vorbisenc_src_template);
|
||||
gst_element_class_set_details (element_class, &vorbisenc_details);
|
||||
}
|
||||
|
||||
|
@ -196,14 +197,15 @@ gst_vorbisenc_class_init (VorbisEncClass * klass)
|
|||
"Specify quality instead of specifying a particular bitrate.",
|
||||
0.0, 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SERIAL,
|
||||
g_param_spec_int ("serial", "Serial", "Specify a serial number for the stream. (-1 is random)",
|
||||
-1, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
g_param_spec_int ("serial", "Serial",
|
||||
"Specify a serial number for the stream. (-1 is random)", -1,
|
||||
G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
|
||||
g_param_spec_boolean ("managed", "Managed", "Enable bitrate management engine",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
g_param_spec_boolean ("managed", "Managed",
|
||||
"Enable bitrate management engine", FALSE, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
|
||||
g_param_spec_string ("last-message", "last-message", "The last status message",
|
||||
NULL, G_PARAM_READABLE));
|
||||
g_param_spec_string ("last-message", "last-message",
|
||||
"The last status message", NULL, G_PARAM_READABLE));
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
|
@ -234,8 +236,8 @@ gst_vorbisenc_sinkconnect (GstPad * pad, const GstCaps * caps)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||
GstFormat *dest_format, gint64 *dest_value)
|
||||
gst_vorbisenc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
|
||||
GstFormat * dest_format, gint64 * dest_value)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
VorbisEnc *vorbisenc;
|
||||
|
@ -244,12 +246,10 @@ gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
|||
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
|
||||
|
||||
if (vorbisenc->samples_in == 0 ||
|
||||
vorbisenc->bytes_out == 0 ||
|
||||
vorbisenc->frequency == 0)
|
||||
vorbisenc->bytes_out == 0 || vorbisenc->frequency == 0)
|
||||
return FALSE;
|
||||
|
||||
avg = (vorbisenc->bytes_out * vorbisenc->frequency)/
|
||||
(vorbisenc->samples_in);
|
||||
avg = (vorbisenc->bytes_out * vorbisenc->frequency) / (vorbisenc->samples_in);
|
||||
|
||||
switch (src_format) {
|
||||
case GST_FORMAT_BYTES:
|
||||
|
@ -277,8 +277,8 @@ gst_vorbisenc_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_vorbisenc_convert_sink (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||
GstFormat *dest_format, gint64 *dest_value)
|
||||
gst_vorbisenc_convert_sink (GstPad * pad, GstFormat src_format,
|
||||
gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
guint scale = 1;
|
||||
|
@ -342,8 +342,8 @@ gst_vorbisenc_convert_sink (GstPad *pad, GstFormat src_format, gint64 src_value,
|
|||
return res;
|
||||
}
|
||||
|
||||
static const GstQueryType*
|
||||
gst_vorbisenc_get_query_types (GstPad *pad)
|
||||
static const GstQueryType *
|
||||
gst_vorbisenc_get_query_types (GstPad * pad)
|
||||
{
|
||||
static const GstQueryType gst_vorbisenc_src_query_types[] = {
|
||||
GST_QUERY_TOTAL,
|
||||
|
@ -354,8 +354,8 @@ gst_vorbisenc_get_query_types (GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
|
||||
GstFormat *format, gint64 *value)
|
||||
gst_vorbisenc_src_query (GstPad * pad, GstQueryType type,
|
||||
GstFormat * format, gint64 * value)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
VorbisEnc *vorbisenc;
|
||||
|
@ -374,26 +374,25 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
|
|||
|
||||
res = FALSE;
|
||||
|
||||
peer_formats = gst_pad_get_formats (GST_PAD_PEER (vorbisenc->sinkpad));
|
||||
peer_formats =
|
||||
gst_pad_get_formats (GST_PAD_PEER (vorbisenc->sinkpad));
|
||||
|
||||
while (peer_formats && *peer_formats && !res) {
|
||||
|
||||
GstFormat peer_format = *peer_formats;
|
||||
|
||||
/* do the probe */
|
||||
if (gst_pad_query (GST_PAD_PEER (vorbisenc->sinkpad), GST_QUERY_TOTAL,
|
||||
&peer_format, &peer_value))
|
||||
{
|
||||
if (gst_pad_query (GST_PAD_PEER (vorbisenc->sinkpad),
|
||||
GST_QUERY_TOTAL, &peer_format, &peer_value)) {
|
||||
GstFormat conv_format;
|
||||
|
||||
/* convert to TIME */
|
||||
conv_format = GST_FORMAT_TIME;
|
||||
res = gst_pad_convert (vorbisenc->sinkpad,
|
||||
peer_format, peer_value,
|
||||
&conv_format, value);
|
||||
peer_format, peer_value, &conv_format, value);
|
||||
/* and to final format */
|
||||
res &= gst_pad_convert (pad,
|
||||
GST_FORMAT_TIME, *value,
|
||||
format, value);
|
||||
GST_FORMAT_TIME, *value, format, value);
|
||||
}
|
||||
peer_formats++;
|
||||
}
|
||||
|
@ -411,8 +410,7 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
|
|||
{
|
||||
/* we only know about our samples, convert to requested format */
|
||||
res = gst_pad_convert (pad,
|
||||
GST_FORMAT_BYTES, vorbisenc->bytes_out,
|
||||
format, value);
|
||||
GST_FORMAT_BYTES, vorbisenc->bytes_out, format, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -427,18 +425,26 @@ gst_vorbisenc_src_query (GstPad *pad, GstQueryType type,
|
|||
static void
|
||||
gst_vorbisenc_init (VorbisEnc * vorbisenc)
|
||||
{
|
||||
vorbisenc->sinkpad = gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
|
||||
vorbisenc->sinkpad =
|
||||
gst_pad_new_from_template (gst_vorbisenc_sink_template, "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
|
||||
gst_pad_set_chain_function (vorbisenc->sinkpad, gst_vorbisenc_chain);
|
||||
gst_pad_set_link_function (vorbisenc->sinkpad, gst_vorbisenc_sinkconnect);
|
||||
gst_pad_set_convert_function (vorbisenc->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_sink));
|
||||
gst_pad_set_formats_function (vorbisenc->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
|
||||
gst_pad_set_convert_function (vorbisenc->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_sink));
|
||||
gst_pad_set_formats_function (vorbisenc->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
|
||||
|
||||
vorbisenc->srcpad = gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
|
||||
gst_pad_set_query_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
|
||||
gst_pad_set_query_type_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
|
||||
gst_pad_set_convert_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_src));
|
||||
gst_pad_set_formats_function (vorbisenc->srcpad, GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
|
||||
vorbisenc->srcpad =
|
||||
gst_pad_new_from_template (gst_vorbisenc_src_template, "src");
|
||||
gst_pad_set_query_function (vorbisenc->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_src_query));
|
||||
gst_pad_set_query_type_function (vorbisenc->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_query_types));
|
||||
gst_pad_set_convert_function (vorbisenc->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_convert_src));
|
||||
gst_pad_set_formats_function (vorbisenc->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbisenc_get_formats));
|
||||
gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->srcpad);
|
||||
|
||||
vorbisenc->channels = -1;
|
||||
|
@ -465,7 +471,8 @@ gst_vorbisenc_init (VorbisEnc * vorbisenc)
|
|||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -479,6 +486,7 @@ gst_vorbisenc_get_tag_value (const GstTagList *list, const gchar *tag, int index
|
|||
|| (strcmp (tag, GST_TAG_TRACK_COUNT) == 0)
|
||||
|| (strcmp (tag, GST_TAG_ALBUM_VOLUME_COUNT) == 0)) {
|
||||
guint track_no;
|
||||
|
||||
g_assert (gst_tag_list_get_uint_index (list, tag, index, &track_no));
|
||||
vorbisvalue = g_strdup_printf ("%u", track_no);
|
||||
} else if (strcmp (tag, GST_TAG_DATE) == 0) {
|
||||
|
@ -488,7 +496,8 @@ gst_vorbisenc_get_tag_value (const GstTagList *list, const gchar *tag, int index
|
|||
|
||||
g_assert (gst_tag_list_get_uint_index (list, tag, index, &u));
|
||||
date = g_date_new_julian (u);
|
||||
vorbisvalue = g_strdup_printf ("%04d-%02d-%02d", (gint) g_date_get_year (date),
|
||||
vorbisvalue =
|
||||
g_strdup_printf ("%04d-%02d-%02d", (gint) g_date_get_year (date),
|
||||
(gint) g_date_get_month (date), (gint) g_date_get_day (date));
|
||||
g_date_free (date);
|
||||
} else if (gst_tag_get_type (tag) == G_TYPE_STRING) {
|
||||
|
@ -499,7 +508,8 @@ gst_vorbisenc_get_tag_value (const GstTagList *list, const gchar *tag, int index
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_metadata_set1 (const GstTagList *list, const gchar *tag, gpointer vorbisenc)
|
||||
gst_vorbisenc_metadata_set1 (const GstTagList * list, const gchar * tag,
|
||||
gpointer vorbisenc)
|
||||
{
|
||||
const gchar *vorbistag = NULL;
|
||||
gchar *vorbisvalue = NULL;
|
||||
|
@ -522,7 +532,7 @@ gst_vorbisenc_metadata_set1 (const GstTagList *list, const gchar *tag, gpointer
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_set_metadata (VorbisEnc *vorbisenc)
|
||||
gst_vorbisenc_set_metadata (VorbisEnc * vorbisenc)
|
||||
{
|
||||
GstTagList *copy;
|
||||
const GstTagList *user_tags;
|
||||
|
@ -531,21 +541,23 @@ gst_vorbisenc_set_metadata (VorbisEnc *vorbisenc)
|
|||
if (!(vorbisenc->tags || user_tags))
|
||||
return;
|
||||
|
||||
copy = gst_tag_list_merge (user_tags, vorbisenc->tags, gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
|
||||
copy =
|
||||
gst_tag_list_merge (user_tags, vorbisenc->tags,
|
||||
gst_tag_setter_get_merge_mode (GST_TAG_SETTER (vorbisenc)));
|
||||
vorbis_comment_init (&vorbisenc->vc);
|
||||
gst_tag_list_foreach (copy, gst_vorbisenc_metadata_set1, vorbisenc);
|
||||
gst_tag_list_free (copy);
|
||||
}
|
||||
|
||||
static gchar*
|
||||
get_constraints_string (VorbisEnc *vorbisenc)
|
||||
static gchar *
|
||||
get_constraints_string (VorbisEnc * vorbisenc)
|
||||
{
|
||||
gint min = vorbisenc->min_bitrate;
|
||||
gint max = vorbisenc->max_bitrate;
|
||||
gchar *result;
|
||||
|
||||
if (min > 0 && max > 0)
|
||||
result = g_strdup_printf ("(min %d bps, max %d bps)", min,max);
|
||||
result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
|
||||
else if (min > 0)
|
||||
result = g_strdup_printf ("(min %d bps, no max)", min);
|
||||
else if (max > 0)
|
||||
|
@ -557,7 +569,7 @@ get_constraints_string (VorbisEnc *vorbisenc)
|
|||
}
|
||||
|
||||
static void
|
||||
update_start_message (VorbisEnc *vorbisenc)
|
||||
update_start_message (VorbisEnc * vorbisenc)
|
||||
{
|
||||
gchar *constraints;
|
||||
|
||||
|
@ -570,33 +582,30 @@ update_start_message (VorbisEnc *vorbisenc)
|
|||
g_strdup_printf ("encoding at average bitrate %d bps %s",
|
||||
vorbisenc->bitrate, constraints);
|
||||
g_free (constraints);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
vorbisenc->last_message =
|
||||
g_strdup_printf ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
|
||||
g_strdup_printf
|
||||
("encoding at approximate bitrate %d bps (VBR encoding enabled)",
|
||||
vorbisenc->bitrate);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (vorbisenc->quality_set) {
|
||||
if (vorbisenc->managed) {
|
||||
constraints = get_constraints_string (vorbisenc);
|
||||
vorbisenc->last_message =
|
||||
g_strdup_printf ("encoding at quality level %2.2f using constrained VBR %s",
|
||||
g_strdup_printf
|
||||
("encoding at quality level %2.2f using constrained VBR %s",
|
||||
vorbisenc->quality, constraints);
|
||||
g_free (constraints);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
vorbisenc->last_message =
|
||||
g_strdup_printf ("encoding at quality level %2.2f",
|
||||
vorbisenc->quality);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
constraints = get_constraints_string (vorbisenc);
|
||||
vorbisenc->last_message =
|
||||
g_strdup_printf ("encoding using bitrate management %s",
|
||||
constraints);
|
||||
g_strdup_printf ("encoding using bitrate management %s", constraints);
|
||||
g_free (constraints);
|
||||
}
|
||||
}
|
||||
|
@ -605,11 +614,12 @@ update_start_message (VorbisEnc *vorbisenc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_vorbisenc_setup (VorbisEnc *vorbisenc)
|
||||
gst_vorbisenc_setup (VorbisEnc * vorbisenc)
|
||||
{
|
||||
gint serial;
|
||||
|
||||
if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0 && vorbisenc->max_bitrate < 0) {
|
||||
if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
|
||||
&& vorbisenc->max_bitrate < 0) {
|
||||
vorbisenc->quality_set = TRUE;
|
||||
}
|
||||
|
||||
|
@ -619,20 +629,19 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
|
|||
/* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
|
||||
vorbis_info_init (&vorbisenc->vi);
|
||||
|
||||
if(vorbisenc->quality_set){
|
||||
if (vorbisenc->quality_set) {
|
||||
if (vorbis_encode_setup_vbr (&vorbisenc->vi,
|
||||
vorbisenc->channels,
|
||||
vorbisenc->frequency,
|
||||
vorbisenc->quality))
|
||||
{
|
||||
g_warning ("vorbisenc: initialisation failed: invalid parameters for quality");
|
||||
vorbis_info_clear(&vorbisenc->vi);
|
||||
vorbisenc->channels, vorbisenc->frequency, vorbisenc->quality)) {
|
||||
g_warning
|
||||
("vorbisenc: initialisation failed: invalid parameters for quality");
|
||||
vorbis_info_clear (&vorbisenc->vi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* do we have optional hard quality restrictions? */
|
||||
if(vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0){
|
||||
if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
|
||||
struct ovectl_ratemanage_arg ai;
|
||||
|
||||
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
|
||||
|
||||
/* the bitrates are in kHz */
|
||||
|
@ -642,29 +651,27 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
|
|||
|
||||
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (vorbis_encode_setup_managed (&vorbisenc->vi,
|
||||
vorbisenc->channels,
|
||||
vorbisenc->frequency,
|
||||
vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1,
|
||||
vorbisenc->bitrate,
|
||||
vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1))
|
||||
{
|
||||
g_warning("vorbisenc: initialisation failed: invalid parameters for bitrate\n");
|
||||
vorbis_info_clear(&vorbisenc->vi);
|
||||
vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1)) {
|
||||
g_warning
|
||||
("vorbisenc: initialisation failed: invalid parameters for bitrate\n");
|
||||
vorbis_info_clear (&vorbisenc->vi);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(vorbisenc->managed && vorbisenc->bitrate < 0) {
|
||||
vorbis_encode_ctl(&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
|
||||
}
|
||||
else if(!vorbisenc->managed) {
|
||||
if (vorbisenc->managed && vorbisenc->bitrate < 0) {
|
||||
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
|
||||
} else if (!vorbisenc->managed) {
|
||||
/* Turn off management entirely (if it was turned on). */
|
||||
vorbis_encode_ctl(&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
|
||||
vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
|
||||
}
|
||||
vorbis_encode_setup_init(&vorbisenc->vi);
|
||||
vorbis_encode_setup_init (&vorbisenc->vi);
|
||||
|
||||
/* set up the analysis state and auxiliary encoding storage */
|
||||
vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
|
||||
|
@ -676,8 +683,7 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
|
|||
if (vorbisenc->serial < 0) {
|
||||
srand (time (NULL));
|
||||
serial = rand ();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
serial = vorbisenc->serial;
|
||||
}
|
||||
|
||||
|
@ -689,34 +695,29 @@ gst_vorbisenc_setup (VorbisEnc *vorbisenc)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_write_page (VorbisEnc *vorbisenc, ogg_page *page)
|
||||
gst_vorbisenc_write_page (VorbisEnc * vorbisenc, ogg_page * page)
|
||||
{
|
||||
GstBuffer *outbuf;
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (page->header_len +
|
||||
page->body_len);
|
||||
outbuf = gst_buffer_new_and_alloc (page->header_len + page->body_len);
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), page->header,
|
||||
page->header_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), page->header, 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_BUFFER_SIZE (outbuf));
|
||||
GST_DEBUG ("vorbisenc: encoded buffer of %d bytes", GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
vorbisenc->bytes_out += GST_BUFFER_SIZE (outbuf);
|
||||
|
||||
if (GST_PAD_IS_USABLE (vorbisenc->srcpad)) {
|
||||
gst_pad_push (vorbisenc->srcpad, GST_DATA (outbuf));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gst_buffer_unref (outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
||||
gst_vorbisenc_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
VorbisEnc *vorbisenc;
|
||||
|
@ -752,8 +753,7 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
|||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gint16 *data;
|
||||
gulong size;
|
||||
gulong i, j;
|
||||
|
@ -761,12 +761,14 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
|||
|
||||
if (!vorbisenc->setup) {
|
||||
gst_buffer_unref (buf);
|
||||
GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL), ("encoder not initialized (input is not audio?)"));
|
||||
GST_ELEMENT_ERROR (vorbisenc, CORE, NEGOTIATION, (NULL),
|
||||
("encoder not initialized (input is not audio?)"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vorbisenc->header_sent) {
|
||||
gint result;
|
||||
|
||||
/* Vorbis streams begin with three headers; the initial header (with
|
||||
most of the codec setup parameters) which is mandated by the Ogg
|
||||
bitstream spec. The second header holds any comment fields. The
|
||||
|
@ -778,12 +780,13 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
|||
ogg_packet header_code;
|
||||
|
||||
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,
|
||||
&header_comm, &header_code);
|
||||
ogg_stream_packetin (&vorbisenc->os, &header); /* automatically placed in its own page */
|
||||
ogg_stream_packetin (&vorbisenc->os, &header_comm);
|
||||
ogg_stream_packetin (&vorbisenc->os, &header_code);
|
||||
|
||||
while ((result = ogg_stream_flush(&vorbisenc->os, &vorbisenc->og))) {
|
||||
while ((result = ogg_stream_flush (&vorbisenc->os, &vorbisenc->og))) {
|
||||
gst_vorbisenc_write_page (vorbisenc, &vorbisenc->og);
|
||||
}
|
||||
vorbisenc->header_sent = TRUE;
|
||||
|
@ -818,7 +821,7 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
|||
|
||||
/* analysis */
|
||||
vorbis_analysis (&vorbisenc->vb, NULL);
|
||||
vorbis_bitrate_addblock(&vorbisenc->vb);
|
||||
vorbis_bitrate_addblock (&vorbisenc->vb);
|
||||
|
||||
while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &vorbisenc->op)) {
|
||||
|
||||
|
@ -855,7 +858,8 @@ gst_vorbisenc_chain (GstPad * pad, GstData *_data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
VorbisEnc *vorbisenc;
|
||||
|
||||
|
@ -893,8 +897,8 @@ gst_vorbisenc_get_property (GObject * object, guint prop_id, GValue * value, GPa
|
|||
}
|
||||
|
||||
static void
|
||||
gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
gst_vorbisenc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
VorbisEnc *vorbisenc;
|
||||
|
||||
|
@ -955,7 +959,7 @@ gst_vorbisenc_set_property (GObject * object, guint prop_id, const GValue * valu
|
|||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_vorbisenc_change_state (GstElement *element)
|
||||
gst_vorbisenc_change_state (GstElement * element)
|
||||
{
|
||||
VorbisEnc *vorbisenc = GST_VORBISENC (element);
|
||||
|
||||
|
@ -983,4 +987,3 @@ gst_vorbisenc_change_state (GstElement *element)
|
|||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#include <vorbis/codec.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define GST_TYPE_VORBISENC \
|
||||
|
@ -41,14 +42,14 @@ extern "C" {
|
|||
#define GST_IS_VORBISENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VORBISENC))
|
||||
|
||||
typedef struct _VorbisEnc VorbisEnc;
|
||||
typedef struct _VorbisEncClass VorbisEncClass;
|
||||
typedef struct _VorbisEnc VorbisEnc;
|
||||
typedef struct _VorbisEncClass VorbisEncClass;
|
||||
|
||||
struct _VorbisEnc {
|
||||
struct _VorbisEnc
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad,
|
||||
*srcpad;
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
ogg_stream_state os; /* take physical pages, weld into a logical
|
||||
stream of packets */
|
||||
|
@ -78,18 +79,19 @@ struct _VorbisEnc {
|
|||
guint64 samples_in;
|
||||
guint64 bytes_out;
|
||||
|
||||
GstTagList * tags;
|
||||
GstTagList *tags;
|
||||
|
||||
gboolean setup;
|
||||
gboolean header_sent;
|
||||
gchar *last_message;
|
||||
};
|
||||
};
|
||||
|
||||
struct _VorbisEncClass {
|
||||
struct _VorbisEncClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
};
|
||||
|
||||
GType vorbisenc_get_type(void);
|
||||
GType vorbisenc_get_type (void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <gst/gststructure.h>
|
||||
|
||||
int
|
||||
gst_audio_frame_byte_size (GstPad* pad)
|
||||
gst_audio_frame_byte_size (GstPad * pad)
|
||||
{
|
||||
/* calculate byte size of an audio frame
|
||||
* this should be moved closer to the gstreamer core
|
||||
|
@ -58,7 +58,7 @@ gst_audio_frame_byte_size (GstPad* pad)
|
|||
}
|
||||
|
||||
long
|
||||
gst_audio_frame_length (GstPad* pad, GstBuffer* buf)
|
||||
gst_audio_frame_length (GstPad * pad, GstBuffer * buf)
|
||||
/* calculate length of buffer in frames
|
||||
* this should be moved closer to the gstreamer core
|
||||
* and be implemented for every mime type IMO
|
||||
|
@ -78,7 +78,7 @@ gst_audio_frame_length (GstPad* pad, GstBuffer* buf)
|
|||
}
|
||||
|
||||
long
|
||||
gst_audio_frame_rate (GstPad *pad)
|
||||
gst_audio_frame_rate (GstPad * pad)
|
||||
/*
|
||||
* calculate frame rate (based on caps of pad)
|
||||
* returns 0 if failed, rate if success
|
||||
|
@ -96,8 +96,7 @@ gst_audio_frame_rate (GstPad *pad)
|
|||
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
|
||||
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_get_int (structure, "rate", &rate);
|
||||
return rate;
|
||||
|
@ -105,7 +104,7 @@ gst_audio_frame_rate (GstPad *pad)
|
|||
}
|
||||
|
||||
double
|
||||
gst_audio_length (GstPad* pad, GstBuffer* buf)
|
||||
gst_audio_length (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
/* calculate length in seconds
|
||||
* of audio buffer buf
|
||||
|
@ -125,15 +124,12 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
|
|||
g_assert (GST_IS_BUFFER (buf));
|
||||
/* get caps of pad */
|
||||
caps = GST_PAD_CAPS (pad);
|
||||
if (caps == NULL)
|
||||
{
|
||||
if (caps == NULL) {
|
||||
/* ERROR: could not get caps of pad */
|
||||
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
|
||||
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
|
||||
length = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
bytes = GST_BUFFER_SIZE (buf);
|
||||
gst_structure_get_int (structure, "width", &width);
|
||||
|
@ -151,7 +147,7 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
|
|||
}
|
||||
|
||||
long
|
||||
gst_audio_highest_sample_value (GstPad* pad)
|
||||
gst_audio_highest_sample_value (GstPad * pad)
|
||||
/* calculate highest possible sample value
|
||||
* based on capabilities of pad
|
||||
*/
|
||||
|
@ -162,8 +158,7 @@ gst_audio_highest_sample_value (GstPad* pad)
|
|||
GstStructure *structure;
|
||||
|
||||
caps = GST_PAD_CAPS (pad);
|
||||
if (caps == NULL)
|
||||
{
|
||||
if (caps == NULL) {
|
||||
g_warning ("gstaudio: could not get caps of pad %s:%s\n",
|
||||
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
|
||||
}
|
||||
|
@ -172,13 +167,14 @@ gst_audio_highest_sample_value (GstPad* pad)
|
|||
gst_structure_get_int (structure, "width", &width);
|
||||
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 */
|
||||
return ((long) (1 << width));
|
||||
}
|
||||
|
||||
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 */
|
||||
{
|
||||
if (GST_BUFFER_SIZE (buf) % gst_audio_frame_byte_size (pad) == 0)
|
||||
|
@ -199,8 +195,8 @@ gst_audio_is_buffer_framed (GstPad* pad, GstBuffer* buf)
|
|||
* number of list values, and each of the values, terminating with NULL
|
||||
*/
|
||||
static void
|
||||
_gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
|
||||
GType type, int number, ...)
|
||||
_gst_audio_structure_set_list (GstStructure * structure,
|
||||
const gchar * fieldname, GType type, int number, ...)
|
||||
{
|
||||
va_list varargs;
|
||||
GValue value = { 0 };
|
||||
|
@ -214,17 +210,16 @@ _gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
|
|||
|
||||
va_start (varargs, number);
|
||||
|
||||
for (j = 0; j < number; ++j)
|
||||
{
|
||||
for (j = 0; j < number; ++j) {
|
||||
int i;
|
||||
gboolean b;
|
||||
|
||||
GValue list_value = { 0 };
|
||||
|
||||
switch (type)
|
||||
{
|
||||
switch (type) {
|
||||
case G_TYPE_INT:
|
||||
i = va_arg (varargs, int);
|
||||
|
||||
g_value_init (&list_value, G_TYPE_INT);
|
||||
g_value_set_int (&list_value, i);
|
||||
break;
|
||||
|
@ -234,7 +229,8 @@ _gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
|
|||
g_value_set_boolean (&list_value, b);
|
||||
break;
|
||||
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);
|
||||
|
||||
|
@ -244,38 +240,38 @@ _gst_audio_structure_set_list (GstStructure *structure, const gchar *fieldname,
|
|||
}
|
||||
|
||||
void
|
||||
gst_audio_structure_set_int (GstStructure *structure, GstAudioFieldFlag flag)
|
||||
gst_audio_structure_set_int (GstStructure * structure, GstAudioFieldFlag flag)
|
||||
{
|
||||
if (flag & GST_AUDIO_FIELD_RATE)
|
||||
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
|
||||
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
NULL);
|
||||
if (flag & GST_AUDIO_FIELD_CHANNELS)
|
||||
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
|
||||
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
NULL);
|
||||
if (flag & GST_AUDIO_FIELD_ENDIANNESS)
|
||||
_gst_audio_structure_set_list (structure, "endianness", G_TYPE_INT, 2, G_LITTLE_ENDIAN, G_BIG_ENDIAN, NULL);
|
||||
_gst_audio_structure_set_list (structure, "endianness", G_TYPE_INT, 2,
|
||||
G_LITTLE_ENDIAN, G_BIG_ENDIAN, NULL);
|
||||
if (flag & GST_AUDIO_FIELD_WIDTH)
|
||||
_gst_audio_structure_set_list (structure, "width", G_TYPE_INT, 3, 8, 16, 32, NULL);
|
||||
_gst_audio_structure_set_list (structure, "width", G_TYPE_INT, 3, 8, 16, 32,
|
||||
NULL);
|
||||
if (flag & GST_AUDIO_FIELD_DEPTH)
|
||||
gst_structure_set (structure, "depth", GST_TYPE_INT_RANGE, 1, 32, NULL);
|
||||
if (flag & GST_AUDIO_FIELD_SIGNED)
|
||||
_gst_audio_structure_set_list (structure, "signed", G_TYPE_BOOLEAN, 2, TRUE, FALSE, NULL);
|
||||
_gst_audio_structure_set_list (structure, "signed", G_TYPE_BOOLEAN, 2, TRUE,
|
||||
FALSE, NULL);
|
||||
if (flag & GST_AUDIO_FIELD_BUFFER_FRAMES)
|
||||
gst_structure_set (structure, "buffer-frames", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
|
||||
gst_structure_set (structure, "buffer-frames", GST_TYPE_INT_RANGE, 1,
|
||||
G_MAXINT, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gstaudio",
|
||||
"Support services for audio plugins",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
GST_LICENSE,
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
);
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define __GST_AUDIO_AUDIO_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For people that are looking at this source: the purpose of these defines is
|
||||
* to make GstCaps a bit easier, in that you don't have to know all of the
|
||||
* properties that need to be defined. you can just use these macros. currently
|
||||
|
@ -50,9 +49,7 @@ G_BEGIN_DECLS
|
|||
*
|
||||
* Andy Wingo, 18 August 2001
|
||||
* Thomas, 6 September 2002 */
|
||||
|
||||
#define GST_AUDIO_DEF_RATE 44100
|
||||
|
||||
#define GST_AUDIO_INT_PAD_TEMPLATE_CAPS \
|
||||
"audio/x-raw-int, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
|
@ -61,8 +58,6 @@ G_BEGIN_DECLS
|
|||
"width = (int) { 8, 16, 32 }, " \
|
||||
"depth = (int) [ 1, 32 ], " \
|
||||
"signed = (boolean) { true, false }"
|
||||
|
||||
|
||||
/* "standard" int audio is native order, 16 bit stereo. */
|
||||
#define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS \
|
||||
"audio/x-raw-int, " \
|
||||
|
@ -72,7 +67,6 @@ G_BEGIN_DECLS
|
|||
"width = (int) 16, " \
|
||||
"depth = (int) 16, " \
|
||||
"signed = (boolean) true"
|
||||
|
||||
#define GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS \
|
||||
"audio/x-raw-float, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
|
@ -80,7 +74,6 @@ G_BEGIN_DECLS
|
|||
"endianness = (int) { LITTLE_ENDIAN , BIG_ENDIAN }, " \
|
||||
"width = (int) { 32, 64 }, " \
|
||||
"buffer-frames = (int) [ 1, MAX]"
|
||||
|
||||
/* "standard" float audio is native order, 32 bit mono. */
|
||||
#define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS \
|
||||
"audio/x-raw-float, " \
|
||||
|
@ -88,32 +81,31 @@ G_BEGIN_DECLS
|
|||
"channels = (int) 1, " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"buffer-frames = (int) [ 1, MAX]"
|
||||
|
||||
/*
|
||||
* this library defines and implements some helper functions for audio
|
||||
* handling
|
||||
*/
|
||||
|
||||
/* get byte size of audio frame (based on caps of pad */
|
||||
int gst_audio_frame_byte_size (GstPad* pad);
|
||||
int gst_audio_frame_byte_size (GstPad * pad);
|
||||
|
||||
/* get length in frames of buffer */
|
||||
long gst_audio_frame_length (GstPad* pad, GstBuffer* buf);
|
||||
long gst_audio_frame_length (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
/* get frame rate based on caps */
|
||||
long gst_audio_frame_rate (GstPad *pad);
|
||||
long gst_audio_frame_rate (GstPad * pad);
|
||||
|
||||
/* calculate length in seconds of audio buffer buf based on caps of pad */
|
||||
double gst_audio_length (GstPad* pad, GstBuffer* buf);
|
||||
double gst_audio_length (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
/* calculate highest possible sample value based on capabilities of pad */
|
||||
long gst_audio_highest_sample_value (GstPad* pad);
|
||||
long gst_audio_highest_sample_value (GstPad * pad);
|
||||
|
||||
/* check if the buffer size is a whole multiple of the frame size */
|
||||
gboolean gst_audio_is_buffer_framed (GstPad* pad, GstBuffer* buf);
|
||||
gboolean gst_audio_is_buffer_framed (GstPad * pad, GstBuffer * buf);
|
||||
|
||||
/* functions useful for _getcaps functions */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_AUDIO_FIELD_RATE = (1 << 0),
|
||||
GST_AUDIO_FIELD_CHANNELS = (1 << 1),
|
||||
GST_AUDIO_FIELD_ENDIANNESS = (1 << 2),
|
||||
|
@ -123,8 +115,8 @@ typedef enum {
|
|||
GST_AUDIO_FIELD_BUFFER_FRAMES = (1 << 6)
|
||||
} GstAudioFieldFlag;
|
||||
|
||||
void gst_audio_structure_set_int (GstStructure *structure, GstAudioFieldFlag flag);
|
||||
void gst_audio_structure_set_int (GstStructure * structure,
|
||||
GstAudioFieldFlag flag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_AUDIO_AUDIO_H__ */
|
||||
|
|
|
@ -26,16 +26,17 @@
|
|||
|
||||
#include "audioclock.h"
|
||||
|
||||
static void gst_audio_clock_class_init (GstAudioClockClass *klass);
|
||||
static void gst_audio_clock_init (GstAudioClock *clock);
|
||||
static void gst_audio_clock_class_init (GstAudioClockClass * klass);
|
||||
static void gst_audio_clock_init (GstAudioClock * clock);
|
||||
|
||||
static GstClockTime gst_audio_clock_get_internal_time (GstClock *clock);
|
||||
static GstClockReturn gst_audio_clock_id_wait_async (GstClock *clock,
|
||||
GstClockEntry *entry);
|
||||
static void gst_audio_clock_id_unschedule (GstClock *clock,
|
||||
GstClockEntry *entry);
|
||||
static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock);
|
||||
static GstClockReturn gst_audio_clock_id_wait_async (GstClock * clock,
|
||||
GstClockEntry * entry);
|
||||
static void gst_audio_clock_id_unschedule (GstClock * clock,
|
||||
GstClockEntry * entry);
|
||||
|
||||
static GstSystemClockClass *parent_class = NULL;
|
||||
|
||||
/* static guint gst_audio_clock_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
GType
|
||||
|
@ -64,15 +65,15 @@ gst_audio_clock_get_type (void)
|
|||
|
||||
|
||||
static void
|
||||
gst_audio_clock_class_init (GstAudioClockClass *klass)
|
||||
gst_audio_clock_class_init (GstAudioClockClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstObjectClass *gstobject_class;
|
||||
GstClockClass *gstclock_class;
|
||||
|
||||
gobject_class = (GObjectClass*) klass;
|
||||
gstobject_class = (GstObjectClass*) klass;
|
||||
gstclock_class = (GstClockClass*) klass;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstobject_class = (GstObjectClass *) klass;
|
||||
gstclock_class = (GstClockClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_SYSTEM_CLOCK);
|
||||
|
||||
|
@ -82,7 +83,7 @@ gst_audio_clock_class_init (GstAudioClockClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_audio_clock_init (GstAudioClock *clock)
|
||||
gst_audio_clock_init (GstAudioClock * clock)
|
||||
{
|
||||
gst_object_set_name (GST_OBJECT (clock), "GstAudioClock");
|
||||
|
||||
|
@ -90,20 +91,22 @@ gst_audio_clock_init (GstAudioClock *clock)
|
|||
clock->prev2 = 0;
|
||||
}
|
||||
|
||||
GstClock*
|
||||
gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func, gpointer user_data)
|
||||
GstClock *
|
||||
gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstAudioClock *aclock = GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, NULL));
|
||||
GstAudioClock *aclock =
|
||||
GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, NULL));
|
||||
|
||||
aclock->func = func;
|
||||
aclock->user_data = user_data;
|
||||
aclock->adjust = 0;
|
||||
|
||||
return (GstClock*)aclock;
|
||||
return (GstClock *) aclock;
|
||||
}
|
||||
|
||||
void
|
||||
gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
|
||||
gst_audio_clock_set_active (GstAudioClock * aclock, gboolean active)
|
||||
{
|
||||
GstClockTime time;
|
||||
GstClock *clock;
|
||||
|
@ -117,6 +120,7 @@ gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
|
|||
aclock->adjust = time - aclock->func (clock, aclock->user_data);
|
||||
} else {
|
||||
GTimeVal timeval;
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
|
||||
aclock->adjust = GST_TIMEVAL_TO_TIME (timeval) - time;
|
||||
|
@ -126,7 +130,7 @@ gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active)
|
|||
}
|
||||
|
||||
static GstClockTime
|
||||
gst_audio_clock_get_internal_time (GstClock *clock)
|
||||
gst_audio_clock_get_internal_time (GstClock * clock)
|
||||
{
|
||||
GstAudioClock *aclock = GST_AUDIO_CLOCK (clock);
|
||||
|
||||
|
@ -141,7 +145,7 @@ gst_audio_clock_get_internal_time (GstClock *clock)
|
|||
}
|
||||
|
||||
void
|
||||
gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time)
|
||||
gst_audio_clock_update_time (GstAudioClock * aclock, GstClockTime time)
|
||||
{
|
||||
/* I don't know of a purpose in updating these; perhaps they can be removed */
|
||||
aclock->prev2 = aclock->prev1;
|
||||
|
@ -150,12 +154,12 @@ gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time)
|
|||
/* FIXME: the wait_async subsystem should be made threadsafe, but I don't want
|
||||
* to lock and unlock a mutex on every iteration... */
|
||||
while (aclock->async_entries) {
|
||||
GstClockEntry *entry = (GstClockEntry*)aclock->async_entries->data;
|
||||
GstClockEntry *entry = (GstClockEntry *) aclock->async_entries->data;
|
||||
|
||||
if (entry->time > time)
|
||||
break;
|
||||
|
||||
entry->func ((GstClock*)aclock, time, entry, entry->user_data);
|
||||
entry->func ((GstClock *) aclock, time, entry, entry->user_data);
|
||||
|
||||
aclock->async_entries = g_slist_delete_link (aclock->async_entries,
|
||||
aclock->async_entries);
|
||||
|
@ -164,29 +168,27 @@ gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time)
|
|||
}
|
||||
|
||||
static gint
|
||||
compare_clock_entries (GstClockEntry *entry1, GstClockEntry *entry2)
|
||||
compare_clock_entries (GstClockEntry * entry1, GstClockEntry * entry2)
|
||||
{
|
||||
return entry1->time - entry2->time;
|
||||
}
|
||||
|
||||
static GstClockReturn
|
||||
gst_audio_clock_id_wait_async (GstClock *clock, GstClockEntry *entry)
|
||||
gst_audio_clock_id_wait_async (GstClock * clock, GstClockEntry * entry)
|
||||
{
|
||||
GstAudioClock *aclock = (GstAudioClock*)clock;
|
||||
GstAudioClock *aclock = (GstAudioClock *) clock;
|
||||
|
||||
aclock->async_entries = g_slist_insert_sorted (aclock->async_entries,
|
||||
entry,
|
||||
(GCompareFunc)compare_clock_entries);
|
||||
entry, (GCompareFunc) compare_clock_entries);
|
||||
|
||||
/* is this the proper return val? */
|
||||
return GST_CLOCK_EARLY;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audio_clock_id_unschedule (GstClock *clock, GstClockEntry *entry)
|
||||
gst_audio_clock_id_unschedule (GstClock * clock, GstClockEntry * entry)
|
||||
{
|
||||
GstAudioClock *aclock = (GstAudioClock*)clock;
|
||||
GstAudioClock *aclock = (GstAudioClock *) clock;
|
||||
|
||||
aclock->async_entries = g_slist_remove (aclock->async_entries,
|
||||
entry);
|
||||
aclock->async_entries = g_slist_remove (aclock->async_entries, entry);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <gst/gstsystemclock.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_AUDIO_CLOCK \
|
||||
(gst_audio_clock_get_type())
|
||||
#define GST_AUDIO_CLOCK(obj) \
|
||||
|
@ -38,14 +37,15 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_CLOCK))
|
||||
#define GST_IS_AUDIO_CLOCK_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_CLOCK))
|
||||
|
||||
typedef struct _GstAudioClock GstAudioClock;
|
||||
typedef struct _GstAudioClockClass GstAudioClockClass;
|
||||
|
||||
typedef GstClockTime (*GstAudioClockGetTimeFunc) (GstClock *clock, gpointer user_data);
|
||||
typedef GstClockTime (*GstAudioClockGetTimeFunc) (GstClock * clock,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
struct _GstAudioClock {
|
||||
struct _GstAudioClock
|
||||
{
|
||||
GstSystemClock clock;
|
||||
|
||||
GstClockTime prev1, prev2;
|
||||
|
@ -63,19 +63,19 @@ struct _GstAudioClock {
|
|||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstAudioClockClass {
|
||||
struct _GstAudioClockClass
|
||||
{
|
||||
GstSystemClockClass parent_class;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_audio_clock_get_type (void);
|
||||
GstClock* gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func,
|
||||
GstClock *gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func,
|
||||
gpointer user_data);
|
||||
void gst_audio_clock_set_active (GstAudioClock *aclock, gboolean active);
|
||||
void gst_audio_clock_set_active (GstAudioClock * aclock, gboolean active);
|
||||
|
||||
void gst_audio_clock_update_time (GstAudioClock *aclock, GstClockTime time);
|
||||
void gst_audio_clock_update_time (GstAudioClock * aclock, GstClockTime time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_AUDIO_CLOCK_H__ */
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
|
||||
/* GstAudiofilter signals and args */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_METHOD,
|
||||
/* FILL ME */
|
||||
|
@ -42,13 +44,15 @@ enum {
|
|||
|
||||
static void gst_audiofilter_base_init (gpointer g_class);
|
||||
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_audiofilter_init (GTypeInstance *instance, gpointer g_class);
|
||||
static void gst_audiofilter_init (GTypeInstance * instance, gpointer g_class);
|
||||
|
||||
static void gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
static void gst_audiofilter_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_audiofilter_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_audiofilter_chain (GstPad *pad, GstData *_data);
|
||||
GstCaps * gst_audiofilter_class_get_capslist(GstAudiofilterClass *klass);
|
||||
static void gst_audiofilter_chain (GstPad * pad, GstData * _data);
|
||||
GstCaps *gst_audiofilter_class_get_capslist (GstAudiofilterClass * klass);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
|
@ -59,23 +63,24 @@ gst_audiofilter_get_type (void)
|
|||
|
||||
if (!audiofilter_type) {
|
||||
static const GTypeInfo audiofilter_info = {
|
||||
sizeof(GstAudiofilterClass),
|
||||
sizeof (GstAudiofilterClass),
|
||||
gst_audiofilter_base_init,
|
||||
NULL,
|
||||
gst_audiofilter_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(GstAudiofilter),
|
||||
sizeof (GstAudiofilter),
|
||||
0,
|
||||
gst_audiofilter_init,
|
||||
};
|
||||
audiofilter_type = g_type_register_static(GST_TYPE_ELEMENT,
|
||||
audiofilter_type = g_type_register_static (GST_TYPE_ELEMENT,
|
||||
"GstAudiofilter", &audiofilter_info, G_TYPE_FLAG_ABSTRACT);
|
||||
}
|
||||
return audiofilter_type;
|
||||
}
|
||||
|
||||
static void gst_audiofilter_base_init (gpointer g_class)
|
||||
static void
|
||||
gst_audiofilter_base_init (gpointer g_class)
|
||||
{
|
||||
static GstElementDetails audiofilter_details = {
|
||||
"Audio filter base class",
|
||||
|
@ -89,24 +94,25 @@ static void gst_audiofilter_base_init (gpointer g_class)
|
|||
gst_element_class_set_details (element_class, &audiofilter_details);
|
||||
}
|
||||
|
||||
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
|
||||
static void
|
||||
gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstAudiofilterClass *klass;
|
||||
|
||||
klass = (GstAudiofilterClass *)g_class;
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
klass = (GstAudiofilterClass *) g_class;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_audiofilter_set_property;
|
||||
gobject_class->get_property = gst_audiofilter_get_property;
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
|
||||
gst_audiofilter_link (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
GstAudiofilter *audiofilter;
|
||||
GstPadLinkReturn ret;
|
||||
|
@ -114,10 +120,9 @@ gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
|
|||
GstStructure *structure;
|
||||
GstAudiofilterClass *audiofilter_class;
|
||||
|
||||
GST_DEBUG("gst_audiofilter_link");
|
||||
GST_DEBUG ("gst_audiofilter_link");
|
||||
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
|
||||
audiofilter_class = GST_AUDIOFILTER_CLASS (
|
||||
G_OBJECT_GET_CLASS (audiofilter));
|
||||
audiofilter_class = GST_AUDIOFILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
|
||||
|
||||
|
||||
if (pad == audiofilter->srcpad) {
|
||||
|
@ -135,53 +140,55 @@ gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
|
|||
if (strcmp (gst_structure_get_name (structure), "audio/x-raw-int") == 0) {
|
||||
ret = gst_structure_get_int (structure, "depth", &audiofilter->depth);
|
||||
ret &= gst_structure_get_int (structure, "width", &audiofilter->width);
|
||||
ret &= gst_structure_get_int (structure, "channels", &audiofilter->channels);
|
||||
ret &=
|
||||
gst_structure_get_int (structure, "channels", &audiofilter->channels);
|
||||
} else if (strcmp (gst_structure_get_name (structure), "audio/x-raw-float")
|
||||
== 0) {
|
||||
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
ret &= gst_structure_get_int (structure, "rate", &audiofilter->rate);
|
||||
|
||||
audiofilter->bytes_per_sample = (audiofilter->width/8) *
|
||||
audiofilter->bytes_per_sample = (audiofilter->width / 8) *
|
||||
audiofilter->channels;
|
||||
|
||||
if (audiofilter_class->setup) (audiofilter_class->setup) (audiofilter);
|
||||
if (audiofilter_class->setup)
|
||||
(audiofilter_class->setup) (audiofilter);
|
||||
|
||||
return GST_PAD_LINK_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_init (GTypeInstance *instance, gpointer g_class)
|
||||
gst_audiofilter_init (GTypeInstance * instance, gpointer g_class)
|
||||
{
|
||||
GstAudiofilter *audiofilter = GST_AUDIOFILTER (instance);
|
||||
GstPadTemplate *pad_template;
|
||||
|
||||
GST_DEBUG("gst_audiofilter_init");
|
||||
GST_DEBUG ("gst_audiofilter_init");
|
||||
|
||||
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
|
||||
"sink");
|
||||
g_return_if_fail(pad_template != NULL);
|
||||
audiofilter->sinkpad = gst_pad_new_from_template(pad_template, "sink");
|
||||
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->sinkpad);
|
||||
gst_pad_set_chain_function(audiofilter->sinkpad,gst_audiofilter_chain);
|
||||
gst_pad_set_link_function(audiofilter->sinkpad,gst_audiofilter_link);
|
||||
gst_pad_set_getcaps_function(audiofilter->sinkpad,gst_pad_proxy_getcaps);
|
||||
pad_template =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
|
||||
g_return_if_fail (pad_template != NULL);
|
||||
audiofilter->sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->sinkpad);
|
||||
gst_pad_set_chain_function (audiofilter->sinkpad, gst_audiofilter_chain);
|
||||
gst_pad_set_link_function (audiofilter->sinkpad, gst_audiofilter_link);
|
||||
gst_pad_set_getcaps_function (audiofilter->sinkpad, gst_pad_proxy_getcaps);
|
||||
|
||||
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
|
||||
"src");
|
||||
g_return_if_fail(pad_template != NULL);
|
||||
audiofilter->srcpad = gst_pad_new_from_template(pad_template, "src");
|
||||
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->srcpad);
|
||||
gst_pad_set_link_function(audiofilter->srcpad,gst_audiofilter_link);
|
||||
gst_pad_set_getcaps_function(audiofilter->srcpad,gst_pad_proxy_getcaps);
|
||||
pad_template =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
|
||||
g_return_if_fail (pad_template != NULL);
|
||||
audiofilter->srcpad = gst_pad_new_from_template (pad_template, "src");
|
||||
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->srcpad);
|
||||
gst_pad_set_link_function (audiofilter->srcpad, gst_audiofilter_link);
|
||||
gst_pad_set_getcaps_function (audiofilter->srcpad, gst_pad_proxy_getcaps);
|
||||
|
||||
audiofilter->inited = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_chain (GstPad *pad, GstData *data)
|
||||
gst_audiofilter_chain (GstPad * pad, GstData * data)
|
||||
{
|
||||
GstBuffer *inbuf = GST_BUFFER (data);
|
||||
GstAudiofilter *audiofilter;
|
||||
|
@ -196,60 +203,60 @@ gst_audiofilter_chain (GstPad *pad, GstData *data)
|
|||
|
||||
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
|
||||
//g_return_if_fail (audiofilter->inited);
|
||||
audiofilter_class = GST_AUDIOFILTER_CLASS (
|
||||
G_OBJECT_GET_CLASS (audiofilter));
|
||||
audiofilter_class = GST_AUDIOFILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
|
||||
|
||||
GST_DEBUG ("gst_audiofilter_chain: got buffer of %d bytes in '%s'",
|
||||
GST_BUFFER_SIZE(inbuf), GST_OBJECT_NAME (audiofilter));
|
||||
GST_BUFFER_SIZE (inbuf), GST_OBJECT_NAME (audiofilter));
|
||||
|
||||
if(audiofilter->passthru){
|
||||
gst_pad_push(audiofilter->srcpad, data);
|
||||
if (audiofilter->passthru) {
|
||||
gst_pad_push (audiofilter->srcpad, data);
|
||||
return;
|
||||
}
|
||||
|
||||
audiofilter->size = GST_BUFFER_SIZE (inbuf);
|
||||
audiofilter->n_samples = audiofilter->size / audiofilter->bytes_per_sample;
|
||||
|
||||
if (gst_data_is_writable(data)) {
|
||||
if (gst_data_is_writable (data)) {
|
||||
if (audiofilter_class->filter_inplace) {
|
||||
(audiofilter_class->filter_inplace) (audiofilter, inbuf);
|
||||
outbuf = inbuf;
|
||||
} else {
|
||||
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
|
||||
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
|
||||
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
|
||||
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
|
||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
|
||||
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
|
||||
gst_buffer_unref(inbuf);
|
||||
gst_buffer_unref (inbuf);
|
||||
}
|
||||
} else {
|
||||
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
|
||||
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
|
||||
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
|
||||
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (inbuf));
|
||||
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
if (audiofilter_class->filter) {
|
||||
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
|
||||
} else {
|
||||
memcpy(GST_BUFFER_DATA(outbuf), GST_BUFFER_DATA(inbuf),
|
||||
GST_BUFFER_SIZE(inbuf));
|
||||
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
|
||||
GST_BUFFER_SIZE (inbuf));
|
||||
|
||||
(audiofilter_class->filter_inplace) (audiofilter, outbuf);
|
||||
}
|
||||
gst_buffer_unref(inbuf);
|
||||
gst_buffer_unref (inbuf);
|
||||
}
|
||||
|
||||
gst_pad_push(audiofilter->srcpad, GST_DATA (outbuf));
|
||||
gst_pad_push (audiofilter->srcpad, GST_DATA (outbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
gst_audiofilter_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstAudiofilter *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_AUDIOFILTER(object));
|
||||
src = GST_AUDIOFILTER(object);
|
||||
g_return_if_fail (GST_IS_AUDIOFILTER (object));
|
||||
src = GST_AUDIOFILTER (object);
|
||||
|
||||
GST_DEBUG("gst_audiofilter_set_property");
|
||||
GST_DEBUG ("gst_audiofilter_set_property");
|
||||
switch (prop_id) {
|
||||
default:
|
||||
break;
|
||||
|
@ -257,13 +264,14 @@ gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *valu
|
|||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
gst_audiofilter_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstAudiofilter *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_AUDIOFILTER(object));
|
||||
src = GST_AUDIOFILTER(object);
|
||||
g_return_if_fail (GST_IS_AUDIOFILTER (object));
|
||||
src = GST_AUDIOFILTER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -272,37 +280,31 @@ gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GPa
|
|||
}
|
||||
}
|
||||
|
||||
void gst_audiofilter_class_add_pad_templates (
|
||||
GstAudiofilterClass *audiofilter_class, const GstCaps *caps)
|
||||
void
|
||||
gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *
|
||||
audiofilter_class, const GstCaps * caps)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (audiofilter_class);
|
||||
|
||||
audiofilter_class->caps = gst_caps_copy(caps);
|
||||
audiofilter_class->caps = gst_caps_copy (caps);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||
gst_caps_copy(caps)));
|
||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||
gst_caps_copy (caps)));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||
gst_caps_copy(caps)));
|
||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||
gst_caps_copy (caps)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gstaudiofilter",
|
||||
"Audio filter parent class",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"LGPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -25,17 +25,15 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstAudiofilter GstAudiofilter;
|
||||
G_BEGIN_DECLS typedef struct _GstAudiofilter GstAudiofilter;
|
||||
typedef struct _GstAudiofilterClass GstAudiofilterClass;
|
||||
|
||||
typedef void (*GstAudiofilterFilterFunc)(GstAudiofilter *filter,
|
||||
GstBuffer *outbuf, GstBuffer *inbuf);
|
||||
typedef void (*GstAudiofilterInplaceFilterFunc)(GstAudiofilter *filter,
|
||||
GstBuffer *buffer);
|
||||
typedef void (*GstAudiofilterFilterFunc) (GstAudiofilter * filter,
|
||||
GstBuffer * outbuf, GstBuffer * inbuf);
|
||||
typedef void (*GstAudiofilterInplaceFilterFunc) (GstAudiofilter * filter,
|
||||
GstBuffer * buffer);
|
||||
|
||||
typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter *filter);
|
||||
typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter * filter);
|
||||
|
||||
|
||||
#define GST_TYPE_AUDIOFILTER \
|
||||
|
@ -49,10 +47,11 @@ typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter *filter);
|
|||
#define GST_IS_AUDIOFILTER_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER))
|
||||
|
||||
struct _GstAudiofilter {
|
||||
struct _GstAudiofilter
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad,*srcpad;
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
/* audio state */
|
||||
gboolean inited;
|
||||
|
@ -68,7 +67,8 @@ struct _GstAudiofilter {
|
|||
int bytes_per_sample;
|
||||
};
|
||||
|
||||
struct _GstAudiofilterClass {
|
||||
struct _GstAudiofilterClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
|
||||
GstCaps *caps;
|
||||
|
@ -77,11 +77,10 @@ struct _GstAudiofilterClass {
|
|||
GstAudiofilterFilterFunc filter;
|
||||
};
|
||||
|
||||
GType gst_audiofilter_get_type(void);
|
||||
GType gst_audiofilter_get_type (void);
|
||||
|
||||
void gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *audiofilterclass, const GstCaps *caps);
|
||||
void gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *
|
||||
audiofilterclass, const GstCaps * caps);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_AUDIOFILTER_H__ */
|
||||
|
||||
|
|
|
@ -48,37 +48,47 @@ typedef struct _GstAudiofilterTemplateClass GstAudiofilterTemplateClass;
|
|||
#define GST_IS_AUDIOFILTER_TEMPLATE_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER_TEMPLATE))
|
||||
|
||||
struct _GstAudiofilterTemplate {
|
||||
struct _GstAudiofilterTemplate
|
||||
{
|
||||
GstAudiofilter audiofilter;
|
||||
|
||||
};
|
||||
|
||||
struct _GstAudiofilterTemplateClass {
|
||||
struct _GstAudiofilterTemplateClass
|
||||
{
|
||||
GstAudiofilterClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static void gst_audiofilter_template_base_init (gpointer g_class);
|
||||
static void gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data);
|
||||
static void gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class);
|
||||
static void gst_audiofilter_template_class_init (gpointer g_class,
|
||||
gpointer class_data);
|
||||
static void gst_audiofilter_template_init (GTypeInstance * instance,
|
||||
gpointer g_class);
|
||||
|
||||
static void gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
static void gst_audiofilter_template_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_audiofilter_template_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_audiofilter_template_setup (GstAudiofilter *audiofilter);
|
||||
static void gst_audiofilter_template_filter (GstAudiofilter *audiofilter, GstBuffer *outbuf, GstBuffer *inbuf);
|
||||
static void gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter, GstBuffer *buf);
|
||||
static void gst_audiofilter_template_setup (GstAudiofilter * audiofilter);
|
||||
static void gst_audiofilter_template_filter (GstAudiofilter * audiofilter,
|
||||
GstBuffer * outbuf, GstBuffer * inbuf);
|
||||
static void gst_audiofilter_template_filter_inplace (GstAudiofilter *
|
||||
audiofilter, GstBuffer * buf);
|
||||
|
||||
GType
|
||||
gst_audiofilter_template_get_type (void)
|
||||
|
@ -87,23 +97,24 @@ gst_audiofilter_template_get_type (void)
|
|||
|
||||
if (!audiofilter_template_type) {
|
||||
static const GTypeInfo audiofilter_template_info = {
|
||||
sizeof(GstAudiofilterTemplateClass),
|
||||
sizeof (GstAudiofilterTemplateClass),
|
||||
gst_audiofilter_template_base_init,
|
||||
NULL,
|
||||
gst_audiofilter_template_class_init,
|
||||
NULL,
|
||||
gst_audiofilter_template_init,
|
||||
sizeof(GstAudiofilterTemplate),
|
||||
sizeof (GstAudiofilterTemplate),
|
||||
0,
|
||||
NULL,
|
||||
};
|
||||
audiofilter_template_type = g_type_register_static(GST_TYPE_AUDIOFILTER,
|
||||
audiofilter_template_type = g_type_register_static (GST_TYPE_AUDIOFILTER,
|
||||
"GstAudiofilterTemplate", &audiofilter_template_info, 0);
|
||||
}
|
||||
return audiofilter_template_type;
|
||||
}
|
||||
|
||||
static void gst_audiofilter_template_base_init (gpointer g_class)
|
||||
static void
|
||||
gst_audiofilter_template_base_init (gpointer g_class)
|
||||
{
|
||||
static GstElementDetails audiofilter_template_details = {
|
||||
"Audio filter template",
|
||||
|
@ -128,14 +139,14 @@ gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data)
|
|||
GstAudiofilterTemplateClass *klass;
|
||||
GstAudiofilterClass *audiofilter_class;
|
||||
|
||||
klass = (GstAudiofilterTemplateClass *)g_class;
|
||||
gobject_class = (GObjectClass*)klass;
|
||||
gstelement_class = (GstElementClass*)klass;
|
||||
audiofilter_class = (GstAudiofilterClass *)g_class;
|
||||
klass = (GstAudiofilterTemplateClass *) g_class;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
audiofilter_class = (GstAudiofilterClass *) g_class;
|
||||
|
||||
#if 0
|
||||
g_object_class_install_property(gobject_class, ARG_METHOD,
|
||||
g_param_spec_enum("method","method","method",
|
||||
g_object_class_install_property (gobject_class, ARG_METHOD,
|
||||
g_param_spec_enum ("method", "method", "method",
|
||||
GST_TYPE_AUDIOTEMPLATE_METHOD, GST_AUDIOTEMPLATE_METHOD_1,
|
||||
G_PARAM_READWRITE));
|
||||
#endif
|
||||
|
@ -146,11 +157,11 @@ gst_audiofilter_template_class_init (gpointer g_class, gpointer class_data)
|
|||
audiofilter_class->setup = gst_audiofilter_template_setup;
|
||||
audiofilter_class->filter = gst_audiofilter_template_filter;
|
||||
audiofilter_class->filter_inplace = gst_audiofilter_template_filter_inplace;
|
||||
audiofilter_class->filter = NULL;
|
||||
audiofilter_class->filter = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class)
|
||||
gst_audiofilter_template_init (GTypeInstance * instance, gpointer g_class)
|
||||
{
|
||||
//GstAudiofilterTemplate *audiofilter_template = GST_AUDIOFILTER_TEMPLATE (instance);
|
||||
//GstAudiofilter *audiofilter = GST_AUDIOFILTER (instance);
|
||||
|
@ -162,15 +173,16 @@ gst_audiofilter_template_init (GTypeInstance *instance, gpointer g_class)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
gst_audiofilter_template_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstAudiofilterTemplate *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_AUDIOFILTER_TEMPLATE(object));
|
||||
src = GST_AUDIOFILTER_TEMPLATE(object);
|
||||
g_return_if_fail (GST_IS_AUDIOFILTER_TEMPLATE (object));
|
||||
src = GST_AUDIOFILTER_TEMPLATE (object);
|
||||
|
||||
GST_DEBUG("gst_audiofilter_template_set_property");
|
||||
GST_DEBUG ("gst_audiofilter_template_set_property");
|
||||
switch (prop_id) {
|
||||
default:
|
||||
break;
|
||||
|
@ -178,13 +190,14 @@ gst_audiofilter_template_set_property (GObject *object, guint prop_id, const GVa
|
|||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
gst_audiofilter_template_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstAudiofilterTemplate *src;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
g_return_if_fail(GST_IS_AUDIOFILTER_TEMPLATE(object));
|
||||
src = GST_AUDIOFILTER_TEMPLATE(object);
|
||||
g_return_if_fail (GST_IS_AUDIOFILTER_TEMPLATE (object));
|
||||
src = GST_AUDIOFILTER_TEMPLATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -194,7 +207,7 @@ gst_audiofilter_template_get_property (GObject *object, guint prop_id, GValue *v
|
|||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_library_load ("gstaudiofilter"))
|
||||
return FALSE;
|
||||
|
@ -203,20 +216,13 @@ plugin_init (GstPlugin *plugin)
|
|||
GST_TYPE_AUDIOFILTER_TEMPLATE);
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gstaudiofilter_template",
|
||||
"Audio filter template",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
"LGPL",
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_setup (GstAudiofilter *audiofilter)
|
||||
static void gst_audiofilter_template_setup (GstAudiofilter * audiofilter)
|
||||
{
|
||||
GstAudiofilterTemplate *audiofilter_template;
|
||||
|
||||
|
@ -234,8 +240,8 @@ gst_audiofilter_template_setup (GstAudiofilter *audiofilter)
|
|||
* with a minimum of memory copies. */
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_filter (GstAudiofilter *audiofilter,
|
||||
GstBuffer *outbuf, GstBuffer *inbuf)
|
||||
gst_audiofilter_template_filter (GstAudiofilter * audiofilter,
|
||||
GstBuffer * outbuf, GstBuffer * inbuf)
|
||||
{
|
||||
GstAudiofilterTemplate *audiofilter_template;
|
||||
|
||||
|
@ -245,13 +251,12 @@ gst_audiofilter_template_filter (GstAudiofilter *audiofilter,
|
|||
/* do something interesting here. This simply copies the source
|
||||
* to the destination. */
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
|
||||
audiofilter->size);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf), audiofilter->size);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter,
|
||||
GstBuffer *buf)
|
||||
gst_audiofilter_template_filter_inplace (GstAudiofilter * audiofilter,
|
||||
GstBuffer * buf)
|
||||
{
|
||||
GstAudiofilterTemplate *audiofilter_template;
|
||||
|
||||
|
@ -262,4 +267,3 @@ gst_audiofilter_template_filter_inplace (GstAudiofilter *audiofilter,
|
|||
* to the destination. */
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
#include "colorbalance.h"
|
||||
#include "colorbalance-marshal.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
VALUE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_color_balance_class_init (GstColorBalanceClass *klass);
|
||||
static void gst_color_balance_class_init (GstColorBalanceClass * klass);
|
||||
|
||||
static guint gst_color_balance_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -55,8 +56,7 @@ gst_color_balance_get_type (void)
|
|||
};
|
||||
|
||||
gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstColorBalance",
|
||||
&gst_color_balance_info, 0);
|
||||
"GstColorBalance", &gst_color_balance_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_color_balance_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ gst_color_balance_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_class_init (GstColorBalanceClass *klass)
|
||||
gst_color_balance_class_init (GstColorBalanceClass * klass)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
@ -76,8 +76,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
|
|||
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
|
||||
NULL, NULL,
|
||||
gst_color_balance_marshal_VOID__OBJECT_INT,
|
||||
G_TYPE_NONE, 2,
|
||||
GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
|
||||
G_TYPE_NONE, 2, GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
@ -91,7 +90,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
|
|||
}
|
||||
|
||||
const GList *
|
||||
gst_color_balance_list_channels (GstColorBalance *balance)
|
||||
gst_color_balance_list_channels (GstColorBalance * balance)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -103,9 +102,8 @@ gst_color_balance_list_channels (GstColorBalance *balance)
|
|||
}
|
||||
|
||||
void
|
||||
gst_color_balance_set_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value)
|
||||
gst_color_balance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -115,8 +113,8 @@ gst_color_balance_set_value (GstColorBalance *balance,
|
|||
}
|
||||
|
||||
gint
|
||||
gst_color_balance_get_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel)
|
||||
gst_color_balance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -128,13 +126,11 @@ gst_color_balance_get_value (GstColorBalance *balance,
|
|||
}
|
||||
|
||||
void
|
||||
gst_color_balance_value_changed (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value)
|
||||
gst_color_balance_value_changed (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (balance),
|
||||
gst_color_balance_signals[VALUE_CHANGED],
|
||||
0, channel, value);
|
||||
gst_color_balance_signals[VALUE_CHANGED], 0, channel, value);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <gst/colorbalance/colorbalance-enumtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_COLOR_BALANCE \
|
||||
(gst_color_balance_get_type ())
|
||||
#define GST_COLOR_BALANCE(obj) \
|
||||
|
@ -42,9 +41,7 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE))
|
||||
#define GST_COLOR_BALANCE_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass))
|
||||
|
||||
#define GST_COLOR_BALANCE_TYPE(klass) (klass->balance_type)
|
||||
|
||||
typedef struct _GstColorBalance GstColorBalance;
|
||||
|
||||
typedef enum
|
||||
|
@ -53,24 +50,23 @@ typedef enum
|
|||
GST_COLOR_BALANCE_SOFTWARE
|
||||
} GstColorBalanceType;
|
||||
|
||||
typedef struct _GstColorBalanceClass {
|
||||
typedef struct _GstColorBalanceClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
GstColorBalanceType balance_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_channels) (GstColorBalance *balance);
|
||||
const GList *(*list_channels) (GstColorBalance * balance);
|
||||
|
||||
void (* set_value) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
gint (* get_value) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel);
|
||||
void (*set_value) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
gint (*get_value) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel);
|
||||
|
||||
/* signals */
|
||||
void (* value_changed) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void (*value_changed) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstColorBalanceClass;
|
||||
|
@ -78,19 +74,15 @@ typedef struct _GstColorBalanceClass {
|
|||
GType gst_color_balance_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList *
|
||||
gst_color_balance_list_channels (GstColorBalance *balance);
|
||||
void gst_color_balance_set_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
gint gst_color_balance_get_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel);
|
||||
const GList *gst_color_balance_list_channels (GstColorBalance * balance);
|
||||
void gst_color_balance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
gint gst_color_balance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel);
|
||||
|
||||
/* trigger signal */
|
||||
void gst_color_balance_value_changed (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void gst_color_balance_value_changed (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_COLOR_BALANCE_H__ */
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
|
||||
#include "colorbalancechannel.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_VALUE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass);
|
||||
static void gst_color_balance_channel_init (GstColorBalanceChannel *balance);
|
||||
static void gst_color_balance_channel_dispose (GObject *object);
|
||||
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *
|
||||
klass);
|
||||
static void gst_color_balance_channel_init (GstColorBalanceChannel * balance);
|
||||
static void gst_color_balance_channel_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -59,15 +61,14 @@ gst_color_balance_channel_get_type (void)
|
|||
|
||||
gst_color_balance_channel_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstColorBalanceChannel",
|
||||
&color_balance_channel_info, 0);
|
||||
"GstColorBalanceChannel", &color_balance_channel_info, 0);
|
||||
}
|
||||
|
||||
return gst_color_balance_channel_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
|
||||
gst_color_balance_channel_class_init (GstColorBalanceChannelClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -78,21 +79,20 @@ gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
|
|||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
|
||||
value_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
object_klass->dispose = gst_color_balance_channel_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_init (GstColorBalanceChannel *channel)
|
||||
gst_color_balance_channel_init (GstColorBalanceChannel * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->min_value = channel->max_value = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_dispose (GObject *object)
|
||||
gst_color_balance_channel_dispose (GObject * object)
|
||||
{
|
||||
GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_COLOR_BALANCE_CHANNEL \
|
||||
(gst_color_balance_channel_get_type ())
|
||||
#define GST_COLOR_BALANCE_CHANNEL(obj) \
|
||||
|
@ -38,21 +37,20 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL))
|
||||
#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL))
|
||||
|
||||
typedef struct _GstColorBalanceChannel {
|
||||
typedef struct _GstColorBalanceChannel
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
gint min_value,
|
||||
max_value;
|
||||
gint min_value, max_value;
|
||||
} GstColorBalanceChannel;
|
||||
|
||||
typedef struct _GstColorBalanceChannelClass {
|
||||
typedef struct _GstColorBalanceChannelClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* signals */
|
||||
void (* value_changed) (GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void (*value_changed) (GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstColorBalanceChannelClass;
|
||||
|
@ -60,5 +58,4 @@ typedef struct _GstColorBalanceChannelClass {
|
|||
GType gst_color_balance_channel_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */
|
||||
|
|
|
@ -29,53 +29,46 @@
|
|||
#include <glib/gtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if (HAVE_LRINT && HAVE_LRINTF)
|
||||
|
||||
/* These defines enable functionality introduced with the 1999 ISO C
|
||||
** standard. They must be defined before the inclusion of math.h to
|
||||
** engage them. If optimisation is enabled, these functions will be
|
||||
** inlined. With optimisation switched off, you have to link in the
|
||||
** maths library using -lm.
|
||||
*/
|
||||
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#define _ISOC99_SOURCE 1
|
||||
|
||||
#define __USE_ISOC9X 1
|
||||
#define __USE_ISOC99 1
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define gst_cast_float(x) ((gint)lrintf(x))
|
||||
#define gst_cast_double(x) ((gint)lrint(x))
|
||||
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#define _ISOC99_SOURCE 1
|
||||
#define __USE_ISOC9X 1
|
||||
#define __USE_ISOC99 1
|
||||
#include <math.h>
|
||||
#define gst_cast_float(x) ((gint)lrintf(x))
|
||||
#define gst_cast_double(x) ((gint)lrint(x))
|
||||
#else
|
||||
/* use a standard c cast, but do rounding correctly */
|
||||
#define gst_cast_float(x) ((gint)floor((x)+0.5))
|
||||
#define gst_cast_double(x) ((gint)floor((x)+0.5))
|
||||
|
||||
#define gst_cast_float(x) ((gint)floor((x)+0.5))
|
||||
#define gst_cast_double(x) ((gint)floor((x)+0.5))
|
||||
#endif
|
||||
|
||||
inline static gfloat
|
||||
GFLOAT_SWAP_LE_BE(gfloat in)
|
||||
GFLOAT_SWAP_LE_BE (gfloat in)
|
||||
{
|
||||
gint32 swap;
|
||||
gfloat out;
|
||||
memcpy(&swap, &in, 4);
|
||||
|
||||
memcpy (&swap, &in, 4);
|
||||
swap = GUINT32_SWAP_LE_BE_CONSTANT (swap);
|
||||
memcpy(&out, &swap, 4);
|
||||
memcpy (&out, &swap, 4);
|
||||
return out;
|
||||
}
|
||||
|
||||
inline static gdouble
|
||||
GDOUBLE_SWAP_LE_BE(gdouble in)
|
||||
GDOUBLE_SWAP_LE_BE (gdouble in)
|
||||
{
|
||||
gint64 swap;
|
||||
gdouble out;
|
||||
memcpy(&swap, &in, 8);
|
||||
|
||||
memcpy (&swap, &in, 8);
|
||||
swap = GUINT64_SWAP_LE_BE_CONSTANT (swap);
|
||||
memcpy(&out, &swap, 8);
|
||||
memcpy (&out, &swap, 8);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -101,6 +94,4 @@ GDOUBLE_SWAP_LE_BE(gdouble in)
|
|||
#define GDOUBLE_FROM_BE(val) (GDOUBLE_TO_BE (val))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __FLOATCAST_H__ */
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ gst_gconf_get_client (void)
|
|||
/* go through a bin, finding the one pad that is unconnected in the given
|
||||
* * direction, and return that pad */
|
||||
static GstPad *
|
||||
gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
|
||||
gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
|
||||
{
|
||||
GstPad *pad = NULL;
|
||||
GList *elements = NULL;
|
||||
|
@ -57,22 +57,19 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
|
|||
|
||||
elements = (GList *) gst_bin_get_list (bin);
|
||||
/* traverse all elements looking for unconnected pads */
|
||||
while (elements && pad == NULL)
|
||||
{
|
||||
while (elements && pad == NULL) {
|
||||
element = GST_ELEMENT (elements->data);
|
||||
pads = gst_element_get_pad_list (element);
|
||||
while (pads)
|
||||
{
|
||||
while (pads) {
|
||||
/* check if the direction matches */
|
||||
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction)
|
||||
{
|
||||
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL)
|
||||
{
|
||||
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
|
||||
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
|
||||
/* found it ! */
|
||||
pad = GST_PAD (pads->data);
|
||||
}
|
||||
}
|
||||
if (pad) break; /* found one already */
|
||||
if (pad)
|
||||
break; /* found one already */
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
elements = g_list_next (elements);
|
||||
|
@ -91,7 +88,7 @@ gst_bin_find_unconnected_pad (GstBin *bin, GstPadDirection direction)
|
|||
* Returns: a #gchar string containing @key's value.
|
||||
*/
|
||||
gchar *
|
||||
gst_gconf_get_string (const gchar *key)
|
||||
gst_gconf_get_string (const gchar * key)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *value = NULL;
|
||||
|
@ -101,8 +98,7 @@ gst_gconf_get_string (const gchar *key)
|
|||
value = gconf_client_get_string (gst_gconf_get_client (), full_key, &error);
|
||||
g_free (full_key);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_print ("gst_gconf_get_string: error: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
@ -118,14 +114,13 @@ gst_gconf_get_string (const gchar *key)
|
|||
* Set GConf key @key to string value @value.
|
||||
*/
|
||||
void
|
||||
gst_gconf_set_string (const gchar *key, const gchar *value)
|
||||
gst_gconf_set_string (const gchar * key, const gchar * value)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *full_key = g_strdup_printf ("%s/%s", GST_GCONF_DIR, key);
|
||||
|
||||
gconf_client_set_string (gst_gconf_get_client (), full_key, value, &error);
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_print ("gst_gconf_set_string: error: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
@ -141,7 +136,7 @@ gst_gconf_set_string (const gchar *key, const gchar *value)
|
|||
* Returns: a #GstElement containing the rendered bin.
|
||||
*/
|
||||
GstElement *
|
||||
gst_gconf_render_bin_from_description (const gchar *description)
|
||||
gst_gconf_render_bin_from_description (const gchar * description)
|
||||
{
|
||||
GstElement *bin = NULL;
|
||||
GstPad *pad = NULL;
|
||||
|
@ -152,8 +147,7 @@ gst_gconf_render_bin_from_description (const gchar *description)
|
|||
desc = g_strdup_printf ("bin.( %s )", description);
|
||||
bin = GST_ELEMENT (gst_parse_launch (desc, &error));
|
||||
g_free (desc);
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_print ("DEBUG: gstgconf: error parsing pipeline %s\n%s\n",
|
||||
description, error->message);
|
||||
g_error_free (error);
|
||||
|
@ -161,10 +155,10 @@ gst_gconf_render_bin_from_description (const gchar *description)
|
|||
}
|
||||
|
||||
/* find pads and ghost them if necessary */
|
||||
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))){
|
||||
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))) {
|
||||
gst_element_add_ghost_pad (bin, pad, "src");
|
||||
}
|
||||
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK))){
|
||||
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK))) {
|
||||
gst_element_add_ghost_pad (bin, pad, "sink");
|
||||
}
|
||||
return bin;
|
||||
|
@ -179,7 +173,7 @@ gst_gconf_render_bin_from_description (const gchar *description)
|
|||
* Returns: a #GstElement containing the rendered bin.
|
||||
*/
|
||||
GstElement *
|
||||
gst_gconf_render_bin_from_key (const gchar *key)
|
||||
gst_gconf_render_bin_from_key (const gchar * key)
|
||||
{
|
||||
GstElement *bin = NULL;
|
||||
gchar *value;
|
||||
|
@ -313,11 +307,11 @@ gst_gconf_get_default_visualization_element (void)
|
|||
ret = gst_element_factory_make ("goom", NULL);
|
||||
|
||||
if (!ret)
|
||||
g_warning ("No GConf default visualization plugin key and goom doesn't work");
|
||||
g_warning
|
||||
("No GConf default visualization plugin key and goom doesn't work");
|
||||
else
|
||||
g_print ("GConf visualization plugin not found, using goom\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,17 +27,16 @@
|
|||
#include <gst/gst.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
|
||||
gchar * gst_gconf_get_string (const gchar *key);
|
||||
void gst_gconf_set_string (const gchar *key,
|
||||
const gchar *value);
|
||||
gchar *gst_gconf_get_string (const gchar * key);
|
||||
void gst_gconf_set_string (const gchar * key, const gchar * value);
|
||||
|
||||
GstElement * gst_gconf_render_bin_from_key (const gchar *key);
|
||||
GstElement * gst_gconf_render_bin_from_description (const gchar *description);
|
||||
GstElement *gst_gconf_render_bin_from_key (const gchar * key);
|
||||
GstElement *gst_gconf_render_bin_from_description (const gchar * description);
|
||||
|
||||
GstElement * gst_gconf_get_default_video_sink (void);
|
||||
GstElement * gst_gconf_get_default_audio_sink (void);
|
||||
GstElement * gst_gconf_get_default_video_src (void);
|
||||
GstElement * gst_gconf_get_default_audio_src (void);
|
||||
GstElement * gst_gconf_get_default_visualization_element (void);
|
||||
GstElement *gst_gconf_get_default_video_sink (void);
|
||||
GstElement *gst_gconf_get_default_audio_sink (void);
|
||||
GstElement *gst_gconf_get_default_video_src (void);
|
||||
GstElement *gst_gconf_get_default_audio_src (void);
|
||||
GstElement *gst_gconf_get_default_visualization_element (void);
|
||||
|
||||
#endif /* GST_GCONF_H */
|
||||
|
|
|
@ -16,7 +16,7 @@ typedef DCTELEM DCTBLOCK[DCTSIZE2];
|
|||
|
||||
typedef long INT32; /* must be at least 32 bits */
|
||||
|
||||
extern void gst_idct_int_idct();
|
||||
extern void gst_idct_int_idct ();
|
||||
|
||||
extern void gst_idct_init_fast_int_idct (void);
|
||||
extern void gst_idct_fast_int_idct (short *block);
|
||||
|
@ -27,6 +27,5 @@ extern void gst_idct_mmx32_idct (short *block);
|
|||
extern void gst_idct_sse_idct (short *block);
|
||||
#endif /* HAVE_LIBMMX */
|
||||
|
||||
extern void gst_idct_init_float_idct(void);
|
||||
extern void gst_idct_init_float_idct (void);
|
||||
extern void gst_idct_float_idct (short *block);
|
||||
|
||||
|
|
|
@ -72,35 +72,36 @@ static void idctcol (short *blk);
|
|||
* c[1..7] = 128*sqrt(2)
|
||||
*/
|
||||
|
||||
static void idctrow(blk)
|
||||
short *blk;
|
||||
static void
|
||||
idctrow (blk)
|
||||
short *blk;
|
||||
{
|
||||
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
|
||||
|
||||
/* shortcut */
|
||||
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
|
||||
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
|
||||
{
|
||||
blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
|
||||
if (!((x1 = blk[4] << 11) | (x2 = blk[6]) | (x3 = blk[2]) |
|
||||
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) {
|
||||
blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] =
|
||||
blk[0] << 3;
|
||||
return;
|
||||
}
|
||||
|
||||
x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */
|
||||
x0 = (blk[0] << 11) + 128; /* for proper rounding in the fourth stage */
|
||||
|
||||
/* first stage */
|
||||
x8 = W7*(x4+x5);
|
||||
x4 = x8 + (W1-W7)*x4;
|
||||
x5 = x8 - (W1+W7)*x5;
|
||||
x8 = W3*(x6+x7);
|
||||
x6 = x8 - (W3-W5)*x6;
|
||||
x7 = x8 - (W3+W5)*x7;
|
||||
x8 = W7 * (x4 + x5);
|
||||
x4 = x8 + (W1 - W7) * x4;
|
||||
x5 = x8 - (W1 + W7) * x5;
|
||||
x8 = W3 * (x6 + x7);
|
||||
x6 = x8 - (W3 - W5) * x6;
|
||||
x7 = x8 - (W3 + W5) * x7;
|
||||
|
||||
/* second stage */
|
||||
x8 = x0 + x1;
|
||||
x0 -= x1;
|
||||
x1 = W6*(x3+x2);
|
||||
x2 = x1 - (W2+W6)*x2;
|
||||
x3 = x1 + (W2-W6)*x3;
|
||||
x1 = W6 * (x3 + x2);
|
||||
x2 = x1 - (W2 + W6) * x2;
|
||||
x3 = x1 + (W2 - W6) * x3;
|
||||
x1 = x4 + x6;
|
||||
x4 -= x6;
|
||||
x6 = x5 + x7;
|
||||
|
@ -111,18 +112,18 @@ short *blk;
|
|||
x8 -= x3;
|
||||
x3 = x0 + x2;
|
||||
x0 -= x2;
|
||||
x2 = (181*(x4+x5)+128)>>8;
|
||||
x4 = (181*(x4-x5)+128)>>8;
|
||||
x2 = (181 * (x4 + x5) + 128) >> 8;
|
||||
x4 = (181 * (x4 - x5) + 128) >> 8;
|
||||
|
||||
/* fourth stage */
|
||||
blk[0] = (x7+x1)>>8;
|
||||
blk[1] = (x3+x2)>>8;
|
||||
blk[2] = (x0+x4)>>8;
|
||||
blk[3] = (x8+x6)>>8;
|
||||
blk[4] = (x8-x6)>>8;
|
||||
blk[5] = (x0-x4)>>8;
|
||||
blk[6] = (x3-x2)>>8;
|
||||
blk[7] = (x7-x1)>>8;
|
||||
blk[0] = (x7 + x1) >> 8;
|
||||
blk[1] = (x3 + x2) >> 8;
|
||||
blk[2] = (x0 + x4) >> 8;
|
||||
blk[3] = (x8 + x6) >> 8;
|
||||
blk[4] = (x8 - x6) >> 8;
|
||||
blk[5] = (x0 - x4) >> 8;
|
||||
blk[6] = (x3 - x2) >> 8;
|
||||
blk[7] = (x7 - x1) >> 8;
|
||||
}
|
||||
|
||||
/* column (vertical) IDCT
|
||||
|
@ -134,36 +135,37 @@ short *blk;
|
|||
* where: c[0] = 1/1024
|
||||
* c[1..7] = (1/1024)*sqrt(2)
|
||||
*/
|
||||
static void idctcol(blk)
|
||||
short *blk;
|
||||
static void
|
||||
idctcol (blk)
|
||||
short *blk;
|
||||
{
|
||||
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
|
||||
|
||||
/* shortcut */
|
||||
if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
|
||||
(x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
|
||||
{
|
||||
blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]=
|
||||
iclp[(blk[8*0]+32)>>6];
|
||||
if (!((x1 = (blk[8 * 4] << 8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) |
|
||||
(x4 = blk[8 * 1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 =
|
||||
blk[8 * 3]))) {
|
||||
blk[8 * 0] = blk[8 * 1] = blk[8 * 2] = blk[8 * 3] = blk[8 * 4] =
|
||||
blk[8 * 5] = blk[8 * 6] = blk[8 * 7] = iclp[(blk[8 * 0] + 32) >> 6];
|
||||
return;
|
||||
}
|
||||
|
||||
x0 = (blk[8*0]<<8) + 8192;
|
||||
x0 = (blk[8 * 0] << 8) + 8192;
|
||||
|
||||
/* first stage */
|
||||
x8 = W7*(x4+x5) + 4;
|
||||
x4 = (x8+(W1-W7)*x4)>>3;
|
||||
x5 = (x8-(W1+W7)*x5)>>3;
|
||||
x8 = W3*(x6+x7) + 4;
|
||||
x6 = (x8-(W3-W5)*x6)>>3;
|
||||
x7 = (x8-(W3+W5)*x7)>>3;
|
||||
x8 = W7 * (x4 + x5) + 4;
|
||||
x4 = (x8 + (W1 - W7) * x4) >> 3;
|
||||
x5 = (x8 - (W1 + W7) * x5) >> 3;
|
||||
x8 = W3 * (x6 + x7) + 4;
|
||||
x6 = (x8 - (W3 - W5) * x6) >> 3;
|
||||
x7 = (x8 - (W3 + W5) * x7) >> 3;
|
||||
|
||||
/* second stage */
|
||||
x8 = x0 + x1;
|
||||
x0 -= x1;
|
||||
x1 = W6*(x3+x2) + 4;
|
||||
x2 = (x1-(W2+W6)*x2)>>3;
|
||||
x3 = (x1+(W2-W6)*x3)>>3;
|
||||
x1 = W6 * (x3 + x2) + 4;
|
||||
x2 = (x1 - (W2 + W6) * x2) >> 3;
|
||||
x3 = (x1 + (W2 - W6) * x3) >> 3;
|
||||
x1 = x4 + x6;
|
||||
x4 -= x6;
|
||||
x6 = x5 + x7;
|
||||
|
@ -174,38 +176,40 @@ short *blk;
|
|||
x8 -= x3;
|
||||
x3 = x0 + x2;
|
||||
x0 -= x2;
|
||||
x2 = (181*(x4+x5)+128)>>8;
|
||||
x4 = (181*(x4-x5)+128)>>8;
|
||||
x2 = (181 * (x4 + x5) + 128) >> 8;
|
||||
x4 = (181 * (x4 - x5) + 128) >> 8;
|
||||
|
||||
/* fourth stage */
|
||||
blk[8*0] = iclp[(x7+x1)>>14];
|
||||
blk[8*1] = iclp[(x3+x2)>>14];
|
||||
blk[8*2] = iclp[(x0+x4)>>14];
|
||||
blk[8*3] = iclp[(x8+x6)>>14];
|
||||
blk[8*4] = iclp[(x8-x6)>>14];
|
||||
blk[8*5] = iclp[(x0-x4)>>14];
|
||||
blk[8*6] = iclp[(x3-x2)>>14];
|
||||
blk[8*7] = iclp[(x7-x1)>>14];
|
||||
blk[8 * 0] = iclp[(x7 + x1) >> 14];
|
||||
blk[8 * 1] = iclp[(x3 + x2) >> 14];
|
||||
blk[8 * 2] = iclp[(x0 + x4) >> 14];
|
||||
blk[8 * 3] = iclp[(x8 + x6) >> 14];
|
||||
blk[8 * 4] = iclp[(x8 - x6) >> 14];
|
||||
blk[8 * 5] = iclp[(x0 - x4) >> 14];
|
||||
blk[8 * 6] = iclp[(x3 - x2) >> 14];
|
||||
blk[8 * 7] = iclp[(x7 - x1) >> 14];
|
||||
}
|
||||
|
||||
/* two dimensional inverse discrete cosine transform */
|
||||
void gst_idct_fast_int_idct(block)
|
||||
short *block;
|
||||
void
|
||||
gst_idct_fast_int_idct (block)
|
||||
short *block;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
idctrow(block+8*i);
|
||||
for (i = 0; i < 8; i++)
|
||||
idctrow (block + 8 * i);
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
idctcol(block+i);
|
||||
for (i = 0; i < 8; i++)
|
||||
idctcol (block + i);
|
||||
}
|
||||
|
||||
void gst_idct_init_fast_int_idct()
|
||||
void
|
||||
gst_idct_init_fast_int_idct ()
|
||||
{
|
||||
int i;
|
||||
|
||||
iclp = iclip+512;
|
||||
for (i= -512; i<512; i++)
|
||||
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
|
||||
iclp = iclip + 512;
|
||||
for (i = -512; i < 512; i++)
|
||||
iclp[i] = (i < -256) ? -256 : ((i > 255) ? 255 : i);
|
||||
}
|
||||
|
|
|
@ -56,51 +56,51 @@ static double gst_idct_float_c[8][8];
|
|||
|
||||
/* initialize DCT coefficient matrix */
|
||||
|
||||
void gst_idct_init_float_idct()
|
||||
void
|
||||
gst_idct_init_float_idct ()
|
||||
{
|
||||
int freq, time;
|
||||
double scale;
|
||||
|
||||
for (freq=0; freq < 8; freq++)
|
||||
{
|
||||
scale = (freq == 0) ? sqrt(0.125) : 0.5;
|
||||
for (time=0; time<8; time++)
|
||||
gst_idct_float_c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
|
||||
for (freq = 0; freq < 8; freq++) {
|
||||
scale = (freq == 0) ? sqrt (0.125) : 0.5;
|
||||
for (time = 0; time < 8; time++)
|
||||
gst_idct_float_c[freq][time] =
|
||||
scale * cos ((PI / 8.0) * freq * (time + 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
/* perform IDCT matrix multiply for 8x8 coefficient block */
|
||||
|
||||
void gst_idct_float_idct(block)
|
||||
short *block;
|
||||
void
|
||||
gst_idct_float_idct (block)
|
||||
short *block;
|
||||
{
|
||||
int i, j, k, v;
|
||||
double partial_product;
|
||||
double tmp[64];
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
for (j=0; j<8; j++)
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 8; j++) {
|
||||
partial_product = 0.0;
|
||||
|
||||
for (k=0; k<8; k++)
|
||||
partial_product+= gst_idct_float_c[k][j]*block[8*i+k];
|
||||
for (k = 0; k < 8; k++)
|
||||
partial_product += gst_idct_float_c[k][j] * block[8 * i + k];
|
||||
|
||||
tmp[8*i+j] = partial_product;
|
||||
tmp[8 * i + j] = partial_product;
|
||||
}
|
||||
|
||||
/* Transpose operation is integrated into address mapping by switching
|
||||
loop order of i and j */
|
||||
|
||||
for (j=0; j<8; j++)
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
partial_product = 0.0;
|
||||
|
||||
for (k=0; k<8; k++)
|
||||
partial_product+= gst_idct_float_c[k][i]*tmp[8*k+j];
|
||||
for (k = 0; k < 8; k++)
|
||||
partial_product += gst_idct_float_c[k][i] * tmp[8 * k + j];
|
||||
|
||||
v = (int) floor(partial_product+0.5);
|
||||
block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v);
|
||||
v = (int) floor (partial_product + 0.5);
|
||||
block[8 * i + j] = (v < -256) ? -256 : ((v > 255) ? 255 : v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
#include <gst/idct/idct.h>
|
||||
#include "dct.h"
|
||||
|
||||
static void gst_idct_int_sparse_idct(short *data);
|
||||
static void gst_idct_int_sparse_idct (short *data);
|
||||
|
||||
GstIDCT *gst_idct_new(GstIDCTMethod method)
|
||||
GstIDCT *
|
||||
gst_idct_new (GstIDCTMethod method)
|
||||
{
|
||||
GstIDCT *new = g_malloc(sizeof(GstIDCT));
|
||||
GstIDCT *new = g_malloc (sizeof (GstIDCT));
|
||||
|
||||
new->need_transpose = FALSE;
|
||||
|
||||
if (method == GST_IDCT_DEFAULT) {
|
||||
#ifdef HAVE_LIBMMX
|
||||
if (gst_cpu_get_flags() & GST_CPU_FLAG_MMX) {
|
||||
if (gst_cpu_get_flags () & GST_CPU_FLAG_MMX) {
|
||||
method = GST_IDCT_MMX;
|
||||
}
|
||||
/* disabled for now
|
||||
|
@ -54,48 +55,49 @@ GstIDCT *gst_idct_new(GstIDCTMethod method)
|
|||
|
||||
switch (method) {
|
||||
case GST_IDCT_FAST_INT:
|
||||
GST_INFO ( "using fast_int_idct");
|
||||
gst_idct_init_fast_int_idct();
|
||||
GST_INFO ("using fast_int_idct");
|
||||
gst_idct_init_fast_int_idct ();
|
||||
new->convert = gst_idct_fast_int_idct;
|
||||
break;
|
||||
case GST_IDCT_INT:
|
||||
GST_INFO ( "using int_idct");
|
||||
GST_INFO ("using int_idct");
|
||||
new->convert = gst_idct_int_idct;
|
||||
break;
|
||||
case GST_IDCT_FLOAT:
|
||||
GST_INFO ( "using float_idct");
|
||||
gst_idct_init_float_idct();
|
||||
GST_INFO ("using float_idct");
|
||||
gst_idct_init_float_idct ();
|
||||
new->convert = gst_idct_float_idct;
|
||||
break;
|
||||
#ifdef HAVE_LIBMMX
|
||||
case GST_IDCT_MMX:
|
||||
GST_INFO ( "using MMX_idct");
|
||||
GST_INFO ("using MMX_idct");
|
||||
new->convert = gst_idct_mmx_idct;
|
||||
new->need_transpose = TRUE;
|
||||
break;
|
||||
case GST_IDCT_MMX32:
|
||||
GST_INFO ( "using MMX32_idct");
|
||||
GST_INFO ("using MMX32_idct");
|
||||
new->convert = gst_idct_mmx32_idct;
|
||||
new->need_transpose = TRUE;
|
||||
break;
|
||||
case GST_IDCT_SSE:
|
||||
GST_INFO ( "using SSE_idct");
|
||||
GST_INFO ("using SSE_idct");
|
||||
new->convert = gst_idct_sse_idct;
|
||||
new->need_transpose = TRUE;
|
||||
break;
|
||||
#endif /* HAVE_LIBMMX */
|
||||
default:
|
||||
GST_INFO ( "method not supported");
|
||||
g_free(new);
|
||||
GST_INFO ("method not supported");
|
||||
g_free (new);
|
||||
return NULL;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
static void gst_idct_int_sparse_idct(short *data)
|
||||
static void
|
||||
gst_idct_int_sparse_idct (short *data)
|
||||
{
|
||||
short val;
|
||||
gint32 v, *dp = (guint32 *)data;
|
||||
gint32 v, *dp = (guint32 *) data;
|
||||
|
||||
v = *data;
|
||||
|
||||
|
@ -104,43 +106,61 @@ static void gst_idct_int_sparse_idct(short *data)
|
|||
val += (8 >> 1);
|
||||
val /= 8;
|
||||
val = -val;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val = (v + (8 >> 1)) / 8;
|
||||
}
|
||||
v = (( val & 0xffff) | (val << 16));
|
||||
v = ((val & 0xffff) | (val << 16));
|
||||
|
||||
dp[0] = v; dp[1] = v; dp[2] = v; dp[3] = v;
|
||||
dp[4] = v; dp[5] = v; dp[6] = v; dp[7] = v;
|
||||
dp[8] = v; dp[9] = v; dp[10] = v; dp[11] = v;
|
||||
dp[12] = v; dp[13] = v; dp[14] = v; dp[15] = v;
|
||||
dp[16] = v; dp[17] = v; dp[18] = v; dp[19] = v;
|
||||
dp[20] = v; dp[21] = v; dp[22] = v; dp[23] = v;
|
||||
dp[24] = v; dp[25] = v; dp[26] = v; dp[27] = v;
|
||||
dp[28] = v; dp[29] = v; dp[30] = v; dp[31] = v;
|
||||
dp[0] = v;
|
||||
dp[1] = v;
|
||||
dp[2] = v;
|
||||
dp[3] = v;
|
||||
dp[4] = v;
|
||||
dp[5] = v;
|
||||
dp[6] = v;
|
||||
dp[7] = v;
|
||||
dp[8] = v;
|
||||
dp[9] = v;
|
||||
dp[10] = v;
|
||||
dp[11] = v;
|
||||
dp[12] = v;
|
||||
dp[13] = v;
|
||||
dp[14] = v;
|
||||
dp[15] = v;
|
||||
dp[16] = v;
|
||||
dp[17] = v;
|
||||
dp[18] = v;
|
||||
dp[19] = v;
|
||||
dp[20] = v;
|
||||
dp[21] = v;
|
||||
dp[22] = v;
|
||||
dp[23] = v;
|
||||
dp[24] = v;
|
||||
dp[25] = v;
|
||||
dp[26] = v;
|
||||
dp[27] = v;
|
||||
dp[28] = v;
|
||||
dp[29] = v;
|
||||
dp[30] = v;
|
||||
dp[31] = v;
|
||||
}
|
||||
|
||||
void gst_idct_destroy(GstIDCT *idct)
|
||||
void
|
||||
gst_idct_destroy (GstIDCT * idct)
|
||||
{
|
||||
g_return_if_fail(idct != NULL);
|
||||
g_return_if_fail (idct != NULL);
|
||||
|
||||
g_free(idct);
|
||||
g_free (idct);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"gstidct",
|
||||
"Accelerated IDCT routines",
|
||||
plugin_init,
|
||||
VERSION,
|
||||
GST_LICENSE,
|
||||
GST_PACKAGE,
|
||||
GST_ORIGIN
|
||||
)
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
GST_IDCT_DEFAULT,
|
||||
GST_IDCT_INT,
|
||||
GST_IDCT_FAST_INT,
|
||||
|
@ -34,11 +35,12 @@ typedef enum {
|
|||
} GstIDCTMethod;
|
||||
|
||||
typedef struct _GstIDCT GstIDCT;
|
||||
typedef void (*GstIDCTFunction) (gshort *block);
|
||||
typedef void (*GstIDCTFunction) (gshort * block);
|
||||
|
||||
#define GST_IDCT_TRANSPOSE(idct) ((idct)->need_transpose)
|
||||
|
||||
struct _GstIDCT {
|
||||
struct _GstIDCT
|
||||
{
|
||||
/* private */
|
||||
GstIDCTFunction convert;
|
||||
GstIDCTFunction convert_sparse;
|
||||
|
@ -46,9 +48,10 @@ struct _GstIDCT {
|
|||
};
|
||||
|
||||
|
||||
GstIDCT *gst_idct_new(GstIDCTMethod method);
|
||||
GstIDCT *gst_idct_new (GstIDCTMethod method);
|
||||
|
||||
#define gst_idct_convert(idct, blocks) (idct)->convert((blocks))
|
||||
#define gst_idct_convert_sparse(idct, blocks) (idct)->convert_sparse((blocks))
|
||||
void gst_idct_destroy(GstIDCT *idct);
|
||||
void gst_idct_destroy (GstIDCT * idct);
|
||||
|
||||
#endif /* __GST_IDCT_H__ */
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
void usage (char *msg);
|
||||
long ieeerand (long L, long H);
|
||||
void dct_init(void);
|
||||
void ref_fdct(DCTELEM block[8][8]);
|
||||
void ref_idct(DCTELEM block[8][8]);
|
||||
void dct_init (void);
|
||||
void ref_fdct (DCTELEM block[8][8]);
|
||||
void ref_idct (DCTELEM block[8][8]);
|
||||
|
||||
/* error stat accumulators -- assume initialized to 0 */
|
||||
|
||||
|
@ -38,13 +38,14 @@ long sumsqerrs[DCTSIZE2];
|
|||
int maxerr[DCTSIZE2];
|
||||
|
||||
|
||||
char * meets (double val, double limit)
|
||||
char *
|
||||
meets (double val, double limit)
|
||||
{
|
||||
return ((fabs(val) <= limit) ? "meets" : "FAILS");
|
||||
return ((fabs (val) <= limit) ? "meets" : "FAILS");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
long minpix, maxpix, sign;
|
||||
long curiter, niters;
|
||||
|
@ -61,24 +62,25 @@ main(int argc, char **argv)
|
|||
|
||||
/* Argument parsing --- not very bulletproof at all */
|
||||
|
||||
if (argc != 6) usage(NULL);
|
||||
if (argc != 6)
|
||||
usage (NULL);
|
||||
|
||||
method = atoi(argv[1]);
|
||||
minpix = atoi(argv[2]);
|
||||
maxpix = atoi(argv[3]);
|
||||
sign = atoi(argv[4]);
|
||||
niters = atol(argv[5]);
|
||||
method = atoi (argv[1]);
|
||||
minpix = atoi (argv[2]);
|
||||
maxpix = atoi (argv[3]);
|
||||
sign = atoi (argv[4]);
|
||||
niters = atol (argv[5]);
|
||||
|
||||
gst_library_load("gstidct");
|
||||
gst_library_load ("gstidct");
|
||||
|
||||
idct = gst_idct_new(method);
|
||||
idct = gst_idct_new (method);
|
||||
if (idct == 0) {
|
||||
printf("method not available\n\n\n");
|
||||
printf ("method not available\n\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
dct_init();
|
||||
dct_init ();
|
||||
|
||||
/* Loop once per generated random-data block */
|
||||
|
||||
|
@ -86,164 +88,186 @@ main(int argc, char **argv)
|
|||
|
||||
/* generate a pseudo-random block of data */
|
||||
for (i = 0; i < DCTSIZE2; i++)
|
||||
block[i] = (DCTELEM) (ieeerand(-minpix,maxpix) * sign);
|
||||
block[i] = (DCTELEM) (ieeerand (-minpix, maxpix) * sign);
|
||||
|
||||
/* perform reference FDCT */
|
||||
memcpy(refcoefs, block, sizeof(DCTELEM)*DCTSIZE2);
|
||||
ref_fdct((DCTELEM **) &refcoefs);
|
||||
memcpy (refcoefs, block, sizeof (DCTELEM) * DCTSIZE2);
|
||||
ref_fdct ((DCTELEM **) & refcoefs);
|
||||
/* clip */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if (refcoefs[i] < -2048) refcoefs[i] = -2048;
|
||||
else if (refcoefs[i] > 2047) refcoefs[i] = 2047;
|
||||
if (refcoefs[i] < -2048)
|
||||
refcoefs[i] = -2048;
|
||||
else if (refcoefs[i] > 2047)
|
||||
refcoefs[i] = 2047;
|
||||
}
|
||||
|
||||
/* perform reference IDCT */
|
||||
memcpy(refout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
|
||||
ref_idct(refout);
|
||||
memcpy (refout, refcoefs, sizeof (DCTELEM) * DCTSIZE2);
|
||||
ref_idct (refout);
|
||||
/* clip */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if (refout[i] < -256) refout[i] = -256;
|
||||
else if (refout[i] > 255) refout[i] = 255;
|
||||
if (refout[i] < -256)
|
||||
refout[i] = -256;
|
||||
else if (refout[i] > 255)
|
||||
refout[i] = 255;
|
||||
}
|
||||
|
||||
/* perform test IDCT */
|
||||
if (GST_IDCT_TRANSPOSE(idct)) {
|
||||
if (GST_IDCT_TRANSPOSE (idct)) {
|
||||
for (j = 0; j < DCTSIZE; j++) {
|
||||
for (i = 0; i < DCTSIZE; i++) {
|
||||
testout[i*DCTSIZE+j] = refcoefs[j*DCTSIZE+i];
|
||||
testout[i * DCTSIZE + j] = refcoefs[j * DCTSIZE + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(testout, refcoefs, sizeof(DCTELEM)*DCTSIZE2);
|
||||
} else {
|
||||
memcpy (testout, refcoefs, sizeof (DCTELEM) * DCTSIZE2);
|
||||
}
|
||||
|
||||
gst_trace_read_tsc(&tscstart);
|
||||
gst_idct_convert(idct, testout);
|
||||
gst_trace_read_tsc(&tscstop);
|
||||
gst_trace_read_tsc (&tscstart);
|
||||
gst_idct_convert (idct, testout);
|
||||
gst_trace_read_tsc (&tscstop);
|
||||
/*printf("time %llu, %llu %lld\n", tscstart, tscstop, tscstop-tscstart); */
|
||||
if (tscstop - tscstart < tscmin) tscmin = tscstop-tscstart;
|
||||
if (tscstop - tscstart > tscmax) tscmax = tscstop-tscstart;
|
||||
if (tscstop - tscstart < tscmin)
|
||||
tscmin = tscstop - tscstart;
|
||||
if (tscstop - tscstart > tscmax)
|
||||
tscmax = tscstop - tscstart;
|
||||
|
||||
/* clip */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if (testout[i] < -256) testout[i] = -256;
|
||||
else if (testout[i] > 255) testout[i] = 255;
|
||||
if (testout[i] < -256)
|
||||
testout[i] = -256;
|
||||
else if (testout[i] > 255)
|
||||
testout[i] = 255;
|
||||
}
|
||||
|
||||
/* accumulate error stats */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
register int err = testout[i] - refout[i];
|
||||
|
||||
sumerrs[i] += err;
|
||||
sumsqerrs[i] += err * err;
|
||||
if (err < 0) err = -err;
|
||||
if (maxerr[i] < err) maxerr[i] = err;
|
||||
if (err < 0)
|
||||
err = -err;
|
||||
if (maxerr[i] < err)
|
||||
maxerr[i] = err;
|
||||
}
|
||||
|
||||
if (curiter % 100 == 99) {
|
||||
fprintf(stderr, ".");
|
||||
fflush(stderr);
|
||||
fprintf (stderr, ".");
|
||||
fflush (stderr);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
/* print results */
|
||||
|
||||
printf("IEEE test conditions: -L = %ld, +H = %ld, sign = %ld, #iters = %ld\n",
|
||||
printf
|
||||
("IEEE test conditions: -L = %ld, +H = %ld, sign = %ld, #iters = %ld\n",
|
||||
minpix, maxpix, sign, niters);
|
||||
|
||||
printf("Speed, min time %lld, max %lld\n", tscmin, tscmax);
|
||||
printf ("Speed, min time %lld, max %lld\n", tscmin, tscmax);
|
||||
|
||||
printf("Peak absolute values of errors:\n");
|
||||
printf ("Peak absolute values of errors:\n");
|
||||
for (i = 0, j = 0; i < DCTSIZE2; i++) {
|
||||
if (j < maxerr[i]) j = maxerr[i];
|
||||
printf("%4d", maxerr[i]);
|
||||
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
|
||||
if (j < maxerr[i])
|
||||
j = maxerr[i];
|
||||
printf ("%4d", maxerr[i]);
|
||||
if ((i % DCTSIZE) == DCTSIZE - 1)
|
||||
printf ("\n");
|
||||
}
|
||||
printf("Worst peak error = %d (%s spec limit 1)\n\n", j,
|
||||
meets((double) j, 1.0));
|
||||
printf ("Worst peak error = %d (%s spec limit 1)\n\n", j,
|
||||
meets ((double) j, 1.0));
|
||||
|
||||
printf("Mean square errors:\n");
|
||||
printf ("Mean square errors:\n");
|
||||
max = total = 0.0;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
double err = (double) sumsqerrs[i] / ((double) niters);
|
||||
total += (double) sumsqerrs[i];
|
||||
if (max < err) max = err;
|
||||
printf(" %8.4f", err);
|
||||
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
|
||||
}
|
||||
printf("Worst pmse = %.6f (%s spec limit 0.06)\n", max, meets(max, 0.06));
|
||||
total /= (double) (64*niters);
|
||||
printf("Overall mse = %.6f (%s spec limit 0.02)\n\n", total,
|
||||
meets(total, 0.02));
|
||||
|
||||
printf("Mean errors:\n");
|
||||
total += (double) sumsqerrs[i];
|
||||
if (max < err)
|
||||
max = err;
|
||||
printf (" %8.4f", err);
|
||||
if ((i % DCTSIZE) == DCTSIZE - 1)
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("Worst pmse = %.6f (%s spec limit 0.06)\n", max, meets (max, 0.06));
|
||||
total /= (double) (64 * niters);
|
||||
printf ("Overall mse = %.6f (%s spec limit 0.02)\n\n", total,
|
||||
meets (total, 0.02));
|
||||
|
||||
printf ("Mean errors:\n");
|
||||
max = total = 0.0;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
double err = (double) sumerrs[i] / ((double) niters);
|
||||
|
||||
total += (double) sumerrs[i];
|
||||
printf(" %8.4f", err);
|
||||
if (err < 0.0) err = -err;
|
||||
if (max < err) max = err;
|
||||
if ((i%DCTSIZE) == DCTSIZE-1) printf("\n");
|
||||
printf (" %8.4f", err);
|
||||
if (err < 0.0)
|
||||
err = -err;
|
||||
if (max < err)
|
||||
max = err;
|
||||
if ((i % DCTSIZE) == DCTSIZE - 1)
|
||||
printf ("\n");
|
||||
}
|
||||
printf("Worst mean error = %.6f (%s spec limit 0.015)\n", max,
|
||||
meets(max, 0.015));
|
||||
total /= (double) (64*niters);
|
||||
printf("Overall mean error = %.6f (%s spec limit 0.0015)\n\n", total,
|
||||
meets(total, 0.0015));
|
||||
printf ("Worst mean error = %.6f (%s spec limit 0.015)\n", max,
|
||||
meets (max, 0.015));
|
||||
total /= (double) (64 * niters);
|
||||
printf ("Overall mean error = %.6f (%s spec limit 0.0015)\n\n", total,
|
||||
meets (total, 0.0015));
|
||||
|
||||
/* test for 0 input giving 0 output */
|
||||
memset(testout, 0, sizeof(DCTELEM)*DCTSIZE2);
|
||||
gst_idct_convert(idct, testout);
|
||||
for (i = 0, j=0; i < DCTSIZE2; i++) {
|
||||
memset (testout, 0, sizeof (DCTELEM) * DCTSIZE2);
|
||||
gst_idct_convert (idct, testout);
|
||||
for (i = 0, j = 0; i < DCTSIZE2; i++) {
|
||||
if (testout[i]) {
|
||||
printf("Position %d of IDCT(0) = %d (FAILS)\n", i, testout[i]);
|
||||
printf ("Position %d of IDCT(0) = %d (FAILS)\n", i, testout[i]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
printf("%d elements of IDCT(0) were not zero\n\n\n", j);
|
||||
printf ("%d elements of IDCT(0) were not zero\n\n\n", j);
|
||||
|
||||
exit(0);
|
||||
exit (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usage (char *msg)
|
||||
void
|
||||
usage (char *msg)
|
||||
{
|
||||
if (msg != NULL)
|
||||
fprintf(stderr, "\nerror: %s\n", msg);
|
||||
fprintf (stderr, "\nerror: %s\n", msg);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "usage: ieeetest minpix maxpix sign niters\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " test = 1 - 5\n");
|
||||
fprintf(stderr, " minpix = -L value per IEEE spec\n");
|
||||
fprintf(stderr, " maxpix = H value per IEEE spec\n");
|
||||
fprintf(stderr, " sign = +1 for normal, -1 to run negated test\n");
|
||||
fprintf(stderr, " niters = # iterations (10000 for full test)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "usage: ieeetest minpix maxpix sign niters\n");
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " test = 1 - 5\n");
|
||||
fprintf (stderr, " minpix = -L value per IEEE spec\n");
|
||||
fprintf (stderr, " maxpix = H value per IEEE spec\n");
|
||||
fprintf (stderr, " sign = +1 for normal, -1 to run negated test\n");
|
||||
fprintf (stderr, " niters = # iterations (10000 for full test)\n");
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
exit(1);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
/* Pseudo-random generator specified by IEEE 1180 */
|
||||
|
||||
long ieeerand (long L, long H)
|
||||
long
|
||||
ieeerand (long L, long H)
|
||||
{
|
||||
static long randx = 1;
|
||||
static double z = (double) 0x7fffffff;
|
||||
|
||||
long i,j;
|
||||
long i, j;
|
||||
double x;
|
||||
|
||||
randx = (randx * 1103515245) + 12345;
|
||||
i = randx & 0x7ffffffe;
|
||||
x = ((double) i) / z;
|
||||
x *= (L+H+1);
|
||||
x *= (L + H + 1);
|
||||
j = x;
|
||||
return j-L;
|
||||
return j - L;
|
||||
}
|
||||
|
||||
|
||||
|
@ -256,33 +280,35 @@ double coslu[8][8];
|
|||
|
||||
|
||||
/* Routine to initialise the cosine lookup table */
|
||||
void dct_init(void)
|
||||
void
|
||||
dct_init (void)
|
||||
{
|
||||
int a,b;
|
||||
int a, b;
|
||||
double tmp;
|
||||
|
||||
for(a=0;a<8;a++)
|
||||
for(b=0;b<8;b++) {
|
||||
tmp = cos((double)((a+a+1)*b) * (3.14159265358979323846 / 16.0));
|
||||
if(b==0)
|
||||
tmp /= sqrt(2.0);
|
||||
for (a = 0; a < 8; a++)
|
||||
for (b = 0; b < 8; b++) {
|
||||
tmp = cos ((double) ((a + a + 1) * b) * (3.14159265358979323846 / 16.0));
|
||||
if (b == 0)
|
||||
tmp /= sqrt (2.0);
|
||||
coslu[a][b] = tmp * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ref_fdct (DCTELEM block[8][8])
|
||||
void
|
||||
ref_fdct (DCTELEM block[8][8])
|
||||
{
|
||||
int x,y,u,v;
|
||||
int x, y, u, v;
|
||||
double tmp, tmp2;
|
||||
double res[8][8];
|
||||
|
||||
for (v=0; v<8; v++) {
|
||||
for (u=0; u<8; u++) {
|
||||
for (v = 0; v < 8; v++) {
|
||||
for (u = 0; u < 8; u++) {
|
||||
tmp = 0.0;
|
||||
for (y=0; y<8; y++) {
|
||||
for (y = 0; y < 8; y++) {
|
||||
tmp2 = 0.0;
|
||||
for (x=0; x<8; x++) {
|
||||
for (x = 0; x < 8; x++) {
|
||||
tmp2 += (double) block[y][x] * coslu[x][u];
|
||||
}
|
||||
tmp += coslu[y][v] * tmp2;
|
||||
|
@ -291,11 +317,11 @@ void ref_fdct (DCTELEM block[8][8])
|
|||
}
|
||||
}
|
||||
|
||||
for (v=0; v<8; v++) {
|
||||
for (u=0; u<8; u++) {
|
||||
for (v = 0; v < 8; v++) {
|
||||
for (u = 0; u < 8; u++) {
|
||||
tmp = res[v][u];
|
||||
if (tmp < 0.0) {
|
||||
x = - ((int) (0.5 - tmp));
|
||||
x = -((int) (0.5 - tmp));
|
||||
} else {
|
||||
x = (int) (tmp + 0.5);
|
||||
}
|
||||
|
@ -305,18 +331,19 @@ void ref_fdct (DCTELEM block[8][8])
|
|||
}
|
||||
|
||||
|
||||
void ref_idct (DCTELEM block[8][8])
|
||||
void
|
||||
ref_idct (DCTELEM block[8][8])
|
||||
{
|
||||
int x,y,u,v;
|
||||
int x, y, u, v;
|
||||
double tmp, tmp2;
|
||||
double res[8][8];
|
||||
|
||||
for (y=0; y<8; y++) {
|
||||
for (x=0; x<8; x++) {
|
||||
for (y = 0; y < 8; y++) {
|
||||
for (x = 0; x < 8; x++) {
|
||||
tmp = 0.0;
|
||||
for (v=0; v<8; v++) {
|
||||
for (v = 0; v < 8; v++) {
|
||||
tmp2 = 0.0;
|
||||
for (u=0; u<8; u++) {
|
||||
for (u = 0; u < 8; u++) {
|
||||
tmp2 += (double) block[v][u] * coslu[x][u];
|
||||
}
|
||||
tmp += coslu[y][v] * tmp2;
|
||||
|
@ -325,11 +352,11 @@ void ref_idct (DCTELEM block[8][8])
|
|||
}
|
||||
}
|
||||
|
||||
for (v=0; v<8; v++) {
|
||||
for (u=0; u<8; u++) {
|
||||
for (v = 0; v < 8; v++) {
|
||||
for (u = 0; u < 8; u++) {
|
||||
tmp = res[v][u];
|
||||
if (tmp < 0.0) {
|
||||
x = - ((int) (0.5 - tmp));
|
||||
x = -((int) (0.5 - tmp));
|
||||
} else {
|
||||
x = (int) (tmp + 0.5);
|
||||
}
|
||||
|
|
|
@ -51,10 +51,8 @@
|
|||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
Sorry, this code only copes with 8 x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT
|
||||
* on each column. Direct algorithms are also available, but they are
|
||||
|
@ -90,7 +88,6 @@
|
|||
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
|
||||
* shows that the values given below are the most effective.
|
||||
*/
|
||||
|
||||
#ifdef EIGHT_BIT_SAMPLES
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
|
@ -98,22 +95,16 @@
|
|||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
#define ONE ((INT32) 1)
|
||||
|
||||
#define CONST_SCALE (ONE << CONST_BITS)
|
||||
|
||||
/* Convert a positive real constant to an integer scaled by CONST_SCALE. */
|
||||
|
||||
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
|
||||
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
|
||||
|
@ -141,15 +132,11 @@
|
|||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_072711026 FIX(3.072711026)
|
||||
#endif
|
||||
|
||||
|
||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
||||
* the fudge factor is correct for either sign of X.
|
||||
*/
|
||||
|
||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
|
@ -160,7 +147,6 @@
|
|||
* combination of casts.
|
||||
* NB: for 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#ifdef EIGHT_BIT_SAMPLES
|
||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
||||
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT16) (const)))
|
||||
|
@ -169,17 +155,13 @@
|
|||
#define MULTIPLY(var,const) (((INT16) (var)) * ((INT32) (const)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY /* default definition */
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Perform the inverse DCT on one block of coefficients.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
gst_idct_int_idct (DCTBLOCK data)
|
||||
{
|
||||
INT32 tmp0, tmp1, tmp2, tmp3;
|
||||
|
@ -187,14 +169,13 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
INT32 z1, z2, z3, z4, z5;
|
||||
register DCTELEM *dataptr;
|
||||
int rowctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
SHIFT_TEMPS
|
||||
/* Pass 1: process rows. */
|
||||
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
|
||||
/* furthermore, we scale the results by 2**PASS1_BITS. */
|
||||
|
||||
dataptr = data;
|
||||
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
|
||||
for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
|
||||
/* Due to quantization, we will usually find that many of the input
|
||||
* coefficients are zero, especially the AC terms. We can exploit this
|
||||
* by short-circuiting the IDCT calculation for any row in which all
|
||||
|
@ -228,9 +209,9 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
z2 = (INT32) dataptr[2];
|
||||
z3 = (INT32) dataptr[6];
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
|
||||
|
||||
tmp0 = ((INT32) dataptr[0] + (INT32) dataptr[4]) << CONST_BITS;
|
||||
tmp1 = ((INT32) dataptr[0] - (INT32) dataptr[4]) << CONST_BITS;
|
||||
|
@ -253,16 +234,16 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY (tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY (tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
@ -274,14 +255,14 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
|
||||
dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
|
||||
dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
|
||||
dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
|
||||
dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
|
||||
dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
|
||||
dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
|
||||
dataptr[0] = (DCTELEM) DESCALE (tmp10 + tmp3, CONST_BITS - PASS1_BITS);
|
||||
dataptr[7] = (DCTELEM) DESCALE (tmp10 - tmp3, CONST_BITS - PASS1_BITS);
|
||||
dataptr[1] = (DCTELEM) DESCALE (tmp11 + tmp2, CONST_BITS - PASS1_BITS);
|
||||
dataptr[6] = (DCTELEM) DESCALE (tmp11 - tmp2, CONST_BITS - PASS1_BITS);
|
||||
dataptr[2] = (DCTELEM) DESCALE (tmp12 + tmp1, CONST_BITS - PASS1_BITS);
|
||||
dataptr[5] = (DCTELEM) DESCALE (tmp12 - tmp1, CONST_BITS - PASS1_BITS);
|
||||
dataptr[3] = (DCTELEM) DESCALE (tmp13 + tmp0, CONST_BITS - PASS1_BITS);
|
||||
dataptr[4] = (DCTELEM) DESCALE (tmp13 - tmp0, CONST_BITS - PASS1_BITS);
|
||||
|
||||
dataptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
@ -291,7 +272,7 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
/* and also undo the PASS1_BITS scaling. */
|
||||
|
||||
dataptr = data;
|
||||
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
|
||||
for (rowctr = DCTSIZE - 1; rowctr >= 0; rowctr--) {
|
||||
/* Columns of zeroes can be exploited in the same way as we did with rows.
|
||||
* However, the row calculation has created many nonzero AC terms, so the
|
||||
* simplification applies less often (typically 5% to 10% of the time).
|
||||
|
@ -301,20 +282,20 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
*/
|
||||
|
||||
#ifndef NO_ZERO_COLUMN_TEST
|
||||
if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] |
|
||||
dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] |
|
||||
dataptr[DCTSIZE*7]) == 0) {
|
||||
if ((dataptr[DCTSIZE * 1] | dataptr[DCTSIZE * 2] | dataptr[DCTSIZE * 3] |
|
||||
dataptr[DCTSIZE * 4] | dataptr[DCTSIZE * 5] | dataptr[DCTSIZE * 6] |
|
||||
dataptr[DCTSIZE * 7]) == 0) {
|
||||
/* AC terms all zero */
|
||||
DCTELEM dcval = (DCTELEM) DESCALE((INT32) dataptr[0], PASS1_BITS+3);
|
||||
DCTELEM dcval = (DCTELEM) DESCALE ((INT32) dataptr[0], PASS1_BITS + 3);
|
||||
|
||||
dataptr[DCTSIZE*0] = dcval;
|
||||
dataptr[DCTSIZE*1] = dcval;
|
||||
dataptr[DCTSIZE*2] = dcval;
|
||||
dataptr[DCTSIZE*3] = dcval;
|
||||
dataptr[DCTSIZE*4] = dcval;
|
||||
dataptr[DCTSIZE*5] = dcval;
|
||||
dataptr[DCTSIZE*6] = dcval;
|
||||
dataptr[DCTSIZE*7] = dcval;
|
||||
dataptr[DCTSIZE * 0] = dcval;
|
||||
dataptr[DCTSIZE * 1] = dcval;
|
||||
dataptr[DCTSIZE * 2] = dcval;
|
||||
dataptr[DCTSIZE * 3] = dcval;
|
||||
dataptr[DCTSIZE * 4] = dcval;
|
||||
dataptr[DCTSIZE * 5] = dcval;
|
||||
dataptr[DCTSIZE * 6] = dcval;
|
||||
dataptr[DCTSIZE * 7] = dcval;
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
continue;
|
||||
|
@ -324,15 +305,19 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
/* Even part: reverse the even part of the forward DCT. */
|
||||
/* The rotator is sqrt(2)*c(-6). */
|
||||
|
||||
z2 = (INT32) dataptr[DCTSIZE*2];
|
||||
z3 = (INT32) dataptr[DCTSIZE*6];
|
||||
z2 = (INT32) dataptr[DCTSIZE * 2];
|
||||
z3 = (INT32) dataptr[DCTSIZE * 6];
|
||||
|
||||
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
z1 = MULTIPLY (z2 + z3, FIX_0_541196100);
|
||||
tmp2 = z1 + MULTIPLY (z3, -FIX_1_847759065);
|
||||
tmp3 = z1 + MULTIPLY (z2, FIX_0_765366865);
|
||||
|
||||
tmp0 = ((INT32) dataptr[DCTSIZE*0] + (INT32) dataptr[DCTSIZE*4]) << CONST_BITS;
|
||||
tmp1 = ((INT32) dataptr[DCTSIZE*0] - (INT32) dataptr[DCTSIZE*4]) << CONST_BITS;
|
||||
tmp0 =
|
||||
((INT32) dataptr[DCTSIZE * 0] +
|
||||
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
|
||||
tmp1 =
|
||||
((INT32) dataptr[DCTSIZE * 0] -
|
||||
(INT32) dataptr[DCTSIZE * 4]) << CONST_BITS;
|
||||
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
|
@ -343,25 +328,25 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
|
||||
*/
|
||||
|
||||
tmp0 = (INT32) dataptr[DCTSIZE*7];
|
||||
tmp1 = (INT32) dataptr[DCTSIZE*5];
|
||||
tmp2 = (INT32) dataptr[DCTSIZE*3];
|
||||
tmp3 = (INT32) dataptr[DCTSIZE*1];
|
||||
tmp0 = (INT32) dataptr[DCTSIZE * 7];
|
||||
tmp1 = (INT32) dataptr[DCTSIZE * 5];
|
||||
tmp2 = (INT32) dataptr[DCTSIZE * 3];
|
||||
tmp3 = (INT32) dataptr[DCTSIZE * 1];
|
||||
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
z4 = tmp1 + tmp3;
|
||||
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
z5 = MULTIPLY (z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
|
||||
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
tmp0 = MULTIPLY (tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
|
||||
tmp1 = MULTIPLY (tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
|
||||
tmp2 = MULTIPLY (tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
|
||||
tmp3 = MULTIPLY (tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
|
||||
z1 = MULTIPLY (z1, -FIX_0_899976223); /* sqrt(2) * (c7-c3) */
|
||||
z2 = MULTIPLY (z2, -FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
|
||||
z3 = MULTIPLY (z3, -FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
|
||||
z4 = MULTIPLY (z4, -FIX_0_390180644); /* sqrt(2) * (c5-c3) */
|
||||
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
|
@ -373,22 +358,22 @@ gst_idct_int_idct (DCTBLOCK data)
|
|||
|
||||
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
|
||||
|
||||
dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3);
|
||||
dataptr[DCTSIZE * 0] = (DCTELEM) DESCALE (tmp10 + tmp3,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 7] = (DCTELEM) DESCALE (tmp10 - tmp3,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 1] = (DCTELEM) DESCALE (tmp11 + tmp2,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 6] = (DCTELEM) DESCALE (tmp11 - tmp2,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 2] = (DCTELEM) DESCALE (tmp12 + tmp1,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 5] = (DCTELEM) DESCALE (tmp12 - tmp1,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 3] = (DCTELEM) DESCALE (tmp13 + tmp0,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
dataptr[DCTSIZE * 4] = (DCTELEM) DESCALE (tmp13 - tmp0,
|
||||
CONST_BITS + PASS1_BITS + 3);
|
||||
|
||||
dataptr++; /* advance pointer to next column */
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
/* MMX32 iDCT algorithm (IEEE-1180 compliant) :: idct_mmx32()
*/
|
||||
/*
*/
|
||||
/* MPEG2AVI
*/
|
||||
|
@ -103,7 +102,6 @@
|
|||
/* liaor@umcc.ais.org http://members.tripod.com/~liaor
*/
|
||||
/*
*/
|
||||
|
||||
|
||||
/*;=============================================================================
*/
|
||||
/*;
*/
|
||||
/*; AP-922 http://developer.intel.com/vtune/cbts/strmsimd
*/
|
||||
|
@ -114,11 +112,9 @@
|
|||
/*
|
||||
mword typedef qword
|
||||
qword ptr equ mword ptr */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <mmx.h>
|
||||
|
||||
#define BITS_INV_ACC 4 /*; 4 or 5 for IEEE
*/
|
||||
|
@ -133,12 +129,12 @@ qword ptr equ mword ptr */
|
|||
/*#define RND_INV_ROW (1024 * (6 - BITS_INV_ACC)) //; 1 << (SHIFT_INV_ROW-1)
*/
|
||||
/*#define RND_INV_COL (16 * (BITS_INV_ACC - 3)) //; 1 << (SHIFT_INV_COL-1)
*/
|
||||
|
||||
|
||||
/*.data
*/
|
||||
/*Align 16
*/
|
||||
const static long r_inv_row[2] = { RND_INV_ROW, RND_INV_ROW};
|
||||
const static long r_inv_col[2] = {RND_INV_COL, RND_INV_COL};
|
||||
const static long r_inv_corr[2] = {RND_INV_CORR, RND_INV_CORR };
|
||||
const static long r_inv_row[2] = { RND_INV_ROW, RND_INV_ROW };
|
||||
const static long r_inv_col[2] = { RND_INV_COL, RND_INV_COL };
|
||||
const static long r_inv_corr[2] = { RND_INV_CORR, RND_INV_CORR };
|
||||
|
||||
|
||||
/*const static short r_inv_col[4] =
*/
|
||||
/* {RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL};
*/
|
||||
|
@ -151,9 +147,9 @@ const static long r_inv_corr[2] = {RND_INV_CORR, RND_INV_CORR };
|
|||
/*#define SHIFT_FRW_COL BITS_FRW_ACC
*/
|
||||
/*#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17)
*/
|
||||
/*#define RND_FRW_ROW (262144 * (BITS_FRW_ACC - 1)) //; 1 << (SHIFT_FRW_ROW-1)
*/
|
||||
const static __int64 one_corr = 0x0001000100010001;
|
||||
const static long r_frw_row[2] = { RND_FRW_ROW, RND_FRW_ROW };
|
||||
|
||||
const static __int64 one_corr = 0x0001000100010001;
|
||||
const static long r_frw_row[2] = {RND_FRW_ROW, RND_FRW_ROW };
|
||||
|
||||
/*const static short tg_1_16[4] = {13036, 13036, 13036, 13036 }; //tg * (2<<16) + 0.5
*/
|
||||
/*const static short tg_2_16[4] = {27146, 27146, 27146, 27146 }; //tg * (2<<16) + 0.5
*/
|
||||
|
@ -162,19 +158,20 @@ const static long r_frw_row[2] = {RND_FRW_ROW, RND_FRW_ROW };
|
|||
/*const static short ocos_4_16[4] = {23170, 23170, 23170, 23170 }; //cos * (2<<15) + 0.5
*/
|
||||
|
||||
/*concatenated table, for forward DCT transformation
*/
|
||||
const static short tg_all_16[] = {
|
||||
13036, 13036, 13036, 13036, /* tg * (2<<16) + 0.5
*/
|
||||
const static short tg_all_16[] = {
13036, 13036, 13036, 13036, /* tg * (2<<16) + 0.5
*/
|
||||
27146, 27146, 27146, 27146, /*tg * (2<<16) + 0.5
*/
|
||||
-21746, -21746, -21746, -21746, /* tg * (2<<16) + 0.5
*/
|
||||
-19195, -19195, -19195, -19195, /*cos * (2<<16) + 0.5
*/
|
||||
23170, 23170, 23170, 23170 }; /*cos * (2<<15) + 0.5
*/
|
||||
23170, 23170, 23170, 23170
|
||||
}; /*cos * (2<<15) + 0.5
*/
|
||||
|
||||
|
||||
#define tg_1_16 (tg_all_16 + 0)
|
||||
#define tg_2_16 (tg_all_16 + 8)
|
||||
#define tg_3_16 (tg_all_16 + 16)
|
||||
#define cos_4_16 (tg_all_16 + 24)
|
||||
#define ocos_4_16 (tg_all_16 + 32)
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
;=============================================================================
|
||||
;
|
||||
|
@ -236,51 +233,53 @@ IF _MMX ; MMX code
|
|||
;=============================================================================
|
||||
|
||||
/*; Table for rows 0,4 - constants are multiplied by cos_4_16
*/
|
||||
const short tab_i_04[] = {
|
||||
16384, 16384, 16384, -16384, /* ; movq-> w06 w04 w02 w00
*/
|
||||
const short tab_i_04[] = {
16384, 16384, 16384, -16384, /* ; movq-> w06 w04 w02 w00
*/
|
||||
21407, 8867, 8867, -21407, /* w07 w05 w03 w01
*/
|
||||
16384, -16384, 16384, 16384, /*; w14 w12 w10 w08
*/
|
||||
-8867, 21407, -21407, -8867, /*; w15 w13 w11 w09
*/
|
||||
22725, 12873, 19266, -22725, /*; w22 w20 w18 w16
*/
|
||||
19266, 4520, -4520, -12873, /*; w23 w21 w19 w17
*/
|
||||
12873, 4520, 4520, 19266, /*; w30 w28 w26 w24
*/
|
||||
-22725, 19266, -12873, -22725 };/*w31 w29 w27 w25
*/
|
||||
-22725, 19266, -12873, -22725
|
||||
}; /*w31 w29 w27 w25
*/
|
||||
|
||||
|
||||
/*; Table for rows 1,7 - constants are multiplied by cos_1_16
*/
|
||||
const short tab_i_17[] = {
|
||||
22725, 22725, 22725, -22725, /* ; movq-> w06 w04 w02 w00
*/
|
||||
const short tab_i_17[] = {
22725, 22725, 22725, -22725, /* ; movq-> w06 w04 w02 w00
*/
|
||||
29692, 12299, 12299, -29692, /* ; w07 w05 w03 w01
*/
|
||||
22725, -22725, 22725, 22725, /*; w14 w12 w10 w08
*/
|
||||
-12299, 29692, -29692, -12299, /*; w15 w13 w11 w09
*/
|
||||
31521, 17855, 26722, -31521, /*; w22 w20 w18 w16
*/
|
||||
26722, 6270, -6270, -17855, /*; w23 w21 w19 w17
*/
|
||||
17855, 6270, 6270, 26722, /*; w30 w28 w26 w24
*/
|
||||
-31521, 26722, -17855, -31521}; /* w31 w29 w27 w25
*/
|
||||
-31521, 26722, -17855, -31521
|
||||
}; /* w31 w29 w27 w25
*/
|
||||
|
||||
|
||||
/*; Table for rows 2,6 - constants are multiplied by cos_2_16
*/
|
||||
const short tab_i_26[] = {
|
||||
21407, 21407, 21407, -21407, /* ; movq-> w06 w04 w02 w00
*/
|
||||
const short tab_i_26[] = {
21407, 21407, 21407, -21407, /* ; movq-> w06 w04 w02 w00
*/
|
||||
27969, 11585, 11585, -27969, /* ; w07 w05 w03 w01
*/
|
||||
21407, -21407, 21407, 21407, /* ; w14 w12 w10 w08
*/
|
||||
-11585, 27969, -27969, -11585, /* ;w15 w13 w11 w09
*/
|
||||
29692, 16819, 25172, -29692, /* ;w22 w20 w18 w16
*/
|
||||
25172, 5906, -5906, -16819, /* ;w23 w21 w19 w17
*/
|
||||
16819, 5906, 5906, 25172, /* ;w30 w28 w26 w24
*/
|
||||
-29692, 25172, -16819, -29692}; /* ;w31 w29 w27 w25
*/
|
||||
-29692, 25172, -16819, -29692
|
||||
}; /* ;w31 w29 w27 w25
*/
|
||||
|
||||
|
||||
/*; Table for rows 3,5 - constants are multiplied by cos_3_16
*/
|
||||
const short tab_i_35[] = {
|
||||
19266, 19266, 19266, -19266, /*; movq-> w06 w04 w02 w00
*/
|
||||
const short tab_i_35[] = {
19266, 19266, 19266, -19266, /*; movq-> w06 w04 w02 w00
*/
|
||||
25172, 10426, 10426, -25172, /*; w07 w05 w03 w01
*/
|
||||
19266, -19266, 19266, 19266, /*; w14 w12 w10 w08
*/
|
||||
-10426, 25172, -25172, -10426, /*; w15 w13 w11 w09
*/
|
||||
26722, 15137, 22654, -26722, /*; w22 w20 w18 w16
*/
|
||||
22654, 5315, -5315, -15137, /*; w23 w21 w19 w17
*/
|
||||
15137, 5315, 5315, 22654, /*; w30 w28 w26 w24
*/
|
||||
-26722, 22654, -15137, -26722}; /*; w31 w29 w27 w25
*/
|
||||
*/
|
||||
-26722, 22654, -15137, -26722
|
||||
}; /*; w31 w29 w27 w25
*/
|
||||
|
||||
*/
|
||||
/* CONCATENATED TABLE, rows 0,1,2,3,4,5,6,7 (in order )
*/
|
||||
/*
*/
|
||||
/* In our implementation, however, we only use row0 !
*/
|
||||
|
@ -366,7 +365,8 @@ static const short tab_i_01234567[] = {
|
|||
31521, 17855, 26722, -31521, /*; w22 w20 w18 w16
*/
|
||||
26722, 6270, -6270, -17855, /*; w23 w21 w19 w17
*/
|
||||
17855, 6270, 6270, 26722, /*; w30 w28 w26 w24
*/
|
||||
-31521, 26722, -17855, -31521}; /* w31 w29 w27 w25
*/
|
||||
-31521, 26722, -17855, -31521
|
||||
}; /* w31 w29 w27 w25
*/
|
||||
|
||||
|
||||
#define INP eax /* pointer to (short *blk)
*/
|
||||
|
@ -380,21 +380,21 @@ static const short tab_i_01234567[] = {
|
|||
/* private variables and functions
*/
|
||||
|
||||
/*temporary storage space, 8x8 of shorts
*/
|
||||
__inline static void idct_mmx32_rows (short *blk); /* transform rows
*/
|
||||
__inline static void idct_mmx32_cols (short *blk); /* transform "columns"
*/
|
||||
|
||||
__inline static void idct_mmx32_rows( short *blk ); /* transform rows
*/
|
||||
__inline static void idct_mmx32_cols( short *blk ); /* transform "columns"
*/
|
||||
/* the "column" transform actually transforms rows, it is
*/
|
||||
/* identical to the row-transform except for the ROUNDING
*/
|
||||
/* and SHIFTING coefficients.
*/
|
||||
|
||||
|
||||
static void
|
||||
idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
||||
{
|
||||
static void
|
||||
idct_mmx32_rows (short *blk)
|
||||
{ /* transform all 8 rows of 8x8 iDCT block
*/
|
||||
int x;
|
||||
short qwTemp[64];
|
||||
short *out = &qwTemp[0];
|
||||
short *inptr = blk;
|
||||
|
||||
|
||||
/* this subroutine performs two operations
*/
|
||||
/* 1) iDCT row transform
*/
|
||||
/* for( i = 0; i < 8; ++ i)
*/
|
||||
|
@ -402,88 +402,62 @@ idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
|||
/*
*/
|
||||
/* 2) transpose the matrix (which was stored in qwTemp[])
*/
|
||||
/* qwTemp[] -> [8x8 matrix transpose] -> blk[]
*/
|
||||
|
||||
for (x=0; x<8; x++) { /* transform one row per iteration
*/
|
||||
movq_m2r(*(inptr), mm0); /* 0 ; x3 x2 x1 x0
*/
|
||||
|
||||
movq_m2r(*(inptr+4), mm1); /* 1 ; x7 x6 x5 x4
*/
|
||||
movq_r2r(mm0, mm2); /* 2 ; x3 x2 x1 x0
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567), mm3); /* 3 ; w06 w04 w02 w00
*/
|
||||
punpcklwd_r2r(mm1, mm0); /* x5 x1 x4 x0
*/
|
||||
for (x = 0; x < 8; x++) { /* transform one row per iteration
*/
|
||||
movq_m2r (*(inptr), mm0); /* 0 ; x3 x2 x1 x0
*/
|
||||
movq_m2r (*(inptr + 4), mm1); /* 1 ; x7 x6 x5 x4
*/
|
||||
movq_r2r (mm0, mm2); /* 2 ; x3 x2 x1 x0
*/
|
||||
movq_m2r (*(tab_i_01234567), mm3); /* 3 ; w06 w04 w02 w00
*/
|
||||
punpcklwd_r2r (mm1, mm0); /* x5 x1 x4 x0
*/
|
||||
|
||||
/* ----------
*/
|
||||
movq_r2r(mm0, mm5); /* 5 ; x5 x1 x4 x0
*/
|
||||
punpckldq_r2r(mm0, mm0); /* x4 x0 x4 x0
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+4), mm4); /* 4 ; w07 w05 w03 w01
*/
|
||||
punpckhwd_r2r(mm1, mm2); /* 1 ; x7 x3 x6 x2
*/
|
||||
|
||||
pmaddwd_r2r(mm0, mm3); /* x4*w06+x0*w04 x4*w02+x0*w00
*/
|
||||
movq_r2r(mm2, mm6); /* 6 ; x7 x3 x6 x2
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+16), mm1);/* 1 ; w22 w20 w18 w16
*/
|
||||
punpckldq_r2r(mm2, mm2); /* x6 x2 x6 x2
*/
|
||||
|
||||
pmaddwd_r2r(mm2, mm4); /* x6*w07+x2*w05 x6*w03+x2*w01
*/
|
||||
punpckhdq_r2r(mm5, mm5); /* x5 x1 x5 x1
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+8), mm0);/* x4*w14+x0*w12 x4*w10+x0*w08
*/
|
||||
punpckhdq_r2r(mm6, mm6); /* x7 x3 x7 x3
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+20), mm7);/* 7 ; w23 w21 w19 w17
*/
|
||||
pmaddwd_r2r(mm5, mm1); /* x5*w22+x1*w20 x5*w18+x1*w16
*/
|
||||
|
||||
paddd_m2r(*(r_inv_row), mm3);/* +rounder
*/
|
||||
pmaddwd_r2r(mm6, mm7); /* x7*w23+x3*w21 x7*w19+x3*w17
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+12), mm2);/* x6*w15+x2*w13 x6*w11+x2*w09
*/
|
||||
paddd_r2r(mm4, mm3); /* 4 ; a1=sum(even1) a0=sum(even0)
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+24), mm5);/* x5*w30+x1*w28 x5*w26+x1*w24
*/
|
||||
movq_r2r(mm3, mm4); /* 4 ; a1 a0
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+28), mm6);/* x7*w31+x3*w29 x7*w27+x3*w25
*/
|
||||
paddd_r2r(mm7, mm1); /* 7 ; b1=sum(odd1) b0=sum(odd0)
*/
|
||||
|
||||
paddd_m2r(*(r_inv_row), mm0);/* +rounder
*/
|
||||
psubd_r2r(mm1, mm3); /* a1-b1 a0-b0
*/
|
||||
|
||||
psrad_i2r(SHIFT_INV_ROW, mm3); /* y6=a1-b1 y7=a0-b0
*/
|
||||
paddd_r2r(mm4, mm1); /* 4 ; a1+b1 a0+b0
*/
|
||||
|
||||
paddd_r2r(mm2, mm0); /* 2 ; a3=sum(even3) a2=sum(even2)
*/
|
||||
psrad_i2r(SHIFT_INV_ROW, mm1); /* y1=a1+b1 y0=a0+b0
*/
|
||||
|
||||
paddd_r2r(mm6, mm5); /* 6 ; b3=sum(odd3) b2=sum(odd2)
*/
|
||||
movq_r2r(mm0, mm4); /* 4 ; a3 a2
*/
|
||||
|
||||
paddd_r2r(mm5, mm0); /* a3+b3 a2+b2
*/
|
||||
psubd_r2r(mm5, mm4); /* 5 ; a3-b3 a2-b2
*/
|
||||
|
||||
psrad_i2r(SHIFT_INV_ROW, mm4); /* y4=a3-b3 y5=a2-b2
*/
|
||||
psrad_i2r(SHIFT_INV_ROW, mm0); /* y3=a3+b3 y2=a2+b2
*/
|
||||
|
||||
packssdw_r2r(mm3, mm4); /* 3 ; y6 y7 y4 y5
*/
|
||||
|
||||
packssdw_r2r(mm0, mm1); /* 0 ; y3 y2 y1 y0
*/
|
||||
movq_r2r(mm4, mm7); /* 7 ; y6 y7 y4 y5
*/
|
||||
|
||||
psrld_i2r(16, mm4); /* 0 y6 0 y4
*/
|
||||
|
||||
movq_r2m(mm1, *(out)); /* 1 ; save y3 y2 y1 y0
*/
|
||||
pslld_i2r(16, mm7); /* y7 0 y5 0
*/
|
||||
|
||||
por_r2r(mm4, mm7); /* 4 ; y7 y6 y5 y4
*/
|
||||
movq_r2r (mm0, mm5); /* 5 ; x5 x1 x4 x0
*/
|
||||
punpckldq_r2r (mm0, mm0); /* x4 x0 x4 x0
*/
|
||||
movq_m2r (*(tab_i_01234567 + 4), mm4); /* 4 ; w07 w05 w03 w01
*/
|
||||
punpckhwd_r2r (mm1, mm2); /* 1 ; x7 x3 x6 x2
*/
|
||||
pmaddwd_r2r (mm0, mm3); /* x4*w06+x0*w04 x4*w02+x0*w00
*/
|
||||
movq_r2r (mm2, mm6); /* 6 ; x7 x3 x6 x2
*/
|
||||
movq_m2r (*(tab_i_01234567 + 16), mm1); /* 1 ; w22 w20 w18 w16
*/
|
||||
punpckldq_r2r (mm2, mm2); /* x6 x2 x6 x2
*/
|
||||
pmaddwd_r2r (mm2, mm4); /* x6*w07+x2*w05 x6*w03+x2*w01
*/
|
||||
punpckhdq_r2r (mm5, mm5); /* x5 x1 x5 x1
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 8), mm0); /* x4*w14+x0*w12 x4*w10+x0*w08
*/
|
||||
punpckhdq_r2r (mm6, mm6); /* x7 x3 x7 x3
*/
|
||||
movq_m2r (*(tab_i_01234567 + 20), mm7); /* 7 ; w23 w21 w19 w17
*/
|
||||
pmaddwd_r2r (mm5, mm1); /* x5*w22+x1*w20 x5*w18+x1*w16
*/
|
||||
paddd_m2r (*(r_inv_row), mm3); /* +rounder
*/
|
||||
pmaddwd_r2r (mm6, mm7); /* x7*w23+x3*w21 x7*w19+x3*w17
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 12), mm2); /* x6*w15+x2*w13 x6*w11+x2*w09
*/
|
||||
paddd_r2r (mm4, mm3); /* 4 ; a1=sum(even1) a0=sum(even0)
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 24), mm5); /* x5*w30+x1*w28 x5*w26+x1*w24
*/
|
||||
movq_r2r (mm3, mm4); /* 4 ; a1 a0
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 28), mm6); /* x7*w31+x3*w29 x7*w27+x3*w25
*/
|
||||
paddd_r2r (mm7, mm1); /* 7 ; b1=sum(odd1) b0=sum(odd0)
*/
|
||||
paddd_m2r (*(r_inv_row), mm0); /* +rounder
*/
|
||||
psubd_r2r (mm1, mm3); /* a1-b1 a0-b0
*/
|
||||
psrad_i2r (SHIFT_INV_ROW, mm3); /* y6=a1-b1 y7=a0-b0
*/
|
||||
paddd_r2r (mm4, mm1); /* 4 ; a1+b1 a0+b0
*/
|
||||
paddd_r2r (mm2, mm0); /* 2 ; a3=sum(even3) a2=sum(even2)
*/
|
||||
psrad_i2r (SHIFT_INV_ROW, mm1); /* y1=a1+b1 y0=a0+b0
*/
|
||||
paddd_r2r (mm6, mm5); /* 6 ; b3=sum(odd3) b2=sum(odd2)
*/
|
||||
movq_r2r (mm0, mm4); /* 4 ; a3 a2
*/
|
||||
paddd_r2r (mm5, mm0); /* a3+b3 a2+b2
*/
|
||||
psubd_r2r (mm5, mm4); /* 5 ; a3-b3 a2-b2
*/
|
||||
psrad_i2r (SHIFT_INV_ROW, mm4); /* y4=a3-b3 y5=a2-b2
*/
|
||||
psrad_i2r (SHIFT_INV_ROW, mm0); /* y3=a3+b3 y2=a2+b2
*/
|
||||
packssdw_r2r (mm3, mm4); /* 3 ; y6 y7 y4 y5
*/
|
||||
packssdw_r2r (mm0, mm1); /* 0 ; y3 y2 y1 y0
*/
|
||||
movq_r2r (mm4, mm7); /* 7 ; y6 y7 y4 y5
*/
|
||||
psrld_i2r (16, mm4); /* 0 y6 0 y4
*/
|
||||
movq_r2m (mm1, *(out)); /* 1 ; save y3 y2 y1 y0
*/
|
||||
pslld_i2r (16, mm7); /* y7 0 y5 0
*/
|
||||
por_r2r (mm4, mm7); /* 4 ; y7 y6 y5 y4
*/
|
||||
|
||||
/* begin processing row 1
*/
|
||||
movq_r2m(mm7, *(out+4)); /* 7 ; save y7 y6 y5 y4
*/
|
||||
|
||||
movq_r2m (mm7, *(out + 4)); /* 7 ; save y7 y6 y5 y4
*/
|
||||
inptr += 8;
|
||||
out += 8;
|
||||
}
|
||||
|
||||
|
||||
/* done with the iDCT row-transformation
*/
|
||||
|
||||
/* now we have to transpose the output 8x8 matrix
*/
|
||||
|
@ -494,7 +468,6 @@ idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
|||
/* 3) transpose lower-left quad
*/
|
||||
/* 4) transpose upper-right quad
*/
|
||||
|
||||
|
||||
/* mm0 = 1st row [ A B C D ] row1
*/
|
||||
/* mm1 = 2nd row [ E F G H ] 2
*/
|
||||
/* mm2 = 3rd row [ I J K L ] 3
*/
|
||||
|
@ -502,47 +475,33 @@ idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
|||
|
||||
/* 1) transpose upper-left quad
*/
|
||||
out = &qwTemp[0];
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 0), mm0);
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 1), mm1);
|
||||
movq_r2r(mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 2), mm2);
|
||||
punpcklwd_r2r(mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 3), mm3);
|
||||
punpckhwd_r2r(mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
|
||||
movq_r2r(mm2, mm6);
|
||||
punpcklwd_r2r(mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
|
||||
punpckhwd_r2r(mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r(mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
|
||||
movq_m2r (*(out + ROW_STRIDE * 0), mm0);
|
||||
movq_m2r (*(out + ROW_STRIDE * 1), mm1);
|
||||
movq_r2r (mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 2), mm2);
|
||||
punpcklwd_r2r (mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 3), mm3);
|
||||
punpckhwd_r2r (mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
movq_r2r (mm2, mm6);
|
||||
punpcklwd_r2r (mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
punpckhwd_r2r (mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r (mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
inptr = blk;
|
||||
|
||||
punpckldq_r2r(mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
|
||||
movq_r2r(mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
punpckhdq_r2r(mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
|
||||
movq_r2m(mm0, *(inptr + ROW_STRIDE * 0)); /* store row 1
*/
|
||||
punpckldq_r2r(mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
punpckldq_r2r (mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
movq_r2r (mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
punpckhdq_r2r (mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
movq_r2m (mm0, *(inptr + ROW_STRIDE * 0)); /* store row 1
*/
|
||||
punpckldq_r2r (mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
|
||||
/* begin reading next quadrant (lower-right)
*/
|
||||
movq_m2r(*(out + ROW_STRIDE*4 + 4), mm0);
|
||||
punpckhdq_r2r(mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
|
||||
movq_r2m(mm4, *(inptr + ROW_STRIDE * 2)); /* store row 3
*/
|
||||
movq_r2r(mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
|
||||
movq_r2m(mm1, *(inptr + ROW_STRIDE * 1)); /* store row 2
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE*5 + 4), mm1);
|
||||
|
||||
movq_r2m(mm3, *(inptr + ROW_STRIDE * 3)); /* store row 4
*/
|
||||
punpcklwd_r2r(mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 4 + 4), mm0);
|
||||
punpckhdq_r2r (mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
movq_r2m (mm4, *(inptr + ROW_STRIDE * 2)); /* store row 3
*/
|
||||
movq_r2r (mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
movq_r2m (mm1, *(inptr + ROW_STRIDE * 1)); /* store row 2
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 5 + 4), mm1);
|
||||
movq_r2m (mm3, *(inptr + ROW_STRIDE * 3)); /* store row 4
*/
|
||||
punpcklwd_r2r (mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
|
||||
/* 2) transpose lower-right quadrant
*/
|
||||
|
||||
|
@ -550,83 +509,62 @@ idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
|||
|
||||
/* movq mm1, qword ptr [OUT + ROW_STRIDE*5 + 8]
*/
|
||||
/* movq mm4, mm0; // mm4 = copy of row1[A B C D]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 6 + 4), mm2);
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE*6 + 4), mm2);
|
||||
/* punpcklwd mm0, mm1; // mm0 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r(mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE*7 + 4), mm3);
|
||||
movq_r2r(mm2, mm6);
|
||||
|
||||
punpcklwd_r2r(mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r(mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
|
||||
punpckhwd_r2r(mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r(mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
|
||||
punpckldq_r2r(mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
|
||||
punpckhdq_r2r(mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
punpckhwd_r2r (mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 7 + 4), mm3);
|
||||
movq_r2r (mm2, mm6);
|
||||
punpcklwd_r2r (mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r (mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r (mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r (mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
punpckldq_r2r (mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
punpckhdq_r2r (mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
; /* slot
*/
|
||||
|
||||
movq_r2m(mm0, *(inptr + ROW_STRIDE*4 + 4)); /* store row 1
*/
|
||||
punpckldq_r2r(mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 4 ), mm0);
|
||||
punpckhdq_r2r(mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
|
||||
movq_r2m(mm4, *(inptr + ROW_STRIDE*6 + 4)); /* store row 3
*/
|
||||
movq_r2r(mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
|
||||
movq_r2m(mm1, *(inptr + ROW_STRIDE*5 + 4)); /* store row 2
*/
|
||||
movq_r2m (mm0, *(inptr + ROW_STRIDE * 4 + 4)); /* store row 1
*/
|
||||
punpckldq_r2r (mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 4), mm0);
|
||||
punpckhdq_r2r (mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
movq_r2m (mm4, *(inptr + ROW_STRIDE * 6 + 4)); /* store row 3
*/
|
||||
movq_r2r (mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
movq_r2m (mm1, *(inptr + ROW_STRIDE * 5 + 4)); /* store row 2
*/
|
||||
; /* slot
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 5 ), mm1);
|
||||
movq_m2r (*(out + ROW_STRIDE * 5), mm1);
|
||||
; /* slot
*/
|
||||
|
||||
movq_r2m(mm3, *(inptr + ROW_STRIDE*7 + 4)); /* store row 4
*/
|
||||
punpcklwd_r2r(mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
movq_r2m (mm3, *(inptr + ROW_STRIDE * 7 + 4)); /* store row 4
*/
|
||||
punpcklwd_r2r (mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
|
||||
/* 3) transpose lower-left
*/
|
||||
/* movq mm0, qword ptr [OUT + ROW_STRIDE * 4 ]
*/
|
||||
|
||||
/* movq mm1, qword ptr [OUT + ROW_STRIDE * 5 ]
*/
|
||||
/* movq mm4, mm0; // mm4 = copy of row1[A B C D]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 6), mm2);
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 6 ), mm2);
|
||||
/* punpcklwd mm0, mm1; // mm0 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r(mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE * 7 ), mm3);
|
||||
movq_r2r(mm2, mm6);
|
||||
|
||||
punpcklwd_r2r(mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r(mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
|
||||
punpckhwd_r2r(mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r(mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
|
||||
punpckldq_r2r(mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
|
||||
punpckhdq_r2r(mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
;/*slot
*/
|
||||
|
||||
movq_r2m(mm0, *(inptr + ROW_STRIDE * 0 + 4 )); /* store row 1
*/
|
||||
punpckldq_r2r(mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
punpckhwd_r2r (mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 7), mm3);
|
||||
movq_r2r (mm2, mm6);
|
||||
punpcklwd_r2r (mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r (mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r (mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r (mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
punpckldq_r2r (mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
punpckhdq_r2r (mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
; /*slot
*/
|
||||
movq_r2m (mm0, *(inptr + ROW_STRIDE * 0 + 4)); /* store row 1
*/
|
||||
punpckldq_r2r (mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
|
||||
/* begin reading next quadrant (upper-right)
*/
|
||||
movq_m2r(*(out + ROW_STRIDE*0 + 4), mm0);
|
||||
punpckhdq_r2r(mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
|
||||
movq_r2m(mm4, *(inptr + ROW_STRIDE * 2 + 4)); /* store row 3
*/
|
||||
movq_r2r(mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
|
||||
movq_r2m(mm1, *(inptr + ROW_STRIDE * 1 + 4)); /* store row 2
*/
|
||||
movq_m2r(*(out + ROW_STRIDE*1 + 4), mm1);
|
||||
|
||||
movq_r2m(mm3, *(inptr + ROW_STRIDE * 3 + 4)); /* store row 4
*/
|
||||
punpcklwd_r2r(mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
|
||||
movq_m2r (*(out + ROW_STRIDE * 0 + 4), mm0);
|
||||
punpckhdq_r2r (mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
movq_r2m (mm4, *(inptr + ROW_STRIDE * 2 + 4)); /* store row 3
*/
|
||||
movq_r2r (mm0, mm4); /* mm4 = copy of row1[A B C D]
*/
|
||||
movq_r2m (mm1, *(inptr + ROW_STRIDE * 1 + 4)); /* store row 2
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 1 + 4), mm1);
|
||||
movq_r2m (mm3, *(inptr + ROW_STRIDE * 3 + 4)); /* store row 4
*/
|
||||
punpcklwd_r2r (mm1, mm0); /* mm0 = [ 0 4 1 5]
*/
|
||||
|
||||
/* 2) transpose lower-right quadrant
*/
|
||||
|
||||
|
@ -634,46 +572,35 @@ idct_mmx32_rows( short *blk ) /* transform all 8 rows of 8x8 iDCT block
*/
|
|||
|
||||
/* movq mm1, qword ptr [OUT + ROW_STRIDE*5 + 8]
*/
|
||||
/* movq mm4, mm0; // mm4 = copy of row1[A B C D]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 2 + 4), mm2);
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE*2 + 4), mm2);
|
||||
/* punpcklwd mm0, mm1; // mm0 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r(mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
|
||||
movq_m2r(*(out + ROW_STRIDE*3 + 4), mm3);
|
||||
movq_r2r(mm2, mm6);
|
||||
|
||||
punpcklwd_r2r(mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r(mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
|
||||
punpckhwd_r2r(mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r(mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
|
||||
punpckldq_r2r(mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
|
||||
punpckhdq_r2r(mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
punpckhwd_r2r (mm1, mm4); /* mm4 = [ 2 6 3 7]
*/
|
||||
movq_m2r (*(out + ROW_STRIDE * 3 + 4), mm3);
|
||||
movq_r2r (mm2, mm6);
|
||||
punpcklwd_r2r (mm3, mm2); /* mm2 = [ 8 12 9 13]
*/
|
||||
movq_r2r (mm0, mm1); /* mm1 = [ 0 4 1 5]
*/
|
||||
punpckhwd_r2r (mm3, mm6); /* mm6 = 10 14 11 15]
*/
|
||||
movq_r2r (mm4, mm3); /* mm3 = [ 2 6 3 7]
*/
|
||||
punpckldq_r2r (mm2, mm0); /* final result mm0 = row1 [0 4 8 12]
*/
|
||||
punpckhdq_r2r (mm2, mm1); /* mm1 = final result mm1 = row2 [1 5 9 13]
*/
|
||||
; /* slot
*/
|
||||
|
||||
movq_r2m(mm0, *(inptr + ROW_STRIDE*4)); /* store row 1
*/
|
||||
punpckldq_r2r(mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
|
||||
movq_r2m(mm1, *(inptr + ROW_STRIDE*5)); /* store row 2
*/
|
||||
punpckhdq_r2r(mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
|
||||
movq_r2m(mm4, *(inptr + ROW_STRIDE*6)); /* store row 3
*/
|
||||
movq_r2m (mm0, *(inptr + ROW_STRIDE * 4)); /* store row 1
*/
|
||||
punpckldq_r2r (mm6, mm4); /* final result mm4 = row3 [2 6 10 14]
*/
|
||||
movq_r2m (mm1, *(inptr + ROW_STRIDE * 5)); /* store row 2
*/
|
||||
punpckhdq_r2r (mm6, mm3); /* final result mm3 = row4 [3 7 11 15]
*/
|
||||
movq_r2m (mm4, *(inptr + ROW_STRIDE * 6)); /* store row 3
*/
|
||||
; /* slot
*/
|
||||
|
||||
movq_r2m(mm3, *(inptr + ROW_STRIDE*7)); /* store row 4
*/
|
||||
movq_r2m (mm3, *(inptr + ROW_STRIDE * 7)); /* store row 4
*/
|
||||
; /* slot
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
idct_mmx32_cols( short *blk ) /* transform all 8 cols of 8x8 iDCT block
*/
|
||||
{
|
||||
}
|
||||
static void
|
||||
idct_mmx32_cols (short *blk)
|
||||
{ /* transform all 8 cols of 8x8 iDCT block
*/
|
||||
int x;
|
||||
short *inptr = blk;
|
||||
|
||||
|
||||
/* Despite the function's name, the matrix is transformed
*/
|
||||
/* row by row. This function is identical to idct_mmx32_rows(),
*/
|
||||
/* except for the SHIFT amount and ROUND_INV amount.
*/
|
||||
|
@ -685,103 +612,77 @@ idct_mmx32_cols( short *blk ) /* transform all 8 cols of 8x8 iDCT block
*/
|
|||
/*
*/
|
||||
/* 2) transpose the matrix (which was stored in qwTemp[])
*/
|
||||
/* qwTemp[] -> [8x8 matrix transpose] -> blk[]
*/
|
||||
|
||||
|
||||
for (x=0; x<8; x++) { /* transform one row per iteration
*/
|
||||
|
||||
movq_m2r(*(inptr), mm0); /* 0 ; x3 x2 x1 x0
*/
|
||||
|
||||
movq_m2r(*(inptr+4), mm1); /* 1 ; x7 x6 x5 x4
*/
|
||||
movq_r2r(mm0, mm2); /* 2 ; x3 x2 x1 x0
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567), mm3); /* 3 ; w06 w04 w02 w00
*/
|
||||
punpcklwd_r2r(mm1, mm0); /* x5 x1 x4 x0
*/
|
||||
for (x = 0; x < 8; x++) { /* transform one row per iteration
*/
|
||||
movq_m2r (*(inptr), mm0); /* 0 ; x3 x2 x1 x0
*/
|
||||
movq_m2r (*(inptr + 4), mm1); /* 1 ; x7 x6 x5 x4
*/
|
||||
movq_r2r (mm0, mm2); /* 2 ; x3 x2 x1 x0
*/
|
||||
movq_m2r (*(tab_i_01234567), mm3); /* 3 ; w06 w04 w02 w00
*/
|
||||
punpcklwd_r2r (mm1, mm0); /* x5 x1 x4 x0
*/
|
||||
|
||||
/* ----------
*/
|
||||
movq_r2r(mm0, mm5); /* 5 ; x5 x1 x4 x0
*/
|
||||
punpckldq_r2r(mm0, mm0); /* x4 x0 x4 x0
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+4), mm4); /* 4 ; w07 w05 w03 w01
*/
|
||||
punpckhwd_r2r(mm1, mm2); /* 1 ; x7 x3 x6 x2
*/
|
||||
|
||||
pmaddwd_r2r(mm0, mm3); /* x4*w06+x0*w04 x4*w02+x0*w00
*/
|
||||
movq_r2r(mm2, mm6); /* 6 ; x7 x3 x6 x2
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+16), mm1);/* 1 ; w22 w20 w18 w16
*/
|
||||
punpckldq_r2r(mm2, mm2); /* x6 x2 x6 x2
*/
|
||||
|
||||
pmaddwd_r2r(mm2, mm4); /* x6*w07+x2*w05 x6*w03+x2*w01
*/
|
||||
punpckhdq_r2r(mm5, mm5); /* x5 x1 x5 x1
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+8), mm0);/* x4*w14+x0*w12 x4*w10+x0*w08
*/
|
||||
punpckhdq_r2r(mm6, mm6); /* x7 x3 x7 x3
*/
|
||||
|
||||
movq_m2r(*(tab_i_01234567+20), mm7);/* 7 ; w23 w21 w19 w17
*/
|
||||
pmaddwd_r2r(mm5, mm1); /* x5*w22+x1*w20 x5*w18+x1*w16
*/
|
||||
|
||||
paddd_m2r(*(r_inv_col), mm3);/* +rounder
*/
|
||||
pmaddwd_r2r(mm6, mm7); /* x7*w23+x3*w21 x7*w19+x3*w17
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+12), mm2);/* x6*w15+x2*w13 x6*w11+x2*w09
*/
|
||||
paddd_r2r(mm4, mm3); /* 4 ; a1=sum(even1) a0=sum(even0)
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+24), mm5);/* x5*w30+x1*w28 x5*w26+x1*w24
*/
|
||||
movq_r2r(mm3, mm4); /* 4 ; a1 a0
*/
|
||||
|
||||
pmaddwd_m2r(*(tab_i_01234567+28), mm6);/* x7*w31+x3*w29 x7*w27+x3*w25
*/
|
||||
paddd_r2r(mm7, mm1); /* 7 ; b1=sum(odd1) b0=sum(odd0)
*/
|
||||
|
||||
paddd_m2r(*(r_inv_col), mm0);/* +rounder
*/
|
||||
psubd_r2r(mm1, mm3); /* a1-b1 a0-b0
*/
|
||||
|
||||
psrad_i2r(SHIFT_INV_COL, mm3); /* y6=a1-b1 y7=a0-b0
*/
|
||||
paddd_r2r(mm4, mm1); /* 4 ; a1+b1 a0+b0
*/
|
||||
|
||||
paddd_r2r(mm2, mm0); /* 2 ; a3=sum(even3) a2=sum(even2)
*/
|
||||
psrad_i2r(SHIFT_INV_COL, mm1); /* y1=a1+b1 y0=a0+b0
*/
|
||||
|
||||
paddd_r2r(mm6, mm5); /* 6 ; b3=sum(odd3) b2=sum(odd2)
*/
|
||||
movq_r2r(mm0, mm4); /* 4 ; a3 a2
*/
|
||||
|
||||
paddd_r2r(mm5, mm0); /* a3+b3 a2+b2
*/
|
||||
psubd_r2r(mm5, mm4); /* 5 ; a3-b3 a2-b2
*/
|
||||
|
||||
|
||||
psrad_i2r(SHIFT_INV_COL, mm4); /* y4=a3-b3 y5=a2-b2
*/
|
||||
psrad_i2r(SHIFT_INV_COL, mm0); /* y3=a3+b3 y2=a2+b2
*/
|
||||
|
||||
packssdw_r2r(mm3, mm4); /* 3 ; y6 y7 y4 y5
*/
|
||||
|
||||
packssdw_r2r(mm0, mm1); /* 0 ; y3 y2 y1 y0
*/
|
||||
movq_r2r(mm4, mm7); /* 7 ; y6 y7 y4 y5
*/
|
||||
|
||||
psrld_i2r(16, mm4); /* 0 y6 0 y4
*/
|
||||
|
||||
movq_r2m(mm1, *(inptr)); /* 1 ; save y3 y2 y1 y0
*/
|
||||
pslld_i2r(16, mm7); /* y7 0 y5 0
*/
|
||||
|
||||
por_r2r(mm4, mm7); /* 4 ; y7 y6 y5 y4
*/
|
||||
movq_r2r (mm0, mm5); /* 5 ; x5 x1 x4 x0
*/
|
||||
punpckldq_r2r (mm0, mm0); /* x4 x0 x4 x0
*/
|
||||
movq_m2r (*(tab_i_01234567 + 4), mm4); /* 4 ; w07 w05 w03 w01
*/
|
||||
punpckhwd_r2r (mm1, mm2); /* 1 ; x7 x3 x6 x2
*/
|
||||
pmaddwd_r2r (mm0, mm3); /* x4*w06+x0*w04 x4*w02+x0*w00
*/
|
||||
movq_r2r (mm2, mm6); /* 6 ; x7 x3 x6 x2
*/
|
||||
movq_m2r (*(tab_i_01234567 + 16), mm1); /* 1 ; w22 w20 w18 w16
*/
|
||||
punpckldq_r2r (mm2, mm2); /* x6 x2 x6 x2
*/
|
||||
pmaddwd_r2r (mm2, mm4); /* x6*w07+x2*w05 x6*w03+x2*w01
*/
|
||||
punpckhdq_r2r (mm5, mm5); /* x5 x1 x5 x1
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 8), mm0); /* x4*w14+x0*w12 x4*w10+x0*w08
*/
|
||||
punpckhdq_r2r (mm6, mm6); /* x7 x3 x7 x3
*/
|
||||
movq_m2r (*(tab_i_01234567 + 20), mm7); /* 7 ; w23 w21 w19 w17
*/
|
||||
pmaddwd_r2r (mm5, mm1); /* x5*w22+x1*w20 x5*w18+x1*w16
*/
|
||||
paddd_m2r (*(r_inv_col), mm3); /* +rounder
*/
|
||||
pmaddwd_r2r (mm6, mm7); /* x7*w23+x3*w21 x7*w19+x3*w17
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 12), mm2); /* x6*w15+x2*w13 x6*w11+x2*w09
*/
|
||||
paddd_r2r (mm4, mm3); /* 4 ; a1=sum(even1) a0=sum(even0)
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 24), mm5); /* x5*w30+x1*w28 x5*w26+x1*w24
*/
|
||||
movq_r2r (mm3, mm4); /* 4 ; a1 a0
*/
|
||||
pmaddwd_m2r (*(tab_i_01234567 + 28), mm6); /* x7*w31+x3*w29 x7*w27+x3*w25
*/
|
||||
paddd_r2r (mm7, mm1); /* 7 ; b1=sum(odd1) b0=sum(odd0)
*/
|
||||
paddd_m2r (*(r_inv_col), mm0); /* +rounder
*/
|
||||
psubd_r2r (mm1, mm3); /* a1-b1 a0-b0
*/
|
||||
psrad_i2r (SHIFT_INV_COL, mm3); /* y6=a1-b1 y7=a0-b0
*/
|
||||
paddd_r2r (mm4, mm1); /* 4 ; a1+b1 a0+b0
*/
|
||||
paddd_r2r (mm2, mm0); /* 2 ; a3=sum(even3) a2=sum(even2)
*/
|
||||
psrad_i2r (SHIFT_INV_COL, mm1); /* y1=a1+b1 y0=a0+b0
*/
|
||||
paddd_r2r (mm6, mm5); /* 6 ; b3=sum(odd3) b2=sum(odd2)
*/
|
||||
movq_r2r (mm0, mm4); /* 4 ; a3 a2
*/
|
||||
paddd_r2r (mm5, mm0); /* a3+b3 a2+b2
*/
|
||||
psubd_r2r (mm5, mm4); /* 5 ; a3-b3 a2-b2
*/
|
||||
psrad_i2r (SHIFT_INV_COL, mm4); /* y4=a3-b3 y5=a2-b2
*/
|
||||
psrad_i2r (SHIFT_INV_COL, mm0); /* y3=a3+b3 y2=a2+b2
*/
|
||||
packssdw_r2r (mm3, mm4); /* 3 ; y6 y7 y4 y5
*/
|
||||
packssdw_r2r (mm0, mm1); /* 0 ; y3 y2 y1 y0
*/
|
||||
movq_r2r (mm4, mm7); /* 7 ; y6 y7 y4 y5
*/
|
||||
psrld_i2r (16, mm4); /* 0 y6 0 y4
*/
|
||||
movq_r2m (mm1, *(inptr)); /* 1 ; save y3 y2 y1 y0
*/
|
||||
pslld_i2r (16, mm7); /* y7 0 y5 0
*/
|
||||
por_r2r (mm4, mm7); /* 4 ; y7 y6 y5 y4
*/
|
||||
|
||||
/* begin processing row 1
*/
|
||||
movq_r2m(mm7, *(inptr+4)); /* 7 ; save y7 y6 y5 y4
*/
|
||||
|
||||
movq_r2m (mm7, *(inptr + 4)); /* 7 ; save y7 y6 y5 y4
*/
|
||||
inptr += 8;
|
||||
}
|
||||
|
||||
/* done with the iDCT column-transformation
*/
|
||||
}
|
||||
|
||||
|
||||
/*
*/
|
||||
/* public interface to MMX32 IDCT 8x8 operation
*/
|
||||
/*
*/
|
||||
void
|
||||
gst_idct_mmx32_idct( short *blk )
|
||||
gst_idct_mmx32_idct (short *blk)
|
||||
{
|
||||
|
||||
/* 1) iDCT row transformation
*/
|
||||
idct_mmx32_rows( blk ); /* 1) transform iDCT row, and transpose
*/
|
||||
idct_mmx32_rows (blk); /* 1) transform iDCT row, and transpose
*/
|
||||
|
||||
/* 2) iDCT column transformation
*/
|
||||
idct_mmx32_cols( blk ); /* 2) transform iDCT row, and transpose
*/
|
||||
|
||||
emms(); /* restore processor state
*/
|
||||
idct_mmx32_cols (blk); /* 2) transform iDCT row, and transpose
*/
|
||||
emms (); /* restore processor state
*/
|
||||
/* all done
*/
|
||||
}
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
#include "colorbalance.h"
|
||||
#include "colorbalance-marshal.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
VALUE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_color_balance_class_init (GstColorBalanceClass *klass);
|
||||
static void gst_color_balance_class_init (GstColorBalanceClass * klass);
|
||||
|
||||
static guint gst_color_balance_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -55,8 +56,7 @@ gst_color_balance_get_type (void)
|
|||
};
|
||||
|
||||
gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstColorBalance",
|
||||
&gst_color_balance_info, 0);
|
||||
"GstColorBalance", &gst_color_balance_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_color_balance_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ gst_color_balance_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_class_init (GstColorBalanceClass *klass)
|
||||
gst_color_balance_class_init (GstColorBalanceClass * klass)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
@ -76,8 +76,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
|
|||
G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
|
||||
NULL, NULL,
|
||||
gst_color_balance_marshal_VOID__OBJECT_INT,
|
||||
G_TYPE_NONE, 2,
|
||||
GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
|
||||
G_TYPE_NONE, 2, GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
@ -91,7 +90,7 @@ gst_color_balance_class_init (GstColorBalanceClass *klass)
|
|||
}
|
||||
|
||||
const GList *
|
||||
gst_color_balance_list_channels (GstColorBalance *balance)
|
||||
gst_color_balance_list_channels (GstColorBalance * balance)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -103,9 +102,8 @@ gst_color_balance_list_channels (GstColorBalance *balance)
|
|||
}
|
||||
|
||||
void
|
||||
gst_color_balance_set_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value)
|
||||
gst_color_balance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -115,8 +113,8 @@ gst_color_balance_set_value (GstColorBalance *balance,
|
|||
}
|
||||
|
||||
gint
|
||||
gst_color_balance_get_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel)
|
||||
gst_color_balance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel)
|
||||
{
|
||||
GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance);
|
||||
|
||||
|
@ -128,13 +126,11 @@ gst_color_balance_get_value (GstColorBalance *balance,
|
|||
}
|
||||
|
||||
void
|
||||
gst_color_balance_value_changed (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value)
|
||||
gst_color_balance_value_changed (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (balance),
|
||||
gst_color_balance_signals[VALUE_CHANGED],
|
||||
0, channel, value);
|
||||
gst_color_balance_signals[VALUE_CHANGED], 0, channel, value);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <gst/colorbalance/colorbalance-enumtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_COLOR_BALANCE \
|
||||
(gst_color_balance_get_type ())
|
||||
#define GST_COLOR_BALANCE(obj) \
|
||||
|
@ -42,9 +41,7 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE))
|
||||
#define GST_COLOR_BALANCE_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass))
|
||||
|
||||
#define GST_COLOR_BALANCE_TYPE(klass) (klass->balance_type)
|
||||
|
||||
typedef struct _GstColorBalance GstColorBalance;
|
||||
|
||||
typedef enum
|
||||
|
@ -53,24 +50,23 @@ typedef enum
|
|||
GST_COLOR_BALANCE_SOFTWARE
|
||||
} GstColorBalanceType;
|
||||
|
||||
typedef struct _GstColorBalanceClass {
|
||||
typedef struct _GstColorBalanceClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
GstColorBalanceType balance_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_channels) (GstColorBalance *balance);
|
||||
const GList *(*list_channels) (GstColorBalance * balance);
|
||||
|
||||
void (* set_value) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
gint (* get_value) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel);
|
||||
void (*set_value) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
gint (*get_value) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel);
|
||||
|
||||
/* signals */
|
||||
void (* value_changed) (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void (*value_changed) (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstColorBalanceClass;
|
||||
|
@ -78,19 +74,15 @@ typedef struct _GstColorBalanceClass {
|
|||
GType gst_color_balance_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList *
|
||||
gst_color_balance_list_channels (GstColorBalance *balance);
|
||||
void gst_color_balance_set_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
gint gst_color_balance_get_value (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel);
|
||||
const GList *gst_color_balance_list_channels (GstColorBalance * balance);
|
||||
void gst_color_balance_set_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
gint gst_color_balance_get_value (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel);
|
||||
|
||||
/* trigger signal */
|
||||
void gst_color_balance_value_changed (GstColorBalance *balance,
|
||||
GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void gst_color_balance_value_changed (GstColorBalance * balance,
|
||||
GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_COLOR_BALANCE_H__ */
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
|
||||
#include "colorbalancechannel.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_VALUE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass);
|
||||
static void gst_color_balance_channel_init (GstColorBalanceChannel *balance);
|
||||
static void gst_color_balance_channel_dispose (GObject *object);
|
||||
static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *
|
||||
klass);
|
||||
static void gst_color_balance_channel_init (GstColorBalanceChannel * balance);
|
||||
static void gst_color_balance_channel_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -59,15 +61,14 @@ gst_color_balance_channel_get_type (void)
|
|||
|
||||
gst_color_balance_channel_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstColorBalanceChannel",
|
||||
&color_balance_channel_info, 0);
|
||||
"GstColorBalanceChannel", &color_balance_channel_info, 0);
|
||||
}
|
||||
|
||||
return gst_color_balance_channel_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
|
||||
gst_color_balance_channel_class_init (GstColorBalanceChannelClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -78,21 +79,20 @@ gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass)
|
|||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstColorBalanceChannelClass,
|
||||
value_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
object_klass->dispose = gst_color_balance_channel_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_init (GstColorBalanceChannel *channel)
|
||||
gst_color_balance_channel_init (GstColorBalanceChannel * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->min_value = channel->max_value = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_color_balance_channel_dispose (GObject *object)
|
||||
gst_color_balance_channel_dispose (GObject * object)
|
||||
{
|
||||
GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_COLOR_BALANCE_CHANNEL \
|
||||
(gst_color_balance_channel_get_type ())
|
||||
#define GST_COLOR_BALANCE_CHANNEL(obj) \
|
||||
|
@ -38,21 +37,20 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL))
|
||||
#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL))
|
||||
|
||||
typedef struct _GstColorBalanceChannel {
|
||||
typedef struct _GstColorBalanceChannel
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
gint min_value,
|
||||
max_value;
|
||||
gint min_value, max_value;
|
||||
} GstColorBalanceChannel;
|
||||
|
||||
typedef struct _GstColorBalanceChannelClass {
|
||||
typedef struct _GstColorBalanceChannelClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* signals */
|
||||
void (* value_changed) (GstColorBalanceChannel *channel,
|
||||
gint value);
|
||||
void (*value_changed) (GstColorBalanceChannel * channel, gint value);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstColorBalanceChannelClass;
|
||||
|
@ -60,5 +58,4 @@ typedef struct _GstColorBalanceChannelClass {
|
|||
GType gst_color_balance_channel_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */
|
||||
|
|
|
@ -26,14 +26,15 @@
|
|||
#include "mixer.h"
|
||||
#include "mixer-marshal.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
MUTE_TOGGLED,
|
||||
RECORD_TOGGLED,
|
||||
VOLUME_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_mixer_class_init (GstMixerClass *klass);
|
||||
static void gst_mixer_class_init (GstMixerClass * klass);
|
||||
|
||||
static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -56,8 +57,7 @@ gst_mixer_get_type (void)
|
|||
};
|
||||
|
||||
gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstMixer",
|
||||
&gst_mixer_info, 0);
|
||||
"GstMixer", &gst_mixer_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_mixer_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ gst_mixer_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_class_init (GstMixerClass *klass)
|
||||
gst_mixer_class_init (GstMixerClass * klass)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
@ -119,7 +119,7 @@ gst_mixer_class_init (GstMixerClass *klass)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_mixer_list_tracks (GstMixer *mixer)
|
||||
gst_mixer_list_tracks (GstMixer * mixer)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -146,9 +146,7 @@ gst_mixer_list_tracks (GstMixer *mixer)
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -169,9 +167,7 @@ gst_mixer_set_volume (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_get_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -198,9 +194,7 @@ gst_mixer_get_volume (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_mute (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute)
|
||||
gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -223,9 +217,7 @@ gst_mixer_set_mute (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_record (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record)
|
||||
gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -235,43 +227,30 @@ gst_mixer_set_record (GstMixer *mixer,
|
|||
}
|
||||
|
||||
void
|
||||
gst_mixer_mute_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute)
|
||||
gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[MUTE_TOGGLED], 0,
|
||||
track, mute);
|
||||
gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"mute_toggled",
|
||||
mute);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
|
||||
}
|
||||
|
||||
void
|
||||
gst_mixer_record_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record)
|
||||
gst_mixer_record_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[RECORD_TOGGLED], 0,
|
||||
track, record);
|
||||
gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"record_toggled",
|
||||
record);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
|
||||
}
|
||||
|
||||
void
|
||||
gst_mixer_volume_changed (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_volume_changed (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[VOLUME_CHANGED], 0,
|
||||
track, volumes);
|
||||
gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"volume_changed",
|
||||
volumes);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <gst/mixer/mixer-enumtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIXER \
|
||||
(gst_mixer_get_type ())
|
||||
#define GST_MIXER(obj) \
|
||||
|
@ -40,9 +39,7 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
|
||||
#define GST_MIXER_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass))
|
||||
|
||||
#define GST_MIXER_TYPE(klass) (klass->mixer_type)
|
||||
|
||||
typedef struct _GstMixer GstMixer;
|
||||
|
||||
typedef enum
|
||||
|
@ -51,38 +48,28 @@ typedef enum
|
|||
GST_MIXER_SOFTWARE
|
||||
} GstMixerType;
|
||||
|
||||
typedef struct _GstMixerClass {
|
||||
typedef struct _GstMixerClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
GstMixerType mixer_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_tracks) (GstMixer *mixer);
|
||||
const GList *(*list_tracks) (GstMixer * mixer);
|
||||
|
||||
void (* set_volume) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void (* get_volume) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void (*set_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
|
||||
void (*get_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
|
||||
|
||||
void (* set_mute) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void (* set_record) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
void (*set_mute) (GstMixer * mixer, GstMixerTrack * track, gboolean mute);
|
||||
void (*set_record) (GstMixer * mixer, GstMixerTrack * track, gboolean record);
|
||||
|
||||
/* signals */
|
||||
void (* mute_toggled) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gboolean mute);
|
||||
void (* record_toggled) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gboolean record);
|
||||
void (* volume_changed) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gint *volumes);
|
||||
void (*mute_toggled) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gboolean mute);
|
||||
void (*record_toggled) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gboolean record);
|
||||
void (*volume_changed) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gint * volumes);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstMixerClass;
|
||||
|
@ -90,31 +77,23 @@ typedef struct _GstMixerClass {
|
|||
GType gst_mixer_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList * gst_mixer_list_tracks (GstMixer *mixer);
|
||||
void gst_mixer_set_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_get_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_set_mute (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void gst_mixer_set_record (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
const GList *gst_mixer_list_tracks (GstMixer * mixer);
|
||||
void gst_mixer_set_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_mixer_get_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_mixer_set_mute (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
void gst_mixer_set_record (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record);
|
||||
|
||||
/* trigger signals */
|
||||
void gst_mixer_mute_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void gst_mixer_record_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
void gst_mixer_volume_changed (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_mute_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
void gst_mixer_record_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record);
|
||||
void gst_mixer_volume_changed (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIXER_H__ */
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
#include "mixertrack.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_VOLUME_CHANGED,
|
||||
SIGNAL_RECORD_TOGGLED,
|
||||
|
@ -33,9 +34,9 @@ enum {
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_mixer_track_class_init (GstMixerTrackClass *klass);
|
||||
static void gst_mixer_track_init (GstMixerTrack *mixer);
|
||||
static void gst_mixer_track_dispose (GObject *object);
|
||||
static void gst_mixer_track_class_init (GstMixerTrackClass * klass);
|
||||
static void gst_mixer_track_init (GstMixerTrack * mixer);
|
||||
static void gst_mixer_track_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -61,15 +62,14 @@ gst_mixer_track_get_type (void)
|
|||
|
||||
gst_mixer_track_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstMixerTrack",
|
||||
&mixer_track_info, 0);
|
||||
"GstMixerTrack", &mixer_track_info, 0);
|
||||
}
|
||||
|
||||
return gst_mixer_track_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_class_init (GstMixerTrackClass *klass)
|
||||
gst_mixer_track_class_init (GstMixerTrackClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -101,7 +101,7 @@ gst_mixer_track_class_init (GstMixerTrackClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_init (GstMixerTrack *channel)
|
||||
gst_mixer_track_init (GstMixerTrack * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->min_volume = channel->max_volume = 0;
|
||||
|
@ -110,7 +110,7 @@ gst_mixer_track_init (GstMixerTrack *channel)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_dispose (GObject *object)
|
||||
gst_mixer_track_dispose (GObject * object)
|
||||
{
|
||||
GstMixerTrack *channel = GST_MIXER_TRACK (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIXER_TRACK \
|
||||
(gst_mixer_track_get_type ())
|
||||
#define GST_MIXER_TRACK(obj) \
|
||||
|
@ -38,7 +37,6 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK))
|
||||
#define GST_IS_MIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK))
|
||||
|
||||
/*
|
||||
* Naming:
|
||||
*
|
||||
|
@ -54,39 +52,36 @@ G_BEGIN_DECLS
|
|||
* mixer, which means that setting this track will change
|
||||
* the hearable volume on any output.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
GST_MIXER_TRACK_INPUT = (1<<0),
|
||||
GST_MIXER_TRACK_OUTPUT = (1<<1),
|
||||
GST_MIXER_TRACK_MUTE = (1<<2),
|
||||
GST_MIXER_TRACK_RECORD = (1<<3),
|
||||
GST_MIXER_TRACK_MASTER = (1<<4),
|
||||
GST_MIXER_TRACK_SOFTWARE = (1<<5)
|
||||
typedef enum
|
||||
{
|
||||
GST_MIXER_TRACK_INPUT = (1 << 0),
|
||||
GST_MIXER_TRACK_OUTPUT = (1 << 1),
|
||||
GST_MIXER_TRACK_MUTE = (1 << 2),
|
||||
GST_MIXER_TRACK_RECORD = (1 << 3),
|
||||
GST_MIXER_TRACK_MASTER = (1 << 4),
|
||||
GST_MIXER_TRACK_SOFTWARE = (1 << 5)
|
||||
} GstMixerTrackFlags;
|
||||
|
||||
#define GST_MIXER_TRACK_HAS_FLAG(channel, flag) \
|
||||
((channel)->flags & flag)
|
||||
|
||||
typedef struct _GstMixerTrack {
|
||||
typedef struct _GstMixerTrack
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
GstMixerTrackFlags flags;
|
||||
gint num_channels,
|
||||
min_volume,
|
||||
max_volume;
|
||||
gint num_channels, min_volume, max_volume;
|
||||
} GstMixerTrack;
|
||||
|
||||
typedef struct _GstMixerTrackClass {
|
||||
typedef struct _GstMixerTrackClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* signals */
|
||||
void (* mute_toggled) (GstMixerTrack *channel,
|
||||
gboolean mute);
|
||||
void (* record_toggled) (GstMixerTrack *channel,
|
||||
gboolean record);
|
||||
void (* volume_changed) (GstMixerTrack *channel,
|
||||
gint *volumes);
|
||||
void (*mute_toggled) (GstMixerTrack * channel, gboolean mute);
|
||||
void (*record_toggled) (GstMixerTrack * channel, gboolean record);
|
||||
void (*volume_changed) (GstMixerTrack * channel, gint * volumes);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstMixerTrackClass;
|
||||
|
@ -94,5 +89,4 @@ typedef struct _GstMixerTrackClass {
|
|||
GType gst_mixer_track_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIXER_TRACK_H__ */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <gst/navigation/navigation.h>
|
||||
|
||||
static void gst_navigation_class_init (GstNavigationInterface *iface);
|
||||
static void gst_navigation_class_init (GstNavigationInterface * iface);
|
||||
|
||||
GType
|
||||
gst_navigation_get_type (void)
|
||||
|
@ -46,22 +46,21 @@ gst_navigation_get_type (void)
|
|||
};
|
||||
|
||||
gst_navigation_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstNavigation",
|
||||
&gst_navigation_info, 0);
|
||||
"GstNavigation", &gst_navigation_info, 0);
|
||||
}
|
||||
|
||||
return gst_navigation_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_navigation_class_init (GstNavigationInterface *iface)
|
||||
gst_navigation_class_init (GstNavigationInterface * iface)
|
||||
{
|
||||
/* default virtual functions */
|
||||
iface->send_event = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
|
||||
gst_navigation_send_event (GstNavigation * navigation, GstStructure * structure)
|
||||
{
|
||||
GstNavigationInterface *iface = GST_NAVIGATION_GET_IFACE (navigation);
|
||||
|
||||
|
@ -71,25 +70,20 @@ gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
|
|||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_key_event (GstNavigation *navigation, const char *event,
|
||||
gst_navigation_send_key_event (GstNavigation * navigation, const char *event,
|
||||
const char *key)
|
||||
{
|
||||
gst_navigation_send_event (navigation, gst_structure_new (
|
||||
"application/x-gst-navigation",
|
||||
"event", G_TYPE_STRING, event,
|
||||
"key", G_TYPE_STRING, key, NULL));
|
||||
gst_navigation_send_event (navigation,
|
||||
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
|
||||
event, "key", G_TYPE_STRING, key, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_mouse_event (GstNavigation *navigation, const char *event,
|
||||
gst_navigation_send_mouse_event (GstNavigation * navigation, const char *event,
|
||||
int button, double x, double y)
|
||||
{
|
||||
gst_navigation_send_event (navigation, gst_structure_new (
|
||||
"application/x-gst-navigation",
|
||||
"event", G_TYPE_STRING, event,
|
||||
"button", G_TYPE_INT, button,
|
||||
"pointer_x", G_TYPE_DOUBLE, x,
|
||||
gst_navigation_send_event (navigation,
|
||||
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
|
||||
event, "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x,
|
||||
"pointer_y", G_TYPE_DOUBLE, y, NULL));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_NAVIGATION \
|
||||
(gst_navigation_get_type ())
|
||||
#define GST_NAVIGATION(obj) \
|
||||
|
@ -35,14 +34,14 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION))
|
||||
#define GST_NAVIGATION_GET_IFACE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface))
|
||||
|
||||
typedef struct _GstNavigation GstNavigation;
|
||||
|
||||
typedef struct _GstNavigationInterface {
|
||||
typedef struct _GstNavigationInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* virtual functions */
|
||||
void (*send_event) (GstNavigation *navigation, GstStructure *structure);
|
||||
void (*send_event) (GstNavigation * navigation, GstStructure * structure);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstNavigationInterface;
|
||||
|
@ -50,13 +49,13 @@ typedef struct _GstNavigationInterface {
|
|||
GType gst_navigation_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
void gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure);
|
||||
void gst_navigation_send_event (GstNavigation * navigation,
|
||||
GstStructure * structure);
|
||||
|
||||
void gst_navigation_send_key_event (GstNavigation *navigation,
|
||||
void gst_navigation_send_key_event (GstNavigation * navigation,
|
||||
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);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_NAVIGATION_H__ */
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
|
||||
#include "propertyprobe.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
SIGNAL_PROBE_NEEDED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_property_probe_iface_init (GstPropertyProbeInterface *iface);
|
||||
static void gst_property_probe_iface_init (GstPropertyProbeInterface * iface);
|
||||
|
||||
static guint gst_property_probe_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -56,23 +57,22 @@ gst_property_probe_get_type (void)
|
|||
|
||||
gst_property_probe_type =
|
||||
g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstPropertyProbe",
|
||||
&gst_property_probe_info, 0);
|
||||
"GstPropertyProbe", &gst_property_probe_info, 0);
|
||||
}
|
||||
|
||||
return gst_property_probe_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
|
||||
gst_property_probe_iface_init (GstPropertyProbeInterface * iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized) {
|
||||
gst_property_probe_signals[SIGNAL_PROBE_NEEDED] =
|
||||
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstPropertyProbeInterface, probe_needed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPropertyProbeInterface,
|
||||
probe_needed), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_property_probe_get_properties (GstPropertyProbe *probe)
|
||||
gst_property_probe_get_properties (GstPropertyProbe * probe)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -108,8 +108,7 @@ gst_property_probe_get_properties (GstPropertyProbe *probe)
|
|||
}
|
||||
|
||||
const GParamSpec *
|
||||
gst_property_probe_get_property (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_get_property (GstPropertyProbe * probe, const gchar * name)
|
||||
{
|
||||
const GList *pspecs = gst_property_probe_get_properties (probe);
|
||||
|
||||
|
@ -129,8 +128,8 @@ gst_property_probe_get_property (GstPropertyProbe *probe,
|
|||
}
|
||||
|
||||
void
|
||||
gst_property_probe_probe_property (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_probe_property (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -156,8 +155,8 @@ gst_property_probe_probe_property (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_probe_property_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -188,8 +187,8 @@ gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
gboolean
|
||||
gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_needs_probe (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -215,8 +214,8 @@ gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
gboolean
|
||||
gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -244,8 +243,8 @@ gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -271,8 +270,8 @@ gst_property_probe_get_values (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -301,8 +300,8 @@ gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -328,8 +327,8 @@ gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_probe_and_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_PROPERTY_PROBE \
|
||||
(gst_property_probe_get_type ())
|
||||
#define GST_PROPERTY_PROBE(obj) \
|
||||
|
@ -34,27 +33,23 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROPERTY_PROBE))
|
||||
#define GST_PROPERTY_PROBE_GET_IFACE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_PROPERTY_PROBE, GstPropertyProbeInterface))
|
||||
|
||||
typedef struct _GstPropertyProbe GstPropertyProbe; /* dummy typedef */
|
||||
|
||||
typedef struct _GstPropertyProbeInterface {
|
||||
typedef struct _GstPropertyProbeInterface
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
/* signals */
|
||||
void (*probe_needed) (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
void (*probe_needed) (GstPropertyProbe * probe, const GParamSpec * pspec);
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (*get_properties) (GstPropertyProbe *probe);
|
||||
gboolean (*needs_probe) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
void (*probe_property) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * (*get_values) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
const GList *(*get_properties) (GstPropertyProbe * probe);
|
||||
gboolean (*needs_probe) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
void (*probe_property) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
GValueArray *(*get_values) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstPropertyProbeInterface;
|
||||
|
@ -64,34 +59,33 @@ GType gst_property_probe_get_type (void);
|
|||
/* virtual class function wrappers */
|
||||
|
||||
/* returns list of GParamSpecs */
|
||||
const GList * gst_property_probe_get_properties (GstPropertyProbe *probe);
|
||||
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
const GList *gst_property_probe_get_properties (GstPropertyProbe * probe);
|
||||
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* probe one property */
|
||||
void gst_property_probe_probe_property (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
void gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
void gst_property_probe_probe_property (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
void gst_property_probe_probe_property_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* do we need a probe? */
|
||||
gboolean gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
gboolean gst_property_probe_needs_probe (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* returns list of GValues */
|
||||
GValueArray * gst_property_probe_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
GValueArray *gst_property_probe_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
GValueArray *gst_property_probe_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* sugar */
|
||||
GValueArray * gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
GValueArray *gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
GValueArray *gst_property_probe_probe_and_get_values_name (GstPropertyProbe *
|
||||
probe, const gchar * name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PROPERTY_PROBE_H__ */
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
NORM_CHANGED,
|
||||
CHANNEL_CHANGED,
|
||||
FREQUENCY_CHANGED,
|
||||
|
@ -36,7 +37,7 @@ enum {
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_class_init (GstTunerClass *klass);
|
||||
static void gst_tuner_class_init (GstTunerClass * klass);
|
||||
|
||||
static guint gst_tuner_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -59,8 +60,7 @@ gst_tuner_get_type (void)
|
|||
};
|
||||
|
||||
gst_tuner_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstTuner",
|
||||
&gst_tuner_info, 0);
|
||||
"GstTuner", &gst_tuner_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_tuner_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ gst_tuner_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_tuner_class_init (GstTunerClass *klass)
|
||||
gst_tuner_class_init (GstTunerClass * klass)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
@ -79,8 +79,7 @@ gst_tuner_class_init (GstTunerClass *klass)
|
|||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerClass, norm_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
|
||||
GST_TYPE_TUNER_NORM);
|
||||
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_TUNER_NORM);
|
||||
gst_tuner_signals[CHANNEL_CHANGED] =
|
||||
g_signal_new ("channel-changed",
|
||||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
|
@ -131,7 +130,7 @@ gst_tuner_class_init (GstTunerClass *klass)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_tuner_list_channels (GstTuner *tuner)
|
||||
gst_tuner_list_channels (GstTuner * tuner)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -151,8 +150,7 @@ gst_tuner_list_channels (GstTuner *tuner)
|
|||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_channel (GstTuner *tuner,
|
||||
GstTunerChannel *channel)
|
||||
gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -171,7 +169,7 @@ gst_tuner_set_channel (GstTuner *tuner,
|
|||
*/
|
||||
|
||||
GstTunerChannel *
|
||||
gst_tuner_get_channel (GstTuner *tuner)
|
||||
gst_tuner_get_channel (GstTuner * tuner)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -194,7 +192,7 @@ gst_tuner_get_channel (GstTuner *tuner)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_tuner_list_norms (GstTuner *tuner)
|
||||
gst_tuner_list_norms (GstTuner * tuner)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -214,8 +212,7 @@ gst_tuner_list_norms (GstTuner *tuner)
|
|||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_norm (GstTuner *tuner,
|
||||
GstTunerNorm *norm)
|
||||
gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -235,7 +232,7 @@ gst_tuner_set_norm (GstTuner *tuner,
|
|||
*/
|
||||
|
||||
GstTunerNorm *
|
||||
gst_tuner_get_norm (GstTuner *tuner)
|
||||
gst_tuner_get_norm (GstTuner * tuner)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -259,9 +256,8 @@ gst_tuner_get_norm (GstTuner *tuner)
|
|||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency)
|
||||
gst_tuner_set_frequency (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -285,8 +281,7 @@ gst_tuner_set_frequency (GstTuner *tuner,
|
|||
*/
|
||||
|
||||
gulong
|
||||
gst_tuner_get_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel)
|
||||
gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -315,8 +310,7 @@ gst_tuner_get_frequency (GstTuner *tuner,
|
|||
*/
|
||||
|
||||
gint
|
||||
gst_tuner_signal_strength (GstTuner *tuner,
|
||||
GstTunerChannel *channel)
|
||||
gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner);
|
||||
|
||||
|
@ -331,8 +325,7 @@ gst_tuner_signal_strength (GstTuner *tuner,
|
|||
}
|
||||
|
||||
GstTunerNorm *
|
||||
gst_tuner_find_norm_by_name (GstTuner *tuner,
|
||||
gchar *norm)
|
||||
gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
|
@ -349,8 +342,7 @@ gst_tuner_find_norm_by_name (GstTuner *tuner,
|
|||
}
|
||||
|
||||
GstTunerChannel *
|
||||
gst_tuner_find_channel_by_name (GstTuner *tuner,
|
||||
gchar *channel)
|
||||
gst_tuner_find_channel_by_name (GstTuner * tuner, gchar * channel)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
|
@ -367,59 +359,46 @@ gst_tuner_find_channel_by_name (GstTuner *tuner,
|
|||
}
|
||||
|
||||
void
|
||||
gst_tuner_channel_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel)
|
||||
gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[CHANNEL_CHANGED], 0,
|
||||
channel);
|
||||
gst_tuner_signals[CHANNEL_CHANGED], 0, channel);
|
||||
}
|
||||
|
||||
void
|
||||
gst_tuner_norm_changed (GstTuner *tuner,
|
||||
GstTunerNorm *norm)
|
||||
gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_NORM (norm));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[NORM_CHANGED], 0,
|
||||
norm);
|
||||
g_signal_emit (G_OBJECT (tuner), gst_tuner_signals[NORM_CHANGED], 0, norm);
|
||||
}
|
||||
|
||||
void
|
||||
gst_tuner_frequency_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency)
|
||||
gst_tuner_frequency_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[FREQUENCY_CHANGED], 0,
|
||||
channel, frequency);
|
||||
gst_tuner_signals[FREQUENCY_CHANGED], 0, channel, frequency);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel),
|
||||
"frequency_changed",
|
||||
frequency);
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "frequency_changed", frequency);
|
||||
}
|
||||
|
||||
void
|
||||
gst_tuner_signal_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gint signal)
|
||||
gst_tuner_signal_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gint signal)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[SIGNAL_CHANGED], 0,
|
||||
channel, signal);
|
||||
gst_tuner_signals[SIGNAL_CHANGED], 0, channel, signal);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel),
|
||||
"signal_changed",
|
||||
signal);
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "signal_changed", signal);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <gst/tuner/tuner-enumtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER \
|
||||
(gst_tuner_get_type ())
|
||||
#define GST_TUNER(obj) \
|
||||
|
@ -41,43 +40,33 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER))
|
||||
#define GST_TUNER_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TUNER, GstTunerClass))
|
||||
|
||||
typedef struct _GstTuner GstTuner;
|
||||
|
||||
typedef struct _GstTunerClass {
|
||||
typedef struct _GstTunerClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_channels) (GstTuner *tuner);
|
||||
void (* set_channel) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
GstTunerChannel *
|
||||
(* get_channel) (GstTuner *tuner);
|
||||
const GList *(*list_channels) (GstTuner * tuner);
|
||||
void (*set_channel) (GstTuner * tuner, GstTunerChannel * channel);
|
||||
GstTunerChannel *(*get_channel) (GstTuner * tuner);
|
||||
|
||||
const GList * (* list_norms) (GstTuner *tuner);
|
||||
void (* set_norm) (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
GstTunerNorm *(* get_norm) (GstTuner *tuner);
|
||||
const GList *(*list_norms) (GstTuner * tuner);
|
||||
void (*set_norm) (GstTuner * tuner, GstTunerNorm * norm);
|
||||
GstTunerNorm *(*get_norm) (GstTuner * tuner);
|
||||
|
||||
void (* set_frequency) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
gulong (* get_frequency) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
gint (* signal_strength) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void (*set_frequency) (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency);
|
||||
gulong (*get_frequency) (GstTuner * tuner, GstTunerChannel * channel);
|
||||
gint (*signal_strength) (GstTuner * tuner, GstTunerChannel * channel);
|
||||
|
||||
/* signals */
|
||||
void (*channel_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void (*norm_changed) (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
void (*frequency_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void (*signal_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gint signal);
|
||||
void (*channel_changed) (GstTuner * tuner, GstTunerChannel * channel);
|
||||
void (*norm_changed) (GstTuner * tuner, GstTunerNorm * norm);
|
||||
void (*frequency_changed) (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency);
|
||||
void (*signal_changed) (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gint signal);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstTunerClass;
|
||||
|
@ -85,43 +74,31 @@ typedef struct _GstTunerClass {
|
|||
GType gst_tuner_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList * gst_tuner_list_channels (GstTuner *tuner);
|
||||
void gst_tuner_set_channel (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
GstTunerChannel *
|
||||
gst_tuner_get_channel (GstTuner *tuner);
|
||||
const GList *gst_tuner_list_channels (GstTuner * tuner);
|
||||
void gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel);
|
||||
GstTunerChannel *gst_tuner_get_channel (GstTuner * tuner);
|
||||
|
||||
const GList * gst_tuner_list_norms (GstTuner *tuner);
|
||||
void gst_tuner_set_norm (GstTuner *tuner,
|
||||
GstTunerNorm *channel);
|
||||
GstTunerNorm * gst_tuner_get_norm (GstTuner *tuner);
|
||||
const GList *gst_tuner_list_norms (GstTuner * tuner);
|
||||
void gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * channel);
|
||||
GstTunerNorm *gst_tuner_get_norm (GstTuner * tuner);
|
||||
|
||||
void gst_tuner_set_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
gulong gst_tuner_get_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
gint gst_tuner_signal_strength (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void gst_tuner_set_frequency (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency);
|
||||
gulong gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel);
|
||||
gint gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel);
|
||||
|
||||
/* helper functions */
|
||||
GstTunerNorm * gst_tuner_find_norm_by_name (GstTuner *tuner,
|
||||
gchar *norm);
|
||||
GstTunerChannel *gst_tuner_find_channel_by_name (GstTuner *tuner,
|
||||
gchar *channel);
|
||||
GstTunerNorm *gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm);
|
||||
GstTunerChannel *gst_tuner_find_channel_by_name (GstTuner * tuner,
|
||||
gchar * channel);
|
||||
|
||||
/* trigger signals */
|
||||
void gst_tuner_channel_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void gst_tuner_norm_changed (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
void gst_tuner_frequency_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void gst_tuner_signal_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gint signal);
|
||||
void gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel);
|
||||
void gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm);
|
||||
void gst_tuner_frequency_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency);
|
||||
void gst_tuner_signal_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gint signal);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_H__ */
|
||||
|
|
|
@ -25,16 +25,17 @@
|
|||
|
||||
#include "tunerchannel.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_FREQUENCY_CHANGED,
|
||||
SIGNAL_SIGNAL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_channel_class_init (GstTunerChannelClass *klass);
|
||||
static void gst_tuner_channel_init (GstTunerChannel *channel);
|
||||
static void gst_tuner_channel_dispose (GObject *object);
|
||||
static void gst_tuner_channel_class_init (GstTunerChannelClass * klass);
|
||||
static void gst_tuner_channel_init (GstTunerChannel * channel);
|
||||
static void gst_tuner_channel_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -60,15 +61,14 @@ gst_tuner_channel_get_type (void)
|
|||
|
||||
gst_tuner_channel_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstTunerChannel",
|
||||
&tuner_channel_info, 0);
|
||||
"GstTunerChannel", &tuner_channel_info, 0);
|
||||
}
|
||||
|
||||
return gst_tuner_channel_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_class_init (GstTunerChannelClass *klass)
|
||||
gst_tuner_channel_class_init (GstTunerChannelClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -79,21 +79,19 @@ gst_tuner_channel_class_init (GstTunerChannelClass *klass)
|
|||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerChannelClass,
|
||||
frequency_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__ULONG,
|
||||
G_TYPE_NONE, 1, G_TYPE_ULONG);
|
||||
NULL, NULL, g_cclosure_marshal_VOID__ULONG, G_TYPE_NONE, 1, G_TYPE_ULONG);
|
||||
signals[SIGNAL_SIGNAL_CHANGED] =
|
||||
g_signal_new ("signal-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerChannelClass,
|
||||
signal_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
object_klass->dispose = gst_tuner_channel_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_init (GstTunerChannel *channel)
|
||||
gst_tuner_channel_init (GstTunerChannel * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->flags = 0;
|
||||
|
@ -102,7 +100,7 @@ gst_tuner_channel_init (GstTunerChannel *channel)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_dispose (GObject *object)
|
||||
gst_tuner_channel_dispose (GObject * object)
|
||||
{
|
||||
GstTunerChannel *channel = GST_TUNER_CHANNEL (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER_CHANNEL \
|
||||
(gst_tuner_channel_get_type ())
|
||||
#define GST_TUNER_CHANNEL(obj) \
|
||||
|
@ -38,36 +37,34 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_CHANNEL))
|
||||
#define GST_IS_TUNER_CHANNEL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_CHANNEL))
|
||||
|
||||
typedef enum {
|
||||
GST_TUNER_CHANNEL_INPUT = (1<<0),
|
||||
GST_TUNER_CHANNEL_OUTPUT = (1<<1),
|
||||
GST_TUNER_CHANNEL_FREQUENCY = (1<<2),
|
||||
GST_TUNER_CHANNEL_AUDIO = (1<<3),
|
||||
typedef enum
|
||||
{
|
||||
GST_TUNER_CHANNEL_INPUT = (1 << 0),
|
||||
GST_TUNER_CHANNEL_OUTPUT = (1 << 1),
|
||||
GST_TUNER_CHANNEL_FREQUENCY = (1 << 2),
|
||||
GST_TUNER_CHANNEL_AUDIO = (1 << 3),
|
||||
} GstTunerChannelFlags;
|
||||
|
||||
#define GST_TUNER_CHANNEL_HAS_FLAG(channel, flag) \
|
||||
((channel)->flags & flag)
|
||||
|
||||
typedef struct _GstTunerChannel {
|
||||
typedef struct _GstTunerChannel
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
GstTunerChannelFlags flags;
|
||||
gulong min_frequency,
|
||||
max_frequency;
|
||||
gint min_signal,
|
||||
max_signal;
|
||||
gulong min_frequency, max_frequency;
|
||||
gint min_signal, max_signal;
|
||||
} GstTunerChannel;
|
||||
|
||||
typedef struct _GstTunerChannelClass {
|
||||
typedef struct _GstTunerChannelClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* signals */
|
||||
void (*frequency_changed) (GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void (*signal_changed) (GstTunerChannel *channel,
|
||||
gint signal);
|
||||
void (*frequency_changed) (GstTunerChannel * channel, gulong frequency);
|
||||
void (*signal_changed) (GstTunerChannel * channel, gint signal);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstTunerChannelClass;
|
||||
|
@ -75,5 +72,4 @@ typedef struct _GstTunerChannelClass {
|
|||
GType gst_tuner_channel_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_CHANNEL_H__ */
|
||||
|
|
|
@ -25,16 +25,18 @@
|
|||
|
||||
#include "tunernorm.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_norm_class_init (GstTunerNormClass *klass);
|
||||
static void gst_tuner_norm_init (GstTunerNorm *norm);
|
||||
static void gst_tuner_norm_dispose (GObject *object);
|
||||
static void gst_tuner_norm_class_init (GstTunerNormClass * klass);
|
||||
static void gst_tuner_norm_init (GstTunerNorm * norm);
|
||||
static void gst_tuner_norm_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/*static guint signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
||||
GType
|
||||
|
@ -58,15 +60,14 @@ gst_tuner_norm_get_type (void)
|
|||
|
||||
gst_tuner_norm_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstTunerNorm",
|
||||
&tuner_norm_info, 0);
|
||||
"GstTunerNorm", &tuner_norm_info, 0);
|
||||
}
|
||||
|
||||
return gst_tuner_norm_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_class_init (GstTunerNormClass *klass)
|
||||
gst_tuner_norm_class_init (GstTunerNormClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -76,14 +77,14 @@ gst_tuner_norm_class_init (GstTunerNormClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_init (GstTunerNorm *norm)
|
||||
gst_tuner_norm_init (GstTunerNorm * norm)
|
||||
{
|
||||
norm->label = NULL;
|
||||
norm->fps = 0.;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_dispose (GObject *object)
|
||||
gst_tuner_norm_dispose (GObject * object)
|
||||
{
|
||||
GstTunerNorm *norm = GST_TUNER_NORM (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER_NORM \
|
||||
(gst_tuner_norm_get_type ())
|
||||
#define GST_TUNER_NORM(obj) \
|
||||
|
@ -36,15 +35,16 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_NORM))
|
||||
#define GST_IS_TUNER_NORM_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_NORM))
|
||||
|
||||
typedef struct _GstTunerNorm {
|
||||
typedef struct _GstTunerNorm
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
gfloat fps;
|
||||
} GstTunerNorm;
|
||||
|
||||
typedef struct _GstTunerNormClass {
|
||||
typedef struct _GstTunerNormClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
|
@ -53,5 +53,4 @@ typedef struct _GstTunerNormClass {
|
|||
GType gst_tuner_norm_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_NORM_H__ */
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
#include "xoverlay.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
HAVE_XWINDOW_ID,
|
||||
DESIRED_SIZE,
|
||||
LAST_SIGNAL
|
||||
|
@ -54,8 +55,7 @@ gst_x_overlay_get_type (void)
|
|||
};
|
||||
|
||||
gst_x_overlay_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstXOverlay",
|
||||
&gst_x_overlay_info, 0);
|
||||
"GstXOverlay", &gst_x_overlay_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_x_overlay_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -64,8 +64,9 @@ gst_x_overlay_get_type (void)
|
|||
}
|
||||
|
||||
/* FIXME: evil hack, we should figure out our marshal handling in this interfaces some day */
|
||||
extern void gst_marshal_VOID__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values,
|
||||
const GValue *param_values, gpointer invocation_hint, gpointer marshal_data);
|
||||
extern void gst_marshal_VOID__INT_INT (GClosure * closure,
|
||||
GValue * return_value, guint n_param_values, const GValue * param_values,
|
||||
gpointer invocation_hint, gpointer marshal_data);
|
||||
|
||||
static void
|
||||
gst_x_overlay_base_init (gpointer g_class)
|
||||
|
@ -73,22 +74,18 @@ gst_x_overlay_base_init (gpointer g_class)
|
|||
GstXOverlayClass *overlay_class = (GstXOverlayClass *) g_class;
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (! initialized)
|
||||
{
|
||||
if (!initialized) {
|
||||
gst_x_overlay_signals[HAVE_XWINDOW_ID] =
|
||||
g_signal_new ("have-xwindow-id",
|
||||
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstXOverlayClass, have_xwindow_id),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1,
|
||||
G_TYPE_INT);
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
gst_x_overlay_signals[DESIRED_SIZE] =
|
||||
g_signal_new ("desired-size-changed",
|
||||
GST_TYPE_X_OVERLAY, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstXOverlayClass, desired_size),
|
||||
NULL, NULL,
|
||||
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
|
||||
G_TYPE_INT, G_TYPE_INT);
|
||||
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
@ -107,7 +104,7 @@ gst_x_overlay_base_init (gpointer g_class)
|
|||
* stop using that window and create an internal one.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
|
||||
gst_x_overlay_set_xwindow_id (GstXOverlay * overlay, gulong xwindow_id)
|
||||
{
|
||||
GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay);
|
||||
|
||||
|
@ -126,7 +123,7 @@ gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
|
|||
* This function should be used by video overlay developpers.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
|
||||
gst_x_overlay_got_xwindow_id (GstXOverlay * overlay, gulong xwindow_id)
|
||||
{
|
||||
g_return_if_fail (overlay != NULL);
|
||||
g_return_if_fail (GST_IS_X_OVERLAY (overlay));
|
||||
|
@ -145,7 +142,8 @@ gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id)
|
|||
* size, width and height are set to 0.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *height)
|
||||
gst_x_overlay_get_desired_size (GstXOverlay * overlay, guint * width,
|
||||
guint * height)
|
||||
{
|
||||
guint width_tmp, height_tmp;
|
||||
GstXOverlayClass *klass;
|
||||
|
@ -156,7 +154,8 @@ gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *heigh
|
|||
if (klass->get_desired_size && GST_IS_X_OVERLAY (overlay)) {
|
||||
/* this ensures that elements don't need to check width and height for NULL
|
||||
but apps may use NULL */
|
||||
klass->get_desired_size (overlay, width ? width : &width_tmp, height ? height : &height_tmp);
|
||||
klass->get_desired_size (overlay, width ? width : &width_tmp,
|
||||
height ? height : &height_tmp);
|
||||
} else {
|
||||
if (width)
|
||||
*width = 0;
|
||||
|
@ -176,7 +175,8 @@ gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *heigh
|
|||
* This function should be used by video overlay developpers.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
|
||||
gst_x_overlay_got_desired_size (GstXOverlay * overlay, guint width,
|
||||
guint height)
|
||||
{
|
||||
g_return_if_fail (GST_IS_X_OVERLAY (overlay));
|
||||
|
||||
|
@ -192,7 +192,7 @@ gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height)
|
|||
* in the drawable even if the pipeline is PAUSED.
|
||||
*/
|
||||
void
|
||||
gst_x_overlay_expose (GstXOverlay *overlay)
|
||||
gst_x_overlay_expose (GstXOverlay * overlay)
|
||||
{
|
||||
GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_X_OVERLAY \
|
||||
(gst_x_overlay_get_type ())
|
||||
#define GST_X_OVERLAY(obj) \
|
||||
|
@ -40,27 +39,22 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_X_OVERLAY))
|
||||
#define GST_X_OVERLAY_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_X_OVERLAY, GstXOverlayClass))
|
||||
|
||||
typedef struct _GstXOverlay GstXOverlay;
|
||||
|
||||
typedef struct _GstXOverlayClass {
|
||||
typedef struct _GstXOverlayClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
/* virtual functions */
|
||||
void (* set_xwindow_id) (GstXOverlay *overlay,
|
||||
gulong xwindow_id);
|
||||
void (*set_xwindow_id) (GstXOverlay * overlay, gulong xwindow_id);
|
||||
/* optional virtual functions */
|
||||
void (* get_desired_size) (GstXOverlay *overlay,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void (* expose) (GstXOverlay *overlay);
|
||||
void (*get_desired_size) (GstXOverlay * overlay,
|
||||
guint * width, guint * height);
|
||||
void (*expose) (GstXOverlay * overlay);
|
||||
|
||||
/* signals */
|
||||
void (*have_xwindow_id) (GstXOverlay *overlay,
|
||||
gulong xwindow_id);
|
||||
void (* desired_size) (GstXOverlay *overlay,
|
||||
guint width,
|
||||
guint height);
|
||||
void (*have_xwindow_id) (GstXOverlay * overlay, gulong xwindow_id);
|
||||
void (*desired_size) (GstXOverlay * overlay, guint width, guint height);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstXOverlayClass;
|
||||
|
@ -68,14 +62,15 @@ typedef struct _GstXOverlayClass {
|
|||
GType gst_x_overlay_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
void gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
|
||||
void gst_x_overlay_get_desired_size (GstXOverlay *overlay, guint *width, guint *height);
|
||||
void gst_x_overlay_expose (GstXOverlay *overlay);
|
||||
void gst_x_overlay_set_xwindow_id (GstXOverlay * overlay, gulong xwindow_id);
|
||||
void gst_x_overlay_get_desired_size (GstXOverlay * overlay, guint * width,
|
||||
guint * height);
|
||||
void gst_x_overlay_expose (GstXOverlay * overlay);
|
||||
|
||||
/* public methods to fire signals */
|
||||
void gst_x_overlay_got_xwindow_id (GstXOverlay *overlay, gulong xwindow_id);
|
||||
void gst_x_overlay_got_desired_size (GstXOverlay *overlay, guint width, guint height);
|
||||
void gst_x_overlay_got_xwindow_id (GstXOverlay * overlay, gulong xwindow_id);
|
||||
void gst_x_overlay_got_desired_size (GstXOverlay * overlay, guint width,
|
||||
guint height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_X_OVERLAY_H__ */
|
||||
|
|
|
@ -49,9 +49,10 @@ gmi_stream_new (void)
|
|||
}
|
||||
|
||||
void
|
||||
gmi_stream_free (GstMediaInfoStream *stream)
|
||||
gmi_stream_free (GstMediaInfoStream * stream)
|
||||
{
|
||||
if (stream->mime) g_free (stream->mime);
|
||||
if (stream->mime)
|
||||
g_free (stream->mime);
|
||||
/* FIXME: free tracks */
|
||||
g_free (stream);
|
||||
}
|
||||
|
@ -78,7 +79,8 @@ gmi_track_new (void)
|
|||
|
||||
/* callbacks */
|
||||
static void
|
||||
have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstMediaInfoPriv *priv)
|
||||
have_type_callback (GstElement * typefind, guint probability, GstCaps * type,
|
||||
GstMediaInfoPriv * priv)
|
||||
{
|
||||
GstStructure *str;
|
||||
const gchar *mime;
|
||||
|
@ -90,8 +92,7 @@ have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstM
|
|||
|
||||
/* FIXME: this code doesn't yet work, test it later */
|
||||
#ifdef DONTWORK
|
||||
if (strcmp (mime, "application/x-id3") == 0)
|
||||
{
|
||||
if (strcmp (mime, "application/x-id3") == 0) {
|
||||
/* dig a little deeper */
|
||||
GST_DEBUG ("dealing with id3, digging deeper");
|
||||
gst_element_set_state (priv->pipeline, GST_STATE_READY);
|
||||
|
@ -102,7 +103,8 @@ have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstM
|
|||
if (priv->decontainer == NULL)
|
||||
/* FIXME: signal error */
|
||||
g_warning ("Couldn't create id3tag");
|
||||
if (!gst_element_link_many (priv->source, priv->decontainer, priv->typefind, NULL));
|
||||
if (!gst_element_link_many (priv->source, priv->decontainer, priv->typefind,
|
||||
NULL));
|
||||
g_warning ("Couldn't link in id3tag");
|
||||
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
|
@ -113,59 +115,60 @@ have_type_callback (GstElement *typefind, guint probability, GstCaps *type, GstM
|
|||
}
|
||||
|
||||
void
|
||||
deep_notify_callback (GObject *object, GstObject *origin,
|
||||
GParamSpec *pspec, GstMediaInfoPriv *priv)
|
||||
deep_notify_callback (GObject * object, GstObject * origin,
|
||||
GParamSpec * pspec, GstMediaInfoPriv * priv)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
|
||||
/* we only care about pad notifies */
|
||||
if (!GST_IS_PAD (origin)) return;
|
||||
if (!GST_IS_PAD (origin))
|
||||
return;
|
||||
|
||||
/*
|
||||
GST_DEBUG ("DEBUG: deep_notify: have notify of %s from object %s:%s !",
|
||||
pspec->name, gst_element_get_name (gst_pad_get_parent (GST_PAD (origin))),
|
||||
gst_object_get_name (origin));
|
||||
*/
|
||||
else if (strcmp (pspec->name, "caps") == 0)
|
||||
{
|
||||
else if (strcmp (pspec->name, "caps") == 0) {
|
||||
/* check if we're getting it from fakesink */
|
||||
if (GST_IS_PAD (origin) && GST_PAD_PARENT (origin) == priv->fakesink)
|
||||
{
|
||||
if (GST_IS_PAD (origin) && GST_PAD_PARENT (origin) == priv->fakesink) {
|
||||
GST_DEBUG ("have caps on fakesink pad !");
|
||||
g_value_init (&value, pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (origin), pspec->name, &value);
|
||||
priv->format = g_value_peek_pointer (&value);
|
||||
GST_DEBUG ("caps: %" GST_PTR_FORMAT, priv->format);
|
||||
}
|
||||
else GST_DEBUG ("ignoring caps on object %s:%s",
|
||||
} else
|
||||
GST_DEBUG ("ignoring caps on object %s:%s",
|
||||
gst_object_get_name (gst_object_get_parent (origin)),
|
||||
gst_object_get_name (origin));
|
||||
}
|
||||
else if (strcmp (pspec->name, "offset") == 0)
|
||||
{
|
||||
} else if (strcmp (pspec->name, "offset") == 0) {
|
||||
/* we REALLY ignore offsets, we hate them */
|
||||
}
|
||||
//else GST_DEBUG ("ignoring notify of %s", pspec->name);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
guint meta;
|
||||
guint encoded;
|
||||
} TagFlagScore;
|
||||
|
||||
static void
|
||||
tag_flag_score (const GstTagList *list, const gchar *tag, gpointer user_data)
|
||||
tag_flag_score (const GstTagList * list, const gchar * tag, gpointer user_data)
|
||||
{
|
||||
TagFlagScore *score = (TagFlagScore *) user_data;
|
||||
GstTagFlag flag;
|
||||
|
||||
flag = gst_tag_get_flag (tag);
|
||||
if (flag == GST_TAG_FLAG_META) score->meta++;
|
||||
if (flag == GST_TAG_FLAG_ENCODED) score->encoded++;
|
||||
if (flag == GST_TAG_FLAG_META)
|
||||
score->meta++;
|
||||
if (flag == GST_TAG_FLAG_ENCODED)
|
||||
score->encoded++;
|
||||
}
|
||||
|
||||
void
|
||||
found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, GstMediaInfoPriv *priv)
|
||||
found_tag_callback (GObject * pipeline, GstElement * source, GstTagList * tags,
|
||||
GstMediaInfoPriv * priv)
|
||||
{
|
||||
TagFlagScore score;
|
||||
|
||||
|
@ -179,20 +182,18 @@ found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, Gst
|
|||
|
||||
gst_tag_list_foreach (tags, tag_flag_score, &score);
|
||||
|
||||
if (score.meta > score.encoded)
|
||||
{
|
||||
if (score.meta > score.encoded) {
|
||||
GST_DEBUG ("found tags from decoder, adding them as metadata");
|
||||
priv->metadata = gst_tag_list_copy (tags);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
GST_DEBUG ("found tags, adding them as streaminfo");
|
||||
priv->streaminfo = gst_tag_list_copy (tags);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
error_callback (GObject *element, GstElement *source, GError *error, gchar *debug, GstMediaInfoPriv *priv)
|
||||
error_callback (GObject * element, GstElement * source, GError * error,
|
||||
gchar * debug, GstMediaInfoPriv * priv)
|
||||
{
|
||||
g_print ("ERROR: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
|
@ -202,7 +203,7 @@ error_callback (GObject *element, GstElement *source, GError *error, gchar *debu
|
|||
|
||||
/* General GError creation */
|
||||
static void
|
||||
gst_media_info_error_create (GError **error, const gchar *message)
|
||||
gst_media_info_error_create (GError ** error, const gchar * message)
|
||||
{
|
||||
/* check if caller wanted an error reported */
|
||||
if (error == NULL)
|
||||
|
@ -214,15 +215,14 @@ gst_media_info_error_create (GError **error, const gchar *message)
|
|||
|
||||
/* GError creation when element is missing */
|
||||
static void
|
||||
gst_media_info_error_element (const gchar *element, GError **error)
|
||||
gst_media_info_error_element (const gchar * element, GError ** error)
|
||||
{
|
||||
gchar *message;
|
||||
|
||||
message = g_strdup_printf ("The %s element could not be found. "
|
||||
"This element is essential for reading. "
|
||||
"Please install the right plug-in and verify "
|
||||
"that it works by running 'gst-inspect %s'",
|
||||
element, element);
|
||||
"that it works by running 'gst-inspect %s'", element, element);
|
||||
gst_media_info_error_create (error, message);
|
||||
g_free (message);
|
||||
return;
|
||||
|
@ -230,7 +230,7 @@ gst_media_info_error_element (const gchar *element, GError **error)
|
|||
|
||||
/* initialise priv; done the first time */
|
||||
gboolean
|
||||
gmip_init (GstMediaInfoPriv *priv, GError **error)
|
||||
gmip_init (GstMediaInfoPriv * priv, GError ** error)
|
||||
{
|
||||
#define GST_MEDIA_INFO_MAKE_OR_ERROR(el, factory, name, error) \
|
||||
G_STMT_START { \
|
||||
|
@ -257,7 +257,7 @@ G_STMT_START { \
|
|||
/* called at the beginning of each use cycle */
|
||||
/* reset info to a state where it can be used to query for media info */
|
||||
void
|
||||
gmip_reset (GstMediaInfoPriv *priv)
|
||||
gmip_reset (GstMediaInfoPriv * priv)
|
||||
{
|
||||
|
||||
#define STRING_RESET(string) \
|
||||
|
@ -266,8 +266,8 @@ G_STMT_START { \
|
|||
string = NULL; \
|
||||
} G_STMT_END
|
||||
|
||||
STRING_RESET(priv->pipeline_desc);
|
||||
STRING_RESET(priv->location);
|
||||
STRING_RESET (priv->pipeline_desc);
|
||||
STRING_RESET (priv->location);
|
||||
#undef STRING_RESET
|
||||
|
||||
#define CAPS_RESET(target) \
|
||||
|
@ -275,8 +275,8 @@ G_STMT_START { \
|
|||
if (target) gst_caps_free (target); \
|
||||
target = NULL; \
|
||||
} G_STMT_END
|
||||
CAPS_RESET(priv->type);
|
||||
CAPS_RESET(priv->format);
|
||||
CAPS_RESET (priv->type);
|
||||
CAPS_RESET (priv->format);
|
||||
#undef CAPS_RESET
|
||||
|
||||
#define TAGS_RESET(target) \
|
||||
|
@ -285,12 +285,11 @@ G_STMT_START { \
|
|||
gst_tag_list_free (target); \
|
||||
target = NULL; \
|
||||
} G_STMT_END
|
||||
TAGS_RESET(priv->metadata);
|
||||
TAGS_RESET(priv->streaminfo);
|
||||
TAGS_RESET (priv->metadata);
|
||||
TAGS_RESET (priv->streaminfo);
|
||||
#undef TAGS_RESET
|
||||
|
||||
if (priv->stream)
|
||||
{
|
||||
if (priv->stream) {
|
||||
gmi_stream_free (priv->stream);
|
||||
priv->stream = NULL;
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ G_STMT_START { \
|
|||
|
||||
/* seek to a track and reset metadata and streaminfo structs */
|
||||
gboolean
|
||||
gmi_seek_to_track (GstMediaInfo *info, long track)
|
||||
gmi_seek_to_track (GstMediaInfo * info, long track)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstFormat track_format = 0;
|
||||
|
@ -311,7 +310,8 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
|
|||
|
||||
/* FIXME: consider more nicks as "track" */
|
||||
track_format = gst_format_get_by_nick ("logical_stream");
|
||||
if (track_format == 0) return FALSE;
|
||||
if (track_format == 0)
|
||||
return FALSE;
|
||||
GST_DEBUG ("Track format: %d", track_format);
|
||||
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
|
@ -319,24 +319,19 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
|
|||
g_warning ("Couldn't set to play");
|
||||
g_assert (GST_IS_PAD (info->priv->decoder_pad));
|
||||
event = gst_event_new_seek (track_format |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH,
|
||||
track);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, track);
|
||||
res = gst_pad_send_event (info->priv->decoder_pad, event);
|
||||
if (!res)
|
||||
{
|
||||
if (!res) {
|
||||
g_warning ("seek to logical track on pad %s:%s failed",
|
||||
GST_DEBUG_PAD_NAME(info->priv->decoder_pad));
|
||||
GST_DEBUG_PAD_NAME (info->priv->decoder_pad));
|
||||
return FALSE;
|
||||
}
|
||||
/* clear structs because of the seek */
|
||||
if (priv->metadata)
|
||||
{
|
||||
if (priv->metadata) {
|
||||
gst_tag_list_free (priv->metadata);
|
||||
priv->metadata = NULL;
|
||||
}
|
||||
if (priv->streaminfo)
|
||||
{
|
||||
if (priv->streaminfo) {
|
||||
gst_tag_list_free (priv->streaminfo);
|
||||
priv->streaminfo = NULL;
|
||||
}
|
||||
|
@ -345,7 +340,7 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
|
|||
|
||||
/* set the mime type on the media info getter */
|
||||
gboolean
|
||||
gmi_set_mime (GstMediaInfo *info, const char *mime)
|
||||
gmi_set_mime (GstMediaInfo * info, const char *mime)
|
||||
{
|
||||
gchar *desc = NULL;
|
||||
GError *error = NULL;
|
||||
|
@ -354,31 +349,45 @@ gmi_set_mime (GstMediaInfo *info, const char *mime)
|
|||
/* FIXME: please figure out proper mp3 mimetypes */
|
||||
if ((strcmp (mime, "application/x-ogg") == 0) ||
|
||||
(strcmp (mime, "application/ogg") == 0))
|
||||
desc = g_strdup_printf ("%s name=source ! oggdemux ! vorbisdec name=decoder ! fakesink name=sink", priv->source_name);
|
||||
else if ((strcmp (mime, "audio/mpeg") == 0) ||
|
||||
(strcmp (mime, "audio/x-mp3") == 0) ||
|
||||
(strcmp (mime, "audio/mp3") == 0) ||
|
||||
(strcmp (mime, "application/x-id3") == 0) ||
|
||||
(strcmp (mime, "audio/x-id3") == 0))
|
||||
desc = g_strdup_printf ("%s name=source ! id3tag ! mad name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
|
||||
else if ((strcmp (mime, "application/x-flac") == 0) ||
|
||||
(strcmp (mime, "audio/x-flac") == 0))
|
||||
desc = g_strdup_printf ("%s name=source ! flacdec name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
|
||||
else if ((strcmp (mime, "audio/wav") == 0) ||
|
||||
(strcmp (mime, "audio/x-wav") == 0))
|
||||
desc = g_strdup_printf ("%s ! wavparse name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
|
||||
else if (strcmp (mime, "audio/x-mod") == 0 ||
|
||||
strcmp (mime, "audio/x-s3m") == 0 ||
|
||||
strcmp (mime, "audio/x-xm") == 0 ||
|
||||
strcmp (mime, "audio/x-it") == 0)
|
||||
desc = g_strdup_printf ("%s name=source ! modplug name=decoder ! audio/x-raw-int ! fakesink name=sink", priv->source_name);
|
||||
else return FALSE;
|
||||
desc =
|
||||
g_strdup_printf
|
||||
("%s name=source ! oggdemux ! vorbisdec name=decoder ! fakesink name=sink",
|
||||
priv->source_name);
|
||||
else if ((strcmp (mime, "audio/mpeg") == 0)
|
||||
|| (strcmp (mime, "audio/x-mp3") == 0)
|
||||
|| (strcmp (mime, "audio/mp3") == 0)
|
||||
|| (strcmp (mime, "application/x-id3") == 0)
|
||||
|| (strcmp (mime, "audio/x-id3") == 0))
|
||||
desc =
|
||||
g_strdup_printf
|
||||
("%s name=source ! id3tag ! mad name=decoder ! audio/x-raw-int ! fakesink name=sink",
|
||||
priv->source_name);
|
||||
else if ((strcmp (mime, "application/x-flac") == 0)
|
||||
|| (strcmp (mime, "audio/x-flac") == 0))
|
||||
desc =
|
||||
g_strdup_printf
|
||||
("%s name=source ! flacdec name=decoder ! audio/x-raw-int ! fakesink name=sink",
|
||||
priv->source_name);
|
||||
else if ((strcmp (mime, "audio/wav") == 0)
|
||||
|| (strcmp (mime, "audio/x-wav") == 0))
|
||||
desc =
|
||||
g_strdup_printf
|
||||
("%s ! wavparse name=decoder ! audio/x-raw-int ! fakesink name=sink",
|
||||
priv->source_name);
|
||||
else if (strcmp (mime, "audio/x-mod") == 0
|
||||
|| strcmp (mime, "audio/x-s3m") == 0 || strcmp (mime, "audio/x-xm") == 0
|
||||
|| strcmp (mime, "audio/x-it") == 0)
|
||||
desc =
|
||||
g_strdup_printf
|
||||
("%s name=source ! modplug name=decoder ! audio/x-raw-int ! fakesink name=sink",
|
||||
priv->source_name);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG ("using description %s", desc);
|
||||
priv->pipeline_desc = desc;
|
||||
priv->pipeline = gst_parse_launch (desc, &error);
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_warning ("Error parsing pipeline description: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
|
@ -398,12 +407,15 @@ gmi_set_mime (GstMediaInfo *info, const char *mime)
|
|||
/* get the "decoder" source pad */
|
||||
priv->decoder_pad = gst_element_get_pad (priv->decoder, "src");
|
||||
g_assert (GST_IS_PAD (priv->decoder_pad));
|
||||
GST_DEBUG ("decoder pad: %s:%s", gst_object_get_name (gst_object_get_parent (GST_OBJECT (priv->decoder_pad))), gst_pad_get_name (priv->decoder_pad));
|
||||
GST_DEBUG ("decoder pad: %s:%s",
|
||||
gst_object_get_name (gst_object_get_parent (GST_OBJECT (priv->
|
||||
decoder_pad))), gst_pad_get_name (priv->decoder_pad));
|
||||
|
||||
/* attach notify handler */
|
||||
g_signal_connect (G_OBJECT (info->priv->pipeline), "deep_notify",
|
||||
G_CALLBACK (deep_notify_callback), info->priv);
|
||||
g_signal_connect (G_OBJECT (info->priv->pipeline), "found-tag", G_CALLBACK (found_tag_callback), info->priv);
|
||||
g_signal_connect (G_OBJECT (info->priv->pipeline), "found-tag",
|
||||
G_CALLBACK (found_tag_callback), info->priv);
|
||||
g_signal_connect (G_OBJECT (info->priv->pipeline), "error",
|
||||
G_CALLBACK (error_callback), info->priv);
|
||||
|
||||
|
@ -412,11 +424,10 @@ gmi_set_mime (GstMediaInfo *info, const char *mime)
|
|||
|
||||
/* clear the decoding pipeline */
|
||||
void
|
||||
gmi_clear_decoder (GstMediaInfo *info)
|
||||
gmi_clear_decoder (GstMediaInfo * info)
|
||||
{
|
||||
if (info->priv->pipeline)
|
||||
{
|
||||
GST_DEBUG("Unreffing pipeline");
|
||||
if (info->priv->pipeline) {
|
||||
GST_DEBUG ("Unreffing pipeline");
|
||||
gst_object_unref (GST_OBJECT (info->priv->pipeline));
|
||||
}
|
||||
info->priv->pipeline = NULL;
|
||||
|
@ -430,7 +441,7 @@ gmi_clear_decoder (GstMediaInfo *info)
|
|||
|
||||
/* prepare for typefind, move from NULL to TYPEFIND */
|
||||
gboolean
|
||||
gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
|
||||
gmip_find_type_pre (GstMediaInfoPriv * priv, GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
|
@ -440,8 +451,7 @@ gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
|
|||
* just use it through this function only */
|
||||
|
||||
priv->pipeline = gst_pipeline_new ("pipeline-typefind");
|
||||
if (!GST_IS_PIPELINE (priv->pipeline))
|
||||
{
|
||||
if (!GST_IS_PIPELINE (priv->pipeline)) {
|
||||
gst_media_info_error_create (error, "Internal GStreamer error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -455,8 +465,7 @@ gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
|
|||
g_signal_connect (G_OBJECT (priv->typefind), "have-type",
|
||||
G_CALLBACK (have_type_callback), priv);
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
== GST_STATE_FAILURE)
|
||||
{
|
||||
== GST_STATE_FAILURE) {
|
||||
g_warning ("Couldn't set to play");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -467,24 +476,20 @@ gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error)
|
|||
|
||||
/* finish off typefind */
|
||||
gboolean
|
||||
gmip_find_type_post (GstMediaInfoPriv *priv)
|
||||
gmip_find_type_post (GstMediaInfoPriv * priv)
|
||||
{
|
||||
/*clear up typefind */
|
||||
gst_element_set_state (priv->pipeline, GST_STATE_READY);
|
||||
if (priv->decontainer)
|
||||
{
|
||||
if (priv->decontainer) {
|
||||
gst_element_unlink (priv->source, priv->decontainer);
|
||||
gst_element_unlink (priv->decontainer, priv->typefind);
|
||||
gst_bin_remove (GST_BIN (priv->pipeline), priv->decontainer);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
gst_element_unlink (priv->source, priv->typefind);
|
||||
}
|
||||
gst_bin_remove (GST_BIN (priv->pipeline), priv->typefind);
|
||||
|
||||
if (priv->type == NULL)
|
||||
{
|
||||
if (priv->type == NULL) {
|
||||
g_warning ("iteration ended, type not found !\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -495,25 +500,23 @@ gmip_find_type_post (GstMediaInfoPriv *priv)
|
|||
|
||||
/* complete version */
|
||||
gboolean
|
||||
gmip_find_type (GstMediaInfoPriv *priv, GError ** error)
|
||||
gmip_find_type (GstMediaInfoPriv * priv, GError ** error)
|
||||
{
|
||||
if (!gmip_find_type_pre (priv, error))
|
||||
return FALSE;
|
||||
GST_DEBUG ("gmip_find_type: iterating");
|
||||
while ((priv->type == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG("+");
|
||||
GMI_DEBUG("\n");
|
||||
while ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG ("+");
|
||||
GMI_DEBUG ("\n");
|
||||
return gmip_find_type_post (priv);
|
||||
}
|
||||
|
||||
/* FIXME: why not have these functions work on priv types ? */
|
||||
gboolean
|
||||
gmip_find_stream_pre (GstMediaInfoPriv *priv)
|
||||
gmip_find_stream_pre (GstMediaInfoPriv * priv)
|
||||
{
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
== GST_STATE_FAILURE)
|
||||
{
|
||||
== GST_STATE_FAILURE) {
|
||||
g_warning ("Couldn't set to play");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -522,7 +525,7 @@ gmip_find_stream_pre (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_stream_post (GstMediaInfoPriv *priv)
|
||||
gmip_find_stream_post (GstMediaInfoPriv * priv)
|
||||
{
|
||||
GstMediaInfoStream *stream = priv->stream;
|
||||
const GstFormat *formats;
|
||||
|
@ -541,8 +544,7 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
|
|||
|
||||
/* get supported formats on decoder pad */
|
||||
formats = gst_pad_get_formats (priv->decoder_pad);
|
||||
while (*formats)
|
||||
{
|
||||
while (*formats) {
|
||||
const GstFormatDefinition *definition;
|
||||
|
||||
format = *formats;
|
||||
|
@ -551,13 +553,10 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
|
|||
definition = gst_format_get_details (*formats);
|
||||
GST_DEBUG ("trying to figure out length for format %s", definition->nick);
|
||||
|
||||
res = gst_pad_query (priv->decoder_pad, GST_QUERY_TOTAL,
|
||||
&format, &value);
|
||||
res = gst_pad_query (priv->decoder_pad, GST_QUERY_TOTAL, &format, &value);
|
||||
|
||||
if (res)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
if (res) {
|
||||
switch (format) {
|
||||
case GST_FORMAT_TIME:
|
||||
stream->length_time = value;
|
||||
GST_DEBUG (" total %s: %lld", definition->nick, value);
|
||||
|
@ -568,35 +567,33 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
|
|||
default:
|
||||
/* separation is necessary because track_format doesn't resolve to
|
||||
* int */
|
||||
if (format == track_format)
|
||||
{
|
||||
if (format == track_format) {
|
||||
stream->length_tracks = value;
|
||||
GST_DEBUG (" total %s: %lld", definition->nick, value);
|
||||
}
|
||||
else
|
||||
} else
|
||||
GST_DEBUG ("unhandled format %s", definition->nick);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
GST_DEBUG ("query didn't return result for %s", definition->nick);
|
||||
|
||||
formats++;
|
||||
}
|
||||
if (stream->length_tracks == 0) stream->length_tracks = 1;
|
||||
if (stream->length_tracks == 0)
|
||||
stream->length_tracks = 1;
|
||||
|
||||
/* now get number of bytes from the sink pad to get the bitrate */
|
||||
format = GST_FORMAT_BYTES;
|
||||
g_assert (GST_IS_PAD (priv->source_pad));
|
||||
res = gst_pad_query (priv->source_pad, GST_QUERY_TOTAL,
|
||||
&format, &value);
|
||||
if (!res) g_warning ("Failed to query on sink pad !");
|
||||
res = gst_pad_query (priv->source_pad, GST_QUERY_TOTAL, &format, &value);
|
||||
if (!res)
|
||||
g_warning ("Failed to query on sink pad !");
|
||||
bytes = value;
|
||||
GST_DEBUG ("bitrate calc: bytes gotten: %ld", bytes);
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
if (bytes) {
|
||||
double seconds = (double) stream->length_time / GST_SECOND;
|
||||
double bits = bytes * 8;
|
||||
|
||||
stream->bitrate = (long) (bits / seconds);
|
||||
}
|
||||
GST_DEBUG ("moving to STATE_METADATA\n");
|
||||
|
@ -607,7 +604,7 @@ gmip_find_stream_post (GstMediaInfoPriv *priv)
|
|||
/* get properties of complete physical stream
|
||||
* and return them in pre-alloced stream struct in priv->stream */
|
||||
gboolean
|
||||
gmip_find_stream (GstMediaInfoPriv *priv)
|
||||
gmip_find_stream (GstMediaInfoPriv * priv)
|
||||
{
|
||||
GST_DEBUG ("mip_find_stream start");
|
||||
|
||||
|
@ -615,16 +612,13 @@ gmip_find_stream (GstMediaInfoPriv *priv)
|
|||
/* iterate until caps are found */
|
||||
/* FIXME: this should be done through the plugin sending some signal
|
||||
* that it is ready for queries */
|
||||
while (gst_bin_iterate (GST_BIN (priv->pipeline)) &&
|
||||
priv->format == NULL)
|
||||
;
|
||||
while (gst_bin_iterate (GST_BIN (priv->pipeline)) && priv->format == NULL);
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
|
||||
== GST_STATE_FAILURE)
|
||||
g_warning ("Couldn't set to paused");
|
||||
|
||||
if (priv->format == NULL)
|
||||
{
|
||||
GMI_DEBUG("gmip_find_stream: couldn't get caps !");
|
||||
if (priv->format == NULL) {
|
||||
GMI_DEBUG ("gmip_find_stream: couldn't get caps !");
|
||||
return FALSE;
|
||||
}
|
||||
return gmip_find_stream_post (priv);
|
||||
|
@ -632,14 +626,13 @@ gmip_find_stream (GstMediaInfoPriv *priv)
|
|||
|
||||
/* find metadata encoded in media and store in priv->metadata */
|
||||
gboolean
|
||||
gmip_find_track_metadata_pre (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_metadata_pre (GstMediaInfoPriv * priv)
|
||||
{
|
||||
/* FIXME: this is a hack to set max allowed iterations for metadata
|
||||
* querying - we should make gst smarter by itself instead */
|
||||
priv->metadata_iters = 0;
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
== GST_STATE_FAILURE)
|
||||
{
|
||||
== GST_STATE_FAILURE) {
|
||||
g_warning ("Couldn't set to play");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -647,7 +640,7 @@ gmip_find_track_metadata_pre (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_metadata_post (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_metadata_post (GstMediaInfoPriv * priv)
|
||||
{
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
|
||||
== GST_STATE_FAILURE)
|
||||
|
@ -658,14 +651,13 @@ gmip_find_track_metadata_post (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_metadata (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_metadata (GstMediaInfoPriv * priv)
|
||||
{
|
||||
gmip_find_track_metadata_pre (priv);
|
||||
GST_DEBUG ("gmip_find_metadata: iterating");
|
||||
while ((priv->metadata == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG("+");
|
||||
GMI_DEBUG("\n");
|
||||
while ((priv->metadata == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG ("+");
|
||||
GMI_DEBUG ("\n");
|
||||
gmip_find_track_metadata_post (priv);
|
||||
|
||||
return TRUE;
|
||||
|
@ -674,11 +666,10 @@ gmip_find_track_metadata (GstMediaInfoPriv *priv)
|
|||
/* find streaminfo found by decoder and store in priv->streaminfo */
|
||||
/* FIXME: this is an exact copy, so reuse this function instead */
|
||||
gboolean
|
||||
gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_streaminfo_pre (GstMediaInfoPriv * priv)
|
||||
{
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
== GST_STATE_FAILURE)
|
||||
{
|
||||
== GST_STATE_FAILURE) {
|
||||
g_warning ("Couldn't set to play");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -686,7 +677,7 @@ gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_streaminfo_post (GstMediaInfoPriv * priv)
|
||||
{
|
||||
GstFormat format, track_format;
|
||||
|
||||
|
@ -694,12 +685,9 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
|
|||
|
||||
/* now add total length to this, and maybe even bitrate ? FIXME */
|
||||
track_format = gst_format_get_by_nick ("logical_stream");
|
||||
if (track_format == 0)
|
||||
{
|
||||
if (track_format == 0) {
|
||||
g_print ("FIXME: implement getting length of whole track\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* which one are we at ? */
|
||||
long track_num;
|
||||
gint64 value_start, value_end;
|
||||
|
@ -707,19 +695,15 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
|
|||
|
||||
res = gst_pad_query (priv->decoder_pad, GST_QUERY_POSITION,
|
||||
&track_format, &value_start);
|
||||
if (res)
|
||||
{
|
||||
if (res) {
|
||||
format = GST_FORMAT_TIME;
|
||||
track_num = value_start;
|
||||
GST_DEBUG ("we are currently at %ld", track_num);
|
||||
res = gst_pad_convert (priv->decoder_pad,
|
||||
track_format, track_num,
|
||||
&format, &value_start);
|
||||
track_format, track_num, &format, &value_start);
|
||||
res &= gst_pad_convert (priv->decoder_pad,
|
||||
track_format, track_num + 1,
|
||||
&format, &value_end);
|
||||
if (res)
|
||||
{
|
||||
track_format, track_num + 1, &format, &value_end);
|
||||
if (res) {
|
||||
/* substract to get the length */
|
||||
GST_DEBUG ("start %lld, end %lld", value_start, value_end);
|
||||
value_end -= value_start;
|
||||
|
@ -737,14 +721,14 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_streaminfo (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_streaminfo (GstMediaInfoPriv * priv)
|
||||
{
|
||||
gmip_find_track_streaminfo_pre (priv);
|
||||
GST_DEBUG ("DEBUG: gmip_find_streaminfo: iterating");
|
||||
while ((priv->streaminfo == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG("+");
|
||||
GMI_DEBUG("\n");
|
||||
GMI_DEBUG ("+");
|
||||
GMI_DEBUG ("\n");
|
||||
gmip_find_track_streaminfo_post (priv);
|
||||
|
||||
return TRUE;
|
||||
|
@ -752,11 +736,10 @@ gmip_find_track_streaminfo (GstMediaInfoPriv *priv)
|
|||
|
||||
/* find format found by decoder and store in priv->format */
|
||||
gboolean
|
||||
gmip_find_track_format_pre (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_format_pre (GstMediaInfoPriv * priv)
|
||||
{
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PLAYING)
|
||||
== GST_STATE_FAILURE)
|
||||
{
|
||||
== GST_STATE_FAILURE) {
|
||||
g_warning ("Couldn't set to play");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -764,7 +747,7 @@ gmip_find_track_format_pre (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_format_post (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_format_post (GstMediaInfoPriv * priv)
|
||||
{
|
||||
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
|
||||
== GST_STATE_FAILURE)
|
||||
|
@ -775,17 +758,14 @@ gmip_find_track_format_post (GstMediaInfoPriv *priv)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gmip_find_track_format (GstMediaInfoPriv *priv)
|
||||
gmip_find_track_format (GstMediaInfoPriv * priv)
|
||||
{
|
||||
gmip_find_track_format_pre (priv);
|
||||
GST_DEBUG ("DEBUG: gmip_find_format: iterating");
|
||||
while ((priv->format == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG("+");
|
||||
GMI_DEBUG("\n");
|
||||
while ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
GMI_DEBUG ("+");
|
||||
GMI_DEBUG ("\n");
|
||||
gmip_find_track_format_post (priv);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,45 +96,41 @@ struct GstMediaInfoPriv
|
|||
};
|
||||
|
||||
/* declarations */
|
||||
GstMediaInfoStream *
|
||||
gmi_stream_new (void);
|
||||
void gmi_stream_free (GstMediaInfoStream *stream);
|
||||
GstMediaInfoStream *gmi_stream_new (void);
|
||||
void gmi_stream_free (GstMediaInfoStream * stream);
|
||||
|
||||
GstMediaInfoTrack *
|
||||
gmi_track_new (void);
|
||||
GstMediaInfoTrack *gmi_track_new (void);
|
||||
|
||||
void gmip_reset (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_init (GstMediaInfoPriv *priv, GError **error);
|
||||
void gmip_reset (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_init (GstMediaInfoPriv * priv, GError ** error);
|
||||
|
||||
void gmi_clear_decoder (GstMediaInfo *info);
|
||||
void gmi_clear_decoder (GstMediaInfo * info);
|
||||
|
||||
gboolean gmi_seek_to_track (GstMediaInfo *info,
|
||||
long track);
|
||||
gboolean gmi_seek_to_track (GstMediaInfo * info, long track);
|
||||
|
||||
gboolean gmi_set_mime (GstMediaInfo *info,
|
||||
const char *mime);
|
||||
gboolean gmi_set_mime (GstMediaInfo * info, const char *mime);
|
||||
|
||||
void deep_notify_callback (GObject *object,
|
||||
GstObject *origin,
|
||||
GParamSpec *pspec,
|
||||
GstMediaInfoPriv *priv);
|
||||
void found_tag_callback (GObject *pipeline, GstElement *source, GstTagList *tags, GstMediaInfoPriv *priv);
|
||||
void error_callback (GObject *element, GstElement *source, GError *error, gchar *debug, GstMediaInfoPriv *priv);
|
||||
void deep_notify_callback (GObject * object,
|
||||
GstObject * origin, GParamSpec * pspec, GstMediaInfoPriv * priv);
|
||||
void found_tag_callback (GObject * pipeline, GstElement * source,
|
||||
GstTagList * tags, GstMediaInfoPriv * priv);
|
||||
void error_callback (GObject * element, GstElement * source, GError * error,
|
||||
gchar * debug, GstMediaInfoPriv * priv);
|
||||
|
||||
gboolean gmip_find_type_pre (GstMediaInfoPriv *priv, GError **error);
|
||||
gboolean gmip_find_type_post (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_type (GstMediaInfoPriv *priv, GError **error);
|
||||
gboolean gmip_find_stream_pre (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_stream_post (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_stream (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_metadata_pre (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_metadata_post (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_metadata (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_streaminfo_pre (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_streaminfo (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_format_pre (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_format_post (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_track_format (GstMediaInfoPriv *priv);
|
||||
gboolean gmip_find_type_pre (GstMediaInfoPriv * priv, GError ** error);
|
||||
gboolean gmip_find_type_post (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_type (GstMediaInfoPriv * priv, GError ** error);
|
||||
gboolean gmip_find_stream_pre (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_stream_post (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_stream (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_metadata_pre (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_metadata_post (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_metadata (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_streaminfo_pre (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_streaminfo_post (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_streaminfo (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_format_pre (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_format_post (GstMediaInfoPriv * priv);
|
||||
gboolean gmip_find_track_format (GstMediaInfoPriv * priv);
|
||||
|
||||
#endif /* __GST_MEDIA_INFO_PRIV_H__ */
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "media-info.h"
|
||||
|
||||
static void
|
||||
print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
||||
print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
|
||||
{
|
||||
gint i, count;
|
||||
|
||||
|
@ -17,8 +17,8 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
|||
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
|
||||
g_assert (gst_tag_list_get_string_index (list, tag, i, &str));
|
||||
} else {
|
||||
str = g_strdup_value_contents (
|
||||
gst_tag_list_get_value_index (list, tag, i));
|
||||
str =
|
||||
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
|
@ -32,7 +32,7 @@ print_tag (const GstTagList *list, const gchar *tag, gpointer unused)
|
|||
}
|
||||
|
||||
static void
|
||||
info_print (GstMediaInfoStream *stream)
|
||||
info_print (GstMediaInfoStream * stream)
|
||||
{
|
||||
int i;
|
||||
GList *p;
|
||||
|
@ -44,13 +44,11 @@ info_print (GstMediaInfoStream *stream)
|
|||
g_print ("- bitrate: %.3f kbps\n", stream->bitrate / 1000.0);
|
||||
g_print ("- number of tracks: %ld\n", stream->length_tracks);
|
||||
p = stream->tracks;
|
||||
if (p == NULL)
|
||||
{
|
||||
if (p == NULL) {
|
||||
g_print ("- no track information, probably an error\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < stream->length_tracks; ++i)
|
||||
{
|
||||
for (i = 0; i < stream->length_tracks; ++i) {
|
||||
g_print ("- track %d\n", i);
|
||||
track = (GstMediaInfoTrack *) p->data;
|
||||
g_print (" - metadata:\n");
|
||||
|
@ -80,16 +78,14 @@ main (int argc, char *argv[])
|
|||
gst_init (&argc, &argv);
|
||||
|
||||
info = gst_media_info_new (&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
if (error != NULL) {
|
||||
g_print ("Error creating media-info object: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_assert (G_IS_OBJECT (info));
|
||||
if (!gst_media_info_set_source (info, "gnomevfssrc", &error))
|
||||
{
|
||||
if (!gst_media_info_set_source (info, "gnomevfssrc", &error)) {
|
||||
g_print ("Could not set gnomevfssrc as a source\n");
|
||||
g_print ("reason: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
|
@ -97,19 +93,18 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
g_print ("stream: %p, &stream: %p\n", stream, &stream);
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
for (i = 1; i < argc; ++i) {
|
||||
|
||||
/*
|
||||
stream = gst_media_info_read (info, argv[i], GST_MEDIA_INFO_ALL);
|
||||
*/
|
||||
gst_media_info_read_with_idler (info, argv[i], GST_MEDIA_INFO_ALL, &error);
|
||||
while (gst_media_info_read_idler (info, &stream, &error) && stream == NULL)
|
||||
/* keep idling */ g_print ("+");
|
||||
/* keep idling */
|
||||
g_print ("+");
|
||||
g_print ("\nFILE: %s\n", argv[i]);
|
||||
g_print ("stream: %p, &stream: %p\n", stream, &stream);
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
g_print ("Error reading media info: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
|
|
@ -26,12 +26,11 @@
|
|||
#include "media-info.h"
|
||||
#include "media-info-priv.h"
|
||||
|
||||
static void gst_media_info_class_init (GstMediaInfoClass *klass);
|
||||
static void gst_media_info_instance_init (GstMediaInfo *info);
|
||||
static void gst_media_info_class_init (GstMediaInfoClass * klass);
|
||||
static void gst_media_info_instance_init (GstMediaInfo * info);
|
||||
|
||||
static void gst_media_info_get_property (GObject *object, guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gst_media_info_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
|
||||
static gboolean _media_info_inited = FALSE;
|
||||
|
@ -64,6 +63,7 @@ GQuark
|
|||
gst_media_info_error_quark (void)
|
||||
{
|
||||
static GQuark quark = 0;
|
||||
|
||||
if (quark == 0)
|
||||
quark = g_quark_from_static_string ("gst-media-info-error-quark");
|
||||
return quark;
|
||||
|
@ -86,7 +86,8 @@ GST_DEBUG_CATEGORY (gst_media_info_debug);
|
|||
void
|
||||
gst_media_info_init (void)
|
||||
{
|
||||
if (_media_info_inited) return;
|
||||
if (_media_info_inited)
|
||||
return;
|
||||
|
||||
/* register our debugging category */
|
||||
GST_DEBUG_CATEGORY_INIT (gst_media_info_debug, "GST_MEDIA_INFO", 0,
|
||||
|
@ -99,8 +100,8 @@ GType
|
|||
gst_media_info_get_type (void)
|
||||
{
|
||||
static GType gst_media_info_type = 0;
|
||||
if (!gst_media_info_type)
|
||||
{
|
||||
|
||||
if (!gst_media_info_type) {
|
||||
static const GTypeInfo gst_media_info_info = {
|
||||
sizeof (GstMediaInfoClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
|
@ -113,14 +114,13 @@ gst_media_info_get_type (void)
|
|||
NULL
|
||||
};
|
||||
gst_media_info_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstMediaInfo",
|
||||
&gst_media_info_info, 0);
|
||||
"GstMediaInfo", &gst_media_info_info, 0);
|
||||
}
|
||||
return gst_media_info_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_media_info_class_init (GstMediaInfoClass *klass)
|
||||
gst_media_info_class_init (GstMediaInfoClass * klass)
|
||||
{
|
||||
GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
|
@ -140,25 +140,25 @@ gst_media_info_class_init (GstMediaInfoClass *klass)
|
|||
|
||||
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_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstMediaInfoClass, media_info_signal),
|
||||
NULL, NULL,
|
||||
gst_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_media_info_instance_init (GstMediaInfo *info)
|
||||
gst_media_info_instance_init (GstMediaInfo * info)
|
||||
{
|
||||
GError **error;
|
||||
|
||||
info->priv = g_new0 (GstMediaInfoPriv, 1);
|
||||
error = &info->priv->error;
|
||||
|
||||
if (!_media_info_inited) { gst_media_info_init (); }
|
||||
if (!_media_info_inited) {
|
||||
gst_media_info_init ();
|
||||
}
|
||||
|
||||
gmip_init (info->priv, error);
|
||||
gmip_reset (info->priv);
|
||||
|
@ -166,13 +166,12 @@ gst_media_info_instance_init (GstMediaInfo *info)
|
|||
|
||||
/* get/set */
|
||||
static void
|
||||
gst_media_info_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
gst_media_info_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstMediaInfo *info = GST_MEDIA_INFO (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_SOURCE:
|
||||
g_value_set_string (value, info->priv->source_name);
|
||||
break;
|
||||
|
@ -183,19 +182,15 @@ gst_media_info_get_property (GObject *object, guint prop_id,
|
|||
}
|
||||
|
||||
GstMediaInfo *
|
||||
gst_media_info_new (GError **error)
|
||||
gst_media_info_new (GError ** error)
|
||||
{
|
||||
GstMediaInfo *info = g_object_new (GST_MEDIA_INFO_TYPE, NULL);
|
||||
|
||||
if (info->priv->error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
if (info->priv->error) {
|
||||
if (error) {
|
||||
*error = info->priv->error;
|
||||
info->priv->error = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
g_warning ("Error creating GstMediaInfo object.\n%s",
|
||||
info->priv->error->message);
|
||||
g_error_free (info->priv->error);
|
||||
|
@ -208,7 +203,8 @@ gst_media_info_new (GError **error)
|
|||
* public methods
|
||||
*/
|
||||
gboolean
|
||||
gst_media_info_set_source (GstMediaInfo *info, const char *source, GError **error)
|
||||
gst_media_info_set_source (GstMediaInfo * info, const char *source,
|
||||
GError ** error)
|
||||
{
|
||||
info->priv->source_name = g_strdup (source);
|
||||
return TRUE;
|
||||
|
@ -221,8 +217,8 @@ gst_media_info_set_source (GstMediaInfo *info, const char *source, GError **erro
|
|||
* previous one is done ?
|
||||
*/
|
||||
void
|
||||
gst_media_info_read_with_idler (GstMediaInfo *info, const char *location,
|
||||
guint16 flags, GError **error)
|
||||
gst_media_info_read_with_idler (GstMediaInfo * info, const char *location,
|
||||
guint16 flags, GError ** error)
|
||||
{
|
||||
GstMediaInfoPriv *priv = info->priv;
|
||||
|
||||
|
@ -236,12 +232,14 @@ gst_media_info_read_with_idler (GstMediaInfo *info, const char *location,
|
|||
* returns: TRUE if it was able to idle, FALSE if there was an error
|
||||
*/
|
||||
gboolean
|
||||
gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GError **error)
|
||||
gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
|
||||
GError ** error)
|
||||
{
|
||||
GstMediaInfoPriv *priv;
|
||||
|
||||
/* if it's NULL then we're sure something went wrong higher up) */
|
||||
if (info == NULL) return FALSE;
|
||||
if (info == NULL)
|
||||
return FALSE;
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
priv = info->priv;
|
||||
|
@ -249,12 +247,10 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
g_assert (streamp != NULL);
|
||||
g_assert (priv);
|
||||
|
||||
switch (priv->state)
|
||||
{
|
||||
switch (priv->state) {
|
||||
case GST_MEDIA_INFO_STATE_NULL:
|
||||
/* make sure we have a source */
|
||||
if (!priv->source_name)
|
||||
{
|
||||
if (!priv->source_name) {
|
||||
*error = g_error_new (GST_MEDIA_INFO_ERROR, 0,
|
||||
"No source set on media info.");
|
||||
return FALSE;
|
||||
|
@ -269,14 +265,12 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
gchar *mime;
|
||||
|
||||
GST_LOG ("STATE_TYPEFIND");
|
||||
if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
{
|
||||
if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
|
||||
GST_DEBUG ("iterating while in STATE_TYPEFIND");
|
||||
GMI_DEBUG("?");
|
||||
GMI_DEBUG ("?");
|
||||
return TRUE;
|
||||
}
|
||||
if (priv->type == NULL)
|
||||
{
|
||||
if (priv->type == NULL) {
|
||||
g_warning ("Couldn't find type\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -284,11 +278,11 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
GST_DEBUG ("doing find_type_post");
|
||||
gmip_find_type_post (priv);
|
||||
GST_DEBUG ("finding out mime type");
|
||||
mime = g_strdup (gst_structure_get_name (
|
||||
gst_caps_get_structure(priv->type, 0)));
|
||||
mime =
|
||||
g_strdup (gst_structure_get_name (gst_caps_get_structure (priv->type,
|
||||
0)));
|
||||
GST_DEBUG ("found out mime type: %s", mime);
|
||||
if (!gmi_set_mime (info, mime))
|
||||
{
|
||||
if (!gmi_set_mime (info, mime)) {
|
||||
/* FIXME: pop up error */
|
||||
GST_DEBUG ("no decoder pipeline found for mime %s", mime);
|
||||
return FALSE;
|
||||
|
@ -303,13 +297,11 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
case GST_MEDIA_INFO_STATE_STREAM:
|
||||
{
|
||||
GST_LOG ("STATE_STREAM");
|
||||
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
{
|
||||
GMI_DEBUG("?");
|
||||
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
|
||||
GMI_DEBUG ("?");
|
||||
return TRUE;
|
||||
}
|
||||
if (priv->format == NULL)
|
||||
{
|
||||
if (priv->format == NULL) {
|
||||
g_warning ("Couldn't find format\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -325,21 +317,20 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
{
|
||||
if ((priv->metadata == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)) &&
|
||||
priv->metadata_iters < MAX_METADATA_ITERS)
|
||||
{
|
||||
GMI_DEBUG("?");
|
||||
priv->metadata_iters < MAX_METADATA_ITERS) {
|
||||
GMI_DEBUG ("?");
|
||||
priv->metadata_iters++;
|
||||
return TRUE;
|
||||
}
|
||||
if (priv->metadata_iters == MAX_METADATA_ITERS)
|
||||
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 */
|
||||
GST_DEBUG ("Couldn't find metadata");
|
||||
}
|
||||
GST_DEBUG ("found metadata of track %ld", priv->current_track_num);
|
||||
if (!gmip_find_track_metadata_post (priv)) return FALSE;
|
||||
if (!gmip_find_track_metadata_post (priv))
|
||||
return FALSE;
|
||||
GST_DEBUG ("METADATA: going to STREAMINFO\n");
|
||||
priv->state = GST_MEDIA_INFO_STATE_STREAMINFO;
|
||||
return gmip_find_track_streaminfo_pre (priv);
|
||||
|
@ -347,37 +338,33 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
case GST_MEDIA_INFO_STATE_STREAMINFO:
|
||||
{
|
||||
if ((priv->streaminfo == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
{
|
||||
GMI_DEBUG("?");
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline))) {
|
||||
GMI_DEBUG ("?");
|
||||
return TRUE;
|
||||
}
|
||||
if (priv->streaminfo == NULL)
|
||||
{
|
||||
if (priv->streaminfo == NULL) {
|
||||
/* this is not a permanent failure */
|
||||
GST_DEBUG ("Couldn't find streaminfo");
|
||||
}
|
||||
else
|
||||
} else
|
||||
GST_DEBUG ("found streaminfo of track %ld", priv->current_track_num);
|
||||
if (!gmip_find_track_streaminfo_post (priv)) return FALSE;
|
||||
if (!gmip_find_track_streaminfo_post (priv))
|
||||
return FALSE;
|
||||
priv->state = GST_MEDIA_INFO_STATE_FORMAT;
|
||||
return gmip_find_track_format_pre (priv);
|
||||
}
|
||||
case GST_MEDIA_INFO_STATE_FORMAT:
|
||||
{
|
||||
if ((priv->format == NULL) &&
|
||||
gst_bin_iterate (GST_BIN (priv->pipeline)))
|
||||
{
|
||||
GMI_DEBUG("?");
|
||||
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
|
||||
GMI_DEBUG ("?");
|
||||
return TRUE;
|
||||
}
|
||||
if (priv->format == NULL)
|
||||
{
|
||||
if (priv->format == NULL) {
|
||||
g_warning ("Couldn't find format\n");
|
||||
return FALSE;
|
||||
}
|
||||
GST_DEBUG ("found format of track %ld", priv->current_track_num);
|
||||
if (!gmip_find_track_format_post (priv)) return FALSE;
|
||||
if (!gmip_find_track_format_post (priv))
|
||||
return FALSE;
|
||||
/* save the track info */
|
||||
priv->stream->tracks = g_list_append (priv->stream->tracks,
|
||||
priv->current_track);
|
||||
|
@ -386,12 +373,10 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
priv->location = NULL;
|
||||
/* now see if we need to seek to a next track or not */
|
||||
priv->current_track_num++;
|
||||
if (priv->current_track_num < priv->stream->length_tracks)
|
||||
{
|
||||
if (priv->current_track_num < priv->stream->length_tracks) {
|
||||
gmi_seek_to_track (info, priv->current_track_num);
|
||||
priv->current_track = gmi_track_new ();
|
||||
if (!gmip_find_track_metadata_pre (priv))
|
||||
{
|
||||
if (!gmip_find_track_metadata_pre (priv)) {
|
||||
g_free (priv->current_track);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -417,14 +402,16 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp, GEr
|
|||
* read all possible info from the file pointed to by location
|
||||
* use flags to limit the type of information searched for */
|
||||
GstMediaInfoStream *
|
||||
gst_media_info_read (GstMediaInfo *info, const char *location, guint16 flags, GError **error)
|
||||
gst_media_info_read (GstMediaInfo * info, const char *location, guint16 flags,
|
||||
GError ** error)
|
||||
{
|
||||
GstMediaInfoStream *stream = NULL;
|
||||
|
||||
gst_media_info_read_with_idler (info, location, flags, error);
|
||||
if (*error) return FALSE;
|
||||
if (*error)
|
||||
return FALSE;
|
||||
while (gst_media_info_read_idler (info, &stream, error) && stream == NULL)
|
||||
/* keep looping */;
|
||||
/* keep looping */ ;
|
||||
if (*error)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct GstMediaInfoPriv GstMediaInfoPriv;
|
||||
G_BEGIN_DECLS typedef struct GstMediaInfoPriv GstMediaInfoPriv;
|
||||
typedef struct _GstMediaInfo GstMediaInfo;
|
||||
typedef struct _GstMediaInfoClass GstMediaInfoClass;
|
||||
|
||||
|
@ -43,8 +41,9 @@ struct _GstMediaInfoClass
|
|||
GObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*media_info_signal) (GstMediaInfo *gst_media_info);
|
||||
void (*error_signal) (GstMediaInfo *gst_media_info, GError *error, const gchar *debug);
|
||||
void (*media_info_signal) (GstMediaInfo * gst_media_info);
|
||||
void (*error_signal) (GstMediaInfo * gst_media_info, GError * error,
|
||||
const gchar * debug);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
@ -105,29 +104,20 @@ GQuark gst_media_info_error_quark (void);
|
|||
void gst_media_info_init (void);
|
||||
GType gst_media_info_get_type (void);
|
||||
|
||||
GstMediaInfo * gst_media_info_new (GError **error);
|
||||
GstMediaInfo *gst_media_info_new (GError ** error);
|
||||
|
||||
gboolean gst_media_info_set_source (GstMediaInfo * info,
|
||||
const char *source, GError ** error);
|
||||
void gst_media_info_read_with_idler (GstMediaInfo * media_info,
|
||||
const char *location, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
|
||||
gboolean gst_media_info_read_idler (GstMediaInfo * media_info,
|
||||
GstMediaInfoStream ** streamp, GError ** error);
|
||||
GstMediaInfoStream *gst_media_info_read (GstMediaInfo * media_info,
|
||||
const char *location, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
|
||||
gboolean gst_media_info_read_many (GstMediaInfo * media_info,
|
||||
GList * locations, guint16 GST_MEDIA_INFO_FLAGS, GError ** error);
|
||||
GstCaps *gst_media_info_get_next (GstMediaInfo * media_info, GError ** error);
|
||||
|
||||
gboolean gst_media_info_set_source (GstMediaInfo *info,
|
||||
const char *source,
|
||||
GError **error);
|
||||
void gst_media_info_read_with_idler (GstMediaInfo *media_info,
|
||||
const char *location,
|
||||
guint16 GST_MEDIA_INFO_FLAGS,
|
||||
GError **error);
|
||||
gboolean gst_media_info_read_idler (GstMediaInfo *media_info,
|
||||
GstMediaInfoStream **streamp,
|
||||
GError **error);
|
||||
GstMediaInfoStream *
|
||||
gst_media_info_read (GstMediaInfo *media_info,
|
||||
const char *location,
|
||||
guint16 GST_MEDIA_INFO_FLAGS,
|
||||
GError **error);
|
||||
gboolean gst_media_info_read_many (GstMediaInfo *media_info,
|
||||
GList *locations,
|
||||
guint16 GST_MEDIA_INFO_FLAGS,
|
||||
GError **error);
|
||||
GstCaps * gst_media_info_get_next (GstMediaInfo *media_info,
|
||||
GError **error);
|
||||
/*
|
||||
* FIXME: reset ?
|
||||
gboolean gst_media_info_write (GstMediaInfo *media_info,
|
||||
|
@ -136,5 +126,4 @@ gboolean gst_media_info_write (GstMediaInfo *media_info,
|
|||
*/
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MEDIA_INFO_H__ */
|
||||
|
|
|
@ -26,14 +26,15 @@
|
|||
#include "mixer.h"
|
||||
#include "mixer-marshal.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
MUTE_TOGGLED,
|
||||
RECORD_TOGGLED,
|
||||
VOLUME_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_mixer_class_init (GstMixerClass *klass);
|
||||
static void gst_mixer_class_init (GstMixerClass * klass);
|
||||
|
||||
static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -56,8 +57,7 @@ gst_mixer_get_type (void)
|
|||
};
|
||||
|
||||
gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstMixer",
|
||||
&gst_mixer_info, 0);
|
||||
"GstMixer", &gst_mixer_info, 0);
|
||||
g_type_interface_add_prerequisite (gst_mixer_type,
|
||||
GST_TYPE_IMPLEMENTS_INTERFACE);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ gst_mixer_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_class_init (GstMixerClass *klass)
|
||||
gst_mixer_class_init (GstMixerClass * klass)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
@ -119,7 +119,7 @@ gst_mixer_class_init (GstMixerClass *klass)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_mixer_list_tracks (GstMixer *mixer)
|
||||
gst_mixer_list_tracks (GstMixer * mixer)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -146,9 +146,7 @@ gst_mixer_list_tracks (GstMixer *mixer)
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -169,9 +167,7 @@ gst_mixer_set_volume (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_get_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -198,9 +194,7 @@ gst_mixer_get_volume (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_mute (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute)
|
||||
gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -223,9 +217,7 @@ gst_mixer_set_mute (GstMixer *mixer,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_mixer_set_record (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record)
|
||||
gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
|
||||
|
||||
|
@ -235,43 +227,30 @@ gst_mixer_set_record (GstMixer *mixer,
|
|||
}
|
||||
|
||||
void
|
||||
gst_mixer_mute_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute)
|
||||
gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[MUTE_TOGGLED], 0,
|
||||
track, mute);
|
||||
gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"mute_toggled",
|
||||
mute);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
|
||||
}
|
||||
|
||||
void
|
||||
gst_mixer_record_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record)
|
||||
gst_mixer_record_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[RECORD_TOGGLED], 0,
|
||||
track, record);
|
||||
gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"record_toggled",
|
||||
record);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
|
||||
}
|
||||
|
||||
void
|
||||
gst_mixer_volume_changed (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes)
|
||||
gst_mixer_volume_changed (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (mixer),
|
||||
gst_mixer_signals[VOLUME_CHANGED], 0,
|
||||
track, volumes);
|
||||
gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (track),
|
||||
"volume_changed",
|
||||
volumes);
|
||||
g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <gst/mixer/mixer-enumtypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIXER \
|
||||
(gst_mixer_get_type ())
|
||||
#define GST_MIXER(obj) \
|
||||
|
@ -40,9 +39,7 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
|
||||
#define GST_MIXER_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass))
|
||||
|
||||
#define GST_MIXER_TYPE(klass) (klass->mixer_type)
|
||||
|
||||
typedef struct _GstMixer GstMixer;
|
||||
|
||||
typedef enum
|
||||
|
@ -51,38 +48,28 @@ typedef enum
|
|||
GST_MIXER_SOFTWARE
|
||||
} GstMixerType;
|
||||
|
||||
typedef struct _GstMixerClass {
|
||||
typedef struct _GstMixerClass
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
GstMixerType mixer_type;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_tracks) (GstMixer *mixer);
|
||||
const GList *(*list_tracks) (GstMixer * mixer);
|
||||
|
||||
void (* set_volume) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void (* get_volume) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void (*set_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
|
||||
void (*get_volume) (GstMixer * mixer, GstMixerTrack * track, gint * volumes);
|
||||
|
||||
void (* set_mute) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void (* set_record) (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
void (*set_mute) (GstMixer * mixer, GstMixerTrack * track, gboolean mute);
|
||||
void (*set_record) (GstMixer * mixer, GstMixerTrack * track, gboolean record);
|
||||
|
||||
/* signals */
|
||||
void (* mute_toggled) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gboolean mute);
|
||||
void (* record_toggled) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gboolean record);
|
||||
void (* volume_changed) (GstMixer *mixer,
|
||||
GstMixerTrack *channel,
|
||||
gint *volumes);
|
||||
void (*mute_toggled) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gboolean mute);
|
||||
void (*record_toggled) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gboolean record);
|
||||
void (*volume_changed) (GstMixer * mixer,
|
||||
GstMixerTrack * channel, gint * volumes);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstMixerClass;
|
||||
|
@ -90,31 +77,23 @@ typedef struct _GstMixerClass {
|
|||
GType gst_mixer_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList * gst_mixer_list_tracks (GstMixer *mixer);
|
||||
void gst_mixer_set_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_get_volume (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_set_mute (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void gst_mixer_set_record (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
const GList *gst_mixer_list_tracks (GstMixer * mixer);
|
||||
void gst_mixer_set_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_mixer_get_volume (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_mixer_set_mute (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
void gst_mixer_set_record (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record);
|
||||
|
||||
/* trigger signals */
|
||||
void gst_mixer_mute_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean mute);
|
||||
void gst_mixer_record_toggled (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gboolean record);
|
||||
void gst_mixer_volume_changed (GstMixer *mixer,
|
||||
GstMixerTrack *track,
|
||||
gint *volumes);
|
||||
void gst_mixer_mute_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
void gst_mixer_record_toggled (GstMixer * mixer,
|
||||
GstMixerTrack * track, gboolean record);
|
||||
void gst_mixer_volume_changed (GstMixer * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIXER_H__ */
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
#include "mixertrack.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_VOLUME_CHANGED,
|
||||
SIGNAL_RECORD_TOGGLED,
|
||||
|
@ -33,9 +34,9 @@ enum {
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_mixer_track_class_init (GstMixerTrackClass *klass);
|
||||
static void gst_mixer_track_init (GstMixerTrack *mixer);
|
||||
static void gst_mixer_track_dispose (GObject *object);
|
||||
static void gst_mixer_track_class_init (GstMixerTrackClass * klass);
|
||||
static void gst_mixer_track_init (GstMixerTrack * mixer);
|
||||
static void gst_mixer_track_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -61,15 +62,14 @@ gst_mixer_track_get_type (void)
|
|||
|
||||
gst_mixer_track_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstMixerTrack",
|
||||
&mixer_track_info, 0);
|
||||
"GstMixerTrack", &mixer_track_info, 0);
|
||||
}
|
||||
|
||||
return gst_mixer_track_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_class_init (GstMixerTrackClass *klass)
|
||||
gst_mixer_track_class_init (GstMixerTrackClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
|
@ -101,7 +101,7 @@ gst_mixer_track_class_init (GstMixerTrackClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_init (GstMixerTrack *channel)
|
||||
gst_mixer_track_init (GstMixerTrack * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->min_volume = channel->max_volume = 0;
|
||||
|
@ -110,7 +110,7 @@ gst_mixer_track_init (GstMixerTrack *channel)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_mixer_track_dispose (GObject *object)
|
||||
gst_mixer_track_dispose (GObject * object)
|
||||
{
|
||||
GstMixerTrack *channel = GST_MIXER_TRACK (object);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_MIXER_TRACK \
|
||||
(gst_mixer_track_get_type ())
|
||||
#define GST_MIXER_TRACK(obj) \
|
||||
|
@ -38,7 +37,6 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK))
|
||||
#define GST_IS_MIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK))
|
||||
|
||||
/*
|
||||
* Naming:
|
||||
*
|
||||
|
@ -54,39 +52,36 @@ G_BEGIN_DECLS
|
|||
* mixer, which means that setting this track will change
|
||||
* the hearable volume on any output.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
GST_MIXER_TRACK_INPUT = (1<<0),
|
||||
GST_MIXER_TRACK_OUTPUT = (1<<1),
|
||||
GST_MIXER_TRACK_MUTE = (1<<2),
|
||||
GST_MIXER_TRACK_RECORD = (1<<3),
|
||||
GST_MIXER_TRACK_MASTER = (1<<4),
|
||||
GST_MIXER_TRACK_SOFTWARE = (1<<5)
|
||||
typedef enum
|
||||
{
|
||||
GST_MIXER_TRACK_INPUT = (1 << 0),
|
||||
GST_MIXER_TRACK_OUTPUT = (1 << 1),
|
||||
GST_MIXER_TRACK_MUTE = (1 << 2),
|
||||
GST_MIXER_TRACK_RECORD = (1 << 3),
|
||||
GST_MIXER_TRACK_MASTER = (1 << 4),
|
||||
GST_MIXER_TRACK_SOFTWARE = (1 << 5)
|
||||
} GstMixerTrackFlags;
|
||||
|
||||
#define GST_MIXER_TRACK_HAS_FLAG(channel, flag) \
|
||||
((channel)->flags & flag)
|
||||
|
||||
typedef struct _GstMixerTrack {
|
||||
typedef struct _GstMixerTrack
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *label;
|
||||
GstMixerTrackFlags flags;
|
||||
gint num_channels,
|
||||
min_volume,
|
||||
max_volume;
|
||||
gint num_channels, min_volume, max_volume;
|
||||
} GstMixerTrack;
|
||||
|
||||
typedef struct _GstMixerTrackClass {
|
||||
typedef struct _GstMixerTrackClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
|
||||
/* signals */
|
||||
void (* mute_toggled) (GstMixerTrack *channel,
|
||||
gboolean mute);
|
||||
void (* record_toggled) (GstMixerTrack *channel,
|
||||
gboolean record);
|
||||
void (* volume_changed) (GstMixerTrack *channel,
|
||||
gint *volumes);
|
||||
void (*mute_toggled) (GstMixerTrack * channel, gboolean mute);
|
||||
void (*record_toggled) (GstMixerTrack * channel, gboolean record);
|
||||
void (*volume_changed) (GstMixerTrack * channel, gint * volumes);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstMixerTrackClass;
|
||||
|
@ -94,5 +89,4 @@ typedef struct _GstMixerTrackClass {
|
|||
GType gst_mixer_track_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MIXER_TRACK_H__ */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <gst/navigation/navigation.h>
|
||||
|
||||
static void gst_navigation_class_init (GstNavigationInterface *iface);
|
||||
static void gst_navigation_class_init (GstNavigationInterface * iface);
|
||||
|
||||
GType
|
||||
gst_navigation_get_type (void)
|
||||
|
@ -46,22 +46,21 @@ gst_navigation_get_type (void)
|
|||
};
|
||||
|
||||
gst_navigation_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstNavigation",
|
||||
&gst_navigation_info, 0);
|
||||
"GstNavigation", &gst_navigation_info, 0);
|
||||
}
|
||||
|
||||
return gst_navigation_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_navigation_class_init (GstNavigationInterface *iface)
|
||||
gst_navigation_class_init (GstNavigationInterface * iface)
|
||||
{
|
||||
/* default virtual functions */
|
||||
iface->send_event = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
|
||||
gst_navigation_send_event (GstNavigation * navigation, GstStructure * structure)
|
||||
{
|
||||
GstNavigationInterface *iface = GST_NAVIGATION_GET_IFACE (navigation);
|
||||
|
||||
|
@ -71,25 +70,20 @@ gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
|
|||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_key_event (GstNavigation *navigation, const char *event,
|
||||
gst_navigation_send_key_event (GstNavigation * navigation, const char *event,
|
||||
const char *key)
|
||||
{
|
||||
gst_navigation_send_event (navigation, gst_structure_new (
|
||||
"application/x-gst-navigation",
|
||||
"event", G_TYPE_STRING, event,
|
||||
"key", G_TYPE_STRING, key, NULL));
|
||||
gst_navigation_send_event (navigation,
|
||||
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
|
||||
event, "key", G_TYPE_STRING, key, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
gst_navigation_send_mouse_event (GstNavigation *navigation, const char *event,
|
||||
gst_navigation_send_mouse_event (GstNavigation * navigation, const char *event,
|
||||
int button, double x, double y)
|
||||
{
|
||||
gst_navigation_send_event (navigation, gst_structure_new (
|
||||
"application/x-gst-navigation",
|
||||
"event", G_TYPE_STRING, event,
|
||||
"button", G_TYPE_INT, button,
|
||||
"pointer_x", G_TYPE_DOUBLE, x,
|
||||
gst_navigation_send_event (navigation,
|
||||
gst_structure_new ("application/x-gst-navigation", "event", G_TYPE_STRING,
|
||||
event, "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x,
|
||||
"pointer_y", G_TYPE_DOUBLE, y, NULL));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_NAVIGATION \
|
||||
(gst_navigation_get_type ())
|
||||
#define GST_NAVIGATION(obj) \
|
||||
|
@ -35,14 +34,14 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NAVIGATION))
|
||||
#define GST_NAVIGATION_GET_IFACE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_NAVIGATION, GstNavigationInterface))
|
||||
|
||||
typedef struct _GstNavigation GstNavigation;
|
||||
|
||||
typedef struct _GstNavigationInterface {
|
||||
typedef struct _GstNavigationInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* virtual functions */
|
||||
void (*send_event) (GstNavigation *navigation, GstStructure *structure);
|
||||
void (*send_event) (GstNavigation * navigation, GstStructure * structure);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstNavigationInterface;
|
||||
|
@ -50,13 +49,13 @@ typedef struct _GstNavigationInterface {
|
|||
GType gst_navigation_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
void gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure);
|
||||
void gst_navigation_send_event (GstNavigation * navigation,
|
||||
GstStructure * structure);
|
||||
|
||||
void gst_navigation_send_key_event (GstNavigation *navigation,
|
||||
void gst_navigation_send_key_event (GstNavigation * navigation,
|
||||
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);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_NAVIGATION_H__ */
|
||||
|
|
|
@ -34,7 +34,8 @@ enum
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
struct _GstPlayPrivate {
|
||||
struct _GstPlayPrivate
|
||||
{
|
||||
char *location;
|
||||
|
||||
GHashTable *elements;
|
||||
|
@ -67,13 +68,16 @@ static GstPipelineClass *parent_class = NULL;
|
|||
/* */
|
||||
/* ======================================================= */
|
||||
|
||||
static GstCaps * gst_play_video_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data);
|
||||
static GstCaps * gst_play_audio_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data);
|
||||
static GstCaps *gst_play_video_fixate (GstPad * pad, const GstCaps * caps,
|
||||
gpointer user_data);
|
||||
static GstCaps *gst_play_audio_fixate (GstPad * pad, const GstCaps * caps,
|
||||
gpointer user_data);
|
||||
|
||||
static GQuark
|
||||
gst_play_error_quark (void)
|
||||
{
|
||||
static GQuark quark = 0;
|
||||
|
||||
if (quark == 0)
|
||||
quark = g_quark_from_static_string ("gst-play-error-quark");
|
||||
return quark;
|
||||
|
@ -81,7 +85,7 @@ gst_play_error_quark (void)
|
|||
|
||||
/* General GError creation */
|
||||
static void
|
||||
gst_play_error_create (GError ** error, const gchar *message)
|
||||
gst_play_error_create (GError ** error, const gchar * message)
|
||||
{
|
||||
/* check if caller wanted an error reported */
|
||||
if (error == NULL)
|
||||
|
@ -95,15 +99,14 @@ gst_play_error_create (GError ** error, const gchar *message)
|
|||
/* FIXME: what if multiple elements could have been used and they're all
|
||||
* missing ? varargs ? */
|
||||
static void
|
||||
gst_play_error_plugin (const gchar *element, GError ** error)
|
||||
gst_play_error_plugin (const gchar * element, GError ** error)
|
||||
{
|
||||
gchar *message;
|
||||
|
||||
message = g_strdup_printf ("The %s element could not be found. "
|
||||
"This element is essential for playback. "
|
||||
"Please install the right plug-in and verify "
|
||||
"that it works by running 'gst-inspect %s'",
|
||||
element, element);
|
||||
"that it works by running 'gst-inspect %s'", element, element);
|
||||
gst_play_error_create (error, message);
|
||||
g_free (message);
|
||||
return;
|
||||
|
@ -127,20 +130,25 @@ G_STMT_START { \
|
|||
|
||||
|
||||
static gboolean
|
||||
gst_play_pipeline_setup (GstPlay *play, GError **error)
|
||||
gst_play_pipeline_setup (GstPlay * play, GError ** error)
|
||||
{
|
||||
/* Threads */
|
||||
GstElement *work_thread, *audio_thread, *video_thread;
|
||||
|
||||
/* Main Thread elements */
|
||||
GstElement *source, *autoplugger, *audioconvert, *volume, *tee, *identity;
|
||||
GstElement *identity_cs;
|
||||
|
||||
/* Visualization bin */
|
||||
GstElement *vis_bin, *vis_queue, *vis_element, *vis_cs;
|
||||
|
||||
/* Video Thread elements */
|
||||
GstElement *video_queue, *video_switch, *video_cs, *video_balance;
|
||||
GstElement *balance_cs, *video_scaler, *video_sink;
|
||||
|
||||
/* Audio Thread elements */
|
||||
GstElement *audio_queue, *audio_sink;
|
||||
|
||||
/* Some useful pads */
|
||||
GstPad *tee_pad1, *tee_pad2;
|
||||
|
||||
|
@ -162,7 +170,8 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
g_hash_table_insert (play->priv->elements, "autoplugger", autoplugger);
|
||||
|
||||
/* Make sure we convert audio to the needed format */
|
||||
GST_PLAY_MAKE_OR_ERROR (audioconvert, "audioconvert", "audioconvert", error);
|
||||
GST_PLAY_MAKE_OR_ERROR (audioconvert, "audioconvert", "audioconvert",
|
||||
error);
|
||||
g_hash_table_insert (play->priv->elements, "audioconvert", audioconvert);
|
||||
|
||||
/* Duplicate audio signal to audio sink and visualization thread */
|
||||
|
@ -173,7 +182,8 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
g_hash_table_insert (play->priv->elements, "tee_pad2", tee_pad2);
|
||||
g_hash_table_insert (play->priv->elements, "tee", tee);
|
||||
|
||||
gst_bin_add_many (GST_BIN (work_thread), source, autoplugger, audioconvert, tee, NULL);
|
||||
gst_bin_add_many (GST_BIN (work_thread), source, autoplugger, audioconvert,
|
||||
tee, NULL);
|
||||
if (!gst_element_link_many (source, autoplugger, audioconvert, tee, NULL))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link source thread elements");
|
||||
|
||||
|
@ -184,8 +194,7 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
identity_cs = gst_element_factory_make ("ffcolorspace", "identity_cs");
|
||||
if (!GST_IS_ELEMENT (identity_cs)) {
|
||||
identity_cs = gst_element_factory_make ("colorspace", "identity_cs");
|
||||
if (!GST_IS_ELEMENT (identity_cs))
|
||||
{
|
||||
if (!GST_IS_ELEMENT (identity_cs)) {
|
||||
gst_play_error_plugin ("colorspace", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -199,8 +208,7 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
/* Visualization bin (note: it s not added to the pipeline yet) */
|
||||
{
|
||||
vis_bin = gst_bin_new ("vis_bin");
|
||||
if (!GST_IS_ELEMENT (vis_bin))
|
||||
{
|
||||
if (!GST_IS_ELEMENT (vis_bin)) {
|
||||
gst_play_error_plugin ("bin", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -219,8 +227,7 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
vis_cs = gst_element_factory_make ("ffcolorspace", "vis_cs");
|
||||
if (!GST_IS_ELEMENT (vis_cs)) {
|
||||
vis_cs = gst_element_factory_make ("colorspace", "vis_cs");
|
||||
if (!GST_IS_ELEMENT (vis_cs))
|
||||
{
|
||||
if (!GST_IS_ELEMENT (vis_cs)) {
|
||||
gst_play_error_plugin ("colorspace", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -230,9 +237,10 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
|
||||
gst_bin_add_many (GST_BIN (vis_bin), vis_queue, vis_element, vis_cs, NULL);
|
||||
if (!gst_element_link_many (vis_queue, vis_element, vis_cs, NULL))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link visualisation thread elements");
|
||||
gst_element_add_ghost_pad (vis_bin,
|
||||
gst_element_get_pad (vis_cs, "src"), "src");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link visualisation thread elements");
|
||||
gst_element_add_ghost_pad (vis_bin, gst_element_get_pad (vis_cs, "src"),
|
||||
"src");
|
||||
}
|
||||
/* Creating our video output bin */
|
||||
{
|
||||
|
@ -251,8 +259,7 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
video_cs = gst_element_factory_make ("ffcolorspace", "video_cs");
|
||||
if (!GST_IS_ELEMENT (video_cs)) {
|
||||
video_cs = gst_element_factory_make ("colorspace", "video_cs");
|
||||
if (!GST_IS_ELEMENT (video_cs))
|
||||
{
|
||||
if (!GST_IS_ELEMENT (video_cs)) {
|
||||
gst_play_error_plugin ("colorspace", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -260,15 +267,15 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
g_hash_table_insert (play->priv->elements, "video_cs", video_cs);
|
||||
|
||||
/* Software colorbalance */
|
||||
GST_PLAY_MAKE_OR_ERROR (video_balance, "videobalance", "video_balance", error);
|
||||
GST_PLAY_MAKE_OR_ERROR (video_balance, "videobalance", "video_balance",
|
||||
error);
|
||||
g_hash_table_insert (play->priv->elements, "video_balance", video_balance);
|
||||
|
||||
/* Colorspace conversion */
|
||||
balance_cs = gst_element_factory_make ("ffcolorspace", "balance_cs");
|
||||
if (!GST_IS_ELEMENT (balance_cs)) {
|
||||
balance_cs = gst_element_factory_make ("colorspace", "balance_cs");
|
||||
if (!GST_IS_ELEMENT (balance_cs))
|
||||
{
|
||||
if (!GST_IS_ELEMENT (balance_cs)) {
|
||||
gst_play_error_plugin ("colorspace", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -278,33 +285,39 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
/* Software scaling of video stream */
|
||||
GST_PLAY_MAKE_OR_ERROR (video_scaler, "videoscale", "video_scaler", error);
|
||||
g_hash_table_insert (play->priv->elements, "video_scaler", video_scaler);
|
||||
g_signal_connect (gst_element_get_pad(video_scaler, "src"), "fixate",
|
||||
g_signal_connect (gst_element_get_pad (video_scaler, "src"), "fixate",
|
||||
G_CALLBACK (gst_play_video_fixate), play);
|
||||
|
||||
/* Placeholder for future video sink bin */
|
||||
GST_PLAY_MAKE_OR_ERROR (video_sink, "fakesink", "video_sink", error);
|
||||
g_hash_table_insert (play->priv->elements, "video_sink", video_sink);
|
||||
|
||||
gst_bin_add_many (GST_BIN (video_thread), video_queue, video_switch, video_cs,
|
||||
video_balance, balance_cs, video_scaler, video_sink, NULL);
|
||||
gst_bin_add_many (GST_BIN (video_thread), video_queue, video_switch,
|
||||
video_cs, video_balance, balance_cs, video_scaler, video_sink, NULL);
|
||||
/* break down linking so we can figure out what might be failing */
|
||||
if (!gst_element_link (video_queue, video_switch))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (queue and switch)");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (queue and switch)");
|
||||
if (!gst_element_link (video_switch, video_cs))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (switch and cs)");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (switch and cs)");
|
||||
if (!gst_element_link (video_cs, video_balance))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (cs and balance)");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (cs and balance)");
|
||||
if (!gst_element_link (video_balance, balance_cs))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (balance and balance_cs)");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (balance and balance_cs)");
|
||||
if (!gst_element_link (balance_cs, video_scaler))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (balance_cs and scaler)");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (balance_cs and scaler)");
|
||||
if (!gst_element_link (video_scaler, video_sink))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread (balance_cs and scaler)");
|
||||
gst_element_add_ghost_pad (video_thread,
|
||||
gst_element_get_pad (video_queue, "sink"),
|
||||
"sink");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread (balance_cs and scaler)");
|
||||
gst_element_add_ghost_pad (video_thread, gst_element_get_pad (video_queue,
|
||||
"sink"), "sink");
|
||||
if (!gst_element_link (identity_cs, video_thread))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link video output thread elements");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link video output thread elements");
|
||||
}
|
||||
/* Creating our audio output bin
|
||||
{ queue ! fakesink } */
|
||||
|
@ -320,19 +333,20 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
/* Volume control */
|
||||
GST_PLAY_MAKE_OR_ERROR (volume, "volume", "volume", error);
|
||||
g_hash_table_insert (play->priv->elements, "volume", volume);
|
||||
g_signal_connect (gst_element_get_pad(volume, "src"), "fixate",
|
||||
g_signal_connect (gst_element_get_pad (volume, "src"), "fixate",
|
||||
G_CALLBACK (gst_play_audio_fixate), play);
|
||||
|
||||
/* Placeholder for future audio sink bin */
|
||||
GST_PLAY_MAKE_OR_ERROR (audio_sink, "fakesink", "audio_sink", error);
|
||||
g_hash_table_insert (play->priv->elements, "audio_sink", audio_sink);
|
||||
|
||||
gst_bin_add_many (GST_BIN (audio_thread), audio_queue, volume, audio_sink, NULL);
|
||||
gst_bin_add_many (GST_BIN (audio_thread), audio_queue, volume, audio_sink,
|
||||
NULL);
|
||||
if (!gst_element_link_many (audio_queue, volume, audio_sink, NULL))
|
||||
GST_PLAY_ERROR_RETURN (error, "Could not link audio output thread elements");
|
||||
gst_element_add_ghost_pad (audio_thread,
|
||||
gst_element_get_pad (audio_queue, "sink"),
|
||||
"sink");
|
||||
GST_PLAY_ERROR_RETURN (error,
|
||||
"Could not link audio output thread elements");
|
||||
gst_element_add_ghost_pad (audio_thread, gst_element_get_pad (audio_queue,
|
||||
"sink"), "sink");
|
||||
gst_pad_link (tee_pad2, gst_element_get_pad (audio_queue, "sink"));
|
||||
}
|
||||
|
||||
|
@ -340,8 +354,8 @@ gst_play_pipeline_setup (GstPlay *play, GError **error)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_play_have_video_size (GstElement *element, gint width,
|
||||
gint height, GstPlay *play)
|
||||
gst_play_have_video_size (GstElement * element, gint width,
|
||||
gint height, GstPlay * play)
|
||||
{
|
||||
g_return_if_fail (play != NULL);
|
||||
g_return_if_fail (GST_IS_PLAY (play));
|
||||
|
@ -350,7 +364,7 @@ gst_play_have_video_size (GstElement *element, gint width,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_tick_callback (GstPlay *play)
|
||||
gst_play_tick_callback (GstPlay * play)
|
||||
{
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
gboolean q = FALSE;
|
||||
|
@ -358,8 +372,7 @@ gst_play_tick_callback (GstPlay *play)
|
|||
|
||||
g_return_val_if_fail (play != NULL, FALSE);
|
||||
/* just return without updating the UI when we are in the middle of seeking */
|
||||
if (play->priv->tick_unblock_remaining > 0)
|
||||
{
|
||||
if (play->priv->tick_unblock_remaining > 0) {
|
||||
play->priv->tick_unblock_remaining -= TICK_INTERVAL_MSEC;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -382,7 +395,7 @@ gst_play_tick_callback (GstPlay *play)
|
|||
|
||||
if (q)
|
||||
g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
|
||||
0,play->priv->time_nanos);
|
||||
0, play->priv->time_nanos);
|
||||
|
||||
if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING)
|
||||
return TRUE;
|
||||
|
@ -393,7 +406,7 @@ gst_play_tick_callback (GstPlay *play)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_get_length_callback (GstPlay *play)
|
||||
gst_play_get_length_callback (GstPlay * play)
|
||||
{
|
||||
GstElement *audio_sink_element, *video_sink_element;
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
|
@ -418,14 +431,14 @@ gst_play_get_length_callback (GstPlay *play)
|
|||
if (GST_IS_ELEMENT (audio_sink_element))
|
||||
q = gst_element_query (audio_sink_element, GST_QUERY_TOTAL, &format,
|
||||
&value);
|
||||
if ( (!q) && (GST_IS_ELEMENT (video_sink_element)) )
|
||||
if ((!q) && (GST_IS_ELEMENT (video_sink_element)))
|
||||
q = gst_element_query (video_sink_element, GST_QUERY_TOTAL, &format,
|
||||
&value);
|
||||
|
||||
if (q) {
|
||||
play->priv->length_nanos = value;
|
||||
g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH],
|
||||
0,play->priv->length_nanos);
|
||||
0, play->priv->length_nanos);
|
||||
play->priv->length_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -436,20 +449,20 @@ gst_play_get_length_callback (GstPlay *play)
|
|||
if (play->priv->get_length_attempt > 15) {
|
||||
play->priv->length_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_play_video_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data)
|
||||
gst_play_video_fixate (GstPad * pad, const GstCaps * caps, gpointer user_data)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstCaps *newcaps;
|
||||
|
||||
GST_DEBUG ("video fixate %p %" GST_PTR_FORMAT, pad, caps);
|
||||
|
||||
if (gst_caps_get_size (caps) > 1) return NULL;
|
||||
if (gst_caps_get_size (caps) > 1)
|
||||
return NULL;
|
||||
|
||||
newcaps = gst_caps_copy (caps);
|
||||
structure = gst_caps_get_structure (newcaps, 0);
|
||||
|
@ -471,15 +484,16 @@ gst_play_video_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_play_audio_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data)
|
||||
gst_play_audio_fixate (GstPad * pad, const GstCaps * caps, gpointer user_data)
|
||||
{
|
||||
GstCaps *newcaps;
|
||||
GstStructure *structure;
|
||||
|
||||
GST_DEBUG ("audio fixate %p %" GST_PTR_FORMAT, pad, caps);
|
||||
|
||||
newcaps = gst_caps_new_full (gst_structure_copy (
|
||||
gst_caps_get_structure (caps, 0)), NULL);
|
||||
newcaps =
|
||||
gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (caps, 0)),
|
||||
NULL);
|
||||
structure = gst_caps_get_structure (newcaps, 0);
|
||||
|
||||
if (gst_caps_structure_fixate_field_nearest_int (structure, "rate", 44100)) {
|
||||
|
@ -501,7 +515,7 @@ gst_play_audio_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_play_state_change (GstElement *element, GstElementState old,
|
||||
gst_play_state_change (GstElement * element, GstElementState old,
|
||||
GstElementState state)
|
||||
{
|
||||
GstPlay *play;
|
||||
|
@ -518,8 +532,7 @@ gst_play_state_change (GstElement *element, GstElementState old,
|
|||
}
|
||||
|
||||
play->priv->tick_id = g_timeout_add (TICK_INTERVAL_MSEC,
|
||||
(GSourceFunc) gst_play_tick_callback,
|
||||
play);
|
||||
(GSourceFunc) gst_play_tick_callback, play);
|
||||
|
||||
play->priv->get_length_attempt = 0;
|
||||
|
||||
|
@ -529,10 +542,8 @@ gst_play_state_change (GstElement *element, GstElementState old,
|
|||
}
|
||||
|
||||
play->priv->length_id = g_timeout_add (TICK_INTERVAL_MSEC,
|
||||
(GSourceFunc) gst_play_get_length_callback,
|
||||
play);
|
||||
}
|
||||
else {
|
||||
(GSourceFunc) gst_play_get_length_callback, play);
|
||||
} else {
|
||||
if (play->priv->tick_id) {
|
||||
g_source_remove (play->priv->tick_id);
|
||||
play->priv->tick_id = 0;
|
||||
|
@ -548,7 +559,8 @@ gst_play_state_change (GstElement *element, GstElementState old,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_play_identity_handoff (GstElement *identity, GstBuffer *buf, GstPlay *play)
|
||||
gst_play_identity_handoff (GstElement * identity, GstBuffer * buf,
|
||||
GstPlay * play)
|
||||
{
|
||||
g_signal_handler_disconnect (G_OBJECT (identity), play->priv->handoff_hid);
|
||||
play->priv->handoff_hid = 0;
|
||||
|
@ -562,7 +574,7 @@ gst_play_identity_handoff (GstElement *identity, GstBuffer *buf, GstPlay *play)
|
|||
/* =========================================== */
|
||||
|
||||
static void
|
||||
gst_play_dispose (GObject *object)
|
||||
gst_play_dispose (GObject * object)
|
||||
{
|
||||
GstPlay *play;
|
||||
|
||||
|
@ -595,7 +607,7 @@ gst_play_dispose (GObject *object)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_play_init (GstPlay *play)
|
||||
gst_play_init (GstPlay * play)
|
||||
{
|
||||
play->priv = g_new0 (GstPlayPrivate, 1);
|
||||
play->priv->location = NULL;
|
||||
|
@ -605,15 +617,14 @@ gst_play_init (GstPlay *play)
|
|||
play->priv->error = NULL;
|
||||
play->priv->debug = NULL;
|
||||
|
||||
if (!gst_play_pipeline_setup (play, &play->priv->error))
|
||||
{
|
||||
if (!gst_play_pipeline_setup (play, &play->priv->error)) {
|
||||
g_warning ("libgstplay: failed initializing pipeline, error: %s",
|
||||
play->priv->error->message);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_class_init (GstPlayClass *klass)
|
||||
gst_play_class_init (GstPlayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
@ -637,8 +648,7 @@ gst_play_class_init (GstPlayClass *klass)
|
|||
g_signal_new ("have-video-size", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GstPlayClass, have_video_size), NULL, NULL,
|
||||
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
|
||||
G_TYPE_INT, G_TYPE_INT);
|
||||
gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
|
||||
}
|
||||
|
||||
/* ======================================================= */
|
||||
|
@ -657,7 +667,7 @@ gst_play_class_init (GstPlayClass *klass)
|
|||
* Returns: TRUE if location was set successfully.
|
||||
*/
|
||||
gboolean
|
||||
gst_play_set_location (GstPlay *play, const char *location)
|
||||
gst_play_set_location (GstPlay * play, const char *location)
|
||||
{
|
||||
GstElement *work_thread, *source, *autoplugger;
|
||||
GstElement *audioconvert, *identity;
|
||||
|
@ -728,7 +738,7 @@ gst_play_set_location (GstPlay *play, const char *location)
|
|||
* Returns: a const #char* pointer to current location.
|
||||
*/
|
||||
char *
|
||||
gst_play_get_location (GstPlay *play)
|
||||
gst_play_get_location (GstPlay * play)
|
||||
{
|
||||
g_return_val_if_fail (play != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
|
||||
|
@ -757,8 +767,7 @@ gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
|
|||
"audioconvert");
|
||||
audio_sink_element = g_hash_table_lookup (play->priv->elements,
|
||||
"audio_sink_element");
|
||||
video_seek_element = g_hash_table_lookup (play->priv->elements,
|
||||
"identity");
|
||||
video_seek_element = g_hash_table_lookup (play->priv->elements, "identity");
|
||||
|
||||
if (GST_IS_ELEMENT (audio_seek_element) &&
|
||||
GST_IS_ELEMENT (video_seek_element) &&
|
||||
|
@ -771,12 +780,10 @@ gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
|
|||
play->priv->tick_unblock_remaining = 500;
|
||||
|
||||
s = gst_element_seek (video_seek_element, GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
|
||||
time_nanos);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, time_nanos);
|
||||
if (!s) {
|
||||
s = gst_element_seek (audio_seek_element, GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
|
||||
time_nanos);
|
||||
GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH, time_nanos);
|
||||
}
|
||||
|
||||
if (s) {
|
||||
|
@ -788,7 +795,7 @@ gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
|
|||
|
||||
if (q)
|
||||
g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
|
||||
0,play->priv->time_nanos);
|
||||
0, play->priv->time_nanos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,7 +812,7 @@ gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
|
|||
* Returns: TRUE if call succeeded.
|
||||
*/
|
||||
gboolean
|
||||
gst_play_set_data_src (GstPlay *play, GstElement *data_src)
|
||||
gst_play_set_data_src (GstPlay * play, GstElement * data_src)
|
||||
{
|
||||
GstElement *work_thread, *old_data_src, *autoplugger;
|
||||
|
||||
|
@ -850,7 +857,7 @@ gst_play_set_data_src (GstPlay *play, GstElement *data_src)
|
|||
* Returns: TRUE if call succeeded.
|
||||
*/
|
||||
gboolean
|
||||
gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
|
||||
gst_play_set_video_sink (GstPlay * play, GstElement * video_sink)
|
||||
{
|
||||
GstElement *video_thread, *old_video_sink, *video_scaler, *video_sink_element;
|
||||
|
||||
|
@ -890,12 +897,11 @@ gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
|
|||
video_sink_element);
|
||||
if (GST_IS_X_OVERLAY (video_sink_element)) {
|
||||
g_signal_connect (G_OBJECT (video_sink_element),
|
||||
"desired_size_changed",
|
||||
G_CALLBACK (gst_play_have_video_size), play);
|
||||
"desired_size_changed", G_CALLBACK (gst_play_have_video_size), play);
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_set_state (video_sink, GST_STATE (GST_ELEMENT(play)));
|
||||
gst_element_set_state (video_sink, GST_STATE (GST_ELEMENT (play)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -910,7 +916,7 @@ gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
|
|||
* Returns: TRUE if call succeeded.
|
||||
*/
|
||||
gboolean
|
||||
gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
|
||||
gst_play_set_audio_sink (GstPlay * play, GstElement * audio_sink)
|
||||
{
|
||||
GstElement *old_audio_sink, *audio_thread, *volume, *audio_sink_element;
|
||||
|
||||
|
@ -950,7 +956,7 @@ gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
|
|||
audio_sink_element);
|
||||
}
|
||||
|
||||
gst_element_set_state (audio_sink, GST_STATE (GST_ELEMENT(play)));
|
||||
gst_element_set_state (audio_sink, GST_STATE (GST_ELEMENT (play)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -965,7 +971,7 @@ gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
|
|||
* Returns: TRUE if call succeeded.
|
||||
*/
|
||||
gboolean
|
||||
gst_play_set_visualization (GstPlay *play, GstElement *vis_element)
|
||||
gst_play_set_visualization (GstPlay * play, GstElement * vis_element)
|
||||
{
|
||||
GstElement *vis_bin, *vis_queue, *old_vis_element, *vis_cs;
|
||||
gboolean was_playing = FALSE;
|
||||
|
@ -982,8 +988,7 @@ gst_play_set_visualization (GstPlay *play, GstElement *vis_element)
|
|||
vis_queue = g_hash_table_lookup (play->priv->elements, "vis_queue");
|
||||
if (!GST_IS_ELEMENT (vis_queue))
|
||||
return FALSE;
|
||||
old_vis_element = g_hash_table_lookup (play->priv->elements,
|
||||
"vis_element");
|
||||
old_vis_element = g_hash_table_lookup (play->priv->elements, "vis_element");
|
||||
if (!GST_IS_ELEMENT (old_vis_element))
|
||||
return FALSE;
|
||||
vis_cs = g_hash_table_lookup (play->priv->elements, "vis_cs");
|
||||
|
@ -1079,8 +1084,7 @@ gst_play_connect_visualization (GstPlay * play, gboolean connect)
|
|||
gst_element_release_request_pad (video_switch, switch_pad);
|
||||
gst_object_ref (GST_OBJECT (vis_bin));
|
||||
gst_bin_remove (GST_BIN (video_thread), vis_bin);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
/* If we are supposed to disconnect then nothing to do we return */
|
||||
if (!connect) {
|
||||
|
@ -1097,8 +1101,7 @@ gst_play_connect_visualization (GstPlay * play, gboolean connect)
|
|||
|
||||
/* Adding, linking */
|
||||
play->priv->handoff_hid = g_signal_connect (G_OBJECT (identity),
|
||||
"handoff",
|
||||
G_CALLBACK (gst_play_identity_handoff), play);
|
||||
"handoff", G_CALLBACK (gst_play_identity_handoff), play);
|
||||
gst_bin_add (GST_BIN (video_thread), vis_bin);
|
||||
gst_pad_link (tee_pad1, vis_queue_pad);
|
||||
gst_element_link (vis_bin, video_switch);
|
||||
|
@ -1122,8 +1125,8 @@ gst_play_connect_visualization (GstPlay * play, gboolean connect)
|
|||
* Returns: the sink #GstElement of @element.
|
||||
*/
|
||||
GstElement *
|
||||
gst_play_get_sink_element (GstPlay *play,
|
||||
GstElement *element, GstPlaySinkType sink_type)
|
||||
gst_play_get_sink_element (GstPlay * play,
|
||||
GstElement * element, GstPlaySinkType sink_type)
|
||||
{
|
||||
GList *elements = NULL;
|
||||
const GList *pads = NULL;
|
||||
|
@ -1153,8 +1156,7 @@ gst_play_get_sink_element (GstPlay *play,
|
|||
element = gst_play_get_sink_element (play, element, sink_type);
|
||||
if (GST_IS_ELEMENT (element))
|
||||
return element;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pads = gst_element_get_pad_list (element);
|
||||
has_src = FALSE;
|
||||
has_correct_type = FALSE;
|
||||
|
@ -1163,8 +1165,7 @@ gst_play_get_sink_element (GstPlay *play,
|
|||
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC) {
|
||||
has_src = TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* If not a src pad checking caps */
|
||||
GstCaps *caps;
|
||||
GstStructure *structure;
|
||||
|
@ -1223,20 +1224,17 @@ gst_play_get_sink_element (GstPlay *play,
|
|||
}
|
||||
|
||||
GstPlay *
|
||||
gst_play_new (GError **error)
|
||||
gst_play_new (GError ** error)
|
||||
{
|
||||
GstPlay *play = g_object_new (GST_TYPE_PLAY, NULL);
|
||||
|
||||
if (play->priv->error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
if (play->priv->error) {
|
||||
if (error) {
|
||||
*error = play->priv->error;
|
||||
play->priv->error = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Error creating GstPlay object.\n%s", play->priv->error->message);
|
||||
} else {
|
||||
g_warning ("Error creating GstPlay object.\n%s",
|
||||
play->priv->error->message);
|
||||
g_error_free (play->priv->error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,37 +60,29 @@ struct _GstPlayClass
|
|||
{
|
||||
GstPipelineClass parent_class;
|
||||
|
||||
void (*time_tick) (GstPlay *play, gint64 time_nanos);
|
||||
void (*stream_length) (GstPlay *play, gint64 length_nanos);
|
||||
void (*have_video_size) (GstPlay *play, gint width, gint height);
|
||||
void (*time_tick) (GstPlay * play, gint64 time_nanos);
|
||||
void (*stream_length) (GstPlay * play, gint64 length_nanos);
|
||||
void (*have_video_size) (GstPlay * play, gint width, gint height);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_play_get_type (void);
|
||||
GstPlay * gst_play_new (GError **error);
|
||||
GstPlay *gst_play_new (GError ** error);
|
||||
|
||||
gboolean gst_play_set_data_src (GstPlay *play,
|
||||
GstElement *data_src);
|
||||
gboolean gst_play_set_video_sink (GstPlay *play,
|
||||
GstElement *video_sink);
|
||||
gboolean gst_play_set_audio_sink (GstPlay *play,
|
||||
GstElement *audio_sink);
|
||||
gboolean gst_play_set_data_src (GstPlay * play, GstElement * data_src);
|
||||
gboolean gst_play_set_video_sink (GstPlay * play, GstElement * video_sink);
|
||||
gboolean gst_play_set_audio_sink (GstPlay * play, GstElement * audio_sink);
|
||||
|
||||
gboolean gst_play_set_visualization (GstPlay *play,
|
||||
GstElement *element);
|
||||
gboolean gst_play_connect_visualization (GstPlay *play,
|
||||
gboolean connect);
|
||||
gboolean gst_play_set_visualization (GstPlay * play, GstElement * element);
|
||||
gboolean gst_play_connect_visualization (GstPlay * play, gboolean connect);
|
||||
|
||||
gboolean gst_play_set_location (GstPlay *play,
|
||||
const char *location);
|
||||
char * gst_play_get_location (GstPlay *play);
|
||||
gboolean gst_play_set_location (GstPlay * play, const char *location);
|
||||
char *gst_play_get_location (GstPlay * play);
|
||||
|
||||
gboolean gst_play_seek_to_time (GstPlay *play,
|
||||
gint64 time_nanos);
|
||||
gboolean gst_play_seek_to_time (GstPlay * play, gint64 time_nanos);
|
||||
|
||||
GstElement * gst_play_get_sink_element (GstPlay *play,
|
||||
GstElement *element,
|
||||
GstPlaySinkType sink_type);
|
||||
GstElement *gst_play_get_sink_element (GstPlay * play,
|
||||
GstElement * element, GstPlaySinkType sink_type);
|
||||
|
||||
#endif /* __GST_PLAY_H__ */
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
|
||||
#include "propertyprobe.h"
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
SIGNAL_PROBE_NEEDED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_property_probe_iface_init (GstPropertyProbeInterface *iface);
|
||||
static void gst_property_probe_iface_init (GstPropertyProbeInterface * iface);
|
||||
|
||||
static guint gst_property_probe_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -56,23 +57,22 @@ gst_property_probe_get_type (void)
|
|||
|
||||
gst_property_probe_type =
|
||||
g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstPropertyProbe",
|
||||
&gst_property_probe_info, 0);
|
||||
"GstPropertyProbe", &gst_property_probe_info, 0);
|
||||
}
|
||||
|
||||
return gst_property_probe_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
|
||||
gst_property_probe_iface_init (GstPropertyProbeInterface * iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized) {
|
||||
gst_property_probe_signals[SIGNAL_PROBE_NEEDED] =
|
||||
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstPropertyProbeInterface, probe_needed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
g_signal_new ("probe-needed", G_TYPE_FROM_CLASS (iface),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPropertyProbeInterface,
|
||||
probe_needed), NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ gst_property_probe_iface_init (GstPropertyProbeInterface *iface)
|
|||
*/
|
||||
|
||||
const GList *
|
||||
gst_property_probe_get_properties (GstPropertyProbe *probe)
|
||||
gst_property_probe_get_properties (GstPropertyProbe * probe)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -108,8 +108,7 @@ gst_property_probe_get_properties (GstPropertyProbe *probe)
|
|||
}
|
||||
|
||||
const GParamSpec *
|
||||
gst_property_probe_get_property (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_get_property (GstPropertyProbe * probe, const gchar * name)
|
||||
{
|
||||
const GList *pspecs = gst_property_probe_get_properties (probe);
|
||||
|
||||
|
@ -129,8 +128,8 @@ gst_property_probe_get_property (GstPropertyProbe *probe,
|
|||
}
|
||||
|
||||
void
|
||||
gst_property_probe_probe_property (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_probe_property (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -156,8 +155,8 @@ gst_property_probe_probe_property (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
void
|
||||
gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_probe_property_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -188,8 +187,8 @@ gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
gboolean
|
||||
gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_needs_probe (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -215,8 +214,8 @@ gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
gboolean
|
||||
gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -244,8 +243,8 @@ gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -271,8 +270,8 @@ gst_property_probe_get_values (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
@ -301,8 +300,8 @@ gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec)
|
||||
gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec)
|
||||
{
|
||||
GstPropertyProbeInterface *iface;
|
||||
|
||||
|
@ -328,8 +327,8 @@ gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
|||
*/
|
||||
|
||||
GValueArray *
|
||||
gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name)
|
||||
gst_property_probe_probe_and_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name)
|
||||
{
|
||||
const GParamSpec *pspec;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_PROPERTY_PROBE \
|
||||
(gst_property_probe_get_type ())
|
||||
#define GST_PROPERTY_PROBE(obj) \
|
||||
|
@ -34,27 +33,23 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PROPERTY_PROBE))
|
||||
#define GST_PROPERTY_PROBE_GET_IFACE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_PROPERTY_PROBE, GstPropertyProbeInterface))
|
||||
|
||||
typedef struct _GstPropertyProbe GstPropertyProbe; /* dummy typedef */
|
||||
|
||||
typedef struct _GstPropertyProbeInterface {
|
||||
typedef struct _GstPropertyProbeInterface
|
||||
{
|
||||
GTypeInterface klass;
|
||||
|
||||
/* signals */
|
||||
void (*probe_needed) (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
void (*probe_needed) (GstPropertyProbe * probe, const GParamSpec * pspec);
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (*get_properties) (GstPropertyProbe *probe);
|
||||
gboolean (*needs_probe) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
void (*probe_property) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * (*get_values) (GstPropertyProbe *probe,
|
||||
guint prop_id,
|
||||
const GParamSpec *pspec);
|
||||
const GList *(*get_properties) (GstPropertyProbe * probe);
|
||||
gboolean (*needs_probe) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
void (*probe_property) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
GValueArray *(*get_values) (GstPropertyProbe * probe,
|
||||
guint prop_id, const GParamSpec * pspec);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
} GstPropertyProbeInterface;
|
||||
|
@ -64,34 +59,33 @@ GType gst_property_probe_get_type (void);
|
|||
/* virtual class function wrappers */
|
||||
|
||||
/* returns list of GParamSpecs */
|
||||
const GList * gst_property_probe_get_properties (GstPropertyProbe *probe);
|
||||
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
const GList *gst_property_probe_get_properties (GstPropertyProbe * probe);
|
||||
const GParamSpec *gst_property_probe_get_property (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* probe one property */
|
||||
void gst_property_probe_probe_property (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
void gst_property_probe_probe_property_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
void gst_property_probe_probe_property (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
void gst_property_probe_probe_property_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* do we need a probe? */
|
||||
gboolean gst_property_probe_needs_probe (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
gboolean gst_property_probe_needs_probe (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
gboolean gst_property_probe_needs_probe_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* returns list of GValues */
|
||||
GValueArray * gst_property_probe_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * gst_property_probe_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
GValueArray *gst_property_probe_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
GValueArray *gst_property_probe_get_values_name (GstPropertyProbe * probe,
|
||||
const gchar * name);
|
||||
|
||||
/* sugar */
|
||||
GValueArray * gst_property_probe_probe_and_get_values (GstPropertyProbe *probe,
|
||||
const GParamSpec *pspec);
|
||||
GValueArray * gst_property_probe_probe_and_get_values_name (GstPropertyProbe *probe,
|
||||
const gchar *name);
|
||||
GValueArray *gst_property_probe_probe_and_get_values (GstPropertyProbe * probe,
|
||||
const GParamSpec * pspec);
|
||||
GValueArray *gst_property_probe_probe_and_get_values_name (GstPropertyProbe *
|
||||
probe, const gchar * name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PROPERTY_PROBE_H__ */
|
||||
|
|
|
@ -29,40 +29,46 @@
|
|||
/*#include <ml.h> */
|
||||
#include "private.h"
|
||||
|
||||
void conv_double_float_ref(double *dest, float *src, int n)
|
||||
void
|
||||
conv_double_float_ref (double *dest, float *src, int n)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<n;i++){
|
||||
dest[i]=src[i];
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void conv_float_double_ref(float *dest, double *src, int n)
|
||||
void
|
||||
conv_float_double_ref (float *dest, double *src, int n)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<n;i++){
|
||||
dest[i]=src[i];
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void conv_double_float_dstr(double *dest, float *src, int n, int dstr)
|
||||
void
|
||||
conv_double_float_dstr (double *dest, float *src, int n, int dstr)
|
||||
{
|
||||
int i;
|
||||
void *d = dest;
|
||||
for(i=0;i<n;i++){
|
||||
(*(double *)d)=*src++;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
(*(double *) d) = *src++;
|
||||
d += dstr;
|
||||
}
|
||||
}
|
||||
|
||||
void conv_float_double_sstr(float *dest, double *src, int n, int sstr)
|
||||
void
|
||||
conv_float_double_sstr (float *dest, double *src, int n, int sstr)
|
||||
{
|
||||
int i;
|
||||
void *s = src;
|
||||
|
||||
for(i=0;i<n;i++){
|
||||
*dest++ = *(double *)s;
|
||||
for (i = 0; i < n; i++) {
|
||||
*dest++ = *(double *) s;
|
||||
s += sstr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue