/* make the element (bin) that contains the elements needed to perform * video display. We connect a handoff signal to identity so that we * can grab snapshots. Identity's sinkpad is ghosted to vbin. * * +-------------------------------------------------------------+ * | vbin | * | +--------+ +----------+ +----------+ +---------+ | * | |identity| |colorspace| |videoscale| |videosink| | * | +-sink src-sink src-sink src-sink | | * | | +---+----+ +----------+ +----------+ +---------+ | * sink-+ | | * +----------|--------------------------------------------------+ * handoff */ static GstElement * gen_video_element (GstPlayBin * play_bin) { GstElement *element; GstElement *conv; GstElement *scale; GstElement *sink; GstElement *identity; GstPad *pad; // halley GstPad * play_bin_src_pad = NULL; GstCaps * play_bin_src_caps = NULL; GstStructure *structure; const gchar* structure_name = NULL; int m_b_va_stream = 0; GstIterator *iter; gboolean done = FALSE; gpointer data = NULL; GstElement *child=NULL; gboolean res = TRUE; gchar *temp_name = NULL; /* first see if we have it in the cache */ element = g_hash_table_lookup (play_bin->cache, "vbin"); if (element != NULL) { return element; } if (play_bin->video_sink) { sink = play_bin->video_sink; } else { PRINT_MARK; sink = gst_element_factory_make ("autovideosink", "videosink"); if (sink == NULL) { sink = gst_element_factory_make ("xvimagesink", "videosink"); } if (sink == NULL) goto no_sinks; } gst_object_ref (sink); g_hash_table_insert (play_bin->cache, "video_sink", sink); /* create a bin to hold objects, as we create them we add them to this bin so * that when something goes wrong we only need to unref the bin */ element = gst_bin_new ("vbin"); gst_bin_add (GST_BIN_CAST (element), sink); // halley #if 1 iter = gst_bin_iterate_elements (GST_BIN_CAST(play_bin)); while (!done) { switch (gst_iterator_next (iter, &data)) { case GST_ITERATOR_OK: { child = GST_ELEMENT_CAST (data); temp_name = gst_element_get_name (child); if(!strncmp(temp_name, "decodebin",9)) { GstIterator *iter_2 = NULL; gboolean done_2 = FALSE; gpointer data_2 = NULL; GstElement *child_2=NULL; gboolean res_2 = TRUE; gchar *temp_name_2 = NULL; iter_2 = gst_bin_iterate_elements (GST_BIN_CAST(child)); while (!done_2) { switch (gst_iterator_next (iter_2, &data_2)) { case GST_ITERATOR_OK: { child_2 = GST_ELEMENT_CAST (data_2); temp_name_2 = gst_element_get_name (child_2); PRINTF("====element name -2:%s\n",temp_name_2); g_free (temp_name_2); if ((play_bin_src_pad = gst_element_get_pad (child_2, "src")) == NULL) { PRINTF("===Error, we can't find the src pad of play_bin, wuwu~~~\n"); break; } PRINT_MARK; if (play_bin_src_caps = gst_pad_get_caps (play_bin_src_pad) == NULL) { PRINTF("===Error, we can't find the src caps of play_bin, wuwu~~~\n"); break; } PRINT_MARK; if (GST_IS_BIN(child_2)) { PRINTF("it is a bin\n"); } else { PRINTF("it is not a bin\n"); } PRINT_MARK; if ((structure = gst_caps_get_structure (play_bin_src_caps, 0)) == NULL) { PRINTF("===Error, we can't find the src structure of play_bin, wuwu~~~\n"); break; } PRINT_MARK; structure_name = gst_structure_get_name(structure); PRINTF("==== structure_name: %s====\n",structure_name); gst_object_unref (structure); gst_object_unref (structure_name); gst_object_unref (child_2); } break; case GST_ITERATOR_RESYNC: gst_iterator_resync (iter_2); res_2 = TRUE; break; case GST_ITERATOR_DONE: done_2 = TRUE; break; case GST_ITERATOR_ERROR: g_assert_not_reached (); break; } } gst_iterator_free (iter_2); } g_free (temp_name); // gst_object_unref (child); } break; case GST_ITERATOR_RESYNC: gst_iterator_resync (iter); res = TRUE; break; case GST_ITERATOR_DONE: done = TRUE; break; case GST_ITERATOR_ERROR: g_assert_not_reached (); break; } } gst_iterator_free (iter); #if 0 if (strcmp (structure_name, "video/x-raw-va") == 0) { m_b_va_stream = 1; } else { m_b_va_stream = 0; } PRINTF("===m_b_va_stream:%d\n",m_b_va_stream); #endif #endif #if 0 conv = gst_element_factory_make ("ffmpegcolorspace", "vconv"); if (conv == NULL) goto no_colorspace; gst_bin_add (GST_BIN_CAST (element), conv); scale = gst_element_factory_make ("videoscale", "vscale"); if (scale == NULL) goto no_videoscale; gst_bin_add (GST_BIN_CAST (element), scale); identity = gst_element_factory_make ("identity", "id"); g_object_set (identity, "silent", TRUE, NULL); g_signal_connect (identity, "handoff", G_CALLBACK (handoff), play_bin); gst_bin_add (GST_BIN_CAST (element), identity); gst_element_link_pads (identity, "src", conv, "sink"); gst_element_link_pads (conv, "src", scale, "sink"); /* be more careful with the pad from the custom sink element, it might not * be named 'sink' */ if (!gst_element_link_pads (scale, "src", sink, NULL)) goto link_failed; #else PRINT_MARK; identity = gst_element_factory_make ("identity", "id"); g_object_set (identity, "silent", TRUE, NULL); g_signal_connect (identity, "handoff", G_CALLBACK (handoff), play_bin); gst_bin_add (GST_BIN_CAST (element), identity); /* be more careful with the pad from the custom sink element, it might not * be named 'sink' */ if (!gst_element_link_pads (identity, "src", sink, NULL)) goto link_failed; PRINT_MARK; #endif pad = gst_element_get_pad (identity, "sink"); gst_element_add_pad (element, gst_ghost_pad_new ("sink", pad)); gst_object_unref (pad); gst_element_set_state (element, GST_STATE_READY); /* since we're gonna add it to a bin but don't want to lose it, * we keep a reference. */ gst_object_ref (element); g_hash_table_insert (play_bin->cache, "vbin", element); return element; /* ERRORS */ no_sinks: { post_missing_element_message (play_bin, "autovideosink"); GST_ELEMENT_ERROR (play_bin, CORE, MISSING_PLUGIN, (_("Both autovideosink and xvimagesink elements are missing.")), (NULL)); return NULL; } no_colorspace: { post_missing_element_message (play_bin, "ffmpegcolorspace"); GST_ELEMENT_ERROR (play_bin, CORE, MISSING_PLUGIN, (_("Missing element '%s' - check your GStreamer installation."), "ffmpegcolorspace"), (NULL)); gst_object_unref (element); return NULL; } no_videoscale: { post_missing_element_message (play_bin, "videoscale"); GST_ELEMENT_ERROR (play_bin, CORE, MISSING_PLUGIN, (_("Missing element '%s' - check your GStreamer installation."), "videoscale"), ("possibly a liboil version mismatch?")); gst_object_unref (element); return NULL; } link_failed: { GST_ELEMENT_ERROR (play_bin, CORE, PAD, (NULL), ("Failed to configure the video sink.")); gst_object_unref (element); return NULL; } }