mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 10:25:33 +00:00
basecamerasrc: optimize state changing speed
Create preview pipeline already in initialization phase. This speeds up NULL_TO_READY state change. Also implement a separate function for setting the preview filter element. This also restricts the preview filter property to work only on NULL state.
This commit is contained in:
parent
48275dc071
commit
de138dbc57
4 changed files with 85 additions and 14 deletions
|
@ -350,7 +350,11 @@ gst_base_camera_src_set_property (GObject * object,
|
||||||
if (self->preview_filter)
|
if (self->preview_filter)
|
||||||
gst_object_unref (self->preview_filter);
|
gst_object_unref (self->preview_filter);
|
||||||
self->preview_filter = g_value_dup_object (value);
|
self->preview_filter = g_value_dup_object (value);
|
||||||
self->preview_filter_changed = TRUE;
|
if (!gst_camerabin_preview_set_filter (self->preview_pipeline,
|
||||||
|
self->preview_filter)) {
|
||||||
|
GST_WARNING_OBJECT (self,
|
||||||
|
"Cannot change preview filter, is element in NULL state?");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
|
||||||
|
@ -434,23 +438,11 @@ gst_base_camera_src_change_state (GstElement * element,
|
||||||
if (!construct_pipeline (self))
|
if (!construct_pipeline (self))
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
|
|
||||||
/* recreate the preview pipeline */
|
|
||||||
if (self->preview_pipeline && self->preview_filter_changed) {
|
|
||||||
gst_camerabin_destroy_preview_pipeline (self->preview_pipeline);
|
|
||||||
self->preview_pipeline = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->preview_pipeline == NULL)
|
|
||||||
self->preview_pipeline =
|
|
||||||
gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self),
|
|
||||||
self->preview_filter);
|
|
||||||
|
|
||||||
if (self->preview_pipeline == NULL) {
|
if (self->preview_pipeline == NULL) {
|
||||||
/* failed to create preview pipeline, fail state change */
|
/* failed to create preview pipeline, fail state change */
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->preview_filter_changed = FALSE;
|
|
||||||
if (self->preview_caps) {
|
if (self->preview_caps) {
|
||||||
GST_DEBUG_OBJECT (self,
|
GST_DEBUG_OBJECT (self,
|
||||||
"Setting preview pipeline caps %" GST_PTR_FORMAT,
|
"Setting preview pipeline caps %" GST_PTR_FORMAT,
|
||||||
|
@ -610,6 +602,9 @@ gst_base_camera_src_init (GstBaseCameraSrc * self,
|
||||||
self->capturing_mutex = g_mutex_new ();
|
self->capturing_mutex = g_mutex_new ();
|
||||||
|
|
||||||
self->post_preview = DEFAULT_POST_PREVIEW;
|
self->post_preview = DEFAULT_POST_PREVIEW;
|
||||||
|
|
||||||
|
self->preview_pipeline =
|
||||||
|
gst_camerabin_create_preview_pipeline (GST_ELEMENT_CAST (self), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -77,7 +77,6 @@ struct _GstBaseCameraSrc
|
||||||
gboolean post_preview;
|
gboolean post_preview;
|
||||||
GstElement *preview_filter;
|
GstElement *preview_filter;
|
||||||
GstCameraBinPreviewPipelineData *preview_pipeline;
|
GstCameraBinPreviewPipelineData *preview_pipeline;
|
||||||
gboolean preview_filter_changed;
|
|
||||||
|
|
||||||
/* Resolution of the buffers configured to camerabin */
|
/* Resolution of the buffers configured to camerabin */
|
||||||
gint width;
|
gint width;
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include "gstcamerabinpreview.h"
|
#include "gstcamerabinpreview.h"
|
||||||
#include "gstbasecamerasrc.h"
|
#include "gstbasecamerasrc.h"
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_EXTERN (base_camera_src_debug);
|
||||||
|
#define GST_CAT_DEFAULT base_camera_src_debug
|
||||||
|
|
||||||
static void _gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData *
|
static void _gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData *
|
||||||
preview, GstCaps * caps);
|
preview, GstCaps * caps);
|
||||||
|
|
||||||
|
@ -190,6 +193,7 @@ gst_camerabin_create_preview_pipeline (GstElement * element,
|
||||||
|
|
||||||
data->element = element;
|
data->element = element;
|
||||||
data->filter = filter;
|
data->filter = filter;
|
||||||
|
data->vscale = vscale;
|
||||||
|
|
||||||
data->processing_lock = g_mutex_new ();
|
data->processing_lock = g_mutex_new ();
|
||||||
data->processing_cond = g_cond_new ();
|
data->processing_cond = g_cond_new ();
|
||||||
|
@ -327,3 +331,74 @@ gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview,
|
||||||
}
|
}
|
||||||
g_mutex_unlock (preview->processing_lock);
|
g_mutex_unlock (preview->processing_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_camerabin_preview_set_filter:
|
||||||
|
* @preview: the #GstCameraBinPreviewPipelineData
|
||||||
|
* @filter: Custom filter to process preview data (an extra ref is taken)
|
||||||
|
*
|
||||||
|
* Set the filter element into preview pipeline.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE on success
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_camerabin_preview_set_filter (GstCameraBinPreviewPipelineData * preview,
|
||||||
|
GstElement * filter)
|
||||||
|
{
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
GstState current;
|
||||||
|
|
||||||
|
g_return_val_if_fail (preview != NULL, FALSE);
|
||||||
|
|
||||||
|
GST_DEBUG ("Preview pipeline setting new filter %p", filter);
|
||||||
|
|
||||||
|
g_mutex_lock (preview->processing_lock);
|
||||||
|
|
||||||
|
gst_element_get_state (preview->pipeline, ¤t, NULL, 0);
|
||||||
|
|
||||||
|
if (preview->processing == 0 && current == GST_STATE_NULL) {
|
||||||
|
gboolean linkfail = FALSE;
|
||||||
|
|
||||||
|
if (preview->filter) {
|
||||||
|
/* Unlink and remove old filter */
|
||||||
|
gst_element_unlink (preview->appsrc, preview->filter);
|
||||||
|
gst_element_unlink (preview->filter, preview->vscale);
|
||||||
|
gst_bin_remove (GST_BIN (preview->pipeline), preview->filter);
|
||||||
|
} else {
|
||||||
|
/* Make room for filter by breaking the link between appsrc and vcale */
|
||||||
|
gst_element_unlink (preview->appsrc, preview->vscale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
/* Add and link the new filter between appsrc and vscale */
|
||||||
|
gst_bin_add (GST_BIN (preview->pipeline), gst_object_ref (filter));
|
||||||
|
|
||||||
|
linkfail |=
|
||||||
|
GST_PAD_LINK_FAILED (gst_element_link_pads_full (preview->appsrc,
|
||||||
|
"src", filter, NULL, GST_PAD_LINK_CHECK_NOTHING));
|
||||||
|
|
||||||
|
linkfail |=
|
||||||
|
GST_PAD_LINK_FAILED (gst_element_link_pads_full (filter, NULL,
|
||||||
|
preview->vscale, "sink", GST_PAD_LINK_CHECK_CAPS));
|
||||||
|
} else {
|
||||||
|
/* No filter was given. Just link the appsrc to vscale directly */
|
||||||
|
linkfail |=
|
||||||
|
GST_PAD_LINK_FAILED (gst_element_link_pads_full (preview->appsrc,
|
||||||
|
"src", preview->vscale, "sink", GST_PAD_LINK_CHECK_NOTHING));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linkfail) {
|
||||||
|
GST_WARNING ("Linking the filter to pipeline failed");
|
||||||
|
ret = FALSE;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("Linking the filter to pipeline successful");
|
||||||
|
preview->filter = filter;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GST_WARNING ("Cannot change filter when pipeline is running");
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
g_mutex_unlock (preview->processing_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ typedef struct
|
||||||
GstElement *appsrc;
|
GstElement *appsrc;
|
||||||
GstElement *filter;
|
GstElement *filter;
|
||||||
GstElement *appsink;
|
GstElement *appsink;
|
||||||
|
GstElement *vscale;
|
||||||
|
|
||||||
GstElement *element;
|
GstElement *element;
|
||||||
|
|
||||||
|
@ -50,5 +51,6 @@ GstCameraBinPreviewPipelineData *gst_camerabin_create_preview_pipeline (GstEleme
|
||||||
void gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData * preview);
|
void gst_camerabin_destroy_preview_pipeline (GstCameraBinPreviewPipelineData * preview);
|
||||||
gboolean gst_camerabin_preview_pipeline_post (GstCameraBinPreviewPipelineData * preview, GstBuffer * buffer);
|
gboolean gst_camerabin_preview_pipeline_post (GstCameraBinPreviewPipelineData * preview, GstBuffer * buffer);
|
||||||
void gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview, GstCaps * caps);
|
void gst_camerabin_preview_set_caps (GstCameraBinPreviewPipelineData * preview, GstCaps * caps);
|
||||||
|
gboolean gst_camerabin_preview_set_filter (GstCameraBinPreviewPipelineData * preview, GstElement * filter);
|
||||||
|
|
||||||
#endif /* #ifndef __CAMERABIN_PREVIEW_H_ */
|
#endif /* #ifndef __CAMERABIN_PREVIEW_H_ */
|
||||||
|
|
Loading…
Reference in a new issue