From a31fee156fc3504314dfaa8eda7e8f42350c8961 Mon Sep 17 00:00:00 2001 From: "jinhyung.jo" Date: Tue, 28 May 2013 17:13:21 +0900 Subject: [PATCH] check-cam : add new sources to check the webcam Check the availability of a host webcam. Signed-off-by: Jinhyung Jo --- tizen/src/Makefile | 27 +++++- tizen/src/check_cam.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 tizen/src/check_cam.c diff --git a/tizen/src/Makefile b/tizen/src/Makefile index 7ca25eb..ec4c96c 100644 --- a/tizen/src/Makefile +++ b/tizen/src/Makefile @@ -12,7 +12,7 @@ config-host.mak: endif all: qemu skin_client -qemu: build_info ffmpeg_install check_hax +qemu: build_info ffmpeg_install check_hax check_cam cd ../../ && $(MAKE) qemu_clean: cd ../../ && $(MAKE) clean @@ -28,6 +28,18 @@ ifdef CONFIG_DARWIN $(CC) -mmacosx-version-min=10.4 -o check-hax check_hax.c endif +check_cam: + @echo "build check cam" +ifdef CONFIG_WIN32 + $(CC) -o check-cam.exe check_cam.c -lole32 -loleaut32 -luuid -lstrmiids +endif +ifdef CONFIG_LINUX + $(CC) -o check-cam check_cam.c -lv4l2 -lv4lconvert +endif +ifdef CONFIG_DARWIN + $(CC) -o check-cam check_cam.c +endif + skin_client: ant -buildfile skin/client/build.xml make-jar @@ -50,10 +62,13 @@ ffmpeg_distclean: clean: ffmpeg_clean qemu_clean ifdef CONFIG_WIN32 - rm -f check-hax.exe + rm -f check-hax.exe check-cam.exe endif ifdef CONFIG_DARWIN - rm -f check-hax + rm -f check-hax check-cam +endif +ifdef CONFIG_LINUX + rm -f check-cam endif distclean: ffmpeg_distclean qemu_distclean @@ -103,14 +118,17 @@ endif ifdef CONFIG_WIN32 cp ../../i386-softmmu/check-gl.exe $(EMUL_DIR)/bin cp check-hax.exe $(EMUL_DIR)/bin + cp check-cam.exe $(EMUL_DIR)/bin endif ifdef CONFIG_DARWIN cp ../../i386-softmmu/check-gl $(EMUL_DIR)/bin cp check-hax $(EMUL_DIR)/bin + cp check-cam $(EMUL_DIR)/bin cp sdbscript $(EMUL_DIR)/bin endif ifdef CONFIG_LINUX cp ../../i386-softmmu/check-gl $(EMUL_DIR)/bin + cp check-cam $(EMUL_DIR)/bin cp -pPr ../distrib/initscript/tizen-kvm $(EMUL_DIR)/etc cp -pPr ../distrib/initscript/45-tizen-kvm.rules $(EMUL_DIR)/etc endif @@ -215,15 +233,18 @@ endif ifdef CONFIG_WIN32 cp ../../i386-softmmu/check-gl.exe $(DIBS_COMMON_DIR)/bin cp check-hax.exe $(DIBS_COMMON_DIR)/bin + cp check-cam.exe $(DIBS_COMMON_DIR)/bin endif ifdef CONFIG_DARWIN cp ../../i386-softmmu/check-gl $(DIBS_COMMON_DIR)/bin cp check-hax $(DIBS_COMMON_DIR)/bin + cp check-cam $(DIBS_COMMON_DIR)/bin cp sdbscript $(DIBS_COMMON_DIR)/bin endif ifdef CONFIG_LINUX cp ../../i386-softmmu/check-gl $(DIBS_COMMON_DIR)/bin + cp check-cam $(DIBS_COMMON_DIR)/bin echo "Copying tizen-kvm to $(DIBS_X86_DIR)/etc" cp -pPr ../distrib/initscript/tizen-kvm $(DIBS_X86_DIR)/etc cp -pPr ../distrib/initscript/45-tizen-kvm.rules $(DIBS_X86_DIR)/etc diff --git a/tizen/src/check_cam.c b/tizen/src/check_cam.c new file mode 100644 index 0000000..ddfaa5f --- /dev/null +++ b/tizen/src/check_cam.c @@ -0,0 +1,255 @@ +/* + * check the availability of a host webcam. + * + * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * Jinhyung Jo + * YeongKyoon Lee + * + * 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 + * + */ + +#ifdef _WIN32 +/* Windows implement */ +#include +#include +#define CINTERFACE +#define COBJMACROS +#include "ocidl.h" +#include "errors.h" /* for VFW_E_XXXX */ +#include "mmsystem.h" /* for MAKEFOURCC macro */ +#include "hw/maru_camera_win32_interface.h" + +/* + * COM Interface implementations + * + */ + +#define SAFE_RELEASE(x) \ + do { \ + if (x) { \ + (x)->lpVtbl->Release(x); \ + x = NULL; \ + } \ + } while (0) + +static int check_cam(void) +{ + int ret = 0; + char *device_name = NULL; + HRESULT hr = E_FAIL; + ICreateDevEnum *pCreateDevEnum = NULL; + IGraphBuilder *pGB = NULL; + ICaptureGraphBuilder2 *pCGB = NULL; + IEnumMoniker *pEnumMK = NULL; + IMoniker *pMoniKer = NULL; + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] failed to CoInitailizeEx\n"); + return ret; + } + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, + CLSCTX_INPROC, + &IID_IGraphBuilder, + (void **)&pGB); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] Failed to create GraphBuilder, 0x%x\n", hr); + CoUninitialize(); + return ret; + } + + 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); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] Failed to SetFiltergraph, 0x%x\n", hr); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + 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"); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum, + &CLSID_VideoInputDeviceCategory, &pEnumMK, 0); + if (FAILED(hr)) { + fprintf(stdout, "[Webcam] failed to create class enumerator\n"); + SAFE_RELEASE(pCreateDevEnum); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + if (!pEnumMK) { + fprintf(stdout, "[Webcam] class enumerator is NULL!!\n"); + SAFE_RELEASE(pCreateDevEnum); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + pEnumMK->lpVtbl->Reset(pEnumMK); + hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL); + if (FAILED(hr) || (hr == S_FALSE)) { + fprintf(stdout, "[Webcam] enum moniker returns a invalid value.\n"); + SAFE_RELEASE(pEnumMK); + SAFE_RELEASE(pCreateDevEnum); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } + + 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"); + SAFE_RELEASE(pEnumMK); + SAFE_RELEASE(pCreateDevEnum); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + CoUninitialize(); + return ret; + } else { + VARIANT var; + var.vt = VT_BSTR; + hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL); + if (hr == S_OK) { + ret = 1; + fprintf(stdout, "[Webcam] Check success\n"); + } else { + fprintf(stdout, "[Webcam] failed to find to webcam device.\n"); + } + SysFreeString(var.bstrVal); + SAFE_RELEASE(pBag); + } + SAFE_RELEASE(pMoniKer); + SAFE_RELEASE(pCGB); + SAFE_RELEASE(pGB); + SAFE_RELEASE(pEnumMK); + SAFE_RELEASE(pCreateDevEnum); + CoUninitialize(); + + return ret; +} + + +#elif __linux + +/* Linux implement */ +#include +#include +#include +#include +#include +#include + +static int check_cam(void) +{ + int tmp_fd; + struct stat st; + struct v4l2_fmtdesc format; + struct v4l2_frmsizeenum size; + struct v4l2_capability cap; + char dev_name[] = "/dev/video0"; + int ret = 0; + + if (stat(dev_name, &st) < 0) { + fprintf(stdout, "[Webcam] Cannot identify '%s': %d\n", + dev_name, errno); + } else { + if (!S_ISCHR(st.st_mode)) { + 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) { + fprintf(stdout, "[Webcam] Camera device open failed: %s\n", dev_name); + return ret; + } + if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) { + fprintf(stdout, "[Webcam] Could not qeury video capabilities\n"); + close(tmp_fd); + return ret; + } + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) || + !(cap.capabilities & V4L2_CAP_STREAMING)) { + fprintf(stdout, "[Webcam] Not supported video driver\n"); + close(tmp_fd); + return ret; + } + fprintf(stdout, "[Webcam] Check success\n"); + close(tmp_fd); + + return 1; +} + +#elif __APPLE__ +/* MacOS, Now, not implemented. */ +static int check_cam(void) +{ + return 1; +} + +#else +/* Unsupported OS */ +static int check_cam(void) +{ + fprintf(stdout, "[Webcam] Unsupported OS. Not available.\n"); + return 0; +} +#endif /* end of the if statement */ + +int main(int argc, char** argv) +{ + return check_cam(); +} + -- 2.7.4