maru_camera_linux : modified the worker thread and added logs
authorjinhyung.jo <jinhyung.jo@samsung.com>
Wed, 31 Oct 2012 01:56:48 +0000 (10:56 +0900)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Wed, 31 Oct 2012 01:56:48 +0000 (10:56 +0900)
The worker thread ignores errors occurring from v4l2_read like EAGAIN, EINTR and then works continuously.
Modified some logs in the worker thread and in other functions.

Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
tizen/src/hw/maru_camera_linux_pci.c

index 3fe8118..8e1db29 100644 (file)
@@ -53,6 +53,7 @@ static const char *dev_name = "/dev/video0";
 static int v4l2_fd;\r
 static int convert_trial;\r
 static int ready_count;\r
+static void *grab_buf;\r
 \r
 static struct v4l2_format dst_fmt;\r
 \r
@@ -278,19 +279,20 @@ static int __v4l2_grab(MaruCamState *state)
     FD_ZERO(&fds);\r
     FD_SET(v4l2_fd, &fds);\r
 \r
-    tv.tv_sec = 0;\r
-    tv.tv_usec = 500000;\r
+    tv.tv_sec = 1;\r
+    tv.tv_usec = 0;\r
 \r
     ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);\r
     if (ret < 0) {\r
-        if (errno == EAGAIN || errno == EINTR)\r
+        if (errno == EAGAIN || errno == EINTR) {\r
+            ERR("select again: %s\n", strerror(errno));\r
             return 0;\r
+        }\r
         ERR("failed to select : %s\n", strerror(errno));\r
         __raise_err_intr(state);\r
         return -1;\r
-    }\r
-    if (!ret) {\r
-        WARN("Timed out\n");\r
+    } else if (!ret) {\r
+        ERR("select timed out\n");\r
         return 0;\r
     }\r
 \r
@@ -300,23 +302,15 @@ static int __v4l2_grab(MaruCamState *state)
         return -1;\r
     }\r
 \r
