Commit 13050561 authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Bugfixes - better said, v4lsrc works again (it was broken?) and...

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
parent ce8fe1bc
......@@ -465,7 +465,7 @@ gst_v4lelement_change_state (GstElement *element)
{
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);
......
......@@ -317,23 +317,13 @@ static GstElementStateReturn
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,
......@@ -359,6 +349,22 @@ gst_v4lmjpegsink_change_state (GstElement *element)
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;
}
......
......@@ -363,38 +363,13 @@ static GstElementStateReturn
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))
......@@ -437,6 +412,37 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
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;
}
......
......@@ -445,23 +445,13 @@ static GstElementStateReturn
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))
......@@ -487,6 +477,22 @@ gst_v4lsrc_change_state (GstElement *element)
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;
}
......
......@@ -28,6 +28,10 @@
#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
......@@ -81,7 +85,7 @@ static void *
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");
......@@ -95,20 +99,30 @@ gst_v4lsrc_soft_sync_thread (void *arg)
{
/* 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)
{
......@@ -142,7 +156,7 @@ retry:
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);
}
......@@ -159,25 +173,27 @@ gst_v4lsrc_sync_next_frame (GstV4lSrc *v4lsrc,
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;
......@@ -240,12 +256,20 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
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),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment