diff options
author | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | 2001-12-28 19:54:23 +0000 |
---|---|---|
committer | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | 2001-12-28 19:54:23 +0000 |
commit | dcf3d39af1af5d28425296164a1ee191645f87ce (patch) | |
tree | e8179a7f308bc2f6e9422078819196ffd0526341 /sys | |
parent | bda010a7fac7383f423b4d85022cababaaf87df3 (diff) |
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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/v4l/TODO | 6 | ||||
-rw-r--r-- | sys/v4l/gstv4lelement.c | 230 | ||||
-rw-r--r-- | sys/v4l/gstv4lelement.h | 2 | ||||
-rw-r--r-- | sys/v4l/gstv4lmjpegsink.c | 56 | ||||
-rw-r--r-- | sys/v4l/gstv4lmjpegsrc.c | 131 | ||||
-rw-r--r-- | sys/v4l/gstv4lsrc.c | 65 | ||||
-rw-r--r-- | sys/v4l/v4l_calls.c | 14 | ||||
-rw-r--r-- | sys/v4l/v4lmjpegsink_calls.c | 4 | ||||
-rw-r--r-- | sys/v4l/v4lmjpegsrc_calls.c | 16 | ||||
-rw-r--r-- | sys/v4l/v4lsrc_calls.c | 5 |
10 files changed, 335 insertions, 194 deletions
diff --git a/sys/v4l/TODO b/sys/v4l/TODO index b616d58e2..cfc17216e 100644 --- a/sys/v4l/TODO +++ b/sys/v4l/TODO @@ -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 diff --git a/sys/v4l/gstv4lelement.c b/sys/v4l/gstv4lelement.c index 9b05546f0..25f82b3de 100644 --- a/sys/v4l/gstv4lelement.c +++ b/sys/v4l/gstv4lelement.c @@ -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)) + 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; } diff --git a/sys/v4l/gstv4lelement.h b/sys/v4l/gstv4lelement.h index 62c973b50..b49ebad10 100644 --- a/sys/v4l/gstv4lelement.h +++ b/sys/v4l/gstv4lelement.h @@ -62,7 +62,7 @@ struct _GstV4lElement { gint channel; gint norm; gulong frequency; - gint mute; + gboolean mute; gint volume; gint mode; gint brightness; diff --git a/sys/v4l/gstv4lmjpegsink.c b/sys/v4l/gstv4lmjpegsink.c index b189430c3..998c6f105 100644 --- a/sys/v4l/gstv4lmjpegsink.c +++ b/sys/v4l/gstv4lmjpegsink.c @@ -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; } diff --git a/sys/v4l/gstv4lmjpegsrc.c b/sys/v4l/gstv4lmjpegsrc.c index e15eb0d8c..823512ae4 100644 --- a/sys/v4l/gstv4lmjpegsrc.c +++ b/sys/v4l/gstv4lmjpegsrc.c @@ -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)) + 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; } diff --git a/sys/v4l/gstv4lsrc.c b/sys/v4l/gstv4lsrc.c index 2cc1435a1..cc3e65196 100644 --- a/sys/v4l/gstv4lsrc.c +++ b/sys/v4l/gstv4lsrc.c @@ -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; } diff --git a/sys/v4l/v4l_calls.c b/sys/v4l/v4l_calls.c index 062cd8fd4..c16748cf2 100644 --- a/sys/v4l/v4l_calls.c +++ b/sys/v4l/v4l_calls.c @@ -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; diff --git a/sys/v4l/v4lmjpegsink_calls.c b/sys/v4l/v4lmjpegsink_calls.c index 1814c2e35..4a69fb21f 100644 --- a/sys/v4l/v4lmjpegsink_calls.c +++ b/sys/v4l/v4lmjpegsink_calls.c @@ -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", diff --git a/sys/v4l/v4lmjpegsrc_calls.c b/sys/v4l/v4lmjpegsrc_calls.c index ddd738aee..f6584e29a 100644 --- a/sys/v4l/v4lmjpegsrc_calls.c +++ b/sys/v4l/v4lmjpegsrc_calls.c @@ -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) { diff --git a/sys/v4l/v4lsrc_calls.c b/sys/v4l/v4lsrc_calls.c index 0f3565fd3..c44aca22d 100644 --- a/sys/v4l/v4lsrc_calls.c +++ b/sys/v4l/v4lsrc_calls.c @@ -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); } |