Small changes and integration of norm and input autodetection for mjpegv4lsrc

Original commit message from CVS:
Small changes and integration of norm and input autodetection for mjpegv4lsrc
This commit is contained in:
Ronald S. Bultje 2001-12-28 19:54:23 +00:00
parent bda010a7fa
commit dcf3d39af1
10 changed files with 345 additions and 204 deletions

View file

@ -1,6 +1,6 @@
TODO list (short term):
=======================
* v4lmjpegsrc: integrate input/norm autodetection
* all three: fix interlacing (not handled at all...)
* libgstrec: build (a library for video recording)
TODO list (long term):
@ -13,8 +13,8 @@ TODO list (long term):
Useful Documentation:
=====================
MJPEG/V4L API : ./videodev_mjpeg.h
V4L API : /usr/include/linux/videodev.h or
Linux/V4L API : /usr/include/linux/videodev.h or
http://roadrunner.swansea.uk.linux.org/v4l.shtml
V4L2 API : http://www.thedirks.org/v4l2/
Linux/V4L2 API: http://www.thedirks.org/v4l2/
BSD/Meteor API: /usr/include/machine/ioctl_meteor.h
mjpegtools : http://www.sourceforge.net/projects/mjpeg

View file

@ -50,7 +50,14 @@ enum {
ARG_BRIGHTNESS,
ARG_CONTRAST,
ARG_SATURATION,
ARG_DEVICE
ARG_DEVICE,
ARG_DEVICE_NAME,
ARG_DEVICE_IS_CAPTURE,
ARG_DEVICE_IS_OVERLAY,
ARG_DEVICE_IS_MJPEG_CAPTURE,
ARG_DEVICE_IS_MJPEG_PLAYBACK,
ARG_DEVICE_IS_MPEG_CAPTURE,
ARG_DEVICE_IS_MPEG_PLAYBACK
};
@ -110,35 +117,73 @@ gst_v4lelement_class_init (GstV4lElementClass *klass)
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNEL,
g_param_spec_int("channel","channel","channel",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("channel","channel","channel",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NORM,
g_param_spec_int("norm","norm","norm",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("norm","norm","norm",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_TUNER,
g_param_spec_boolean("has_tuner","has_tuner","has_tuner",0,G_PARAM_READABLE));
g_param_spec_boolean("has_tuner","has_tuner","has_tuner",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQUENCY,
g_param_spec_ulong("frequency","frequency","frequency",0,G_MAXULONG,0,G_PARAM_READWRITE));
g_param_spec_ulong("frequency","frequency","frequency",
0,G_MAXULONG,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_AUDIO,
g_param_spec_boolean("has_audio","has_audio","has_audio",0,G_PARAM_READABLE));
g_param_spec_boolean("has_audio","has_audio","has_audio",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MUTE,
g_param_spec_boolean("mute","mute","mute",0,G_PARAM_READWRITE));
g_param_spec_boolean("mute","mute","mute",
0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME,
g_param_spec_int("volume","volume","volume",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("volume","volume","volume",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MODE,
g_param_spec_int("mode","mode","mode",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("mode","mode","mode",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HUE,
g_param_spec_int("hue","hue","hue",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("hue","hue","hue",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BRIGHTNESS,
g_param_spec_int("brightness","brightness","brightness",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("brightness","brightness","brightness",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CONTRAST,
g_param_spec_int("contrast","contrast","contrast",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("contrast","contrast","contrast",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SATURATION,
g_param_spec_int("saturation","saturation","saturation",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("saturation","saturation","saturation",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
g_param_spec_string("device","device","device", NULL, G_PARAM_READWRITE));
g_param_spec_string("device","device","device",
NULL, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_NAME,
g_param_spec_string("device_name","device_name","device_name",
NULL, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_CAPTURE,
g_param_spec_boolean("can_capture","can_capture","can_capture",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_OVERLAY,
g_param_spec_boolean("has_overlay","has_overlay","has_overlay",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MJPEG_CAPTURE,
g_param_spec_boolean("can_capture_mjpeg","can_capture_mjpeg","can_capture_mjpeg",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MJPEG_PLAYBACK,
g_param_spec_boolean("can_playback_mjpeg","can_playback_mjpeg","can_playback_mjpeg",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MPEG_CAPTURE,
g_param_spec_boolean("can_capture_mpeg","can_capture_mpeg","can_capture_mpeg",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MPEG_PLAYBACK,
g_param_spec_boolean("can_playback_mpeg","can_playback_mpeg","can_playback_mpeg",
0,G_PARAM_READABLE));
gobject_class->set_property = gst_v4lelement_set_property;
gobject_class->get_property = gst_v4lelement_get_property;
@ -156,11 +201,11 @@ gst_v4lelement_init (GstV4lElement *v4lelement)
v4lelement->videodev = NULL;
v4lelement->norm = -1;
v4lelement->channel = 0; /* the first channel */
v4lelement->channel = -1; /* the first channel */
v4lelement->frequency = 0;
v4lelement->mute = -1;
v4lelement->mute = FALSE;
v4lelement->volume = -1;
v4lelement->mode = -1;
@ -189,7 +234,9 @@ gst_v4lelement_set_property (GObject *object,
v4lelement->channel = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement))
{
if (v4lelement->norm >= 0)
if (v4lelement->norm >= VIDEO_MODE_PAL &&
v4lelement->norm < VIDEO_MODE_AUTO &&
v4lelement->channel >= 0)
if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
return;
}
@ -198,25 +245,29 @@ gst_v4lelement_set_property (GObject *object,
v4lelement->norm = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement))
{
if (v4lelement->norm >= 0)
if (v4lelement->norm >= VIDEO_MODE_PAL &&
v4lelement->norm < VIDEO_MODE_AUTO &&
v4lelement->channel >= 0)
if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
return;
}
break;
case ARG_FREQUENCY:
v4lelement->frequency = g_value_get_ulong(value);
if (GST_V4L_IS_ACTIVE(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement))
if (GST_V4L_IS_OPEN(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement))
{
if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
return;
if (gst_v4l_has_tuner(v4lelement))
if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
return;
}
break;
case ARG_MUTE:
v4lelement->mute = g_value_get_boolean(value)?1:0;
v4lelement->mute = g_value_get_boolean(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, V4L_AUDIO_MUTE, v4lelement->mute))
return;
if (gst_v4l_has_audio(v4lelement))
if (!gst_v4l_set_audio(v4lelement, V4L_AUDIO_MUTE, v4lelement->mute))
return;
}
break;
case ARG_MODE:
@ -315,7 +366,8 @@ gst_v4lelement_get_property (GObject *object,
break;
case ARG_FREQUENCY:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_get_frequency(v4lelement, &temp_ul);
if (gst_v4l_has_tuner(v4lelement))
gst_v4l_get_frequency(v4lelement, &temp_ul);
g_value_set_ulong(value, temp_ul);
break;
case ARG_HAS_AUDIO:
@ -326,9 +378,9 @@ gst_v4lelement_get_property (GObject *object,
break;
case ARG_MUTE:
if (GST_V4L_IS_OPEN(v4lelement))
if (gst_v4l_has_tuner(v4lelement))
if (gst_v4l_has_audio(v4lelement))
gst_v4l_get_audio(v4lelement, V4L_AUDIO_MUTE, &temp_i);
g_value_set_int(value, temp_i?TRUE:FALSE);
g_value_set_boolean(value, temp_i?TRUE:FALSE);
break;
case ARG_MODE:
if (GST_V4L_IS_OPEN(v4lelement))
@ -363,7 +415,43 @@ gst_v4lelement_get_property (GObject *object,
g_value_set_int(value, temp_i);
break;
case ARG_DEVICE:
g_value_set_string(value, v4lelement->videodev?v4lelement->videodev:"/dev/video");
g_value_set_string(value, g_strdup(v4lelement->videodev?v4lelement->videodev:"/dev/video"));
break;
case ARG_DEVICE_NAME:
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_string(value, g_strdup(v4lelement->vcap.name));
else
g_value_set_string(value, g_strdup("None"));
break;
case ARG_DEVICE_IS_CAPTURE:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_CAPTURE);
break;
case ARG_DEVICE_IS_OVERLAY:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_OVERLAY);
break;
case ARG_DEVICE_IS_MJPEG_CAPTURE:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MJPEG_ENCODER);
break;
case ARG_DEVICE_IS_MJPEG_PLAYBACK:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MJPEG_DECODER);
break;
case ARG_DEVICE_IS_MPEG_CAPTURE:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MPEG_ENCODER);
break;
case ARG_DEVICE_IS_MPEG_PLAYBACK:
g_value_set_boolean(value, FALSE);
if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MPEG_DECODER);
break;
default:
//G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -384,66 +472,62 @@ gst_v4lelement_change_state (GstElement *element)
/* if going down into NULL state, close the device if it's open
* if going to READY, open the device (and set some options)
*/
switch (GST_STATE_PENDING(element))
switch (GST_STATE_TRANSITION(element))
{
case GST_STATE_NULL:
if (GST_V4L_IS_OPEN(v4lelement))
if (!gst_v4l_close(v4lelement))
return GST_STATE_FAILURE;
break;
case GST_STATE_READY:
if (!GST_V4L_IS_OPEN(v4lelement))
case GST_STATE_NULL_TO_READY:
{
int n, temp;
if (!gst_v4l_open(v4lelement))
return GST_STATE_FAILURE;
/* now, sync options */
if (v4lelement->norm >= VIDEO_MODE_PAL &&
v4lelement->norm < VIDEO_MODE_AUTO &&
v4lelement->channel >= 0)
{
int n, temp;
if (!gst_v4l_open(v4lelement))
if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
return GST_STATE_FAILURE;
/* now, sync options */
if (v4lelement->norm >= VIDEO_MODE_PAL &&
v4lelement->norm < VIDEO_MODE_AUTO &&
v4lelement->channel >= 0)
}
if (v4lelement->frequency > 0 && gst_v4l_has_tuner(v4lelement))
{
if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
return GST_STATE_FAILURE;
}
for (n=V4L_AUDIO_VOLUME;n<=V4L_AUDIO_MODE;n++)
{
switch (n)
{
if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
case V4L_AUDIO_MUTE: temp = v4lelement->mute; break;
case V4L_AUDIO_VOLUME: temp = v4lelement->volume; break;
case V4L_AUDIO_MODE: temp = v4lelement->mode; break;
}
if (temp >= 0 && gst_v4l_has_audio(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, n, temp))
return GST_STATE_FAILURE;
}
if (v4lelement->frequency > 0 && gst_v4l_has_tuner(v4lelement))
{
if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
return GST_STATE_FAILURE;
}
for (n=V4L_AUDIO_VOLUME;n<=V4L_AUDIO_MODE;n++)
{
switch (n)
{
case V4L_AUDIO_MUTE: temp = v4lelement->mute; break;
case V4L_AUDIO_VOLUME: temp = v4lelement->volume; break;
case V4L_AUDIO_MODE: temp = v4lelement->mode; break;
}
if (temp >= 0 && gst_v4l_has_audio(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, n, temp))
return GST_STATE_FAILURE;
}
}
for (n=V4L_PICTURE_HUE;n<=V4L_PICTURE_SATURATION;n++)
{
switch (n)
{
case V4L_PICTURE_HUE: temp = v4lelement->hue; break;
case V4L_PICTURE_BRIGHTNESS: temp = v4lelement->brightness; break;
case V4L_PICTURE_SATURATION: temp = v4lelement->saturation; break;
case V4L_PICTURE_CONTRAST: temp = v4lelement->contrast; break;
}
if (temp >= 0)
{
if (!gst_v4l_set_picture(v4lelement, n, temp))
return GST_STATE_FAILURE;
}
}
}
for (n=V4L_PICTURE_HUE;n<=V4L_PICTURE_SATURATION;n++)
{
switch (n)
{
case V4L_PICTURE_HUE: temp = v4lelement->hue; break;
case V4L_PICTURE_BRIGHTNESS: temp = v4lelement->brightness; break;
case V4L_PICTURE_SATURATION: temp = v4lelement->saturation; break;
case V4L_PICTURE_CONTRAST: temp = v4lelement->contrast; break;
}
if (temp >= 0)
{
if (!gst_v4l_set_picture(v4lelement, n, temp))
return GST_STATE_FAILURE;
}
}
}
break;
default:
case GST_STATE_READY_TO_NULL:
if (!gst_v4l_close(v4lelement))
return GST_STATE_FAILURE;
break;
}

View file

@ -62,7 +62,7 @@ struct _GstV4lElement {
gint channel;
gint norm;
gulong frequency;
gint mute;
gboolean mute;
gint volume;
gint mode;
gint brightness;

View file

@ -278,7 +278,7 @@ gst_v4lmjpegsink_set_property (GObject *object,
v4lmjpegsink->y_offset = g_value_get_int(value);
break;
default:
parent_class->set_property(object, prop_id, value, pspec);
/*parent_class->set_property(object, prop_id, value, pspec);*/
break;
}
}
@ -309,7 +309,7 @@ gst_v4lmjpegsink_get_property (GObject *object,
g_value_set_int (value, v4lmjpegsink->bufsize);
break;
default:
parent_class->get_property(object, prop_id, value, pspec);
/*parent_class->get_property(object, prop_id, value, pspec);*/
break;
}
}
@ -323,40 +323,44 @@ gst_v4lmjpegsink_change_state (GstElement *element)
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_PENDING(element)) {
case GST_STATE_READY:
if (GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsink))) {
/* stop playback, unmap all buffers */
if (!gst_v4lmjpegsink_playback_deinit(v4lmjpegsink))
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_PAUSED:
if (!GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsink))) {
/* set buffer info */
if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
v4lmjpegsink->numbufs, v4lmjpegsink->bufsize))
return GST_STATE_FAILURE;
if (!gst_v4lmjpegsink_playback_init(v4lmjpegsink))
return GST_STATE_FAILURE;
}
else {
/* de-queue all queued buffers */
if (!gst_v4lmjpegsink_playback_stop(v4lmjpegsink))
return GST_STATE_FAILURE;
}
case GST_STATE_READY_TO_PAUSED:
/* set buffer info */
if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
v4lmjpegsink->numbufs, v4lmjpegsink->bufsize))
return GST_STATE_FAILURE;
if (!gst_v4lmjpegsink_playback_init(v4lmjpegsink))
return GST_STATE_FAILURE;
break;
case GST_STATE_PLAYING:
case GST_STATE_PAUSED_TO_PLAYING:
/* start */
if (!gst_v4lmjpegsink_playback_start(v4lmjpegsink))
return GST_STATE_FAILURE;
break;
case GST_STATE_PLAYING_TO_PAUSED:
/* de-queue all queued buffers */
if (!gst_v4lmjpegsink_playback_stop(v4lmjpegsink))
return GST_STATE_FAILURE;
break;
case GST_STATE_PAUSED_TO_READY:
/* stop playback, unmap all buffers */
if (!gst_v4lmjpegsink_playback_deinit(v4lmjpegsink))
return GST_STATE_FAILURE;
break;
}
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}

View file

@ -125,31 +125,42 @@ gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass)
parent_class = g_type_class_ref(GST_TYPE_V4LELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_X_OFFSET,
g_param_spec_int("x_offset","x_offset","x_offset",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("x_offset","x_offset","x_offset",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_Y_OFFSET,
g_param_spec_int("y_offset","y_offset","y_offset",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("y_offset","y_offset","y_offset",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_F_WIDTH,
g_param_spec_int("frame_width","frame_width","frame_width",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("frame_width","frame_width","frame_width",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_F_HEIGHT,
g_param_spec_int("frame_height","frame_height","frame_height",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("frame_height","frame_height","frame_height",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_H_DECIMATION,
g_param_spec_int("h_decimation","h_decimation","h_decimation",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("h_decimation","h_decimation","h_decimation",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_V_DECIMATION,
g_param_spec_int("v_decimation","v_decimation","v_decimation",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("v_decimation","v_decimation","v_decimation",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDTH,
g_param_spec_int("width","width","width",G_MININT,G_MAXINT,0,G_PARAM_READABLE));
g_param_spec_int("width","width","width",
G_MININT,G_MAXINT,0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT,
g_param_spec_int("height","height","height",G_MININT,G_MAXINT,0,G_PARAM_READABLE));
g_param_spec_int("height","height","height",
G_MININT,G_MAXINT,0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_QUALITY,
g_param_spec_int("quality","quality","quality",G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_param_spec_int("quality","quality","quality",
G_MININT,G_MAXINT,0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUMBUFS,
g_param_spec_int("num_buffers","num_buffers","num_buffers",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("num_buffers","num_buffers","num_buffers",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFSIZE,
g_param_spec_int("buffer_size","buffer_size","buffer_size",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("buffer_size","buffer_size","buffer_size",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
gobject_class->set_property = gst_v4lmjpegsrc_set_property;
gobject_class->get_property = gst_v4lmjpegsrc_get_property;
@ -311,7 +322,7 @@ gst_v4lmjpegsrc_set_property (GObject *object,
v4lmjpegsrc->bufsize = g_value_get_int(value);
break;
default:
parent_class->set_property(object, prop_id, value, pspec);
/*parent_class->set_property(object, prop_id, value, pspec);*/
break;
}
}
@ -342,7 +353,7 @@ gst_v4lmjpegsrc_get_property (GObject *object,
g_value_set_int(value, v4lmjpegsrc->breq.size);
break;
default:
parent_class->get_property(object, prop_id, value, pspec);
/*parent_class->get_property(object, prop_id, value, pspec);*/
break;
}
}
@ -357,57 +368,75 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
v4lmjpegsrc = GST_V4LMJPEGSRC(element);
switch (GST_STATE_PENDING(element)) {
case GST_STATE_READY:
if (GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsrc))) {
/* stop capturing, unmap all buffers */
if (!gst_v4lmjpegsrc_capture_deinit(v4lmjpegsrc))
return GST_STATE_FAILURE;
}
break;
case GST_STATE_PAUSED:
if (!GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsrc))) {
/* set buffer info */
if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize))
return GST_STATE_FAILURE;
/* set capture parameters and mmap the buffers */
if (!v4lmjpegsrc->frame_width && !v4lmjpegsrc->frame_height &&
v4lmjpegsrc->x_offset < 0 && v4lmjpegsrc->y_offset < 0 &&
v4lmjpegsrc->horizontal_decimation == v4lmjpegsrc->vertical_decimation)
{
if (!gst_v4lmjpegsrc_set_capture(v4lmjpegsrc,
v4lmjpegsrc->horizontal_decimation, v4lmjpegsrc->quality))
return GST_STATE_FAILURE;
}
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
{
if (!gst_v4lmjpegsrc_set_capture_m(v4lmjpegsrc,
v4lmjpegsrc->x_offset, v4lmjpegsrc->y_offset,
v4lmjpegsrc->frame_width, v4lmjpegsrc->frame_height,
v4lmjpegsrc->horizontal_decimation, v4lmjpegsrc->vertical_decimation,
v4lmjpegsrc->quality))
return GST_STATE_FAILURE;
}
v4lmjpegsrc->init = TRUE;
if (!gst_v4lmjpegsrc_capture_init(v4lmjpegsrc))
return GST_STATE_FAILURE;
}
else {
/* de-queue all queued buffers */
if (!gst_v4lmjpegsrc_capture_stop(v4lmjpegsrc))
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_PLAYING:
case GST_STATE_READY_TO_PAUSED:
/* set buffer info */
if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize))
return GST_STATE_FAILURE;
/* set capture parameters and mmap the buffers */
if (!v4lmjpegsrc->frame_width && !v4lmjpegsrc->frame_height &&
v4lmjpegsrc->x_offset < 0 && v4lmjpegsrc->y_offset < 0 &&
v4lmjpegsrc->horizontal_decimation == v4lmjpegsrc->vertical_decimation)
{
if (!gst_v4lmjpegsrc_set_capture(v4lmjpegsrc,
v4lmjpegsrc->horizontal_decimation, v4lmjpegsrc->quality))
return GST_STATE_FAILURE;
}
else
{
if (!gst_v4lmjpegsrc_set_capture_m(v4lmjpegsrc,
v4lmjpegsrc->x_offset, v4lmjpegsrc->y_offset,
v4lmjpegsrc->frame_width, v4lmjpegsrc->frame_height,
v4lmjpegsrc->horizontal_decimation, v4lmjpegsrc->vertical_decimation,
v4lmjpegsrc->quality))
return GST_STATE_FAILURE;
}
v4lmjpegsrc->init = TRUE;
if (!gst_v4lmjpegsrc_capture_init(v4lmjpegsrc))
return GST_STATE_FAILURE;
case GST_STATE_PAUSED_TO_PLAYING:
/* queue all buffer, start streaming capture */
if (!gst_v4lmjpegsrc_capture_start(v4lmjpegsrc))
return GST_STATE_FAILURE;
break;
case GST_STATE_PLAYING_TO_PAUSED:
/* de-queue all queued buffers */
if (!gst_v4lmjpegsrc_capture_stop(v4lmjpegsrc))
return GST_STATE_FAILURE;
break;
case GST_STATE_PAUSED_TO_READY:
/* stop capturing, unmap all buffers */
if (!gst_v4lmjpegsrc_capture_deinit(v4lmjpegsrc))
return GST_STATE_FAILURE;
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
return GST_STATE_SUCCESS;
}

View file

@ -119,11 +119,14 @@ gst_v4lsrc_class_init (GstV4lSrcClass *klass)
parent_class = g_type_class_ref(GST_TYPE_V4LELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDTH,
g_param_spec_int("width","width","width",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("width","width","width",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT,
g_param_spec_int("height","height","height",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("height","height","height",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PALETTE,
g_param_spec_int("palette","palette","palette",G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_param_spec_int("palette","palette","palette",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
gobject_class->set_property = gst_v4lsrc_set_property;
gobject_class->get_property = gst_v4lsrc_get_property;
@ -401,7 +404,7 @@ gst_v4lsrc_set_property (GObject *object,
break;
default:
parent_class->set_property(object, prop_id, value, pspec);
/*parent_class->set_property(object, prop_id, value, pspec);*/
break;
}
}
@ -432,7 +435,7 @@ gst_v4lsrc_get_property (GObject *object,
break;
default:
parent_class->get_property(object, prop_id, value, pspec);
/*parent_class->get_property(object, prop_id, value, pspec);*/
break;
}
}
@ -447,39 +450,43 @@ gst_v4lsrc_change_state (GstElement *element)
v4lsrc = GST_V4LSRC(element);
switch (GST_STATE_PENDING(element)) {
case GST_STATE_READY:
if (GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lsrc))) {
/* stop capturing, unmap all buffers */
if (!gst_v4lsrc_capture_deinit(v4lsrc))
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_PAUSED:
if (!GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lsrc))) {
/* set capture parameters and mmap the buffers */
if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette))
return GST_STATE_FAILURE;
v4lsrc->init = TRUE;
if (!gst_v4lsrc_capture_init(v4lsrc))
return GST_STATE_FAILURE;
}
else {
/* de-queue all queued buffers */
if (!gst_v4lsrc_capture_stop(v4lsrc))
return GST_STATE_FAILURE;
}
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))
return GST_STATE_FAILURE;
v4lsrc->init = TRUE;
if (!gst_v4lsrc_capture_init(v4lsrc))
return GST_STATE_FAILURE;
break;
case GST_STATE_PLAYING:
case GST_STATE_PAUSED_TO_PLAYING:
/* queue all buffer, start streaming capture */
if (!gst_v4lsrc_capture_start(v4lsrc))
return GST_STATE_FAILURE;
break;
case GST_STATE_PLAYING_TO_PAUSED:
/* de-queue all queued buffers */
if (!gst_v4lsrc_capture_stop(v4lsrc))
return GST_STATE_FAILURE;
break;
case GST_STATE_PAUSED_TO_READY:
/* stop capturing, unmap all buffers */
if (!gst_v4lsrc_capture_deinit(v4lsrc))
return GST_STATE_FAILURE;
break;
}
if (GST_ELEMENT_CLASS(parent_class)->change_state)
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
return GST_STATE_SUCCESS;
}

View file

@ -208,12 +208,14 @@ gst_v4l_set_chan_norm (GstV4lElement *v4lelement,
GST_V4L_CHECK_OPEN(v4lelement);
GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
// if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
// {
// gst_error("V4lElement - Error getting the channel/norm settings: %s",
// sys_errlist[errno]);
// return FALSE;
// }
#if 0
if (ioctl(v4lelement->video_fd, VIDIOCGCHAN, &vchan) < 0)
{
gst_error("V4lElement - Error getting the channel/norm settings: %s",
sys_errlist[errno]);
return FALSE;
}
#endif
vchan.channel = channel;
vchan.norm = norm;

View file

@ -69,7 +69,7 @@ gst_v4lmjpegsink_sync_thread (void *arg)
pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
if (ioctl(GST_V4LELEMENT(v4lmjpegsink)->video_fd, MJPIOC_SYNC,
&(v4lmjpegsink->bsync)) < 0)
&(v4lmjpegsink->bsync)) < 0)
{
gst_element_error(GST_ELEMENT(v4lmjpegsink),
"Failed to sync on frame %d: %s",
@ -432,7 +432,7 @@ gst_v4lmjpegsink_playback_start (GstV4lMjpegSink *v4lmjpegsink)
/* create sync() thread */
if (pthread_create(&(v4lmjpegsink->thread_queued_frames), NULL,
gst_v4lmjpegsink_sync_thread, (void *) v4lmjpegsink))
gst_v4lmjpegsink_sync_thread, (void *) v4lmjpegsink))
{
gst_element_error(GST_ELEMENT(v4lmjpegsink),
"Failed to create sync thread: %s",

View file

@ -144,6 +144,18 @@ gst_v4lmjpegsrc_set_input_norm (GstV4lMjpegSrc *v4lmjpegsrc,
break;
}
}
/* check */
if (input == V4L_MJPEG_INPUT_AUTO || norm == VIDEO_MODE_AUTO)
{
gst_element_error(GST_ELEMENT(v4lmjpegsrc),
"Unable to auto-detect an input");
return FALSE;
}
/* save */
GST_V4LELEMENT(v4lmjpegsrc)->channel = input;
GST_V4LELEMENT(v4lmjpegsrc)->norm = norm;
}
else if (norm == VIDEO_MODE_AUTO && input)
{
@ -163,6 +175,7 @@ gst_v4lmjpegsrc_set_input_norm (GstV4lMjpegSrc *v4lmjpegsrc,
gst_element_info(GST_ELEMENT(v4lmjpegsrc),
"Norm %s detected on input %s",
norm_name[bstat.norm], input_name[input]);
GST_V4LELEMENT(v4lmjpegsrc)->norm = norm;
}
else
{
@ -430,7 +443,8 @@ gst_v4lmjpegsrc_capture_init (GstV4lMjpegSrc *v4lmjpegsrc)
v4lmjpegsrc->breq.count, v4lmjpegsrc->breq.size/1024);
/* Map the buffers */
GST_V4LELEMENT(v4lmjpegsrc)->buffer = mmap(0, v4lmjpegsrc->breq.count * v4lmjpegsrc->breq.size,
GST_V4LELEMENT(v4lmjpegsrc)->buffer = mmap(0,
v4lmjpegsrc->breq.count * v4lmjpegsrc->breq.size,
PROT_READ, MAP_SHARED, GST_V4LELEMENT(v4lmjpegsrc)->video_fd, 0);
if (GST_V4LELEMENT(v4lmjpegsrc)->buffer == MAP_FAILED)
{

View file

@ -141,8 +141,9 @@ retry:
}
end:
gst_element_info(GST_ELEMENT(v4lsrc),
"Software sync thread got signalled to exit");
#ifdef DEBUG
fprintf(stderr, "Software sync thread got signalled to exit");
#endif
pthread_exit(NULL);
}