From 52e314ef812478661a56f2141e0958f332bb92d1 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 15 Oct 2009 16:15:03 +0300 Subject: [PATCH] camerabin: set camerabin default sources/sinks like in playbin2. Fixes #574434 This uses same approach like in playbin, namely checking for user defined element, auto{audio,video}{sink,src} and finally DEFAULT_{AUDIO,VIDEO}{SRC,SINK} defines from config.h. --- configure.ac | 3 ++ gst/camerabin/camerabingeneral.c | 49 +++++++++++++++++++++- gst/camerabin/camerabingeneral.h | 2 + gst/camerabin/camerabinvideo.c | 17 ++++---- gst/camerabin/gstcamerabin.c | 70 +++++++++++++------------------- 5 files changed, 91 insertions(+), 50 deletions(-) diff --git a/configure.ac b/configure.ac index 1bd4d668c1..6092881aa4 100644 --- a/configure.ac +++ b/configure.ac @@ -246,6 +246,9 @@ AG_GST_SET_ERROR_CXXFLAGS($GST_CVS) dnl define correct level for debugging messages AG_GST_SET_LEVEL_DEFAULT($GST_CVS) +dnl used in examples +AG_GST_DEFAULT_ELEMENTS + dnl *** plug-ins to include *** dnl these are all the gst plug-ins, compilable without additional libs diff --git a/gst/camerabin/camerabingeneral.c b/gst/camerabin/camerabingeneral.c index ba6b82a968..635a4b6a92 100644 --- a/gst/camerabin/camerabingeneral.c +++ b/gst/camerabin/camerabingeneral.c @@ -117,7 +117,7 @@ gst_camerabin_try_add_element (GstBin * bin, GstElement * new_elem) GstElement * gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name) { - GstElement *new_elem = NULL; + GstElement *new_elem; new_elem = gst_element_factory_make (elem_name, NULL); if (!new_elem) { @@ -130,6 +130,53 @@ gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name) return new_elem; } +/* try to change the state of an element. This function returns the element when + * the state change could be performed. When this function returns NULL an error + * occured and the element is unreffed if @unref is TRUE. */ +static GstElement * +try_element (GstElement * bin, GstElement * element, gboolean unref) +{ + GstStateChangeReturn ret; + + if (element) { + ret = gst_element_set_state (element, GST_STATE_READY); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_DEBUG_OBJECT (bin, "failed state change.."); + gst_element_set_state (element, GST_STATE_NULL); + if (unref) + gst_object_unref (element); + element = NULL; + } + } + return element; +} + +GstElement * +gst_camerabin_setup_default_element (GstBin * bin, GstElement * user_elem, + const gchar * auto_elem_name, const gchar * default_elem_name) +{ + GstElement *elem; + + if (user_elem) { + GST_DEBUG_OBJECT (bin, "trying configured element"); + elem = try_element (bin, user_elem, FALSE); + } else { + /* only try fallback if no specific sink was chosen */ + GST_DEBUG_OBJECT (bin, "trying %s", auto_elem_name); + elem = gst_element_factory_make (auto_elem_name, NULL); + elem = try_element (bin, elem, TRUE); + if (elem == NULL) { + /* if default sink from config.h is different then try it too */ + if (strcmp (default_elem_name, auto_elem_name)) { + GST_DEBUG_OBJECT (bin, "trying %s", default_elem_name); + elem = gst_element_factory_make (default_elem_name, NULL); + elem = try_element (bin, elem, TRUE); + } + } + } + return elem; +} + /** * gst_camerabin_remove_elements_from_bin: * @bin: removes all elements from this bin diff --git a/gst/camerabin/camerabingeneral.h b/gst/camerabin/camerabingeneral.h index 13eea756a1..1270aed817 100644 --- a/gst/camerabin/camerabingeneral.h +++ b/gst/camerabin/camerabingeneral.h @@ -27,6 +27,8 @@ gboolean gst_camerabin_try_add_element (GstBin * bin, GstElement * new_elem); gboolean gst_camerabin_add_element (GstBin * bin, GstElement * new_elem); GstElement *gst_camerabin_create_and_add_element (GstBin * bin, const gchar * elem_name); +GstElement * gst_camerabin_setup_default_element (GstBin * bin, GstElement *user_elem, const gchar *auto_elem_name, const gchar *default_elem_name); + void gst_camerabin_remove_elements_from_bin (GstBin * bin); gboolean gst_camerabin_drop_eos_probe (GstPad * pad, GstEvent * event, gpointer u_data); diff --git a/gst/camerabin/camerabinvideo.c b/gst/camerabin/camerabinvideo.c index f9c9d8759a..6ca4161336 100644 --- a/gst/camerabin/camerabinvideo.c +++ b/gst/camerabin/camerabinvideo.c @@ -51,6 +51,9 @@ * includes */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include "camerabingeneral.h" @@ -63,7 +66,6 @@ /* internal element names */ -#define DEFAULT_AUD_SRC "pulsesrc" #define DEFAULT_AUD_ENC "vorbisenc" #define DEFAULT_VID_ENC "theoraenc" #define DEFAULT_MUX "oggmux" @@ -616,14 +618,13 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid) NULL); /* Add user set or default audio source element */ - if (vid->user_aud_src) { - vid->aud_src = vid->user_aud_src; - if (!gst_camerabin_add_element (vidbin, vid->aud_src)) { - goto error; - } - } else if (!(vid->aud_src = - gst_camerabin_create_and_add_element (vidbin, DEFAULT_AUD_SRC))) { + if (!(vid->aud_src = gst_camerabin_setup_default_element (vidbin, + vid->user_aud_src, "autoaudiosrc", DEFAULT_AUDIOSRC))) { + vid->aud_src = NULL; goto error; + } else { + if (!gst_camerabin_add_element (vidbin, vid->aud_src)) + goto error; } /* Add queue element for audio */ diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c index 13c4e4b9c7..7fe31b722e 100644 --- a/gst/camerabin/gstcamerabin.c +++ b/gst/camerabin/gstcamerabin.c @@ -226,12 +226,6 @@ static guint camerabin_signals[LAST_SIGNAL]; //#define USE_VIEWFINDER_COLOR_CONVERTER 1 //#define USE_VIEWFINDER_SCALE 1 -/* internal element names */ - -/* FIXME: Make sure this can work with autovideosrc and use that. */ -#define DEFAULT_SRC_VID_SRC "v4l2src" -#define DEFAULT_VIEW_SINK "autovideosink" - /* message names */ #define PREVIEW_MESSAGE_NAME "preview-image" #define IMG_CAPTURED_MESSAGE_NAME "image-captured" @@ -558,16 +552,15 @@ camerabin_create_src_elements (GstCameraBin * camera) GstBin *cbin = GST_BIN (camera); gchar *driver_name = NULL; - if (camera->user_vid_src) { - camera->src_vid_src = camera->user_vid_src; - - if (!gst_camerabin_add_element (cbin, camera->src_vid_src)) { - camera->src_vid_src = NULL; - goto done; - } - } else if (!(camera->src_vid_src = - gst_camerabin_create_and_add_element (cbin, DEFAULT_SRC_VID_SRC))) + /* Add user set or default video src element */ + if (!(camera->src_vid_src = gst_camerabin_setup_default_element (cbin, + camera->user_vid_src, "autovideosrc", DEFAULT_VIDEOSRC))) { + camera->src_vid_src = NULL; goto done; + } else { + if (!gst_camerabin_add_element (cbin, camera->src_vid_src)) + goto done; + } #ifdef USE_COLOR_CONVERTER if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace")) goto done; @@ -646,10 +639,10 @@ static gboolean camerabin_create_view_elements (GstCameraBin * camera) { const GList *pads; + GstBin *cbin = GST_BIN (camera); if (!(camera->view_in_sel = - gst_camerabin_create_and_add_element (GST_BIN (camera), - "input-selector"))) { + gst_camerabin_create_and_add_element (cbin, "input-selector"))) { goto error; } @@ -664,33 +657,29 @@ camerabin_create_view_elements (GstCameraBin * camera) #ifdef USE_VIEWFINDER_CONVERTERS /* Add videoscale in case we need to downscale frame for view finder */ if (!(camera->view_scale = - gst_camerabin_create_and_add_element (GST_BIN (camera), - "videoscale"))) { + gst_camerabin_create_and_add_element (cbin, "videoscale"))) { goto error; } /* Add capsfilter to maintain aspect ratio while scaling */ if (!(camera->aspect_filter = - gst_camerabin_create_and_add_element (GST_BIN (camera), - "capsfilter"))) { + gst_camerabin_create_and_add_element (cbin, "capsfilter"))) { goto error; } #endif #ifdef USE_VIEWFINDER_COLOR_CONVERTER - if (!gst_camerabin_create_and_add_element (GST_BIN (camera), - "ffmpegcolorspace")) { + if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace")) { goto error; } #endif - if (camera->user_vf_sink) { - camera->view_sink = camera->user_vf_sink; - if (!gst_camerabin_add_element (GST_BIN (camera), camera->view_sink)) { - goto error; - } - } else if (!(camera->view_sink = - gst_camerabin_create_and_add_element (GST_BIN (camera), - DEFAULT_VIEW_SINK))) { + /* Add user set or default video sink element */ + if (!(camera->view_sink = gst_camerabin_setup_default_element (cbin, + camera->user_vf_sink, "autovideosink", DEFAULT_VIDEOSINK))) { + camera->view_sink = NULL; goto error; + } else { + if (!gst_camerabin_add_element (cbin, camera->view_sink)) + goto error; } return TRUE; @@ -1652,8 +1641,7 @@ gst_camerabin_send_video_eos (GstCameraBin * camera) gst_pad_send_event (videopad, gst_event_new_eos ()); gst_object_unref (videopad); camera->eos_handled = TRUE; - } - else { + } else { GST_INFO_OBJECT (camera, "dropping duplicate EOS"); } } @@ -2472,41 +2460,41 @@ gst_camerabin_class_init (GstCameraBinClass * klass) * GstCameraBin:vfsink: * * Set up a sink element to render frames in view finder. - * By default "autovideosink" will be the sink element. + * By default "autovideosink" or DEFAULT_VIDEOSINK will be used. * This property can only be set while #GstCameraBin is in NULL state. * The ownership of the element will be taken by #GstCameraBin. */ g_object_class_install_property (gobject_class, ARG_VF_SINK, g_param_spec_object ("vfsink", "View finder sink", - "View finder sink GStreamer element (default is " DEFAULT_VIEW_SINK - ")", GST_TYPE_ELEMENT, G_PARAM_READWRITE)); + "View finder sink GStreamer element (NULL = default video sink)", + GST_TYPE_ELEMENT, G_PARAM_READWRITE)); /** * GstCameraBin:videosrc: * * Set up a video source element. - * By default "v4l2src" will be the src element. + * By default "autovideosrc" or DEFAULT_VIDEOSRC will be used. * This property can only be set while #GstCameraBin is in NULL state. * The ownership of the element will be taken by #GstCameraBin. */ g_object_class_install_property (gobject_class, ARG_VIDEO_SRC, g_param_spec_object ("videosrc", "Video source element", - "Video source GStreamer element (default is " DEFAULT_SRC_VID_SRC ")", + "Video source GStreamer element (NULL = default video src)", GST_TYPE_ELEMENT, G_PARAM_READWRITE)); /** * GstCameraBin:audiosrc: * * Set up an audio source element. - * By default "pulsesrc" will be the source element. + * By default "autoaudiosrc" or DEFAULT_AUDIOSRC will be used. * This property can only be set while #GstCameraBin is in NULL state. * The ownership of the element will be taken by #GstCameraBin. */ g_object_class_install_property (gobject_class, ARG_AUDIO_SRC, g_param_spec_object ("audiosrc", "Audio source element", - "Audio source GStreamer element (default is pulsesrc)", + "Audio source GStreamer element (NULL = default audio src)", GST_TYPE_ELEMENT, G_PARAM_READWRITE)); /** @@ -2898,7 +2886,7 @@ gst_camerabin_set_property (GObject * object, guint prop_id, new_caps = (GstCaps *) gst_value_get_caps (value); GST_DEBUG_OBJECT (camera, "setting preview caps: %" GST_PTR_FORMAT " -> %" GST_PTR_FORMAT, - camera->preview_caps, new_caps); + camera->preview_caps, new_caps); if (!gst_caps_is_equal (camera->preview_caps, new_caps)) { GST_OBJECT_LOCK (camera);