mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
camerabin: prevent captures from being lost when switching resolutions
When switching capture caps, camerabin1 resets its state to ready to force a new caps to be negotiated. This causes ongoing captures to be aborted. This commit adds a condition to wait for captures to finish before going to ready state.
This commit is contained in:
parent
9bd40e92ce
commit
3b549c4dbd
2 changed files with 27 additions and 5 deletions
|
@ -242,25 +242,37 @@ static guint camerabin_signals[LAST_SIGNAL];
|
|||
GST_DEBUG_OBJECT ((c), "Processing counter incremented to: %d", \
|
||||
(c)->processing_counter); \
|
||||
if ((c)->processing_counter == 1) \
|
||||
g_object_notify (G_OBJECT (c), "idle"); \
|
||||
g_object_notify (G_OBJECT (c), "idle");
|
||||
|
||||
#define CAMERABIN_PROCESSING_DEC_UNLOCKED(c) \
|
||||
(c)->processing_counter -= 1; \
|
||||
GST_DEBUG_OBJECT ((c), "Processing counter decremented to: %d", \
|
||||
(c)->processing_counter); \
|
||||
g_assert ((c)->processing_counter >= 0); \
|
||||
if ((c)->processing_counter == 0) \
|
||||
g_object_notify (G_OBJECT (c), "idle"); \
|
||||
if ((c)->processing_counter == 0) { \
|
||||
g_cond_signal ((c)->idle_cond); \
|
||||
g_object_notify (G_OBJECT (c), "idle"); \
|
||||
}
|
||||
|
||||
#define CAMERABIN_PROCESSING_INC(c) \
|
||||
g_mutex_lock ((c)->capture_mutex); \
|
||||
CAMERABIN_PROCESSING_INC_UNLOCKED ((c)); \
|
||||
g_mutex_unlock ((c)->capture_mutex); \
|
||||
g_mutex_unlock ((c)->capture_mutex);
|
||||
|
||||
#define CAMERABIN_PROCESSING_DEC(c) \
|
||||
g_mutex_lock ((c)->capture_mutex); \
|
||||
CAMERABIN_PROCESSING_DEC_UNLOCKED ((c)); \
|
||||
g_mutex_unlock ((c)->capture_mutex); \
|
||||
g_mutex_unlock ((c)->capture_mutex);
|
||||
|
||||
#define CAMERABIN_PROCESSING_WAIT_IDLE(c) \
|
||||
g_mutex_lock ((c)->capture_mutex); \
|
||||
if ((c)->processing_counter > 0) { \
|
||||
GST_DEBUG_OBJECT ((c), "Waiting for processing operations to finish %d", \
|
||||
(c)->processing_counter); \
|
||||
g_cond_wait ((c)->idle_cond, (c)->capture_mutex); \
|
||||
GST_DEBUG_OBJECT ((c), "Processing operations finished"); \
|
||||
} \
|
||||
g_mutex_unlock ((c)->capture_mutex);
|
||||
|
||||
/*
|
||||
* static helper functions declaration
|
||||
|
@ -939,6 +951,10 @@ camerabin_dispose_elements (GstCameraBin * camera)
|
|||
g_cond_free (camera->cond);
|
||||
camera->cond = NULL;
|
||||
}
|
||||
if (camera->idle_cond) {
|
||||
g_cond_free (camera->idle_cond);
|
||||
camera->idle_cond = NULL;
|
||||
}
|
||||
if (camera->filename) {
|
||||
g_string_free (camera->filename, TRUE);
|
||||
camera->filename = NULL;
|
||||
|
@ -1613,6 +1629,9 @@ reset_video_capture_caps (GstCameraBin * camera)
|
|||
/* Interrupt ongoing capture */
|
||||
gst_camerabin_do_stop (camera);
|
||||
|
||||
/* prevent image captures from being lost */
|
||||
CAMERABIN_PROCESSING_WAIT_IDLE (camera);
|
||||
|
||||
gst_element_get_state (GST_ELEMENT (camera), &state, &pending, 0);
|
||||
if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) {
|
||||
GST_INFO_OBJECT (camera,
|
||||
|
@ -3354,6 +3373,7 @@ gst_camerabin_init (GstCameraBin * camera, GstCameraBinClass * gclass)
|
|||
/* concurrency control */
|
||||
camera->capture_mutex = g_mutex_new ();
|
||||
camera->cond = g_cond_new ();
|
||||
camera->idle_cond = g_cond_new ();
|
||||
camera->processing_counter = 0;
|
||||
|
||||
/* pad names for output and input selectors */
|
||||
|
@ -3932,6 +3952,7 @@ gst_camerabin_change_state (GstElement * element, GstStateChange transition)
|
|||
GST_DEBUG_OBJECT (camera, "Reset processing counter from %d to 0",
|
||||
camera->processing_counter);
|
||||
camera->processing_counter = 0;
|
||||
g_cond_signal (camera->idle_cond);
|
||||
g_object_notify (G_OBJECT (camera), "idle");
|
||||
g_mutex_unlock (camera->capture_mutex);
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ struct _GstCameraBin
|
|||
/* concurrency control */
|
||||
GMutex *capture_mutex;
|
||||
GCond *cond;
|
||||
GCond *idle_cond;
|
||||
gboolean capturing;
|
||||
gboolean eos_handled;
|
||||
/* everytime a new capture is started this is incremented, when it is
|
||||
|
|
Loading…
Reference in a new issue