Bugfixes - better said, v4lsrc works again (it was broken?) and v4lmjpegsrc/sink...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 4 Jan 2002 23:58:11 +0000 (23:58 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 4 Jan 2002 23:58:11 +0000 (23:58 +0000)
Original commit message from CVS:
Bugfixes - better said, v4lsrc works again (it was broken?) and v4lmjpegsrc/sink are being worked on

sys/v4l/gstv4lelement.c
sys/v4l/gstv4lmjpegsink.c
sys/v4l/gstv4lmjpegsrc.c
sys/v4l/gstv4lsrc.c
sys/v4l/v4lsrc_calls.c

index 25f82b3..b2930aa 100644 (file)
@@ -465,7 +465,7 @@ gst_v4lelement_change_state (GstElement *element)
 {
   GstV4lElement *v4lelement;
   
-  g_return_val_if_fail(GST_IS_V4LELEMENT(element), FALSE);
+  g_return_val_if_fail(GST_IS_V4LELEMENT(element), GST_STATE_FAILURE);
   
   v4lelement = GST_V4LELEMENT(element);
 
index 5ec3f94..bbbca44 100644 (file)
@@ -317,23 +317,13 @@ static GstElementStateReturn
 gst_v4lmjpegsink_change_state (GstElement *element)
 {
   GstV4lMjpegSink *v4lmjpegsink;
+  GstElementStateReturn parent_value;
 
   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_TRANSITION(element)) {
-    case GST_STATE_NULL_TO_READY:
-      if (GST_V4LELEMENT(v4lmjpegsink)->norm >= VIDEO_MODE_PAL &&
-          GST_V4LELEMENT(v4lmjpegsink)->norm < VIDEO_MODE_AUTO &&
-          GST_V4LELEMENT(v4lmjpegsink)->channel < 0)
-        if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsink),
-             0, GST_V4LELEMENT(v4lmjpegsink)->norm))
-          return GST_STATE_FAILURE;
-      break;
     case GST_STATE_READY_TO_PAUSED:
       /* set buffer info */
       if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
@@ -359,6 +349,22 @@ gst_v4lmjpegsink_change_state (GstElement *element)
       break;
   }
 
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+  {
+    if ((GST_V4LELEMENT(v4lmjpegsink)->norm >= VIDEO_MODE_PAL ||
+         GST_V4LELEMENT(v4lmjpegsink)->norm < VIDEO_MODE_AUTO) ||
+        GST_V4LELEMENT(v4lmjpegsink)->channel < 0)
+      if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsink),
+           0, GST_V4LELEMENT(v4lmjpegsink)->norm))
+        return GST_STATE_FAILURE;
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return parent_value;
+
   return GST_STATE_SUCCESS;
 }
 
index 823512a..b4a0c1b 100644 (file)
@@ -363,38 +363,13 @@ static GstElementStateReturn
 gst_v4lmjpegsrc_change_state (GstElement *element)
 {
   GstV4lMjpegSrc *v4lmjpegsrc;
-  
-  g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), FALSE);
+  GstElementStateReturn parent_value;
+
+  g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), GST_STATE_FAILURE);
   
   v4lmjpegsrc = GST_V4LMJPEGSRC(element);
 
