af status info passing via gst_element_post_message
authorMarko Ollonen <marko.ollonen@ixonos.com>
Fri, 23 Nov 2012 14:35:33 +0000 (16:35 +0200)
committerMarko Ollonen <marko.ollonen@ixonos.com>
Mon, 26 Nov 2012 07:16:21 +0000 (09:16 +0200)
Change-Id: Ibae7517d7e3abd750e8e3230b1b426948f62d608

gst-libs/atomisphal/mfld_cam.c
gst-libs/atomisphal/mfld_cam.h
gst-libs/gst/camera/gstmfldcameracontroliface.c
gst-libs/gst/camera/gstmfldcamerasrc.c
gst-libs/gst/camera/gstmfldcamerasrc.h
gst/mfldv4l2cam/v4l2camsrc_calls.c
packaging/mfldv4l2camsrc.changes

index 5666510..45d6a79 100644 (file)
@@ -95,6 +95,7 @@ struct mfld_driver_t
   int af_enabled, ae_enabled, awb_enabled;
   int af_result;  // 0 means fail, it will be filled when captured finished.
   int still_af_count, start_still_af;
+  struct timeval af_start_time;
   int initflag;
   int mmap;
   int first_frame;
@@ -106,6 +107,7 @@ struct mfld_driver_t
   float frame_rate;
   int sensor_type;
   struct timeval timestamp;
+  int focus_done;
 };
 
 struct buffer
@@ -114,12 +116,30 @@ struct buffer
   size_t length;
 };
 
+/* TODO: Check if this is needed anymore after focus works like it should.
+ * Hysteriss added to focus_done
+ * in some case when old focus is still in progress and appication
+ * ask new focus to be started  might be a case that 3A returns false "focus ready"
+ * and status info is sent to app. -> for some reason it will crash to that.
+* */
+#define FOCUS_REALLY_DONE   2
+
+/* Maximum auto focus time */
+static const int STILL_AF_MAX_TIME_IN_MS = 2200;
+
 /* FIXME: Add lock to protec this global variable
  * */
 static struct mfld_cam_settings_t mfld_cam_settings;
 static struct mfld_driver_t mfld_driver;
 static GstV4l2MFLDAdvCI *mfldadvci;
 
