summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2010-12-24 09:10:48 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2010-12-29 13:24:05 -0300
commit1c761196f709d4f06616750ad6403a459fac5dc0 (patch)
treec923128cf90e7cd0021a0774d7466e587d52ee90
parent17ab963b104327d0a01071d9028d502dcb45819a (diff)
downloadgstreamer-plugins-bad-1c761196f709d4f06616750ad6403a459fac5dc0.tar.gz
wrappercamerabinsrc: Refactor internal pipeline
Instead of linking 3 src pads from tee to the ghostpads, use 2 srcpads and add an output-selector to completely split caps negotiation of video/image modes. I don't think there is an use case that would require image and video pads to be used at the same time.
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.c90
-rw-r--r--gst/camerabin2/gstwrappercamerabinsrc.h10
2 files changed, 80 insertions, 20 deletions
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c
index 19567ab62..353e733ca 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.c
+++ b/gst/camerabin2/gstwrappercamerabinsrc.c
@@ -1,6 +1,7 @@
/*
* GStreamer
* Copyright (C) 2010 Texas Instruments, Inc
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -137,6 +138,10 @@ gst_wrapper_camera_bin_src_imgsrc_probe (GstPad * pad, GstBuffer * buffer,
GstBaseCameraSrc *camerasrc = GST_BASE_CAMERA_SRC (data);
gboolean ret = FALSE;
+ GST_LOG_OBJECT (self, "Image probe, mode %d, capture count %d, caps %"
+ GST_PTR_FORMAT, camerasrc->mode, self->image_capture_count,
+ GST_BUFFER_CAPS (buffer));
+
g_mutex_lock (camerasrc->capturing_mutex);
if (self->image_capture_count > 0) {
ret = TRUE;
@@ -162,6 +167,9 @@ gst_wrapper_camera_bin_src_vidsrc_probe (GstPad * pad, GstBuffer * buffer,
GstBaseCameraSrc *camerasrc = GST_BASE_CAMERA_SRC_CAST (self);
gboolean ret = FALSE;
+ GST_LOG_OBJECT (self, "Video probe, mode %d, capture status %d",
+ camerasrc->mode, self->video_rec_status);
+
/* TODO do we want to lock for every buffer? */
/*
* Note that we can use gst_pad_push_event here because we are a buffer
@@ -200,6 +208,9 @@ gst_wrapper_camera_bin_src_event (GstPad * pad, GstEvent * event)
structure = gst_event_get_structure (event);
if (structure && gst_structure_has_name (structure, "renegotiate")) {
+ GST_DEBUG_OBJECT (src, "Received renegotiate on pad %s",
+ GST_PAD_NAME (pad));
+
if (pad == src->imgsrc) {
src->image_renegotiate = TRUE;
} else if (pad == src->vidsrc) {
@@ -224,7 +235,11 @@ src_event_probe (GstPad * pad, GstEvent * event, gpointer user_data)
* @bcamsrc: camerasrc object
*
* This function creates and links the elements of the camerasrc bin
- * videosrc ! cspconv ! capsfilter ! crop ! scale ! capsfilter ! tee ! ..
+ * videosrc ! cspconv ! capsfilter ! crop ! scale ! capsfilter ! tee name=t !
+ * t. ! ... (viewfinder pad)
+ * t. ! output-selector name=outsel
+ * outsel. ! (image pad)
+ * outsel. ! (video pad)
*
* Returns: TRUE, if elements were successfully created, FALSE otherwise
*/
@@ -236,6 +251,11 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
GstElement *tee;
gboolean ret = FALSE;
GstElement *videoscale;
+ GstPad *vf_pad;
+ GstPad *tee_capture_pad;
+
+ if (self->elements_created)
+ return TRUE;
GST_DEBUG_OBJECT (self, "constructing pipeline");
@@ -250,6 +270,7 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
}
}
+ /* add a buffer probe to the src elemento to drop EOS from READY->NULL */
{
GstPad *pad;
pad = gst_element_get_static_pad (self->src_vid_src, "src");
@@ -279,8 +300,9 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
if (!(tee = gst_camerabin_create_and_add_element (cbin, "tee")))
goto done;
- self->tee_vf_srcpad = gst_element_get_request_pad (tee, "src%d");
- g_object_set (tee, "alloc-pad", self->tee_vf_srcpad, NULL);
+ /* viewfinder pad */
+ vf_pad = gst_element_get_request_pad (tee, "src%d");
+ g_object_set (tee, "alloc-pad", vf_pad, NULL);
/* the viewfinder should always work, so we add some converters to it */
if (!gst_camerabin_create_and_add_element (cbin, "ffmpegcolorspace"))
@@ -288,30 +310,56 @@ gst_wrapper_camera_bin_src_construct_pipeline (GstBaseCameraSrc * bcamsrc)
if (!(videoscale = gst_camerabin_create_and_add_element (cbin, "videoscale")))
goto done;
- gst_object_unref (self->tee_vf_srcpad);
- self->tee_vf_srcpad = gst_element_get_static_pad (videoscale, "src");
+ gst_object_unref (vf_pad);
+ vf_pad = gst_element_get_static_pad (videoscale, "src");
+
+ /* image/video pad from tee */
+ tee_capture_pad = gst_element_get_request_pad (tee, "src%d");
+
+ self->output_selector =
+ gst_element_factory_make ("output-selector", "outsel");
+ gst_bin_add (GST_BIN (self), self->output_selector);
+ {
+ GstPad *pad = gst_element_get_static_pad (self->output_selector, "sink");
+
+ /* check return TODO */
+ gst_pad_link (tee_capture_pad, pad);
+ gst_object_unref (pad);
+ }
- self->tee_image_srcpad = gst_element_get_request_pad (tee, "src%d");
- self->tee_video_srcpad = gst_element_get_request_pad (tee, "src%d");
+ /* Create the 2 output pads for video and image */
+ self->outsel_vidpad =
+ gst_element_get_request_pad (self->output_selector, "src%d");
+ self->outsel_imgpad =
+ gst_element_get_request_pad (self->output_selector, "src%d");
- gst_pad_add_buffer_probe (self->tee_image_srcpad,
+ g_assert (self->outsel_vidpad != NULL);
+ g_assert (self->outsel_imgpad != NULL);
+
+ gst_pad_add_buffer_probe (self->outsel_imgpad,
G_CALLBACK (gst_wrapper_camera_bin_src_imgsrc_probe), self);
- gst_pad_add_buffer_probe (self->tee_video_srcpad,
+ gst_pad_add_buffer_probe (self->outsel_vidpad,
G_CALLBACK (gst_wrapper_camera_bin_src_vidsrc_probe), self);
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc), self->outsel_imgpad);
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), self->outsel_vidpad);
+ if (bcamsrc->mode == MODE_IMAGE) {
+ g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
+ NULL);
+ } else {
+ g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
+ NULL);
+ }
- /* hook-up the ghostpads */
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), self->tee_vf_srcpad);
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc),
- self->tee_image_srcpad);
- gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc),
- self->tee_video_srcpad);
+ /* hook-up the vf ghostpads */
+ gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
gst_pad_set_active (self->vfsrc, TRUE);
gst_pad_set_active (self->imgsrc, TRUE); /* XXX ??? */
gst_pad_set_active (self->vidsrc, TRUE); /* XXX ??? */
ret = TRUE;
+ self->elements_created = TRUE;
done:
return ret;
}
@@ -498,6 +546,16 @@ gst_wrapper_camera_bin_src_set_mode (GstBaseCameraSrc * bcamsrc,
self->mode = mode;
+ if (self->output_selector) {
+ if (mode == MODE_IMAGE) {
+ g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
+ NULL);
+ } else {
+ g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
+ NULL);
+ }
+ }
+
if (photography) {
if (g_object_class_find_property (G_OBJECT_GET_CLASS (photography),
"capture-mode")) {
@@ -775,8 +833,8 @@ gst_wrapper_camera_bin_src_start_capture (GstBaseCameraSrc * camerasrc)
/* TODO shoud we access this directly? Maybe a macro is better? */
if (src->mode == MODE_IMAGE) {
- src->image_capture_count = 1;
start_image_capture (src);
+ src->image_capture_count = 1;
} else if (src->mode == MODE_VIDEO) {
g_mutex_unlock (camerasrc->capturing_mutex);
gst_wrapper_camera_bin_reset_video_src_caps (src, NULL);
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.h b/gst/camerabin2/gstwrappercamerabinsrc.h
index 22697b93a..2813e8b4b 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.h
+++ b/gst/camerabin2/gstwrappercamerabinsrc.h
@@ -1,6 +1,7 @@
/*
* GStreamer
* Copyright (C) 2010 Texas Instruments, Inc
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -75,13 +76,14 @@ struct _GstWrapperCameraBinSrc
GstElement *src_zoom_crop;
GstElement *src_zoom_scale;
GstElement *src_zoom_filter;
+ GstElement *output_selector;
+
+ gboolean elements_created;
guint src_event_probe_id;
- /* srcpads of tee */
- GstPad *tee_vf_srcpad;
- GstPad *tee_image_srcpad;
- GstPad *tee_video_srcpad;
+ GstPad *outsel_imgpad;
+ GstPad *outsel_vidpad;
GstPadEventFunction srcpad_event_func;