diff options
Diffstat (limited to 'gst-libs/gst/play')
-rw-r--r-- | gst-libs/gst/play/play.c | 125 |
1 files changed, 95 insertions, 30 deletions
diff --git a/gst-libs/gst/play/play.c b/gst-libs/gst/play/play.c index db352464..892270bc 100644 --- a/gst-libs/gst/play/play.c +++ b/gst-libs/gst/play/play.c @@ -132,14 +132,25 @@ G_STMT_START { \ } G_STMT_END +/* setup parts of the pipeline + * only put decoding part in the thread + * create all others and keep them around + */ + static gboolean gst_play_pipeline_setup (GstPlay * play, GError ** error) { /* Threads */ GstElement *work_thread, *audio_thread, *video_thread; + /* output bin */ + GstElement *output_bin; + /* Main Thread elements */ - GstElement *source, *autoplugger, *audioconvert, *volume, *tee, *identity; + GstElement *source, *autoplugger; + + /* output bin elements */ + GstElement *audioconvert, *volume, *tee, *identity; GstElement *identity_cs; /* Visualization bin */ @@ -158,6 +169,7 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) g_return_val_if_fail (play != NULL, FALSE); g_return_val_if_fail (GST_IS_PLAY (play), FALSE); + GST_DEBUG_OBJECT (play, "setting up pipeline"); /* Creating main thread and its elements */ { GST_PLAY_MAKE_OR_ERROR (work_thread, "thread", "work_thread", error); @@ -172,6 +184,16 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) GST_PLAY_MAKE_OR_ERROR (autoplugger, "spider", "autoplugger", error); g_hash_table_insert (play->priv->elements, "autoplugger", autoplugger); + /* adding and linking */ + gst_bin_add_many (GST_BIN (work_thread), source, autoplugger, NULL); + if (!gst_element_link (source, autoplugger)) + GST_PLAY_ERROR_RETURN (error, "Could not link source and autoplugger"); + } + + /* output bin */ + { + GST_PLAY_MAKE_OR_ERROR (output_bin, "bin", "output_bin", error); + g_hash_table_insert (play->priv->elements, "output_bin", output_bin); /* Make sure we convert audio to the needed format */ GST_PLAY_MAKE_OR_ERROR (audioconvert, "audioconvert", "audioconvert", error); @@ -185,10 +207,9 @@ 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); - if (!gst_element_link_many (source, autoplugger, audioconvert, tee, NULL)) - GST_PLAY_ERROR_RETURN (error, "Could not link source thread elements"); + gst_bin_add_many (GST_BIN (output_bin), audioconvert, tee, NULL); + if (!gst_element_link (audioconvert, tee)) + GST_PLAY_ERROR_RETURN (error, "Could not link audio thread elements"); /* identity ! colorspace ! switch */ GST_PLAY_MAKE_OR_ERROR (identity, "identity", "identity", error); @@ -207,9 +228,10 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) } } g_hash_table_insert (play->priv->elements, "identity_cs", identity_cs); - gst_bin_add_many (GST_BIN (work_thread), identity, identity_cs, NULL); + gst_bin_add_many (GST_BIN (output_bin), identity, identity_cs, NULL); if (!gst_element_link_many (autoplugger, identity, identity_cs, NULL)) GST_PLAY_ERROR_RETURN (error, "Could not link work thread elements"); + gst_bin_add (GST_BIN (work_thread), output_bin); } /* Visualization bin (note: it s not added to the pipeline yet) */ @@ -256,7 +278,7 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) { GST_PLAY_MAKE_OR_ERROR (video_thread, "thread", "video_thread", error); g_hash_table_insert (play->priv->elements, "video_thread", video_thread); - gst_bin_add (GST_BIN (work_thread), video_thread); + gst_bin_add (GST_BIN (output_bin), video_thread); /* Buffer queue for video data */ GST_PLAY_MAKE_OR_ERROR (video_queue, "queue", "video_queue", error); @@ -340,7 +362,7 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) { GST_PLAY_MAKE_OR_ERROR (audio_thread, "thread", "audio_thread", error); g_hash_table_insert (play->priv->elements, "audio_thread", audio_thread); - gst_bin_add (GST_BIN (work_thread), audio_thread); + gst_bin_add (GST_BIN (output_bin), audio_thread); /* Buffer queue for our audio thread */ GST_PLAY_MAKE_OR_ERROR (audio_queue, "queue", "audio_queue", error); @@ -366,6 +388,7 @@ gst_play_pipeline_setup (GstPlay * play, GError ** error) gst_pad_link (tee_pad2, gst_element_get_pad (audio_queue, "sink")); } + GST_DEBUG_OBJECT (play, "setting up pipeline succeeded."); return TRUE; } @@ -432,6 +455,7 @@ gst_play_get_length_callback (GstPlay * play) g_return_val_if_fail (play != NULL, FALSE); g_return_val_if_fail (GST_IS_PLAY (play), FALSE); + GST_DEBUG_OBJECT (play, "trying to get length"); /* We try to get length from all real sink elements */ audio_sink_element = g_hash_table_lookup (play->priv->elements, "audio_sink_element"); @@ -444,15 +468,25 @@ gst_play_get_length_callback (GstPlay * play) } /* Audio first and then Video */ - if (GST_IS_ELEMENT (audio_sink_element)) + if (GST_IS_ELEMENT (audio_sink_element)) { + GST_DEBUG_OBJECT (play, "querying for length on audio sink"); q = gst_element_query (audio_sink_element, GST_QUERY_TOTAL, &format, &value); - if ((!q) && (GST_IS_ELEMENT (video_sink_element))) - q = gst_element_query (video_sink_element, GST_QUERY_TOTAL, &format, - &value); + } else + GST_DEBUG_OBJECT (play, "no audio sink element"); + if (!q) { + GST_DEBUG_OBJECT (play, "no query result from audio sink"); + if (GST_IS_ELEMENT (video_sink_element)) { + GST_DEBUG_OBJECT (play, "querying for length on video sink"); + q = gst_element_query (video_sink_element, GST_QUERY_TOTAL, &format, + &value); + } + } if (q) { play->priv->length_nanos = value; + GST_DEBUG_OBJECT (play, "got length, %" GST_TIME_FORMAT, + GST_TIME_ARGS ((GstClockTime) value)); g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH], 0, play->priv->length_nanos); play->priv->length_id = 0; @@ -460,6 +494,8 @@ gst_play_get_length_callback (GstPlay * play) } play->priv->get_length_attempt++; + GST_DEBUG_OBJECT (play, "no length yet, was attempt %d", + play->priv->get_length_attempt); /* We try 16 times */ if (play->priv->get_length_attempt > 15) { @@ -782,16 +818,20 @@ gst_play_get_location (GstPlay * play) * * Performs a seek on @play until @time_nanos. */ +/* FIXME: use GstClockTime for 0.9 */ gboolean gst_play_seek_to_time (GstPlay * play, gint64 time_nanos) { GstElement *audio_seek_element, *video_seek_element, *audio_sink_element; + GstClockTime seek_to; g_return_val_if_fail (play != NULL, FALSE); g_return_val_if_fail (GST_IS_PLAY (play), FALSE); + g_return_val_if_fail (time_nanos >= 0L, FALSE); - if (time_nanos < 0LL) - time_nanos = 0LL; + seek_to = (GstClockTime) time_nanos; + GST_DEBUG_OBJECT (play, "seeking to time %" GST_TIME_FORMAT, + GST_TIME_ARGS (seek_to)); audio_seek_element = g_hash_table_lookup (play->priv->elements, "audioconvert"); @@ -849,6 +889,8 @@ gst_play_set_data_src (GstPlay * play, GstElement * data_src) g_return_val_if_fail (play != NULL, FALSE); g_return_val_if_fail (GST_IS_PLAY (play), FALSE); + GST_DEBUG_OBJECT (play, "setting new data src element %s", + GST_ELEMENT_NAME (data_src)); /* We bring back the pipeline to READY */ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY) { GstElementStateReturn ret; @@ -1248,18 +1290,25 @@ gst_play_get_sink_element (GstPlay * play, g_return_val_if_fail (GST_IS_PLAY (play), NULL); g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); + GST_DEBUG_OBJECT (play, "looking for sink element in %s", + GST_ELEMENT_NAME (element)); + if (!GST_IS_BIN (element)) { - /* since its not a bin, we'll presume this + /* since its not a bin, we'll assume this * element is a sink element */ + GST_DEBUG_OBJECT (play, "not a bin, returning %s as sink element", + GST_ELEMENT_NAME (element)); return element; } elements = (GList *) gst_bin_get_list (GST_BIN (element)); - /* traverse all elements looking for a src pad */ + /* traverse all elements looking for one without src pad */ while (elements) { element = GST_ELEMENT (elements->data); + GST_DEBUG_OBJECT (play, "looking at element %s", + GST_ELEMENT_NAME (element)); /* Recursivity :) */ @@ -1274,28 +1323,41 @@ gst_play_get_sink_element (GstPlay * play, while (pads) { /* check for src pad */ if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC) { + GST_DEBUG_OBJECT (play, "element %s has a src pad", + GST_ELEMENT_NAME (element)); has_src = TRUE; break; } else { /* If not a src pad checking caps */ + GstPad *pad; GstCaps *caps; GstStructure *structure; + int i; gboolean has_video_cap = FALSE; gboolean has_audio_cap = FALSE; - caps = gst_pad_get_caps (GST_PAD (pads->data)); - structure = gst_caps_get_structure (caps, 0); - - if (strcmp (gst_structure_get_name (structure), - "audio/x-raw-int") == 0) { - has_audio_cap = TRUE; - } - - if (strcmp (gst_structure_get_name (structure), - "video/x-raw-yuv") == 0 || - strcmp (gst_structure_get_name (structure), - "video/x-raw-rgb") == 0) { - has_video_cap = TRUE; + pad = GST_PAD (pads->data); + caps = gst_pad_get_caps (pad); + /* loop over all caps members to find mime types */ + for (i = 0; i < gst_caps_get_size (caps); ++i) { + structure = gst_caps_get_structure (caps, i); + + GST_DEBUG_OBJECT (play, + "looking at caps %d pad %s:%s on element %s with mime %s", i, + GST_DEBUG_PAD_NAME (pad), + GST_ELEMENT_NAME (element), gst_structure_get_name (structure)); + + if (strcmp (gst_structure_get_name (structure), + "audio/x-raw-int") == 0) { + has_audio_cap = TRUE; + } + + if (strcmp (gst_structure_get_name (structure), + "video/x-raw-yuv") == 0 || + strcmp (gst_structure_get_name (structure), + "video/x-raw-rgb") == 0) { + has_video_cap = TRUE; + } } gst_caps_free (caps); @@ -1322,8 +1384,11 @@ gst_play_get_sink_element (GstPlay * play, } - if ((!has_src) && (has_correct_type)) + if ((!has_src) && (has_correct_type)) { + GST_DEBUG_OBJECT (play, "found %s with src pad and correct type", + GST_ELEMENT_NAME (element)); return element; + } } elements = g_list_next (elements); |