From ba774d33a80a0358802ec7e8a829814519a88999 Mon Sep 17 00:00:00 2001 From: "jinhyung.jo" Date: Fri, 14 Sep 2012 14:36:38 +0900 Subject: [PATCH] [Title] Printed some information of connected webcam in the log.(dev name, pixel format, resolution) [Type] Enhancement [Module] emulator qemu [Priority] minor [CQ#] [Redmine#] [Problem] [Cause] [Solution] [TestCase] --- tizen/src/hw/maru_camera_common.h | 2 +- tizen/src/hw/maru_camera_linux_pci.c | 111 +++++++++++++++--- tizen/src/hw/maru_camera_win32_pci.c | 217 +++++++++++++++++++++++++++++------ vl.c | 21 ++-- 4 files changed, 289 insertions(+), 62 deletions(-) diff --git a/tizen/src/hw/maru_camera_common.h b/tizen/src/hw/maru_camera_common.h index e06cea6..a0b4e5b 100644 --- a/tizen/src/hw/maru_camera_common.h +++ b/tizen/src/hw/maru_camera_common.h @@ -89,7 +89,7 @@ struct MaruCamState { /* ----------------------------------------------------------------------------- */ /* Fucntion prototype */ /* ----------------------------------------------------------------------------- */ -int marucam_device_check(void); +int marucam_device_check(int log_flag); void marucam_device_init(MaruCamState *state); void marucam_device_open(MaruCamState *state); void marucam_device_close(MaruCamState *state); diff --git a/tizen/src/hw/maru_camera_linux_pci.c b/tizen/src/hw/maru_camera_linux_pci.c index 9afcfdc..628b021 100644 --- a/tizen/src/hw/maru_camera_linux_pci.c +++ b/tizen/src/hw/maru_camera_linux_pci.c @@ -58,6 +58,17 @@ static struct v4l2_format dst_fmt; #define CLEAR(x) memset(&(x), 0, sizeof(x)) +static int yioctl(int fd, int req, void *arg) +{ + int r; + + do { + r = ioctl(fd, req, arg); + } while ( r < 0 && errno == EINTR); + + return r; +} + static int xioctl(int fd, int req, void *arg) { int r; @@ -358,39 +369,102 @@ wait_worker_thread: return NULL; } -int marucam_device_check(void) +int marucam_device_check(int log_flag) { int tmp_fd; + struct timeval t1, t2; struct stat st; + struct v4l2_fmtdesc format; + struct v4l2_frmsizeenum size; struct v4l2_capability cap; + int ret = 0; + gettimeofday(&t1, NULL); if (stat(dev_name, &st) < 0) { - INFO("Cannot identify '%s': %s\n", dev_name, strerror(errno)); + fprintf(stdout, "[Webcam] Cannot identify '%s': %s\n", + dev_name, strerror(errno)); } else { if (!S_ISCHR(st.st_mode)) { - INFO("%s is no character device.\n", dev_name); + fprintf(stdout, "[Webcam] %s is no character device.\n", + dev_name); } } tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0); if (tmp_fd < 0) { - ERR("Camera device open failed.(%s)\n", dev_name); - return 0; + fprintf(stdout, "[Webcam] Camera device open failed.(%s)\n", dev_name); + goto error; } if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) { - ERR("Could not qeury video capabilities\n"); - close(tmp_fd); - return 0; + fprintf(stdout, "[Webcam] Could not qeury video capabilities\n"); + goto error; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) || !(cap.capabilities & V4L2_CAP_STREAMING)) { - ERR("Not supported video driver.\n"); - close(tmp_fd); - return 0; + fprintf(stdout, "[Webcam] Not supported video driver.\n"); + goto error; } + ret = 1; + if (log_flag) { + fprintf(stdout, "[Webcam] Driver : %s\n", cap.driver); + fprintf(stdout, "[Webcam] Card : %s\n", cap.card); + fprintf(stdout, "[Webcam] Bus info : %s\n", cap.bus_info); + + CLEAR(format); + format.index = 0; + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) { + goto error; + } + + do { + CLEAR(size); + size.index = 0; + size.pixel_format = format.pixelformat; + + fprintf(stdout, "[Webcam] PixelFormat : %c%c%c%c\n", + (char)(format.pixelformat), + (char)(format.pixelformat >> 8), + (char)(format.pixelformat >> 16), + (char)(format.pixelformat >> 24)); + + if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) { + goto error; + } + + if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { + do { + fprintf(stdout, "[Webcam] got discrete frame size %dx%d\n", + size.discrete.width, size.discrete.height); + size.index++; + } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0); + } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + fprintf(stdout, "[Webcam] we have stepwise frame sizes:\n"); + fprintf(stdout, "[Webcam] min width: %d, min height: %d\n", + size.stepwise.min_width, size.stepwise.min_height); + fprintf(stdout, "[Webcam] max width: %d, max height: %d\n", + size.stepwise.max_width, size.stepwise.max_height); + fprintf(stdout, "[Webcam] step width: %d, step height: %d\n", + size.stepwise.step_width, size.stepwise.step_height); + } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { + fprintf(stdout, "[Webcam] we have continuous frame sizes:\n"); + fprintf(stdout, "[Webcam] min width: %d, min height: %d\n", + size.stepwise.min_width, size.stepwise.min_height); + fprintf(stdout, "[Webcam] max width: %d, max height: %d\n", + size.stepwise.max_width, size.stepwise.max_height); + + } + format.index++; + } while (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) >= 0); + } +error: close(tmp_fd); - return 1; + gettimeofday(&t2, NULL); + fprintf(stdout, "[Webcam] Elapsed time : %lu:%06lu\n", + t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec); + return ret; } void marucam_device_init(MaruCamState* state) @@ -419,8 +493,15 @@ void marucam_device_start_preview(MaruCamState* state) struct timespec req; req.tv_sec = 0; req.tv_nsec = 10000000; - - INFO("Starting preview!\n"); + INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n", + (char)(dst_fmt.fmt.pix.pixelformat), + (char)(dst_fmt.fmt.pix.pixelformat >> 8), + (char)(dst_fmt.fmt.pix.pixelformat >> 16), + (char)(dst_fmt.fmt.pix.pixelformat >> 24), + dst_fmt.fmt.pix.width, + dst_fmt.fmt.pix.height, + dst_fmt.fmt.pix.sizeimage); + INFO("Starting preview\n"); qemu_mutex_lock(&state->thread_mutex); qemu_cond_signal(&state->thread_cond); qemu_mutex_unlock(&state->thread_mutex); @@ -445,7 +526,7 @@ void marucam_device_stop_preview(MaruCamState* state) while (!is_stream_paused(state)) nanosleep(&req, NULL); - INFO("Stopping preview!\n"); + INFO("Stopping preview\n"); } void marucam_device_s_param(MaruCamState* state) diff --git a/tizen/src/hw/maru_camera_win32_pci.c b/tizen/src/hw/maru_camera_win32_pci.c index 71320f3..901a4c1 100644 --- a/tizen/src/hw/maru_camera_win32_pci.c +++ b/tizen/src/hw/maru_camera_win32_pci.c @@ -1555,69 +1555,208 @@ static STDMETHODIMP SetVideoProcAmp(long nProperty, long value) return hr; } -int marucam_device_check(void) +static char* __wchar_to_char(const WCHAR *pwstr) { + char *pstr = NULL; + int len = 0; + + len = wcslen(pwstr) + 1; + pstr = (char *)g_malloc0(sizeof(char) * len); + wcstombs(pstr, pwstr, len + 1); + + return pstr; +} + +int marucam_device_check(int log_flag) +{ + struct timeval t1, t2; int ret = 0; + char *device_name = NULL; HRESULT hr = E_FAIL; ICreateDevEnum *pCreateDevEnum = NULL; + IGraphBuilder *pGB = NULL; + ICaptureGraphBuilder2 *pCGB = NULL; + IBaseFilter *pSrcFilter = NULL; IEnumMoniker *pEnumMK = NULL; IMoniker *pMoniKer = NULL; + IAMStreamConfig *pSConfig = NULL; + int iCount = 0, iSize = 0; + gettimeofday(&t1, NULL); hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) { - ERR("[%s] failed to CoInitailizeEx\n", __func__); - goto error; + fprintf(stdout, "[Webcam] failed to CoInitailizeEx\n"); + goto leave_check; } - hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)&pCreateDevEnum); + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, + CLSCTX_INPROC, + &IID_IGraphBuilder, + (void**)&pGB); if (FAILED(hr)) { - ERR("[%s] failed to create instance of CLSID_SystemDeviceEnum\n", __func__); - goto error; + fprintf(stdout, "[Webcam] Failed to create GraphBuilder, 0x%x\n", hr); + goto leave_check; } - hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, &CLSID_VideoInputDeviceCategory, &pEnumMK, 0); - if (FAILED(hr)) - { - ERR("[%s] failed to create class enumerator\n", __func__); - goto error; + hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, + CLSCTX_INPROC, + &IID_ICaptureGraphBuilder2, + (void**)&pCGB); + if (FAILED(hr)) { + fprintf(stdout, + "[Webcam] Failed to create CaptureGraphBuilder2, 0x%x\n", hr); + goto leave_check; } - if (!pEnumMK) - { - ERR("[%s] class enumerator is NULL!!\n", __func__); - goto error; + hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] Failed to SetFiltergraph, 0x%x\n", hr); + goto leave_check; + } + + hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, + CLSCTX_INPROC, + &IID_ICreateDevEnum, + (void**)&pCreateDevEnum); + if (FAILED(hr)) { + fprintf(stdout, + "[Webcam] failed to create instance of CLSID_SystemDeviceEnum\n"); + goto leave_check; + } + + hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, + &CLSID_VideoInputDeviceCategory, &pEnumMK, 0); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] failed to create class enumerator\n"); + goto leave_check; + } + + if (!pEnumMK) { + fprintf(stdout, "[Webcam] class enumerator is NULL!!\n"); + goto leave_check; } pEnumMK->lpVtbl->Reset(pEnumMK); hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL); - if (hr == S_FALSE) + if (FAILED(hr) || (hr == S_FALSE)) { + fprintf(stdout, "[Webcam] enum moniker returns a invalid value.\n"); + goto leave_check; + } + + IPropertyBag *pBag = NULL; + hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0, + &IID_IPropertyBag, + (void **)&pBag); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] failed to bind to storage.\n"); + goto leave_check; + } else { + VARIANT var; + var.vt = VT_BSTR; + hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL); + if (hr == S_OK) { + ret = 1; + if (!log_flag) { + SysFreeString(var.bstrVal); + SAFE_RELEASE(pBag); + SAFE_RELEASE(pMoniKer); + goto leave_check; + } + device_name = __wchar_to_char(var.bstrVal); + fprintf(stdout, "[Webcam] Device name : %s\n", device_name); + g_free(device_name); + hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL, + &IID_IBaseFilter, + (void**)&pSrcFilter); + if (FAILED(hr)) { + fprintf(stdout, + "[Webcam] Counldn't bind moniker to filter object!!\n"); + goto leave_check; + } else { + pSrcFilter->lpVtbl->AddRef(pSrcFilter); + } + SysFreeString(var.bstrVal); + } + SAFE_RELEASE(pBag); + } + SAFE_RELEASE(pMoniKer); + + hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture"); + if (hr != S_OK && hr != S_FALSE) { + fprintf(stdout, + "[Webcam] Counldn't add Video Capture filter to our graph!\n"); + goto leave_check; + } + + hr = pCGB->lpVtbl->FindInterface(pCGB, &PIN_CATEGORY_CAPTURE, 0, + pSrcFilter, &IID_IAMStreamConfig, + (void**)&pSConfig); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] failed to FindInterface method\n"); + goto leave_check; + } + + hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize); + if (FAILED(hr)) { - ERR("[%s] enum moniker returns a invalid value.\n", __func__); - hr = E_FAIL; + fprintf(stdout, "[Webcam] failed to GetNumberOfCapabilities method\n"); + goto leave_check; } - if (SUCCEEDED(hr)) + + if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) { - IPropertyBag *pBag = NULL; - hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0, &IID_IPropertyBag, (void **)&pBag); - if (SUCCEEDED(hr)) + int iFormat = 0; + for (iFormat = 0; iFormat < iCount; iFormat++) { - VARIANT var; - var.vt = VT_BSTR; - hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL); - if (hr == NOERROR) + VIDEO_STREAM_CONFIG_CAPS scc; + AM_MEDIA_TYPE *pmtConfig; + + hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig, + (BYTE*)&scc); + if (hr == S_OK) { - ret = 1; - SysFreeString(var.bstrVal); + if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) + { + VIDEOINFOHEADER *pvi = + (VIDEOINFOHEADER *)pmtConfig->pbFormat; + if (pvi->bmiHeader.biCompression == BI_RGB) { + fprintf(stdout, "[Webcam] RGB BitCount: %d, %ux%u\n", + pvi->bmiHeader.biBitCount, + pvi->bmiHeader.biWidth, + pvi->bmiHeader.biHeight); + } else { + fprintf(stdout, + "[Webcam] PixelFormat: %c%c%c%c, %ux%u\n", + (char)(pvi->bmiHeader.biCompression), + (char)(pvi->bmiHeader.biCompression >> 8), + (char)(pvi->bmiHeader.biCompression >> 16), + (char)(pvi->bmiHeader.biCompression >> 24), + pvi->bmiHeader.biWidth, + pvi->bmiHeader.biHeight); + } + } + DeleteMediaType(pmtConfig); } - SAFE_RELEASE(pBag); } - SAFE_RELEASE(pMoniKer); } -error: + hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] Failed to remove source filer. 0x%x\n", hr); + } + +leave_check: + SAFE_RELEASE(pSConfig); + SAFE_RELEASE(pSrcFilter); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); SAFE_RELEASE(pEnumMK); SAFE_RELEASE(pCreateDevEnum); CoUninitialize(); + gettimeofday(&t2, NULL); + fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n", + t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec); + return ret; } @@ -1678,7 +1817,7 @@ void marucam_device_open(MaruCamState* state) goto error_failed; } - INFO("Open successfully!!!\n"); + INFO("Opened\n"); return; error_failed: @@ -1700,7 +1839,7 @@ void marucam_device_close(MaruCamState* state) RemoveFilters(); CloseInterfaces(); CoUninitialize(); - INFO("Close successfully!!!\n"); + INFO("Closed\n"); } /* MARUCAM_CMD_START_PREVIEW */ @@ -1717,8 +1856,11 @@ void marucam_device_start_preview(MaruCamState* state) pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt; state->buf_size = get_sizeimage(pixfmt, width, height); - INFO("Pixfmt(0x%x), Width:Height(%d:%d), buffer size(%u)\n", - pixfmt, width, height, state->buf_size); + INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u)\n", + (char)(pixfmt), (char)(pixfmt >> 8), + (char)(pixfmt >> 16), (char)(pixfmt >> 24), + width, height, state->buf_size); + INFO("Starting preview\n"); assert(g_pCallback != NULL); hr = ((HWCInPin*)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, g_pCallback); @@ -1739,7 +1881,7 @@ void marucam_device_start_preview(MaruCamState* state) state->streamon = 1; qemu_mutex_unlock(&state->thread_mutex); - INFO("Start preview!!!\n"); + INFO("Streaming on ......\n"); } /* MARUCAM_CMD_STOP_PREVIEW */ @@ -1749,6 +1891,7 @@ void marucam_device_stop_preview(MaruCamState* state) MaruCamParam *param = state->param; param->top = 0; + INFO("...... Streaming off\n"); qemu_mutex_lock(&state->thread_mutex); state->streamon = 0; qemu_mutex_unlock(&state->thread_mutex); @@ -1769,7 +1912,7 @@ void marucam_device_stop_preview(MaruCamState* state) state->buf_size = 0; - INFO("Stop preview!!!\n"); + INFO("Stopping preview\n"); } /* MARUCAM_CMD_S_PARAM */ diff --git a/vl.c b/vl.c index e07e583..53abfd1 100644 --- a/vl.c +++ b/vl.c @@ -269,8 +269,10 @@ extern int gl_acceleration_capability_check (void); int enable_gl = 0; int capability_check_gl = 0; #endif -#if defined(CONFIG_MARU) -extern int marucam_device_check(void); +#if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN)) +#define WEBCAM_INFO_IGNORE 0x00 +#define WEBCAM_INFO_WRITE 0x04 +extern int marucam_device_check(int log_flag); int is_webcam_enabled = 0; #endif @@ -1808,7 +1810,7 @@ static int device_init_func(QemuOpts *opts, void *opaque) } } #endif -#if defined(CONFIG_MARU) +#if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN)) if (!is_webcam_enabled) { const char *driver = qemu_opt_get(opts, "driver"); if (driver && (strcmp (driver, MARUCAM_DEV_NAME) == 0)) { @@ -3264,26 +3266,27 @@ fprintf(stdout, "kernel command : %s\n", kernel_cmdline); } #endif -#if defined(CONFIG_MARU) - is_webcam_enabled = marucam_device_check(); +#if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN)) + is_webcam_enabled = marucam_device_check(WEBCAM_INFO_WRITE); if (!is_webcam_enabled) { - fprintf (stderr, "WARNING: Webcam support was disabled due to " - "the fail of webcam capability check!\n"); + fprintf (stderr, "[Webcam] Webcam support was disabled " + "due to the fail of webcam capability check!\n"); } gchar *tmp_cam_kcmd = kernel_cmdline; kernel_cmdline = g_strdup_printf("%s enable_cam=%d", tmp_cam_kcmd, is_webcam_enabled); - fprintf(stdout, "kernel command : %s\n", kernel_cmdline); g_free(tmp_cam_kcmd); if (is_webcam_enabled) { device_opt_finding_t devp = {MARUCAM_DEV_NAME, 0}; qemu_opts_foreach(qemu_find_opts("device"), find_device_opt, &devp, 0); if (devp.found == 0) { - if (!qemu_opts_parse(qemu_find_opts("device"), MARUCAM_DEV_NAME, "driver")) { + if (!qemu_opts_parse(qemu_find_opts("device"), MARUCAM_DEV_NAME, 1)) { + fprintf(stderr, "Failed to initialize the marucam device.\n"); exit(1); } } + fprintf(stdout, "[Webcam] Webcam support was enabled.\n"); } #endif -- 2.7.4