mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +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;
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in a new issue