Small changes and integration of norm and input autodetection for mjpegv4lsrc
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 28 Dec 2001 19:54:23 +0000 (19:54 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 28 Dec 2001 19:54:23 +0000 (19:54 +0000)
Original commit message from CVS:
Small changes and integration of norm and input autodetection for mjpegv4lsrc

sys/v4l/TODO
sys/v4l/gstv4lelement.c
sys/v4l/gstv4lelement.h
sys/v4l/gstv4lmjpegsink.c
sys/v4l/gstv4lmjpegsrc.c
sys/v4l/gstv4lsrc.c
sys/v4l/v4l_calls.c
sys/v4l/v4lmjpegsink_calls.c
sys/v4l/v4lmjpegsrc_calls.c
sys/v4l/v4lsrc_calls.c

index b616d58..cfc1721 100644 (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
index 9b05546..25f82b3 100644 (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))
+    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;
   }
 
index 62c973b..b49ebad 100644 (file)
@@ -62,7 +62,7 @@ struct _GstV4lElement {
   gint channel;
   gint norm;
   gulong frequency;
-  gint mute;
+  gboolean mute;
   gint volume;
   gint mode;
   gint brightness;
index b189430..998c6f1 100644 (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;
 }
 
index e15eb0d..823512a 100644 (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))
+  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;
 }
 
index 2cc1435..cc3e651 100644 (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;
 }
 
index 062cd8f..c16748c 100644 (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;
index 1814c2e..4a69fb2 100644 (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",
index ddd738a..f6584e2 100644 (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)
   {
index 0f3565f..c44aca2 100644 (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);
 }