maru_camera : Fixed some problems 89/17589/3
authorjinhyung.jo <jinhyung.jo@samsung.com>
Thu, 6 Mar 2014 06:05:39 +0000 (15:05 +0900)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Mon, 10 Mar 2014 08:15:41 +0000 (17:15 +0900)
Change the logging function to suit the log format.
Reset the camera state when the emualtor is resetting.
Modified functions from memcpy to strcpy, because of out-of-bounds access.

Change-Id: I213542ce5a02b81ce9adb625f486d75e830aef17
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
tizen/src/hw/maru_camera_common_pci.c
tizen/src/hw/maru_camera_darwin_pci.m
tizen/src/hw/maru_camera_linux_pci.c
tizen/src/hw/maru_camera_win32_pci.c

index 7e32e83..0c40ffe 100644 (file)
@@ -253,6 +253,19 @@ static void marucam_exitfn(PCIDevice *pci_dev)
     INFO("[%s] camera device was released.\n", __func__);
 }
 
+static void marucam_resetfn(DeviceState *d)
+{
+    MaruCamState *s = (MaruCamState *)d;
+
+    marucam_device_close(s);
+    qemu_mutex_lock(&s->thread_mutex);
+    s->isr = s->streamon = s->req_frame = s->buf_size = 0;
+    qemu_mutex_unlock(&s->thread_mutex);
+    memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
+    memset(s->param, 0x00, sizeof(MaruCamParam));
+    INFO("[%s]\n", __func__);
+}
+
 int maru_camera_pci_init(PCIBus *bus)
 {
     INFO("[%s] camera device was initialized.\n", __func__);
@@ -271,6 +284,7 @@ static void maru_camera_pci_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_TIZEN;
     k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;
     k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = marucam_resetfn;
     dc->desc = "MARU Virtual Camera device for Tizen emulator";
 }
 
index b9c2530..7de11b1 100644 (file)
@@ -575,8 +575,12 @@ void marucam_device_close(MaruCamState *state)
     param->top = 0;
 
     if (mcd != NULL) {
+        if (is_streamon()) {
+            marucam_device_stop_preview(state);
+        }
         [mcd->driver dealloc];
         free(mcd);
+        mcd = NULL;
     }
 
     /* marucam_reset_controls(); */
