[Title] Heuristically set the FPS for performance reasons on Windows, other minor...
authorjinhyung.jo <jinhyung.jo@samsung.com>
Thu, 30 Aug 2012 15:43:36 +0000 (00:43 +0900)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Thu, 30 Aug 2012 15:43:36 +0000 (00:43 +0900)
[Type] Bugfix & Enhancement
[Module] Emulator / Camera
[Priority] Major
[CQ#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

tizen/src/hw/maru_camera_common.h
tizen/src/hw/maru_camera_common_pci.c
tizen/src/hw/maru_camera_linux_pci.c
tizen/src/hw/maru_camera_win32_pci.c

index 59917ee526350d3198d2636177c76507117401ba..e06cea655128374cebe0263a35a88622f780e9d9 100644 (file)
@@ -33,6 +33,7 @@
 #include "qemu-thread.h"\r
 \r
 #define MARUCAM_MAX_PARAM    20\r
+#define MARUCAM_SKIPFRAMES    2\r
 \r
 /* must sync with GUEST camera_driver */\r
 #define MARUCAM_CMD_INIT           0x00\r
index e148e645f5193963047bc824457c0a89d7c7b56d..c1ff7360bed11ab34f2531d0a2d1613e1a4f5f95 100644 (file)
@@ -244,13 +244,6 @@ static int marucam_exitfn(PCIDevice *dev)
     return 0;\r
 }\r
 \r
-int maru_camera_pci_init(PCIBus *bus)\r
-{\r
-    INFO("[%s] camera device was initialized.\n", __func__);\r
-    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);\r
-    return 0;\r
-}\r
-\r
 static PCIDeviceInfo maru_camera_info = {\r
     .qdev.name    = MARU_PCI_CAMERA_DEVICE_NAME,\r
     .qdev.desc    = "MARU Virtual Camera device for Tizen emulator",\r
index 5575831957aa8525e7f258b4d591b4722fcd1de5..cf5f85708f14918775c46262715158f5179eeb88 100644 (file)
@@ -43,8 +43,6 @@
 \r
 MULTI_DEBUG_CHANNEL(tizen, camera_linux);\r
 \r
-#define MARUCAM_SKIPFRAMES    2\r
-\r
 enum {\r
     _MC_THREAD_PAUSED,\r
     _MC_THREAD_STREAMON,\r
@@ -163,7 +161,6 @@ static int is_stream_paused(MaruCamState *state)
 static int __v4l2_grab(MaruCamState *state)\r
 {\r
     fd_set fds;\r
-    static uint32_t index = 0;\r
     struct timeval tv;\r
     void *buf;\r
     int ret;\r
@@ -194,7 +191,19 @@ static int __v4l2_grab(MaruCamState *state)
     if (!is_streamon(state))\r
         return -1;\r
 \r
-    buf = state->vaddr + (state->buf_size * index);\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->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
     if ( ret < 0) {\r
         switch (errno) {\r
@@ -214,26 +223,17 @@ static int __v4l2_grab(MaruCamState *state)
         }\r
     }\r
 \r
-    index = !index;\r
-\r
     qemu_mutex_lock(&state->thread_mutex);\r
     if (state->streamon == _MC_THREAD_STREAMON) {\r
-        if (ready_count >= MARUCAM_SKIPFRAMES) {\r
-            if (state->req_frame) {\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
-            }\r
-            ret = 1;\r
-        } else {\r
-            ++ready_count; // skip a frame cause first some frame are distorted.\r
-            ret = 0;\r
-        }\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
+               ret = 1;\r
     } else {\r
         ret = -1;\r
     }\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
 \r
+    qemu_mutex_unlock(&state->thread_mutex);\r
     return ret;\r
 }\r
 \r
index f9e6cd54435c015d65dd7f82c804bea504ede8e9..98f41860f1720ab6bdd32cf963a2c009c4d6ea4b 100644 (file)
@@ -40,6 +40,8 @@
 \r
 MULTI_DEBUG_CHANNEL(tizen, camera_win32);\r
 \r
+extern int hax_enabled(void);\r
+\r
 /*\r
  * COM Interface implementations\r
  *\r
@@ -940,10 +942,6 @@ IBaseFilter *g_pSrcFilter;
 \r
 IGrabCallback *g_pCallback;\r
 \r
-DWORD g_dwFourcc;\r
-LONG g_dwWidth;\r
-LONG g_dwHeight;\r
-\r
 // V4L2 defines copy from videodev2.h\r
 #define V4L2_CTRL_FLAG_SLIDER       0x0020\r
 \r
@@ -1059,35 +1057,41 @@ static long value_convert_to_guest(long min, long max, long value)
  */\r
 static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)\r
 {\r
-    static uint32_t index = 0;\r
+    void *tmp_buf;\r
     uint32_t width, height;\r
+\r
+    qemu_mutex_lock(&g_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(&g_state->thread_mutex);\r
+        return S_OK;\r
+    }\r
+    if (g_state->req_frame == 0) {\r
+        qemu_mutex_unlock(&g_state->thread_mutex);\r
+        return S_OK;\r
+    }\r
+    tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);\r
+    qemu_mutex_unlock(&g_state->thread_mutex);\r
+\r
     width = supported_dst_frames[cur_frame_idx].width;\r
     height = supported_dst_frames[cur_frame_idx].height;\r
-    void *buf = g_state->vaddr + (g_state->buf_size * index);\r
 \r
     switch (supported_dst_pixfmts[cur_fmt_idx].fmt) {\r
     case V4L2_PIX_FMT_YUV420:\r
-        v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 0);\r
+        v4lconvert_yuyv_to_yuv420(pBuffer, tmp_buf, width, height, 0);\r
         break;\r
     case V4L2_PIX_FMT_YVU420:\r
-        v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 1);\r
+        v4lconvert_yuyv_to_yuv420(pBuffer, tmp_buf, width, height, 1);\r
         break;\r
     case V4L2_PIX_FMT_YUYV:\r