-  if (GST_ELEMENT_CLASS(parent_class)->change_state)
-    return GST_ELEMENT_CLASS(parent_class)->change_state(element);
-
   switch (GST_STATE_TRANSITION(element)) {
-    case GST_STATE_NULL_TO_READY:
-      /* do autodetection if no input/norm is selected yet */
-      if (GST_V4LELEMENT(v4lmjpegsrc)->norm < VIDEO_MODE_PAL ||
-          GST_V4LELEMENT(v4lmjpegsrc)->norm == VIDEO_MODE_AUTO ||
-          GST_V4LELEMENT(v4lmjpegsrc)->channel < 0 ||
-          GST_V4LELEMENT(v4lmjpegsrc)->channel == V4L_MJPEG_INPUT_AUTO)
-      {
-        gint norm, input;
-
-        if (GST_V4LELEMENT(v4lmjpegsrc)->norm < 0)
-          norm = VIDEO_MODE_AUTO;
-        else
-          norm = GST_V4LELEMENT(v4lmjpegsrc)->norm;
-
-        if (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0)
-          input = V4L_MJPEG_INPUT_AUTO;
-        else
-          input = GST_V4LELEMENT(v4lmjpegsrc)->channel;
-
-        if (!gst_v4lmjpegsrc_set_input_norm(v4lmjpegsrc, input, norm))
-          return GST_STATE_FAILURE;
-      }
-      break;
     case GST_STATE_READY_TO_PAUSED:
       /* set buffer info */
       if (!gst_v4lmjpegsrc_set_buffer(v4lmjpegsrc, v4lmjpegsrc->numbufs, v4lmjpegsrc->bufsize))
@@ -437,6 +412,37 @@ gst_v4lmjpegsrc_change_state (GstElement *element)
       break;
   }
 
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+  {
+    /* do autodetection if no input/norm is selected yet */
+    if ((GST_V4LELEMENT(v4lmjpegsrc)->norm < VIDEO_MODE_PAL ||
+         GST_V4LELEMENT(v4lmjpegsrc)->norm == VIDEO_MODE_AUTO) ||
+        (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0 ||
+         GST_V4LELEMENT(v4lmjpegsrc)->channel == V4L_MJPEG_INPUT_AUTO))
+    {
+      gint norm, input;
+
+      if (GST_V4LELEMENT(v4lmjpegsrc)->norm < 0)
+        norm = VIDEO_MODE_AUTO;
+      else
+        norm = GST_V4LELEMENT(v4lmjpegsrc)->norm;
+
+      if (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0)
+        input = V4L_MJPEG_INPUT_AUTO;
+      else
+        input = GST_V4LELEMENT(v4lmjpegsrc)->channel;
+
+      if (!gst_v4lmjpegsrc_set_input_norm(v4lmjpegsrc, input, norm))
+        return GST_STATE_FAILURE;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return parent_value;
+
   return GST_STATE_SUCCESS;
 }
 
index cc3e651..6322d8e 100644 (file)
@@ -445,23 +445,13 @@ static GstElementStateReturn
 gst_v4lsrc_change_state (GstElement *element)
 {
   GstV4lSrc *v4lsrc;
-  
-  g_return_val_if_fail(GST_IS_V4LSRC(element), FALSE);
+  GstElementStateReturn parent_value;
+
+  g_return_val_if_fail(GST_IS_V4LSRC(element), GST_STATE_FAILURE);
   
   v4lsrc = GST_V4LSRC(element);
 
-  if (GST_ELEMENT_CLASS(parent_class)->change_state)
-    return GST_ELEMENT_CLASS(parent_class)->change_state(element);
-
   switch (GST_STATE_TRANSITION(element)) {
-    case GST_STATE_NULL_TO_READY:
-      if (GST_V4LELEMENT(v4lsrc)->norm >= VIDEO_MODE_PAL &&
-          GST_V4LELEMENT(v4lsrc)->norm < VIDEO_MODE_AUTO &&
-          GST_V4LELEMENT(v4lsrc)->channel < 0)
-        if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lsrc),
-             0, GST_V4LELEMENT(v4lsrc)->norm))
-          return GST_STATE_FAILURE;
-      break;
     case GST_STATE_READY_TO_PAUSED:
       /* set capture parameters and mmap the buffers */
       if (!gst_v4lsrc_set_capture(v4lsrc, v4lsrc->width, v4lsrc->height, v4lsrc->palette))
@@ -487,6 +477,22 @@ gst_v4lsrc_change_state (GstElement *element)
       break;
   }
 
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY)
+  {
+    if ((GST_V4LELEMENT(v4lsrc)->norm >= VIDEO_MODE_PAL ||
+         GST_V4LELEMENT(v4lsrc)->norm < VIDEO_MODE_AUTO) ||
+        GST_V4LELEMENT(v4lsrc)->channel < 0)
+      if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lsrc),
+           0, GST_V4LELEMENT(v4lsrc)->norm))
+        return GST_STATE_FAILURE;
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return parent_value;
+
   return GST_STATE_SUCCESS;
 }
 
index c44aca2..228f3e7 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include "v4lsrc_calls.h"
+#include <sys/time.h>
+
+/* number of buffers to be queued *at least* before syncing */
+#define MIN_BUFFERS_QUEUED 2
 
 /* On some systems MAP_FAILED seems to be missing */
 #ifndef MAP_FAILED
