mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
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:
parent
ce8fe1bc5e
commit
130505618b
5 changed files with 106 additions and 64 deletions
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue