libuvc_internal.h
Go to the documentation of this file.
00001 
00005 #ifndef LIBUVC_INTERNAL_H
00006 #define LIBUVC_INTERNAL_H
00007 
00008 #include <assert.h>
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <pthread.h>
00013 #include <signal.h>
00014 #include "utlist.h"
00015 
00017 #define DW_TO_INT(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
00018 
00019 #define SW_TO_SHORT(p) ((p)[0] | ((p)[1] << 8))
00020 
00021 #define SHORT_TO_SW(s, p) \
00022   (p)[0] = (s); \
00023   (p)[1] = (s) >> 8;
00024 
00025 #define INT_TO_DW(i, p) \
00026   (p)[0] = (i); \
00027   (p)[1] = (i) >> 8; \
00028   (p)[2] = (i) >> 16; \
00029   (p)[3] = (i) >> 24;
00030 
00032 #define DL_NTH(head, out, n) \
00033   do { \
00034     int dl_nth_i = 0; \
00035     LDECLTYPE(head) dl_nth_p = (head); \
00036     if ((n) < 0) { \
00037       while (dl_nth_p && dl_nth_i > (n)) { \
00038         dl_nth_p = dl_nth_p->prev; \
00039         dl_nth_i--; \
00040       } \
00041     } else { \
00042       while (dl_nth_p && dl_nth_i < (n)) { \
00043         dl_nth_p = dl_nth_p->next; \
00044         dl_nth_i++; \
00045       } \
00046     } \
00047     (out) = dl_nth_p; \
00048   } while (0);
00049 
00050 #ifdef UVC_DEBUGGING
00051 #include <libgen.h>
00052 #define UVC_DEBUG(format, ...) fprintf(stderr, "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
00053 #define UVC_ENTER() fprintf(stderr, "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
00054 #define UVC_EXIT(code) fprintf(stderr, "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code)
00055 #define UVC_EXIT_VOID() fprintf(stderr, "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
00056 #else
00057 #define UVC_DEBUG(format, ...)
00058 #define UVC_ENTER()
00059 #define UVC_EXIT_VOID()
00060 #define UVC_EXIT(code)
00061 #endif
00062 
00063 /* http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers */
00064 #define IS_INDEXABLE(arg) (sizeof(arg[0]))
00065 #define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
00066 #define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))
00067 
00069 enum uvc_int_subclass_code {
00070   UVC_SC_UNDEFINED = 0x00,
00071   UVC_SC_VIDEOCONTROL = 0x01,
00072   UVC_SC_VIDEOSTREAMING = 0x02,
00073   UVC_SC_VIDEO_INTERFACE_COLLECTION = 0x03
00074 };
00075 
00077 enum uvc_int_proto_code {
00078   UVC_PC_PROTOCOL_UNDEFINED = 0x00
00079 };
00080 
00082 enum uvc_vc_desc_subtype {
00083   UVC_VC_DESCRIPTOR_UNDEFINED = 0x00,
00084   UVC_VC_HEADER = 0x01,
00085   UVC_VC_INPUT_TERMINAL = 0x02,
00086   UVC_VC_OUTPUT_TERMINAL = 0x03,
00087   UVC_VC_SELECTOR_UNIT = 0x04,
00088   UVC_VC_PROCESSING_UNIT = 0x05,
00089   UVC_VC_EXTENSION_UNIT = 0x06
00090 };
00091 
00093 enum uvc_ep_desc_subtype {
00094   UVC_EP_UNDEFINED = 0x00,
00095   UVC_EP_GENERAL = 0x01,
00096   UVC_EP_ENDPOINT = 0x02,
00097   UVC_EP_INTERRUPT = 0x03
00098 };
00099 
00101 enum uvc_vc_ctrl_selector {
00102   UVC_VC_CONTROL_UNDEFINED = 0x00,
00103   UVC_VC_VIDEO_POWER_MODE_CONTROL = 0x01,
00104   UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02
00105 };
00106 
00108 enum uvc_term_ctrl_selector {
00109   UVC_TE_CONTROL_UNDEFINED = 0x00
00110 };
00111 
00113 enum uvc_su_ctrl_selector {
00114   UVC_SU_CONTROL_UNDEFINED = 0x00,
00115   UVC_SU_INPUT_SELECT_CONTROL = 0x01
00116 };
00117 
00119 enum uvc_xu_ctrl_selector {
00120   UVC_XU_CONTROL_UNDEFINED = 0x00
00121 };
00122 
00124 enum uvc_vs_ctrl_selector {
00125   UVC_VS_CONTROL_UNDEFINED = 0x00,
00126   UVC_VS_PROBE_CONTROL = 0x01,
00127   UVC_VS_COMMIT_CONTROL = 0x02,
00128   UVC_VS_STILL_PROBE_CONTROL = 0x03,
00129   UVC_VS_STILL_COMMIT_CONTROL = 0x04,
00130   UVC_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
00131   UVC_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
00132   UVC_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
00133   UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
00134   UVC_VS_SYNC_DELAY_CONTROL = 0x09
00135 };
00136 
00138 enum uvc_status_type {
00139   UVC_STATUS_TYPE_CONTROL = 1,
00140   UVC_STATUS_TYPE_STREAMING = 2
00141 };
00142 
00144 #define UVC_STREAM_EOH (1 << 7)
00145 #define UVC_STREAM_ERR (1 << 6)
00146 #define UVC_STREAM_STI (1 << 5)
00147 #define UVC_STREAM_RES (1 << 4)
00148 #define UVC_STREAM_SCR (1 << 3)
00149 #define UVC_STREAM_PTS (1 << 2)
00150 #define UVC_STREAM_EOF (1 << 1)
00151 #define UVC_STREAM_FID (1 << 0)
00152 
00154 #define UVC_CONTROL_CAP_GET (1 << 0)
00155 #define UVC_CONTROL_CAP_SET (1 << 1)
00156 #define UVC_CONTROL_CAP_DISABLED (1 << 2)
00157 #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
00158 #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
00159 
00160 struct uvc_streaming_interface;
00161 struct uvc_device_info;
00162 
00164 typedef struct uvc_streaming_interface {
00165   struct uvc_device_info *parent;
00166   struct uvc_streaming_interface *prev, *next;
00168   uint8_t bInterfaceNumber;
00170   struct uvc_format_desc *format_descs;
00172   uint8_t bEndpointAddress;
00173   uint8_t bTerminalLink;
00174 } uvc_streaming_interface_t;
00175 
00177 typedef struct uvc_control_interface {
00178   struct uvc_device_info *parent;
00179   struct uvc_input_terminal *input_term_descs;
00180   // struct uvc_output_terminal *output_term_descs;
00181   struct uvc_processing_unit *processing_unit_descs;
00182   struct uvc_extension_unit *extension_unit_descs;
00183   uint16_t bcdUVC;
00184   uint8_t bEndpointAddress;
00186   uint8_t bInterfaceNumber;
00187 } uvc_control_interface_t;
00188 
00189 struct uvc_stream_ctrl;
00190 
00191 struct uvc_device {
00192   struct uvc_context *ctx;
00193   int ref;
00194   libusb_device *usb_dev;
00195 };
00196 
00197 typedef struct uvc_device_info {
00199   struct libusb_config_descriptor *config;
00201   uvc_control_interface_t ctrl_if;
00203   uvc_streaming_interface_t *stream_ifs;
00204 
00205   /* Store the interface for multiple UVCs on a single VID/PID device (Intel RealSense, VF200, e.g) */
00206   int camera_number;
00207 } uvc_device_info_t;
00208 
00209 /*
00210   set a high number of transfer buffers. This uses a lot of ram, but
00211   avoids problems with scheduling delays on slow boards causing missed
00212   transfers. A better approach may be to make the transfer thread FIFO
00213   scheduled (if we have root).
00214   We could/should change this to allow reduce it to, say, 5 by default
00215   and then allow the user to change the number of buffers as required.
00216  */
00217 #define LIBUVC_XFER_BUF_SIZE (64 * 1024 * 1024)
00218 
00219 struct uvc_stream_handle {
00220   struct uvc_device_handle *devh;
00221   struct uvc_stream_handle *prev, *next;
00222   struct uvc_streaming_interface *stream_if;
00223 
00225   uint8_t running;
00227   struct uvc_stream_ctrl cur_ctrl;
00228 
00229   /* listeners may only access hold*, and only when holding a 
00230    * lock on cb_mutex (probably signaled with cb_cond) */
00231   uint8_t fid;
00232   uint32_t seq, hold_seq;
00233   uint32_t pts, hold_pts;
00234   uint32_t last_scr, hold_last_scr;
00235   size_t got_bytes, hold_bytes;
00236   uint8_t *outbuf, *holdbuf;
00237   pthread_mutex_t cb_mutex;
00238   pthread_cond_t cb_cond;
00239   pthread_t cb_thread;
00240   uint32_t last_polled_seq;
00241   uvc_frame_callback_t *user_cb;
00242   void *user_ptr;
00243   struct libusb_transfer **transfers; // num_transfer_bufs
00244   uint8_t **transfer_bufs; // num_transfer_bufs
00245   struct uvc_frame frame;
00246   uint32_t fourcc;
00247   int num_transfer_bufs;
00248 };
00249 
00254 struct uvc_device_handle {
00255   struct uvc_device *dev;
00256   struct uvc_device_handle *prev, *next;
00258   libusb_device_handle *usb_devh;
00259   struct uvc_device_info *info;
00260   struct libusb_transfer *status_xfer;
00261   uint8_t status_buf[32];
00263   uvc_status_callback_t *status_cb;
00264   void *status_user_ptr;
00265 
00266   uvc_stream_handle_t *streams;
00268   uint8_t is_isight;
00269 };
00270 
00272 struct uvc_context {
00274   struct libusb_context *usb_ctx;
00276   uint8_t own_usb_ctx;
00278   uvc_device_handle_t *open_devices;
00279   pthread_t handler_thread;
00280   uint8_t kill_handler_thread;
00281 };
00282 
00283 uvc_error_t uvc_query_stream_ctrl(
00284     uvc_device_handle_t *devh,
00285     uvc_stream_ctrl_t *ctrl,
00286     uint8_t probe,
00287     enum uvc_req_code req);
00288 
00289 void uvc_start_handler_thread(uvc_context_t *ctx);
00290 uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx);
00291 uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx);
00292 
00293 #endif // !def(LIBUVC_INTERNAL_H)
00294 


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:39