index a990abe..9629212 100644 (file)
@@ -707,46 +707,46 @@ int marucam_device_check(int log_flag)
 
     gettimeofday(&t1, NULL);
     if (stat(dev_name, &st) < 0) {
-        fprintf(stdout, "[Webcam] <WARNING> Cannot identify '%s': %s\n",
+        INFO("<WARNING> Cannot identify '%s': %s\n",
                 dev_name, strerror(errno));
     } else {
         if (!S_ISCHR(st.st_mode)) {
-            fprintf(stdout, "[Webcam] <WARNING>%s is no character device\n",
+            INFO("<WARNING>%s is no character device\n",
                     dev_name);
         }
     }
 
     tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
     if (tmp_fd < 0) {
-        fprintf(stdout, "[Webcam] Camera device open failed: %s\n", dev_name);
+        ERR("Camera device open failed: %s\n", dev_name);
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+        ERR("Elapsed time: %lu:%06lu\n",
                 t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
     if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) {
-        fprintf(stdout, "[Webcam] Could not qeury video capabilities\n");
+        ERR("Could not qeury video capabilities\n");
         close(tmp_fd);
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+        ERR("Elapsed time: %lu:%06lu\n",
                 t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
             !(cap.capabilities & V4L2_CAP_STREAMING)) {
-        fprintf(stdout, "[Webcam] Not supported video driver\n");
+        ERR("Not supported video driver\n");
         close(tmp_fd);
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+        ERR("Elapsed time: %lu:%06lu\n",
                 t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
     ret = 1;
 
     if (log_flag) {
-        fprintf(stdout, "[Webcam] Driver: %s\n", cap.driver);
-        fprintf(stdout, "[Webcam] Card:  %s\n", cap.card);
-        fprintf(stdout, "[Webcam] Bus info: %s\n", cap.bus_info);
+        INFO("Driver: %s\n", cap.driver);
+        INFO("Card:  %s\n", cap.card);
+        INFO("Bus info: %s\n", cap.bus_info);
 
         CLEAR(format);
         format.index = 0;
@@ -755,7 +755,7 @@ int marucam_device_check(int log_flag)
         if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) {
             close(tmp_fd);
             gettimeofday(&t2, NULL);
-            fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+            ERR("Elapsed time: %lu:%06lu\n",
                     t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
             return ret;
         }
@@ -765,7 +765,7 @@ int marucam_device_check(int log_flag)
             size.index = 0;
             size.pixel_format = format.pixelformat;
 
-            fprintf(stdout, "[Webcam] PixelFormat: %c%c%c%c\n",
+            INFO("PixelFormat: %c%c%c%c\n",
                              (char)(format.pixelformat),
                              (char)(format.pixelformat >> 8),
                              (char)(format.pixelformat >> 16),
@@ -774,30 +774,30 @@ int marucam_device_check(int log_flag)
             if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) {
                 close(tmp_fd);
                 gettimeofday(&t2, NULL);
-                fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                ERR("Elapsed time: %lu:%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
                 return ret;
             }
 
             if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
                 do {
-                    fprintf(stdout, "[Webcam] got discrete frame size %dx%d\n",
+                    INFO("\tGot a discrete frame size %dx%d\n",
                                     size.discrete.width, size.discrete.height);
                     size.index++;
                 } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
             } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
-                fprintf(stdout, "[Webcam] we have stepwise frame sizes:\n");
-                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",
+                INFO("We have stepwise frame sizes:\n");
+                INFO("\tmin width: %d, min height: %d\n",
                         size.stepwise.min_width, size.stepwise.min_height);
-                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",
+                INFO("\tmax width: %d, max height: %d\n",
                         size.stepwise.max_width, size.stepwise.max_height);
-                fprintf(stdout, "[Webcam] step width: %d, step height: %d\n",
+                INFO("\tstep width: %d, step height: %d\n",
                         size.stepwise.step_width, size.stepwise.step_height);
             } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
-                fprintf(stdout, "[Webcam] we have continuous frame sizes:\n");
-                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",
+                INFO("We have continuous frame sizes:\n");
+                INFO("\tmin width: %d, min height: %d\n",
                         size.stepwise.min_width, size.stepwise.min_height);
-                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",
+                INFO("\tmax width: %d, max height: %d\n",
                         size.stepwise.max_width, size.stepwise.max_height);
 
             }
@@ -807,7 +807,7 @@ int marucam_device_check(int log_flag)
 
     close(tmp_fd);
     gettimeofday(&t2, NULL);
-    fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+    INFO("Elapsed time: %lu:%06lu\n",
                     t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
     return ret;
 }
@@ -1115,13 +1115,13 @@ void marucam_device_enum_fmt(MaruCamState *state)
     /* set description */
     switch (supported_dst_pixfmts[index].fmt) {
     case V4L2_PIX_FMT_YUYV:
-        memcpy(&param->stack[3], "YUYV", 32);
+        strcpy((char *)&param->stack[3], "YUYV");
         break;
     case V4L2_PIX_FMT_YUV420:
-        memcpy(&param->stack[3], "YU12", 32);
+        strcpy((char *)&param->stack[3], "YU12");
         break;
     case V4L2_PIX_FMT_YVU420:
-        memcpy(&param->stack[3], "YV12", 32);
+        strcpy((char *)&param->stack[3], "YV12");
         break;
     default:
         ERR("Invalid fixel format\n");
@@ -1144,22 +1144,22 @@ void marucam_device_qctrl(MaruCamState *state)
     switch (ctrl.id) {
     case V4L2_CID_BRIGHTNESS:
         TRACE("Query : BRIGHTNESS\n");
-        memcpy((void *)name, (void *)"brightness", 32);
+        strcpy(name, "brightness");
         i = 0;
         break;
     case V4L2_CID_CONTRAST:
         TRACE("Query : CONTRAST\n");
-        memcpy((void *)name, (void *)"contrast", 32);
+        strcpy(name, "contrast");
         i = 1;
         break;
     case V4L2_CID_SATURATION:
         TRACE("Query : SATURATION\n");
-        memcpy((void *)name, (void *)"saturation", 32);
+        strcpy(name, "saturation");
         i = 2;
         break;
     case V4L2_CID_SHARPNESS:
         TRACE("Query : SHARPNESS\n");
-        memcpy((void *)name, (void *)"sharpness", 32);
+        strcpy(name, "sharpness");
         i = 3;
         break;
     default:
index 8b78926..63b5a06 100644 (file)
@@ -1744,9 +1744,9 @@ int marucam_device_check(int log_flag)
     gettimeofday(&t1, NULL);
     hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] failed to CoInitailizeEx\n");
+        ERR("Failed to CoInitailizeEx\n");
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1756,10 +1756,10 @@ int marucam_device_check(int log_flag)
                           &IID_IGraphBuilder,
                           (void **)&pGB);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] Failed to create GraphBuilder, 0x%x\n", hr);
+        ERR("Failed to create GraphBuilder, 0x%x\n", hr);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1769,24 +1769,23 @@ int marucam_device_check(int log_flag)
                           &IID_ICaptureGraphBuilder2,
                           (void **)&pCGB);
     if (FAILED(hr)) {
-        fprintf(stdout,
-        "[Webcam] Failed to create CaptureGraphBuilder2, 0x%x\n", hr);
+        ERR("Failed to create CaptureGraphBuilder2, 0x%x\n", hr);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
 
     hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] Failed to SetFiltergraph, 0x%x\n", hr);
+        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1796,13 +1795,12 @@ int marucam_device_check(int log_flag)
                           &IID_ICreateDevEnum,
                           (void **)&pCreateDevEnum);
     if (FAILED(hr)) {
-        fprintf(stdout,
-            "[Webcam] failed to create instance of CLSID_SystemDeviceEnum\n");
+        ERR("Failed to create instance of CLSID_SystemDeviceEnum\n");
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1810,25 +1808,25 @@ int marucam_device_check(int log_flag)
     hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
                                   &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] failed to create class enumerator\n");
+        ERR("Failed to create class enumerator\n");
         SAFE_RELEASE(pCreateDevEnum);
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
 
     if (!pEnumMK) {
-        fprintf(stdout, "[Webcam] class enumerator is NULL!!\n");
+        ERR("Class enumerator is NULL!!\n");
         SAFE_RELEASE(pCreateDevEnum);
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1836,14 +1834,14 @@ int marucam_device_check(int log_flag)
 
     hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
     if (FAILED(hr) || (hr == S_FALSE)) {
-        fprintf(stdout, "[Webcam] enum moniker returns a invalid value.\n");
+        ERR("Enum moniker returns a invalid value.\n");
         SAFE_RELEASE(pEnumMK);
         SAFE_RELEASE(pCreateDevEnum);
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1853,14 +1851,14 @@ int marucam_device_check(int log_flag)
                                          &IID_IPropertyBag,
                                          (void **)&pBag);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] failed to bind to storage.\n");
+        ERR("Failed to bind to storage.\n");
         SAFE_RELEASE(pEnumMK);
         SAFE_RELEASE(pCreateDevEnum);
         SAFE_RELEASE(pCGB);
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     } else {
@@ -1879,19 +1877,18 @@ int marucam_device_check(int log_flag)
                 SAFE_RELEASE(pGB);
                 CoUninitialize();
                 gettimeofday(&t2, NULL);
-                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                ERR("Elapsed time : %lu.%06lu\n",
                                 t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
                 return ret;
             }
             device_name = __wchar_to_char(var.bstrVal);
-            fprintf(stdout, "[Webcam] Device name : %s\n", device_name);
+            INFO("Device name : %s\n", device_name);
             g_free(device_name);
             hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
                                                 &IID_IBaseFilter,
                                                 (void **)&pSrcFilter);
             if (FAILED(hr)) {
-                fprintf(stdout,
-                   "[Webcam] Counldn't bind moniker to filter object!!\n");
+                ERR("Counldn't bind moniker to filter object!!\n");
                 SysFreeString(var.bstrVal);
                 SAFE_RELEASE(pBag);
                 SAFE_RELEASE(pMoniKer);
@@ -1901,7 +1898,7 @@ int marucam_device_check(int log_flag)
                 SAFE_RELEASE(pGB);
                 CoUninitialize();
                 gettimeofday(&t2, NULL);
-                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                ERR("Elapsed time : %lu.%06lu\n",
                                 t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
                 return ret;
             } else {
@@ -1915,8 +1912,7 @@ int marucam_device_check(int log_flag)
 
     hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture");
     if (hr != S_OK && hr != S_FALSE) {
-        fprintf(stdout,
-                "[Webcam] Counldn't add Video Capture filter to our graph!\n");
+        ERR("Counldn't add Video Capture filter to our graph!\n");
         SAFE_RELEASE(pSrcFilter);
         SAFE_RELEASE(pEnumMK);
         SAFE_RELEASE(pCreateDevEnum);
@@ -1924,7 +1920,7 @@ int marucam_device_check(int log_flag)
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1933,7 +1929,7 @@ int marucam_device_check(int log_flag)
                                        pSrcFilter, &IID_IAMStreamConfig,
                                        (void **)&pSConfig);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] failed to FindInterface method\n");
+        ERR("Failed to FindInterface method\n");
         SAFE_RELEASE(pSrcFilter);
         SAFE_RELEASE(pEnumMK);
         SAFE_RELEASE(pCreateDevEnum);
@@ -1941,14 +1937,14 @@ int marucam_device_check(int log_flag)
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
 
     hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] failed to GetNumberOfCapabilities method\n");
+        ERR("Failed to GetNumberOfCapabilities method\n");
         SAFE_RELEASE(pSConfig);
         SAFE_RELEASE(pSrcFilter);
         SAFE_RELEASE(pEnumMK);
@@ -1957,7 +1953,7 @@ int marucam_device_check(int log_flag)
         SAFE_RELEASE(pGB);
         CoUninitialize();
         gettimeofday(&t2, NULL);
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+        ERR("Elapsed time : %lu.%06lu\n",
                         t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
         return ret;
     }
@@ -1975,19 +1971,18 @@ int marucam_device_check(int log_flag)
                     VIDEOINFOHEADER *pvi =
                                          (VIDEOINFOHEADER *)pmtConfig->pbFormat;
                     if (pvi->bmiHeader.biCompression == BI_RGB) {
-                        fprintf(stdout, "[Webcam] RGB BitCount: %d, %ux%u\n",
+                        INFO("RGB BitCount: %d, Frame size: %ux%u\n",
                                 pvi->bmiHeader.biBitCount,
                                 pvi->bmiHeader.biWidth,
                                 pvi->bmiHeader.biHeight);
                     } else {
-                        fprintf(stdout,
-                                "[Webcam] PixelFormat: %c%c%c%c, %ux%u\n",
-                                (char)(pvi->bmiHeader.biCompression),
-                                (char)(pvi->bmiHeader.biCompression >> 8),
-                                (char)(pvi->bmiHeader.biCompression >> 16),
-                                (char)(pvi->bmiHeader.biCompression >> 24),
-                                pvi->bmiHeader.biWidth,
-                                pvi->bmiHeader.biHeight);
+                        INFO("PixelFormat: %c%c%c%c, Frame size: %ux%u\n",
+                            (char)(pvi->bmiHeader.biCompression),
+                            (char)(pvi->bmiHeader.biCompression >> 8),
+                            (char)(pvi->bmiHeader.biCompression >> 16),
+                            (char)(pvi->bmiHeader.biCompression >> 24),
+                            pvi->bmiHeader.biWidth,
+                            pvi->bmiHeader.biHeight);
                     }
                 }
                 DeleteMediaType(pmtConfig);
@@ -1997,7 +1992,7 @@ int marucam_device_check(int log_flag)
 
     hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter);
     if (FAILED(hr)) {
-        fprintf(stdout, "[Webcam] Failed to remove source filer. 0x%x\n", hr);
+        ERR("Failed to remove source filer. 0x%x\n", hr);
     }
 
     SAFE_RELEASE(pSConfig);
@@ -2008,7 +2003,7 @@ int marucam_device_check(int log_flag)
     SAFE_RELEASE(pCreateDevEnum);
     CoUninitialize();
     gettimeofday(&t2, NULL);
-    fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+    ERR("Elapsed time : %lu.%06lu\n",
                     t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
 
     return ret;
@@ -2114,10 +2109,20 @@ void marucam_device_open(MaruCamState *state)
 void marucam_device_close(MaruCamState *state)
 {
     MaruCamParam *param = state->param;
+    int ret = 0;
     param->top = 0;
 
-    DisconnectPins();
-    RemoveFilters();
+    qemu_mutex_lock(&state->thread_mutex);
+    ret = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    if (ret) {
+        marucam_device_stop_preview(state);
+    }
+
+    if (g_pGB) {
+        DisconnectPins();
+        RemoveFilters();
+    }
     CloseInterfaces();
     CoUninitialize();
     INFO("Closed\n");