1 /** @file libuvc_internal.h
2   * @brief Implementation-specific UVC constants and structures.
3   * @cond include_hidden
4   */
5 #ifndef LIBUVC_INTERNAL_H
6 #define LIBUVC_INTERNAL_H
7 
8 #include <assert.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <pthread.h>
13 #include <signal.h>
14 #include <libusb.h>
15 #include "utlist.h"
16 
17 /** Converts an unaligned four-byte little-endian integer into an int32 */
18 #define DW_TO_INT(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
19 /** Converts an unaligned two-byte little-endian integer into an int16 */
20 #define SW_TO_SHORT(p) ((p)[0] | ((p)[1] << 8))
21 /** Converts an int16 into an unaligned two-byte little-endian integer */
22 #define SHORT_TO_SW(s, p) \
23   (p)[0] = (s); \
24   (p)[1] = (s) >> 8;
25 /** Converts an int32 into an unaligned four-byte little-endian integer */
26 #define INT_TO_DW(i, p) \
27   (p)[0] = (i); \
28   (p)[1] = (i) >> 8; \
29   (p)[2] = (i) >> 16; \
30   (p)[3] = (i) >> 24;
31 
32 /** Selects the nth item in a doubly linked list. n=-1 selects the last item. */
33 #define DL_NTH(head, out, n) \
34   do { \
35     int dl_nth_i = 0; \
36     LDECLTYPE(head) dl_nth_p = (head); \
37     if ((n) < 0) { \
38       while (dl_nth_p && dl_nth_i > (n)) { \
39         dl_nth_p = dl_nth_p->prev; \
40         dl_nth_i--; \
41       } \
42     } else { \
43       while (dl_nth_p && dl_nth_i < (n)) { \
44         dl_nth_p = dl_nth_p->next; \
45         dl_nth_i++; \
46       } \
47     } \
48     (out) = dl_nth_p; \
49   } while (0);
50 
51 #ifdef UVC_DEBUGGING
52 #include <libgen.h>
53 #ifdef __ANDROID__
54 #include <android/log.h>
55 #define UVC_DEBUG(format, ...) __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
56 #define UVC_ENTER() __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
57 #define UVC_EXIT(code) __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code)
58 #define UVC_EXIT_VOID() __android_log_print(ANDROID_LOG_DEBUG, "libuvc", "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
59 #else
60 #define UVC_DEBUG(format, ...) fprintf(stderr, "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
61 #define UVC_ENTER() fprintf(stderr, "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
62 #define UVC_EXIT(code) fprintf(stderr, "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code)
63 #define UVC_EXIT_VOID() fprintf(stderr, "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
64 #endif
65 #else
66 #define UVC_DEBUG(format, ...)
67 #define UVC_ENTER()
68 #define UVC_EXIT_VOID()
69 #define UVC_EXIT(code)
70 #endif
71 
72 /* http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers */
73 #define IS_INDEXABLE(arg) (sizeof(arg[0]))
74 #define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
75 #define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))
76 
77 /** Video interface subclass code (A.2) */
78 enum uvc_int_subclass_code {
79   UVC_SC_UNDEFINED = 0x00,
80   UVC_SC_VIDEOCONTROL = 0x01,
81   UVC_SC_VIDEOSTREAMING = 0x02,
82   UVC_SC_VIDEO_INTERFACE_COLLECTION = 0x03
83 };
84 
85 /** Video interface protocol code (A.3) */
86 enum uvc_int_proto_code {
87   UVC_PC_PROTOCOL_UNDEFINED = 0x00
88 };
89 
90 /** VideoControl interface descriptor subtype (A.5) */
91 enum uvc_vc_desc_subtype {
92   UVC_VC_DESCRIPTOR_UNDEFINED = 0x00,
93   UVC_VC_HEADER = 0x01,
94   UVC_VC_INPUT_TERMINAL = 0x02,
95   UVC_VC_OUTPUT_TERMINAL = 0x03,
96   UVC_VC_SELECTOR_UNIT = 0x04,
97   UVC_VC_PROCESSING_UNIT = 0x05,
98   UVC_VC_EXTENSION_UNIT = 0x06
99 };
100 
101 /** UVC endpoint descriptor subtype (A.7) */
102 enum uvc_ep_desc_subtype {
103   UVC_EP_UNDEFINED = 0x00,
104   UVC_EP_GENERAL = 0x01,
105   UVC_EP_ENDPOINT = 0x02,
106   UVC_EP_INTERRUPT = 0x03
107 };
108 
109 /** VideoControl interface control selector (A.9.1) */
110 enum uvc_vc_ctrl_selector {
111   UVC_VC_CONTROL_UNDEFINED = 0x00,
112   UVC_VC_VIDEO_POWER_MODE_CONTROL = 0x01,
113   UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02
114 };
115 
116 /** Terminal control selector (A.9.2) */
117 enum uvc_term_ctrl_selector {
118   UVC_TE_CONTROL_UNDEFINED = 0x00
119 };
120 
121 /** Selector unit control selector (A.9.3) */
122 enum uvc_su_ctrl_selector {
123   UVC_SU_CONTROL_UNDEFINED = 0x00,
124   UVC_SU_INPUT_SELECT_CONTROL = 0x01
125 };
126 
127 /** Extension unit control selector (A.9.6) */
128 enum uvc_xu_ctrl_selector {
129   UVC_XU_CONTROL_UNDEFINED = 0x00
130 };
131 
132 /** VideoStreaming interface control selector (A.9.7) */
133 enum uvc_vs_ctrl_selector {
134   UVC_VS_CONTROL_UNDEFINED = 0x00,
135   UVC_VS_PROBE_CONTROL = 0x01,
136   UVC_VS_COMMIT_CONTROL = 0x02,
137   UVC_VS_STILL_PROBE_CONTROL = 0x03,
138   UVC_VS_STILL_COMMIT_CONTROL = 0x04,
139   UVC_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
140   UVC_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
141   UVC_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
142   UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
143   UVC_VS_SYNC_DELAY_CONTROL = 0x09
144 };
145 
146 /** Status packet type (2.4.2.2) */
147 enum uvc_status_type {
148   UVC_STATUS_TYPE_CONTROL = 1,
149   UVC_STATUS_TYPE_STREAMING = 2
150 };
151 
152 /** Payload header flags (2.4.3.3) */
153 #define UVC_STREAM_EOH (1 << 7)
154 #define UVC_STREAM_ERR (1 << 6)
155 #define UVC_STREAM_STI (1 << 5)
156 #define UVC_STREAM_RES (1 << 4)
157 #define UVC_STREAM_SCR (1 << 3)
158 #define UVC_STREAM_PTS (1 << 2)
159 #define UVC_STREAM_EOF (1 << 1)
160 #define UVC_STREAM_FID (1 << 0)
161 
162 /** Control capabilities (4.1.2) */
163 #define UVC_CONTROL_CAP_GET (1 << 0)
164 #define UVC_CONTROL_CAP_SET (1 << 1)
165 #define UVC_CONTROL_CAP_DISABLED (1 << 2)
166 #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
167 #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
168 
169 struct uvc_streaming_interface;
170 struct uvc_device_info;
171 
172 /** VideoStream interface */
173 typedef struct uvc_streaming_interface {
174   struct uvc_device_info *parent;
175   struct uvc_streaming_interface *prev, *next;
176   /** Interface number */
177   uint8_t bInterfaceNumber;
178   /** Video formats that this interface provides */
179   struct uvc_format_desc *format_descs;
180   /** USB endpoint to use when communicating with this interface */
181   uint8_t bEndpointAddress;
182   uint8_t bTerminalLink;
183   uint8_t bStillCaptureMethod;
184 } uvc_streaming_interface_t;
185 
186 /** VideoControl interface */
187 typedef struct uvc_control_interface {
188   struct uvc_device_info *parent;
189   struct uvc_input_terminal *input_term_descs;
190   // struct uvc_output_terminal *output_term_descs;
191   struct uvc_selector_unit *selector_unit_descs;
192   struct uvc_processing_unit *processing_unit_descs;
193   struct uvc_extension_unit *extension_unit_descs;
194   uint16_t bcdUVC;
195   uint32_t dwClockFrequency;
196   uint8_t bEndpointAddress;
197   /** Interface number */
198   uint8_t bInterfaceNumber;
199 } uvc_control_interface_t;
200 
201 struct uvc_stream_ctrl;
202 
203 struct uvc_device {
204   struct uvc_context *ctx;
205   int ref;
206   libusb_device *usb_dev;
207 };
208 
209 typedef struct uvc_device_info {
210   /** Configuration descriptor for USB device */
211   struct libusb_config_descriptor *config;
212   /** VideoControl interface provided by device */
213   uvc_control_interface_t ctrl_if;
214   /** VideoStreaming interfaces on the device */
215   uvc_streaming_interface_t *stream_ifs;
216 } uvc_device_info_t;
217 
218 /*
219   set a high number of transfer buffers. This uses a lot of ram, but
220   avoids problems with scheduling delays on slow boards causing missed
221   transfers. A better approach may be to make the transfer thread FIFO
222   scheduled (if we have root).
223   We could/should change this to allow reduce it to, say, 5 by default
224   and then allow the user to change the number of buffers as required.
225  */
226 #define LIBUVC_NUM_TRANSFER_BUFS 100
227 
228 #define LIBUVC_XFER_BUF_SIZE	( 16 * 1024 * 1024 )
229 #define LIBUVC_XFER_META_BUF_SIZE ( 4 * 1024 )
230 
231 struct uvc_stream_handle {
232   struct uvc_device_handle *devh;
233   struct uvc_stream_handle *prev, *next;
234   struct uvc_streaming_interface *stream_if;
235 
236   /** if true, stream is running (streaming video to host) */
237   uint8_t running;
238   /** Current control block */
239   struct uvc_stream_ctrl cur_ctrl;
240 
241   /* listeners may only access hold*, and only when holding a
242    * lock on cb_mutex (probably signaled with cb_cond) */
243   uint8_t fid;
244   uint32_t seq, hold_seq;
245   uint32_t pts, hold_pts;
246   uint32_t last_scr, hold_last_scr;
247   size_t got_bytes, hold_bytes;
248   uint8_t *outbuf, *holdbuf;
249   pthread_mutex_t cb_mutex;
250   pthread_cond_t cb_cond;
251   pthread_t cb_thread;
252   uint32_t last_polled_seq;
253   uvc_frame_callback_t *user_cb;
254   void *user_ptr;
255   struct libusb_transfer *transfers[LIBUVC_NUM_TRANSFER_BUFS];
256   uint8_t *transfer_bufs[LIBUVC_NUM_TRANSFER_BUFS];
257   struct uvc_frame frame;
258   enum uvc_frame_format frame_format;
259   struct timespec capture_time_finished;
260 
261   /* raw metadata buffer if available */
262   uint8_t *meta_outbuf, *meta_holdbuf;
263   size_t meta_got_bytes, meta_hold_bytes;
264 };
265 
266 /** Handle on an open UVC device
267  *
268  * @todo move most of this into a uvc_device struct?
269  */
270 struct uvc_device_handle {
271   struct uvc_device *dev;
272   struct uvc_device_handle *prev, *next;
273   /** Underlying USB device handle */
274   libusb_device_handle *usb_devh;
275   struct uvc_device_info *info;
276   struct libusb_transfer *status_xfer;
277   uint8_t status_buf[32];
278   /** Function to call when we receive status updates from the camera */
279   uvc_status_callback_t *status_cb;
280   void *status_user_ptr;
281   /** Function to call when we receive button events from the camera */
282   uvc_button_callback_t *button_cb;
283   void *button_user_ptr;
284 
285   uvc_stream_handle_t *streams;
286   /** Whether the camera is an iSight that sends one header per frame */
287   uint8_t is_isight;
288   uint32_t claimed;
289 };
290 
291 /** Context within which we communicate with devices */
292 struct uvc_context {
293   /** Underlying context for USB communication */
294   struct libusb_context *usb_ctx;
295   /** True iff libuvc initialized the underlying USB context */
296   uint8_t own_usb_ctx;
297   /** List of open devices in this context */
298   uvc_device_handle_t *open_devices;
299   pthread_t handler_thread;
300   int kill_handler_thread;
301 };
302 
303 uvc_error_t uvc_query_stream_ctrl(
304     uvc_device_handle_t *devh,
305     uvc_stream_ctrl_t *ctrl,
306     uint8_t probe,
307     enum uvc_req_code req);
308 
309 void uvc_start_handler_thread(uvc_context_t *ctx);
310 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx);
311 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx);
312 
313 #endif // !def(LIBUVC_INTERNAL_H)
314 /** @endcond */
315 
316