+static inline long
+calculate_timediff(struct timeval *t0, struct timeval *t1)
+{
+  return ((t1->tv_sec - t0->tv_sec) * 1000000 +
+            t1->tv_usec - t0->tv_usec) / 1000;
+}
+
 static void
 clear_bit (int nr, unsigned int *addr)
 {
@@ -780,18 +800,24 @@ cam_set_privacy_light (int fd, int on)
 
 /* V4l2camerasrc uses this to query autofocusing status.
  */
-cam_err_t
-cam_checkfocus_status (cam_focus_status_t * status)
+int
+cam_checkfocus_status (cam_focus_status_t * status, int force_update)
 {
-  ia_3a_af_status adv_status;
-
+  ia_3a_af_status af_status;
+  bool do_read = FALSE;
 
-  mfldadvci->AfGetStillAfStatus (&adv_status);
-
-  cam_driver_dbg ("%s\n", __func__);
-
-  *status = cam_find_item_new (focus_status_map, adv_status, 1);
-  return CAM_ERR_NONE;
+  if (mfld_driver.focus_done >= FOCUS_REALLY_DONE) {
+    mfld_driver.focus_done = 0;
+    do_read = TRUE;
+  }
+  if ((do_read == TRUE) || (force_update == 1)) {
+    mfldadvci->AfGetStillAfStatus (&af_status);
+    *status = cam_find_item_new (focus_status_map, af_status, 1);
+    cam_driver_dbg ("%s *status : %d\n ", __func__, *status);
+    *status  = CAM_FOCUS_STATUS_RUNNING;
+    return 1;
+  }
+  return 0;
 }
 
 /* V4l2camerasrc uses this to query the risk for image shaking.
@@ -1136,6 +1162,7 @@ libmfld_cam_init (GstV4l2MFLDAdvCI * advci)
 
   mfld_driver.dvs_vector.x = 0;
   mfld_driver.dvs_vector.y = 0;
+  mfld_driver.focus_done = 0;
 
   mfldadvci = advci;
 
@@ -1513,8 +1540,10 @@ cam_capture_init (int fd, struct v4l2_buffer *buffer,
   if (mfld_driver.start_still_af) {
     if (mfld_driver.af_enabled && mfld_driver.still_af_count > 0)
       mfldadvci->af_stop ();
+    mfld_driver.focus_done = 0;
     mfld_driver.start_still_af = 0;
     mfld_driver.still_af_count = 1;
+    mfld_driver.af_start_time = mfld_driver.timestamp;
 
     if (mfld_driver.af_enabled)
       mfldadvci->af_start ();
@@ -1629,12 +1658,19 @@ run_normal_sequence(int fd, struct v4l2_buffer *buffer)
     if (mfld_driver.af_enabled)
       complete = mfldadvci->af_is_complete ();
 
-    if (complete || mfld_driver.still_af_count > 100) {
-      mfld_driver.still_af_count = 0;
-      if (complete == 0) {
-        mfldadvci->af_stop();
-        cam_driver_dbg ("AF: Focus Failed %s\n", __func__);
+   if (complete ||
+       (calculate_timediff(&mfld_driver.af_start_time, &mfld_driver.timestamp)
+        > STILL_AF_MAX_TIME_IN_MS) ) {
+      mfld_driver.focus_done ++;
+      if(mfld_driver.focus_done >= FOCUS_REALLY_DONE) {
+        mfld_driver.still_af_count = 0;
+        if (complete == 0) {
+          mfldadvci->af_stop();
+          cam_driver_dbg ("AF: Focus Failed %s\n", __func__);
+        }
       }
+      else
+        mfld_driver.still_af_count++;
     } else
       mfld_driver.still_af_count++;
   }
index 59b73c2..b324143 100644 (file)
@@ -244,7 +244,7 @@ cam_err_t cam_set_autofocus (int on);
 
 cam_err_t cam_set_frame_rate( float frame_rate);
 
-cam_err_t cam_checkfocus_status (cam_focus_status_t * status);
+int cam_checkfocus_status (cam_focus_status_t * status, int force_update);
 
 cam_err_t cam_get_shake_risk (int fd, int risk);
 
index 4640b5b..1f12f73 100644 (file)
@@ -36,13 +36,6 @@ GST_BOILERPLATE (GstCameraSrcCameraControlChannel,
     gst_camerasrc_camera_control_channel,
     GstCameraControlChannel, GST_TYPE_CAMERA_CONTROL_CHANNEL);
 
-gboolean
-gst_camerasrc_camera_control_parse_preview_caps (GstCameraSrc *camerasrc,
-                                        GstCaps *op_mode_caps);
-
-gboolean
-gst_camerasrc_camera_control_parse_capture_caps (GstCameraSrc * camerasrc,
-    GstCaps * op_mode_caps);
 
 static void
 gst_camerasrc_camera_control_channel_base_init (gpointer g_class)
@@ -361,11 +354,13 @@ gst_camerasrc_camera_control_set_focus( GstCameraSrc* camerasrc,
     case MM_CAMCORDER_FOCUS_MODE_NONE:
       focus_mode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY;
       break;
-    case MM_CAMCORDER_FOCUS_MODE_PAN:
     case MM_CAMCORDER_FOCUS_MODE_AUTO:
     case MM_CAMCORDER_FOCUS_MODE_TOUCH_AUTO:
       focus_mode = GST_PHOTOGRAPHY_FOCUS_MODE_AUTO;
       break;
+    case MM_CAMCORDER_FOCUS_MODE_PAN:
+      focus_mode = GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL;
+      break;
     case MM_CAMCORDER_FOCUS_MODE_MANUAL:
       focus_mode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY;
       break;
@@ -403,6 +398,9 @@ gst_camerasrc_camera_control_get_focus( GstCameraSrc* camerasrc,
     case GST_PHOTOGRAPHY_FOCUS_MODE_AUTO:
       *mode = MM_CAMCORDER_FOCUS_MODE_AUTO;
       break;
+    case GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL:
+      *mode = MM_CAMCORDER_FOCUS_MODE_PAN;
+      break;
     case GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL:
       *mode = MM_CAMCORDER_FOCUS_MODE_CONTINUOUS;
       break;
@@ -664,7 +662,6 @@ gst_camerasrc_camera_control_set_capture_command( GstCameraSrc* camerasrc,
         "framerate", GST_TYPE_FRACTION, camerasrc->capture_fps_n,
          camerasrc->capture_fps_d, NULL);
 
-     gst_camerasrc_camera_control_parse_capture_caps(camerasrc,CaptureCaps);
      camerasrc->photo_capture_phase = GST_CAMERA_CAPTURE_START;
      g_mutex_unlock (camerasrc->state_lock);
   }
@@ -675,225 +672,3 @@ gst_camerasrc_camera_control_set_capture_command( GstCameraSrc* camerasrc,
     g_mutex_unlock (camerasrc->state_lock);
   }
 }
-
-
-gboolean
-gst_camerasrc_camera_control_parse_capture_caps (GstCameraSrc * camerasrc,
-    GstCaps * op_mode_caps)
-{
-  GstCameraSrcClass *bclass;
-
-  gboolean ret = TRUE;
-  GstStructure *cstr;
-  guint32 fcc_format;
-  gint tmp_fps_n = 0;
-  gint tmp_fps_d = 0;
-  gint tmp_w = 0;
-  gint tmp_h = 0;
-
-  bclass = GST_CAMERA_SRC_GET_CLASS (camerasrc);
-
-  GST_DEBUG_OBJECT (camerasrc, "Parsing image capture caps");
-
-  if (op_mode_caps == NULL) {
-    camerasrc->capture_resolution_set = FALSE;
-    GST_DEBUG_OBJECT (camerasrc, "NULL caps received for image capture");
-    goto done;
-  }
-
-  cstr = gst_caps_get_structure (op_mode_caps, 0);
-
-  /* FIXME: Use VF format if fourcc is not given */
-  /* FIXME: Don't require FPS here */
-  if (gst_structure_get_fourcc (cstr, "format", &fcc_format) &&
-      gst_structure_get_int (cstr, "width", &tmp_w) &&
-      gst_structure_get_int (cstr, "height", &tmp_h) &&
-      gst_structure_get_fraction (cstr, "framerate", &tmp_fps_n, &tmp_fps_d)) {
-    /* check if the requested fourcc format is supported   */
-    GstCaps *s_caps = NULL;
-
-    /* get camsrc sourcepad caps, because the pad has
-     * caps-template including supported formats */
-    s_caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
-            (camerasrc)));
-
-    /* if intersection is empty -> provided caps not supported */
-    GST_LOG_OBJECT (camerasrc, "op_mode_caps caps: %" GST_PTR_FORMAT, op_mode_caps);
-    GST_LOG_OBJECT (camerasrc, "s_caps caps: %" GST_PTR_FORMAT, s_caps);
-
-    if (!gst_caps_can_intersect (op_mode_caps, s_caps)) {
-      GST_WARNING_OBJECT (camerasrc,
-          "Unsupported fourcc format provided by caller");
-      ret = FALSE;
-    }
-
-    /* Check that the requested resolution is not the same as what is
-     * currently configured to be in use. If so, no need to set it again.
-     */
-    if ((camerasrc->capture_w != tmp_w ||
-            camerasrc->capture_h != tmp_h ||
-            camerasrc->capture_fourcc != fcc_format) && ret == TRUE) {
-      GST_DEBUG_OBJECT (camerasrc,
-          "set width: %d , height: %d , fps_n: %d , fps_d :%d , format: %"
-          GST_FOURCC_FORMAT, tmp_w, tmp_h, tmp_fps_n, tmp_fps_d,
-          GST_FOURCC_ARGS (fcc_format));
-
-      ret = bclass->set_capture (camerasrc,
-          GST_PHOTOGRAPHY_OPERATION_MODE_IMAGE_CAPTURE, FALSE, &fcc_format,
-          (guint *) & tmp_w, (guint *) & tmp_h, NULL, NULL);
-/*
-      ret = bclass->set_capture (camerasrc,
-          GST_PHOTOGRAPHY_OPERATION_MODE_PREVIEW, FALSE, &fcc_format,
-          (guint *) & tmp_w, (guint *) & tmp_h, NULL, NULL);
-*/
-      if (ret) {
-        camerasrc->capture_w = tmp_w;
-        camerasrc->capture_h = tmp_h;
-        camerasrc->capture_fps_n = tmp_fps_n;
-        camerasrc->capture_fps_d = tmp_fps_d;
-        camerasrc->capture_fourcc = fcc_format;
-        camerasrc->capture_resolution_set = TRUE;
-
-        /* Write the assigned values back to the caps structure if possible */
-        if (GST_CAPS_REFCOUNT_VALUE (op_mode_caps) == 1) {
-          gst_caps_set_simple (op_mode_caps,
-              "width", G_TYPE_INT, camerasrc->capture_w,
-              "height", G_TYPE_INT, camerasrc->capture_h,
-              "format", GST_TYPE_FOURCC, camerasrc->capture_fourcc, NULL);
-        }
-
-        /* It may not be possible to create the preview with previously
-         * given resolution. Therefore we cancel the preview creation */
-        gst_camerasrc_camera_control_parse_preview_caps (camerasrc, NULL);
-
-        /* Notify that supported preview caps may have changed */
-        g_object_notify (G_OBJECT (camerasrc),
-            GST_PHOTOGRAPHY_PROP_IMAGE_PREVIEW_SUPPORTED_CAPS);
-      }
-    } else {
-      GST_DEBUG_OBJECT (camerasrc, "format not set");
-      ret = FALSE;
-    }
-    if (s_caps)
-      gst_caps_unref (s_caps);
-
-  } else {
-    GST_DEBUG_OBJECT (camerasrc, "Unable to parse given caps");
-    ret = FALSE;
-  }
-
-done:
-
-  return ret;
-}
-
-
-gboolean
-gst_camerasrc_camera_control_parse_preview_caps (GstCameraSrc *camerasrc,
-    GstCaps *op_mode_caps)
-{
-  GstCameraSrcClass *bclass;
-  gboolean ret = FALSE;
-  guint32 fourcc = 0;
-  gint tmp_w = 0;
-  gint tmp_h = 0;
-
-  bclass = GST_CAMERA_SRC_GET_CLASS (camerasrc);
-
-  if (op_mode_caps == NULL) {
-    /* Setting NULL caps means canceling the preview image creation process.
-     * In this case resolution 0x0 will be given to subclass */
-    GST_DEBUG_OBJECT (camerasrc, "NULL caps received for preview image");
-    ret = TRUE;
-  }
-  else {
-    GstStructure *cstr;
-
-    GST_DEBUG_OBJECT (camerasrc, "parsing preview caps");
-
-    cstr = gst_caps_get_structure (op_mode_caps, 0);
-
-    /* FIXME: Use VF format if fourcc is not given */
-    if (gst_structure_get_fourcc (cstr, "format", &fourcc) &&
-        gst_structure_get_int (cstr, "width",  &tmp_w) &&
-        gst_structure_get_int (cstr, "height", &tmp_h))
-    {
-#if 0
-      /* check if the requested fourcc format is supported */
-      GstCaps * s_caps = NULL;
-      GstCaps * r_caps = NULL;
-
-      /* get camsrc sourcepad caps, because the pad has
-       * caps-template including supported formats */
-      s_caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
-              (camerasrc)));
-      /* take an intersection between sourcepad caps and provided caps */
-      r_caps = gst_caps_intersect (op_mode_caps, s_caps);
-
-      /* if EMPTY or NULL => provided caps not supported as not set in sourcepad */
-      if (r_caps == NULL || gst_caps_is_empty (r_caps)) {
-        GST_WARNING_OBJECT (camerasrc,
-            "Unsupported fourcc format provided by caller");
-        ret = FALSE;
-      }
-      if (s_caps)
-        gst_caps_unref (s_caps);
-      if (r_caps)
-        gst_caps_unref (r_caps);
-#endif
-      ret = TRUE;
-    }
-    else {
-      GST_DEBUG_OBJECT (camerasrc, "Unable to parse given caps");
-      ret = FALSE;
-    }
-  }
-
-  /* Check that the requested resolution is not the same as what is
-   * currently configured to be in use. If so, no need to set it again.
-   */
-  if (ret && (camerasrc->preview_w != tmp_w || camerasrc->preview_h != tmp_h ||
-      camerasrc->preview_fourcc != fourcc))
-  {
-    GST_DEBUG_OBJECT (camerasrc,
-          "set preview width: %d, height: %d, format: %"
-          GST_FOURCC_FORMAT, tmp_w, tmp_h, GST_FOURCC_ARGS (fourcc));
-
-    ret = bclass->set_capture (camerasrc,
-        GST_PHOTOGRAPHY_OPERATION_MODE_PREVIEW, FALSE,
-        &fourcc, (guint *) &tmp_w, (guint *) &tmp_h, NULL, NULL);
-
-    if (fourcc == 0) {
-      /* Special case: preview image creation is canceled (NULL caps)*/
-      camerasrc->preview_resolution_set = FALSE;
-      ret = TRUE;
-    }
-    else {
-      if (ret && op_mode_caps && GST_CAPS_REFCOUNT_VALUE (op_mode_caps) == 1) {
-        /* Write the assigned values back to the caps structure */
-        gst_caps_set_simple (op_mode_caps,
-            "width", G_TYPE_INT, tmp_w,
-            "height", G_TYPE_INT, tmp_h,
-            "format", GST_TYPE_FOURCC, fourcc,
-            NULL);
-      }
-
-      GST_DEBUG_OBJECT (camerasrc,
-          "selected preview width: %d, height: %d, format: %"
-          GST_FOURCC_FORMAT, tmp_w, tmp_h, GST_FOURCC_ARGS (fourcc));
-
-      camerasrc->preview_resolution_set = ret;
-    }
-  } else {
-    GST_DEBUG_OBJECT (camerasrc, "format not set");
-    ret = FALSE;
-  }
-
-  if (ret) {
-    camerasrc->preview_w = tmp_w;
-    camerasrc->preview_h = tmp_h;
-    camerasrc->preview_fourcc = fourcc;
-  }
-
-  return ret;
-}
index f7f52e1..0cb6afc 100644 (file)
@@ -382,7 +382,22 @@ void gst_camerasrc_VOID__OBJECT_OBJECT(GClosure *closure,
                 data2);
 }
 
