1 /** @file libuvc_internal.h
2 * @brief Implementation-specific UVC constants and structures.
5 #ifndef LIBUVC_INTERNAL_H
6 #define LIBUVC_INTERNAL_H
16 /** Converts an unaligned four-byte little-endian integer into an int32 */
17 #define DW_TO_INT(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
18 /** Converts an unaligned two-byte little-endian integer into an int16 */
19 #define SW_TO_SHORT(p) ((p)[0] | ((p)[1] << 8))
20 /** Converts an int16 into an unaligned two-byte little-endian integer */
21 #define SHORT_TO_SW(s, p) \
24 /** Converts an int32 into an unaligned four-byte little-endian integer */
25 #define INT_TO_DW(i, p) \
31 /** Selects the nth item in a doubly linked list. n=-1 selects the last item. */
32 #define DL_NTH(head, out, n) \
35 LDECLTYPE(head) dl_nth_p = (head); \
37 while (dl_nth_p && dl_nth_i > (n)) { \
38 dl_nth_p = dl_nth_p->prev; \
42 while (dl_nth_p && dl_nth_i < (n)) { \
43 dl_nth_p = dl_nth_p->next; \
52 #define UVC_DEBUG(format, ...) fprintf(stderr, "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
53 #define UVC_ENTER() fprintf(stderr, "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
54 #define UVC_EXIT(code) fprintf(stderr, "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code)
55 #define UVC_EXIT_VOID() fprintf(stderr, "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
57 #define UVC_DEBUG(format, ...)
59 #define UVC_EXIT_VOID()
60 #define UVC_EXIT(code)
63 /* http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers */
64 #define IS_INDEXABLE(arg) (sizeof(arg[0]))
65 #define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
66 #define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))
68 /** Video interface subclass code (A.2) */
69 enum uvc_int_subclass_code {
70 UVC_SC_UNDEFINED = 0x00,
71 UVC_SC_VIDEOCONTROL = 0x01,
72 UVC_SC_VIDEOSTREAMING = 0x02,
73 UVC_SC_VIDEO_INTERFACE_COLLECTION = 0x03
76 /** Video interface protocol code (A.3) */
77 enum uvc_int_proto_code {
78 UVC_PC_PROTOCOL_UNDEFINED = 0x00
81 /** VideoControl interface descriptor subtype (A.5) */
82 enum uvc_vc_desc_subtype {
83 UVC_VC_DESCRIPTOR_UNDEFINED = 0x00,
85 UVC_VC_INPUT_TERMINAL = 0x02,
86 UVC_VC_OUTPUT_TERMINAL = 0x03,
87 UVC_VC_SELECTOR_UNIT = 0x04,
88 UVC_VC_PROCESSING_UNIT = 0x05,
89 UVC_VC_EXTENSION_UNIT = 0x06
92 /** VideoStreaming interface descriptor subtype (A.6) */
93 enum uvc_vs_desc_subtype {
94 UVC_VS_UNDEFINED = 0x00,
95 UVC_VS_INPUT_HEADER = 0x01,
96 UVC_VS_OUTPUT_HEADER = 0x02,
97 UVC_VS_STILL_IMAGE_FRAME = 0x03,
98 UVC_VS_FORMAT_UNCOMPRESSED = 0x04,
99 UVC_VS_FRAME_UNCOMPRESSED = 0x05,
100 UVC_VS_FORMAT_MJPEG = 0x06,
101 UVC_VS_FRAME_MJPEG = 0x07,
102 UVC_VS_FORMAT_MPEG2TS = 0x0a,
103 UVC_VS_FORMAT_DV = 0x0c,
104 UVC_VS_COLORFORMAT = 0x0d,
105 UVC_VS_FORMAT_FRAME_BASED = 0x10,
106 UVC_VS_FRAME_FRAME_BASED = 0x11,
107 UVC_VS_FORMAT_STREAM_BASED = 0x12
110 /** UVC endpoint descriptor subtype (A.7) */
111 enum uvc_ep_desc_subtype {
112 UVC_EP_UNDEFINED = 0x00,
113 UVC_EP_GENERAL = 0x01,
114 UVC_EP_ENDPOINT = 0x02,
115 UVC_EP_INTERRUPT = 0x03
118 /** VideoControl interface control selector (A.9.1) */
119 enum uvc_vc_ctrl_selector {
120 UVC_VC_CONTROL_UNDEFINED = 0x00,
121 UVC_VC_VIDEO_POWER_MODE_CONTROL = 0x01,
122 UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02
125 /** Terminal control selector (A.9.2) */
126 enum uvc_term_ctrl_selector {
127 UVC_TE_CONTROL_UNDEFINED = 0x00
130 /** Selector unit control selector (A.9.3) */
131 enum uvc_su_ctrl_selector {
132 UVC_SU_CONTROL_UNDEFINED = 0x00,
133 UVC_SU_INPUT_SELECT_CONTROL = 0x01
136 /** Extension unit control selector (A.9.6) */
137 enum uvc_xu_ctrl_selector {
138 UVC_XU_CONTROL_UNDEFINED = 0x00
141 /** VideoStreaming interface control selector (A.9.7) */
142 enum uvc_vs_ctrl_selector {
143 UVC_VS_CONTROL_UNDEFINED = 0x00,
144 UVC_VS_PROBE_CONTROL = 0x01,
145 UVC_VS_COMMIT_CONTROL = 0x02,
146 UVC_VS_STILL_PROBE_CONTROL = 0x03,
147 UVC_VS_STILL_COMMIT_CONTROL = 0x04,
148 UVC_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
149 UVC_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
150 UVC_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
151 UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
152 UVC_VS_SYNC_DELAY_CONTROL = 0x09
155 /** Status packet type (2.4.2.2) */
156 enum uvc_status_type {
157 UVC_STATUS_TYPE_CONTROL = 1,
158 UVC_STATUS_TYPE_STREAMING = 2
161 /** Payload header flags (2.4.3.3) */
162 #define UVC_STREAM_EOH (1 << 7)
163 #define UVC_STREAM_ERR (1 << 6)
164 #define UVC_STREAM_STI (1 << 5)
165 #define UVC_STREAM_RES (1 << 4)
166 #define UVC_STREAM_SCR (1 << 3)
167 #define UVC_STREAM_PTS (1 << 2)
168 #define UVC_STREAM_EOF (1 << 1)
169 #define UVC_STREAM_FID (1 << 0)
171 /** Control capabilities (4.1.2) */
172 #define UVC_CONTROL_CAP_GET (1 << 0)
173 #define UVC_CONTROL_CAP_SET (1 << 1)
174 #define UVC_CONTROL_CAP_DISABLED (1 << 2)
175 #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
176 #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
178 struct uvc_format_desc;
179 struct uvc_frame_desc;
180 struct uvc_streaming_interface;
181 struct uvc_device_info;
185 * A "frame" is a configuration of a streaming format
186 * for a particular image size at one of possibly several
187 * available frame rates.
189 typedef struct uvc_frame_desc {
190 struct uvc_format_desc *parent;
191 struct uvc_frame_desc *prev, *next;
192 /** Type of frame, such as JPEG frame or uncompressed frme */
193 enum uvc_vs_desc_subtype bDescriptorSubtype;
194 /** Index of the frame within the list of specs available for this format */
196 uint8_t bmCapabilities;
201 /** Bitrate of corresponding stream at minimal frame rate */
202 uint32_t dwMinBitRate;
203 /** Bitrate of corresponding stream at maximal frame rate */
204 uint32_t dwMaxBitRate;
205 /** Maximum number of bytes for a video frame */
206 uint32_t dwMaxVideoFrameBufferSize;
207 /** Default frame interval (in 100ns units) */
208 uint32_t dwDefaultFrameInterval;
209 /** Minimum frame interval for continuous mode (100ns units) */
210 uint32_t dwMinFrameInterval;
211 /** Maximum frame interval for continuous mode (100ns units) */
212 uint32_t dwMaxFrameInterval;
213 /** Granularity of frame interval range for continuous mode (100ns) */
214 uint32_t dwFrameIntervalStep;
215 /** Available frame rates, zero-terminated (in 100ns units) */
219 /** Format descriptor
221 * A "format" determines a stream's image type (e.g., raw YUYV or JPEG)
222 * and includes many "frame" configurations.
224 typedef struct uvc_format_desc {
225 struct uvc_streaming_interface *parent;
226 struct uvc_format_desc *prev, *next;
227 /** Type of image stream, such as JPEG or uncompressed. */
228 enum uvc_vs_desc_subtype bDescriptorSubtype;
229 /** Identifier of this format within the VS interface's format list */
230 uint8_t bFormatIndex;
231 /** Format specifier */
233 uint8_t guidFormat[16];
234 uint8_t fourccFormat[4];
236 /** Format-specific data */
238 /** BPP for uncompressed stream */
239 uint8_t bBitsPerPixel;
240 /** Flags for JPEG stream */
243 /** Default {uvc_frame_desc} to choose given this format */
244 uint8_t bDefaultFrameIndex;
245 uint8_t bAspectRatioX;
246 uint8_t bAspectRatioY;
247 uint8_t bmInterlaceFlags;
248 uint8_t bCopyProtect;
249 /** Available frame specifications for this format */
250 struct uvc_frame_desc *frame_descs;
254 /** VideoStream interface */
255 typedef struct uvc_streaming_interface {
256 struct uvc_device_info *parent;
257 struct uvc_streaming_interface *prev, *next;
258 /** Interface number */
259 uint8_t bInterfaceNumber;
260 /** Video formats that this interface provides */
261 struct uvc_format_desc *format_descs;
262 /** USB endpoint to use when communicating with this interface */
263 uint8_t bEndpointAddress;
264 uint8_t bTerminalLink;
265 } uvc_streaming_interface_t;
267 /** VideoControl interface */
268 typedef struct uvc_control_interface {
269 struct uvc_device_info *parent;
270 struct uvc_input_terminal *input_term_descs;
271 // struct uvc_output_terminal *output_term_descs;
272 struct uvc_processing_unit *processing_unit_descs;
273 struct uvc_extension_unit *extension_unit_descs;
275 uint8_t bEndpointAddress;
276 /** Interface number */
277 uint8_t bInterfaceNumber;
278 } uvc_control_interface_t;
280 struct uvc_stream_ctrl;
283 struct uvc_context *ctx;
285 libusb_device *usb_dev;
288 typedef struct uvc_device_info {
289 /** Configuration descriptor for USB device */
290 struct libusb_config_descriptor *config;
291 /** VideoControl interface provided by device */
292 uvc_control_interface_t ctrl_if;
293 /** VideoStreaming interfaces on the device */
294 uvc_streaming_interface_t *stream_ifs;
297 struct uvc_stream_handle {
298 struct uvc_device_handle *devh;
299 struct uvc_stream_handle *prev, *next;
300 struct uvc_streaming_interface *stream_if;
302 /** if true, stream is running (streaming video to host) */
304 /** Current control block */
305 struct uvc_stream_ctrl cur_ctrl;
307 /* listeners may only access hold*, and only when holding a
308 * lock on cb_mutex (probably signaled with cb_cond) */
310 uint32_t seq, hold_seq;
311 uint32_t pts, hold_pts;
312 uint32_t last_scr, hold_last_scr;
313 size_t got_bytes, hold_bytes;
314 uint8_t *outbuf, *holdbuf;
315 pthread_mutex_t cb_mutex;
316 pthread_cond_t cb_cond;
318 uint32_t last_polled_seq;
319 uvc_frame_callback_t *user_cb;
321 struct libusb_transfer *transfers[5];
322 uint8_t *transfer_bufs[5];
323 struct uvc_frame frame;
324 enum uvc_frame_format frame_format;
327 /** Handle on an open UVC device
329 * @todo move most of this into a uvc_device struct?
331 struct uvc_device_handle {
332 struct uvc_device *dev;
333 struct uvc_device_handle *prev, *next;
334 /** Underlying USB device handle */
335 libusb_device_handle *usb_devh;
336 struct uvc_device_info *info;
337 struct libusb_transfer *status_xfer;
338 uint8_t status_buf[32];
339 /** Function to call when we receive status updates from the camera */
340 uvc_status_callback_t *status_cb;
341 void *status_user_ptr;
343 uvc_stream_handle_t *streams;
344 /** Whether the camera is an iSight that sends one header per frame */
348 /** Context within which we communicate with devices */
350 /** Underlying context for USB communication */
351 struct libusb_context *usb_ctx;
352 /** True iff libuvc initialized the underlying USB context */
354 /** List of open devices in this context */
355 uvc_device_handle_t *open_devices;
356 pthread_t handler_thread;
357 uint8_t kill_handler_thread;
360 uvc_error_t uvc_query_stream_ctrl(
361 uvc_device_handle_t *devh,
362 uvc_stream_ctrl_t *ctrl,
364 enum uvc_req_code req);
366 void uvc_start_handler_thread(uvc_context_t *ctx);
367 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx);
368 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx);
370 #endif // !def(LIBUVC_INTERNAL_H)