From 2609427ada306d6cc9ce9b96b91d4d5406d5c81c Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Thu, 30 Jun 2011 11:09:44 +0200 Subject: [PATCH] camerabin2: Add flags prop to toggle encodebin conversion elements A flags property has been added to encodebin to toggle whether the conversion elements (ffmpegcolorspace, videoscale, audioconvert, audioresample, audiorate) are created and linked into the appropriate branches of encodebin. Not including these elements avoids some slow caps negotiation and allows the first buffers to flow through encodebin much more quickly. However, it imposes that the uncompressed input is appropriate for the target profile and elements selected to meet that profile. --- gst/camerabin2/gstcamerabin2.c | 55 ++++++++++++++++++- gst/camerabin2/gstcamerabin2.h | 10 ++++ .../examples/camerabin2/gst-camerabin2-test.c | 5 ++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index abdd35386d..b444fb28e6 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -124,7 +124,8 @@ enum PROP_ZOOM, PROP_MAX_ZOOM, PROP_IMAGE_ENCODING_PROFILE, - PROP_IDLE + PROP_IDLE, + PROP_FLAGS }; enum @@ -142,6 +143,7 @@ static guint camerabin_signals[LAST_SIGNAL]; #define DEFAULT_POST_PREVIEWS TRUE #define DEFAULT_MUTE_AUDIO FALSE #define DEFAULT_IDLE TRUE +#define DEFAULT_FLAGS 0 #define DEFAULT_AUDIO_SRC "autoaudiosrc" @@ -161,6 +163,31 @@ static void gst_camera_bin_handle_message (GstBin * bin, GstMessage * message); static gboolean gst_camera_bin_send_event (GstElement * element, GstEvent * event); +#define C_FLAGS(v) ((guint) v) +#define GST_TYPE_CAM_FLAGS (gst_cam_flags_get_type()) +static GType +gst_cam_flags_get_type (void) +{ + static const GFlagsValue values[] = { + {C_FLAGS (GST_CAM_FLAG_NO_AUDIO_CONVERSION), "Do not use audio conversion " + "elements", "no-audio-conversion"}, + {C_FLAGS (GST_CAM_FLAG_NO_VIDEO_CONVERSION), "Do not use video conversion " + "elements", "no-video-conversion"}, + {0, NULL, NULL} + }; + static volatile GType id = 0; + + if (g_once_init_enter ((gsize *) & id)) { + GType _id; + + _id = g_flags_register_static ("GstCamFlags", values); + + g_once_init_leave ((gsize *) & id, _id); + } + + return id; +} + GType gst_camera_bin2_get_type (void) { @@ -658,6 +685,16 @@ gst_camera_bin_class_init (GstCameraBin2Class * klass) "The caps that the camera source can produce on the viewfinder pad", GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * GstCameraBin:flags + * + * Control the behaviour of encodebin. + */ + g_object_class_install_property (object_class, PROP_FLAGS, + g_param_spec_flags ("flags", "Flags", "Flags to control behaviour", + GST_TYPE_CAM_FLAGS, DEFAULT_FLAGS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstCameraBin2::capture-start: * @camera: the camera bin element @@ -692,6 +729,7 @@ gst_camera_bin_init (GstCameraBin2 * camera) camera->viewfinderbin = gst_element_factory_make ("viewfinderbin", "vf-bin"); camera->zoom = DEFAULT_ZOOM; camera->max_zoom = MAX_ZOOM; + camera->flags = DEFAULT_FLAGS; /* capsfilters are created here as we proxy their caps properties and * this way we avoid having to store the caps while on NULL state to @@ -1064,6 +1102,7 @@ gst_camera_bin_create_elements (GstCameraBin2 * camera) gboolean has_audio; gboolean profile_switched = FALSE; const gchar *missing_element_name; + gint encbin_flags = 0; if (!camera->elements_created) { /* TODO check that elements created in _init were really created */ @@ -1078,6 +1117,14 @@ gst_camera_bin_create_elements (GstCameraBin2 * camera) g_signal_connect (camera->video_encodebin, "element-added", (GCallback) encodebin_element_added, camera); + /* propagate the flags property by translating appropriate values + * to GstEncFlags values */ + if (camera->flags & GST_CAM_FLAG_NO_AUDIO_CONVERSION) + encbin_flags |= (1 << 0); + if (camera->flags & GST_CAM_FLAG_NO_VIDEO_CONVERSION) + encbin_flags |= (1 << 1); + g_object_set (camera->video_encodebin, "flags", encbin_flags, NULL); + camera->videosink = gst_element_factory_make ("filesink", "videobin-filesink"); g_object_set (camera->videosink, "async", FALSE, NULL); @@ -1677,6 +1724,9 @@ gst_camera_bin_set_property (GObject * object, guint prop_id, (GstEncodingProfile *) gst_value_dup_mini_object (value); camera->image_profile_switch = TRUE; break; + case PROP_FLAGS: + camera->flags = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1835,6 +1885,9 @@ gst_camera_bin_get_property (GObject * object, guint prop_id, g_value_set_boolean (value, g_atomic_int_get (&camera->processing_counter) == 0); break; + case PROP_FLAGS: + g_value_set_flags (value, camera->flags); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h index 1dc9c00986..d5a37f034e 100644 --- a/gst/camerabin2/gstcamerabin2.h +++ b/gst/camerabin2/gstcamerabin2.h @@ -31,6 +31,15 @@ G_BEGIN_DECLS #define GST_IS_CAMERA_BIN2(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CAMERA_BIN2)) #define GST_IS_CAMERA_BIN2_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CAMERA_BIN2)) +typedef enum +{ + /* matches GstEncFlags GST_ENC_FLAG_NO_AUDIO_CONVERSION in encodebin */ + GST_CAM_FLAG_NO_AUDIO_CONVERSION = (1 << 0), + /* matches GstEncFlags GST_ENC_FLAG_NO_VIDEO_CONVERSION in encodebin */ + GST_CAM_FLAG_NO_VIDEO_CONVERSION = (1 << 1) +} GstCamFlags; + + typedef struct _GstCameraBin2 GstCameraBin2; typedef struct _GstCameraBin2Class GstCameraBin2Class; @@ -92,6 +101,7 @@ struct _GstCameraBin2 GstEncodingProfile *image_profile; gfloat zoom; gfloat max_zoom; + GstCamFlags flags; gboolean elements_created; }; diff --git a/tests/examples/camerabin2/gst-camerabin2-test.c b/tests/examples/camerabin2/gst-camerabin2-test.c index abeeb9d022..4e74927645 100644 --- a/tests/examples/camerabin2/gst-camerabin2-test.c +++ b/tests/examples/camerabin2/gst-camerabin2-test.c @@ -217,6 +217,7 @@ static gchar *viewfinder_caps_str = NULL; static gchar *video_capture_caps_str = NULL; static gboolean performance_measure = FALSE; static gchar *performance_targets_str = NULL; +static gchar *camerabin2_flags = NULL; #define MODE_VIDEO 2 @@ -676,6 +677,8 @@ setup_pipeline (void) GST_INFO_OBJECT (camerabin, "camerabin2 created"); + gst_util_set_object_arg (camerabin, "flags", camerabin2_flags); + if (videosrc_name) { GstElement *wrapper; GstElement *videosrc; @@ -1234,6 +1237,8 @@ main (int argc, char *argv[]) ", shot to snapshot, shot to shot, preview to shot, shot to buffer. " "e.g. 3.5,1.0,5.0,2.5,5.0,1.5,1.0", NULL}, + {"flags", '\0', 0, G_OPTION_ARG_STRING, &camerabin2_flags, + "camerabin2 element flags (default = 0)", NULL}, {NULL} };