From cb915196e2882a68dc8435791d78c3a7dfa330a3 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Tue, 30 Nov 2010 18:19:20 -0300 Subject: [PATCH] camerabin2: Handle vidbin state change individually Keep vidbin state locked to avoid it going to playing without being used and leaving an empty file created. Check the docs on the code for details on the handling. --- gst/camerabin2/gstcamerabin2.c | 58 ++++++++++++++++++++++++++++++++++ gst/camerabin2/gstcamerabin2.h | 3 ++ 2 files changed, 61 insertions(+) diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index c967a1c45e..a127622e35 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -25,6 +25,26 @@ * development. */ +/* + * Detail Topics: + * + * videorecordingbin state management (for now on vidbin) + * - The problem: keeping vidbin state in sync with camerabin will make it + * go to playing when it might not be used, causing its internal + * filesink to open a file that might be left blank. + * - The solution: vidbin state is set to locked upon its creation and camerabin + * registers itself on the notify::ready-for-capture of the src. + * Whenever the src readyness goes to FALSE it means a new + * capture is starting. If we are on video mode, the vidbin's + * state is set to NULL and then PLAYING (in between this we + * have room to set the destination filename). + * There is no problem to leave it on playing after an EOS, so + * no action is taken on stop-capture. + * - TODO: What happens when an error pops? + * + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -132,14 +152,37 @@ gst_camera_bin_change_mode (GstCameraBin * camerabin, gint mode) g_object_set (camerabin->src, "mode", mode, NULL); } +static void +gst_camera_bin_src_notify_readyforcapture (GObject * obj, GParamSpec * pspec, + gpointer user_data) +{ + GstCameraBin *camera = GST_CAMERA_BIN_CAST (user_data); + gboolean ready; + + if (camera->mode == MODE_VIDEO) { + g_object_get (camera->src, "ready-for-capture", &ready, NULL); + if (!ready) { + /* a video recording is about to start, we reset the videobin */ + gst_element_set_state (camera->vidbin, GST_STATE_NULL); + gst_element_set_state (camera->vidbin, GST_STATE_PLAYING); + } + } +} + static void gst_camera_bin_dispose (GObject * object) { GstCameraBin *camerabin = GST_CAMERA_BIN_CAST (object); + if (camerabin->src_capture_notify_id) + g_signal_handler_disconnect (camerabin->src, + camerabin->src_capture_notify_id); if (camerabin->src) gst_object_unref (camerabin->src); + if (camerabin->vidbin) + gst_object_unref (camerabin->vidbin); + G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -256,6 +299,7 @@ gst_camera_bin_create_elements (GstCameraBin * camera) vf = gst_element_factory_make ("viewfinderbin", "vf-bin"); camera->src = gst_object_ref (src); + camera->vidbin = gst_object_ref (vid); vid_queue = gst_element_factory_make ("queue", "video-queue"); img_queue = gst_element_factory_make ("queue", "image-queue"); @@ -276,6 +320,20 @@ gst_camera_bin_create_elements (GstCameraBin * camera) gst_element_link_pads (src, "imgsrc", img_queue, "sink"); gst_element_link_pads (src, "vidsrc", vid_queue, "sink"); + /* + * Video can't get into playing as its internal filesink will open + * a file for writing and leave it empty if unused. + * + * Its state is managed using the current mode and the source's + * ready-for-capture notify callback. When we are at video mode and + * the source's ready-for-capture goes to FALSE it means it is + * starting recording, so we should prepare the video bin. + */ + gst_element_set_locked_state (vid, TRUE); + camera->src_capture_notify_id = g_signal_connect (G_OBJECT (src), + "notify::ready-for-capture", + G_CALLBACK (gst_camera_bin_src_notify_readyforcapture), camera); + camera->elements_created = TRUE; return TRUE; } diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h index beafd4cd34..a859d80f3b 100644 --- a/gst/camerabin2/gstcamerabin2.h +++ b/gst/camerabin2/gstcamerabin2.h @@ -38,6 +38,9 @@ struct _GstCameraBin GstPipeline pipeline; GstElement *src; + gulong src_capture_notify_id; + + GstElement *vidbin; /* properties */ gint mode;