camerabin: Add "ready-for-capture" property
authorLasse Laukkanen <ext-lasse.2.laukkanen@nokia.com>
Wed, 5 May 2010 10:58:07 +0000 (13:58 +0300)
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>
Fri, 5 Nov 2010 00:41:07 +0000 (21:41 -0300)
Add "ready-for-capture" property to indicate if preparing a new
capture is possible.

"ready-for-capture" changes before the 'image-done' signal, so
the application can be notified that it can do a new capture
even before the previous one has finished encoding/saving.

gst/camerabin/gstcamerabin-enum.h
gst/camerabin/gstcamerabin.c
tests/check/elements/camerabin.c

index 747828af1dcb945a5e9491a4be5380abd698878e..aa456144a5d401ae7791ce72584aef57a150b40e 100644 (file)
@@ -67,7 +67,8 @@ enum
   ARG_VIDEO_CAPTURE_WIDTH,
   ARG_VIDEO_CAPTURE_HEIGHT,
   ARG_VIDEO_CAPTURE_FRAMERATE,
-  ARG_PREVIEW_SOURCE_FILTER
+  ARG_PREVIEW_SOURCE_FILTER,
+  ARG_READY_FOR_CAPTURE
 };
 
 /**
index 23b314a8b779a08cde5a5fc9d7097f26ff399594..4eedcf58b7f23b3829ec54eb3536bbb7bd7e6d32 100644 (file)
@@ -218,6 +218,7 @@ static guint camerabin_signals[LAST_SIGNAL];
 #define DEFAULT_V4L2CAMSRC_DRIVER_NAME "omap3cam"
 
 #define DEFAULT_BLOCK_VIEWFINDER FALSE
+#define DEFAULT_READY_FOR_CAPTURE TRUE
 
 /* message names */
 #define PREVIEW_MESSAGE_NAME "preview-image"
@@ -1914,6 +1915,9 @@ gst_camerabin_have_src_buffer (GstPad * pad, GstBuffer * buffer,
   /* our work is done, disconnect */
   gst_pad_remove_buffer_probe (pad, camera->image_captured_id);
 
+  /* Image captured, notify that preparing a new capture is possible */
+  g_object_notify (G_OBJECT (camera), "ready-for-capture");
+
   return TRUE;
 }
 
@@ -3052,6 +3056,20 @@ gst_camerabin_class_init (GstCameraBinClass * klass)
           DEFAULT_FPS_N, DEFAULT_FPS_D,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstCameraBin:ready-for-capture:
+   *
+   * When TRUE new capture can be prepared. If FALSE capturing is ongoing
+   * and starting a new capture immediately is not possible.
+   */
+
+  g_object_class_install_property (gobject_class, ARG_READY_FOR_CAPTURE,
+      g_param_spec_boolean ("ready-for-capture",
+          "Indicates if preparing a new capture is possible",
+          "Indicates if preparing a new capture is possible",
+          DEFAULT_READY_FOR_CAPTURE,
+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstCameraBin::capture-start:
    * @camera: the camera bin element
@@ -3685,6 +3703,11 @@ gst_camerabin_get_property (GObject * object, guint prop_id,
     case ARG_BLOCK_VIEWFINDER:
       g_value_set_boolean (value, camera->block_viewfinder_prop);
       break;
+    case ARG_READY_FOR_CAPTURE:
+      g_mutex_lock (camera->capture_mutex);
+      g_value_set_boolean (value, !camera->capturing);
+      g_mutex_unlock (camera->capture_mutex);
+      break;
     case ARG_IMAGE_CAPTURE_WIDTH:
       g_value_set_int (value, camera->image_capture_width);
       break;
@@ -3930,6 +3953,8 @@ gst_camerabin_capture_start (GstCameraBin * camera)
       gst_camerabin_start_video_recording (camera);
     }
   }
+  /* Capturing is now ongoing, notify that new capture isn't possible */
+  g_object_notify (G_OBJECT (camera), "ready-for-capture");
 }
 
 static void
@@ -3939,6 +3964,8 @@ gst_camerabin_capture_stop (GstCameraBin * camera)
     GST_INFO_OBJECT (camera, "stopping video capture");
     gst_camerabin_do_stop (camera);
     gst_camerabin_reset_to_view_finder (camera);
+    /* Video capture stopped, notify that preparing a new capture is possible */
+    g_object_notify (G_OBJECT (camera), "ready-for-capture");
   } else {
     GST_INFO_OBJECT (camera, "stopping image capture isn't needed");
   }
index 3930d40d7466206e0f3ed3eaf74fa52ce41e34d9..613c226f4914ddc33b4024f62626a0156cfa2d65 100644 (file)
@@ -243,7 +243,10 @@ capture_bus_cb (GstBus * bus, GstMessage * message, gpointer data)
     default:
       st = gst_message_get_structure (message);
       if (st && gst_structure_has_name (st, "image-captured")) {
+        gboolean ready = FALSE;
         GST_INFO ("image captured");
+        g_object_get (camera, "ready-for-capture", &ready, NULL);
+        fail_if (!ready, "not ready for capture");
       }
       break;
   }
@@ -489,6 +492,7 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist)
 
 GST_START_TEST (test_single_image_capture)
 {
+  gboolean ready = FALSE;
   if (!camera)
     return;
 
@@ -506,9 +510,16 @@ GST_START_TEST (test_single_image_capture)
   /* don't run viewfinder after capture */
   g_object_set (camera, "block-after-capture", TRUE, NULL);
 
+  /* check that capturing is possible */
+  g_object_get (camera, "ready-for-capture", &ready, NULL);
+  fail_if (!ready, "not ready for capture");
+
   GST_INFO ("starting capture");
   g_signal_emit_by_name (camera, "capture-start", NULL);
 
+  g_object_get (camera, "ready-for-capture", &ready, NULL);
+  fail_if (ready, "ready for capture during capture");
+
   g_main_loop_run (main_loop);
   gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);