summaryrefslogtreecommitdiff
path: root/gst-libs/gst/basecamerabinsrc
diff options
context:
space:
mode:
authorLauri Lehtinen <lauri.lehtinen@digia.com>2011-04-08 09:22:11 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2011-05-16 18:08:39 -0300
commit802028081c5a33e4b596eba99508d7bd8d8771b5 (patch)
tree666ca38f4a675e28d42c5f6feebfe7ad70d7e16e /gst-libs/gst/basecamerabinsrc
parentaa4df686eb697b6af02ce449672cc59a9d5407cc (diff)
downloadgstreamer-plugins-bad-802028081c5a33e4b596eba99508d7bd8d8771b5.tar.gz
basecamerabinsrc: Protection for previewpipeline when setting new preview caps
Implements a state indicating flag to preview pipeline, so that new caps are not set if the pipeline is processing a preview. The caps are set as pending and applied when the next preview post is called. In this case a wait was implemented in the post_preview function, so that new preview image buffer will wait until the other previews have been posted to the application and the new caps can be used safely.
Diffstat (limited to 'gst-libs/gst/basecamerabinsrc')
-rw-r--r--gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c77
-rw-r--r--gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h6
2 files changed, 72 insertions, 11 deletions
diff --git a/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c b/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
index 6e223dce4..94c638825 100644
--- a/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
+++ b/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c
@@ -31,6 +31,9 @@
#include "gstcamerabinpreview.h"
#include "gstbasecamerasrc.h"
+static void _gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData *
+ preview, GstCaps * caps);
+
static GstFlowReturn
gst_camerabin_preview_pipeline_new_preroll (GstAppSink * appsink,
gpointer user_data)
@@ -66,6 +69,14 @@ gst_camerabin_preview_pipeline_new_buffer (GstAppSink * appsink,
"This element has no bus, therefore no message sent!");
}
+ g_mutex_lock (data->processing_lock);
+
+ data->processing--;
+ if (data->processing == 0)
+ g_cond_signal (data->processing_cond);
+
+ g_mutex_unlock (data->processing_lock);
+
return GST_FLOW_OK;
}
@@ -132,6 +143,12 @@ gst_camerabin_create_preview_pipeline (GstElement * element,
data->element = element;
data->filter = filter;
+ data->processing_lock = g_mutex_new ();
+ data->processing_cond = g_cond_new ();
+
+ data->pending_preview_caps = NULL;
+ data->processing = 0;
+
return data;
error:
GST_WARNING ("Failed to create camerabin's preview pipeline");
@@ -163,6 +180,14 @@ void
gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData *
preview)
{
+ if (preview->processing_lock) {
+ g_mutex_free (preview->processing_lock);
+ preview->processing_lock = NULL;
+ }
+ if (preview->processing_cond) {
+ g_cond_free (preview->processing_cond);
+ preview->processing_cond = NULL;
+ }
if (preview->pipeline) {
gst_element_set_state (preview->pipeline, GST_STATE_NULL);
gst_object_unref (preview->pipeline);
@@ -188,22 +213,28 @@ gst_camerabin_preview_pipeline_post (GstCameraBinPreviewPipelineData * preview,
g_return_val_if_fail (preview->pipeline != NULL, FALSE);
g_return_val_if_fail (buffer, FALSE);
+ g_mutex_lock (preview->processing_lock);
+
+ if (preview->pending_preview_caps) {
+ if (preview->processing > 0) {
+ g_cond_wait (preview->processing_cond, preview->processing_lock);
+ }
+ _gst_camerabin_preview_set_caps (preview, preview->pending_preview_caps);
+ gst_caps_replace (&preview->pending_preview_caps, NULL);
+ }
+
+ preview->processing++;
+
gst_app_src_push_buffer ((GstAppSrc *) preview->appsrc,
gst_buffer_ref (buffer));
+ g_mutex_unlock (preview->processing_lock);
+
return TRUE;
}
-/**
- * gst_camerabin_preview_set_caps:
- * @preview: the #GstCameraBinPreviewPipelineData
- * @caps: the #GstCaps to be set
- *
- * The caps that preview buffers should have when posted
- * on the bus
- */
-void
-gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
+static void
+_gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
GstCaps * caps)
{
GstState state, pending;
@@ -217,10 +248,34 @@ gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
state = GST_STATE_PLAYING;
pending = GST_STATE_VOID_PENDING;
}
-
gst_element_set_state (preview->pipeline, GST_STATE_NULL);
g_object_set (preview->capsfilter, "caps", caps, NULL);
if (pending != GST_STATE_VOID_PENDING)
state = pending;
gst_element_set_state (preview->pipeline, state);
}
+
+/**
+ * gst_camerabin_preview_set_caps:
+ * @preview: the #GstCameraBinPreviewPipelineData
+ * @caps: the #GstCaps to be set (a new ref will be taken)
+ *
+ * The caps that preview buffers should have when posted
+ * on the bus
+ */
+void
+gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
+ GstCaps * caps)
+{
+ g_return_if_fail (preview != NULL);
+
+ g_mutex_lock (preview->processing_lock);
+
+ if (preview->processing == 0) {
+ _gst_camerabin_preview_set_caps (preview, caps);
+ } else {
+ GST_DEBUG ("Preview pipeline busy, storing new caps as pending");
+ gst_caps_replace (&preview->pending_preview_caps, caps);
+ }
+ g_mutex_unlock (preview->processing_lock);
+}
diff --git a/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h b/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
index 4c8cf2187..ff5bc719e 100644
--- a/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
+++ b/gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h
@@ -39,6 +39,12 @@ typedef struct
GstElement *appsink;
GstElement *element;
+
+ GstCaps *pending_preview_caps;
+ guint processing;
+ GMutex *processing_lock;
+ GCond *processing_cond;
+
} GstCameraBinPreviewPipelineData;
GstCameraBinPreviewPipelineData *gst_camerabin_create_preview_pipeline (GstElement * element, GstElement * filter);