44 #define DELTA_EPOCH_IN_MICROSECS 116444736000000000Ui64 49 int gettimeofday(
struct timeval *tv,
struct timezone *
tz)
52 unsigned __int64 tmpres = 0;
53 static int tzflag = 0;
56 GetSystemTimeAsFileTime(&ft);
57 tmpres |= ft.dwHighDateTime;
59 tmpres |= ft.dwLowDateTime;
61 tmpres -= DELTA_EPOCH_IN_MICROSECS;
62 tv->tv_sec = (long)(tmpres / 1000000UL);
63 tv->tv_usec = (long)(tmpres % 1000000UL);
69 uint16_t format_id, uint16_t frame_id);
71 uint16_t format_id, uint16_t frame_id);
77 return fourcc == *(
const uint32_t *)guid ? 1 : 0;
81 return *(
const uint32_t *)guid;
100 memset(buf, 0,
sizeof(buf));
102 if (devh->info->ctrl_if.bcdUVC >= 0x0110)
109 SHORT_TO_SW(ctrl->
bmHint, buf);
117 SHORT_TO_SW(ctrl->
wDelay, buf + 16);
132 err = libusb_control_transfer(
136 probe ? (UVC_VS_PROBE_CONTROL << 8) : (UVC_VS_COMMIT_CONTROL << 8),
147 ctrl->
bmHint = SW_TO_SHORT(buf);
155 ctrl->
wDelay = SW_TO_SHORT(buf + 16);
204 strmh->cur_ctrl = *ctrl;
215 uint16_t format_id, uint16_t frame_id) {
233 uint16_t format_id, uint16_t frame_id) {
244 uint16_t format_id, uint16_t frame_id) {
246 uvc_streaming_interface_t *stream_if;
249 DL_FOREACH(devh->info->stream_ifs, stream_if) {
274 uvc_streaming_interface_t *stream_if;
277 DL_FOREACH(devh->info->stream_ifs, stream_if) {
283 if(fourcc != *(
const uint32_t *)format->
guidFormat)
293 for (interval = frame->
intervals; *interval; ++interval) {
295 int uvc_fps = 10000000 / *interval;
296 if (abs(uvc_fps - fps) <= 1 || fps == 0) {
312 uint32_t interval_100ns = 10000000 / fps;
316 && interval_100ns <= frame->dwMaxFrameInterval
373 pthread_mutex_lock(&strmh->cb_mutex);
376 tmp_buf = strmh->holdbuf;
377 strmh->hold_bytes = strmh->got_bytes;
378 strmh->holdbuf = strmh->outbuf;
379 strmh->outbuf = tmp_buf;
380 strmh->hold_last_scr = strmh->last_scr;
381 strmh->hold_pts = strmh->pts;
382 strmh->hold_seq = strmh->seq;
384 pthread_cond_broadcast(&strmh->cb_cond);
385 pthread_mutex_unlock(&strmh->cb_mutex);
388 strmh->got_bytes = 0;
407 struct libusb_iso_packet_descriptor *pkt;
410 static uint8_t isight_tag[] = {
411 0x11, 0x22, 0x33, 0x44,
412 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce
416 if (payload_len == 0)
427 if (strmh->devh->is_isight &&
428 (payload_len < 14 || memcmp(isight_tag, payload + 2,
sizeof(isight_tag))) &&
429 (payload_len < 15 || memcmp(isight_tag, payload + 3,
sizeof(isight_tag)))) {
432 data_len = payload_len;
434 header_len = payload[0];
436 if (header_len > payload_len) {
437 UVC_DEBUG(
"bogus packet: actual_len=%zd, header_len=%zd\n", payload_len, header_len);
441 if (strmh->devh->is_isight)
444 data_len = payload_len - header_len;
447 if (header_len < 2) {
451 size_t variable_offset = 2;
453 header_info = payload[1];
455 if (header_info & 0x40) {
456 UVC_DEBUG(
"bad packet: error bit set",);
460 if (strmh->fid != (header_info & 1) && strmh->got_bytes != 0) {
467 strmh->fid = header_info & 1;
469 if (header_info & (1 << 2)) {
470 strmh->pts = DW_TO_INT(payload + variable_offset);
471 variable_offset += 4;
474 if (header_info & (1 << 3)) {
476 strmh->last_scr = DW_TO_INT(payload + variable_offset);
477 variable_offset += 6;
482 memcpy(strmh->outbuf + strmh->got_bytes, payload + header_len, data_len);
483 strmh->got_bytes += data_len;
485 if (header_info & (1 << 1)) {
505 switch (transfer->status) {
506 case LIBUSB_TRANSFER_COMPLETED:
507 if (transfer->num_iso_packets == 0) {
514 for (packet_id = 0; packet_id < transfer->num_iso_packets; ++packet_id) {
516 struct libusb_iso_packet_descriptor *pkt;
518 pkt = transfer->iso_packet_desc + packet_id;
520 if (pkt->status != 0) {
521 UVC_DEBUG(
"bad packet (isochronous transfer); status: %d", pkt->status);
525 pktbuf = libusb_get_iso_packet_buffer_simple(transfer, packet_id);
532 case LIBUSB_TRANSFER_CANCELLED:
533 case LIBUSB_TRANSFER_ERROR:
534 case LIBUSB_TRANSFER_NO_DEVICE: {
536 UVC_DEBUG(
"transfer exception, status = %s", libusb_error_name(transfer->status));
537 pthread_mutex_lock(&strmh->cb_mutex);
540 for(i=0; i < strmh->num_transfer_bufs; i++) {
541 if(strmh->transfers[i] == transfer) {
542 UVC_DEBUG(
"Freeing transfer %d (%p)", i, transfer);
543 free(transfer->buffer);
544 libusb_free_transfer(transfer);
545 strmh->transfers[i] = NULL;
549 if(i == strmh->num_transfer_bufs ) {
550 UVC_DEBUG(
"transfer %p not found; not freeing!", transfer);
555 pthread_cond_broadcast(&strmh->cb_cond);
556 pthread_mutex_unlock(&strmh->cb_mutex);
560 case LIBUSB_TRANSFER_TIMED_OUT:
561 case LIBUSB_TRANSFER_STALL:
562 case LIBUSB_TRANSFER_OVERFLOW:
563 UVC_DEBUG(
"retrying transfer, status = %d", transfer->status);
567 if (strmh->running && resubmit)
568 libusb_submit_transfer(transfer);
587 int num_transfer_buffers
598 UVC_DEBUG(
"FAILED TO START STREAM: %i", ret);
612 if (strmh->stream_if->bInterfaceNumber == interface_idx)
620 uvc_streaming_interface_t *stream_if;
622 DL_FOREACH(devh->info->stream_ifs, stream_if) {
623 if (stream_if->bInterfaceNumber == interface_idx)
640 uvc_streaming_interface_t *stream_if;
656 strmh = calloc(1,
sizeof(*strmh));
662 strmh->stream_if = stream_if;
663 strmh->frame.library_owns_data = 1;
665 ret =
uvc_claim_if(strmh->devh, strmh->stream_if->bInterfaceNumber);
676 strmh->outbuf = malloc( LIBUVC_XFER_BUF_SIZE );
677 strmh->holdbuf = malloc( LIBUVC_XFER_BUF_SIZE );
679 pthread_mutex_init(&strmh->cb_mutex, NULL);
680 pthread_cond_init(&strmh->cb_cond, NULL);
709 int num_transfer_buffers
712 const struct libusb_interface *interface;
720 size_t total_transfer_size;
721 struct libusb_transfer *transfer;
724 ctrl = &strmh->cur_ctrl;
728 if (strmh->running) {
744 format_desc = frame_desc->
parent;
749 interface_id = strmh->stream_if->bInterfaceNumber;
750 interface = &strmh->devh->info->config->interface[interface_id];
754 isochronous = interface->num_altsetting > 1;
759 const struct libusb_interface_descriptor *altsetting;
760 const struct libusb_endpoint_descriptor *endpoint;
763 size_t config_bytes_per_packet;
765 size_t packets_per_transfer;
767 size_t endpoint_bytes_per_packet;
771 config_bytes_per_packet = strmh->cur_ctrl.dwMaxPayloadTransferSize;
776 for (alt_idx = 0; alt_idx < interface->num_altsetting; alt_idx++) {
777 altsetting = interface->altsetting + alt_idx;
778 endpoint_bytes_per_packet = 0;
781 for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) {
782 endpoint = altsetting->endpoint + ep_idx;
784 if (endpoint->bEndpointAddress == format_desc->
parent->bEndpointAddress) {
785 endpoint_bytes_per_packet = endpoint->wMaxPacketSize;
787 endpoint_bytes_per_packet = (endpoint_bytes_per_packet & 0x07ff) *
788 (((endpoint_bytes_per_packet >> 11) & 3) + 1);
793 if (endpoint_bytes_per_packet >= config_bytes_per_packet) {
797 endpoint_bytes_per_packet - 1) / endpoint_bytes_per_packet;
800 if (packets_per_transfer > 32)
801 packets_per_transfer = 32;
803 total_transfer_size = packets_per_transfer * endpoint_bytes_per_packet;
809 if (alt_idx == interface->num_altsetting) {
815 ret = libusb_set_interface_alt_setting(strmh->devh->usb_devh,
816 altsetting->bInterfaceNumber,
817 altsetting->bAlternateSetting);
819 UVC_DEBUG(
"libusb_set_interface_alt_setting failed",);
824 strmh->num_transfer_bufs = num_transfer_buffers;
825 strmh->transfers = malloc(
sizeof(
struct libusb_transfer *) * num_transfer_buffers);
826 strmh->transfer_bufs = malloc(
sizeof(
struct uint8_t *) * num_transfer_buffers);
827 for (transfer_id = 0; transfer_id < num_transfer_buffers; ++transfer_id)
829 transfer = libusb_alloc_transfer(packets_per_transfer);
830 strmh->transfers[transfer_id] = transfer;
831 strmh->transfer_bufs[transfer_id] = malloc(total_transfer_size);
833 libusb_fill_iso_transfer(
834 transfer, strmh->devh->usb_devh, format_desc->
parent->bEndpointAddress,
835 strmh->transfer_bufs[transfer_id],
838 libusb_set_iso_packet_lengths(transfer, endpoint_bytes_per_packet);
844 strmh->num_transfer_bufs = num_transfer_buffers;
845 strmh->transfers = malloc(
sizeof(
struct libusb_transfer *) * num_transfer_buffers);
846 strmh->transfer_bufs = malloc(
sizeof(
struct uint8_t *) * num_transfer_buffers);
847 for (transfer_id = 0; transfer_id < num_transfer_buffers; ++transfer_id)
849 transfer = libusb_alloc_transfer(0);
850 strmh->transfers[transfer_id] = transfer;
851 strmh->transfer_bufs[transfer_id] = malloc (
852 strmh->cur_ctrl.dwMaxPayloadTransferSize );
853 libusb_fill_bulk_transfer ( transfer, strmh->devh->usb_devh,
854 format_desc->
parent->bEndpointAddress,
855 strmh->transfer_bufs[transfer_id],
857 (
void* ) strmh, 5000 );
862 strmh->user_ptr = user_ptr;
872 for (transfer_id = 0; transfer_id < num_transfer_buffers; transfer_id++)
874 ret = libusb_submit_transfer(strmh->transfers[transfer_id]);
877 UVC_DEBUG(
"libusb_submit_transfer failed",);
898 uint32_t last_seq = 0;
901 pthread_mutex_lock(&strmh->cb_mutex);
903 while (strmh->running && last_seq == strmh->hold_seq) {
904 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
907 if (!strmh->running) {
908 pthread_mutex_unlock(&strmh->cb_mutex);
912 last_seq = strmh->hold_seq;
915 pthread_mutex_unlock(&strmh->cb_mutex);
917 strmh->user_cb(&strmh->frame, strmh->user_ptr);
928 size_t alloc_size = strmh->cur_ctrl.dwMaxVideoFrameSize;
938 strmh->cur_ctrl.bFrameIndex);
940 frame->
fourcc = strmh->fourcc;
945 #pragma GCC diagnostic push 946 #pragma GCC diagnostic ignored "-Wmultichar" 948 #pragma GCC diagnostic ignored "-Wfour-char-constants" 958 #pragma GCC diagnostic pop 962 frame->
data = realloc(frame->
data, strmh->hold_bytes);
979 int32_t timeout_us) {
991 pthread_mutex_lock(&strmh->cb_mutex);
993 if (strmh->last_polled_seq < strmh->hold_seq) {
995 *frame = &strmh->frame;
996 strmh->last_polled_seq = strmh->hold_seq;
997 }
else if (timeout_us != -1) {
998 if (timeout_us == 0) {
999 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1001 add_secs = timeout_us / 1000000;
1002 add_nsecs = (timeout_us % 1000000) * 1000;
1006 #if _POSIX_TIMERS > 0 1007 clock_gettime(CLOCK_REALTIME, &ts);
1009 gettimeofday(&tv, NULL);
1010 ts.tv_sec = tv.tv_sec;
1011 ts.tv_nsec = tv.tv_usec * 1000;
1014 ts.tv_sec += add_secs;
1015 ts.tv_nsec += add_nsecs;
1017 pthread_cond_timedwait(&strmh->cb_cond, &strmh->cb_mutex, &ts);
1020 if (strmh->last_polled_seq < strmh->hold_seq) {
1022 *frame = &strmh->frame;
1023 strmh->last_polled_seq = strmh->hold_seq;
1031 pthread_mutex_unlock(&strmh->cb_mutex);
1063 if (!strmh->running)
1068 pthread_mutex_lock(&strmh->cb_mutex);
1070 for(i=0; i < strmh->num_transfer_bufs; i++) {
1071 if(strmh->transfers[i] != NULL) {
1072 int res = libusb_cancel_transfer(strmh->transfers[i]);
1074 free(strmh->transfers[i]->buffer);
1075 libusb_free_transfer(strmh->transfers[i]);
1076 strmh->transfers[i] = NULL;
1084 for(i=0; i < strmh->num_transfer_bufs; i++) {
1085 if(strmh->transfers[i] != NULL)
1089 if(i == strmh->num_transfer_bufs )
1095 add_secs = timeout_s ;
1099 #if _POSIX_TIMERS > 0 1100 clock_gettime(CLOCK_REALTIME, &ts);
1102 gettimeofday(&tv, NULL);
1103 ts.tv_sec = tv.tv_sec;
1104 ts.tv_nsec = tv.tv_usec * 1000;
1107 ts.tv_sec += add_secs;
1109 if (ETIMEDOUT == pthread_cond_timedwait(&strmh->cb_cond, &strmh->cb_mutex, &ts)){
1116 pthread_cond_broadcast(&strmh->cb_cond);
1117 pthread_mutex_unlock(&strmh->cb_mutex);
1121 if (strmh->user_cb) {
1124 pthread_join(strmh->cb_thread, NULL);
1143 if (strmh->frame.data)
1144 free(strmh->frame.data);
1146 free(strmh->outbuf);
1147 free(strmh->holdbuf);
1149 pthread_cond_destroy(&strmh->cb_cond);
1150 pthread_mutex_destroy(&strmh->cb_mutex);
static uint32_t uvc_frame_format_for_guid(uint8_t guid[16])
void _uvc_populate_frame(uvc_stream_handle_t *strmh)
uvc_error_t uvc_query_stream_ctrl(uvc_device_handle_t *devh, uvc_stream_ctrl_t *ctrl, uint8_t probe, enum uvc_req_code req)
enum uvc_error uvc_error_t
uvc_error_t uvc_stream_ctrl(uvc_stream_handle_t *strmh, uvc_stream_ctrl_t *ctrl)
Reconfigure stream with a new stream format.This may be executed whether or not the stream is running...
GLint GLint GLsizei GLsizei height
#define DL_FOREACH(head, el)
void uvc_stop_streaming(uvc_device_handle_t *devh)
Stop streaming videoCloses all streams, ends threads and cancels pollers.
uvc_error_t uvc_stream_start(uvc_stream_handle_t *strmh, uvc_frame_callback_t *cb, void *user_ptr, uint8_t flags, int num_transfer_buffers)
uvc_error_t uvc_start_streaming(uvc_device_handle_t *devh, uvc_stream_ctrl_t *ctrl, uvc_frame_callback_t *cb, void *user_ptr, uint8_t flags, int num_transfer_buffers)
GLenum GLuint GLenum GLsizei const GLchar * buf
uvc_error_t uvc_stream_get_frame(uvc_stream_handle_t *strmh, uvc_frame_t **frame, int32_t timeout_us)
uint32_t dwFrameIntervalStep
struct uvc_format_desc * parent
uint32_t dwMaxVideoFrameBufferSize
uvc_frame_desc_t * uvc_find_frame_desc(uvc_device_handle_t *devh, uint16_t format_id, uint16_t frame_id)
uvc_stream_handle_t * handle
uint32_t dwMaxPayloadTransferSize
uvc_error_t uvc_stream_open_ctrl(uvc_device_handle_t *devh, uvc_stream_handle_t **strmhp, uvc_stream_ctrl_t *ctrl)
uvc_frame_desc_t * uvc_find_frame_desc_stream(uvc_stream_handle_t *strmh, uint16_t format_id, uint16_t frame_id)
#define DL_DELETE(head, del)
void _uvc_swap_buffers(uvc_stream_handle_t *strmh)
uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh)
Stop stream.Stops stream, ends threads and cancels pollers.
uint32_t dwClockFrequency
uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx)
format
Formats: defines how each stream can be encoded. rs_format specifies how a frame is represented in me...
Implementation-specific UVC constants and structures.
struct uvc_stream_handle uvc_stream_handle_t
static uvc_streaming_interface_t * _uvc_get_stream_if(uvc_device_handle_t *devh, int interface_idx)
uvc_error_t uvc_get_stream_ctrl_format_size(uvc_device_handle_t *devh, uvc_stream_ctrl_t *ctrl, uint32_t fourcc, int width, int height, int fps)
static uvc_frame_desc_t * _uvc_find_frame_desc_stream_if(uvc_streaming_interface_t *stream_if, uint16_t format_id, uint16_t frame_id)
uint32_t dwMaxVideoFrameSize
uvc_error_t uvc_probe_stream_ctrl(uvc_device_handle_t *devh, uvc_stream_ctrl_t *ctrl)
void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer)
GLint GLint GLsizei width
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define DL_APPEND(head, add)
struct uvc_device_handle uvc_device_handle_t
#define DL_FOREACH_SAFE(head, el, tmp)
uint32_t dwMinFrameInterval
static uvc_stream_handle_t * _uvc_get_stream_by_interface(uvc_device_handle_t *devh, int interface_idx)
void _uvc_process_payload(uvc_stream_handle_t *strmh, uint8_t *payload, size_t payload_len)
uint8_t bPreferredVersion
void * _uvc_user_caller(void *arg)
void( uvc_frame_callback_t)(struct uvc_frame *frame, void *user_ptr)
uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx)
void uvc_stream_close(uvc_stream_handle_t *strmh)
Close stream.Closes stream, frees handle and all streaming resources.
static uint8_t _uvc_frame_format_matches_guid(uint32_t fourcc, uint8_t guid[16])