diff options
author | Lauri Lehtinen <lauri.lehtinen@digia.com> | 2011-04-08 09:22:11 -0300 |
---|---|---|
committer | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-05-16 18:08:39 -0300 |
commit | 802028081c5a33e4b596eba99508d7bd8d8771b5 (patch) | |
tree | 666ca38f4a675e28d42c5f6feebfe7ad70d7e16e /gst-libs/gst/basecamerabinsrc | |
parent | aa4df686eb697b6af02ce449672cc59a9d5407cc (diff) | |
download | gstreamer-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.c | 77 | ||||
-rw-r--r-- | gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h | 6 |
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); |