1 /*********************************************************************
2 * modified _uvc_handle_events to improve performance on Android
3 * Copyright (C) 2014 saki@serenegiant All rights reserved.
4 *********************************************************************/
5 /*********************************************************************
6 * Software License Agreement (BSD License)
8 * Copyright (C) 2010-2012 Ken Tossell
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
21 * * Neither the name of the author nor other contributors may be
22 * used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *********************************************************************/
39 \mainpage libuvc: a cross-platform library for USB video devices
41 \b libuvc is a library that supports enumeration, control and streaming
42 for USB Video Class (UVC) devices, such as consumer webcams.
44 \section features Features
45 \li UVC device \ref device "discovery and management" API
46 \li \ref streaming "Video streaming" (device to host) with asynchronous/callback and synchronous/polling modes
47 \li Read/write access to standard \ref ctrl "device settings"
48 \li \ref frame "Conversion" between various formats: RGB, YUV, JPEG, etc.
49 \li Tested on Mac and Linux, portable to Windows and some BSDs
51 \section roadmap Roadmap
52 \li Bulk-mode image capture
53 \li One-shot image capture
54 \li Improved support for standard settings
55 \li Support for "extended" (vendor-defined) settings
58 \p The source code can be found at https://github.com/ktossell/libuvc. To build
59 the library, install <a href="http://libusb.org/">libusb</a> 1.0+ and run:
62 $ git clone https://github.com/ktossell/libuvc.git
66 $ cmake -DCMAKE_BUILD_TYPE=Release ..
67 $ make && make install
71 In this example, libuvc is used to acquire images in a 30 fps, 640x480
72 YUV stream from a UVC device such as a standard webcam.
79 * @defgroup init Library initialization/deinitialization
80 * @brief Setup routines used to construct UVC access contexts
82 #include "libuvc/libuvc.h"
83 #include "libuvc/libuvc_internal.h"
84 #if defined(__ANDROID__)
87 #include <sys/resource.h>
88 #endif // defined(__ANDROID__)
91 * @brief Event handler thread
92 * There's one of these per UVC context.
93 * @todo We shouldn't run this if we don't own the USB context
95 void *_uvc_handle_events(void *arg) {
96 uvc_context_t *ctx = (uvc_context_t *) arg;
98 #if defined(__ANDROID__)
99 // try to increase thread priority
100 int prio = getpriority(PRIO_PROCESS, 0);
102 if (UNLIKELY(getpriority(PRIO_PROCESS, 0) >= prio)) {
103 LOGW("could not change thread priority");
106 for (; !ctx->kill_handler_thread ;)
107 libusb_handle_events(ctx->usb_ctx);
111 /** @brief Initializes the UVC context
114 * @note If you provide your own USB context, you must handle
115 * libusb event processing using a function such as libusb_handle_events.
117 * @param[out] pctx The location where the context reference should be stored.
118 * @param[in] usb_ctx Optional USB context to use
119 * @return Error opening context or UVC_SUCCESS
121 uvc_error_t uvc_init2(uvc_context_t **pctx, struct libusb_context *usb_ctx, const char *usbfs) {
122 uvc_error_t ret = UVC_SUCCESS;
123 uvc_context_t *ctx = calloc(1, sizeof(*ctx));
125 if (usb_ctx == NULL) {
126 if (usbfs && strlen(usbfs) > 0) {
127 LOGD("call #libusb_init2");
128 ret = libusb_init2(&ctx->usb_ctx, usbfs);
130 LOGD("call #libusb_init");
131 ret = libusb_init(&ctx->usb_ctx);
133 ctx->own_usb_ctx = 1;
134 if (UNLIKELY(ret != UVC_SUCCESS)) {
135 LOGW("failed:err=%d", ret);
140 ctx->own_usb_ctx = 0;
141 ctx->usb_ctx = usb_ctx;
150 uvc_error_t uvc_init(uvc_context_t **pctx, struct libusb_context *usb_ctx) {
151 return uvc_init2(pctx, usb_ctx, NULL);
153 uvc_error_t ret = UVC_SUCCESS;
154 uvc_context_t *ctx = calloc(1, sizeof(*ctx));
156 if (usb_ctx == NULL) {
157 ret = libusb_init(&ctx->usb_ctx);
158 ctx->own_usb_ctx = 1;
159 if (UNLIKELY(ret != UVC_SUCCESS)) {
164 ctx->own_usb_ctx = 0;
165 ctx->usb_ctx = usb_ctx;
176 * @brief Closes the UVC context, shutting down any active cameras.
179 * @note This function invalides any existing references to the context's
182 * If no USB context was provided to #uvc_init, the UVC-specific USB
183 * context will be destroyed.
185 * @param ctx UVC context to shut down
187 void uvc_exit(uvc_context_t *ctx) {
188 uvc_device_handle_t *devh;
190 DL_FOREACH(ctx->open_devices, devh)
195 if (ctx->own_usb_ctx)
196 libusb_exit(ctx->usb_ctx);
203 * @brief Spawns a handler thread for the context
206 * This should be called at the end of a successful uvc_open if no devices
207 * are already open (and being handled).
209 void uvc_start_handler_thread(uvc_context_t *ctx) {
210 if (ctx->own_usb_ctx) {
211 pthread_create(&ctx->handler_thread, NULL, _uvc_handle_events, (void*) ctx);