+int gst_camerasrc_send_af_status(GstCameraSrc *camsrc , int state)
+{
+  GstMessage *m = NULL;
+  GstStructure *s = NULL;
+
+  GST_INFO_OBJECT(camsrc, "autofocus callback: state [%d]", state);
+
+  s = gst_structure_new("camerasrc-AF",
+                      "focus-state", G_TYPE_INT, state,
+                      NULL);
 
+  m = gst_message_new_element(GST_OBJECT(camsrc), s);
+  gst_element_post_message(GST_ELEMENT(camsrc), m);
+
+  return 0;
+}
 /*
  */
 static void
index 191dde5..cb305e3 100644 (file)
@@ -87,6 +87,13 @@ G_BEGIN_DECLS
 */
 #define GST_CAMERA_SRC_CAF_STATUS "caf-update"
 
+typedef enum {
+    CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED = 2,    /**< Focused.*/
+    CAMERASRC_AUTO_FOCUS_RESULT_FAILED,         /**< AF failed.*/
+    CAMERASRC_AUTO_FOCUS_RESULT_NUM,            /**< Number of AF result*/
+}camerasrc_auto_focus_result_t;
+
+
 /**
  * GstCameraSrcCaptureMode:
  * @GST_CAMERA_SRC_CAPTURE_MODE_VIEWFINDER: Viewfinder is running.
@@ -463,6 +470,8 @@ const gchar * gst_camerasrc_metering_mode_from_exif_value (gint value);
 
 const gchar * gst_camerasrc_file_source_from_exif_value (gint value);
 
+int gst_camerasrc_send_af_status(GstCameraSrc *camsrc , int state);
+
 G_END_DECLS
 
 #endif /* __GST_CAMSRC_H__ */
