stream pushing ok without access permission of /dev/video0
[rtmpclient.git] / app / src / main / jni / libuvc / src / init.c
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)
7  *
8  *  Copyright (C) 2010-2012 Ken Tossell
9  *  All rights reserved.
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
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.
24  *
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  *********************************************************************/
38 /**
39 \mainpage libuvc: a cross-platform library for USB video devices
40
41 \b libuvc is a library that supports enumeration, control and streaming
42 for USB Video Class (UVC) devices, such as consumer webcams.
43
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
50
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
56
57 \section misc Misc.
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:
60
61 \code
62 $ git clone https://github.com/ktossell/libuvc.git
63 $ cd libuvc
64 $ mkdir build
65 $ cd build
66 $ cmake -DCMAKE_BUILD_TYPE=Release ..
67 $ make && make install
68 \endcode
69
70 \section Example
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.
73
74 \include example.c
75
76 */
77
78 /**
79  * @defgroup init Library initialization/deinitialization
80  * @brief Setup routines used to construct UVC access contexts
81  */
82 #include "libuvc/libuvc.h"
83 #include "libuvc/libuvc_internal.h"
84 #if defined(__ANDROID__)
85 #include <unistd.h>
86 #include <sys/time.h>
87 #include <sys/resource.h>
88 #endif  // defined(__ANDROID__)
89
90 /** @internal
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
94  */
95 void *_uvc_handle_events(void *arg) {
96         uvc_context_t *ctx = (uvc_context_t *) arg;
97
98 #if defined(__ANDROID__)
99         // try to increase thread priority
100         int prio = getpriority(PRIO_PROCESS, 0);
101         nice(-18);
102         if (UNLIKELY(getpriority(PRIO_PROCESS, 0) >= prio)) {
103                 LOGW("could not change thread priority");
104         }
105 #endif
106         for (; !ctx->kill_handler_thread ;)
107                 libusb_handle_events(ctx->usb_ctx);
108         return NULL;
109 }
110
111 /** @brief Initializes the UVC context
112  * @ingroup init
113  *
114  * @note If you provide your own USB context, you must handle
115  * libusb event processing using a function such as libusb_handle_events.
116  *
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
120  */
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));
124
125         if (usb_ctx == NULL) {
126                 if (usbfs && strlen(usbfs) > 0) {
127                         LOGD("call #libusb_init2");
128                         ret = libusb_init2(&ctx->usb_ctx, usbfs);
129                 } else {
130                         LOGD("call #libusb_init");
131                         ret = libusb_init(&ctx->usb_ctx);
132                 }
133                 ctx->own_usb_ctx = 1;
134                 if (UNLIKELY(ret != UVC_SUCCESS)) {
135                         LOGW("failed:err=%d", ret);
136                         free(ctx);
137                         ctx = NULL;
138                 }
139         } else {
140                 ctx->own_usb_ctx = 0;
141                 ctx->usb_ctx = usb_ctx;
142         }
143
144         if (ctx != NULL)
145                 *pctx = ctx;
146
147         return ret;
148 }
149
150 uvc_error_t uvc_init(uvc_context_t **pctx, struct libusb_context *usb_ctx) {
151         return uvc_init2(pctx, usb_ctx, NULL);
152 #if 0
153         uvc_error_t ret = UVC_SUCCESS;
154         uvc_context_t *ctx = calloc(1, sizeof(*ctx));
155
156         if (usb_ctx == NULL) {
157                 ret = libusb_init(&ctx->usb_ctx);
158                 ctx->own_usb_ctx = 1;
159                 if (UNLIKELY(ret != UVC_SUCCESS)) {
160                         free(ctx);
161                         ctx = NULL;
162                 }
163         } else {
164                 ctx->own_usb_ctx = 0;
165                 ctx->usb_ctx = usb_ctx;
166         }
167
168         if (ctx != NULL)
169                 *pctx = ctx;
170
171         return ret;
172 #endif
173 }
174
175 /**
176  * @brief Closes the UVC context, shutting down any active cameras.
177  * @ingroup init
178  *
179  * @note This function invalides any existing references to the context's
180  * cameras.
181  *
182  * If no USB context was provided to #uvc_init, the UVC-specific USB
183  * context will be destroyed.
184  *
185  * @param ctx UVC context to shut down
186  */
187 void uvc_exit(uvc_context_t *ctx) {
188         uvc_device_handle_t *devh;
189
190         DL_FOREACH(ctx->open_devices, devh)
191         {
192                 uvc_close(devh);
193         }
194
195         if (ctx->own_usb_ctx)
196                 libusb_exit(ctx->usb_ctx);
197
198         free(ctx);
199 }
200
201 /**
202  * @internal
203  * @brief Spawns a handler thread for the context
204  * @ingroup init
205  *
206  * This should be called at the end of a successful uvc_open if no devices
207  * are already open (and being handled).
208  */
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);
212         }
213 }
214