-        memcpy(buf, (void*)pBuffer, dwSize);\r
+        memcpy(tmp_buf, (void*)pBuffer, (size_t)dwSize);\r
         break;\r
     }\r
-    index = !index;\r
 \r
     qemu_mutex_lock(&g_state->thread_mutex);\r
-    if (ready_count >= 4) {\r
-        if (g_state->req_frame) {\r
-            g_state->req_frame = 0; // clear request\r
-            g_state->isr |= 0x01; // set a flag raising a interrupt.\r
-            qemu_bh_schedule(g_state->tx_bh);\r
-        }\r
-    } else {\r
-        ++ready_count; // skip a frame cause first some frame are distorted.\r
-    }\r
+    g_state->req_frame = 0; /* clear request */\r
+    g_state->isr |= 0x01; /* set a flag raising a interrupt. */\r
+    qemu_bh_schedule(g_state->tx_bh);\r
     qemu_mutex_unlock(&g_state->thread_mutex);\r
     return S_OK;\r
 }\r
@@ -1301,13 +1305,23 @@ static STDMETHODIMP ConnectFilters(void)
     return hr;\r
 }\r
 \r
-static STDMETHODIMP SetDefaultValues(void)\r
+/* default fps is 15 */\r
+#define MARUCAM_DEFAULT_FRAMEINTERVAL    666666\r
+\r
+static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,\r
+                              uint32_t dwFourcc)\r
 {\r
     HRESULT hr;\r
     IAMStreamConfig *pSConfig;\r
     int iCount = 0, iSize = 0;\r
 \r
-    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0, g_pSrcFilter, &IID_IAMStreamConfig, (void**)&pSConfig);\r
+    if (dwFourcc == 0) {\r
+        dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
+    }\r
+\r
+    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,\r
+                                       g_pSrcFilter, &IID_IAMStreamConfig,\r
+                                       (void**)&pSConfig);\r
     if (FAILED(hr)) {\r
         ERR("failed to FindInterface method\n");\r
         return hr;\r
@@ -1329,19 +1343,29 @@ static STDMETHODIMP SetDefaultValues(void)
             VIDEO_STREAM_CONFIG_CAPS scc;\r
             AM_MEDIA_TYPE *pmtConfig;\r
 \r
-            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig, (BYTE*)&scc);\r
+            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,\r
+                                                 (BYTE*)&scc);\r
             if (hr == S_OK)\r
             {\r
                 if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo))\r
                 {\r
-                    VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
-                    if ((pvi->bmiHeader.biWidth == g_dwWidth) &&\r
-                        (pvi->bmiHeader.biHeight == g_dwHeight) &&\r
-                        (pvi->bmiHeader.biCompression == g_dwFourcc))\r
+                    VIDEOINFOHEADER *pvi =\r
+                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;\r
+                    if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&\r
+                        (pvi->bmiHeader.biHeight == (LONG)dwHeight) &&\r
+                        (pvi->bmiHeader.biCompression == (DWORD)dwFourcc))\r
                     {\r
+                        /* use minimum FPS(maximum frameinterval)\r
+                           with non-VT system  */\r
+                       if (!hax_enabled()) {\r
+                            pvi->AvgTimePerFrame =\r
+                                    (REFERENCE_TIME)scc.MaxFrameInterval;\r
+                        } else {\r
+                            pvi->AvgTimePerFrame =\r
+                                (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;\r
+                        }\r
                         hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);\r
                         DeleteMediaType(pmtConfig);\r
-                        INFO("Setting default values.\n");\r
                         break;\r
                     }\r
                 }\r