index d3747db..637a1a3 100644 (file)
@@ -2197,21 +2197,21 @@ gst_v4l2camsrc_grab_frame (GstCameraSrc * camsrc, GstBuffer ** buf,
 
   if (phase == GST_CAMERA_CAPTURE) {
     gst_camerasrc_send_capture_stop_message (camsrc);
-  } else if (v4l2camsrc->debug_flags & GST_CAMERASRC_DEBUG_FLAGS_AUTO_FOCUS) {
+  } else  {
     /* Send the CAF status message */
-    //static GstCameraFocusStatus old_s;
     GstCameraFocusStatus s;
     gboolean lret;
     lret = gst_v4l2camsrc_check_focus_status(v4l2camsrc, &s, FALSE);
-
     if (lret) {
       GST_LOG_OBJECT (v4l2camsrc, "CAF status: %d", s.status);
-      /*
-      if (old_s.status != s.status) {
-       old_s.status = s.status; */
-       /* should send the message that the AF status is succses */
-       /* if (s.status == GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS) */
-         gst_camerasrc_caf_update (GST_CAMERA_SRC (v4l2camsrc), &s);
+      if (s.status == GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS )
+        gst_camerasrc_send_af_status(GST_CAMERA_SRC (v4l2camsrc) ,CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED);
+      else if (s.status == GST_PHOTOGRAPHY_FOCUS_STATUS_FAIL )
+        gst_camerasrc_send_af_status(GST_CAMERA_SRC (v4l2camsrc) ,CAMERASRC_AUTO_FOCUS_RESULT_FAILED);
+      else {
+        GST_WARNING_OBJECT (v4l2camsrc, "CAF status erronous: %d send as failed", s.status);
+        gst_camerasrc_send_af_status(GST_CAMERA_SRC (v4l2camsrc) ,CAMERASRC_AUTO_FOCUS_RESULT_FAILED);
+      }
     }
   }
 
@@ -3415,12 +3415,13 @@ gst_v4l2camsrc_check_focus_status (GstMFLDV4l2CamSrc * v4l2camsrc,
   gboolean ret = FALSE;
   cam_focus_status_t status;
   cam_err_t err;
+  gboolean update;
 
   GST_DEBUG_OBJECT (v4l2camsrc, "Retrieving focus status");
 
-  err = cam_checkfocus_status (&status);
+  update = cam_checkfocus_status (&status, (v4l2camsrc->debug_flags & GST_CAMERASRC_DEBUG_FLAGS_AUTO_FOCUS));
 
-  if (err == CAM_ERR_NONE) {
+  if (update == TRUE) {
     fs->status = cam_find_item_new (gst_v4l2camsrc_focus_status_map, status, TRUE);
     ret =  TRUE;
 
@@ -3433,9 +3434,6 @@ gst_v4l2camsrc_check_focus_status (GstMFLDV4l2CamSrc * v4l2camsrc,
       fs->focus_columns = 1;
       fs->coverage = 0;
     }
-  } else {
-    GST_WARNING_OBJECT (v4l2camsrc, "FOCUS_STATUS failed: %s",
-                       cameralib_error_map[err]);
   }
   return ret;
 }
index ee5b86b..36b945e 100644 (file)
@@ -1,3 +1,6 @@
+* Fri Nov 23 2012 Marko Ollonen <marko.ollonen@ixonos.com> submit/trunk/20121123.104013@93e507e
+- af status info passing via gst_element_post_message
+
 * Fri Nov 23 2012 Telle-Tiia Pitkänen <telle-tiia.pitkanen@ixonos.com> accepted/trunk/20121120.150732@187c1fa
 - Setting scene mode moved to correct place