Bugfixes - better said, v4lsrc works again (it was broken?) and v4lmjpegsrc/sink are being worked on

Original commit message from CVS:
Bugfixes - better said, v4lsrc works again (it was broken?) and v4lmjpegsrc/sink are being worked on
This commit is contained in:
Ronald S. Bultje 2002-01-04 23:58:11 +00:00
parent ce8fe1bc5e
commit 130505618b
5 changed files with 106 additions and 64 deletions

View file

@ -465,7 +465,7 @@ gst_v4lelement_change_state (GstElement *element)
{ {
GstV4lElement *v4lelement; 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); v4lelement = GST_V4LELEMENT(element);

View file

@ -317,23 +317,13 @@ static GstElementStateReturn
gst_v4lmjpegsink_change_state (GstElement *element) gst_v4lmjpegsink_change_state (GstElement *element)
{ {
GstV4lMjpegSink *v4lmjpegsink; GstV4lMjpegSink *v4lmjpegsink;
GstElementStateReturn parent_value;
g_return_val_if_fail (GST_IS_V4LMJPEGSINK (element), GST_STATE_FAILURE); g_return_val_if_fail (GST_IS_V4LMJPEGSINK (element), GST_STATE_FAILURE);
v4lmjpegsink = GST_V4LMJPEGSINK(element); 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 */ /* set up change state */
switch (GST_STATE_TRANSITION(element)) { 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: case GST_STATE_READY_TO_PAUSED:
/* set buffer info */ /* set buffer info */
if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink, if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
@ -359,6 +349,22 @@ gst_v4lmjpegsink_change_state (GstElement *element)
break; 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; return GST_STATE_SUCCESS;
} }

View file

@ -363,38 +363,13 @@ static GstElementStateReturn
gst_v4lmjpegsrc_change_state (GstElement *element) gst_v4lmjpegsrc_change_state (GstElement *element)
{ {
GstV4lMjpegSrc *v4lmjpegsrc; GstV4lMjpegSrc *v4lmjpegsrc;
GstElementStateReturn parent_value;
g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), FALSE); g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), GST_STATE_FAILURE);
v4lmjpegsrc = GST_V4LMJPEGSRC(element); 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)) { 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: case GST_STATE_READY_TO_PAUSED:
/* set buffer info */ /* set buffer info */
if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize)) if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize))
@ -437,6 +412,37 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
break; 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; return GST_STATE_SUCCESS;
} }

View file

@ -445,23 +445,13 @@ static GstElementStateReturn
gst_v4lsrc_change_state (GstElement *element) gst_v4lsrc_change_state (GstElement *element)
{ {
GstV4lSrc *v4lsrc; GstV4lSrc *v4lsrc;
GstElementStateReturn parent_value;
g_return_val_if_fail(GST_IS_V4LSRC(element), FALSE); g_return_val_if_fail(GST_IS_V4LSRC(element), GST_STATE_FAILURE);
v4lsrc = GST_V4LSRC(element); 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)) { 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: case GST_STATE_READY_TO_PAUSED:
/* set capture parameters and mmap the buffers */ /* set capture parameters and mmap the buffers */
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette)) if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette))
@ -487,6 +477,22 @@ gst_v4lsrc_change_state (GstElement *element)
break; 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; return GST_STATE_SUCCESS;
} }

View file

@ -28,6 +28,10 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "v4lsrc_calls.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 */ /* On some systems MAP_FAILED seems to be missing */
#ifndef MAP_FAILED #ifndef MAP_FAILED
@ -81,7 +85,7 @@ static void *
gst_v4lsrc_soft_sync_thread (void *arg) gst_v4lsrc_soft_sync_thread (void *arg)
{ {
GstV4lSrc *v4lsrc = GST_V4LSRC(arg); GstV4lSrc *v4lsrc = GST_V4LSRC(arg);
guint16 frame = 0; gint frame = 0;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "gst_v4lsrc_soft_sync_thread()\n"); fprintf(stderr, "gst_v4lsrc_soft_sync_thread()\n");
@ -95,20 +99,30 @@ gst_v4lsrc_soft_sync_thread (void *arg)
{ {
/* are there queued frames left? */ /* are there queued frames left? */
pthread_mutex_lock(&(v4lsrc->mutex_queued_frames)); 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), pthread_cond_wait(&(v4lsrc->cond_queued_frames),
&(v4lsrc->mutex_queued_frames)); &(v4lsrc->mutex_queued_frames));
} }
pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames)); pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
/* if still wrong, we got interrupted and we should exit */ /* 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; goto end;
} }
/* sync on the frame */ /* sync on the frame */
#ifdef DEBUG
fprintf(stderr, "Sync\'ing on frame %d\n", frame);
#endif
retry: retry:
if (ioctl(GST_V4LELEMENT(v4lsrc)->video_fd, VIDIOCSYNC, &frame) < 0) if (ioctl(GST_V4LELEMENT(v4lsrc)->video_fd, VIDIOCSYNC, &frame) < 0)
{ {
@ -142,7 +156,7 @@ retry:
end: end:
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Software sync thread got signalled to exit"); fprintf(stderr, "Software sync thread got signalled to exit\n");
#endif #endif
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -159,25 +173,27 @@ gst_v4lsrc_sync_next_frame (GstV4lSrc *v4lsrc,
gint *num) gint *num)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame(), num = %d\n", fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame()\n");
num);
#endif #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 */ /* "software sync()" on the frame */
pthread_mutex_lock(&(v4lsrc->mutex_soft_sync)); 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]), pthread_cond_wait(&(v4lsrc->cond_soft_sync[*num]),
&(v4lsrc->mutex_soft_sync)); &(v4lsrc->mutex_soft_sync));
} }
pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
if (v4lsrc->isready_soft_sync[*num] < 0) if (v4lsrc->isready_soft_sync[*num] < 0)
return FALSE; return FALSE;
v4lsrc->isready_soft_sync[*num] = 0; v4lsrc->isready_soft_sync[*num] = 0;
pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
v4lsrc->frame_queued[*num] = FALSE; v4lsrc->frame_queued[*num] = FALSE;
@ -240,12 +256,20 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
return 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), gst_element_info(GST_ELEMENT(v4lsrc),
"Got %d buffers of size %d KB", "Got %d buffers of size %d KB",
v4lsrc->mbuf.frames, v4lsrc->mbuf.size/(v4lsrc->mbuf.frames*1024)); v4lsrc->mbuf.frames, v4lsrc->mbuf.size/(v4lsrc->mbuf.frames*1024));
/* keep trakc of queued buffers */ /* 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) if (!v4lsrc->frame_queued)
{ {
gst_element_error(GST_ELEMENT(v4lsrc), gst_element_error(GST_ELEMENT(v4lsrc),