-    if (!is_streamon(state))\r
-        return -1;\r
-\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    if (state->req_frame == 0) {\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-        return 0;\r
-    }\r
-    buf = state->vaddr + state->buf_size * (state->req_frame -1);\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-    ret = v4l2_read(v4l2_fd, buf, state->buf_size);\r
+    ret = v4l2_read(v4l2_fd, grab_buf, state->buf_size);\r
     if (ret < 0) {\r
         switch (errno) {\r
         case EAGAIN:\r
-        case EIO:\r
         case EINTR:\r
+            ERR("v4l2_read met the error: %s\n", strerror(errno));\r
+            return 0;\r
+        case EIO:\r
+            ERR("v4l2_read met the EIO.\n");\r
             if (convert_trial-- == -1) {\r
                 ERR("Try count for v4l2_read is exceeded: %s\n",\r
                     strerror(errno));\r
@@ -332,12 +326,21 @@ static int __v4l2_grab(MaruCamState *state)
     }\r
 \r
     qemu_mutex_lock(&state->thread_mutex);\r
-    if (ready_count < MARUCAM_SKIPFRAMES) {\r
-        ++ready_count; /* skip a frame cause first some frame are distorted */\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-        return 0;\r
-    }\r
     if (state->streamon == _MC_THREAD_STREAMON) {\r
+        if (ready_count < MARUCAM_SKIPFRAMES) {\r
+            /* skip a frame cause first some frame are distorted */\r
+            ++ready_count;\r
+            TRACE("skip %d frame\n", ready_count);\r
+            qemu_mutex_unlock(&state->thread_mutex);\r
+            return 0;\r
+        }\r
+        if (state->req_frame == 0) {\r
+            TRACE("there is no request\n");\r
+            qemu_mutex_unlock(&state->thread_mutex);\r
+            return 0;\r
+        }\r
+        buf = state->vaddr + state->buf_size * (state->req_frame -1);\r
+        memcpy(buf, grab_buf, state->buf_size);\r
         state->req_frame = 0; /* clear request */\r
         state->isr |= 0x01;   /* set a flag of rasing a interrupt */\r
         qemu_bh_schedule(state->tx_bh);\r
@@ -363,13 +366,11 @@ wait_worker_thread:
     convert_trial = 10;\r
     ready_count = 0;\r
     qemu_mutex_lock(&state->thread_mutex);\r
-    state->buf_size = dst_fmt.fmt.pix.sizeimage;\r
     state->streamon = _MC_THREAD_STREAMON;\r
     qemu_mutex_unlock(&state->thread_mutex);\r
     INFO("Streaming on ......\n");\r
 \r
-    while (1)\r
-    {\r
+    while (1) {\r
         if (is_streamon(state)) {\r
             if (__v4l2_grab(state) < 0) {\r
                 INFO("...... Streaming off\n");\r
@@ -498,16 +499,37 @@ void marucam_device_open(MaruCamState* state)
         param->errCode = EINVAL;\r
         return;\r
     }\r
+    INFO("Opened\n");\r
 \r
     CLEAR(dst_fmt);\r
-    INFO("Opened\n");\r
+    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+    dst_fmt.fmt.pix.width = 640;\r
+    dst_fmt.fmt.pix.height = 480;\r
+    dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;\r
+    dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;\r
+\r
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {\r
+        ERR("failed to set video format: format(0x%x), width:height(%d:%d), "\r
+          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,\r
+          dst_fmt.fmt.pix.height, strerror(errno));\r
+        param->errCode = errno;\r
+        return;\r
+    }\r
+    TRACE("set the default format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
+         "color(%d), field(%d)\n",\r
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,\r
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,\r
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);\r
 }\r
 \r
 void marucam_device_start_preview(MaruCamState* state)\r
 {\r
     struct timespec req;\r
+    MaruCamParam *param = state->param;\r
+    param->top = 0;\r
     req.tv_sec = 0;\r
     req.tv_nsec = 10000000;\r
+\r
     INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n",\r
          (char)(dst_fmt.fmt.pix.pixelformat),\r
          (char)(dst_fmt.fmt.pix.pixelformat >> 8),\r
@@ -517,6 +539,17 @@ void marucam_device_start_preview(MaruCamState* state)
          dst_fmt.fmt.pix.height,\r
          dst_fmt.fmt.pix.sizeimage);\r
     INFO("Starting preview\n");\r
+\r
+    if (grab_buf) {\r
+        g_free(grab_buf);\r
+        grab_buf = NULL;\r
+    }\r
+    grab_buf = (void *)g_malloc0(dst_fmt.fmt.pix.sizeimage);\r
+    if (grab_buf == NULL) {\r
+        param->errCode = ENOMEM;\r
+        return;\r
+    }\r
+    state->buf_size = dst_fmt.fmt.pix.sizeimage;\r
     qemu_mutex_lock(&state->thread_mutex);\r
     qemu_cond_signal(&state->thread_cond);\r
     qemu_mutex_unlock(&state->thread_mutex);\r
@@ -535,7 +568,6 @@ void marucam_device_stop_preview(MaruCamState* state)
     if (is_streamon(state)) {\r
         qemu_mutex_lock(&state->thread_mutex);\r
         state->streamon = _MC_THREAD_STREAMOFF;\r
-        state->buf_size = 0;\r
         qemu_mutex_unlock(&state->thread_mutex);\r
 \r
         /* nanosleep until thread is paused  */\r
@@ -543,6 +575,12 @@ void marucam_device_stop_preview(MaruCamState* state)
             nanosleep(&req, NULL);\r
     }\r
 \r
+    if (grab_buf) {\r
+        g_free(grab_buf);\r
+        grab_buf = NULL;\r
+    }\r
+    state->buf_size = 0;\r
+\r
     INFO("Stopping preview\n");\r
 }\r
 \r
@@ -576,24 +614,26 @@ void marucam_device_g_param(MaruCamState* state)
 \r
 void marucam_device_s_fmt(MaruCamState* state)\r
 {\r
+    struct v4l2_format format;\r
     MaruCamParam *param = state->param;\r
 \r
     param->top = 0;\r
-    CLEAR(dst_fmt);\r
-    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    dst_fmt.fmt.pix.width = param->stack[0];\r
-    dst_fmt.fmt.pix.height = param->stack[1];\r
-    dst_fmt.fmt.pix.pixelformat = param->stack[2];\r
-    dst_fmt.fmt.pix.field = param->stack[3];\r
+    CLEAR(format);\r
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+    format.fmt.pix.width = param->stack[0];\r
+    format.fmt.pix.height = param->stack[1];\r
+    format.fmt.pix.pixelformat = param->stack[2];\r
+    format.fmt.pix.field = V4L2_FIELD_ANY;\r
 \r
-    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {\r
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &format) < 0) {\r
         ERR("failed to set video format: format(0x%x), width:height(%d:%d), "\r
-          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,\r
-          dst_fmt.fmt.pix.height, strerror(errno));\r
+          "errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,\r
+          format.fmt.pix.height, strerror(errno));\r
         param->errCode = errno;\r
         return;\r
     }\r
 \r
+    memcpy(&dst_fmt, &format, sizeof(format));\r
     param->stack[0] = dst_fmt.fmt.pix.width;\r
     param->stack[1] = dst_fmt.fmt.pix.height;\r
     param->stack[2] = dst_fmt.fmt.pix.field;\r
@@ -602,6 +642,11 @@ void marucam_device_s_fmt(MaruCamState* state)
     param->stack[5] = dst_fmt.fmt.pix.sizeimage;\r
     param->stack[6] = dst_fmt.fmt.pix.colorspace;\r
     param->stack[7] = dst_fmt.fmt.pix.priv;\r
+    TRACE("set the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
+         "color(%d), field(%d)\n",\r
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,\r
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,\r
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);\r
 }\r
 \r
 void marucam_device_g_fmt(MaruCamState* state)\r
@@ -625,7 +670,11 @@ void marucam_device_g_fmt(MaruCamState* state)
         param->stack[5] = format.fmt.pix.sizeimage;\r
         param->stack[6] = format.fmt.pix.colorspace;\r
         param->stack[7] = format.fmt.pix.priv;\r
-        memcpy(&dst_fmt, &format, sizeof(format));\r
+        TRACE("get the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
+             "color(%d), field(%d)\n",\r
+             format.fmt.pix.width, format.fmt.pix.height,\r
+             format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,\r
+             format.fmt.pix.colorspace, format.fmt.pix.field);\r
     }\r
 }\r
 \r