@@ -81,7 +85,7 @@ static void *
 gst_v4lsrc_soft_sync_thread (void *arg)
 {
   GstV4lSrc *v4lsrc = GST_V4LSRC(arg);
-  guint16 frame = 0;
+  gint frame = 0;
 
 #ifdef DEBUG
   fprintf(stderr, "gst_v4lsrc_soft_sync_thread()\n");
@@ -95,20 +99,30 @@ gst_v4lsrc_soft_sync_thread (void *arg)
   {
     /* are there queued frames left? */
     pthread_mutex_lock(&(v4lsrc->mutex_queued_frames));
-    if (v4lsrc->num_queued_frames < 1)
+    if (v4lsrc->num_queued_frames < MIN_BUFFERS_QUEUED)
     {
+#ifdef DEBUG
+      fprintf(stderr, "Waiting for new frames to be queued (%d < %d)\n",
+        v4lsrc->num_queued_frames, MIN_BUFFERS_QUEUED);
+#endif
       pthread_cond_wait(&(v4lsrc->cond_queued_frames),
         &(v4lsrc->mutex_queued_frames));
     }
     pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
 
     /* if still wrong, we got interrupted and we should exit */
-    if (v4lsrc->num_queued_frames < 1)
+    if (v4lsrc->num_queued_frames < MIN_BUFFERS_QUEUED)
     {
+#ifdef DEBUG
+      fprintf(stderr, "Still not enough frames, quitting...\n");
+#endif
       goto end;
     }
 
     /* sync on the frame */
+#ifdef DEBUG
+    fprintf(stderr, "Sync\'ing on frame %d\n", frame);
+#endif
 retry:
     if (ioctl(GST_V4LELEMENT(v4lsrc)->video_fd, VIDIOCSYNC, &frame) < 0)
     {
@@ -142,7 +156,7 @@ retry:
 
 end:
 #ifdef DEBUG
-  fprintf(stderr, "Software sync thread got signalled to exit");
+  fprintf(stderr, "Software sync thread got signalled to exit\n");
 #endif
   pthread_exit(NULL);
 }
@@ -159,25 +173,27 @@ gst_v4lsrc_sync_next_frame (GstV4lSrc *v4lsrc,
                             gint      *num)
 {
 #ifdef DEBUG
-  fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame(), num = %d\n",
-    num);
+  fprintf(stderr, "V4LSRC: gst_v4lsrc_sync_frame()\n");
 #endif
 
-  *num = (v4lsrc->sync_frame + 1)%v4lsrc->mbuf.frames;
+  *num = v4lsrc->sync_frame = (v4lsrc->sync_frame + 1)%v4lsrc->mbuf.frames;
 
   /* "software sync()" on the frame */
   pthread_mutex_lock(&(v4lsrc->mutex_soft_sync));
-  if (v4lsrc->isready_soft_sync[*num])
+  if (v4lsrc->isready_soft_sync[*num] == 0)
   {
+#ifdef DEBUG
+    fprintf(stderr, "Waiting for frame %d to be synced on\n",
+      *num);
+#endif
     pthread_cond_wait(&(v4lsrc->cond_soft_sync[*num]),
       &(v4lsrc->mutex_soft_sync));
   }
-  pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
 
   if (v4lsrc->isready_soft_sync[*num] < 0)
     return FALSE;
-
   v4lsrc->isready_soft_sync[*num] = 0;
+  pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
 
   v4lsrc->frame_queued[*num] = FALSE;
 
@@ -240,12 +256,20 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
     return FALSE;
   }
 
+  if (v4lsrc->mbuf.frames < MIN_BUFFERS_QUEUED)
+  {
+    gst_element_error(GST_ELEMENT(v4lsrc),
+      "Too little buffers. We got %d, we want at least %d",
+      v4lsrc->mbuf.frames, MIN_BUFFERS_QUEUED);
+    return FALSE;
+  }
+
   gst_element_info(GST_ELEMENT(v4lsrc),
     "Got %d buffers of size %d KB",
     v4lsrc->mbuf.frames, v4lsrc->mbuf.size/(v4lsrc->mbuf.frames*1024));
 
   /* keep trakc of queued buffers */
-  v4lsrc->frame_queued = (gint *) malloc(sizeof(gint) * v4lsrc->mbuf.frames);
+  v4lsrc->frame_queued = (gint *) malloc(sizeof(int) * v4lsrc->mbuf.frames);
   if (!v4lsrc->frame_queued)
   {
     gst_element_error(GST_ELEMENT(v4lsrc),