time_tick works.

Original commit message from CVS:
time_tick works.
have_video_size works.
This commit is contained in:
Julien Moutte 2003-12-07 19:02:31 +00:00
parent 6077e73e63
commit bacc26059b
4 changed files with 384 additions and 4 deletions

View file

@ -220,6 +220,53 @@ gst_play_pipeline_setup (GstPlay *play)
return TRUE;
}
static void
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));
g_signal_emit (G_OBJECT (play), gst_play_signals[HAVE_VIDEO_SIZE],
0, width, height);
}
static gboolean
gst_play_tick_callback (GstPlay *play)
{
GstClock *clock = NULL;
g_return_val_if_fail (play != NULL, FALSE);
g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
clock = gst_bin_get_clock (GST_BIN (play));
play->time_nanos = gst_clock_get_time (clock);
g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
0,play->time_nanos);
return (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING);
}
static void
gst_play_state_change (GstElement *element, GstElementState old,
GstElementState state)
{
GstPlay *play;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_PLAY (element));
play = GST_PLAY (element);
if (state == GST_STATE_PLAYING)
{
g_timeout_add (200, (GSourceFunc) gst_play_tick_callback, play);
}
if (GST_ELEMENT_CLASS (parent_class)->state_change)
GST_ELEMENT_CLASS (parent_class)->state_change (element, old, state);
}
/* =========================================== */
/* */
/* Interfaces */
@ -323,11 +370,14 @@ static void
gst_play_class_init (GstPlayClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gobject_class->dispose = gst_play_dispose;
element_class->state_change = gst_play_state_change;
gst_play_signals[TIME_TICK] =
g_signal_new ("time_tick", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstPlayClass, time_tick), NULL, NULL,
@ -511,7 +561,7 @@ gst_play_set_data_src (GstPlay *play, GstElement *data_src)
gboolean
gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
{
GstElement *video_thread, *old_video_sink, *video_scaler;
GstElement *video_thread, *old_video_sink, *video_scaler, *video_sink_element;
g_return_val_if_fail (play != NULL, FALSE);
g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
@ -540,6 +590,17 @@ gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
g_hash_table_replace (play->elements, "video_sink", video_sink);
video_sink_element = gst_play_get_sink_element (play, video_sink,
GST_PLAY_SINK_TYPE_VIDEO);
if (GST_IS_ELEMENT (video_sink_element))
{
g_hash_table_replace (play->elements, "video_sink_element",
video_sink_element);
g_signal_connect (G_OBJECT (video_sink_element), "have_video_size",
G_CALLBACK (gst_play_have_video_size), play);
}
return TRUE;
}
@ -596,6 +657,125 @@ gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
return TRUE;
}
/**
* gst_play_get_sink_element:
* @play: a #GstPlay.
* @element: a #GstElement.
* @sink_type: a #GstPlaySinkType.
*
* Searches recursively for a sink #GstElement with
* type @sink_type in @element which is supposed to be a #GstBin.
*
* Returns: the sink #GstElement of @element.
*/
GstElement *
gst_play_get_sink_element (GstPlay *play,
GstElement *element, GstPlaySinkType sink_type)
{
GList *elements = NULL;
const GList *pads = NULL;
gboolean has_src, has_correct_type;
g_return_val_if_fail (play != NULL, NULL);
g_return_val_if_fail (element != NULL, NULL);
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
if (!GST_IS_BIN (element))
{
/* since its not a bin, we'll presume this
* element is a sink element */
return element;
}
elements = (GList *) gst_bin_get_list (GST_BIN (element));
/* traverse all elements looking for a src pad */
while (elements)
{
element = GST_ELEMENT (elements->data);
/* Recursivity :) */
if (GST_IS_BIN (element))
{
element = gst_play_get_sink_element (play, element, sink_type);
if (GST_IS_ELEMENT (element))
{
return element;
}
}
else
{
pads = gst_element_get_pad_list (element);
has_src = FALSE;
has_correct_type = FALSE;
while (pads)
{
/* check for src pad */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC)
{
has_src = TRUE;
break;
}
else
{
/* If not a src pad checking caps */
GstCaps *caps;
caps = gst_pad_get_caps (GST_PAD (pads->data));
while (caps)
{
gboolean has_video_cap = FALSE, has_audio_cap = FALSE;
if (g_ascii_strcasecmp (gst_caps_get_mime (caps),
"audio/x-raw-int") == 0)
{
has_audio_cap = TRUE;
}
if ((g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-yuv") == 0) ||
(g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-rgb") == 0))
{
has_video_cap = TRUE;
}
switch (sink_type)
{
case GST_PLAY_SINK_TYPE_AUDIO:
if (has_audio_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_VIDEO:
if (has_video_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_ANY:
if ((has_video_cap) || (has_audio_cap))
has_correct_type = TRUE;
break;;
default:
has_correct_type = FALSE;
}
caps = caps->next;
}
}
pads = g_list_next (pads);
}
if ((!has_src) && (has_correct_type))
{
return element;
}
}
elements = g_list_next (elements);
}
/* we didn't find a sink element */
return NULL;
}
GstPlay *
gst_play_new (void)
{

View file

@ -29,6 +29,13 @@
#define GST_IS_PLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY))
#define GST_PLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PLAY, GstPlayClass))
typedef enum
{
GST_PLAY_SINK_TYPE_AUDIO,
GST_PLAY_SINK_TYPE_VIDEO,
GST_PLAY_SINK_TYPE_ANY,
} GstPlaySinkType;
typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass;
@ -59,6 +66,9 @@ struct _GstPlayClass
GType gst_play_get_type (void);
GstPlay * gst_play_new (void);
GstElement * gst_play_get_sink_element (GstPlay *play,
GstElement *element,
GstPlaySinkType sink_type);
gboolean gst_play_set_data_src (GstPlay *play,
GstElement *data_src);
gboolean gst_play_set_video_sink (GstPlay *play,

View file

@ -220,6 +220,53 @@ gst_play_pipeline_setup (GstPlay *play)
return TRUE;
}
static void
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));
g_signal_emit (G_OBJECT (play), gst_play_signals[HAVE_VIDEO_SIZE],
0, width, height);
}
static gboolean
gst_play_tick_callback (GstPlay *play)
{
GstClock *clock = NULL;
g_return_val_if_fail (play != NULL, FALSE);
g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
clock = gst_bin_get_clock (GST_BIN (play));
play->time_nanos = gst_clock_get_time (clock);
g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
0,play->time_nanos);
return (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING);
}
static void
gst_play_state_change (GstElement *element, GstElementState old,
GstElementState state)
{
GstPlay *play;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_PLAY (element));
play = GST_PLAY (element);
if (state == GST_STATE_PLAYING)
{
g_timeout_add (200, (GSourceFunc) gst_play_tick_callback, play);
}
if (GST_ELEMENT_CLASS (parent_class)->state_change)
GST_ELEMENT_CLASS (parent_class)->state_change (element, old, state);
}
/* =========================================== */
/* */
/* Interfaces */
@ -323,11 +370,14 @@ static void
gst_play_class_init (GstPlayClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gobject_class->dispose = gst_play_dispose;
element_class->state_change = gst_play_state_change;
gst_play_signals[TIME_TICK] =
g_signal_new ("time_tick", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstPlayClass, time_tick), NULL, NULL,
@ -511,7 +561,7 @@ gst_play_set_data_src (GstPlay *play, GstElement *data_src)
gboolean
gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
{
GstElement *video_thread, *old_video_sink, *video_scaler;
GstElement *video_thread, *old_video_sink, *video_scaler, *video_sink_element;
g_return_val_if_fail (play != NULL, FALSE);
g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
@ -540,6 +590,17 @@ gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
g_hash_table_replace (play->elements, "video_sink", video_sink);
video_sink_element = gst_play_get_sink_element (play, video_sink,
GST_PLAY_SINK_TYPE_VIDEO);
if (GST_IS_ELEMENT (video_sink_element))
{
g_hash_table_replace (play->elements, "video_sink_element",
video_sink_element);
g_signal_connect (G_OBJECT (video_sink_element), "have_video_size",
G_CALLBACK (gst_play_have_video_size), play);
}
return TRUE;
}
@ -596,6 +657,125 @@ gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
return TRUE;
}
/**
* gst_play_get_sink_element:
* @play: a #GstPlay.
* @element: a #GstElement.
* @sink_type: a #GstPlaySinkType.
*
* Searches recursively for a sink #GstElement with
* type @sink_type in @element which is supposed to be a #GstBin.
*
* Returns: the sink #GstElement of @element.
*/
GstElement *
gst_play_get_sink_element (GstPlay *play,
GstElement *element, GstPlaySinkType sink_type)
{
GList *elements = NULL;
const GList *pads = NULL;
gboolean has_src, has_correct_type;
g_return_val_if_fail (play != NULL, NULL);
g_return_val_if_fail (element != NULL, NULL);
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
if (!GST_IS_BIN (element))
{
/* since its not a bin, we'll presume this
* element is a sink element */
return element;
}
elements = (GList *) gst_bin_get_list (GST_BIN (element));
/* traverse all elements looking for a src pad */
while (elements)
{
element = GST_ELEMENT (elements->data);
/* Recursivity :) */
if (GST_IS_BIN (element))
{
element = gst_play_get_sink_element (play, element, sink_type);
if (GST_IS_ELEMENT (element))
{
return element;
}
}
else
{
pads = gst_element_get_pad_list (element);
has_src = FALSE;
has_correct_type = FALSE;
while (pads)
{
/* check for src pad */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC)
{
has_src = TRUE;
break;
}
else
{
/* If not a src pad checking caps */
GstCaps *caps;
caps = gst_pad_get_caps (GST_PAD (pads->data));
while (caps)
{
gboolean has_video_cap = FALSE, has_audio_cap = FALSE;
if (g_ascii_strcasecmp (gst_caps_get_mime (caps),
"audio/x-raw-int") == 0)
{
has_audio_cap = TRUE;
}
if ((g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-yuv") == 0) ||
(g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-rgb") == 0))
{
has_video_cap = TRUE;
}
switch (sink_type)
{
case GST_PLAY_SINK_TYPE_AUDIO:
if (has_audio_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_VIDEO:
if (has_video_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_ANY:
if ((has_video_cap) || (has_audio_cap))
has_correct_type = TRUE;
break;;
default:
has_correct_type = FALSE;
}
caps = caps->next;
}
}
pads = g_list_next (pads);
}
if ((!has_src) && (has_correct_type))
{
return element;
}
}
elements = g_list_next (elements);
}
/* we didn't find a sink element */
return NULL;
}
GstPlay *
gst_play_new (void)
{

View file

@ -29,6 +29,13 @@
#define GST_IS_PLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY))
#define GST_PLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PLAY, GstPlayClass))
typedef enum
{
GST_PLAY_SINK_TYPE_AUDIO,
GST_PLAY_SINK_TYPE_VIDEO,
GST_PLAY_SINK_TYPE_ANY,
} GstPlaySinkType;
typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass;
@ -59,6 +66,9 @@ struct _GstPlayClass
GType gst_play_get_type (void);
GstPlay * gst_play_new (void);
GstElement * gst_play_get_sink_element (GstPlay *play,
GstElement *element,
GstPlaySinkType sink_type);
gboolean gst_play_set_data_src (GstPlay *play,
GstElement *data_src);
gboolean gst_play_set_video_sink (GstPlay *play,