@@ -640,7 +689,7 @@ void marucam_device_try_fmt(MaruCamState* state)
     format.fmt.pix.width = param->stack[0];\r
     format.fmt.pix.height = param->stack[1];\r
     format.fmt.pix.pixelformat = param->stack[2];\r
-    format.fmt.pix.field = param->stack[3];\r
+    format.fmt.pix.field = V4L2_FIELD_ANY;\r
 \r
     if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {\r
         ERR("failed to check video format: format(0x%x), width:height(%d:%d),"\r
@@ -657,6 +706,11 @@ void marucam_device_try_fmt(MaruCamState* state)
     param->stack[5] = format.fmt.pix.sizeimage;\r
     param->stack[6] = format.fmt.pix.colorspace;\r
     param->stack[7] = format.fmt.pix.priv;\r
+    TRACE("check the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
+         "color(%d), field(%d)\n",\r
+         format.fmt.pix.width, format.fmt.pix.height,\r
+         format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,\r
+         format.fmt.pix.colorspace, format.fmt.pix.field);\r
 }\r
 \r
 void marucam_device_enum_fmt(MaruCamState* state)\r
@@ -903,6 +957,6 @@ void marucam_device_close(MaruCamState* state)
     marucam_reset_controls();\r
 \r
     v4l2_close(v4l2_fd);\r
-    v4l2_fd = -1;\r
+    v4l2_fd = 0;\r
     INFO("Closed\n");\r
 }\r