Fix issue 1) not recognizes some usb device, 2) reconnect when ffmpeg encoder error
[rtmpclient.git] / app / src / main / jni / libuvc / src / ctrl_original.c
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 *  Copyright (C) 2010-2012 Ken Tossell
5 *  All rights reserved.
6 *
7 *  Redistribution and use in source and binary forms, with or without
8 *  modification, are permitted provided that the following conditions
9 *  are met:
10 *
11 *   * Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 *   * Redistributions in binary form must reproduce the above
14 *     copyright notice, this list of conditions and the following
15 *     disclaimer in the documentation and/or other materials provided
16 *     with the distribution.
17 *   * Neither the name of the author nor other contributors may be
18 *     used to endorse or promote products derived from this software
19 *     without specific prior written permission.
20 *
21 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 *  POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 /**
35  * @defgroup ctrl Video capture and processing control
36  */
37
38 #include "libuvc/libuvc.h"
39 #include "libuvc/libuvc_internal.h"
40
41 static const int REQ_TYPE_SET = 0x21;
42 static const int REQ_TYPE_GET = 0xa1;
43
44 uvc_error_t uvc_get_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode *mode, enum uvc_req_code req_code) {
45   uint8_t mode_char;
46   uvc_error_t ret;
47
48   ret = libusb_control_transfer(
49     devh->usb_devh,
50     REQ_TYPE_GET, req_code,
51     UVC_VC_VIDEO_POWER_MODE_CONTROL << 8,
52     0,
53     &mode_char,
54     sizeof(mode_char),
55     0);
56
57   if (ret == 1) {
58     *mode = mode_char;
59     return UVC_SUCCESS;
60   } else {
61     return ret;
62   }
63 }
64
65 uvc_error_t uvc_set_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode mode) {
66   uint8_t mode_char = mode;
67   uvc_error_t ret;
68
69   ret = libusb_control_transfer(
70     devh->usb_devh,
71     REQ_TYPE_SET, UVC_SET_CUR,
72     UVC_VC_VIDEO_POWER_MODE_CONTROL << 8,
73     0,
74     &mode_char,
75     sizeof(mode_char),
76     0);
77
78   if (ret == 1)
79     return UVC_SUCCESS;
80   else
81     return ret;
82 }
83
84 /***** CAMERA TERMINAL CONTROLS *****/
85
86 uvc_error_t uvc_get_ae_mode(uvc_device_handle_t *devh, int *mode, enum uvc_req_code req_code) {
87   uint8_t data[1];
88   uvc_error_t ret;
89
90   ret = libusb_control_transfer(
91     devh->usb_devh,
92     REQ_TYPE_GET, req_code,
93     UVC_CT_AE_MODE_CONTROL << 8,
94     1 << 8,
95     data,
96     sizeof(data),
97     0);
98
99   if (ret == sizeof(data)) {
100     *mode = data[0];
101     return UVC_SUCCESS;
102   } else {
103     return ret;
104   }
105 }
106
107 uvc_error_t uvc_set_ae_mode(uvc_device_handle_t *devh, int mode) {
108   uint8_t data[1];
109   uvc_error_t ret;
110
111   data[0] = mode;
112
113   ret = libusb_control_transfer(
114     devh->usb_devh,
115     REQ_TYPE_SET, UVC_SET_CUR,
116     UVC_CT_AE_MODE_CONTROL << 8,
117     1 << 8,
118     data,
119     sizeof(data),
120     0);
121
122   if (ret == sizeof(data))
123     return UVC_SUCCESS;
124   else
125     return ret;
126 }
127
128 uvc_error_t uvc_get_ae_priority(uvc_device_handle_t *devh, uint8_t *priority, enum uvc_req_code req_code) {
129   uint8_t data[1];
130   uvc_error_t ret;
131
132   ret = libusb_control_transfer(
133     devh->usb_devh,
134     REQ_TYPE_GET, req_code,
135     UVC_CT_AE_PRIORITY_CONTROL << 8,
136     1 << 8,
137     data,
138     sizeof(data),
139     0);
140
141   if (ret == sizeof(data)) {
142     *priority = data[0];
143     return UVC_SUCCESS;
144   } else {
145     return ret;
146   }
147 }
148
149 uvc_error_t uvc_set_ae_priority(uvc_device_handle_t *devh, uint8_t priority) {
150   uint8_t data[1];
151   uvc_error_t ret;
152
153   data[0] = priority;
154
155   ret = libusb_control_transfer(
156     devh->usb_devh,
157     REQ_TYPE_SET, UVC_SET_CUR,
158     UVC_CT_AE_PRIORITY_CONTROL << 8,
159     1 << 8,
160     data,
161     sizeof(data),
162     0);
163
164   if (ret == sizeof(data))
165     return UVC_SUCCESS;
166   else
167     return ret;
168 }
169
170 uvc_error_t uvc_get_exposure_abs(uvc_device_handle_t *devh, int *time, enum uvc_req_code req_code) {
171   uint8_t data[4];
172   uvc_error_t ret;
173
174   ret = libusb_control_transfer(
175     devh->usb_devh,
176     REQ_TYPE_GET, req_code,
177     UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
178     1 << 8,
179     data,
180     sizeof(data),
181     0);
182
183   if (ret == sizeof(data)) {
184     *time = DW_TO_INT(data);
185     return UVC_SUCCESS;
186   } else {
187     return ret;
188   }
189 }
190
191 uvc_error_t uvc_set_exposure_abs(uvc_device_handle_t *devh, int time) {
192   uint8_t data[4];
193   uvc_error_t ret;
194
195   INT_TO_DW(time, data);
196
197   ret = libusb_control_transfer(
198     devh->usb_devh,
199     REQ_TYPE_SET, UVC_SET_CUR,
200     UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL << 8,
201     1 << 8,
202     data,
203     sizeof(data),
204     0);
205
206   if (ret == sizeof(data))
207     return UVC_SUCCESS;
208   else
209     return ret;
210 }
211
212 uvc_error_t uvc_get_exposure_rel(uvc_device_handle_t *devh, int *step, enum uvc_req_code req_code) {
213   uint8_t data[1];
214   uvc_error_t ret;
215
216   ret = libusb_control_transfer(
217     devh->usb_devh,
218     REQ_TYPE_GET, req_code,
219     UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
220     1 << 8,
221     data,
222     sizeof(data),
223     0);
224
225   if (ret == sizeof(data)) {
226     *step = data[0];
227     return UVC_SUCCESS;
228   } else {
229     return ret;
230   }
231 }
232
233 uvc_error_t uvc_set_exposure_rel(uvc_device_handle_t *devh, int step) {
234   uint8_t data[1];
235   uvc_error_t ret;
236
237   data[0] = step;
238
239   ret = libusb_control_transfer(
240     devh->usb_devh,
241     REQ_TYPE_SET, UVC_SET_CUR,
242     UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL << 8,
243     1 << 8,
244     data,
245     sizeof(data),
246     0);
247
248   if (ret == sizeof(data))
249     return UVC_SUCCESS;
250   else
251     return ret;
252 }
253
254 uvc_error_t uvc_get_scanning_mode(uvc_device_handle_t *devh, int *step, enum uvc_req_code req_code) {
255   uint8_t data[1];
256   uvc_error_t ret;
257
258   ret = libusb_control_transfer(
259     devh->usb_devh,
260     REQ_TYPE_GET, req_code,
261     UVC_CT_SCANNING_MODE_CONTROL << 8,
262     1 << 8,
263     data,
264     sizeof(data),
265     0);
266
267   if (ret == sizeof(data)) {
268     *step = data[0];
269     return UVC_SUCCESS;
270   } else {
271     return ret;
272   }
273 }
274
275 uvc_error_t uvc_set_scanning_mode(uvc_device_handle_t *devh, int mode) {
276   uint8_t data[1];
277   uvc_error_t ret;
278
279   data[0] = mode;
280
281   ret = libusb_control_transfer(
282     devh->usb_devh,
283     REQ_TYPE_SET, UVC_SET_CUR,
284     UVC_CT_SCANNING_MODE_CONTROL << 8,
285     1 << 8,
286     data,
287     sizeof(data),
288     0);
289
290   if (ret == sizeof(data))
291     return UVC_SUCCESS;
292   else
293     return ret;
294 }
295
296 uvc_error_t uvc_get_focus_abs(uvc_device_handle_t *devh, short *focus, enum uvc_req_code req_code) {
297   uint8_t data[2];
298   uvc_error_t ret;
299
300   ret = libusb_control_transfer(
301     devh->usb_devh,
302     REQ_TYPE_GET, req_code,
303     UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
304     1 << 8,
305     data,
306     sizeof(data),
307     0);
308
309   if (ret == sizeof(data)) {
310     *focus = SW_TO_SHORT(data);
311     return UVC_SUCCESS;
312   } else {
313     return ret;
314   }
315 }
316
317 uvc_error_t uvc_set_focus_abs(uvc_device_handle_t *devh, short focus) {
318   uint8_t data[2];
319   uvc_error_t ret;
320
321   SHORT_TO_SW(focus, data);
322
323   ret = libusb_control_transfer(
324     devh->usb_devh,
325     REQ_TYPE_SET, UVC_SET_CUR,
326     UVC_CT_FOCUS_ABSOLUTE_CONTROL << 8,
327     1 << 8,
328     data,
329     sizeof(data),
330     0);
331
332   if (ret == sizeof(data))
333     return UVC_SUCCESS;
334   else
335     return ret;
336 }
337
338 /** @todo focus_rel, focus_auto_control */
339 /** @todo iris_abs_ctrl, iris_rel_ctrl */
340 /** @todo zoom_abs, zoom_rel */
341
342 uvc_error_t uvc_get_pantilt_abs(uvc_device_handle_t *devh, int *pan, int *tilt, enum uvc_req_code req_code) {
343   uint8_t data[8];
344   uvc_error_t ret;
345
346   ret = libusb_control_transfer(
347     devh->usb_devh,
348     REQ_TYPE_GET, req_code,
349     UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
350     1 << 8,
351     data,
352     sizeof(data),
353     0);
354
355   if (ret == sizeof(data)) {
356     *pan = DW_TO_INT(data);
357     *tilt = DW_TO_INT(data + 4);
358     return UVC_SUCCESS;
359   } else {
360     return ret;
361   }
362 }
363
364 uvc_error_t uvc_set_pantilt_abs(uvc_device_handle_t *devh, int pan, int tilt) {
365   uint8_t data[8];
366   uvc_error_t ret;
367
368   INT_TO_DW(pan, data);
369   INT_TO_DW(tilt, data + 4);
370
371   ret = libusb_control_transfer(
372     devh->usb_devh,
373     REQ_TYPE_SET, UVC_SET_CUR,
374     UVC_CT_PANTILT_ABSOLUTE_CONTROL << 8,
375     1 << 8,
376     data,
377     sizeof(data),
378     0);
379
380   if (ret == sizeof(data))
381     return UVC_SUCCESS;
382   else
383     return ret;
384 }
385
386 /** @todo pantilt_rel */
387
388 /** @todo roll_abs, roll_rel */
389
390 /** @todo privacy */
391
392 /***** SELECTOR UNIT CONTROLS *****/
393
394 /** @todo input_select */
395
396 /***** PROCESSING UNIT CONTROLS *****/
397
398 /***** GENERIC CONTROLS *****/
399 /**
400  * @brief Get the length of a control on a terminal or unit.
401  * 
402  * @param devh UVC device handle
403  * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit
404  * @param ctrl Vendor-specific control number to query
405  * @return On success, the length of the control as reported by the device. Otherwise,
406  *   a uvc_error_t error describing the error encountered.
407  */
408 int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) {
409   unsigned char buf[2];
410
411   int ret = libusb_control_transfer(
412     devh->usb_devh,
413     REQ_TYPE_GET, UVC_GET_LEN,
414     ctrl << 8,
415     unit << 8,
416     buf,
417     2,
418     0 /* timeout */);
419
420   if (ret < 0)
421     return ret;
422   else
423     return (unsigned short)SW_TO_SHORT(buf);
424 }
425
426 /**
427  * @brief Perform a GET_* request from an extension unit.
428  * 
429  * @param devh UVC device handle
430  * @param unit Unit ID; obtain this from the uvc_extension_unit_t describing the extension unit
431  * @param ctrl Control number to query
432  * @param data Data buffer to be filled by the device
433  * @param len Size of data buffer
434  * @param req_code GET_* request to execute
435  * @return On success, the number of bytes actually transferred. Otherwise,
436  *   a uvc_error_t error describing the error encountered.
437  */
438 int uvc_get_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len, enum uvc_req_code req_code) {
439   return libusb_control_transfer(
440     devh->usb_devh,
441     REQ_TYPE_GET, req_code,
442     ctrl << 8,
443     unit << 8,
444     data,
445     len,
446     0 /* timeout */);
447 }
448
449 /**
450  * @brief Perform a SET_CUR request to a terminal or unit.
451  * 
452  * @param devh UVC device handle
453  * @param unit Unit or Terminal ID
454  * @param ctrl Control number to set
455  * @param data Data buffer to be sent to the device
456  * @param len Size of data buffer
457  * @return On success, the number of bytes actually transferred. Otherwise,
458  *   a uvc_error_t error describing the error encountered.
459  */
460 int uvc_set_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len) {
461   return libusb_control_transfer(
462     devh->usb_devh,
463     REQ_TYPE_SET, UVC_SET_CUR,
464     ctrl << 8,
465     unit << 8,
466     data,
467     len,
468     0 /* timeout */);
469 }