{
GstV4lElement *v4lelement;
- g_return_val_if_fail(GST_IS_V4LELEMENT(element), FALSE);
+ g_return_val_if_fail(GST_IS_V4LELEMENT(element), GST_STATE_FAILURE);
v4lelement = GST_V4LELEMENT(element);
gst_v4lmjpegsink_change_state (GstElement *element)
{
GstV4lMjpegSink *v4lmjpegsink;
+ GstElementStateReturn parent_value;
g_return_val_if_fail (GST_IS_V4LMJPEGSINK (element), GST_STATE_FAILURE);
v4lmjpegsink = GST_V4LMJPEGSINK(element);
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element);
-
/* set up change state */
switch (GST_STATE_TRANSITION(element)) {
- case GST_STATE_NULL_TO_READY:
- if (GST_V4LELEMENT(v4lmjpegsink)->norm >= VIDEO_MODE_PAL &&
- GST_V4LELEMENT(v4lmjpegsink)->norm < VIDEO_MODE_AUTO &&
- GST_V4LELEMENT(v4lmjpegsink)->channel < 0)
- if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsink),
- 0, GST_V4LELEMENT(v4lmjpegsink)->norm))
- return GST_STATE_FAILURE;
- break;
case GST_STATE_READY_TO_PAUSED:
/* set buffer info */
if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
break;
}
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+ {
+ if ((GST_V4LELEMENT(v4lmjpegsink)->norm >= VIDEO_MODE_PAL ||
+ GST_V4LELEMENT(v4lmjpegsink)->norm < VIDEO_MODE_AUTO) ||
+ GST_V4LELEMENT(v4lmjpegsink)->channel < 0)
+ if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsink),
+ 0, GST_V4LELEMENT(v4lmjpegsink)->norm))
+ return GST_STATE_FAILURE;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return parent_value;
+
return GST_STATE_SUCCESS;
}
gst_v4lmjpegsrc_change_state (GstElement *element)
{
GstV4lMjpegSrc *v4lmjpegsrc;
-
- g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), FALSE);
+ GstElementStateReturn parent_value;
+
+ g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), GST_STATE_FAILURE);
v4lmjpegsrc = GST_V4LMJPEGSRC(element);
- if (GST_ELEMENT_CLASS(parent_class)->change_state)
- return GST_ELEMENT_CLASS(parent_class)->change_state(element);
-
switch (GST_STATE_TRANSITION(element)) {
- case GST_STATE_NULL_TO_READY:
- /* do autodetection if no input/norm is selected yet */
- if (GST_V4LELEMENT(v4lmjpegsrc)->norm < VIDEO_MODE_PAL ||
- GST_V4LELEMENT(v4lmjpegsrc)->norm == VIDEO_MODE_AUTO ||
- GST_V4LELEMENT(v4lmjpegsrc)->channel < 0 ||
- GST_V4LELEMENT(v4lmjpegsrc)->channel == V4L_MJPEG_INPUT_AUTO)
- {
- gint norm, input;
-
- if (GST_V4LELEMENT(v4lmjpegsrc)->norm < 0)
- norm = VIDEO_MODE_AUTO;
- else
- norm = GST_V4LELEMENT(v4lmjpegsrc)->norm;
-
- if (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0)
- input = V4L_MJPEG_INPUT_AUTO;
- else
- input = GST_V4LELEMENT(v4lmjpegsrc)->channel;
-
- if (!gst_v4lmjpegsrc_set_input_norm(v4lmjpegsrc, input, norm))
- return GST_STATE_FAILURE;
- }
- break;
case GST_STATE_READY_TO_PAUSED:
/* set buffer info */
if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize))
break;
}
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+ {
+ /* do autodetection if no input/norm is selected yet */
+ if ((GST_V4LELEMENT(v4lmjpegsrc)->norm < VIDEO_MODE_PAL ||
+ GST_V4LELEMENT(v4lmjpegsrc)->norm == VIDEO_MODE_AUTO) ||
+ (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0 ||
+ GST_V4LELEMENT(v4lmjpegsrc)->channel == V4L_MJPEG_INPUT_AUTO))
+ {
+ gint norm, input;
+
+ if (GST_V4LELEMENT(v4lmjpegsrc)->norm < 0)
+ norm = VIDEO_MODE_AUTO;
+ else
+ norm = GST_V4LELEMENT(v4lmjpegsrc)->norm;
+
+ if (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0)
+ input = V4L_MJPEG_INPUT_AUTO;
+ else
+ input = GST_V4LELEMENT(v4lmjpegsrc)->channel;
+
+ if (!gst_v4lmjpegsrc_set_input_norm(v4lmjpegsrc, input, norm))
+ return GST_STATE_FAILURE;
+ }
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return parent_value;
+
return GST_STATE_SUCCESS;
}
gst_v4lsrc_change_state (GstElement *element)
{
GstV4lSrc *v4lsrc;
-
- g_return_val_if_fail(GST_IS_V4LSRC(element), FALSE);
+ GstElementStateReturn parent_value;
+
+ g_return_val_if_fail(GST_IS_V4LSRC(element), GST_STATE_FAILURE);
v4lsrc = GST_V4LSRC(element);
- if (GST_ELEMENT_CLASS(parent_class)->change_state)
- return GST_ELEMENT_CLASS(parent_class)->change_state(element);
-
switch (GST_STATE_TRANSITION(element)) {
- case GST_STATE_NULL_TO_READY:
- if (GST_V4LELEMENT(v4lsrc)->norm >= VIDEO_MODE_PAL &&
- GST_V4LELEMENT(v4lsrc)->norm < VIDEO_MODE_AUTO &&
- GST_V4LELEMENT(v4lsrc)->channel < 0)
- if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lsrc),
- 0, GST_V4LELEMENT(v4lsrc)->norm))
- return GST_STATE_FAILURE;
- break;
case GST_STATE_READY_TO_PAUSED:
/* set capture parameters and mmap the buffers */
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette))
break;
}
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+ {
+ if ((GST_V4LELEMENT(v4lsrc)->norm >= VIDEO_MODE_PAL ||
+ GST_V4LELEMENT(v4lsrc)->norm < VIDEO_MODE_AUTO) ||
+ GST_V4LELEMENT(v4lsrc)->channel < 0)
+ if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lsrc),
+ 0, GST_V4LELEMENT(v4lsrc)->norm))
+ return GST_STATE_FAILURE;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return parent_value;
+
return GST_STATE_SUCCESS;
}
#include <string.h>
#include <errno.h>
#include "v4lsrc_calls.h"
+#include <sys/time.h>
+
+/* number of buffers to be queued *at least* before syncing */
+#define MIN_BUFFERS_QUEUED 2
/* On some systems MAP_FAILED seems to be missing */
#ifndef MAP_FAILED
gst_v4lsrc_soft_sync_thread (void *arg)
{
GstV4lSrc *v4lsrc = GST_V4LSRC(arg);
- guint16 frame = 0;
+ gint frame = 0;
#ifdef DEBUG
fprintf(stderr, "gst_v4lsrc_soft_sync_thread()\n");
{
/* are there queued frames left? */
pthread_mutex_lock(&(v4lsrc->mutex_queued_frames));
- if (v4lsrc->num_queued_frames < 1)
+ if (v4lsrc->num_queued_frames < MIN_BUFFERS_QUEUED)
{
+#ifdef DEBUG
+ fprintf(stderr, "Waiting for new frames to be queued (%d < %d)\n",
+ v4lsrc->num_queued_frames, MIN_BUFFERS_QUEUED);
+#endif
pthread_cond_wait(&(v4lsrc->cond_queued_frames),
&(v4lsrc->mutex_queued_frames));
}
pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
/* if still wrong, we got interrupted and we should exit */
- if (v4lsrc->num_queued_frames < 1)
+ if (v4lsrc->num_queued_frames < MIN_BUFFERS_QUEUED)
{
+#ifdef DEBUG
+ fprintf(stderr, "Still not enough frames, quitting...\n");
+#endif
goto end;
}
/* sync on the frame */
+#ifdef DEBUG
+ fprintf(stderr, "Sync\'ing on frame %d\n", frame);
+#endif
retry:
if (ioctl(GST_V4LELEMENT(v4lsrc)->video_fd, VIDIOCSYNC, &frame) < 0)
{
end:
#ifdef DEBUG
- fprintf(stderr, "Software sync thread got signalled to exit");
+ fprintf(stderr, "Software sync thread got signalled to exit\n");
#endif
pthread_exit(NULL);
}
gint *num)
{
#ifdef DEBUG
- fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame(), num = %d\n",
- num);
+ fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame()\n");
#endif
- *num = (v4lsrc->sync_frame + 1)%v4lsrc->mbuf.frames;
+ *num = v4lsrc->sync_frame = (v4lsrc->sync_frame + 1)%v4lsrc->mbuf.frames;
/* "software sync()" on the frame */
pthread_mutex_lock(&(v4lsrc->mutex_soft_sync));
- if (v4lsrc->isready_soft_sync[*num])
+ if (v4lsrc->isready_soft_sync[*num] == 0)
{
+#ifdef DEBUG
+ fprintf(stderr, "Waiting for frame %d to be synced on\n",
+ *num);
+#endif
pthread_cond_wait(&(v4lsrc->cond_soft_sync[*num]),
&(v4lsrc->mutex_soft_sync));
}
- pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
if (v4lsrc->isready_soft_sync[*num] < 0)
return FALSE;
-
v4lsrc->isready_soft_sync[*num] = 0;
+ pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
v4lsrc->frame_queued[*num] = FALSE;
return FALSE;
}
+ if (v4lsrc->mbuf.frames < MIN_BUFFERS_QUEUED)
+ {
+ gst_element_error(GST_ELEMENT(v4lsrc),
+ "Too little buffers. We got %d, we want at least %d",
+ v4lsrc->mbuf.frames, MIN_BUFFERS_QUEUED);
+ return FALSE;
+ }
+
gst_element_info(GST_ELEMENT(v4lsrc),
"Got %d buffers of size %d KB",
v4lsrc->mbuf.frames, v4lsrc->mbuf.size/(v4lsrc->mbuf.frames*1024));
/* keep trakc of queued buffers */
- v4lsrc->frame_queued = (gint *) malloc(sizeof(gint) * v4lsrc->mbuf.frames);
+ v4lsrc->frame_queued = (gint *) malloc(sizeof(int) * v4lsrc->mbuf.frames);
if (!v4lsrc->frame_queued)
{
gst_element_error(GST_ELEMENT(v4lsrc),