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):
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
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
};
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;
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;
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;
}
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:
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:
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))
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);
/* 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))
+ 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)
+ {
+ if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
return GST_STATE_FAILURE;
- break;
- case GST_STATE_READY:
- if (!GST_V4L_IS_OPEN(v4lelement))
+ }
+ if (v4lelement->frequency > 0 && gst_v4l_has_tuner(v4lelement))
{
- int n, temp;
-
- if (!gst_v4l_open(v4lelement))
+ if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
return GST_STATE_FAILURE;
-
- /* now, sync options */
- if (v4lelement->norm >= VIDEO_MODE_PAL &&
- v4lelement->norm < VIDEO_MODE_AUTO &&
- v4lelement->channel >= 0)
+ }
+ for (n=V4L_AUDIO_VOLUME;n<=V4L_AUDIO_MODE;n++)
+ {
+ switch (n)
{
- if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm))
- return GST_STATE_FAILURE;
+ 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 (v4lelement->frequency > 0 && gst_v4l_has_tuner(v4lelement))
+ if (temp >= 0 && gst_v4l_has_audio(v4lelement))
{
- if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency))
+ if (!gst_v4l_set_audio(v4lelement, n, temp))
return GST_STATE_FAILURE;
}
- for (n=V4L_AUDIO_VOLUME;n<=V4L_AUDIO_MODE;n++)
+ }
+ for (n=V4L_PICTURE_HUE;n<=V4L_PICTURE_SATURATION;n++)
+ {
+ switch (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;
- }
+ 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;
}
- for (n=V4L_PICTURE_HUE;n<=V4L_PICTURE_SATURATION;n++)
+ if (temp >= 0)
{
- 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;
- }
+ 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;
}
gint channel;
gint norm;
gulong frequency;
- gint mute;
+ gboolean mute;
gint volume;
gint mode;
gint brightness;
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;
}
}
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;
}
}
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;
}
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;
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;
}
}
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;
}
}
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))
+ 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_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;
- }
- 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))
+ 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 {
- /* de-queue all queued buffers */
- if (!gst_v4lmjpegsrc_capture_stop(v4lmjpegsrc))
+ 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;
}
- break;
- case GST_STATE_PLAYING:
+ 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;
}
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;
break;
default:
- parent_class->set_property(object, prop_id, value, pspec);
+ /*parent_class->set_property(object, prop_id, value, pspec);*/
break;
}
}
break;
default:
- parent_class->get_property(object, prop_id, value, pspec);
+ /*parent_class->get_property(object, prop_id, value, pspec);*/
break;
}
}
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;
}
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;
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",
/* 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",
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)
{
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
{
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)
{
}
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);
}