@@ -1349,7 +1373,10 @@ static STDMETHODIMP SetDefaultValues(void)
             }\r
         }\r
         if (iFormat >= iCount) {\r
-            ERR("Maybe connected webcam does not support %ld x %ld resolution.\n", g_dwWidth, g_dwHeight);\r
+            ERR("Failed to Set format. "\r
+                "Maybe connected webcam does not support "\r
+                "(%ldx%ld) resolution or YUY2 image format.\n",\r
+                dwWidth, dwHeight);\r
             hr = E_FAIL;\r
         }\r
     }\r
@@ -1357,42 +1384,6 @@ static STDMETHODIMP SetDefaultValues(void)
     return hr;\r
 }\r
 \r
-static STDMETHODIMP SetResolution(LONG width, LONG height)\r
-{\r
-    HRESULT hr;\r
-    IAMStreamConfig* vsc = NULL;\r
-    AM_MEDIA_TYPE* pmt = NULL;\r
-\r
-    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pSrcFilter, &IID_IAMStreamConfig, (void**)&vsc);\r
-    if (FAILED(hr))\r
-        return hr;\r
-\r
-    hr = vsc->lpVtbl->GetFormat(vsc, &pmt);\r
-    if (FAILED(hr))\r
-    {\r
-        vsc->lpVtbl->Release(vsc);\r
-        return hr;\r
-    }\r
-\r
-    if (pmt != NULL)\r
-    {\r
-        if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))\r
-        {\r
-            VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
-            pvi->bmiHeader.biWidth = width;\r
-            pvi->bmiHeader.biHeight = height;\r
-            pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;\r
-            hr = vsc->lpVtbl->SetFormat(vsc, pmt);\r
-            if (hr != S_OK) {\r
-                ERR("failed to set the resolution.(w:%ld, h:%ld), Maybe connected webcam does not support the resolution.\n", width, height);\r
-            }\r
-        }\r
-        DeleteMediaType(pmt);\r
-    }\r
-    vsc->lpVtbl->Release(vsc);\r
-    return hr;\r
-}\r
-\r
 static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
 {\r
     HRESULT hr;\r
@@ -1522,6 +1513,7 @@ void marucam_device_init(MaruCamState* state)
 void marucam_device_open(MaruCamState* state)\r
 {\r
     HRESULT hr;\r
+    uint32_t dwHeight, dwWidth;\r
     MaruCamParam *param = state->param;\r
     param->top = 0;\r
 \r
@@ -1557,16 +1549,16 @@ void marucam_device_open(MaruCamState* state)
         goto error_failed;\r
     }\r
 \r
-    g_dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
-    g_dwHeight = 480;\r
-    g_dwWidth = 640;\r
-    hr = SetDefaultValues();\r
+    cur_frame_idx = 0;\r
+    cur_fmt_idx = 0;\r
+\r
+    dwHeight = supported_dst_frames[cur_frame_idx].height;\r
+    dwWidth = supported_dst_frames[cur_frame_idx].width;\r
+    hr = SetFormat(dwWidth, dwHeight, 0);\r
     if (hr != S_OK) {\r
-        ERR("SetDefaultValues\n");\r
+        ERR("failed to Set default values\n");\r
         goto error_failed;\r
     }\r
-    cur_frame_idx = 0;\r
-    cur_fmt_idx = 0;\r
 \r
     INFO("Open successfully!!!\n");\r
     return;\r
@@ -1709,13 +1701,11 @@ void marucam_device_s_fmt(MaruCamState* state)
 \r
     if ((supported_dst_frames[cur_frame_idx].width != width) &&\r
             (supported_dst_frames[cur_frame_idx].height != height)) {\r
-        HRESULT hr = SetResolution((LONG)width, (LONG)height);\r
+        HRESULT hr = SetFormat(width, height, 0);\r
         if (FAILED(hr)) {\r
             param->errCode = EINVAL;\r
             return;\r
         }\r
-        g_dwWidth = (LONG)width;\r
-        g_dwHeight = (LONG)height;\r
     }\r
 \r
     param->stack[0] = width;\r