[Title] changed thread API to use(pthread -> qemu-thread) & removed VS2010 dependency.
authorJinhyung Jo <jinhyung.jo@samsung.com>
Wed, 28 Mar 2012 09:35:50 +0000 (18:35 +0900)
committerJinhyung Jo <jinhyung.jo@samsung.com>
Wed, 28 Mar 2012 09:35:50 +0000 (18:35 +0900)
[Type] Enhancement
[Module] Emulator/Camera
[Priority] Minor
[CQ#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

tizen/src/Makefile.tizen
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_interface.h [new file with mode: 0644]
tizen/src/hw/maru_camera_win32_pci.c

index b6775b8..56c32ec 100755 (executable)
@@ -79,10 +79,12 @@ obj-i386-y += maru_touchscreen.o
 obj-i386-$(CONFIG_PCI) += maru_camera_common_pci.o
 obj-i386-$(CONFIG_LINUX) += maru_camera_linux_pci.o
 obj-i386-$(CONFIG_WIN32) += maru_camera_win32_pci.o
-# libs for maru camera on linux host
-ifdef CONFIG_LINUX
+ifdef CONFIG_LINUX # libs for maru camera on linux host
 LIBS += -lv4l2 -lv4lconvert
 endif
+ifdef CONFIG_WIN32 # libs for maru camera on windows host
+LIBS += -lole32 -loleaut32 -luuid -lstrmiids
+endif
 
 
 # maru skin
index 853b8a6..5d5cf7a 100644 (file)
-/*
- * Common header of MARU Virtual Camera device.
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#ifndef _MARU_CAMERA_COMMON_H_
-#define _MARU_CAMERA_COMMON_H_
-
-#include "pci.h"
-#include <pthread.h>
-
-#define MARUCAM_MAX_PARAM       20
-
-/* must sync with GUEST camera_driver */
-#define MARUCAM_CMD_INIT           0x00
-#define MARUCAM_CMD_OPEN           0x04
-#define MARUCAM_CMD_CLOSE          0x08
-#define MARUCAM_CMD_ISSTREAM       0x0C
-#define MARUCAM_CMD_START_PREVIEW  0x10
-#define MARUCAM_CMD_STOP_PREVIEW   0x14
-#define MARUCAM_CMD_S_PARAM        0x18
-#define MARUCAM_CMD_G_PARAM        0x1C
-#define MARUCAM_CMD_ENUM_FMT       0x20
-#define MARUCAM_CMD_TRY_FMT        0x24
-#define MARUCAM_CMD_S_FMT          0x28
-#define MARUCAM_CMD_G_FMT          0x2C
-#define MARUCAM_CMD_QCTRL          0x30
-#define MARUCAM_CMD_S_CTRL         0x34
-#define MARUCAM_CMD_G_CTRL         0x38
-#define MARUCAM_CMD_ENUM_FSIZES    0x3C
-#define MARUCAM_CMD_ENUM_FINTV     0x40
-#define MARUCAM_CMD_S_DATA         0x44
-#define MARUCAM_CMD_G_DATA         0x48
-#define MARUCAM_CMD_CLRIRQ         0x4C
-#define MARUCAM_CMD_DATACLR        0x50
-#define MARUCAM_CMD_REQFRAME       0x54
-
-typedef struct MaruCamState MaruCamState;
-typedef struct MaruCamThreadInfo MaruCamThreadInfo;
-typedef struct MaruCamParam MaruCamParam;
-
-struct MaruCamParam {
-       uint32_t        top;
-       uint32_t        retVal;
-       uint32_t        errCode;
-       uint32_t        stack[MARUCAM_MAX_PARAM];
-};
-
-struct MaruCamThreadInfo {
-       MaruCamState*    state;
-       MaruCamParam*    param;
-
-       pthread_t        thread_id;
-       pthread_cond_t   thread_cond;
-       pthread_mutex_t  mutex_lock;
-};
-
-struct MaruCamState {
-       PCIDevice           dev;
-
-       void                *vaddr;             /* vram ptr */
-       uint32_t            streamon;
-       uint32_t            buf_size;
-       uint32_t            req_frame;
-
-    MemoryRegion        vram;
-    MemoryRegion        mmio;
-
-       MaruCamThreadInfo       *thread;
-};
-
-/* ----------------------------------------------------------------------------- */
-/* Fucntion prototype                                                                               */
-/* ----------------------------------------------------------------------------- */
-void marucam_device_init(MaruCamState *state);
-void marucam_device_open(MaruCamState *state);
-void marucam_device_close(MaruCamState *state);
-void marucam_device_start_preview(MaruCamState *state);
-void marucam_device_stop_preview(MaruCamState *state);
-void marucam_device_s_param(MaruCamState *state);
-void marucam_device_g_param(MaruCamState *state);
-void marucam_device_s_fmt(MaruCamState *state);
-void marucam_device_g_fmt(MaruCamState *state);
-void marucam_device_try_fmt(MaruCamState *state);
-void marucam_device_enum_fmt(MaruCamState *state);
-void marucam_device_qctrl(MaruCamState *state);
-void marucam_device_s_ctrl(MaruCamState *state);
-void marucam_device_g_ctrl(MaruCamState *state);
-void marucam_device_enum_fsizes(MaruCamState *state);
-void marucam_device_enum_fintv(MaruCamState *state);
-
-
-#endif /* _MARU_CAMERA_COMMON_H_ */
+/*\r
+ * Common header of MARU Virtual Camera device.\r
+ *\r
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ * JinHyung Jo <jinhyung.jo@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#ifndef _MARU_CAMERA_COMMON_H_\r
+#define _MARU_CAMERA_COMMON_H_\r
+\r
+#include "pci.h"\r
+#include "qemu-thread.h"\r
+\r
+#define MARUCAM_MAX_PARAM       20\r
+\r
+/* must sync with GUEST camera_driver */\r
+#define MARUCAM_CMD_INIT           0x00\r
+#define MARUCAM_CMD_OPEN           0x04\r
+#define MARUCAM_CMD_CLOSE          0x08\r
+#define MARUCAM_CMD_ISSTREAM       0x0C\r
+#define MARUCAM_CMD_START_PREVIEW  0x10\r
+#define MARUCAM_CMD_STOP_PREVIEW   0x14\r
+#define MARUCAM_CMD_S_PARAM        0x18\r
+#define MARUCAM_CMD_G_PARAM        0x1C\r
+#define MARUCAM_CMD_ENUM_FMT       0x20\r
+#define MARUCAM_CMD_TRY_FMT        0x24\r
+#define MARUCAM_CMD_S_FMT          0x28\r
+#define MARUCAM_CMD_G_FMT          0x2C\r
+#define MARUCAM_CMD_QCTRL          0x30\r
+#define MARUCAM_CMD_S_CTRL         0x34\r
+#define MARUCAM_CMD_G_CTRL         0x38\r
+#define MARUCAM_CMD_ENUM_FSIZES    0x3C\r
+#define MARUCAM_CMD_ENUM_FINTV     0x40\r
+#define MARUCAM_CMD_S_DATA         0x44\r
+#define MARUCAM_CMD_G_DATA         0x48\r
+#define MARUCAM_CMD_CLRIRQ         0x4C\r
+#define MARUCAM_CMD_DATACLR        0x50\r
+#define MARUCAM_CMD_REQFRAME       0x54\r
+\r
+typedef struct MaruCamState MaruCamState;\r
+typedef struct MaruCamParam MaruCamParam;\r
+\r
+struct MaruCamParam {\r
+       uint32_t        top;\r
+       uint32_t        retVal;\r
+       uint32_t        errCode;\r
+       uint32_t        stack[MARUCAM_MAX_PARAM];\r
+};\r
+\r
+struct MaruCamState {\r
+       PCIDevice           dev;\r
+       MaruCamParam        *param;\r
+       QemuThread          thread_id;\r
+       QemuMutex           thread_mutex;;\r
+       QemuCond            thread_cond;\r
+\r
+       void                *vaddr;             /* vram ptr */\r
+       uint32_t            streamon;\r
+       uint32_t            buf_size;\r
+       uint32_t            req_frame;\r
+\r
+    MemoryRegion        vram;\r
+    MemoryRegion        mmio;\r
+};\r
+\r
+/* ----------------------------------------------------------------------------- */\r
+/* Fucntion prototype                                                                               */\r
+/* ----------------------------------------------------------------------------- */\r
+void marucam_device_init(MaruCamState *state);\r
+void marucam_device_open(MaruCamState *state);\r
+void marucam_device_close(MaruCamState *state);\r
+void marucam_device_start_preview(MaruCamState *state);\r
+void marucam_device_stop_preview(MaruCamState *state);\r
+void marucam_device_s_param(MaruCamState *state);\r
+void marucam_device_g_param(MaruCamState *state);\r
+void marucam_device_s_fmt(MaruCamState *state);\r
+void marucam_device_g_fmt(MaruCamState *state);\r
+void marucam_device_try_fmt(MaruCamState *state);\r
+void marucam_device_enum_fmt(MaruCamState *state);\r
+void marucam_device_qctrl(MaruCamState *state);\r
+void marucam_device_s_ctrl(MaruCamState *state);\r
+void marucam_device_g_ctrl(MaruCamState *state);\r
+void marucam_device_enum_fsizes(MaruCamState *state);\r
+void marucam_device_enum_fintv(MaruCamState *state);\r
+\r
+\r
+#endif /* _MARU_CAMERA_COMMON_H_ */\r
index f6eccd0..5ee1df7 100644 (file)
-/*
- * Common implementation of MARU Virtual Camera device by PCI bus.
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-
-#include "qemu-common.h"
-#include "cpu-common.h"
-
-#include "pci.h"
-#include "pci_ids.h"
-#include "maru_pci_ids.h"
-
-#include "maru_camera_common.h"
-#include "tizen/src/debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(tizen, camera_pci);
-
-#define MARU_PCI_CAMERA_DEVICE_NAME            "maru_camera_pci"
-
-#define MARUCAM_MEM_SIZE               (4 * 1024 * 1024)       // 4MB
-#define MARUCAM_REG_SIZE               (256)                           // 64 * 4
-
-/*
- *  I/O functions
- */
-static inline uint32_t marucam_mmio_read(void *opaque, target_phys_addr_t offset)
-{
-       uint32_t ret = 0;
-       MaruCamState *state = (MaruCamState*)opaque;
-
-       switch (offset & 0xFF) {
-       case MARUCAM_CMD_ISSTREAM:
-               pthread_mutex_lock(&state->thread->mutex_lock);
-               ret = state->streamon;
-               pthread_mutex_unlock(&state->thread->mutex_lock);
-               break;
-       case MARUCAM_CMD_G_DATA:
-               ret = state->thread->param->stack[state->thread->param->top++];
-               break;
-       case MARUCAM_CMD_OPEN:
-       case MARUCAM_CMD_CLOSE:
-       case MARUCAM_CMD_START_PREVIEW:
-       case MARUCAM_CMD_STOP_PREVIEW:
-       case MARUCAM_CMD_S_PARAM:
-       case MARUCAM_CMD_G_PARAM:
-       case MARUCAM_CMD_ENUM_FMT:
-       case MARUCAM_CMD_TRY_FMT:
-       case MARUCAM_CMD_S_FMT:
-       case MARUCAM_CMD_G_FMT:
-       case MARUCAM_CMD_QCTRL:
-       case MARUCAM_CMD_S_CTRL:
-       case MARUCAM_CMD_G_CTRL:
-       case MARUCAM_CMD_ENUM_FSIZES:
-       case MARUCAM_CMD_ENUM_FINTV:
-               ret = state->thread->param->errCode;
-               state->thread->param->errCode = 0;
-               break;
-       default:
-               WARN("Not supported command!!\n");
-               break;
-       }
-       return ret;
-}
-
-static inline void marucam_mmio_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
-       MaruCamState *state = (MaruCamState*)opaque;
-       
-       switch(offset & 0xFF) {
-       case MARUCAM_CMD_OPEN:
-               marucam_device_open(state);
-               break;
-       case MARUCAM_CMD_CLOSE:
-               marucam_device_close(state);
-               break;
-       case MARUCAM_CMD_START_PREVIEW:
-               marucam_device_start_preview(state);
-               break;
-       case MARUCAM_CMD_STOP_PREVIEW:
-               marucam_device_stop_preview(state);
-               break;
-       case MARUCAM_CMD_S_PARAM:
-               marucam_device_s_param(state);
-               break;
-       case MARUCAM_CMD_G_PARAM:
-               marucam_device_g_param(state);
-               break;
-       case MARUCAM_CMD_ENUM_FMT:
-               marucam_device_enum_fmt(state);
-               break;
-       case MARUCAM_CMD_TRY_FMT:
-               marucam_device_try_fmt(state);
-               break;
-       case MARUCAM_CMD_S_FMT:
-               marucam_device_s_fmt(state);
-               break;
-       case MARUCAM_CMD_G_FMT:
-               marucam_device_g_fmt(state);
-               break;
-       case MARUCAM_CMD_QCTRL:
-               marucam_device_qctrl(state);
-               break;
-       case MARUCAM_CMD_S_CTRL:
-               marucam_device_s_ctrl(state);
-               break;
-       case MARUCAM_CMD_G_CTRL:
-               marucam_device_g_ctrl(state);
-               break;
-       case MARUCAM_CMD_ENUM_FSIZES:
-               marucam_device_enum_fsizes(state);
-               break;
-       case MARUCAM_CMD_ENUM_FINTV:
-               marucam_device_enum_fintv(state);
-               break;
-       case MARUCAM_CMD_S_DATA:
-               state->thread->param->stack[state->thread->param->top++] = value;
-               break;
-       case MARUCAM_CMD_DATACLR:
-               memset(state->thread->param, 0, sizeof(MaruCamParam));
-               break;
-       case MARUCAM_CMD_CLRIRQ:
-               qemu_irq_lower(state->dev.irq[2]);
-               break;
-       case MARUCAM_CMD_REQFRAME:
-               pthread_mutex_lock(&state->thread->mutex_lock);
-               state->req_frame = value + 1;
-               pthread_mutex_unlock(&state->thread->mutex_lock);
-               break;
-       default:
-               WARN("Not supported command!!\n");
-               break;
-       }
-}
-
-static const MemoryRegionOps maru_camera_mmio_ops = {
-    .old_mmio = {
-        .read = {
-            marucam_mmio_read,
-            marucam_mmio_read,
-            marucam_mmio_read,
-        },
-        .write = {
-            marucam_mmio_write,
-            marucam_mmio_write,
-            marucam_mmio_write,
-        },
-    },
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-/*
- *  Initialization function
- */
-static int marucam_initfn(PCIDevice *dev)
-{
-       MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);
-       uint8_t *pci_conf = s->dev.config;
-       MaruCamThreadInfo *thread;
-       MaruCamParam *param;
-
-       pci_config_set_interrupt_pin(pci_conf, 0x03);
-
-    memory_region_init_ram(&s->vram, NULL, "marucamera.ram", MARUCAM_MEM_SIZE);
-    s->vaddr = memory_region_get_ram_ptr(&s->vram);
-
-    memory_region_init_io (&s->mmio, &maru_camera_mmio_ops, s, "maru-camera-mmio", MARUCAM_REG_SIZE);
-    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
-
-       /* for worker thread */
-       thread = (MaruCamThreadInfo*)g_malloc0(sizeof(MaruCamThreadInfo));
-       param = (MaruCamParam*)g_malloc0(sizeof(MaruCamParam));
-
-       thread->state = s;
-       thread->param = param;
-       s->thread = thread;
-
-       marucam_device_init(s);
-
-       return 0;
-}
-
-/*
- *  Termination function
- */
-static int marucam_exitfn(PCIDevice *dev)
-{
-       MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);
-
-       g_free((gpointer)s->thread->param);
-       g_free((gpointer)s->thread);
-
-    memory_region_destroy (&s->vram);
-    memory_region_destroy (&s->mmio);
-    return 0;
-}
-
-int maru_camera_pci_init(PCIBus *bus)
-{
-    INFO("[%s] camera device was initialized.\n", __func__);
-    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);
-    return 0;
-}
-
-static PCIDeviceInfo maru_camera_info = {
-    .qdev.name    = MARU_PCI_CAMERA_DEVICE_NAME,
-    .qdev.desc    = "MARU Virtual Camera device for Tizen emulator",
-    .qdev.size    = sizeof(MaruCamState),
-    .no_hotplug   = 1,
-    .init         = marucam_initfn,
-    .exit         = marucam_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_TIZEN,
-    .device_id    = PCI_DEVICE_ID_VIRTUAL_CAMERA,
-    .class_id     = PCI_CLASS_OTHERS,
-};
-
-static void maru_camera_pci_register(void)
-{
-    pci_qdev_register(&maru_camera_info);
-}
-
-device_init(maru_camera_pci_register);
+/*\r
+ * Common implementation of MARU Virtual Camera device by PCI bus.\r
+ *\r
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ * JinHyung Jo <jinhyung.jo@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+\r
+#include <stdarg.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <inttypes.h>\r
+#include <signal.h>\r
+\r
+#include "qemu-common.h"\r
+#include "cpu-common.h"\r
+\r
+#include "pci.h"\r
+#include "pci_ids.h"\r
+#include "maru_pci_ids.h"\r
+\r
+#include "maru_camera_common.h"\r
+#include "tizen/src/debug_ch.h"\r
+\r
+MULTI_DEBUG_CHANNEL(tizen, camera_pci);\r
+\r
+#define MARU_PCI_CAMERA_DEVICE_NAME            "maru_camera_pci"\r
+\r
+#define MARUCAM_MEM_SIZE               (4 * 1024 * 1024)       // 4MB\r
+#define MARUCAM_REG_SIZE               (256)                           // 64 * 4\r
+\r
+/*\r
+ *  I/O functions\r
+ */\r
+static inline uint32_t marucam_mmio_read(void *opaque, target_phys_addr_t offset)\r
+{\r
+       uint32_t ret = 0;\r
+       MaruCamState *state = (MaruCamState*)opaque;\r
+\r
+       switch (offset & 0xFF) {\r
+       case MARUCAM_CMD_ISSTREAM:\r
+               qemu_mutex_lock(&state->thread_mutex);\r
+               ret = state->streamon;\r
+               qemu_mutex_unlock(&state->thread_mutex);\r
+               break;\r
+       case MARUCAM_CMD_G_DATA:\r
+               ret = state->param->stack[state->param->top++];\r
+               break;\r
+       case MARUCAM_CMD_OPEN:\r
+       case MARUCAM_CMD_CLOSE:\r
+       case MARUCAM_CMD_START_PREVIEW:\r
+       case MARUCAM_CMD_STOP_PREVIEW:\r
+       case MARUCAM_CMD_S_PARAM:\r
+       case MARUCAM_CMD_G_PARAM:\r
+       case MARUCAM_CMD_ENUM_FMT:\r
+       case MARUCAM_CMD_TRY_FMT:\r
+       case MARUCAM_CMD_S_FMT:\r
+       case MARUCAM_CMD_G_FMT:\r
+       case MARUCAM_CMD_QCTRL:\r
+       case MARUCAM_CMD_S_CTRL:\r
+       case MARUCAM_CMD_G_CTRL:\r
+       case MARUCAM_CMD_ENUM_FSIZES:\r
+       case MARUCAM_CMD_ENUM_FINTV:\r
+               ret = state->param->errCode;\r
+               state->param->errCode = 0;\r
+               break;\r
+       default:\r
+               WARN("Not supported command!!\n");\r
+               break;\r
+       }\r
+       return ret;\r
+}\r
+\r
+static inline void marucam_mmio_write(void *opaque, target_phys_addr_t offset, uint32_t value)\r
+{\r
+       MaruCamState *state = (MaruCamState*)opaque;\r
+       \r
+       switch(offset & 0xFF) {\r
+       case MARUCAM_CMD_OPEN:\r
+               marucam_device_open(state);\r
+               break;\r
+       case MARUCAM_CMD_CLOSE:\r
+               marucam_device_close(state);\r
+               break;\r
+       case MARUCAM_CMD_START_PREVIEW:\r
+               marucam_device_start_preview(state);\r
+               break;\r
+       case MARUCAM_CMD_STOP_PREVIEW:\r
+               marucam_device_stop_preview(state);\r
+               break;\r
+       case MARUCAM_CMD_S_PARAM:\r
+               marucam_device_s_param(state);\r
+               break;\r
+       case MARUCAM_CMD_G_PARAM:\r
+               marucam_device_g_param(state);\r
+               break;\r
+       case MARUCAM_CMD_ENUM_FMT:\r
+               marucam_device_enum_fmt(state);\r
+               break;\r
+       case MARUCAM_CMD_TRY_FMT:\r
+               marucam_device_try_fmt(state);\r
+               break;\r
+       case MARUCAM_CMD_S_FMT:\r
+               marucam_device_s_fmt(state);\r
+               break;\r
+       case MARUCAM_CMD_G_FMT:\r
+               marucam_device_g_fmt(state);\r
+               break;\r
+       case MARUCAM_CMD_QCTRL:\r
+               marucam_device_qctrl(state);\r
+               break;\r
+       case MARUCAM_CMD_S_CTRL:\r
+               marucam_device_s_ctrl(state);\r
+               break;\r
+       case MARUCAM_CMD_G_CTRL:\r
+               marucam_device_g_ctrl(state);\r
+               break;\r
+       case MARUCAM_CMD_ENUM_FSIZES:\r
+               marucam_device_enum_fsizes(state);\r
+               break;\r
+       case MARUCAM_CMD_ENUM_FINTV:\r
+               marucam_device_enum_fintv(state);\r
+               break;\r
+       case MARUCAM_CMD_S_DATA:\r
+               state->param->stack[state->param->top++] = value;\r
+               break;\r
+       case MARUCAM_CMD_DATACLR:\r
+               memset(state->param, 0, sizeof(MaruCamParam));\r
+               break;\r
+       case MARUCAM_CMD_CLRIRQ:\r
+               qemu_irq_lower(state->dev.irq[2]);\r
+               break;\r
+       case MARUCAM_CMD_REQFRAME:\r
+               qemu_mutex_lock(&state->thread_mutex);\r
+               state->req_frame = value + 1;\r
+               qemu_mutex_unlock(&state->thread_mutex);\r
+               break;\r
+       default:\r
+               WARN("Not supported command!!\n");\r
+               break;\r
+       }\r
+}\r
+\r
+static const MemoryRegionOps maru_camera_mmio_ops = {\r
+    .old_mmio = {\r
+        .read = {\r
+            marucam_mmio_read,\r
+            marucam_mmio_read,\r
+            marucam_mmio_read,\r
+        },\r
+        .write = {\r
+            marucam_mmio_write,\r
+            marucam_mmio_write,\r
+            marucam_mmio_write,\r
+        },\r
+    },\r
+    .endianness = DEVICE_LITTLE_ENDIAN,\r
+};\r
+\r
+/*\r
+ *  Initialization function\r
+ */\r
+static int marucam_initfn(PCIDevice *dev)\r
+{\r
+       MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);\r
+       uint8_t *pci_conf = s->dev.config;\r
+\r
+       pci_config_set_interrupt_pin(pci_conf, 0x03);\r
+\r
+    memory_region_init_ram(&s->vram, NULL, "marucamera.ram", MARUCAM_MEM_SIZE);\r
+    s->vaddr = memory_region_get_ram_ptr(&s->vram);\r
+\r
+    memory_region_init_io (&s->mmio, &maru_camera_mmio_ops, s, "maru-camera-mmio", MARUCAM_REG_SIZE);\r
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);\r
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);\r
+\r
+       /* for worker thread */\r
+       s->param = (MaruCamParam*)g_malloc0(sizeof(MaruCamParam));\r
+       qemu_cond_init(&s->thread_cond);\r
+       qemu_mutex_init(&s->thread_mutex);\r
+\r
+       marucam_device_init(s);\r
+\r
+       return 0;\r
+}\r
+\r
+/*\r
+ *  Termination function\r
+ */\r
+static int marucam_exitfn(PCIDevice *dev)\r
+{\r
+       MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);\r
+\r
+       g_free((gpointer)s->param);\r
+       qemu_cond_destroy(&s->thread_cond);\r
+       qemu_mutex_destroy(&s->thread_mutex);\r
+\r
+    memory_region_destroy (&s->vram);\r
+    memory_region_destroy (&s->mmio);\r
+    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
+    .qdev.size    = sizeof(MaruCamState),\r
+    .no_hotplug   = 1,\r
+    .init         = marucam_initfn,\r
+    .exit         = marucam_exitfn,\r
+    .vendor_id    = PCI_VENDOR_ID_TIZEN,\r
+    .device_id    = PCI_DEVICE_ID_VIRTUAL_CAMERA,\r
+    .class_id     = PCI_CLASS_OTHERS,\r
+};\r
+\r
+static void maru_camera_pci_register(void)\r
+{\r
+    pci_qdev_register(&maru_camera_info);\r
+}\r
+\r
+device_init(maru_camera_pci_register);\r
index 2bdb16b..0e86dc2 100644 (file)
-/*
- * Implementation of MARU Virtual Camera device by PCI bus on Linux.
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include "qemu-common.h"
-#include "qemu-common.h"
-#include "maru_camera_common.h"
-#include "pci.h"
-#include "kvm.h"
-#include "tizen/src/debug_ch.h"
-
-#include <linux/videodev2.h>
-
-#include <libv4l2.h>
-#include <libv4lconvert.h>
-
-MULTI_DEBUG_CHANNEL(tizen, camera_linux);
-
-static int v4l2_fd;
-static int convert_trial;
-
-static struct v4l2_format dst_fmt;
-
-static int xioctl(int fd, int req, void *arg)
-{
-       int r;
-
-       do {
-               r = v4l2_ioctl(fd, req, arg);
-       } while ( r < 0 && errno == EINTR);
-
-       return r;
-}
-
-#define MARUCAM_CTRL_VALUE_MAX         20
-#define MARUCAM_CTRL_VALUE_MIN         1
-#define MARUCAM_CTRL_VALUE_MID         10
-#define MARUCAM_CTRL_VALUE_STEP                1
-
-struct marucam_qctrl {
-       uint32_t id;
-       uint32_t hit;
-       int32_t min;
-       int32_t max;
-       int32_t step;
-       int32_t init_val;
-};
-
-static struct marucam_qctrl qctrl_tbl[] = {
-       { V4L2_CID_BRIGHTNESS, 0, },
-       { V4L2_CID_CONTRAST, 0, },
-       { V4L2_CID_SATURATION,0, },
-       { V4L2_CID_SHARPNESS, 0, },
-};
-
-static void marucam_reset_controls(void)
-{
-       uint32_t i;
-       for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {
-               if (qctrl_tbl[i].hit) {
-                       struct v4l2_control ctrl = {0,};
-                       ctrl.id = qctrl_tbl[i].id;
-                       ctrl.value = qctrl_tbl[i].init_val;
-                       if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
-                               ERR("failed to set video control value while reset values : %s\n", strerror(errno));
-                       }
-               }
-       }
-}
-
-static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)
-{
-       double rate = 0.0;
-       int32_t dist = 0, ret = 0;
-
-       dist = max - min;
-
-       if (dist < MARUCAM_CTRL_VALUE_MAX) {
-               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-               ret = min + (int32_t)(value / rate);
-       } else {
-               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-               ret = min + (int32_t)(rate * value);
-       }
-       return ret;
-}
-
-static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)
-{
-       double rate  = 0.0;
-       int32_t dist = 0, ret = 0;
-
-       dist = max - min;
-
-       if (dist < MARUCAM_CTRL_VALUE_MAX) {
-               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-               ret = (int32_t)((double)(value - min) * rate);
-       } else {
-               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-               ret = (int32_t)((double)(value - min) / rate);
-       }
-
-       return ret;
-}
-
-static int __v4l2_grab(MaruCamState *state)
-{
-       fd_set fds;
-       static uint32_t index = 0;
-       struct timeval tv;
-       void *buf;
-       int ret;
-       
-       FD_ZERO(&fds);
-       FD_SET(v4l2_fd, &fds);
-
-       tv.tv_sec = 2;
-       tv.tv_usec = 0;
-
-       ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);
-       if ( ret < 0) {
-               if (errno == EINTR)
-                       return 0;
-               ERR("select : %s\n", strerror(errno));
-               return -1;
-       }
-       if (!ret) {
-               WARN("Timed out\n");
-               return 0;
-       }
-
-       if (!v4l2_fd) {
-               WARN("file descriptor is closed or not opened \n");
-               return -1;
-       }
-
-       buf = state->vaddr + (state->buf_size * index);
-       ret = v4l2_read(v4l2_fd, buf, state->buf_size);
-       if ( ret < 0) {
-               switch (errno) {
-               case EINVAL:
-               case ENOMEM:
-                       ERR("v4l2_read failed : %s\n", strerror(errno));
-                       return -1;
-               case EAGAIN:
-               case EIO:
-               case EINTR:
-               default:
-                       if (convert_trial-- == -1) {
-                               ERR("Try count for v4l2_read is exceeded\n");
-                               return -1;
-                       }
-                       return 0;
-               }
-       }
-
-       index = !index;
-
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       if (state->streamon) {
-               if (state->req_frame) {
-                       qemu_irq_raise(state->dev.irq[2]);
-                       state->req_frame = 0;
-               }
-               ret = 1;
-       } else {
-               ret = -1;
-       }
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-
-       return ret;
-}
-
-// Worker thread
-static void *marucam_worker_thread(void *thread_param)
-{
-       MaruCamThreadInfo* thread = (MaruCamThreadInfo*)thread_param;
-
-wait_worker_thread:
-       pthread_mutex_lock(&thread->mutex_lock);
-       thread->state->streamon = 0;
-       convert_trial = 10;
-       pthread_cond_wait(&thread->thread_cond, &thread->mutex_lock);
-       pthread_mutex_unlock(&thread->mutex_lock);
-       INFO("Streaming on ......\n");
-
-       while (1)
-       {
-               pthread_mutex_lock(&thread->mutex_lock);
-               if (thread->state->streamon) {
-                       pthread_mutex_unlock(&thread->mutex_lock);
-                       if (__v4l2_grab(thread->state) < 0) {
-                               INFO("...... Streaming off\n");
-                               goto wait_worker_thread;
-                       }
-               } else {
-                       pthread_mutex_unlock(&thread->mutex_lock);
-                       goto wait_worker_thread;
-               }
-       }
-       pthread_exit(0);
-}
-
-void marucam_device_init(MaruCamState* state)
-{
-       MaruCamThreadInfo *thread = state->thread;
-
-       if (pthread_cond_init(&thread->thread_cond, NULL)) {
-               ERR("failed to initialize thread condition\n");
-               exit(61);
-       }
-       if (pthread_mutex_init(&thread->mutex_lock, NULL)) {
-               ERR("failed to initialize mutex\n");
-               exit(62);
-       }
-
-       if (pthread_create(&thread->thread_id, NULL, marucam_worker_thread, (void*)thread) != 0) {
-               perror("failed to create a worker thread for webcam connection\n");
-               exit(63);
-       }
-}
-
-// MARUCAM_CMD_OPEN
-void marucam_device_open(MaruCamState* state)
-{
-       struct v4l2_capability cap;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       v4l2_fd = v4l2_open("/dev/video0", O_RDWR | O_NONBLOCK);
-       if (v4l2_fd < 0) {
-               ERR("v4l2 device open failed.(/dev/video0)\n");
-               param->errCode = EINVAL;
-               return;
-       }
-       if (xioctl(v4l2_fd, VIDIOC_QUERYCAP, &cap) < 0) {
-               ERR("Could not qeury video capabilities\n");
-               v4l2_close(v4l2_fd);
-               param->errCode = EINVAL;
-               return;
-       }
-       if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
-                       !(cap.capabilities & V4L2_CAP_STREAMING)) {
-               ERR("Not supported video driver.\n");
-               v4l2_close(v4l2_fd);
-               param->errCode = EINVAL;
-               return;
-       }
-
-       memset(&dst_fmt, 0, sizeof(dst_fmt));
-       INFO("Opened\n");
-}
-
-// MARUCAM_CMD_START_PREVIEW
-void marucam_device_start_preview(MaruCamState* state)
-{
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       state->streamon = 1;
-       state->buf_size = dst_fmt.fmt.pix.sizeimage;
-       if (pthread_cond_signal(&state->thread->thread_cond))
-               ERR("failed to send a signal to the worker thread\n");
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-}
-
-// MARUCAM_CMD_STOP_PREVIEW
-void marucam_device_stop_preview(MaruCamState* state)
-{
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       state->streamon = 0;
-       state->buf_size = 0;
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-       sleep(0);
-}
-
-void marucam_device_s_param(MaruCamState* state)
-{
-       struct v4l2_streamparm sp;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&sp, 0, sizeof(struct v4l2_streamparm));
-       sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       sp.parm.capture.timeperframe.numerator = param->stack[0];
-       sp.parm.capture.timeperframe.denominator = param->stack[1];
-
-       if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {
-               ERR("failed to set FPS: %s\n", strerror(errno));
-               param->errCode = errno;
-       }
-}
-
-void marucam_device_g_param(MaruCamState* state)
-{
-       struct v4l2_streamparm sp;
-       MaruCamParam *param = state->thread->param;
-       
-       param->top = 0;
-       memset(&sp, 0, sizeof(struct v4l2_streamparm));
-       sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-       if (xioctl(v4l2_fd, VIDIOC_G_PARM, &sp) < 0) {
-               ERR("failed to get FPS: %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-       param->stack[0] = sp.parm.capture.capability;
-       param->stack[1] = sp.parm.capture.timeperframe.numerator;
-       param->stack[2] = sp.parm.capture.timeperframe.denominator;
-}
-
-void marucam_device_s_fmt(MaruCamState* state)
-{
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&dst_fmt, 0, sizeof(struct v4l2_format));
-       dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       dst_fmt.fmt.pix.width = param->stack[0];
-       dst_fmt.fmt.pix.height = param->stack[1];
-       dst_fmt.fmt.pix.pixelformat = param->stack[2];
-       dst_fmt.fmt.pix.field = param->stack[3];
-
-       if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {
-               ERR("failed to set video format: %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-
-       param->stack[0] = dst_fmt.fmt.pix.width;
-       param->stack[1] = dst_fmt.fmt.pix.height;
-       param->stack[2] = dst_fmt.fmt.pix.field;
-       param->stack[3] = dst_fmt.fmt.pix.pixelformat;
-       param->stack[4] = dst_fmt.fmt.pix.bytesperline;
-       param->stack[5] = dst_fmt.fmt.pix.sizeimage;
-       param->stack[6] = dst_fmt.fmt.pix.colorspace;
-       param->stack[7] = dst_fmt.fmt.pix.priv;
-}
-
-void marucam_device_g_fmt(MaruCamState* state)
-{
-       struct v4l2_format format;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&format, 0, sizeof(struct v4l2_format));
-       format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-       if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {
-               ERR("failed to get video format: %s\n", strerror(errno));
-               param->errCode = errno;         
-       } else {
-               param->stack[0] = format.fmt.pix.width;
-               param->stack[1] = format.fmt.pix.height;
-               param->stack[2] = format.fmt.pix.field;
-               param->stack[3] = format.fmt.pix.pixelformat;
-               param->stack[4] = format.fmt.pix.bytesperline;
-               param->stack[5] = format.fmt.pix.sizeimage;
-               param->stack[6] = format.fmt.pix.colorspace;
-               param->stack[7] = format.fmt.pix.priv;
-               memcpy(&dst_fmt, &format, sizeof(format));
-       }
-}
-
-void marucam_device_try_fmt(MaruCamState* state)
-{
-       struct v4l2_format format;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&format, 0, sizeof(struct v4l2_format));
-       format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       format.fmt.pix.width = param->stack[0];
-       format.fmt.pix.height = param->stack[1];
-       format.fmt.pix.pixelformat = param->stack[2];
-       format.fmt.pix.field = param->stack[3];
-
-       if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {
-               ERR("failed to check video format: %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-       param->stack[0] = format.fmt.pix.width;
-       param->stack[1] = format.fmt.pix.height;
-       param->stack[2] = format.fmt.pix.field;
-       param->stack[3] = format.fmt.pix.pixelformat;
-       param->stack[4] = format.fmt.pix.bytesperline;
-       param->stack[5] = format.fmt.pix.sizeimage;
-       param->stack[6] = format.fmt.pix.colorspace;
-       param->stack[7] = format.fmt.pix.priv;
-}
-
-void marucam_device_enum_fmt(MaruCamState* state)
-{
-       struct v4l2_fmtdesc format;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&format, 0, sizeof(struct v4l2_fmtdesc));
-       format.index = param->stack[0];
-       format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-       if (xioctl(v4l2_fd, VIDIOC_ENUM_FMT, &format) < 0) {
-               if (errno != EINVAL)
-                       ERR("failed to enumerate video formats: %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-       param->stack[0] = format.index;
-       param->stack[1] = format.flags;
-       param->stack[2] = format.pixelformat;
-       /* set description */
-       memcpy(&param->stack[3], format.description, sizeof(format.description));
-}
-
-void marucam_device_qctrl(MaruCamState* state)
-{
-       uint32_t i;
-       char name[32] = {0,};
-       struct v4l2_queryctrl ctrl;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&ctrl, 0, sizeof(struct v4l2_queryctrl));
-       ctrl.id = param->stack[0];
-
-       switch (ctrl.id) {
-       case V4L2_CID_BRIGHTNESS:
-               TRACE("Query : BRIGHTNESS\n");
-               memcpy((void*)name, (void*)"brightness", 32);
-               i = 0;
-               break;
-       case V4L2_CID_CONTRAST:
-               TRACE("Query : CONTRAST\n");
-               memcpy((void*)name, (void*)"contrast", 32);
-               i = 1;
-               break;
-       case V4L2_CID_SATURATION:
-               TRACE("Query : SATURATION\n");
-               memcpy((void*)name, (void*)"saturation", 32);
-               i = 2;
-               break;
-       case V4L2_CID_SHARPNESS:
-               TRACE("Query : SHARPNESS\n");
-               memcpy((void*)name, (void*)"sharpness", 32);
-               i = 3;
-               break;
-       default:
-               param->errCode = EINVAL;
-               return;
-       }
-
-       if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {
-               if (errno != EINVAL)
-                       ERR("failed to query video controls : %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       } else {
-               struct v4l2_control sctrl;
-               memset(&sctrl, 0, sizeof(struct v4l2_control));
-               sctrl.id = ctrl.id;
-               if ((ctrl.maximum + ctrl.minimum) == 0) {
-                       sctrl.value = 0;
-               } else {
-                       sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;
-               }
-               if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {
-                       ERR("failed to set video control value : %s\n", strerror(errno));
-                       param->errCode = errno;
-                       return;
-               }
-               qctrl_tbl[i].hit = 1;
-               qctrl_tbl[i].min = ctrl.minimum;
-               qctrl_tbl[i].max = ctrl.maximum;
-               qctrl_tbl[i].step = ctrl.step;
-               qctrl_tbl[i].init_val = ctrl.default_value;
-       }
-
-       // set fixed values by FW configuration file
-       param->stack[0] = ctrl.id;
-       param->stack[1] = MARUCAM_CTRL_VALUE_MIN;       // minimum
-       param->stack[2] = MARUCAM_CTRL_VALUE_MAX;       // maximum
-       param->stack[3] = MARUCAM_CTRL_VALUE_STEP;// step
-       param->stack[4] = MARUCAM_CTRL_VALUE_MID;       // default_value
-       param->stack[5] = ctrl.flags;
-       /* name field setting */
-       memcpy(&param->stack[6], (void*)name, sizeof(ctrl.name));
-}
-
-void marucam_device_s_ctrl(MaruCamState* state)
-{
-       uint32_t i;
-       struct v4l2_control ctrl;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&ctrl, 0, sizeof(struct v4l2_control));
-       ctrl.id = param->stack[0];
-
-       switch (ctrl.id) {
-       case V4L2_CID_BRIGHTNESS:
-               i = 0;
-               TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);
-               break;
-       case V4L2_CID_CONTRAST:
-               i = 1;
-               TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);
-               break;
-       case V4L2_CID_SATURATION:
-               i = 2;
-               TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);
-               break;
-       case V4L2_CID_SHARPNESS:
-               i = 3;
-               TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);
-               break;
-       default:
-               ERR("our emulator does not support this control : 0x%x\n", ctrl.id);
-               param->errCode = EINVAL;
-               return;
-       }
-
-       ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,
-                       qctrl_tbl[i].max, param->stack[1]);
-       if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
-               ERR("failed to set video control value : value(%d), %s\n", param->stack[1], strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-}
-
-void marucam_device_g_ctrl(MaruCamState* state)
-{
-       uint32_t i;
-       struct v4l2_control ctrl;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&ctrl, 0, sizeof(struct v4l2_control));
-       ctrl.id = param->stack[0];
-
-       switch (ctrl.id) {
-       case V4L2_CID_BRIGHTNESS:
-               TRACE("Gets the value of the BRIGHTNESS\n");
-               i = 0;
-               break;
-       case V4L2_CID_CONTRAST:
-               TRACE("Gets the value of the CONTRAST\n");
-               i = 1;
-               break;
-       case V4L2_CID_SATURATION:
-               TRACE("Gets the value of the SATURATION\n");
-               i = 2;
-               break;
-       case V4L2_CID_SHARPNESS:
-               TRACE("Gets the value of the SHARPNESS\n");
-               i = 3;
-               break;
-       default:
-               ERR("our emulator does not support this control : 0x%x\n", ctrl.id);
-               param->errCode = EINVAL;
-               return;
-       }
-
-       if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {
-               ERR("failed to get video control value : %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-       param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,
-                       qctrl_tbl[i].max, ctrl.value);
-       TRACE("Value : %d\n", param->stack[0]);
-}
-
-void marucam_device_enum_fsizes(MaruCamState* state)
-{
-       struct v4l2_frmsizeenum fsize;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&fsize, 0, sizeof(struct v4l2_frmsizeenum));
-       fsize.index = param->stack[0];
-       fsize.pixel_format = param->stack[1];
-
-       if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMESIZES, &fsize) < 0) {
-               if (errno != EINVAL)
-                       ERR("failed to get frame sizes : %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-
-       if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
-               param->stack[0] = fsize.discrete.width;
-               param->stack[1] = fsize.discrete.height;
-       } else {
-               param->errCode = EINVAL;
-               ERR("Not Supported mode, we only support DISCRETE\n");
-       }
-}
-
-void marucam_device_enum_fintv(MaruCamState* state)
-{
-       struct v4l2_frmivalenum ival;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       memset(&ival, 0, sizeof(struct v4l2_frmivalenum));
-       ival.index = param->stack[0];
-       ival.pixel_format = param->stack[1];
-       ival.width = param->stack[2];
-       ival.height = param->stack[3];
-
-       if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0) {
-               if (errno != EINVAL)
-                       ERR("failed to get frame intervals : %s\n", strerror(errno));
-               param->errCode = errno;
-               return;
-       }
-
-       if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
-               param->stack[0] = ival.discrete.numerator;
-               param->stack[1] = ival.discrete.denominator;
-       } else {
-               param->errCode = EINVAL;
-               ERR("Not Supported mode, we only support DISCRETE\n");
-       }
-}
-
-// MARUCAM_CMD_CLOSE
-void marucam_device_close(MaruCamState* state)
-{
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       state->streamon = 0;
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-
-       marucam_reset_controls();
-
-       v4l2_close(v4l2_fd);
-       v4l2_fd = 0;
-       INFO("Closed\n");
-}
+/*\r
+ * Implementation of MARU Virtual Camera device by PCI bus on Linux.\r
+ *\r
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ * JinHyung Jo <jinhyung.jo@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#include "qemu-common.h"\r
+#include "qemu-common.h"\r
+#include "maru_camera_common.h"\r
+#include "pci.h"\r
+#include "kvm.h"\r
+#include "tizen/src/debug_ch.h"\r
+\r
+#include <linux/videodev2.h>\r
+\r
+#include <libv4l2.h>\r
+#include <libv4lconvert.h>\r
+\r
+MULTI_DEBUG_CHANNEL(tizen, camera_linux);\r
+\r
+static int v4l2_fd;\r
+static int convert_trial;\r
+\r
+static struct v4l2_format dst_fmt;\r
+\r
+static int xioctl(int fd, int req, void *arg)\r
+{\r
+       int r;\r
+\r
+       do {\r
+               r = v4l2_ioctl(fd, req, arg);\r
+       } while ( r < 0 && errno == EINTR);\r
+\r
+       return r;\r
+}\r
+\r
+#define MARUCAM_CTRL_VALUE_MAX         20\r
+#define MARUCAM_CTRL_VALUE_MIN         1\r
+#define MARUCAM_CTRL_VALUE_MID         10\r
+#define MARUCAM_CTRL_VALUE_STEP                1\r
+\r
+struct marucam_qctrl {\r
+       uint32_t id;\r
+       uint32_t hit;\r
+       int32_t min;\r
+       int32_t max;\r
+       int32_t step;\r
+       int32_t init_val;\r
+};\r
+\r
+static struct marucam_qctrl qctrl_tbl[] = {\r
+       { V4L2_CID_BRIGHTNESS, 0, },\r
+       { V4L2_CID_CONTRAST, 0, },\r
+       { V4L2_CID_SATURATION,0, },\r
+       { V4L2_CID_SHARPNESS, 0, },\r
+};\r
+\r
+static void marucam_reset_controls(void)\r
+{\r
+       uint32_t i;\r
+       for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {\r
+               if (qctrl_tbl[i].hit) {\r
+                       struct v4l2_control ctrl = {0,};\r
+                       ctrl.id = qctrl_tbl[i].id;\r
+                       ctrl.value = qctrl_tbl[i].init_val;\r
+                       if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {\r
+                               ERR("failed to set video control value while reset values : %s\n", strerror(errno));\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)\r
+{\r
+       double rate = 0.0;\r
+       int32_t dist = 0, ret = 0;\r
+\r
+       dist = max - min;\r
+\r
+       if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
+               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
+               ret = min + (int32_t)(value / rate);\r
+       } else {\r
+               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
+               ret = min + (int32_t)(rate * value);\r
+       }\r
+       return ret;\r
+}\r
+\r
+static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)\r
+{\r
+       double rate  = 0.0;\r
+       int32_t dist = 0, ret = 0;\r
+\r
+       dist = max - min;\r
+\r
+       if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
+               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
+               ret = (int32_t)((double)(value - min) * rate);\r
+       } else {\r
+               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
+               ret = (int32_t)((double)(value - min) / rate);\r
+       }\r
+\r
+       return ret;\r
+}\r
+\r
+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
+       \r
+       FD_ZERO(&fds);\r
+       FD_SET(v4l2_fd, &fds);\r
+\r
+       tv.tv_sec = 2;\r
+       tv.tv_usec = 0;\r
+\r
+       ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);\r
+       if ( ret < 0) {\r
+               if (errno == EINTR)\r
+                       return 0;\r
+               ERR("select : %s\n", strerror(errno));\r
+               return -1;\r
+       }\r
+       if (!ret) {\r
+               WARN("Timed out\n");\r
+               return 0;\r
+       }\r
+\r
+       if (!v4l2_fd) {\r
+               WARN("file descriptor is closed or not opened \n");\r
+               return -1;\r
+       }\r
+\r
+       buf = state->vaddr + (state->buf_size * index);\r
+       ret = v4l2_read(v4l2_fd, buf, state->buf_size);\r
+       if ( ret < 0) {\r
+               switch (errno) {\r
+               case EINVAL:\r
+               case ENOMEM:\r
+                       ERR("v4l2_read failed : %s\n", strerror(errno));\r
+                       return -1;\r
+               case EAGAIN:\r
+               case EIO:\r
+               case EINTR:\r
+               default:\r
+                       if (convert_trial-- == -1) {\r
+                               ERR("Try count for v4l2_read is exceeded\n");\r
+                               return -1;\r
+                       }\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       index = !index;\r
+\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       if (state->streamon) {\r
+               if (state->req_frame) {\r
+                       qemu_irq_raise(state->dev.irq[2]);\r
+                       state->req_frame = 0;\r
+               }\r
+               ret = 1;\r
+       } else {\r
+               ret = -1;\r
+       }\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+\r
+       return ret;\r
+}\r
+\r
+// Worker thread\r
+static void *marucam_worker_thread(void *thread_param)\r
+{\r
+       MaruCamState *state = (MaruCamState*)thread_param;\r
+\r
+wait_worker_thread:\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 0;\r
+       convert_trial = 10;\r
+       qemu_cond_wait(&state->thread_cond, &state->thread_mutex);\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+       INFO("Streaming on ......\n");\r
+\r
+       while (1)\r
+       {\r
+               qemu_mutex_lock(&state->thread_mutex);\r
+               if (state->streamon) {\r
+                       qemu_mutex_unlock(&state->thread_mutex);\r
+                       if (__v4l2_grab(state) < 0) {\r
+                               INFO("...... Streaming off\n");\r
+                               goto wait_worker_thread;\r
+                       }\r
+               } else {\r
+                       qemu_mutex_unlock(&state->thread_mutex);\r
+                       goto wait_worker_thread;\r
+               }\r
+       }\r
+       qemu_thread_exit((void*)0);\r
+}\r
+\r
+void marucam_device_init(MaruCamState* state)\r
+{\r
+       qemu_thread_create(&state->thread_id, marucam_worker_thread, (void*)state);\r
+}\r
+\r
+// MARUCAM_CMD_OPEN\r
+void marucam_device_open(MaruCamState* state)\r
+{\r
+       struct v4l2_capability cap;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       v4l2_fd = v4l2_open("/dev/video0", O_RDWR | O_NONBLOCK);\r
+       if (v4l2_fd < 0) {\r
+               ERR("v4l2 device open failed.(/dev/video0)\n");\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       if (xioctl(v4l2_fd, VIDIOC_QUERYCAP, &cap) < 0) {\r
+               ERR("Could not qeury video capabilities\n");\r
+               v4l2_close(v4l2_fd);\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||\r
+                       !(cap.capabilities & V4L2_CAP_STREAMING)) {\r
+               ERR("Not supported video driver.\n");\r
+               v4l2_close(v4l2_fd);\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       memset(&dst_fmt, 0, sizeof(dst_fmt));\r
+       INFO("Opened\n");\r
+}\r
+\r
+// MARUCAM_CMD_START_PREVIEW\r
+void marucam_device_start_preview(MaruCamState* state)\r
+{\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 1;\r
+       state->buf_size = dst_fmt.fmt.pix.sizeimage;\r
+       qemu_cond_signal(&state->thread_cond);\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+}\r
+\r
+// MARUCAM_CMD_STOP_PREVIEW\r
+void marucam_device_stop_preview(MaruCamState* state)\r
+{\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 0;\r
+       state->buf_size = 0;\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+       sleep(0);\r
+}\r
+\r
+void marucam_device_s_param(MaruCamState* state)\r
+{\r
+       struct v4l2_streamparm sp;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&sp, 0, sizeof(struct v4l2_streamparm));\r
+       sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+       sp.parm.capture.timeperframe.numerator = param->stack[0];\r
+       sp.parm.capture.timeperframe.denominator = param->stack[1];\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {\r
+               ERR("failed to set FPS: %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+       }\r
+}\r
+\r
+void marucam_device_g_param(MaruCamState* state)\r
+{\r
+       struct v4l2_streamparm sp;\r
+       MaruCamParam *param = state->param;\r
+       \r
+       param->top = 0;\r
+       memset(&sp, 0, sizeof(struct v4l2_streamparm));\r
+       sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_G_PARM, &sp) < 0) {\r
+               ERR("failed to get FPS: %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+       param->stack[0] = sp.parm.capture.capability;\r
+       param->stack[1] = sp.parm.capture.timeperframe.numerator;\r
+       param->stack[2] = sp.parm.capture.timeperframe.denominator;\r
+}\r
+\r
+void marucam_device_s_fmt(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&dst_fmt, 0, sizeof(struct v4l2_format));\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
+\r
+       if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {\r
+               ERR("failed to set video format: %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+\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
+       param->stack[3] = dst_fmt.fmt.pix.pixelformat;\r
+       param->stack[4] = dst_fmt.fmt.pix.bytesperline;\r
+       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
+}\r
+\r
+void marucam_device_g_fmt(MaruCamState* state)\r
+{\r
+       struct v4l2_format format;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&format, 0, sizeof(struct v4l2_format));\r
+       format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {\r
+               ERR("failed to get video format: %s\n", strerror(errno));\r
+               param->errCode = errno;         \r
+       } else {\r
+               param->stack[0] = format.fmt.pix.width;\r
+               param->stack[1] = format.fmt.pix.height;\r
+               param->stack[2] = format.fmt.pix.field;\r
+               param->stack[3] = format.fmt.pix.pixelformat;\r
+               param->stack[4] = format.fmt.pix.bytesperline;\r
+               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
+       }\r
+}\r
+\r
+void marucam_device_try_fmt(MaruCamState* state)\r
+{\r
+       struct v4l2_format format;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&format, 0, sizeof(struct v4l2_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 = param->stack[3];\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {\r
+               ERR("failed to check video format: %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+       param->stack[0] = format.fmt.pix.width;\r
+       param->stack[1] = format.fmt.pix.height;\r
+       param->stack[2] = format.fmt.pix.field;\r
+       param->stack[3] = format.fmt.pix.pixelformat;\r
+       param->stack[4] = format.fmt.pix.bytesperline;\r
+       param->stack[5] = format.fmt.pix.sizeimage;\r
+       param->stack[6] = format.fmt.pix.colorspace;\r
+       param->stack[7] = format.fmt.pix.priv;\r
+}\r
+\r
+void marucam_device_enum_fmt(MaruCamState* state)\r
+{\r
+       struct v4l2_fmtdesc format;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&format, 0, sizeof(struct v4l2_fmtdesc));\r
+       format.index = param->stack[0];\r
+       format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_ENUM_FMT, &format) < 0) {\r
+               if (errno != EINVAL)\r
+                       ERR("failed to enumerate video formats: %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+       param->stack[0] = format.index;\r
+       param->stack[1] = format.flags;\r
+       param->stack[2] = format.pixelformat;\r
+       /* set description */\r
+       memcpy(&param->stack[3], format.description, sizeof(format.description));\r
+}\r
+\r
+void marucam_device_qctrl(MaruCamState* state)\r
+{\r
+       uint32_t i;\r
+       char name[32] = {0,};\r
+       struct v4l2_queryctrl ctrl;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&ctrl, 0, sizeof(struct v4l2_queryctrl));\r
+       ctrl.id = param->stack[0];\r
+\r
+       switch (ctrl.id) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               TRACE("Query : BRIGHTNESS\n");\r
+               memcpy((void*)name, (void*)"brightness", 32);\r
+               i = 0;\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               TRACE("Query : CONTRAST\n");\r
+               memcpy((void*)name, (void*)"contrast", 32);\r
+               i = 1;\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               TRACE("Query : SATURATION\n");\r
+               memcpy((void*)name, (void*)"saturation", 32);\r
+               i = 2;\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               TRACE("Query : SHARPNESS\n");\r
+               memcpy((void*)name, (void*)"sharpness", 32);\r
+               i = 3;\r
+               break;\r
+       default:\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {\r
+               if (errno != EINVAL)\r
+                       ERR("failed to query video controls : %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       } else {\r
+               struct v4l2_control sctrl;\r
+               memset(&sctrl, 0, sizeof(struct v4l2_control));\r
+               sctrl.id = ctrl.id;\r
+               if ((ctrl.maximum + ctrl.minimum) == 0) {\r
+                       sctrl.value = 0;\r
+               } else {\r
+                       sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;\r
+               }\r
+               if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {\r
+                       ERR("failed to set video control value : %s\n", strerror(errno));\r
+                       param->errCode = errno;\r
+                       return;\r
+               }\r
+               qctrl_tbl[i].hit = 1;\r
+               qctrl_tbl[i].min = ctrl.minimum;\r
+               qctrl_tbl[i].max = ctrl.maximum;\r
+               qctrl_tbl[i].step = ctrl.step;\r
+               qctrl_tbl[i].init_val = ctrl.default_value;\r
+       }\r
+\r
+       // set fixed values by FW configuration file\r
+       param->stack[0] = ctrl.id;\r
+       param->stack[1] = MARUCAM_CTRL_VALUE_MIN;       // minimum\r
+       param->stack[2] = MARUCAM_CTRL_VALUE_MAX;       // maximum\r
+       param->stack[3] = MARUCAM_CTRL_VALUE_STEP;// step\r
+       param->stack[4] = MARUCAM_CTRL_VALUE_MID;       // default_value\r
+       param->stack[5] = ctrl.flags;\r
+       /* name field setting */\r
+       memcpy(&param->stack[6], (void*)name, sizeof(ctrl.name));\r
+}\r
+\r
+void marucam_device_s_ctrl(MaruCamState* state)\r
+{\r
+       uint32_t i;\r
+       struct v4l2_control ctrl;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&ctrl, 0, sizeof(struct v4l2_control));\r
+       ctrl.id = param->stack[0];\r
+\r
+       switch (ctrl.id) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               i = 0;\r
+               TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               i = 1;\r
+               TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               i = 2;\r
+               TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               i = 3;\r
+               TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);\r
+               break;\r
+       default:\r
+               ERR("our emulator does not support this control : 0x%x\n", ctrl.id);\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,\r
+                       qctrl_tbl[i].max, param->stack[1]);\r
+       if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {\r
+               ERR("failed to set video control value : value(%d), %s\n", param->stack[1], strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+}\r
+\r
+void marucam_device_g_ctrl(MaruCamState* state)\r
+{\r
+       uint32_t i;\r
+       struct v4l2_control ctrl;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&ctrl, 0, sizeof(struct v4l2_control));\r
+       ctrl.id = param->stack[0];\r
+\r
+       switch (ctrl.id) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               TRACE("Gets the value of the BRIGHTNESS\n");\r
+               i = 0;\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               TRACE("Gets the value of the CONTRAST\n");\r
+               i = 1;\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               TRACE("Gets the value of the SATURATION\n");\r
+               i = 2;\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               TRACE("Gets the value of the SHARPNESS\n");\r
+               i = 3;\r
+               break;\r
+       default:\r
+               ERR("our emulator does not support this control : 0x%x\n", ctrl.id);\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {\r
+               ERR("failed to get video control value : %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+       param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,\r
+                       qctrl_tbl[i].max, ctrl.value);\r
+       TRACE("Value : %d\n", param->stack[0]);\r
+}\r
+\r
+void marucam_device_enum_fsizes(MaruCamState* state)\r
+{\r
+       struct v4l2_frmsizeenum fsize;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&fsize, 0, sizeof(struct v4l2_frmsizeenum));\r
+       fsize.index = param->stack[0];\r
+       fsize.pixel_format = param->stack[1];\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMESIZES, &fsize) < 0) {\r
+               if (errno != EINVAL)\r
+                       ERR("failed to get frame sizes : %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+\r
+       if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {\r
+               param->stack[0] = fsize.discrete.width;\r
+               param->stack[1] = fsize.discrete.height;\r
+       } else {\r
+               param->errCode = EINVAL;\r
+               ERR("Not Supported mode, we only support DISCRETE\n");\r
+       }\r
+}\r
+\r
+void marucam_device_enum_fintv(MaruCamState* state)\r
+{\r
+       struct v4l2_frmivalenum ival;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       memset(&ival, 0, sizeof(struct v4l2_frmivalenum));\r
+       ival.index = param->stack[0];\r
+       ival.pixel_format = param->stack[1];\r
+       ival.width = param->stack[2];\r
+       ival.height = param->stack[3];\r
+\r
+       if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0) {\r
+               if (errno != EINVAL)\r
+                       ERR("failed to get frame intervals : %s\n", strerror(errno));\r
+               param->errCode = errno;\r
+               return;\r
+       }\r
+\r
+       if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {\r
+               param->stack[0] = ival.discrete.numerator;\r
+               param->stack[1] = ival.discrete.denominator;\r
+       } else {\r
+               param->errCode = EINVAL;\r
+               ERR("Not Supported mode, we only support DISCRETE\n");\r
+       }\r
+}\r
+\r
+// MARUCAM_CMD_CLOSE\r
+void marucam_device_close(MaruCamState* state)\r
+{\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 0;\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+\r
+       marucam_reset_controls();\r
+\r
+       v4l2_close(v4l2_fd);\r
+       v4l2_fd = 0;\r
+       INFO("Closed\n");\r
+}\r
diff --git a/tizen/src/hw/maru_camera_win32_interface.h b/tizen/src/hw/maru_camera_win32_interface.h
new file mode 100644 (file)
index 0000000..d68cb85
--- /dev/null
@@ -0,0 +1,932 @@
+/*\r
+ * Interface definition header for Windows host.\r
+ *\r
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ * JinHyung Jo <jinhyung.jo@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#ifndef _MARU_CAMERA_INTERFACE_H_\r
+#define _MARU_CAMERA_INTERFACE_H_\r
+\r
+static const WCHAR HWCPinName[] = L"HWCInputPin\0";\r
+static const WCHAR HWCFilterName[] = L"HWCFilter\0";\r
+\r
+/* Forward Declarations */\r
+FWD_DECL(IBaseFilter);\r
+FWD_DECL(IFilterGraph);\r
+\r
+/* defines */\r
+#define MAX_PIN_NAME     128\r
+#define MAX_FILTER_NAME  128\r
+\r
+typedef LONGLONG REFERENCE_TIME;\r
+typedef long OAFilterState;\r
+typedef DWORD_PTR HSEMAPHORE;\r
+typedef DWORD_PTR HEVENT;\r
+\r
+typedef enum _FilterState {\r
+  State_Stopped,\r
+  State_Paused,\r
+  State_Running\r
+} FILTER_STATE;\r
+\r
+typedef struct _FilterInfo {\r
+  WCHAR achName[MAX_FILTER_NAME];\r
+  IFilterGraph *pGraph;\r
+} FILTER_INFO;\r
+\r
+typedef enum _PinDirection\r
+{      PINDIR_INPUT    = 0,\r
+       PINDIR_OUTPUT   = ( PINDIR_INPUT + 1 )\r
+} PIN_DIRECTION;\r
+\r
+typedef struct _PinInfo {\r
+  IBaseFilter *pFilter;\r
+  PIN_DIRECTION dir;\r
+  WCHAR achName[MAX_PIN_NAME];\r
+} PIN_INFO;\r
+\r
+typedef struct _AllocatorProperties {\r
+  long cBuffers;\r
+  long cbBuffer;\r
+  long cbAlign;\r
+  long cbPrefix;\r
+} ALLOCATOR_PROPERTIES;\r
+\r
+typedef struct _AMMediaType {\r
+  GUID majortype;\r
+  GUID subtype;\r
+  BOOL bFixedSizeSamples;\r
+  BOOL bTemporalCompression;\r
+  ULONG lSampleSize;\r
+  GUID formattype;\r
+  IUnknown *pUnk;\r
+  ULONG cbFormat;\r
+  BYTE *pbFormat;\r
+} AM_MEDIA_TYPE;\r
+\r
+typedef enum tagVideoProcAmpFlags {\r
+       VideoProcAmp_Flags_Auto = 0x0001,\r
+       VideoProcAmp_Flags_Manual = 0x0002\r
+} VideoProcAmpFlags;\r
+\r
+typedef enum tagVideoProcAmpProperty {\r
+       VideoProcAmp_Brightness,\r
+       VideoProcAmp_Contrast,\r
+       VideoProcAmp_Hue,\r
+       VideoProcAmp_Saturation,\r
+       VideoProcAmp_Sharpness,\r
+       VideoProcAmp_Gamma,\r
+       VideoProcAmp_ColorEnable,\r
+       VideoProcAmp_WhiteBalance,\r
+       VideoProcAmp_BacklightCompensation,\r
+       VideoProcAmp_Gain\r
+} VideoProcAmpProperty;\r
+\r
+typedef struct tagVIDEOINFOHEADER {\r
+       RECT rcSource;\r
+       RECT rcTarget;\r
+       DWORD dwBitRate;\r
+       DWORD dwBitErrorRate;\r
+       REFERENCE_TIME AvgTimePerFrame;\r
+       BITMAPINFOHEADER bmiHeader;\r
+} VIDEOINFOHEADER;\r
+\r
+typedef struct _VIDEO_STREAM_CONFIG_CAPS\r
+{\r
+  GUID guid;\r
+  ULONG VideoStandard;\r
+  SIZE InputSize;\r
+  SIZE MinCroppingSize;\r
+  SIZE MaxCroppingSize;\r
+  int CropGranularityX;\r
+  int CropGranularityY;\r
+  int CropAlignX;\r
+  int CropAlignY;\r
+  SIZE MinOutputSize;\r
+  SIZE MaxOutputSize;\r
+  int OutputGranularityX;\r
+  int OutputGranularityY;\r
+  int StretchTapsX;\r
+  int StretchTapsY;\r
+  int ShrinkTapsX;\r
+  int ShrinkTapsY;\r
+  LONGLONG MinFrameInterval;\r
+  LONGLONG MaxFrameInterval;\r
+  LONG MinBitsPerSecond;\r
+  LONG MaxBitsPerSecond;\r
+} VIDEO_STREAM_CONFIG_CAPS;\r
+\r
+\r
+/* Interface & Class GUIDs */\r
+static const IID IID_IGrabCallback   = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};\r
+\r
+EXTERN_C const IID IID_IBaseFilter;\r
+EXTERN_C const IID IID_ICreateDevEnum;\r
+EXTERN_C const IID IID_IGraphBuilder;\r
+EXTERN_C const IID IID_IMediaSeeking;\r
+EXTERN_C const IID IID_IMediaEventSink;\r
+EXTERN_C const IID IID_IMemInputPin;\r
+EXTERN_C const IID IID_IEnumPins;\r
+EXTERN_C const IID IID_IMediaFilter;\r
+EXTERN_C const IID IID_IEnumMediaTypes;\r
+EXTERN_C const IID IID_IMemAllocator;\r
+EXTERN_C const IID IID_IPin;\r
+EXTERN_C const IID IID_ICaptureGraphBuilder2;\r
+EXTERN_C const IID IID_IFileSinkFilter;\r
+EXTERN_C const IID IID_IAMCopyCaptureFileProgress;\r
+EXTERN_C const IID IID_IEnumFilters;\r
+EXTERN_C const IID IID_IMediaSample;\r
+EXTERN_C const IID IID_IMediaControl;\r
+EXTERN_C const IID IID_IAMStreamConfig;\r
+EXTERN_C const IID IID_IAMVideoProcAmp;\r
+\r
+EXTERN_C const IID CLSID_CaptureGraphBuilder2;\r
+EXTERN_C const IID CLSID_VideoInputDeviceCategory;\r
+EXTERN_C const IID CLSID_AudioRender;\r
+EXTERN_C const IID CLSID_SystemDeviceEnum;\r
+EXTERN_C const IID CLSID_AudioRendererCategory;\r
+EXTERN_C const IID CLSID_FilterGraph;\r
+EXTERN_C const IID CLSID_InfTee;\r
+EXTERN_C const IID CLSID_VideoMixingRenderer9;\r
+EXTERN_C const IID CLSID_MemoryAllocator;\r
+\r
+\r
+/* other types GUIDs*/\r
+EXTERN_C const IID MEDIATYPE_Audio;\r
+EXTERN_C const IID MEDIATYPE_Video;\r
+EXTERN_C const IID MEDIATYPE_Stream;\r
+EXTERN_C const IID MEDIASUBTYPE_PCM;\r
+EXTERN_C const IID MEDIASUBTYPE_WAVE;\r
+EXTERN_C const IID MEDIASUBTYPE_Avi;\r
+EXTERN_C const IID MEDIASUBTYPE_RGB32;\r
+EXTERN_C const IID MEDIASUBTYPE_YV12;\r
+EXTERN_C const IID MEDIASUBTYPE_YUY2;\r
+EXTERN_C const IID MEDIASUBTYPE_I420;\r
+EXTERN_C const IID MEDIASUBTYPE_YUYV;\r
+EXTERN_C const IID FORMAT_WaveFormatEx;\r
+EXTERN_C const IID FORMAT_VideoInfo;\r
+EXTERN_C const IID FORMAT_VideoInfo2;\r
+EXTERN_C const IID PIN_CATEGORY_CAPTURE;\r
+EXTERN_C const IID PIN_CATEGORY_PREVIEW;\r
+\r
+\r
+#define MEDIATYPE_NULL       GUID_NULL\r
+#define MEDIASUBTYPE_NULL    GUID_NULL\r
+\r
+#define INTERFACE IGrabCallback\r
+DECLARE_INTERFACE_(IGrabCallback, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(Grab)(THIS_ ULONG,BYTE*) PURE;\r
+};\r
+#undef INTERFACE\r
+\r
+#ifdef COBJMACROS\r
+#define IGrabCallback_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)\r
+#define IGrabCallback_AddRef(T) (T)->lpVtbl->AddRef(T)\r
+#define IGrabCallback_Release(T) (T)->lpVtbl->Release(T)\r
+#define IGrabCallback_Grab(T,a,b) (T)->lpVtbl->Grab(T,a,b)\r
+#endif /* COBJMACROS */\r
+\r
+#define INTERFACE IAMCopyCaptureFileProgress\r
+DECLARE_INTERFACE_(IAMCopyCaptureFileProgress, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(Progress)(THIS_ int) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IReferenceClock\r
+DECLARE_INTERFACE_(IReferenceClock, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *) PURE;\r
+    STDMETHOD(AdviseTime)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HEVENT, DWORD_PTR *) PURE;\r
+    STDMETHOD(AdvisePeriodic)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HSEMAPHORE, DWORD_PTR *) PURE;\r
+    STDMETHOD(Unadvise)(THIS_ DWORD_PTR) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IEnumFilters\r
+DECLARE_INTERFACE_(IEnumFilters, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(Next)(THIS_ ULONG, IBaseFilter **, ULONG *) PURE;\r
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
+    STDMETHOD(Reset)(THIS) PURE;\r
+    STDMETHOD(Clone)(THIS_ IEnumFilters **) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IEnumMediaTypes\r
+DECLARE_INTERFACE_(IEnumMediaTypes, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(Next)(THIS_ ULONG, AM_MEDIA_TYPE **, ULONG *) PURE;\r
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
+    STDMETHOD(Reset)(THIS) PURE;\r
+    STDMETHOD(Clone)(THIS_ IEnumMediaTypes **) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IPin\r
+DECLARE_INTERFACE_(IPin, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(Connect)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(ReceiveConnection)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(Disconnect)(THIS) PURE;\r
+    STDMETHOD(ConnectedTo)(THIS_ IPin **) PURE;\r
+    STDMETHOD(ConnectionMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(QueryPinInfo)(THIS_ PIN_INFO *) PURE;\r
+    STDMETHOD(QueryDirection)(THIS_ PIN_DIRECTION *) PURE;\r
+    STDMETHOD(QueryId)(THIS_ LPWSTR *) PURE;\r
+    STDMETHOD(QueryAccept)(THIS_ const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(EnumMediaTypes)(THIS_ IEnumMediaTypes **) PURE;\r
+    STDMETHOD(QueryInternalConnections)(THIS_ IPin **, ULONG *) PURE;\r
+    STDMETHOD(EndOfStream)(THIS) PURE;\r
+    STDMETHOD(BeginFlush)(THIS) PURE;\r
+    STDMETHOD(EndFlush)(THIS) PURE;\r
+    STDMETHOD(NewSegment)(THIS_ REFERENCE_TIME, REFERENCE_TIME, double) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IEnumPins\r
+DECLARE_INTERFACE_(IEnumPins, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(Next)(THIS_ ULONG, IPin **, ULONG *) PURE;\r
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
+    STDMETHOD(Reset)(THIS) PURE;\r
+    STDMETHOD(Clone)(THIS_ IEnumPins **) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IMediaFilter\r
+DECLARE_INTERFACE_(IMediaFilter, IPersist)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;\r
+    STDMETHOD(Stop)(THIS) PURE;\r
+    STDMETHOD(Pause)(THIS) PURE;\r
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;\r
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;\r
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;\r
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IBaseFilter\r
+//DECLARE_INTERFACE_(IBaseFilter, IMediaFilter)\r
+_COM_interface IBaseFilter { CONST_VTABLE struct IBaseFilterVtbl *lpVtbl; };\r
+typedef CONST_VTABLE struct IBaseFilterVtbl IBaseFilterVtbl;\r
+CONST_VTABLE struct IBaseFilterVtbl\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;\r
+    STDMETHOD(Stop)(THIS) PURE;\r
+    STDMETHOD(Pause)(THIS) PURE;\r
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;\r
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;\r
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;\r
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;\r
+    STDMETHOD(EnumPins)(THIS_ IEnumPins **) PURE;\r
+    STDMETHOD(FindPin)(THIS_ LPCWSTR, IPin **) PURE;\r
+    STDMETHOD(QueryFilterInfo)(THIS_ FILTER_INFO *) PURE;\r
+    STDMETHOD(JoinFilterGraph)(THIS_ IFilterGraph *, LPCWSTR) PURE;\r
+    STDMETHOD(QueryVendorInfo)(THIS_ LPWSTR *) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IFilterGraph\r
+//DECLARE_INTERFACE_(IFilterGraph ,IUnknown)\r
+_COM_interface IFilterGraph { CONST_VTABLE struct IFilterGraphVtbl *lpVtbl; };\r
+typedef CONST_VTABLE struct IFilterGraphVtbl IFilterGraphVtbl;\r
+CONST_VTABLE struct IFilterGraphVtbl\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;\r
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;\r
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;\r
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;\r
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;\r
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;\r
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IGraphBuilder\r
+DECLARE_INTERFACE_(IGraphBuilder ,IFilterGraph)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;\r
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;\r
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;\r
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;\r
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;\r
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;\r
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;\r
+       STDMETHOD(Connect)(THIS_ IPin *, IPin *) PURE;\r
+    STDMETHOD(Render)(THIS_ IPin *) PURE;\r
+    STDMETHOD(RenderFile)(THIS_ LPCWSTR, LPCWSTR) PURE;\r
+    STDMETHOD(AddSourceFilter)(THIS_ LPCWSTR, LPCWSTR, IBaseFilter **) PURE;\r
+    STDMETHOD(SetLogFile)(THIS_ DWORD_PTR) PURE;\r
+    STDMETHOD(Abort)(THIS) PURE;\r
+    STDMETHOD(ShouldOperationContinue)(THIS) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE ICreateDevEnum\r
+DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(CreateClassEnumerator)(THIS_ REFCLSID, IEnumMoniker **, DWORD) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IMediaSample\r
+DECLARE_INTERFACE_(IMediaSample, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(GetPointer)(THIS_ BYTE **) PURE;\r
+    STDMETHOD_(long, GetSize)(THIS) PURE;\r
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;\r
+    STDMETHOD(SetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;\r
+    STDMETHOD(IsSyncPoint)(THIS) PURE;\r
+    STDMETHOD(SetSyncPoint)(THIS_ BOOL) PURE;\r
+    STDMETHOD(IsPreroll)(THIS) PURE;\r
+    STDMETHOD(SetPreroll)(THIS_ BOOL) PURE;\r
+    STDMETHOD_(long, GetActualDataLength)(THIS) PURE;\r
+    STDMETHOD(SetActualDataLength)(THIS_ long) PURE;\r
+    STDMETHOD(GetMediaType)(THIS_ AM_MEDIA_TYPE **) PURE;\r
+    STDMETHOD(SetMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(IsDiscontinuity)(THIS) PURE;\r
+    STDMETHOD(SetDiscontinuity)(THIS_ BOOL) PURE;\r
+    STDMETHOD(GetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;\r
+    STDMETHOD(SetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IMemAllocator\r
+DECLARE_INTERFACE_(IMemAllocator, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(SetProperties)(THIS_ ALLOCATOR_PROPERTIES *, ALLOCATOR_PROPERTIES *) PURE;\r
+    STDMETHOD(GetProperties)(THIS_ ALLOCATOR_PROPERTIES *) PURE;\r
+    STDMETHOD(Commit)(THIS) PURE;\r
+    STDMETHOD(Decommit)(THIS) PURE;\r
+    STDMETHOD(GetBuffer)(THIS_ IMediaSample **, REFERENCE_TIME *, REFERENCE_TIME *, DWORD) PURE;\r
+    STDMETHOD(ReleaseBuffer)(THIS_ IMediaSample *) PURE;\r
+\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IMemInputPin\r
+DECLARE_INTERFACE_(IMemInputPin, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(GetAllocator)(THIS_ IMemAllocator **) PURE;\r
+    STDMETHOD(NotifyAllocator)(THIS_ IMemAllocator *, BOOL) PURE;\r
+    STDMETHOD(GetAllocatorRequirements)(THIS_ ALLOCATOR_PROPERTIES *) PURE;\r
+    STDMETHOD(Receive)(THIS_ IMediaSample *) PURE;\r
+    STDMETHOD(ReceiveMultiple)(THIS_ IMediaSample **, long, long *) PURE;\r
+    STDMETHOD(ReceiveCanBlock)(THIS) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IFileSinkFilter\r
+DECLARE_INTERFACE_(IFileSinkFilter, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(SetFileName)(THIS_ LPCOLESTR,const AM_MEDIA_TYPE *) PURE;\r
+    STDMETHOD(GetCurFile)(THIS_ LPOLESTR *,AM_MEDIA_TYPE*) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE ICaptureGraphBuilder2\r
+DECLARE_INTERFACE_(ICaptureGraphBuilder2, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(SetFiltergraph)(THIS_ IGraphBuilder*) PURE;\r
+    STDMETHOD(GetFiltergraph)(THIS_ IGraphBuilder**) PURE;\r
+    STDMETHOD(SetOutputFileName)(THIS_ const GUID*,LPCOLESTR,IBaseFilter**,IFileSinkFilter**) PURE;\r
+    STDMETHOD(FindInterface)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFIID,void**) PURE;\r
+    STDMETHOD(RenderStream)(THIS_ const GUID*,const GUID*,IUnknown*,IBaseFilter*,IBaseFilter*) PURE;\r
+    STDMETHOD(ControlStream)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFERENCE_TIME*,REFERENCE_TIME*,WORD,WORD) PURE;\r
+    STDMETHOD(AllocCapFile)(THIS_ LPCOLESTR,DWORDLONG) PURE;\r
+    STDMETHOD(CopyCaptureFile)(THIS_ LPOLESTR,LPOLESTR,int,IAMCopyCaptureFileProgress*) PURE;\r
+    STDMETHOD(FindPin)(THIS_ IUnknown*,PIN_DIRECTION,const GUID*,const GUID*,BOOL,int,IPin**) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IAMStreamConfig\r
+DECLARE_INTERFACE_(IAMStreamConfig, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+    STDMETHOD(SetFormat)(THIS_ AM_MEDIA_TYPE*) PURE;\r
+    STDMETHOD(GetFormat)(THIS_ AM_MEDIA_TYPE**) PURE;\r
+    STDMETHOD(GetNumberOfCapabilities)(THIS_ int*,int*) PURE;\r
+    STDMETHOD(GetStreamCaps)(THIS_ int,AM_MEDIA_TYPE**,BYTE*) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IAMVideoProcAmp\r
+DECLARE_INTERFACE_(IAMVideoProcAmp, IUnknown)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(GetRange)(THIS_ long,long*,long*,long*,long*,long*) PURE;\r
+       STDMETHOD(Set)(THIS_ long,long,long) PURE;\r
+       STDMETHOD(Get)(THIS_ long,long*,long*) PURE;\r
+};\r
+#undef INTERFACE\r
+#define INTERFACE IMediaControl\r
+DECLARE_INTERFACE_(IMediaControl, IDispatch)\r
+{\r
+       STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
+       STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
+       STDMETHOD_(ULONG,Release)(THIS) PURE;\r
+       STDMETHOD(GetTypeInfoCount)(THIS_ UINT*);\r
+       STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,ITypeInfo**);\r
+       STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*);\r
+       STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);\r
+       STDMETHOD(Run)(THIS);\r
+       STDMETHOD(Pause)(THIS);\r
+       STDMETHOD(Stop)(THIS);\r
+       STDMETHOD(GetState)(THIS_ LONG, OAFilterState*);\r
+       STDMETHOD(RenderFile)(THIS_ BSTR);\r
+       STDMETHOD(AddSourceFilter)(THIS_ BSTR,IDispatch**);\r
+       STDMETHOD(get_FilterCollection)(THIS_ IDispatch**);\r
+       STDMETHOD(get_RegFilterCollection)(THIS_ IDispatch**);\r
+       STDMETHOD(StopWhenReady)(THIS);\r
+};\r
+#undef INTERFACE\r
+\r
+#ifdef COBJMACROS\r
+#define ICreateDevEnum_QueryInterface(This,riid,ppvObject)     \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define ICreateDevEnum_AddRef(This)    \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define ICreateDevEnum_Release(This)   \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define ICreateDevEnum_CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags)      \\r
+    ( (This)->lpVtbl -> CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IPin_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IPin_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IPin_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IPin_Connect(This,pReceivePin,pmt)     \\r
+    ( (This)->lpVtbl -> Connect(This,pReceivePin,pmt) )\r
+#define IPin_ReceiveConnection(This,pConnector,pmt)    \\r
+    ( (This)->lpVtbl -> ReceiveConnection(This,pConnector,pmt) )\r
+#define IPin_Disconnect(This)  \\r
+    ( (This)->lpVtbl -> Disconnect(This) )\r
+#define IPin_ConnectedTo(This,pPin)    \\r
+    ( (This)->lpVtbl -> ConnectedTo(This,pPin) )\r
+#define IPin_ConnectionMediaType(This,pmt)     \\r
+    ( (This)->lpVtbl -> ConnectionMediaType(This,pmt) )\r
+#define IPin_QueryPinInfo(This,pInfo)  \\r
+    ( (This)->lpVtbl -> QueryPinInfo(This,pInfo) )\r
+#define IPin_QueryDirection(This,pPinDir)      \\r
+    ( (This)->lpVtbl -> QueryDirection(This,pPinDir) )\r
+#define IPin_QueryId(This,Id)  \\r
+    ( (This)->lpVtbl -> QueryId(This,Id) )\r
+#define IPin_QueryAccept(This,pmt)     \\r
+    ( (This)->lpVtbl -> QueryAccept(This,pmt) )\r
+#define IPin_EnumMediaTypes(This,ppEnum)       \\r
+    ( (This)->lpVtbl -> EnumMediaTypes(This,ppEnum) )\r
+#define IPin_QueryInternalConnections(This,apPin,nPin) \\r
+    ( (This)->lpVtbl -> QueryInternalConnections(This,apPin,nPin) )\r
+#define IPin_EndOfStream(This) \\r
+    ( (This)->lpVtbl -> EndOfStream(This) )\r
+#define IPin_BeginFlush(This)  \\r
+    ( (This)->lpVtbl -> BeginFlush(This) )\r
+#define IPin_EndFlush(This)    \\r
+    ( (This)->lpVtbl -> EndFlush(This) )\r
+#define IPin_NewSegment(This,tStart,tStop,dRate)       \\r
+    ( (This)->lpVtbl -> NewSegment(This,tStart,tStop,dRate) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IEnumPins_QueryInterface(This,riid,ppvObject)  \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IEnumPins_AddRef(This) \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IEnumPins_Release(This)        \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IEnumPins_Next(This,cPins,ppPins,pcFetched)    \\r
+    ( (This)->lpVtbl -> Next(This,cPins,ppPins,pcFetched) )\r
+#define IEnumPins_Skip(This,cPins)     \\r
+    ( (This)->lpVtbl -> Skip(This,cPins) )\r
+#define IEnumPins_Reset(This)  \\r
+    ( (This)->lpVtbl -> Reset(This) )\r
+#define IEnumPins_Clone(This,ppEnum)   \\r
+    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IAMStreamConfig_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IAMStreamConfig_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IAMStreamConfig_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IAMStreamConfig_SetFormat(This,pmt)    \\r
+    ( (This)->lpVtbl -> SetFormat(This,pmt) )\r
+#define IAMStreamConfig_GetFormat(This,ppmt)   \\r
+    ( (This)->lpVtbl -> GetFormat(This,ppmt) )\r
+#define IAMStreamConfig_GetNumberOfCapabilities(This,piCount,piSize)   \\r
+    ( (This)->lpVtbl -> GetNumberOfCapabilities(This,piCount,piSize) )\r
+#define IAMStreamConfig_GetStreamCaps(This,iIndex,ppmt,pSCC)   \\r
+    ( (This)->lpVtbl -> GetStreamCaps(This,iIndex,ppmt,pSCC) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IFilterGraph_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IFilterGraph_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IFilterGraph_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IFilterGraph_AddFilter(This,pFilter,pName)     \\r
+    ( (This)->lpVtbl -> AddFilter(This,pFilter,pName) )\r
+#define IFilterGraph_RemoveFilter(This,pFilter)        \\r
+    ( (This)->lpVtbl -> RemoveFilter(This,pFilter) )\r
+#define IFilterGraph_EnumFilters(This,ppEnum)  \\r
+    ( (This)->lpVtbl -> EnumFilters(This,ppEnum) )\r
+#define IFilterGraph_FindFilterByName(This,pName,ppFilter)     \\r
+    ( (This)->lpVtbl -> FindFilterByName(This,pName,ppFilter) )\r
+#define IFilterGraph_ConnectDirect(This,ppinOut,ppinIn,pmt)    \\r
+    ( (This)->lpVtbl -> ConnectDirect(This,ppinOut,ppinIn,pmt) )\r
+#define IFilterGraph_Reconnect(This,ppin)      \\r
+    ( (This)->lpVtbl -> Reconnect(This,ppin) )\r
+#define IFilterGraph_Disconnect(This,ppin)     \\r
+    ( (This)->lpVtbl -> Disconnect(This,ppin) )\r
+#define IFilterGraph_SetDefaultSyncSource(This)        \\r
+    ( (This)->lpVtbl -> SetDefaultSyncSource(This) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IMediaFilter_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IMediaFilter_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IMediaFilter_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IMediaFilter_GetClassID(This,pClassID) \\r
+    ( (This)->lpVtbl -> GetClassID(This,pClassID) )\r
+#define IMediaFilter_Stop(This)        \\r
+    ( (This)->lpVtbl -> Stop(This) )\r
+#define IMediaFilter_Pause(This)       \\r
+    ( (This)->lpVtbl -> Pause(This) )\r
+#define IMediaFilter_Run(This,tStart)  \\r
+    ( (This)->lpVtbl -> Run(This,tStart) )\r
+#define IMediaFilter_GetState(This,dwMilliSecsTimeout,State)   \\r
+    ( (This)->lpVtbl -> GetState(This,dwMilliSecsTimeout,State) )\r
+#define IMediaFilter_SetSyncSource(This,pClock)        \\r
+    ( (This)->lpVtbl -> SetSyncSource(This,pClock) )\r
+#define IMediaFilter_GetSyncSource(This,pClock)        \\r
+    ( (This)->lpVtbl -> GetSyncSource(This,pClock) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IBaseFilter_QueryInterface(This,riid,ppvObject)        \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IBaseFilter_AddRef(This)       \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IBaseFilter_Release(This)      \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IBaseFilter_GetClassID(This,pClassID)  \\r
+    ( (This)->lpVtbl -> GetClassID(This,pClassID) )\r
+#define IBaseFilter_Stop(This) \\r
+    ( (This)->lpVtbl -> Stop(This) )\r
+#define IBaseFilter_Pause(This)        \\r
+    ( (This)->lpVtbl -> Pause(This) )\r
+#define IBaseFilter_Run(This,tStart)   \\r
+    ( (This)->lpVtbl -> Run(This,tStart) )\r
+#define IBaseFilter_GetState(This,dwMilliSecsTimeout,State)    \\r
+    ( (This)->lpVtbl -> GetState(This,dwMilliSecsTimeout,State) )\r
+#define IBaseFilter_SetSyncSource(This,pClock) \\r
+    ( (This)->lpVtbl -> SetSyncSource(This,pClock) )\r
+#define IBaseFilter_GetSyncSource(This,pClock) \\r
+    ( (This)->lpVtbl -> GetSyncSource(This,pClock) )\r
+#define IBaseFilter_EnumPins(This,ppEnum)      \\r
+    ( (This)->lpVtbl -> EnumPins(This,ppEnum) )\r
+#define IBaseFilter_FindPin(This,Id,ppPin)     \\r
+    ( (This)->lpVtbl -> FindPin(This,Id,ppPin) )\r
+#define IBaseFilter_QueryFilterInfo(This,pInfo)        \\r
+    ( (This)->lpVtbl -> QueryFilterInfo(This,pInfo) )\r
+#define IBaseFilter_JoinFilterGraph(This,pGraph,pName) \\r
+    ( (This)->lpVtbl -> JoinFilterGraph(This,pGraph,pName) )\r
+#define IBaseFilter_QueryVendorInfo(This,pVendorInfo)  \\r
+    ( (This)->lpVtbl -> QueryVendorInfo(This,pVendorInfo) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IMediaSample_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IMediaSample_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IMediaSample_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IMediaSample_GetPointer(This,ppBuffer) \\r
+    ( (This)->lpVtbl -> GetPointer(This,ppBuffer) )\r
+#define IMediaSample_GetSize(This)     \\r
+               ( (This)->lpVtbl -> GetSize(This) )\r
+#define IMediaSample_GetTime(This,pTimeStart,pTimeEnd) \\r
+    ( (This)->lpVtbl -> GetTime(This,pTimeStart,pTimeEnd) )\r
+#define IMediaSample_SetTime(This,pTimeStart,pTimeEnd) \\r
+    ( (This)->lpVtbl -> SetTime(This,pTimeStart,pTimeEnd) )\r
+#define IMediaSample_IsSyncPoint(This) \\r
+    ( (This)->lpVtbl -> IsSyncPoint(This) )\r
+#define IMediaSample_SetSyncPoint(This,bIsSyncPoint)   \\r
+    ( (This)->lpVtbl -> SetSyncPoint(This,bIsSyncPoint) )\r
+#define IMediaSample_IsPreroll(This)   \\r
+    ( (This)->lpVtbl -> IsPreroll(This) )\r
+#define IMediaSample_SetPreroll(This,bIsPreroll)       \\r
+    ( (This)->lpVtbl -> SetPreroll(This,bIsPreroll) )\r
+#define IMediaSample_GetActualDataLength(This) \\r
+    ( (This)->lpVtbl -> GetActualDataLength(This) )\r
+#define IMediaSample_SetActualDataLength(This,length)  \\r
+    ( (This)->lpVtbl -> SetActualDataLength(This,length) )\r
+#define IMediaSample_GetMediaType(This,ppMediaType)    \\r
+    ( (This)->lpVtbl -> GetMediaType(This,ppMediaType) )\r
+#define IMediaSample_SetMediaType(This,pMediaType)     \\r
+    ( (This)->lpVtbl -> SetMediaType(This,pMediaType) )\r
+#define IMediaSample_IsDiscontinuity(This)     \\r
+    ( (This)->lpVtbl -> IsDiscontinuity(This) )\r
+#define IMediaSample_SetDiscontinuity(This,bDiscontinuity)     \\r
+    ( (This)->lpVtbl -> SetDiscontinuity(This,bDiscontinuity) )\r
+#define IMediaSample_GetMediaTime(This,pTimeStart,pTimeEnd)    \\r
+    ( (This)->lpVtbl -> GetMediaTime(This,pTimeStart,pTimeEnd) )\r
+#define IMediaSample_SetMediaTime(This,pTimeStart,pTimeEnd)    \\r
+    ( (This)->lpVtbl -> SetMediaTime(This,pTimeStart,pTimeEnd) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IEnumFilters_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IEnumFilters_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IEnumFilters_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IEnumFilters_Next(This,cFilters,ppFilter,pcFetched)    \\r
+    ( (This)->lpVtbl -> Next(This,cFilters,ppFilter,pcFetched) )\r
+#define IEnumFilters_Skip(This,cFilters)       \\r
+    ( (This)->lpVtbl -> Skip(This,cFilters) )\r
+#define IEnumFilters_Reset(This)       \\r
+    ( (This)->lpVtbl -> Reset(This) )\r
+#define IEnumFilters_Clone(This,ppEnum)        \\r
+    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IMemAllocator_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IMemAllocator_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IMemAllocator_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IMemAllocator_SetProperties(This,pRequest,pActual)     \\r
+    ( (This)->lpVtbl -> SetProperties(This,pRequest,pActual) )\r
+#define IMemAllocator_GetProperties(This,pProps)       \\r
+    ( (This)->lpVtbl -> GetProperties(This,pProps) )\r
+#define IMemAllocator_Commit(This)     \\r
+    ( (This)->lpVtbl -> Commit(This) )\r
+#define IMemAllocator_Decommit(This)   \\r
+    ( (This)->lpVtbl -> Decommit(This) )\r
+#define IMemAllocator_GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags)     \\r
+    ( (This)->lpVtbl -> GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags) )\r
+#define IMemAllocator_ReleaseBuffer(This,pBuffer)      \\r
+    ( (This)->lpVtbl -> ReleaseBuffer(This,pBuffer) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IMemInputPin_QueryInterface(This,riid,ppvObject)       \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IMemInputPin_AddRef(This)      \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IMemInputPin_Release(This)     \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IMemInputPin_GetAllocator(This,ppAllocator)    \\r
+    ( (This)->lpVtbl -> GetAllocator(This,ppAllocator) )\r
+#define IMemInputPin_NotifyAllocator(This,pAllocator,bReadOnly)        \\r
+    ( (This)->lpVtbl -> NotifyAllocator(This,pAllocator,bReadOnly) )\r
+#define IMemInputPin_GetAllocatorRequirements(This,pProps)     \\r
+    ( (This)->lpVtbl -> GetAllocatorRequirements(This,pProps) )\r
+#define IMemInputPin_Receive(This,pSample)     \\r
+    ( (This)->lpVtbl -> Receive(This,pSample) )\r
+#define IMemInputPin_ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed) \\r
+    ( (This)->lpVtbl -> ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed) )\r
+#define IMemInputPin_ReceiveCanBlock(This)     \\r
+    ( (This)->lpVtbl -> ReceiveCanBlock(This) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IGraphBuilder_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IGraphBuilder_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IGraphBuilder_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IGraphBuilder_AddFilter(This,pFilter,pName)    \\r
+    ( (This)->lpVtbl -> AddFilter(This,pFilter,pName) )\r
+#define IGraphBuilder_RemoveFilter(This,pFilter)       \\r
+    ( (This)->lpVtbl -> RemoveFilter(This,pFilter) )\r
+#define IGraphBuilder_EnumFilters(This,ppEnum) \\r
+    ( (This)->lpVtbl -> EnumFilters(This,ppEnum) )\r
+#define IGraphBuilder_FindFilterByName(This,pName,ppFilter)    \\r
+    ( (This)->lpVtbl -> FindFilterByName(This,pName,ppFilter) )\r
+#define IGraphBuilder_ConnectDirect(This,ppinOut,ppinIn,pmt)   \\r
+    ( (This)->lpVtbl -> ConnectDirect(This,ppinOut,ppinIn,pmt) )\r
+#define IGraphBuilder_Reconnect(This,ppin)     \\r
+    ( (This)->lpVtbl -> Reconnect(This,ppin) )\r
+#define IGraphBuilder_Disconnect(This,ppin)    \\r
+    ( (This)->lpVtbl -> Disconnect(This,ppin) )\r
+#define IGraphBuilder_SetDefaultSyncSource(This)       \\r
+    ( (This)->lpVtbl -> SetDefaultSyncSource(This) )\r
+#define IGraphBuilder_Connect(This,ppinOut,ppinIn)     \\r
+    ( (This)->lpVtbl -> Connect(This,ppinOut,ppinIn) )\r
+#define IGraphBuilder_Render(This,ppinOut)     \\r
+    ( (This)->lpVtbl -> Render(This,ppinOut) )\r
+#define IGraphBuilder_RenderFile(This,lpcwstrFile,lpcwstrPlayList)     \\r
+    ( (This)->lpVtbl -> RenderFile(This,lpcwstrFile,lpcwstrPlayList) )\r
+#define IGraphBuilder_AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter) \\r
+    ( (This)->lpVtbl -> AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter) )\r
+#define IGraphBuilder_SetLogFile(This,hFile)   \\r
+    ( (This)->lpVtbl -> SetLogFile(This,hFile) )\r
+#define IGraphBuilder_Abort(This)      \\r
+    ( (This)->lpVtbl -> Abort(This) )\r
+#define IGraphBuilder_ShouldOperationContinue(This)    \\r
+    ( (This)->lpVtbl -> ShouldOperationContinue(This) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IEnumMediaTypes_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IEnumMediaTypes_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IEnumMediaTypes_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IEnumMediaTypes_Next(This,cMediaTypes,ppMediaTypes,pcFetched)  \\r
+    ( (This)->lpVtbl -> Next(This,cMediaTypes,ppMediaTypes,pcFetched) )\r
+#define IEnumMediaTypes_Skip(This,cMediaTypes) \\r
+    ( (This)->lpVtbl -> Skip(This,cMediaTypes) )\r
+#define IEnumMediaTypes_Reset(This)    \\r
+    ( (This)->lpVtbl -> Reset(This) )\r
+#define IEnumMediaTypes_Clone(This,ppEnum)     \\r
+    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IMediaControl_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IMediaControl_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IMediaControl_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IMediaControl_GetTypeInfoCount(This,pctinfo)   \\r
+    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )\r
+#define IMediaControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo)    \\r
+    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )\r
+#define IMediaControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)  \\r
+    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )\r
+#define IMediaControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)    \\r
+    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )\r
+#define IMediaControl_Run(This)        \\r
+    ( (This)->lpVtbl -> Run(This) )\r
+#define IMediaControl_Pause(This)      \\r
+    ( (This)->lpVtbl -> Pause(This) )\r
+#define IMediaControl_Stop(This)       \\r
+    ( (This)->lpVtbl -> Stop(This) )\r
+#define IMediaControl_GetState(This,msTimeout,pfs)     \\r
+    ( (This)->lpVtbl -> GetState(This,msTimeout,pfs) )\r
+#define IMediaControl_RenderFile(This,strFilename)     \\r
+    ( (This)->lpVtbl -> RenderFile(This,strFilename) )\r
+#define IMediaControl_AddSourceFilter(This,strFilename,ppUnk)  \\r
+    ( (This)->lpVtbl -> AddSourceFilter(This,strFilename,ppUnk) )\r
+#define IMediaControl_get_FilterCollection(This,ppUnk) \\r
+    ( (This)->lpVtbl -> get_FilterCollection(This,ppUnk) )\r
+#define IMediaControl_get_RegFilterCollection(This,ppUnk)      \\r
+    ( (This)->lpVtbl -> get_RegFilterCollection(This,ppUnk) )\r
+#define IMediaControl_StopWhenReady(This)      \\r
+    ( (This)->lpVtbl -> StopWhenReady(This) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IAMVideoProcAmp_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IAMVideoProcAmp_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IAMVideoProcAmp_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IAMVideoProcAmp_GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags)   \\r
+    ( (This)->lpVtbl -> GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags) )\r
+#define IAMVideoProcAmp_Set(This,Property,lValue,Flags)        \\r
+    ( (This)->lpVtbl -> Set(This,Property,lValue,Flags) )\r
+#define IAMVideoProcAmp_Get(This,Property,lValue,Flags)        \\r
+    ( (This)->lpVtbl -> Get(This,Property,lValue,Flags) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IFileSinkFilter_QueryInterface(This,riid,ppvObject)    \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IFileSinkFilter_AddRef(This)   \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IFileSinkFilter_Release(This)  \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IFileSinkFilter_SetFileName(This,pszFileName,pmt)      \\r
+    ( (This)->lpVtbl -> SetFileName(This,pszFileName,pmt) )\r
+#define IFileSinkFilter_GetCurFile(This,ppszFileName,pmt)      \\r
+    ( (This)->lpVtbl -> GetCurFile(This,ppszFileName,pmt) )\r
+#endif /* COBJMACROS */\r
+\r
+#ifdef COBJMACROS\r
+#define IAMCopyCaptureFileProgress_QueryInterface(This,riid,ppvObject) \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define IAMCopyCaptureFileProgress_AddRef(This)        \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define IAMCopyCaptureFileProgress_Release(This)       \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define IAMCopyCaptureFileProgress_Progress(This,iProgress)    \\r
+    ( (This)->lpVtbl -> Progress(This,iProgress) )\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#ifdef COBJMACROS\r
+#define ICaptureGraphBuilder2_QueryInterface(This,riid,ppvObject)      \\r
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
+#define ICaptureGraphBuilder2_AddRef(This)     \\r
+    ( (This)->lpVtbl -> AddRef(This) )\r
+#define ICaptureGraphBuilder2_Release(This)    \\r
+    ( (This)->lpVtbl -> Release(This) )\r
+#define ICaptureGraphBuilder2_SetFiltergraph(This,pfg) \\r
+    ( (This)->lpVtbl -> SetFiltergraph(This,pfg) )\r
+#define ICaptureGraphBuilder2_GetFiltergraph(This,ppfg)        \\r
+    ( (This)->lpVtbl -> GetFiltergraph(This,ppfg) )\r
+#define ICaptureGraphBuilder2_SetOutputFileName(This,pType,lpstrFile,ppf,ppSink)       \\r
+    ( (This)->lpVtbl -> SetOutputFileName(This,pType,lpstrFile,ppf,ppSink) )\r
+#define ICaptureGraphBuilder2_FindInterface(This,pCategory,pType,pf,riid,ppint)        \\r
+    ( (This)->lpVtbl -> FindInterface(This,pCategory,pType,pf,riid,ppint) )\r
+#define ICaptureGraphBuilder2_RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer)       \\r
+    ( (This)->lpVtbl -> RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer) )\r
+#define ICaptureGraphBuilder2_ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie)        \\r
+    ( (This)->lpVtbl -> ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) )\r
+#define ICaptureGraphBuilder2_AllocCapFile(This,lpstr,dwlSize) \\r
+    ( (This)->lpVtbl -> AllocCapFile(This,lpstr,dwlSize) )\r
+#define ICaptureGraphBuilder2_CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback)       \\r
+    ( (This)->lpVtbl -> CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback) )\r
+#define ICaptureGraphBuilder2_FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin)      \\r
+    ( (This)->lpVtbl -> FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin) )\r
+#endif /* COBJMACROS */\r
+\r
+#endif // _MARU_CAMERA_INTERFACE_H_\r
index 9dcb38c..aeae0bd 100644 (file)
-/*
- * Implementation of MARU Virtual Camera device by PCI bus on Windows.
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#include "qemu-common.h"
-#include "maru_camera_common.h"
-#include "pci.h"
-#include "kvm.h"
-#include "tizen/src/debug_ch.h"
-
-#include "windows.h"
-#include "basetyps.h"
-#include "mmsystem.h"
-
-MULTI_DEBUG_CHANNEL(tizen, camera_win32);
-
-// V4L2 defines copy from videodev2.h
-#define V4L2_CTRL_FLAG_SLIDER          0x0020
-
-#define V4L2_CTRL_CLASS_USER           0x00980000
-#define V4L2_CID_BASE                          (V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_BRIGHTNESS                    (V4L2_CID_BASE+0)
-#define V4L2_CID_CONTRAST                      (V4L2_CID_BASE+1)
-#define V4L2_CID_SATURATION                    (V4L2_CID_BASE+2)
-#define V4L2_CID_SHARPNESS                     (V4L2_CID_BASE+27)
-
-#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
-#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
-
-enum {
-       HWC_OPEN,
-       HWC_CLOSE,
-       HWC_START,
-       HWC_STOP,
-       HWC_S_FPS,
-       HWC_G_FPS,
-       HWC_S_FMT,
-       HWC_G_FMT,
-       HWC_TRY_FMT,
-       HWC_ENUM_FMT,
-       HWC_QCTRL,
-       HWC_S_CTRL,
-       HWC_G_CTRL,
-       HWC_ENUM_FSIZES,
-       HWC_ENUM_INTERVALS
-};
-
-typedef enum tagVideoProcAmpProperty {
-  VideoProcAmp_Brightness,
-  VideoProcAmp_Contrast,
-  VideoProcAmp_Hue,
-  VideoProcAmp_Saturation,
-  VideoProcAmp_Sharpness,
-  VideoProcAmp_Gamma,
-  VideoProcAmp_ColorEnable,
-  VideoProcAmp_WhiteBalance,
-  VideoProcAmp_BacklightCompensation,
-  VideoProcAmp_Gain
-} VideoProcAmpProperty;
-
-typedef struct tagHWCParam {
-       long val1;
-       long val2;
-       long val3;
-       long val4;
-       long val5;
-} HWCParam;
-
-typedef struct tagMaruCamConvertPixfmt {
-       uint32_t fmt;   /* fourcc */
-       uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
-       uint32_t needs_conversion;
-} MaruCamConvertPixfmt;
-
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
-               { V4L2_PIX_FMT_YUYV, 16, 0 },
-               { V4L2_PIX_FMT_YUV420, 12, 0 },
-               { V4L2_PIX_FMT_YVU420, 12, 0 },
-};
-
-typedef struct tagMaruCamConvertFrameInfo {
-       uint32_t width;
-       uint32_t height;
-} MaruCamConvertFrameInfo;
-
-static MaruCamConvertFrameInfo supported_dst_frames[] = {
-               { 640, 480 },
-               { 352, 288 },
-               { 320, 240 },
-               { 176, 144 },
-               { 160, 120 },
-};
-
-#define MARUCAM_CTRL_VALUE_MAX         20
-#define MARUCAM_CTRL_VALUE_MIN         1
-#define MARUCAM_CTRL_VALUE_MID         10
-#define MARUCAM_CTRL_VALUE_STEP                1
-
-struct marucam_qctrl {
-       uint32_t id;
-       uint32_t hit;
-       long min;
-       long max;
-       long step;
-       long init_val;
-};
-
-static struct marucam_qctrl qctrl_tbl[] = {
-       { V4L2_CID_BRIGHTNESS, 0, },
-       { V4L2_CID_CONTRAST, 0, },
-       { V4L2_CID_SATURATION,0, },
-       { V4L2_CID_SHARPNESS, 0, },
-};
-
-typedef int (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);
-typedef HRESULT (STDAPICALLTYPE *CTRLFN)(UINT, UINT, LPVOID);
-typedef HRESULT (STDAPICALLTYPE *SETCALLBACKFN)(CallbackFn);
-
-
-static HINSTANCE g_hInst = NULL;
-static MaruCamState *g_state = NULL;
-
-static CTRLFN MaruCamCtrl;
-static SETCALLBACKFN MaruCamSetCallbackFn;
-
-static uint32_t cur_fmt_idx = 0;
-static uint32_t cur_frame_idx = 0;
-
-void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
-               uint32_t width, uint32_t height, uint32_t yvu);
-
-
-static long value_convert_from_guest(long min, long max, long value)
-{
-       double rate = 0.0;
-       long dist = 0, ret = 0;
-
-       dist = max - min;
-
-       if (dist < MARUCAM_CTRL_VALUE_MAX) {
-               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-               ret = min + (int32_t)(value / rate);
-       } else {
-               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-               ret = min + (int32_t)(rate * value);
-       }
-       return ret;
-}
-
-static long value_convert_to_guest(long min, long max, long value)
-{
-       double rate  = 0.0;
-       long dist = 0, ret = 0;
-
-       dist = max - min;
-
-       if (dist < MARUCAM_CTRL_VALUE_MAX) {
-               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-               ret = (int32_t)((double)(value - min) * rate);
-       } else {
-               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-               ret = (int32_t)((double)(value - min) / rate);
-       }
-
-       return ret;
-}
-
-static int STDAPICALLTYPE marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)
-{
-       static uint32_t index = 0;
-       uint32_t width, height;
-       width = supported_dst_frames[cur_frame_idx].width;
-       height = supported_dst_frames[cur_frame_idx].height;
-       void *buf = g_state->vaddr + (g_state->buf_size * index);
-
-       switch (supported_dst_pixfmts[cur_fmt_idx].fmt) {
-       case V4L2_PIX_FMT_YUV420:
-               v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 0);
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 1);
-               break;
-       case V4L2_PIX_FMT_YUYV:
-               memcpy(buf, (void*)pBuffer, dwSize);
-               break;
-       }
-       index = !index;
-
-       if (g_state->req_frame) {
-               qemu_irq_raise(g_state->dev.irq[2]);
-               g_state->req_frame = 0;
-       }
-       return 1;
-}
-
-// MARUCAM_CMD_INIT
-void marucam_device_init(MaruCamState* state)
-{
-       MaruCamThreadInfo *thread = state->thread;
-
-       pthread_cond_init(&thread->thread_cond, NULL);
-       pthread_mutex_init(&thread->mutex_lock, NULL);
-
-       g_state = state;
-}
-
-// MARUCAM_CMD_OPEN
-void marucam_device_open(MaruCamState* state)
-{
-       HRESULT hr;
-       MaruCamParam *param = state->thread->param;
-       param->top = 0;
-
-       g_hInst = LoadLibrary("hwcfilter.dll");
-
-       if (!g_hInst) {
-               g_hInst = LoadLibrary("bin\\hwcfilter.dll");
-               if (!g_hInst) {
-                       ERR("load library failed!!!!\n");
-                       param->errCode = EINVAL;
-                       return;
-               }
-       }
-
-       MaruCamCtrl = (CTRLFN)GetProcAddress(g_hInst, "HWCCtrl");
-       if (!MaruCamCtrl) {
-               ERR("HWCCtrl get failed!!!\n");
-               FreeLibrary(g_hInst);
-               param->errCode = EINVAL;
-               return;
-       }
-
-       MaruCamSetCallbackFn = (SETCALLBACKFN)GetProcAddress(g_hInst, "HWCSetCallback");
-       if (!MaruCamSetCallbackFn) {
-               ERR("HWCSetCallback get failed!!!\n");
-               FreeLibrary(g_hInst);
-               param->errCode = EINVAL;
-               return;
-       }
-
-       hr = MaruCamCtrl(HWC_OPEN, 0, NULL);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               FreeLibrary(g_hInst);
-               ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-               return;
-       }
-       hr = MaruCamSetCallbackFn((CallbackFn)marucam_device_callbackfn);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               MaruCamCtrl(HWC_CLOSE, 0, NULL);
-               FreeLibrary(g_hInst);
-               ERR("call back function set failed!!!, [HRESULT : 0x%x]\n", hr);
-       }
-
-       TRACE("camera device open success!!!, [HRESULT : 0x%x]\n", hr);
-}
-
-// MARUCAM_CMD_CLOSE
-void marucam_device_close(MaruCamState* state)
-{
-       HRESULT hr;
-       MaruCamParam *param = state->thread->param;
-       param->top = 0;
-       hr = MaruCamCtrl(HWC_CLOSE, 0, NULL);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("camera device close failed!!!, [HRESULT : 0x%x]\n", hr);
-       }
-       FreeLibrary(g_hInst);
-       TRACE("camera device close success!!!, [HRESULT : 0x%x]\n", hr);
-}
-
-// MARUCAM_CMD_START_PREVIEW
-void marucam_device_start_preview(MaruCamState* state)
-{
-       HRESULT hr;
-       uint32_t width, height;
-       MaruCamParam *param = state->thread->param;
-       TRACE("marucam_device_start_preview\n");
-       param->top = 0;
-       hr = MaruCamCtrl(HWC_START, 0, NULL);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("start preview failed!!!, [HRESULT : 0x%x]\n", hr);
-               return;
-       }
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       state->streamon = 1;
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-
-       width = supported_dst_frames[cur_frame_idx].width;
-       height = supported_dst_frames[cur_frame_idx].height;
-       state->buf_size = height * ((width * supported_dst_pixfmts[cur_fmt_idx].bpp) >> 3);
-}
-
-// MARUCAM_CMD_STOP_PREVIEW
-void marucam_device_stop_preview(MaruCamState* state)
-{
-       HRESULT hr;
-       MaruCamParam *param = state->thread->param;
-       TRACE("marucam_device_stop_preview\n");
-       param->top = 0;
-       hr = MaruCamCtrl(HWC_STOP, 0, NULL);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("stop preview failed!!!, [HRESULT : 0x%x]\n", hr);
-       }
-       pthread_mutex_lock(&state->thread->mutex_lock);
-       state->streamon = 0;
-       pthread_mutex_unlock(&state->thread->mutex_lock);
-       state->buf_size = 0;
-}
-
-// MARUCAM_CMD_S_PARAM
-void marucam_device_s_param(MaruCamState* state)
-{
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       TRACE("setting fps : %d/%d\n", param->stack[0], param->stack[1]);
-}
-
-// MARUCAM_CMD_G_PARAM
-void marucam_device_g_param(MaruCamState* state)
-{
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       TRACE("getting fps : 30/1\n");
-
-       param->stack[0] = 0x1000; // V4L2_CAP_TIMEPERFRAME
-       param->stack[1] = 1; // numerator;
-       param->stack[2] = 30; // denominator;
-}
-
-// MARUCAM_CMD_S_FMT
-void marucam_device_s_fmt(MaruCamState* state)
-{
-       uint32_t width, height, pixfmt, pidx, fidx;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       width = param->stack[0];                // width
-       height = param->stack[1];               // height
-       pixfmt = param->stack[2];               // pixelformat
-
-       for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
-               if ((supported_dst_frames[fidx].width == width) &&
-                               (supported_dst_frames[fidx].height == height)) {
-                       break;
-               }
-       }
-       if (fidx == ARRAY_SIZE(supported_dst_frames)) {
-               param->errCode = EINVAL;
-               return;
-       }
-       for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
-               if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
-                       break;
-               }
-       }
-       if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
-               param->errCode = EINVAL;
-               return;
-       }
-
-       if ((supported_dst_frames[cur_frame_idx].width != width) &&
-                       (supported_dst_frames[cur_frame_idx].height != height)) {
-               HWCParam inParam = {0,};
-               inParam.val1 = width;
-               inParam.val2 = height;
-               HRESULT hr = MaruCamCtrl(HWC_S_FMT, sizeof(HWCParam), &inParam);
-               if (FAILED(hr)) {
-                       param->errCode = EINVAL;
-                       return;
-               }
-       }
-
-       param->stack[0] = width;
-       param->stack[1] = height;
-       param->stack[2] = 1; // V4L2_FIELD_NONE
-       param->stack[3] = pixfmt;
-       // bytes per line = (width * bpp) / 8
-       param->stack[4] = (width * supported_dst_pixfmts[pidx].bpp) >> 3;
-       param->stack[5] = param->stack[4] * height;     // height * bytesperline
-       param->stack[6] = 0;
-       param->stack[7] = 0;
-
-       cur_frame_idx = fidx;
-       cur_fmt_idx = pidx;
-}
-
-// MARUCAM_CMD_G_FMT
-void marucam_device_g_fmt(MaruCamState* state)
-{
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-
-       param->stack[0] = supported_dst_frames[cur_frame_idx].width;    // width
-       param->stack[1] = supported_dst_frames[cur_frame_idx].height;   // height
-       param->stack[2] = 1; // V4L2_FIELD_NONE
-       param->stack[3] = supported_dst_pixfmts[cur_fmt_idx].fmt;       // pixelformat
-       // bytes per line = (width * bpp) / 8
-       param->stack[4] = (param->stack[0] * supported_dst_pixfmts[cur_fmt_idx].bpp) >> 3;
-       param->stack[5] = param->stack[1] * param->stack[4];    // height * bytesperline
-       param->stack[6] = 0;
-       param->stack[7] = 0;
-}
-
-void marucam_device_try_fmt(MaruCamState* state)
-{
-       uint32_t width, height, pixfmt, i;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       width = param->stack[0];                // width
-       height = param->stack[1];               // height
-       pixfmt = param->stack[2];               // pixelformat
-
-       for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {
-               if ((supported_dst_frames[i].width == width) &&
-                               (supported_dst_frames[i].height == height)) {
-                       break;
-               }
-       }
-       if (i == ARRAY_SIZE(supported_dst_frames)) {
-               param->errCode = EINVAL;
-               return;
-       }
-       for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-               if (supported_dst_pixfmts[i].fmt == pixfmt) {
-                       break;
-               }
-       }
-       if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-               param->errCode = EINVAL;
-               return;
-       }
-
-       param->stack[0] = width;
-       param->stack[1] = height;
-       param->stack[2] = 1; // V4L2_FIELD_NONE
-       param->stack[3] = pixfmt;
-       // bytes per line = (width * bpp) / 8
-       param->stack[4] = (width * supported_dst_pixfmts[i].bpp) >> 3;
-       param->stack[5] = param->stack[4] * height;     // height * bytesperline
-       param->stack[6] = 0;
-       param->stack[7] = 0;
-}
-
-void marucam_device_enum_fmt(MaruCamState* state)
-{
-       uint32_t index;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       index = param->stack[0];
-
-       if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
-               param->errCode = EINVAL;
-               return;
-       }
-       param->stack[1] = 0;                                                    // flags = NONE;
-       param->stack[2] = supported_dst_pixfmts[index].fmt;     // pixelformat;
-       /* set description */
-       switch (supported_dst_pixfmts[index].fmt) {
-       case V4L2_PIX_FMT_YUYV:
-               memcpy(&param->stack[3], "YUY2", 32);
-               break;
-       case V4L2_PIX_FMT_YUV420:
-               memcpy(&param->stack[3], "YU12", 32);
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               memcpy(&param->stack[3], "YV12", 32);
-               break;
-       }
-}
-
-void marucam_device_qctrl(MaruCamState* state)
-{
-       HRESULT hr;
-       uint32_t id, i;
-       HWCParam inParam = {0,};
-       char name[32] = {0,};
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       id = param->stack[0];
-
-       switch (id) {
-       case V4L2_CID_BRIGHTNESS:
-               TRACE("V4L2_CID_BRIGHTNESS\n");
-               inParam.val1 = VideoProcAmp_Brightness;
-               memcpy((void*)name, (void*)"brightness", 32);
-               i = 0;
-               break;
-       case V4L2_CID_CONTRAST:
-               TRACE("V4L2_CID_CONTRAST\n");
-               inParam.val1 = VideoProcAmp_Contrast;
-               memcpy((void*)name, (void*)"contrast", 32);
-               i = 1;
-               break;
-       case V4L2_CID_SATURATION:
-               TRACE("V4L2_CID_SATURATION\n");
-               inParam.val1 = VideoProcAmp_Saturation;
-               memcpy((void*)name, (void*)"saturation", 32);
-               i = 2;
-               break;
-       case V4L2_CID_SHARPNESS:
-               TRACE("V4L2_CID_SHARPNESS\n");
-               inParam.val1 = VideoProcAmp_Sharpness;
-               memcpy((void*)name, (void*)"sharpness", 32);
-               i = 3;
-               break;
-       default:
-               param->errCode = EINVAL;
-               return;
-       }
-       hr = MaruCamCtrl(HWC_QCTRL, sizeof(inParam), &inParam);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);
-               return;
-       } else {
-               qctrl_tbl[i].hit = 1;
-               qctrl_tbl[i].min = inParam.val2;
-               qctrl_tbl[i].max = inParam.val3;
-               qctrl_tbl[i].step = inParam.val4;
-               qctrl_tbl[i].init_val = inParam.val5;
-
-               if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {
-                       inParam.val2 = 0;
-               } else {
-                       inParam.val2 = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;
-               }
-               hr = MaruCamCtrl(HWC_S_CTRL, sizeof(inParam), &inParam);
-               if (FAILED(hr)) {
-                       param->errCode = EINVAL;
-                       ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
-                       return;
-               }
-       }
-
-       param->stack[0] = id;
-       param->stack[1] = MARUCAM_CTRL_VALUE_MIN;       // minimum
-       param->stack[2] = MARUCAM_CTRL_VALUE_MAX;       // maximum
-       param->stack[3] = MARUCAM_CTRL_VALUE_STEP;// step
-       param->stack[4] = MARUCAM_CTRL_VALUE_MID;       // default_value
-       param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
-       /* name field setting */
-       memcpy(&param->stack[6], (void*)name, sizeof(name)/sizeof(name[0]));
-}
-
-void marucam_device_s_ctrl(MaruCamState* state)
-{
-       HRESULT hr;
-       uint32_t i;
-       HWCParam inParam = {0,};
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-
-       switch (param->stack[0]) {
-       case V4L2_CID_BRIGHTNESS:
-               i = 0;
-               inParam.val1 = VideoProcAmp_Brightness;
-               break;
-       case V4L2_CID_CONTRAST:
-               i = 1;
-               inParam.val1 = VideoProcAmp_Contrast;
-               break;
-       case V4L2_CID_SATURATION:
-               i = 2;
-               inParam.val1 = VideoProcAmp_Saturation;
-               break;
-       case V4L2_CID_SHARPNESS:
-               i = 3;
-               inParam.val1 = VideoProcAmp_Sharpness;
-               break;
-       default:
-               param->errCode = EINVAL;
-               return;
-       }
-       inParam.val2 = value_convert_from_guest(qctrl_tbl[i].min,
-                       qctrl_tbl[i].max, (long)param->stack[1]);
-       hr = MaruCamCtrl(HWC_S_CTRL, sizeof(inParam), &inParam);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
-               return;
-       }
-}
-
-void marucam_device_g_ctrl(MaruCamState* state)
-{
-       HRESULT hr;
-       uint32_t i;
-       HWCParam inParam = {0,};
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       switch (param->stack[0]) {
-       case V4L2_CID_BRIGHTNESS:
-               i = 0;
-               inParam.val1 = VideoProcAmp_Brightness;
-               break;
-       case V4L2_CID_CONTRAST:
-               i = 1;
-               inParam.val1 = VideoProcAmp_Contrast;
-               break;
-       case V4L2_CID_SATURATION:
-               i = 2;
-               inParam.val1 = VideoProcAmp_Saturation;
-               break;
-       case V4L2_CID_SHARPNESS:
-               i = 3;
-               inParam.val1 = VideoProcAmp_Sharpness;
-               break;
-       default:
-               param->errCode = EINVAL;
-               return;
-       }
-
-       hr = MaruCamCtrl(HWC_G_CTRL, sizeof(inParam), &inParam);
-       if (FAILED(hr)) {
-               param->errCode = EINVAL;
-               ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);
-               return;
-       }
-       param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,
-                               qctrl_tbl[i].max, inParam.val2);
-}
-
-void marucam_device_enum_fsizes(MaruCamState* state)
-{
-       uint32_t index, pixfmt, i;
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-       index = param->stack[0];
-       pixfmt = param->stack[1];
-
-       if (index >= ARRAY_SIZE(supported_dst_frames)) {
-               param->errCode = EINVAL;
-               return;
-       }
-       for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-               if (supported_dst_pixfmts[i].fmt == pixfmt)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-               param->errCode = EINVAL;
-               return;
-       }
-
-       param->stack[0] = supported_dst_frames[index].width;
-       param->stack[1] = supported_dst_frames[index].height;
-}
-
-void marucam_device_enum_fintv(MaruCamState* state)
-{
-       MaruCamParam *param = state->thread->param;
-
-       param->top = 0;
-
-       // switch by index(param->stack[0])
-       switch (param->stack[0]) {
-       case 0:
-               param->stack[1] = 30;   // denominator
-               break;
-       default:
-               param->errCode = EINVAL;
-               return;
-       }
-       param->stack[0] = 1;    // numerator
-}
-
-void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
-               uint32_t width, uint32_t height, uint32_t yvu)
-{
-       uint32_t i, j;
-       const unsigned char *src1;
-       unsigned char *udest, *vdest;
-
-       /* copy the Y values */
-       src1 = src;
-       for (i = 0; i < height; i++) {
-               for (j = 0; j < width; j += 2) {
-                       *dest++ = src1[0];
-                       *dest++ = src1[2];
-                       src1 += 4;
-               }
-       }
-
-       /* copy the U and V values */
-       src++;                          /* point to V */
-       src1 = src + width * 2;         /* next line */
-       if (yvu) {
-               vdest = dest;
-               udest = dest + width * height / 4;
-       } else {
-               udest = dest;
-               vdest = dest + width * height / 4;
-       }
-       for (i = 0; i < height; i += 2) {
-               for (j = 0; j < width; j += 2) {
-                       *udest++ = ((int) src[0] + src1[0]) / 2;        /* U */
-                       *vdest++ = ((int) src[2] + src1[2]) / 2;        /* V */
-                       src += 4;
-                       src1 += 4;
-               }
-               src = src1;
-               src1 += width * 2;
-       }
-}
+/*\r
+ * Implementation of MARU Virtual Camera device by PCI bus on Windows.\r
+ *\r
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ * JinHyung Jo <jinhyung.jo@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+\r
+#include "qemu-common.h"\r
+#include "maru_camera_common.h"\r
+#include "tizen/src/debug_ch.h"\r
+\r
+#define CINTERFACE\r
+#define COBJMACROS\r
+#include "ocidl.h"\r
+#include "errors.h"      /* for VFW_E_XXXX */\r
+#include "mmsystem.h"    /* for MAKEFOURCC macro */\r
+#include "maru_camera_win32_interface.h"\r
+\r
+MULTI_DEBUG_CHANNEL(tizen, camera_win32);\r
+\r
+/*\r
+ * COM Interface implementations\r
+ *\r
+ */\r
+\r
+#define SAFE_RELEASE(x) { if (x) x->lpVtbl->Release(x); x = NULL; }\r
+\r
+typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);\r
+\r
+/*\r
+ * HWCGrabCallback\r
+ */\r
+\r
+typedef struct HWCGrabCallback\r
+{\r
+       IGrabCallback IGrabCallback_iface;\r
+       long m_cRef;\r
+    CallbackFn m_pCallback;\r
+    STDMETHODIMP (*SetCallback)(IGrabCallback *iface, CallbackFn pCallbackFn);\r
+} HWCGrabCallback;\r
+\r
+static inline HWCGrabCallback *impl_from_IGrabCallback(IGrabCallback *iface)\r
+{\r
+       return CONTAINING_RECORD(iface, HWCGrabCallback, IGrabCallback_iface);\r
+}\r
+\r
+static STDMETHODIMP HWCGrabCallback_QueryInterface(IGrabCallback *iface, REFIID riid, void **ppv)\r
+{\r
+       if (IsEqualIID(riid, &IID_IUnknown)) {\r
+               *ppv = (IUnknown*)iface;\r
+       } else if (IsEqualIID(riid, &IID_IGrabCallback)) {\r
+               *ppv = (IGrabCallback*)iface;\r
+       } else {\r
+               *ppv = NULL;\r
+               return E_NOINTERFACE;\r
+       }\r
+\r
+       IGrabCallback_AddRef(iface);\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCGrabCallback_AddRef(IGrabCallback *iface)\r
+{\r
+       HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
+\r
+       return InterlockedIncrement(&This->m_cRef);\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCGrabCallback_Release(IGrabCallback *iface)\r
+{\r
+       HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
+\r
+       if( InterlockedDecrement(&This->m_cRef) == 0)\r
+       {\r
+               This->m_pCallback = NULL;\r
+               g_free((void*)This);\r
+               return 0;\r
+       }\r
+\r
+       return This->m_cRef;\r
+}\r
+\r
+static STDMETHODIMP HWCGrabCallback_Grab(IGrabCallback *iface, ULONG dwSize, BYTE *pBuffer)\r
+{\r
+       HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
+\r
+       if (This->m_pCallback) {\r
+               This->m_pCallback(dwSize, pBuffer);\r
+               return S_OK;\r
+       }\r
+\r
+       return E_FAIL;\r
+}\r
+\r
+static STDMETHODIMP HWCGrabCallback_SetCallback(IGrabCallback *iface, CallbackFn pCallbackFn)\r
+{\r
+       HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
+\r
+       This->m_pCallback = pCallbackFn;\r
+       return S_OK;\r
+}\r
+\r
+static IGrabCallbackVtbl HWCGrabCallback_Vtbl =\r
+{\r
+               HWCGrabCallback_QueryInterface,\r
+               HWCGrabCallback_AddRef,\r
+               HWCGrabCallback_Release,\r
+               HWCGrabCallback_Grab\r
+};\r
+\r
+static STDMETHODIMP HWCGrabCallback_Construct(IGrabCallback **ppv)\r
+{\r
+       HWCGrabCallback *This = (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));\r
+\r
+       if (!This) {\r
+               return E_OUTOFMEMORY;\r
+       }\r
+\r
+       This->IGrabCallback_iface.lpVtbl = &HWCGrabCallback_Vtbl;\r
+       This->m_cRef = 1;\r
+       This->m_pCallback = NULL;\r
+       This->SetCallback = HWCGrabCallback_SetCallback;\r
+       *ppv = &This->IGrabCallback_iface;\r
+       return S_OK;\r
+}\r
+\r
+/*\r
+ * HWCPin\r
+ */\r
+\r
+typedef struct HWCInPin\r
+{\r
+       IPin IPin_iface;\r
+       IMemInputPin IMemInputPin_iface;\r
+       IBaseFilter *m_pCFilter;\r
+       IPin *m_pConnectedPin;\r
+       IGrabCallback *m_pCallback;\r
+       BOOL m_bReadOnly;\r
+       long m_cRef;\r
+       STDMETHODIMP (*SetGrabCallbackIF)(IPin *iface, IGrabCallback *pCaptureCB);\r
+} HWCInPin;\r
+\r
+static inline HWCInPin *impl_from_IPin(IPin *iface)\r
+{\r
+       return CONTAINING_RECORD(iface, HWCInPin, IPin_iface);\r
+}\r
+\r
+static inline HWCInPin *impl_from_IMemInputPin(IMemInputPin *iface)\r
+{\r
+       return CONTAINING_RECORD(iface, HWCInPin, IMemInputPin_iface);\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin)) {\r
+               *ppv = &This->IPin_iface;\r
+               IPin_AddRef((IPin*)*ppv);\r
+       } else if (IsEqualIID(riid, &IID_IMemInputPin)) {\r
+               *ppv = &This->IMemInputPin_iface;\r
+               IPin_AddRef((IMemInputPin*)*ppv);\r
+       } else {\r
+               *ppv = NULL;\r
+               return E_NOINTERFACE;\r
+       }\r
+\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCPin_AddRef(IPin *iface)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       return InterlockedIncrement(&This->m_cRef);\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCPin_Release(IPin *iface)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if( InterlockedDecrement(&This->m_cRef) == 0)\r
+       {\r
+               if (This->m_pCFilter) {\r
+                       IBaseFilter_Release(This->m_pCFilter);\r
+                       This->m_pCFilter = NULL;\r
+               }\r
+               if (This->m_pCallback) {\r
+                       IGrabCallback_Release(This->m_pCallback);\r
+                       This->m_pCallback = NULL;\r
+               }\r
+               if (This->m_pConnectedPin) {\r
+                       IPin_Release(This->m_pConnectedPin);\r
+                       This->m_pConnectedPin = NULL;\r
+               }\r
+               g_free((void*)This);\r
+               return 0;\r
+       }\r
+       return This->m_cRef;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)\r
+{\r
+       if ( !pmt )\r
+               return S_OK;\r
+       return S_FALSE;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_ReceiveConnection(IPin *iface, IPin *pConnector, const AM_MEDIA_TYPE *pmt)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if (pConnector == NULL || pmt == NULL)\r
+               return E_POINTER;\r
+\r
+       if (This->m_pConnectedPin) {\r
+               return VFW_E_ALREADY_CONNECTED;\r
+       }\r
+       FILTER_STATE fs;\r
+       IBaseFilter_GetState(This->m_pCFilter, 0, &fs);\r
+       if (fs != State_Stopped) {\r
+               return VFW_E_NOT_STOPPED;\r
+       }\r
+       PIN_DIRECTION pd;\r
+       IPin_QueryDirection(pConnector, &pd);\r
+       if (pd == PINDIR_INPUT) {\r
+               return VFW_E_INVALID_DIRECTION;\r
+       }\r
+\r
+       This->m_pConnectedPin = pConnector;\r
+       IPin_AddRef(This->m_pConnectedPin);\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_Disconnect(IPin *iface)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       HRESULT hr;\r
+       if (This->m_pConnectedPin == NULL) {\r
+               hr = S_FALSE;\r
+       } else {\r
+               IPin_Release(This->m_pConnectedPin);\r
+               This->m_pConnectedPin = NULL;\r
+               hr = S_OK;\r
+       }\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_ConnectedTo(IPin *iface, IPin **pPin)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if (pPin == NULL)\r
+               return E_POINTER;\r
+\r
+       if (This->m_pConnectedPin == NULL) {\r
+               return VFW_E_NOT_CONNECTED;\r
+       } else {\r
+               *pPin = This->m_pConnectedPin;\r
+               IPin_AddRef(This->m_pConnectedPin);\r
+       }\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)\r
+{\r
+       if (pmt == NULL) {\r
+               return E_POINTER;\r
+       }\r
+       return VFW_E_NOT_CONNECTED;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if (pInfo == NULL)\r
+               return E_POINTER;\r
+\r
+       pInfo->pFilter = This->m_pCFilter;\r
+       if (This->m_pCFilter) {\r
+               IBaseFilter_AddRef(This->m_pCFilter);\r
+       }\r
+       memcpy((void*)pInfo->achName, (void*)HWCPinName, sizeof(HWCPinName));\r
+       pInfo->dir = PINDIR_INPUT;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)\r
+{\r
+       if (pPinDir == NULL)\r
+               return E_POINTER;\r
+       *pPinDir = PINDIR_INPUT;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryId(IPin *iface, LPWSTR *Id)\r
+{\r
+       if (Id == NULL)\r
+               return E_POINTER;\r
+       PVOID pId = CoTaskMemAlloc(sizeof(HWCPinName));\r
+       memcpy((void*)pId, (void*)HWCPinName, sizeof(HWCPinName));\r
+       *Id = (LPWSTR)pId;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)\r
+{\r
+       if (pmt == NULL)\r
+               return E_POINTER;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)\r
+{\r
+       if (ppEnum == NULL)\r
+                       return E_POINTER;\r
+       return E_NOTIMPL;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_QueryInternalConnections(IPin *iface, IPin **ppPin, ULONG *nPin)\r
+{\r
+       return E_NOTIMPL;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_EndOfStream(IPin *iface)\r
+{\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_BeginFlush(IPin *iface)\r
+{\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_EndFlush(IPin *iface)\r
+{\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)\r
+{\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv)\r
+{\r
+       HWCInPin *This = impl_from_IMemInputPin(iface);\r
+\r
+       if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMemInputPin)) {\r
+               *ppv = &This->IMemInputPin_iface;\r
+               IMemInputPin_AddRef((IMemInputPin*)*ppv);\r
+       } else if (IsEqualIID(riid, &IID_IPin)) {\r
+               *ppv = &This->IPin_iface;\r
+               IPin_AddRef((IPin*)*ppv);\r
+       } else {\r
+               *ppv = NULL;\r
+               return E_NOINTERFACE;\r
+       }\r
+\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCMemInputPin_AddRef(IMemInputPin *iface)\r
+{\r
+       HWCInPin *This = impl_from_IMemInputPin(iface);\r
+\r
+       return InterlockedIncrement(&This->m_cRef);\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCMemInputPin_Release(IMemInputPin *iface)\r
+{\r
+       HWCInPin *This = impl_from_IMemInputPin(iface);\r
+\r
+       if( InterlockedDecrement(&This->m_cRef) == 0)\r
+       {\r
+               if (This->m_pCFilter) {\r
+                       IBaseFilter_Release(This->m_pCFilter);\r
+                       This->m_pCFilter = NULL;\r
+               }\r
+               if (This->m_pCallback) {\r
+                       IGrabCallback_Release(This->m_pCallback);\r
+                       This->m_pCallback = NULL;\r
+               }\r
+               if (This->m_pConnectedPin) {\r
+                       IPin_Release(This->m_pConnectedPin);\r
+                       This->m_pConnectedPin = NULL;\r
+               }\r
+               g_free((void*)This);\r
+               return 0;\r
+       }\r
+       return This->m_cRef;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator)\r
+{\r
+       if (ppAllocator == NULL)\r
+               return E_POINTER;\r
+       return VFW_E_NO_ALLOCATOR;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_NotifyAllocator(IMemInputPin *iface, IMemAllocator *pAllocator, BOOL bReadOnly)\r
+{\r
+       if (pAllocator == NULL)\r
+               return E_POINTER;\r
+\r
+       return NOERROR;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_GetAllocatorRequirements(IMemInputPin *iface, ALLOCATOR_PROPERTIES *pProps)\r
+{\r
+       return E_NOTIMPL;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_Receive(IMemInputPin *iface, IMediaSample *pSample)\r
+{\r
+       HWCInPin *This = impl_from_IMemInputPin(iface);\r
+\r
+       if (pSample == NULL)\r
+               return E_POINTER;\r
+       if (This->m_pCallback != NULL) {\r
+               HRESULT hr;\r
+               BYTE* pBuffer = NULL;\r
+               BYTE* pTmp_Buffer = NULL;       /* is this required? */\r
+               DWORD dwSize = 0;\r
+               dwSize = IMediaSample_GetSize(pSample);\r
+               hr = IMediaSample_GetPointer(pSample, &pBuffer);\r
+               if (FAILED(hr))\r
+                       return hr;\r
+\r
+               pTmp_Buffer = (BYTE *)g_malloc0((size_t)dwSize);\r
+               if (!pTmp_Buffer)\r
+                       return E_OUTOFMEMORY;\r
+               memcpy((void*)pTmp_Buffer, (void*)pBuffer, (size_t)dwSize);\r
+\r
+               hr = IGrabCallback_Grab(This->m_pCallback, dwSize, pTmp_Buffer);\r
+               if (FAILED(hr))\r
+                       return hr;\r
+       }\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_ReceiveMultiple(IMemInputPin *iface, IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)\r
+{\r
+       HRESULT hr = S_OK;\r
+\r
+       if (pSamples == NULL)\r
+               return E_POINTER;\r
+\r
+       *nSamplesProcessed = 0;\r
+\r
+       while (nSamples-- > 0)\r
+       {\r
+               hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);\r
+               if (hr != S_OK)\r
+                       break;\r
+               (*nSamplesProcessed)++;\r
+       }\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP HWCMemInputPin_ReceiveCanBlock(IMemInputPin *iface)\r
+{\r
+       return S_FALSE;\r
+}\r
+\r
+static STDMETHODIMP HWCPin_SetCallback(IPin *iface, IGrabCallback *pCaptureCB)\r
+{\r
+       HWCInPin *This = impl_from_IPin(iface);\r
+\r
+       if (pCaptureCB == NULL) {\r
+               IGrabCallback_Release(This->m_pCallback);\r
+               This->m_pCallback = NULL;\r
+       } else {\r
+               This->m_pCallback = pCaptureCB;\r
+               IGrabCallback_AddRef(This->m_pCallback);\r
+       }\r
+\r
+       return S_OK;\r
+}\r
+\r
+\r
+static IPinVtbl HWCPin_Vtbl =\r
+{\r
+       HWCPin_QueryInterface,\r
+       HWCPin_AddRef,\r
+       HWCPin_Release,\r
+       HWCPin_Connect,\r
+       HWCPin_ReceiveConnection,\r
+       HWCPin_Disconnect,\r
+       HWCPin_ConnectedTo,\r
+       HWCPin_ConnectionMediaType,\r
+       HWCPin_QueryPinInfo,\r
+       HWCPin_QueryDirection,\r
+       HWCPin_QueryId,\r
+       HWCPin_QueryAccept,\r
+       HWCPin_EnumMediaTypes,\r
+       HWCPin_QueryInternalConnections,\r
+       HWCPin_EndOfStream,\r
+       HWCPin_BeginFlush,\r
+       HWCPin_EndFlush,\r
+       HWCPin_NewSegment\r
+};\r
+\r
+static IMemInputPinVtbl HWCMemInputPin_Vtbl =\r
+{\r
+       HWCMemInputPin_QueryInterface,\r
+       HWCMemInputPin_AddRef,\r
+       HWCMemInputPin_Release,\r
+       HWCMemInputPin_GetAllocator,\r
+       HWCMemInputPin_NotifyAllocator,\r
+       HWCMemInputPin_GetAllocatorRequirements,\r
+       HWCMemInputPin_Receive,\r
+       HWCMemInputPin_ReceiveMultiple,\r
+       HWCMemInputPin_ReceiveCanBlock\r
+};\r
+\r
+static STDMETHODIMP HWCInPin_Construct(IBaseFilter *pFilter, IPin **ppv)\r
+{\r
+       HWCInPin *This = (HWCInPin *)g_malloc0(sizeof(HWCInPin));\r
+\r
+       if (!This) {\r
+               return E_OUTOFMEMORY;\r
+       }\r
+\r
+       This->IPin_iface.lpVtbl = &HWCPin_Vtbl;\r
+       This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;\r
+       This->m_bReadOnly = FALSE;\r
+       This->m_pCFilter = pFilter;\r
+       if (This->m_pCFilter) {\r
+               IBaseFilter_AddRef(This->m_pCFilter);\r
+       }\r
+       This->m_pConnectedPin = NULL;\r
+       This->m_pCallback = NULL;\r
+       This->m_cRef = 1;\r
+       This->SetGrabCallbackIF = HWCPin_SetCallback;\r
+       *ppv = &This->IPin_iface;\r
+\r
+       return S_OK;\r
+}\r
+\r
+/*\r
+ * HWCEnumPins\r
+ */\r
+\r
+typedef struct HWCEnumPins\r
+{\r
+       IEnumPins IEnumPins_iface;\r
+       IBaseFilter *m_pFilter;\r
+       int m_nPos;\r
+       long m_cRef;\r
+} HWCEnumPins;\r
+\r
+static inline HWCEnumPins *impl_from_IEnumPins(IEnumPins *iface)\r
+{\r
+       return CONTAINING_RECORD(iface, HWCEnumPins, IEnumPins_iface);\r
+}\r
+\r
+static STDMETHODIMP HWCEnumPins_QueryInterface(IEnumPins *iface, REFIID riid, void **ppv)\r
+{\r
+       if (ppv == NULL)\r
+               return E_POINTER;\r
+\r
+       if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumPins)) {\r
+               *ppv = iface;\r
+       } else {\r
+               *ppv = NULL;\r
+               return E_NOINTERFACE;\r
+       }\r
+\r
+       IEnumPins_AddRef(iface);\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCEnumPins_AddRef(IEnumPins *iface)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+\r
+       return InterlockedIncrement(&This->m_cRef);\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCEnumPins_Release(IEnumPins *iface)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+\r
+       if (InterlockedDecrement(&This->m_cRef) == 0) {\r
+               if (This->m_pFilter) {\r
+                       IBaseFilter_Release(This->m_pFilter);\r
+                       This->m_pFilter = NULL;\r
+               }\r
+               This->m_nPos = 0;\r
+               g_free((void*)This);\r
+               return 0;\r
+       }\r
+       return This->m_cRef;\r
+}\r
+\r
+static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins, IPin **ppPins,\r
+                                                               ULONG *pcFetched)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+\r
+       if (ppPins == NULL)\r
+                       return E_POINTER;\r
+\r
+       ULONG fetched;\r
+       if (This->m_nPos < 1 && cPins > 0) {\r
+               IPin *pPin;\r
+               IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);\r
+               *ppPins = pPin;\r
+               IPin_AddRef(pPin);\r
+               fetched = 1;\r
+               This->m_nPos++;\r
+       } else {\r
+               fetched = 0;\r
+       }\r
+\r
+       if (pcFetched != NULL ) {\r
+               *pcFetched = fetched;\r
+       }\r
+\r
+       return ( fetched == cPins ) ? S_OK : S_FALSE;\r
+}\r
+\r
+static STDMETHODIMP HWCEnumPins_Skip(IEnumPins *iface, ULONG cPins)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+       This->m_nPos += cPins;\r
+       return ( This->m_nPos >= 1 ) ? S_FALSE : S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCEnumPins_Reset(IEnumPins *iface)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+       This->m_nPos = 0;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter, int nPos, IEnumPins **ppv);\r
+\r
+static STDMETHODIMP HWCEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum)\r
+{\r
+       HWCEnumPins *This = impl_from_IEnumPins(iface);\r
+\r
+       if (ppEnum == NULL)\r
+               return E_POINTER;\r
+\r
+       HWCEnumPins_Construct(This->m_pFilter, This->m_nPos, ppEnum);\r
+       if (*ppEnum == NULL) {\r
+               return E_OUTOFMEMORY;\r
+       }\r
+\r
+       return S_OK;\r
+}\r
+\r
+static IEnumPinsVtbl HWCEnumPins_Vtbl =\r
+{\r
+       HWCEnumPins_QueryInterface,\r
+       HWCEnumPins_AddRef,\r
+       HWCEnumPins_Release,\r
+       HWCEnumPins_Next,\r
+       HWCEnumPins_Skip,\r
+       HWCEnumPins_Reset,\r
+       HWCEnumPins_Clone\r
+};\r
+\r
+\r
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter, int nPos, IEnumPins **ppv)\r
+{\r
+       HWCEnumPins *This = (HWCEnumPins *)g_malloc0(sizeof(HWCEnumPins));\r
+\r
+       if (!This) {\r
+               return E_OUTOFMEMORY;\r
+       }\r
+\r
+       This->IEnumPins_iface.lpVtbl = &HWCEnumPins_Vtbl;\r
+       This->m_pFilter = pFilter;\r
+       if (This->m_pFilter) {\r
+               IBaseFilter_AddRef(This->m_pFilter);\r
+       }\r
+       This->m_cRef = 1;\r
+       This->m_nPos = nPos;\r
+       *ppv = &This->IEnumPins_iface;\r
+\r
+       return S_OK;\r
+}\r
+\r
+/*\r
+ * HWCFilter\r
+ */\r
+\r
+typedef struct HWCFilter\r
+{\r
+       IBaseFilter IBaseFilter_iface;\r
+       IPin *m_pPin;\r
+       IFilterGraph *m_pFilterGraph;\r
+       FILTER_STATE m_state;\r
+       long m_cRef;\r
+} HWCFilter;\r
+\r
+static inline HWCFilter *impl_from_IBaseFilter(IBaseFilter *iface)\r
+{\r
+       return CONTAINING_RECORD(iface, HWCFilter, IBaseFilter_iface);\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)\r
+{\r
+       if(IsEqualIID(riid, &IID_IUnknown)) {\r
+               *ppv = (IUnknown*)iface;\r
+       } else if (IsEqualIID(riid, &IID_IPersist)) {\r
+               *ppv = (IPersist*)iface;\r
+       } else if (IsEqualIID(riid, &IID_IMediaFilter)) {\r
+               *ppv = (IMediaFilter*)iface;\r
+       } else if (IsEqualIID(riid, &IID_IBaseFilter)) {\r
+               *ppv = (IBaseFilter*)iface;\r
+       } else {\r
+               *ppv = NULL;\r
+               return E_NOINTERFACE;\r
+       }\r
+\r
+       IBaseFilter_AddRef(iface);\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCFilter_AddRef(IBaseFilter *iface)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       return InterlockedIncrement(&This->m_cRef);\r
+}\r
+\r
+static STDMETHODIMP_(ULONG) HWCFilter_Release(IBaseFilter *iface)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       if( InterlockedDecrement(&This->m_cRef) == 0) {\r
+               if (This->m_pPin) {\r
+                       IPin_Release(This->m_pPin);\r
+                       This->m_pPin = NULL;\r
+               }\r
+               if (This->m_pFilterGraph) {\r
+                       IFilterGraph_Release(This->m_pFilterGraph);\r
+                       This->m_pFilterGraph = NULL;\r
+               }\r
+               g_free((void*)This);\r
+               return 0;\r
+       }\r
+       return This->m_cRef;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_GetClassID(IBaseFilter *iface, CLSID *pClsID)\r
+{\r
+       if (pClsID == NULL)\r
+               return E_POINTER;\r
+       return E_NOTIMPL;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_GetState(IBaseFilter *iface, DWORD dwMSecs, FILTER_STATE *State)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+       *State = This->m_state;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)\r
+{\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **pClock)\r
+{\r
+       *pClock = NULL;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_Stop(IBaseFilter *iface)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       IPin_EndFlush(This->m_pPin);\r
+       This->m_state = State_Stopped;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_Pause(IBaseFilter *iface)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+       This->m_state = State_Paused;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       if (This->m_state == State_Stopped){\r
+               HRESULT hr;\r
+               hr = IBaseFilter_Pause(iface);\r
+               if (FAILED(hr)) {\r
+                       return hr;\r
+               }\r
+       }\r
+\r
+       This->m_state = State_Running;\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)\r
+{\r
+       if (ppEnum == NULL)\r
+               return E_POINTER;\r
+\r
+       HWCEnumPins_Construct(iface, 0, ppEnum);\r
+       return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       if (ppPin == NULL)\r
+               return E_POINTER;\r
+\r
+       if (memcmp((void*)Id, (void*)HWCPinName, sizeof(HWCPinName))) {\r
+               return VFW_E_NOT_FOUND;\r
+       }\r
+\r
+       if (!This->m_pPin) {\r
+                HWCInPin_Construct(iface, &This->m_pPin);\r
+       }\r
+       *ppPin = This->m_pPin;\r
+\r
+       IPin_AddRef(This->m_pPin);\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       if (pInfo == NULL)\r
+               return E_POINTER;\r
+\r
+       memcpy((void*)pInfo->achName, (void*)HWCFilterName, sizeof(HWCFilterName));\r
+       pInfo->pGraph = This->m_pFilterGraph;\r
+       if(This->m_pFilterGraph) {\r
+               IFilterGraph_AddRef(This->m_pFilterGraph);\r
+       }\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph,\r
+                                                                               LPCWSTR pName)\r
+{\r
+       HWCFilter *This = impl_from_IBaseFilter(iface);\r
+\r
+       This->m_pFilterGraph = pGraph;\r
+       if (pGraph) {\r
+               IFilterGraph_AddRef(pGraph);\r
+       }\r
+       return S_OK;\r
+}\r
+\r
+static STDMETHODIMP HWCFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR* pVendorInfo)\r
+{\r
+       return E_NOTIMPL;\r
+}\r
+\r
+static IBaseFilterVtbl HWCFilter_Vtbl =\r
+{\r
+       HWCFilter_QueryInterface,\r
+       HWCFilter_AddRef,\r
+       HWCFilter_Release,\r
+       HWCFilter_GetClassID,\r
+       HWCFilter_Stop,\r
+       HWCFilter_Pause,\r
+       HWCFilter_Run,\r
+       HWCFilter_GetState,\r
+       HWCFilter_SetSyncSource,\r
+       HWCFilter_GetSyncSource,\r
+       HWCFilter_EnumPins,\r
+       HWCFilter_FindPin,\r
+       HWCFilter_QueryFilterInfo,\r
+       HWCFilter_JoinFilterGraph,\r
+       HWCFilter_QueryVendorInfo\r
+};\r
+\r
+static STDMETHODIMP HWCFilter_Construct(IBaseFilter **ppv)\r
+{\r
+       HWCFilter *This = (HWCFilter *)g_malloc0(sizeof(HWCFilter));\r
+\r
+       if (!This) {\r
+               return E_OUTOFMEMORY;\r
+       }\r
+\r
+       This->IBaseFilter_iface.lpVtbl = &HWCFilter_Vtbl;\r
+       This->m_pFilterGraph = NULL;\r
+       This->m_state = State_Stopped;\r
+       This->m_cRef = 1;\r
+       HWCInPin_Construct(&This->IBaseFilter_iface, &This->m_pPin);\r
+       *ppv = &This->IBaseFilter_iface;\r
+\r
+       return S_OK;\r
+}\r
+\r
+/**********************************************************\r
+ *\r
+ * Virtual device implementations\r
+ *\r
+ **********************************************************/\r
+\r
+\r
+/*\r
+ * Declaration global variables for Win32 COM Interfaces\r
+ */\r
+IGraphBuilder *g_pGB ;\r
+ICaptureGraphBuilder2 *g_pCGB;\r
+IMediaControl *g_pMediaControl;\r
+\r
+IPin *g_pOutputPin;\r
+IPin *g_pInputPin;\r
+IBaseFilter *g_pDstFilter;\r
+IBaseFilter *g_pSrcFilter;\r
+\r
+IGrabCallback *g_pCallback;\r
+\r
+DWORD g_dwFourcc;\r
+LONG g_dwWidth;\r
+LONG g_dwHeight;\r
+REFERENCE_TIME g_dwAvgInterval;\r
+\r
+// V4L2 defines copy from videodev2.h\r
+#define V4L2_CTRL_FLAG_SLIDER          0x0020\r
+\r
+#define V4L2_CTRL_CLASS_USER           0x00980000\r
+#define V4L2_CID_BASE                          (V4L2_CTRL_CLASS_USER | 0x900)\r
+#define V4L2_CID_BRIGHTNESS                    (V4L2_CID_BASE+0)\r
+#define V4L2_CID_CONTRAST                      (V4L2_CID_BASE+1)\r
+#define V4L2_CID_SATURATION                    (V4L2_CID_BASE+2)\r
+#define V4L2_CID_SHARPNESS                     (V4L2_CID_BASE+27)\r
+\r
+#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */\r
+#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */\r
+#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */\r
+\r
+typedef struct tagMaruCamConvertPixfmt {\r
+       uint32_t fmt;   /* fourcc */\r
+       uint32_t bpp;   /* bits per pixel, 0 for compressed formats */\r
+       uint32_t needs_conversion;\r
+} MaruCamConvertPixfmt;\r
+\r
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {\r
+               { V4L2_PIX_FMT_YUYV, 16, 0 },\r
+               { V4L2_PIX_FMT_YUV420, 12, 0 },\r
+               { V4L2_PIX_FMT_YVU420, 12, 0 },\r
+};\r
+\r
+typedef struct tagMaruCamConvertFrameInfo {\r
+       uint32_t width;\r
+       uint32_t height;\r
+} MaruCamConvertFrameInfo;\r
+\r
+static MaruCamConvertFrameInfo supported_dst_frames[] = {\r
+               { 640, 480 },\r
+               { 352, 288 },\r
+               { 320, 240 },\r
+               { 176, 144 },\r
+               { 160, 120 },\r
+};\r
+\r
+#define MARUCAM_CTRL_VALUE_MAX         20\r
+#define MARUCAM_CTRL_VALUE_MIN         1\r
+#define MARUCAM_CTRL_VALUE_MID         10\r
+#define MARUCAM_CTRL_VALUE_STEP                1\r
+\r
+struct marucam_qctrl {\r
+       uint32_t id;\r
+       uint32_t hit;\r
+       long min;\r
+       long max;\r
+       long step;\r
+       long init_val;\r
+};\r
+\r
+static struct marucam_qctrl qctrl_tbl[] = {\r
+       { V4L2_CID_BRIGHTNESS, 0, },\r
+       { V4L2_CID_CONTRAST, 0, },\r
+       { V4L2_CID_SATURATION,0, },\r
+       { V4L2_CID_SHARPNESS, 0, },\r
+};\r
+\r
+static MaruCamState *g_state = NULL;\r
+\r
+static uint32_t cur_fmt_idx = 0;\r
+static uint32_t cur_frame_idx = 0;\r
+\r
+\r
+/*\r
+ * Helper functions - converting image formats, converting values\r
+ */\r
+\r
+void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,\r
+               uint32_t width, uint32_t height, uint32_t yvu);\r
+\r
+\r
+static long value_convert_from_guest(long min, long max, long value)\r
+{\r
+       double rate = 0.0;\r
+       long dist = 0, ret = 0;\r
+\r
+       dist = max - min;\r
+\r
+       if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
+               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
+               ret = min + (int32_t)(value / rate);\r
+       } else {\r
+               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
+               ret = min + (int32_t)(rate * value);\r
+       }\r
+       return ret;\r
+}\r
+\r
+static long value_convert_to_guest(long min, long max, long value)\r
+{\r
+       double rate  = 0.0;\r
+       long dist = 0, ret = 0;\r
+\r
+       dist = max - min;\r
+\r
+       if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
+               rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
+               ret = (int32_t)((double)(value - min) * rate);\r
+       } else {\r
+               rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
+               ret = (int32_t)((double)(value - min) / rate);\r
+       }\r
+\r
+       return ret;\r
+}\r
+\r
+/*\r
+ * Callback function for grab frames\r
+ */\r
+static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)\r
+{\r
+       static uint32_t index = 0;\r
+       static uint32_t is_init = 1;\r
+       uint32_t width, height;\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
+       if (is_init == 1) {\r
+               qemu_thread_get_self(&g_state->thread_id);\r
+               is_init = 0;\r
+       }\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
+               break;\r
+       case V4L2_PIX_FMT_YVU420:\r
+               v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 1);\r
+               break;\r
+       case V4L2_PIX_FMT_YUYV:\r
+               memcpy(buf, (void*)pBuffer, dwSize);\r
+               break;\r
+       }\r
+       index = !index;\r
+\r
+       if (g_state->req_frame) {\r
+               qemu_irq_raise(g_state->dev.irq[2]);\r
+               g_state->req_frame = 0;\r
+       }\r
+       return S_OK;\r
+}\r
+\r
+/*\r
+ * Internal functions for manipulate interfaces\r
+ */\r
+\r
+static STDMETHODIMP_(void) CloseInterfaces(void)\r
+{\r
+       INFO("%s\n", __func__);\r
+       if (g_pMediaControl)\r
+               g_pMediaControl->lpVtbl->Stop(g_pMediaControl);\r
+\r
+       if (g_pOutputPin)\r
+               g_pOutputPin->lpVtbl->Disconnect(g_pOutputPin);\r
+\r
+       SAFE_RELEASE(g_pGB);\r
+       SAFE_RELEASE(g_pCGB);\r
+       SAFE_RELEASE(g_pMediaControl);\r
+       SAFE_RELEASE(g_pOutputPin);\r
+       SAFE_RELEASE(g_pInputPin);\r
+       SAFE_RELEASE(g_pDstFilter);\r
+       SAFE_RELEASE(g_pSrcFilter);\r
+       SAFE_RELEASE(g_pCallback);\r
+}\r
+\r
+static STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt)\r
+{\r
+       INFO("%s\n", __func__);\r
+       if (pmt == NULL) {\r
+               return;\r
+       }\r
+\r
+       if (pmt->cbFormat != 0) {\r
+               CoTaskMemFree((PVOID)pmt->pbFormat);\r
+               pmt->cbFormat = 0;\r
+               pmt->pbFormat = NULL;\r
+       }\r
+       if (pmt->pUnk != NULL) {\r
+               pmt->pUnk->lpVtbl->Release(pmt->pUnk);\r
+               pmt->pUnk = NULL;\r
+       }\r
+\r
+       CoTaskMemFree((PVOID)pmt);\r
+}\r
+\r
+static STDMETHODIMP GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)\r
+{\r
+       HRESULT hr;\r
+       IEnumPins *pEnum = NULL;\r
+       IPin *pPin = NULL;\r
+\r
+       INFO("%s\n", __func__);\r
+\r
+       if (ppPin == NULL)\r
+       {\r
+               return E_POINTER;\r
+       }\r
+\r
+       hr = pFilter->lpVtbl->EnumPins(pFilter, &pEnum);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       while(pEnum->lpVtbl->Next(pEnum, 1, &pPin, 0) == S_OK)\r
+       {\r
+               PIN_DIRECTION PinDirThis;\r
+               hr = pPin->lpVtbl->QueryDirection(pPin, &PinDirThis);\r
+               if (FAILED(hr))\r
+               {\r
+                       SAFE_RELEASE(pPin);\r
+                       SAFE_RELEASE(pEnum);\r
+                       return hr;\r
+               }\r
+               if (PinDir == PinDirThis)\r
+               {\r
+                       *ppPin = pPin;\r
+                       SAFE_RELEASE(pEnum);\r
+                       return S_OK;\r
+               }\r
+               SAFE_RELEASE(pPin);\r
+       }\r
+\r
+       SAFE_RELEASE(pEnum);\r
+       return S_FALSE;\r
+}\r
+\r
+static STDMETHODIMP GraphBuilder_Init(void)\r
+{\r
+       HRESULT hr;\r
+       INFO("%s\n", __func__);\r
+\r
+       hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC, &IID_IGraphBuilder, (void**)&g_pGB);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, &IID_ICaptureGraphBuilder2, (void**)&g_pCGB);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl, (void **)&g_pMediaControl);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = HWCGrabCallback_Construct(&g_pCallback);\r
+       if (g_pCallback == NULL)\r
+               hr = E_OUTOFMEMORY;\r
+\r
+       hr = ((HWCGrabCallback*)g_pCallback)->SetCallback(g_pCallback, (CallbackFn)marucam_device_callbackfn);\r
+\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP BindSourceFilter(void)\r
+{\r
+       HRESULT hr;\r
+       ICreateDevEnum *pCreateDevEnum = NULL;\r
+       IEnumMoniker *pEnumMK = NULL;\r
+       IMoniker *pMoniKer;\r
+\r
+       INFO("%s\n", __func__);\r
+       hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)&pCreateDevEnum);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
+       if (FAILED(hr))\r
+       {\r
+               pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
+               return hr;\r
+       }\r
+\r
+       if (!pEnumMK)\r
+       {\r
+               pCreateDevEnum->lpVtbl->Release(pCreateDevEnum);\r
+               return E_FAIL;\r
+       }\r
+       pEnumMK->lpVtbl->Reset(pEnumMK);\r
+\r
+       hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);\r
+       if (hr == S_FALSE)\r
+       {\r
+               hr = E_FAIL;\r
+       }\r
+       if (SUCCEEDED(hr))\r
+       {\r
+               IPropertyBag *pBag = NULL;\r
+               hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0, &IID_IPropertyBag, (void **)&pBag);\r
+               if(SUCCEEDED(hr))\r
+               {\r
+                       VARIANT var;\r
+                       var.vt = VT_BSTR;\r
+                       hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);\r
+                       if (hr == NOERROR)\r
+                       {\r
+                               hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL, &IID_IBaseFilter, (void**)&g_pSrcFilter);\r
+                               if (FAILED(hr))\r
+                               {\r
+                                       ERR("Counldn't bind moniker to filter object!!\n");\r
+                               }\r
+                               else\r
+                               {\r
+                                       g_pSrcFilter->lpVtbl->AddRef(g_pSrcFilter);\r
+                               }\r
+                               SysFreeString(var.bstrVal);\r
+                       }\r
+                       pBag->lpVtbl->Release(pBag);\r
+               }\r
+               pMoniKer->lpVtbl->Release(pMoniKer);\r
+       }\r
+\r
+       if (SUCCEEDED(hr))\r
+       {\r
+               hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pSrcFilter, L"Video Capture");\r
+               if (hr != S_OK && hr != S_FALSE)\r
+               {\r
+                       ERR("Counldn't add Video Capture filter to our graph!\n");\r
+               }\r
+       }\r
+\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP BindTargetFilter(void)\r
+{\r
+       HRESULT hr;\r
+       hr = HWCFilter_Construct(&g_pDstFilter);\r
+\r
+       INFO("%s\n", __func__);\r
+       if (SUCCEEDED(hr) && g_pDstFilter)\r
+       {\r
+               hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pDstFilter, L"HWCFilter");\r
+               if (FAILED(hr))\r
+               {\r
+                       ERR("Counldn't add HWCFilterr to our graph!\n");\r
+               }\r
+       }\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP ConnectFilters(void)\r
+{\r
+       HRESULT hr;\r
+\r
+       INFO("%s\n", __func__);\r
+       hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP SetDefaultValues(void)\r
+{\r
+       HRESULT hr;\r
+       IAMStreamConfig *pSConfig;\r
+       int iCount = 0, iSize = 0;\r
+\r
+       INFO("%s\n", __func__);\r
+       hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0, g_pSrcFilter, &IID_IAMStreamConfig, (void**)&pSConfig);\r
+       if (FAILED(hr)) {\r
+               ERR("failed to FindInterface method\n");\r
+               return hr;\r
+       }\r
+\r
+       hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);\r
+       if (FAILED(hr))\r
+       {\r
+               ERR("failed to GetNumberOfCapabilities method\n");\r
+               pSConfig->lpVtbl->Release(pSConfig);\r
+               return hr;\r
+       }\r
+\r
+       if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
+       {\r
+               int iFormat = 0;\r
+               for (iFormat = 0; iFormat < iCount; iFormat++)\r
+               {\r
+                       VIDEO_STREAM_CONFIG_CAPS scc;\r
+                       AM_MEDIA_TYPE *pmtConfig;\r
+\r
+                       hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig, (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
+                                       {\r
+                                               pvi->AvgTimePerFrame = g_dwAvgInterval;\r
+                                               hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);\r
+                                               DeleteMediaType(pmtConfig);\r
+                                               INFO("Setting default values.\n");\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               DeleteMediaType(pmtConfig);\r
+                       }\r
+               }\r
+       }\r
+       pSConfig->lpVtbl->Release(pSConfig);\r
+       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
+       INFO("%s\n", __func__);\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->AvgTimePerFrame = g_dwAvgInterval;\r
+                       pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;\r
+                       hr = vsc->lpVtbl->SetFormat(vsc, pmt);\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
+       long Flags;\r
+       IAMVideoProcAmp *pProcAmp = NULL;\r
+\r
+       INFO("%s\n", __func__);\r
+\r
+       hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter, &IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+       if (FAILED(hr)) {\r
+               return hr;\r
+       }\r
+\r
+       hr = pProcAmp->lpVtbl->GetRange(pProcAmp, nProperty, pMin, pMax, pStep, pDefault, &Flags);\r
+\r
+       SAFE_RELEASE(pProcAmp);\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue)\r
+{\r
+       HRESULT hr;\r
+       long Flags;\r
+       IAMVideoProcAmp *pProcAmp = NULL;\r
+\r
+       INFO("%s\n", __func__);\r
+       hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter, &IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = pProcAmp->lpVtbl->Get(pProcAmp, nProperty, pValue, &Flags);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to get property for video\n");\r
+       }\r
+\r
+       SAFE_RELEASE(pProcAmp);\r
+       return hr;\r
+}\r
+\r
+static STDMETHODIMP SetVideoProcAmp(long nProperty, long value)\r
+{\r
+       HRESULT hr;\r
+\r
+       IAMVideoProcAmp *pProcAmp = NULL;\r
+       hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter, &IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+       if (FAILED(hr))\r
+               return hr;\r
+\r
+       hr = pProcAmp->lpVtbl->Set(pProcAmp, nProperty, value, VideoProcAmp_Flags_Manual);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to set property for video\n");\r
+       }\r
+       SAFE_RELEASE(pProcAmp);\r
+       return hr;\r
+}\r
+\r
+// MARUCAM_CMD_INIT\r
+void marucam_device_init(MaruCamState* state)\r
+{\r
+       g_state = state;\r
+}\r
+\r
+// MARUCAM_CMD_OPEN\r
+void marucam_device_open(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       MaruCamParam *param = state->param;\r
+       param->top = 0;\r
+\r
+       INFO("%s\n", __func__);\r
+       CoInitialize(NULL);\r
+\r
+       hr = GraphBuilder_Init();\r
+       if (FAILED(hr)) {\r
+               ERR("GraphBuilder_Init\n");\r
+               goto error_failed;\r
+       }\r
+\r
+       hr = BindSourceFilter();\r
+       if (FAILED(hr)) {\r
+               ERR("BindSourceFilter\n");\r
+               goto error_failed;\r
+       }\r
+\r
+       hr = BindTargetFilter();\r
+       if (FAILED(hr)) {\r
+               ERR("BindTargetFilter\n");\r
+               goto error_failed;\r
+       }\r
+\r
+       hr = ConnectFilters();\r
+       if (FAILED(hr)) {\r
+               ERR("ConnectFilters\n");\r
+               goto error_failed;\r
+       }\r
+\r
+       g_dwAvgInterval = 333333;\r
+       g_dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
+       g_dwHeight = 480;\r
+       g_dwWidth = 640;\r
+       hr = SetDefaultValues();\r
+       if (hr != S_OK) {\r
+               ERR("SetDefaultValues\n");\r
+               goto error_failed;\r
+       }\r
+\r
+       INFO("Open successfully!!!\n");\r
+       return;\r
+\r
+error_failed:\r
+       CloseInterfaces();\r
+       CoUninitialize();\r
+       param->errCode = EINVAL;\r
+       ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
+}\r
+\r
+// MARUCAM_CMD_CLOSE\r
+void marucam_device_close(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+       param->top = 0;\r
+\r
+       CloseInterfaces();\r
+       CoUninitialize();\r
+       INFO("Close successfully!!!\n");\r
+}\r
+\r
+// MARUCAM_CMD_START_PREVIEW\r
+void marucam_device_start_preview(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       uint32_t width, height;\r
+       MaruCamParam *param = state->param;\r
+       param->top = 0;\r
+\r
+       INFO("%s\n", __func__);\r
+       assert(g_pCallback != NULL);\r
+       hr = ((HWCInPin*)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, g_pCallback);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to set IGrabCallback interface.\n");\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       hr = g_pMediaControl->lpVtbl->Run(g_pMediaControl);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to run media control.\n");\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 1;\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+\r
+       width = supported_dst_frames[cur_frame_idx].width;\r
+       height = supported_dst_frames[cur_frame_idx].height;\r
+       state->buf_size = height * ((width * supported_dst_pixfmts[cur_fmt_idx].bpp) >> 3);\r
+\r
+       INFO("Start preview!!!\n");\r
+}\r
+\r
+// MARUCAM_CMD_STOP_PREVIEW\r
+void marucam_device_stop_preview(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       MaruCamParam *param = state->param;\r
+       param->top = 0;\r
+\r
+       hr = ((HWCInPin*)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, NULL);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to set IGrabCallback interface.\n");\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       hr = g_pMediaControl->lpVtbl->Stop(g_pMediaControl);\r
+       if (FAILED(hr)) {\r
+               ERR("Failed to stop media control.\n");\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       qemu_mutex_lock(&state->thread_mutex);\r
+       state->streamon = 0;\r
+       qemu_mutex_unlock(&state->thread_mutex);\r
+       state->buf_size = 0;\r
+\r
+       INFO("Stop preview!!!\n");\r
+}\r
+\r
+// MARUCAM_CMD_S_PARAM\r
+void marucam_device_s_param(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       TRACE("setting fps : %d/%d\n", param->stack[0], param->stack[1]);\r
+}\r
+\r
+// MARUCAM_CMD_G_PARAM\r
+void marucam_device_g_param(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       TRACE("getting fps : 30/1\n");\r
+\r
+       param->stack[0] = 0x1000; // V4L2_CAP_TIMEPERFRAME\r
+       param->stack[1] = 1; // numerator;\r
+       param->stack[2] = 30; // denominator;\r
+}\r
+\r
+// MARUCAM_CMD_S_FMT\r
+void marucam_device_s_fmt(MaruCamState* state)\r
+{\r
+       uint32_t width, height, pixfmt, pidx, fidx;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       width = param->stack[0];                // width\r
+       height = param->stack[1];               // height\r
+       pixfmt = param->stack[2];               // pixelformat\r
+\r
+       for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {\r
+               if ((supported_dst_frames[fidx].width == width) &&\r
+                               (supported_dst_frames[fidx].height == height)) {\r
+                       break;\r
+               }\r
+       }\r
+       if (fidx == ARRAY_SIZE(supported_dst_frames)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {\r
+               if (supported_dst_pixfmts[pidx].fmt == pixfmt) {\r
+                       break;\r
+               }\r
+       }\r
+       if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\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
+               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
+       param->stack[1] = height;\r
+       param->stack[2] = 1; // V4L2_FIELD_NONE\r
+       param->stack[3] = pixfmt;\r
+       // bytes per line = (width * bpp) / 8\r
+       param->stack[4] = (width * supported_dst_pixfmts[pidx].bpp) >> 3;\r
+       param->stack[5] = param->stack[4] * height;     // height * bytesperline\r
+       param->stack[6] = 0;\r
+       param->stack[7] = 0;\r
+\r
+       cur_frame_idx = fidx;\r
+       cur_fmt_idx = pidx;\r
+\r
+       TRACE("Set format...\n");\r
+}\r
+\r
+// MARUCAM_CMD_G_FMT\r
+void marucam_device_g_fmt(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+\r
+       param->stack[0] = supported_dst_frames[cur_frame_idx].width;    // width\r
+       param->stack[1] = supported_dst_frames[cur_frame_idx].height;   // height\r
+       param->stack[2] = 1; // V4L2_FIELD_NONE\r
+       param->stack[3] = supported_dst_pixfmts[cur_fmt_idx].fmt;       // pixelformat\r
+       // bytes per line = (width * bpp) / 8\r
+       param->stack[4] = (param->stack[0] * supported_dst_pixfmts[cur_fmt_idx].bpp) >> 3;\r
+       param->stack[5] = param->stack[1] * param->stack[4];    // height * bytesperline\r
+       param->stack[6] = 0;\r
+       param->stack[7] = 0;\r
+\r
+       TRACE("Get format...\n");\r
+}\r
+\r
+void marucam_device_try_fmt(MaruCamState* state)\r
+{\r
+       uint32_t width, height, pixfmt, i;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       width = param->stack[0];                // width\r
+       height = param->stack[1];               // height\r
+       pixfmt = param->stack[2];               // pixelformat\r
+\r
+       for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {\r
+               if ((supported_dst_frames[i].width == width) &&\r
+                               (supported_dst_frames[i].height == height)) {\r
+                       break;\r
+               }\r
+       }\r
+       if (i == ARRAY_SIZE(supported_dst_frames)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {\r
+               if (supported_dst_pixfmts[i].fmt == pixfmt) {\r
+                       break;\r
+               }\r
+       }\r
+       if (i == ARRAY_SIZE(supported_dst_pixfmts)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       param->stack[0] = width;\r
+       param->stack[1] = height;\r
+       param->stack[2] = 1; // V4L2_FIELD_NONE\r
+       param->stack[3] = pixfmt;\r
+       // bytes per line = (width * bpp) / 8\r
+       param->stack[4] = (width * supported_dst_pixfmts[i].bpp) >> 3;\r
+       param->stack[5] = param->stack[4] * height;     // height * bytesperline\r
+       param->stack[6] = 0;\r
+       param->stack[7] = 0;\r
+}\r
+\r
+void marucam_device_enum_fmt(MaruCamState* state)\r
+{\r
+       uint32_t index;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       index = param->stack[0];\r
+\r
+       if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       param->stack[1] = 0;                                                    // flags = NONE;\r
+       param->stack[2] = supported_dst_pixfmts[index].fmt;     // pixelformat;\r
+       /* set description */\r
+       switch (supported_dst_pixfmts[index].fmt) {\r
+       case V4L2_PIX_FMT_YUYV:\r
+               memcpy(&param->stack[3], "YUY2", 32);\r
+               break;\r
+       case V4L2_PIX_FMT_YUV420:\r
+               memcpy(&param->stack[3], "YU12", 32);\r
+               break;\r
+       case V4L2_PIX_FMT_YVU420:\r
+               memcpy(&param->stack[3], "YV12", 32);\r
+               break;\r
+       }\r
+}\r
+\r
+void marucam_device_qctrl(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       uint32_t id, i;\r
+       long property, min, max, step, def_val, set_val;\r
+       char name[32] = {0,};\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       id = param->stack[0];\r
+\r
+       switch (id) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               TRACE("V4L2_CID_BRIGHTNESS\n");\r
+               property = VideoProcAmp_Brightness;\r
+               memcpy((void*)name, (void*)"brightness", 32);\r
+               i = 0;\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               TRACE("V4L2_CID_CONTRAST\n");\r
+               property = VideoProcAmp_Contrast;\r
+               memcpy((void*)name, (void*)"contrast", 32);\r
+               i = 1;\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               TRACE("V4L2_CID_SATURATION\n");\r
+               property = VideoProcAmp_Saturation;\r
+               memcpy((void*)name, (void*)"saturation", 32);\r
+               i = 2;\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               TRACE("V4L2_CID_SHARPNESS\n");\r
+               property = VideoProcAmp_Sharpness;\r
+               memcpy((void*)name, (void*)"sharpness", 32);\r
+               i = 3;\r
+               break;\r
+       default:\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       hr = QueryVideoProcAmp(property, &min, &max, &step, &def_val);\r
+       if (FAILED(hr)) {\r
+               param->errCode = EINVAL;\r
+               ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);\r
+               return;\r
+       } else {\r
+               qctrl_tbl[i].hit = 1;\r
+               qctrl_tbl[i].min = min;\r
+               qctrl_tbl[i].max = max;\r
+               qctrl_tbl[i].step = step;\r
+               qctrl_tbl[i].init_val = def_val;\r
+\r
+               if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {\r
+                       set_val = 0;\r
+               } else {\r
+                       set_val = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;\r
+               }\r
+               hr = SetVideoProcAmp(property, set_val);\r
+               if (FAILED(hr)) {\r
+                       param->errCode = EINVAL;\r
+                       ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);\r
+                       return;\r
+               }\r
+       }\r
+\r
+       param->stack[0] = id;\r
+       param->stack[1] = MARUCAM_CTRL_VALUE_MIN;       // minimum\r
+       param->stack[2] = MARUCAM_CTRL_VALUE_MAX;       // maximum\r
+       param->stack[3] = MARUCAM_CTRL_VALUE_STEP;// step\r
+       param->stack[4] = MARUCAM_CTRL_VALUE_MID;       // default_value\r
+       param->stack[5] = V4L2_CTRL_FLAG_SLIDER;\r
+       /* name field setting */\r
+       memcpy(&param->stack[6], (void*)name, sizeof(name)/sizeof(name[0]));\r
+}\r
+\r
+void marucam_device_s_ctrl(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       uint32_t i;\r
+       long property, set_val;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+\r
+       switch (param->stack[0]) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               i = 0;\r
+               property = VideoProcAmp_Brightness;\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               i = 1;\r
+               property = VideoProcAmp_Contrast;\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               i = 2;\r
+               property = VideoProcAmp_Saturation;\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               i = 3;\r
+               property = VideoProcAmp_Sharpness;\r
+               break;\r
+       default:\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       set_val = value_convert_from_guest(qctrl_tbl[i].min,\r
+                       qctrl_tbl[i].max, (long)param->stack[1]);\r
+       hr = SetVideoProcAmp(property, set_val);\r
+       if (FAILED(hr)) {\r
+               param->errCode = EINVAL;\r
+               ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);\r
+               return;\r
+       }\r
+}\r
+\r
+void marucam_device_g_ctrl(MaruCamState* state)\r
+{\r
+       HRESULT hr;\r
+       uint32_t i;\r
+       long property, get_val;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       switch (param->stack[0]) {\r
+       case V4L2_CID_BRIGHTNESS:\r
+               i = 0;\r
+               property = VideoProcAmp_Brightness;\r
+               break;\r
+       case V4L2_CID_CONTRAST:\r
+               i = 1;\r
+               property = VideoProcAmp_Contrast;\r
+               break;\r
+       case V4L2_CID_SATURATION:\r
+               i = 2;\r
+               property = VideoProcAmp_Saturation;\r
+               break;\r
+       case V4L2_CID_SHARPNESS:\r
+               i = 3;\r
+               property = VideoProcAmp_Sharpness;\r
+               break;\r
+       default:\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       hr = GetVideoProcAmp(property, &get_val);\r
+       if (FAILED(hr)) {\r
+               param->errCode = EINVAL;\r
+               ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);\r
+               return;\r
+       }\r
+       param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,\r
+                               qctrl_tbl[i].max, get_val);\r
+}\r
+\r
+void marucam_device_enum_fsizes(MaruCamState* state)\r
+{\r
+       uint32_t index, pixfmt, i;\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+       index = param->stack[0];\r
+       pixfmt = param->stack[1];\r
+\r
+       if (index >= ARRAY_SIZE(supported_dst_frames)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {\r
+               if (supported_dst_pixfmts[i].fmt == pixfmt)\r
+                       break;\r
+       }\r
+\r
+       if (i == ARRAY_SIZE(supported_dst_pixfmts)) {\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+\r
+       param->stack[0] = supported_dst_frames[index].width;\r
+       param->stack[1] = supported_dst_frames[index].height;\r
+}\r
+\r
+void marucam_device_enum_fintv(MaruCamState* state)\r
+{\r
+       MaruCamParam *param = state->param;\r
+\r
+       param->top = 0;\r
+\r
+       // switch by index(param->stack[0])\r
+       switch (param->stack[0]) {\r
+       case 0:\r
+               param->stack[1] = 30;   // denominator\r
+               break;\r
+       default:\r
+               param->errCode = EINVAL;\r
+               return;\r
+       }\r
+       param->stack[0] = 1;    // numerator\r
+}\r
+\r
+void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,\r
+               uint32_t width, uint32_t height, uint32_t yvu)\r
+{\r
+       uint32_t i, j;\r
+       const unsigned char *src1;\r
+       unsigned char *udest, *vdest;\r
+\r
+       /* copy the Y values */\r
+       src1 = src;\r
+       for (i = 0; i < height; i++) {\r
+               for (j = 0; j < width; j += 2) {\r
+                       *dest++ = src1[0];\r
+                       *dest++ = src1[2];\r
+                       src1 += 4;\r
+               }\r
+       }\r
+\r
+       /* copy the U and V values */\r
+       src++;                          /* point to V */\r
+       src1 = src + width * 2;         /* next line */\r
+       if (yvu) {\r
+               vdest = dest;\r
+               udest = dest + width * height / 4;\r
+       } else {\r
+               udest = dest;\r
+               vdest = dest + width * height / 4;\r
+       }\r
+       for (i = 0; i < height; i += 2) {\r
+               for (j = 0; j < width; j += 2) {\r
+                       *udest++ = ((int) src[0] + src1[0]) / 2;        /* U */\r
+                       *vdest++ = ((int) src[2] + src1[2]) / 2;        /* V */\r
+                       src += 4;\r
+                       src1 += 4;\r
+               }\r
+               src = src1;\r
+               src1 += width * 2;\r
+       }\r
+}\r