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 streaming Streaming control functions
36 * @brief Tools for creating, managing and consuming video streams
37 */
38
39 #include "libuvc/libuvc.h"
40 #include "libuvc/libuvc_internal.h"
41 #include "errno.h"
42
43 #ifdef _MSC_VER
44
45 #define DELTA_EPOCH_IN_MICROSECS 116444736000000000Ui64
46
47 // gettimeofday - get time of day for Windows;
48 // A gettimeofday implementation for Microsoft Windows;
49 // Public domain code, author "ponnada";
gettimeofday(struct timeval * tv,struct timezone * tz)50 int gettimeofday(struct timeval *tv, struct timezone *tz)
51 {
52 FILETIME ft;
53 unsigned __int64 tmpres = 0;
54 static int tzflag = 0;
55 if (NULL != tv)
56 {
57 GetSystemTimeAsFileTime(&ft);
58 tmpres |= ft.dwHighDateTime;
59 tmpres <<= 32;
60 tmpres |= ft.dwLowDateTime;
61 tmpres /= 10;
62 tmpres -= DELTA_EPOCH_IN_MICROSECS;
63 tv->tv_sec = (long)(tmpres / 1000000UL);
64 tv->tv_usec = (long)(tmpres % 1000000UL);
65 }
66 return 0;
67 }
68 #endif // _MSC_VER
69 uvc_frame_desc_t *uvc_find_frame_desc_stream(uvc_stream_handle_t *strmh,
70 uint16_t format_id, uint16_t frame_id);
71 uvc_frame_desc_t *uvc_find_frame_desc(uvc_device_handle_t *devh,
72 uint16_t format_id, uint16_t frame_id);
73 void *_uvc_user_caller(void *arg);
74 void _uvc_populate_frame(uvc_stream_handle_t *strmh);
75
76 static uvc_streaming_interface_t *_uvc_get_stream_if(uvc_device_handle_t *devh, int interface_idx);
77 static uvc_stream_handle_t *_uvc_get_stream_by_interface(uvc_device_handle_t *devh, int interface_idx);
78
79 struct format_table_entry {
80 enum uvc_frame_format format;
81 uint8_t abstract_fmt;
82 uint8_t guid[16];
83 int children_count;
84 enum uvc_frame_format *children;
85 };
86
_get_format_entry(enum uvc_frame_format format)87 struct format_table_entry *_get_format_entry(enum uvc_frame_format format) {
88 #define ABS_FMT(_fmt, _num, ...) \
89 case _fmt: { \
90 static enum uvc_frame_format _fmt##_children[] = __VA_ARGS__; \
91 static struct format_table_entry _fmt##_entry = { \
92 _fmt, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, _num, _fmt##_children }; \
93 return &_fmt##_entry; }
94
95 #define FMT(_fmt, ...) \
96 case _fmt: { \
97 static struct format_table_entry _fmt##_entry = { \
98 _fmt, 0, __VA_ARGS__, 0, NULL }; \
99 return &_fmt##_entry; }
100
101 switch(format) {
102 /* Define new formats here */
103 ABS_FMT(UVC_FRAME_FORMAT_ANY, 2,
104 {UVC_FRAME_FORMAT_UNCOMPRESSED, UVC_FRAME_FORMAT_COMPRESSED})
105
106 ABS_FMT(UVC_FRAME_FORMAT_UNCOMPRESSED, 6,
107 {UVC_FRAME_FORMAT_YUYV, UVC_FRAME_FORMAT_UYVY, UVC_FRAME_FORMAT_GRAY8,
108 UVC_FRAME_FORMAT_GRAY16, UVC_FRAME_FORMAT_NV12, UVC_FRAME_FORMAT_BGR})
109 FMT(UVC_FRAME_FORMAT_YUYV,
110 {'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
111 FMT(UVC_FRAME_FORMAT_UYVY,
112 {'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
113 FMT(UVC_FRAME_FORMAT_GRAY8,
114 {'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
115 FMT(UVC_FRAME_FORMAT_GRAY16,
116 {'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
117 FMT(UVC_FRAME_FORMAT_NV12,
118 {'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
119 FMT(UVC_FRAME_FORMAT_BGR,
120 {0x7d, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70})
121 FMT(UVC_FRAME_FORMAT_BY8,
122 {'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
123 FMT(UVC_FRAME_FORMAT_BA81,
124 {'B', 'A', '8', '1', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
125 FMT(UVC_FRAME_FORMAT_SGRBG8,
126 {'G', 'R', 'B', 'G', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
127 FMT(UVC_FRAME_FORMAT_SGBRG8,
128 {'G', 'B', 'R', 'G', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
129 FMT(UVC_FRAME_FORMAT_SRGGB8,
130 {'R', 'G', 'G', 'B', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
131 FMT(UVC_FRAME_FORMAT_SBGGR8,
132 {'B', 'G', 'G', 'R', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
133 ABS_FMT(UVC_FRAME_FORMAT_COMPRESSED, 2,
134 {UVC_FRAME_FORMAT_MJPEG, UVC_FRAME_FORMAT_H264})
135 FMT(UVC_FRAME_FORMAT_MJPEG,
136 {'M', 'J', 'P', 'G'})
137 FMT(UVC_FRAME_FORMAT_H264,
138 {'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
139
140 default:
141 return NULL;
142 }
143
144 #undef ABS_FMT
145 #undef FMT
146 }
147
_uvc_frame_format_matches_guid(enum uvc_frame_format fmt,uint8_t guid[16])148 static uint8_t _uvc_frame_format_matches_guid(enum uvc_frame_format fmt, uint8_t guid[16]) {
149 struct format_table_entry *format;
150 int child_idx;
151
152 format = _get_format_entry(fmt);
153 if (!format)
154 return 0;
155
156 if (!format->abstract_fmt && !memcmp(guid, format->guid, 16))
157 return 1;
158
159 for (child_idx = 0; child_idx < format->children_count; child_idx++) {
160 if (_uvc_frame_format_matches_guid(format->children[child_idx], guid))
161 return 1;
162 }
163
164 return 0;
165 }
166
uvc_frame_format_for_guid(uint8_t guid[16])167 static enum uvc_frame_format uvc_frame_format_for_guid(uint8_t guid[16]) {
168 struct format_table_entry *format;
169 enum uvc_frame_format fmt;
170
171 for (fmt = 0; fmt < UVC_FRAME_FORMAT_COUNT; ++fmt) {
172 format = _get_format_entry(fmt);
173 if (!format || format->abstract_fmt)
174 continue;
175 if (!memcmp(format->guid, guid, 16))
176 return format->format;
177 }
178
179 return UVC_FRAME_FORMAT_UNKNOWN;
180 }
181
182 /** @internal
183 * Run a streaming control query
184 * @param[in] devh UVC device
185 * @param[in,out] ctrl Control block
186 * @param[in] probe Whether this is a probe query or a commit query
187 * @param[in] req Query type
188 */
uvc_query_stream_ctrl(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl,uint8_t probe,enum uvc_req_code req)189 uvc_error_t uvc_query_stream_ctrl(
190 uvc_device_handle_t *devh,
191 uvc_stream_ctrl_t *ctrl,
192 uint8_t probe,
193 enum uvc_req_code req) {
194 uint8_t buf[34];
195 size_t len;
196 uvc_error_t err;
197
198 memset(buf, 0, sizeof(buf));
199
200 if (devh->info->ctrl_if.bcdUVC >= 0x0110)
201 len = 34;
202 else
203 len = 26;
204
205 /* prepare for a SET transfer */
206 if (req == UVC_SET_CUR) {
207 SHORT_TO_SW(ctrl->bmHint, buf);
208 buf[2] = ctrl->bFormatIndex;
209 buf[3] = ctrl->bFrameIndex;
210 INT_TO_DW(ctrl->dwFrameInterval, buf + 4);
211 SHORT_TO_SW(ctrl->wKeyFrameRate, buf + 8);
212 SHORT_TO_SW(ctrl->wPFrameRate, buf + 10);
213 SHORT_TO_SW(ctrl->wCompQuality, buf + 12);
214 SHORT_TO_SW(ctrl->wCompWindowSize, buf + 14);
215 SHORT_TO_SW(ctrl->wDelay, buf + 16);
216 INT_TO_DW(ctrl->dwMaxVideoFrameSize, buf + 18);
217 INT_TO_DW(ctrl->dwMaxPayloadTransferSize, buf + 22);
218
219 if (len == 34) {
220 INT_TO_DW ( ctrl->dwClockFrequency, buf + 26 );
221 buf[30] = ctrl->bmFramingInfo;
222 buf[31] = ctrl->bPreferredVersion;
223 buf[32] = ctrl->bMinVersion;
224 buf[33] = ctrl->bMaxVersion;
225 /** @todo support UVC 1.1 */
226 }
227 }
228
229 /* do the transfer */
230 err = libusb_control_transfer(
231 devh->usb_devh,
232 req == UVC_SET_CUR ? 0x21 : 0xA1,
233 req,
234 probe ? (UVC_VS_PROBE_CONTROL << 8) : (UVC_VS_COMMIT_CONTROL << 8),
235 ctrl->bInterfaceNumber,
236 buf, len, 0
237 );
238
239 if (err <= 0) {
240 return err;
241 }
242
243 /* now decode following a GET transfer */
244 if (req != UVC_SET_CUR) {
245 ctrl->bmHint = SW_TO_SHORT(buf);
246 ctrl->bFormatIndex = buf[2];
247 ctrl->bFrameIndex = buf[3];
248 ctrl->dwFrameInterval = DW_TO_INT(buf + 4);
249 ctrl->wKeyFrameRate = SW_TO_SHORT(buf + 8);
250 ctrl->wPFrameRate = SW_TO_SHORT(buf + 10);
251 ctrl->wCompQuality = SW_TO_SHORT(buf + 12);
252 ctrl->wCompWindowSize = SW_TO_SHORT(buf + 14);
253 ctrl->wDelay = SW_TO_SHORT(buf + 16);
254 ctrl->dwMaxVideoFrameSize = DW_TO_INT(buf + 18);
255 ctrl->dwMaxPayloadTransferSize = DW_TO_INT(buf + 22);
256
257 if (len == 34) {
258 ctrl->dwClockFrequency = DW_TO_INT ( buf + 26 );
259 ctrl->bmFramingInfo = buf[30];
260 ctrl->bPreferredVersion = buf[31];
261 ctrl->bMinVersion = buf[32];
262 ctrl->bMaxVersion = buf[33];
263 /** @todo support UVC 1.1 */
264 }
265 else
266 ctrl->dwClockFrequency = devh->info->ctrl_if.dwClockFrequency;
267
268 /* fix up block for cameras that fail to set dwMax* */
269 if (ctrl->dwMaxVideoFrameSize == 0) {
270 uvc_frame_desc_t *frame = uvc_find_frame_desc(devh, ctrl->bFormatIndex, ctrl->bFrameIndex);
271
272 if (frame) {
273 ctrl->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize;
274 }
275 }
276 }
277
278 return UVC_SUCCESS;
279 }
280
281 /** @internal
282 * Run a streaming control query
283 * @param[in] devh UVC device
284 * @param[in,out] ctrl Control block
285 * @param[in] probe Whether this is a probe query or a commit query
286 * @param[in] req Query type
287 */
uvc_query_still_ctrl(uvc_device_handle_t * devh,uvc_still_ctrl_t * still_ctrl,uint8_t probe,enum uvc_req_code req)288 uvc_error_t uvc_query_still_ctrl(
289 uvc_device_handle_t *devh,
290 uvc_still_ctrl_t *still_ctrl,
291 uint8_t probe,
292 enum uvc_req_code req) {
293
294 uint8_t buf[11];
295 const size_t len = 11;
296 uvc_error_t err;
297
298 memset(buf, 0, sizeof(buf));
299
300 if (req == UVC_SET_CUR) {
301 /* prepare for a SET transfer */
302 buf[0] = still_ctrl->bFormatIndex;
303 buf[1] = still_ctrl->bFrameIndex;
304 buf[2] = still_ctrl->bCompressionIndex;
305 INT_TO_DW(still_ctrl->dwMaxVideoFrameSize, buf + 3);
306 INT_TO_DW(still_ctrl->dwMaxPayloadTransferSize, buf + 7);
307 }
308
309 /* do the transfer */
310 err = libusb_control_transfer(
311 devh->usb_devh,
312 req == UVC_SET_CUR ? 0x21 : 0xA1,
313 req,
314 probe ? (UVC_VS_STILL_PROBE_CONTROL << 8) : (UVC_VS_STILL_COMMIT_CONTROL << 8),
315 still_ctrl->bInterfaceNumber,
316 buf, len, 0
317 );
318
319 if (err <= 0) {
320 return err;
321 }
322
323 /* now decode following a GET transfer */
324 if (req != UVC_SET_CUR) {
325 still_ctrl->bFormatIndex = buf[0];
326 still_ctrl->bFrameIndex = buf[1];
327 still_ctrl->bCompressionIndex = buf[2];
328 still_ctrl->dwMaxVideoFrameSize = DW_TO_INT(buf + 3);
329 still_ctrl->dwMaxPayloadTransferSize = DW_TO_INT(buf + 7);
330 }
331
332 return UVC_SUCCESS;
333 }
334
335 /** Initiate a method 2 (in stream) still capture
336 * @ingroup streaming
337 *
338 * @param[in] devh Device handle
339 * @param[in] still_ctrl Still capture control block
340 */
uvc_trigger_still(uvc_device_handle_t * devh,uvc_still_ctrl_t * still_ctrl)341 uvc_error_t uvc_trigger_still(
342 uvc_device_handle_t *devh,
343 uvc_still_ctrl_t *still_ctrl) {
344 uvc_stream_handle_t* stream;
345 uvc_streaming_interface_t* stream_if;
346 uint8_t buf;
347 uvc_error_t err;
348
349 /* Stream must be running for method 2 to work */
350 stream = _uvc_get_stream_by_interface(devh, still_ctrl->bInterfaceNumber);
351 if (!stream || !stream->running)
352 return UVC_ERROR_NOT_SUPPORTED;
353
354 /* Only method 2 is supported */
355 stream_if = _uvc_get_stream_if(devh, still_ctrl->bInterfaceNumber);
356 if(!stream_if || stream_if->bStillCaptureMethod != 2)
357 return UVC_ERROR_NOT_SUPPORTED;
358
359 /* prepare for a SET transfer */
360 buf = 1;
361
362 /* do the transfer */
363 err = libusb_control_transfer(
364 devh->usb_devh,
365 0x21, //type set
366 UVC_SET_CUR,
367 (UVC_VS_STILL_IMAGE_TRIGGER_CONTROL << 8),
368 still_ctrl->bInterfaceNumber,
369 &buf, 1, 0);
370
371 if (err <= 0) {
372 return err;
373 }
374
375 return UVC_SUCCESS;
376 }
377
378 /** @brief Reconfigure stream with a new stream format.
379 * @ingroup streaming
380 *
381 * This may be executed whether or not the stream is running.
382 *
383 * @param[in] strmh Stream handle
384 * @param[in] ctrl Control block, processed using {uvc_probe_stream_ctrl} or
385 * {uvc_get_stream_ctrl_format_size}
386 */
uvc_stream_ctrl(uvc_stream_handle_t * strmh,uvc_stream_ctrl_t * ctrl)387 uvc_error_t uvc_stream_ctrl(uvc_stream_handle_t *strmh, uvc_stream_ctrl_t *ctrl) {
388 uvc_error_t ret;
389
390 if (strmh->stream_if->bInterfaceNumber != ctrl->bInterfaceNumber)
391 return UVC_ERROR_INVALID_PARAM;
392
393 /* @todo Allow the stream to be modified without restarting the stream */
394 if (strmh->running)
395 return UVC_ERROR_BUSY;
396
397 ret = uvc_query_stream_ctrl(strmh->devh, ctrl, 0, UVC_SET_CUR);
398 if (ret != UVC_SUCCESS)
399 return ret;
400
401 strmh->cur_ctrl = *ctrl;
402 return UVC_SUCCESS;
403 }
404
405 /** @internal
406 * @brief Find the descriptor for a specific frame configuration
407 * @param stream_if Stream interface
408 * @param format_id Index of format class descriptor
409 * @param frame_id Index of frame descriptor
410 */
_uvc_find_frame_desc_stream_if(uvc_streaming_interface_t * stream_if,uint16_t format_id,uint16_t frame_id)411 static uvc_frame_desc_t *_uvc_find_frame_desc_stream_if(uvc_streaming_interface_t *stream_if,
412 uint16_t format_id, uint16_t frame_id) {
413
414 uvc_format_desc_t *format = NULL;
415 uvc_frame_desc_t *frame = NULL;
416
417 DL_FOREACH(stream_if->format_descs, format) {
418 if (format->bFormatIndex == format_id) {
419 DL_FOREACH(format->frame_descs, frame) {
420 if (frame->bFrameIndex == frame_id)
421 return frame;
422 }
423 }
424 }
425
426 return NULL;
427 }
428
uvc_find_frame_desc_stream(uvc_stream_handle_t * strmh,uint16_t format_id,uint16_t frame_id)429 uvc_frame_desc_t *uvc_find_frame_desc_stream(uvc_stream_handle_t *strmh,
430 uint16_t format_id, uint16_t frame_id) {
431 return _uvc_find_frame_desc_stream_if(strmh->stream_if, format_id, frame_id);
432 }
433
434 /** @internal
435 * @brief Find the descriptor for a specific frame configuration
436 * @param devh UVC device
437 * @param format_id Index of format class descriptor
438 * @param frame_id Index of frame descriptor
439 */
uvc_find_frame_desc(uvc_device_handle_t * devh,uint16_t format_id,uint16_t frame_id)440 uvc_frame_desc_t *uvc_find_frame_desc(uvc_device_handle_t *devh,
441 uint16_t format_id, uint16_t frame_id) {
442
443 uvc_streaming_interface_t *stream_if;
444 uvc_frame_desc_t *frame;
445
446 DL_FOREACH(devh->info->stream_ifs, stream_if) {
447 frame = _uvc_find_frame_desc_stream_if(stream_if, format_id, frame_id);
448 if (frame)
449 return frame;
450 }
451
452 return NULL;
453 }
454
455 /** Get a negotiated streaming control block for some common parameters.
456 * @ingroup streaming
457 *
458 * @param[in] devh Device handle
459 * @param[in,out] ctrl Control block
460 * @param[in] format_class Type of streaming format
461 * @param[in] width Desired frame width
462 * @param[in] height Desired frame height
463 * @param[in] fps Frame rate, frames per second
464 */
uvc_get_stream_ctrl_format_size(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl,enum uvc_frame_format cf,int width,int height,int fps)465 uvc_error_t uvc_get_stream_ctrl_format_size(
466 uvc_device_handle_t *devh,
467 uvc_stream_ctrl_t *ctrl,
468 enum uvc_frame_format cf,
469 int width, int height,
470 int fps) {
471 uvc_streaming_interface_t *stream_if;
472
473 /* find a matching frame descriptor and interval */
474 DL_FOREACH(devh->info->stream_ifs, stream_if) {
475 uvc_format_desc_t *format;
476
477 DL_FOREACH(stream_if->format_descs, format) {
478 uvc_frame_desc_t *frame;
479
480 if (!_uvc_frame_format_matches_guid(cf, format->guidFormat))
481 continue;
482
483 DL_FOREACH(format->frame_descs, frame) {
484 if (frame->wWidth != width || frame->wHeight != height)
485 continue;
486
487 uint32_t *interval;
488
489 ctrl->bInterfaceNumber = stream_if->bInterfaceNumber;
490 UVC_DEBUG("claiming streaming interface %d", stream_if->bInterfaceNumber );
491 uvc_claim_if(devh, ctrl->bInterfaceNumber);
492 /* get the max values */
493 uvc_query_stream_ctrl( devh, ctrl, 1, UVC_GET_MAX);
494
495 if (frame->intervals) {
496 for (interval = frame->intervals; *interval; ++interval) {
497 // allow a fps rate of zero to mean "accept first rate available"
498 if (10000000 / *interval == (unsigned int) fps || fps == 0) {
499
500 ctrl->bmHint = (1 << 0); /* don't negotiate interval */
501 ctrl->bFormatIndex = format->bFormatIndex;
502 ctrl->bFrameIndex = frame->bFrameIndex;
503 ctrl->dwFrameInterval = *interval;
504
505 goto found;
506 }
507 }
508 } else {
509 uint32_t interval_100ns = 10000000 / fps;
510 uint32_t interval_offset = interval_100ns - frame->dwMinFrameInterval;
511
512 if (interval_100ns >= frame->dwMinFrameInterval
513 && interval_100ns <= frame->dwMaxFrameInterval
514 && !(interval_offset
515 && (interval_offset % frame->dwFrameIntervalStep))) {
516
517 ctrl->bmHint = (1 << 0);
518 ctrl->bFormatIndex = format->bFormatIndex;
519 ctrl->bFrameIndex = frame->bFrameIndex;
520 ctrl->dwFrameInterval = interval_100ns;
521
522 goto found;
523 }
524 }
525 }
526 }
527 }
528
529 return UVC_ERROR_INVALID_MODE;
530
531 found:
532 return uvc_probe_stream_ctrl(devh, ctrl);
533 }
534
535 /** Get a negotiated still control block for some common parameters.
536 * @ingroup streaming
537 *
538 * @param[in] devh Device handle
539 * @param[in] ctrl Control block
540 * @param[in, out] still_ctrl Still capture control block
541 * @param[in] width Desired frame width
542 * @param[in] height Desired frame height
543 */
uvc_get_still_ctrl_format_size(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl,uvc_still_ctrl_t * still_ctrl,int width,int height)544 uvc_error_t uvc_get_still_ctrl_format_size(
545 uvc_device_handle_t *devh,
546 uvc_stream_ctrl_t *ctrl,
547 uvc_still_ctrl_t *still_ctrl,
548 int width, int height) {
549 uvc_streaming_interface_t *stream_if;
550 uvc_still_frame_desc_t *still;
551 uvc_format_desc_t *format;
552 uvc_still_frame_res_t *sizePattern;
553
554 stream_if = _uvc_get_stream_if(devh, ctrl->bInterfaceNumber);
555
556 /* Only method 2 is supported */
557 if(!stream_if || stream_if->bStillCaptureMethod != 2)
558 return UVC_ERROR_NOT_SUPPORTED;
559
560 DL_FOREACH(stream_if->format_descs, format) {
561
562 if (ctrl->bFormatIndex != format->bFormatIndex)
563 continue;
564
565 /* get the max values */
566 uvc_query_still_ctrl(devh, still_ctrl, 1, UVC_GET_MAX);
567
568 //look for still format
569 DL_FOREACH(format->still_frame_desc, still) {
570 DL_FOREACH(still->imageSizePatterns, sizePattern) {
571
572 if (sizePattern->wWidth != width || sizePattern->wHeight != height)
573 continue;
574
575 still_ctrl->bInterfaceNumber = ctrl->bInterfaceNumber;
576 still_ctrl->bFormatIndex = format->bFormatIndex;
577 still_ctrl->bFrameIndex = sizePattern->bResolutionIndex;
578 still_ctrl->bCompressionIndex = 0; //TODO support compression index
579 goto found;
580 }
581 }
582 }
583
584 return UVC_ERROR_INVALID_MODE;
585
586 found:
587 return uvc_probe_still_ctrl(devh, still_ctrl);
588 }
589
590 /** @internal
591 * Negotiate streaming parameters with the device
592 *
593 * @param[in] devh UVC device
594 * @param[in,out] ctrl Control block
595 */
uvc_probe_stream_ctrl(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl)596 uvc_error_t uvc_probe_stream_ctrl(
597 uvc_device_handle_t *devh,
598 uvc_stream_ctrl_t *ctrl) {
599
600 uvc_query_stream_ctrl(
601 devh, ctrl, 1, UVC_SET_CUR
602 );
603
604 uvc_query_stream_ctrl(
605 devh, ctrl, 1, UVC_GET_CUR
606 );
607
608 /** @todo make sure that worked */
609 return UVC_SUCCESS;
610 }
611
612 /** @internal
613 * Negotiate still parameters with the device
614 *
615 * @param[in] devh UVC device
616 * @param[in,out] still_ctrl Still capture control block
617 */
uvc_probe_still_ctrl(uvc_device_handle_t * devh,uvc_still_ctrl_t * still_ctrl)618 uvc_error_t uvc_probe_still_ctrl(
619 uvc_device_handle_t *devh,
620 uvc_still_ctrl_t *still_ctrl) {
621
622 int res = uvc_query_still_ctrl(
623 devh, still_ctrl, 1, UVC_SET_CUR
624 );
625
626 if(res == UVC_SUCCESS) {
627 res = uvc_query_still_ctrl(
628 devh, still_ctrl, 1, UVC_GET_CUR
629 );
630
631 if(res == UVC_SUCCESS) {
632 res = uvc_query_still_ctrl(
633 devh, still_ctrl, 0, UVC_SET_CUR
634 );
635 }
636 }
637
638 return res;
639 }
640
641 /** @internal
642 * @brief Swap the working buffer with the presented buffer and notify consumers
643 */
_uvc_swap_buffers(uvc_stream_handle_t * strmh)644 void _uvc_swap_buffers(uvc_stream_handle_t *strmh) {
645 uint8_t *tmp_buf;
646
647 pthread_mutex_lock(&strmh->cb_mutex);
648
649 (void)clock_gettime(CLOCK_MONOTONIC, &strmh->capture_time_finished);
650
651 /* swap the buffers */
652 tmp_buf = strmh->holdbuf;
653 strmh->hold_bytes = strmh->got_bytes;
654 strmh->holdbuf = strmh->outbuf;
655 strmh->outbuf = tmp_buf;
656 strmh->hold_last_scr = strmh->last_scr;
657 strmh->hold_pts = strmh->pts;
658 strmh->hold_seq = strmh->seq;
659
660 /* swap metadata buffer */
661 tmp_buf = strmh->meta_holdbuf;
662 strmh->meta_holdbuf = strmh->meta_outbuf;
663 strmh->meta_outbuf = tmp_buf;
664 strmh->meta_hold_bytes = strmh->meta_got_bytes;
665
666 pthread_cond_broadcast(&strmh->cb_cond);
667 pthread_mutex_unlock(&strmh->cb_mutex);
668
669 strmh->seq++;
670 strmh->got_bytes = 0;
671 strmh->meta_got_bytes = 0;
672 strmh->last_scr = 0;
673 strmh->pts = 0;
674 }
675
676 /** @internal
677 * @brief Process a payload transfer
678 *
679 * Processes stream, places frames into buffer, signals listeners
680 * (such as user callback thread and any polling thread) on new frame
681 *
682 * @param payload Contents of the payload transfer, either a packet (isochronous) or a full
683 * transfer (bulk mode)
684 * @param payload_len Length of the payload transfer
685 */
_uvc_process_payload(uvc_stream_handle_t * strmh,uint8_t * payload,size_t payload_len)686 void _uvc_process_payload(uvc_stream_handle_t *strmh, uint8_t *payload, size_t payload_len) {
687 size_t header_len;
688 uint8_t header_info;
689 size_t data_len;
690
691 /* magic numbers for identifying header packets from some iSight cameras */
692 static uint8_t isight_tag[] = {
693 0x11, 0x22, 0x33, 0x44,
694 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce
695 };
696
697 /* ignore empty payload transfers */
698 if (payload_len == 0)
699 return;
700
701 /* Certain iSight cameras have strange behavior: They send header
702 * information in a packet with no image data, and then the following
703 * packets have only image data, with no more headers until the next frame.
704 *
705 * The iSight header: len(1), flags(1 or 2), 0x11223344(4),
706 * 0xdeadbeefdeadface(8), ??(16)
707 */
708
709 if (strmh->devh->is_isight &&
710 (payload_len < 14 || memcmp(isight_tag, payload + 2, sizeof(isight_tag))) &&
711 (payload_len < 15 || memcmp(isight_tag, payload + 3, sizeof(isight_tag)))) {
712 /* The payload transfer doesn't have any iSight magic, so it's all image data */
713 header_len = 0;
714 data_len = payload_len;
715 } else {
716 header_len = payload[0];
717
718 if (header_len > payload_len) {
719 UVC_DEBUG("bogus packet: actual_len=%zd, header_len=%zd\n", payload_len, header_len);
720 return;
721 }
722
723 if (strmh->devh->is_isight)
724 data_len = 0;
725 else
726 data_len = payload_len - header_len;
727 }
728
729 if (header_len < 2) {
730 header_info = 0;
731 } else {
732 /** @todo we should be checking the end-of-header bit */
733 size_t variable_offset = 2;
734
735 header_info = payload[1];
736
737 if (header_info & 0x40) {
738 UVC_DEBUG("bad packet: error bit set");
739 return;
740 }
741
742 if (strmh->fid != (header_info & 1) && strmh->got_bytes != 0) {
743 /* The frame ID bit was flipped, but we have image data sitting
744 around from prior transfers. This means the camera didn't send
745 an EOF for the last transfer of the previous frame. */
746 _uvc_swap_buffers(strmh);
747 }
748
749 strmh->fid = header_info & 1;
750
751 if (header_info & (1 << 2)) {
752 strmh->pts = DW_TO_INT(payload + variable_offset);
753 variable_offset += 4;
754 }
755
756 if (header_info & (1 << 3)) {
757 /** @todo read the SOF token counter */
758 strmh->last_scr = DW_TO_INT(payload + variable_offset);
759 variable_offset += 6;
760 }
761
762 if (header_len > variable_offset)
763 {
764 // Metadata is attached to header
765 memcpy(strmh->meta_outbuf + strmh->meta_got_bytes, payload + variable_offset, header_len - variable_offset);
766 strmh->meta_got_bytes += header_len - variable_offset;
767 }
768 }
769
770 if (data_len > 0) {
771 memcpy(strmh->outbuf + strmh->got_bytes, payload + header_len, data_len);
772 strmh->got_bytes += data_len;
773
774 if (header_info & (1 << 1)) {
775 /* The EOF bit is set, so publish the complete frame */
776 _uvc_swap_buffers(strmh);
777 }
778 }
779 }
780
781 /** @internal
782 * @brief Stream transfer callback
783 *
784 * Processes stream, places frames into buffer, signals listeners
785 * (such as user callback thread and any polling thread) on new frame
786 *
787 * @param transfer Active transfer
788 */
_uvc_stream_callback(struct libusb_transfer * transfer)789 void LIBUSB_CALL _uvc_stream_callback(struct libusb_transfer *transfer) {
790 uvc_stream_handle_t *strmh = transfer->user_data;
791
792 int resubmit = 1;
793
794 switch (transfer->status) {
795 case LIBUSB_TRANSFER_COMPLETED:
796 if (transfer->num_iso_packets == 0) {
797 /* This is a bulk mode transfer, so it just has one payload transfer */
798 _uvc_process_payload(strmh, transfer->buffer, transfer->actual_length);
799 } else {
800 /* This is an isochronous mode transfer, so each packet has a payload transfer */
801 int packet_id;
802
803 for (packet_id = 0; packet_id < transfer->num_iso_packets; ++packet_id) {
804 uint8_t *pktbuf;
805 struct libusb_iso_packet_descriptor *pkt;
806
807 pkt = transfer->iso_packet_desc + packet_id;
808
809 if (pkt->status != 0) {
810 UVC_DEBUG("bad packet (isochronous transfer); status: %d", pkt->status);
811 continue;
812 }
813
814 pktbuf = libusb_get_iso_packet_buffer_simple(transfer, packet_id);
815
816 _uvc_process_payload(strmh, pktbuf, pkt->actual_length);
817
818 }
819 }
820 break;
821 case LIBUSB_TRANSFER_CANCELLED:
822 case LIBUSB_TRANSFER_ERROR:
823 case LIBUSB_TRANSFER_NO_DEVICE: {
824 int i;
825 UVC_DEBUG("not retrying transfer, status = %d", transfer->status);
826 pthread_mutex_lock(&strmh->cb_mutex);
827
828 /* Mark transfer as deleted. */
829 for(i=0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
830 if(strmh->transfers[i] == transfer) {
831 UVC_DEBUG("Freeing transfer %d (%p)", i, transfer);
832 free(transfer->buffer);
833 libusb_free_transfer(transfer);
834 strmh->transfers[i] = NULL;
835 break;
836 }
837 }
838 if(i == LIBUVC_NUM_TRANSFER_BUFS ) {
839 UVC_DEBUG("transfer %p not found; not freeing!", transfer);
840 }
841
842 resubmit = 0;
843
844 pthread_cond_broadcast(&strmh->cb_cond);
845 pthread_mutex_unlock(&strmh->cb_mutex);
846
847 break;
848 }
849 case LIBUSB_TRANSFER_TIMED_OUT:
850 case LIBUSB_TRANSFER_STALL:
851 case LIBUSB_TRANSFER_OVERFLOW:
852 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
853 break;
854 }
855
856 if ( resubmit ) {
857 if ( strmh->running ) {
858 int libusbRet = libusb_submit_transfer(transfer);
859 if (libusbRet < 0)
860 {
861 int i;
862 pthread_mutex_lock(&strmh->cb_mutex);
863
864 /* Mark transfer as deleted. */
865 for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
866 if (strmh->transfers[i] == transfer) {
867 UVC_DEBUG("Freeing failed transfer %d (%p)", i, transfer);
868 free(transfer->buffer);
869 libusb_free_transfer(transfer);
870 strmh->transfers[i] = NULL;
871 break;
872 }
873 }
874 if (i == LIBUVC_NUM_TRANSFER_BUFS) {
875 UVC_DEBUG("failed transfer %p not found; not freeing!", transfer);
876 }
877
878 pthread_cond_broadcast(&strmh->cb_cond);
879 pthread_mutex_unlock(&strmh->cb_mutex);
880 }
881 } else {
882 int i;
883 pthread_mutex_lock(&strmh->cb_mutex);
884
885 /* Mark transfer as deleted. */
886 for(i=0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
887 if(strmh->transfers[i] == transfer) {
888 UVC_DEBUG("Freeing orphan transfer %d (%p)", i, transfer);
889 free(transfer->buffer);
890 libusb_free_transfer(transfer);
891 strmh->transfers[i] = NULL;
892 break;
893 }
894 }
895 if(i == LIBUVC_NUM_TRANSFER_BUFS ) {
896 UVC_DEBUG("orphan transfer %p not found; not freeing!", transfer);
897 }
898
899 pthread_cond_broadcast(&strmh->cb_cond);
900 pthread_mutex_unlock(&strmh->cb_mutex);
901 }
902 }
903 }
904
905 /** Begin streaming video from the camera into the callback function.
906 * @ingroup streaming
907 *
908 * @param devh UVC device
909 * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
910 * {uvc_get_stream_ctrl_format_size}
911 * @param cb User callback function. See {uvc_frame_callback_t} for restrictions.
912 * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
913 * is reserved for backward compatibility.
914 */
uvc_start_streaming(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl,uvc_frame_callback_t * cb,void * user_ptr,uint8_t flags)915 uvc_error_t uvc_start_streaming(
916 uvc_device_handle_t *devh,
917 uvc_stream_ctrl_t *ctrl,
918 uvc_frame_callback_t *cb,
919 void *user_ptr,
920 uint8_t flags
921 ) {
922 uvc_error_t ret;
923 uvc_stream_handle_t *strmh;
924
925 ret = uvc_stream_open_ctrl(devh, &strmh, ctrl);
926 if (ret != UVC_SUCCESS)
927 return ret;
928
929 ret = uvc_stream_start(strmh, cb, user_ptr, flags);
930 if (ret != UVC_SUCCESS) {
931 uvc_stream_close(strmh);
932 return ret;
933 }
934
935 return UVC_SUCCESS;
936 }
937
938 /** Begin streaming video from the camera into the callback function.
939 * @ingroup streaming
940 *
941 * @deprecated The stream type (bulk vs. isochronous) will be determined by the
942 * type of interface associated with the uvc_stream_ctrl_t parameter, regardless
943 * of whether the caller requests isochronous streaming. Please switch to
944 * uvc_start_streaming().
945 *
946 * @param devh UVC device
947 * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
948 * {uvc_get_stream_ctrl_format_size}
949 * @param cb User callback function. See {uvc_frame_callback_t} for restrictions.
950 */
uvc_start_iso_streaming(uvc_device_handle_t * devh,uvc_stream_ctrl_t * ctrl,uvc_frame_callback_t * cb,void * user_ptr)951 uvc_error_t uvc_start_iso_streaming(
952 uvc_device_handle_t *devh,
953 uvc_stream_ctrl_t *ctrl,
954 uvc_frame_callback_t *cb,
955 void *user_ptr
956 ) {
957 return uvc_start_streaming(devh, ctrl, cb, user_ptr, 0);
958 }
959
_uvc_get_stream_by_interface(uvc_device_handle_t * devh,int interface_idx)960 static uvc_stream_handle_t *_uvc_get_stream_by_interface(uvc_device_handle_t *devh, int interface_idx) {
961 uvc_stream_handle_t *strmh;
962
963 DL_FOREACH(devh->streams, strmh) {
964 if (strmh->stream_if->bInterfaceNumber == interface_idx)
965 return strmh;
966 }
967
968 return NULL;
969 }
970
_uvc_get_stream_if(uvc_device_handle_t * devh,int interface_idx)971 static uvc_streaming_interface_t *_uvc_get_stream_if(uvc_device_handle_t *devh, int interface_idx) {
972 uvc_streaming_interface_t *stream_if;
973
974 DL_FOREACH(devh->info->stream_ifs, stream_if) {
975 if (stream_if->bInterfaceNumber == interface_idx)
976 return stream_if;
977 }
978
979 return NULL;
980 }
981
982 /** Open a new video stream.
983 * @ingroup streaming
984 *
985 * @param devh UVC device
986 * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
987 * {uvc_get_stream_ctrl_format_size}
988 */
uvc_stream_open_ctrl(uvc_device_handle_t * devh,uvc_stream_handle_t ** strmhp,uvc_stream_ctrl_t * ctrl)989 uvc_error_t uvc_stream_open_ctrl(uvc_device_handle_t *devh, uvc_stream_handle_t **strmhp, uvc_stream_ctrl_t *ctrl) {
990 /* Chosen frame and format descriptors */
991 uvc_stream_handle_t *strmh = NULL;
992 uvc_streaming_interface_t *stream_if;
993 uvc_error_t ret;
994
995 UVC_ENTER();
996
997 if (_uvc_get_stream_by_interface(devh, ctrl->bInterfaceNumber) != NULL) {
998 ret = UVC_ERROR_BUSY; /* Stream is already opened */
999 goto fail;
1000 }
1001
1002 stream_if = _uvc_get_stream_if(devh, ctrl->bInterfaceNumber);
1003 if (!stream_if) {
1004 ret = UVC_ERROR_INVALID_PARAM;
1005 goto fail;
1006 }
1007
1008 strmh = calloc(1, sizeof(*strmh));
1009 if (!strmh) {
1010 ret = UVC_ERROR_NO_MEM;
1011 goto fail;
1012 }
1013 strmh->devh = devh;
1014 strmh->stream_if = stream_if;
1015 strmh->frame.library_owns_data = 1;
1016
1017 ret = uvc_claim_if(strmh->devh, strmh->stream_if->bInterfaceNumber);
1018 if (ret != UVC_SUCCESS)
1019 goto fail;
1020
1021 ret = uvc_stream_ctrl(strmh, ctrl);
1022 if (ret != UVC_SUCCESS)
1023 goto fail;
1024
1025 // Set up the streaming status and data space
1026 strmh->running = 0;
1027 /** @todo take only what we need */
1028 strmh->outbuf = malloc( LIBUVC_XFER_BUF_SIZE );
1029 strmh->holdbuf = malloc( LIBUVC_XFER_BUF_SIZE );
1030
1031 strmh->meta_outbuf = malloc( LIBUVC_XFER_META_BUF_SIZE );
1032 strmh->meta_holdbuf = malloc( LIBUVC_XFER_META_BUF_SIZE );
1033
1034 pthread_mutex_init(&strmh->cb_mutex, NULL);
1035 pthread_cond_init(&strmh->cb_cond, NULL);
1036
1037 DL_APPEND(devh->streams, strmh);
1038
1039 *strmhp = strmh;
1040
1041 UVC_EXIT(0);
1042 return UVC_SUCCESS;
1043
1044 fail:
1045 if(strmh)
1046 free(strmh);
1047 UVC_EXIT(ret);
1048 return ret;
1049 }
1050
1051 /** Begin streaming video from the stream into the callback function.
1052 * @ingroup streaming
1053 *
1054 * @param strmh UVC stream
1055 * @param cb User callback function. See {uvc_frame_callback_t} for restrictions.
1056 * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
1057 * is reserved for backward compatibility.
1058 */
uvc_stream_start(uvc_stream_handle_t * strmh,uvc_frame_callback_t * cb,void * user_ptr,uint8_t flags)1059 uvc_error_t uvc_stream_start(
1060 uvc_stream_handle_t *strmh,
1061 uvc_frame_callback_t *cb,
1062 void *user_ptr,
1063 uint8_t flags
1064 ) {
1065 /* USB interface we'll be using */
1066 const struct libusb_interface *interface;
1067 int interface_id;
1068 char isochronous;
1069 uvc_frame_desc_t *frame_desc;
1070 uvc_format_desc_t *format_desc;
1071 uvc_stream_ctrl_t *ctrl;
1072 uvc_error_t ret;
1073 /* Total amount of data per transfer */
1074 size_t total_transfer_size = 0;
1075 struct libusb_transfer *transfer;
1076 int transfer_id;
1077
1078 ctrl = &strmh->cur_ctrl;
1079
1080 UVC_ENTER();
1081
1082 if (strmh->running) {
1083 UVC_EXIT(UVC_ERROR_BUSY);
1084 return UVC_ERROR_BUSY;
1085 }
1086
1087 strmh->running = 1;
1088 strmh->seq = 1;
1089 strmh->fid = 0;
1090 strmh->pts = 0;
1091 strmh->last_scr = 0;
1092
1093 frame_desc = uvc_find_frame_desc_stream(strmh, ctrl->bFormatIndex, ctrl->bFrameIndex);
1094 if (!frame_desc) {
1095 ret = UVC_ERROR_INVALID_PARAM;
1096 goto fail;
1097 }
1098 format_desc = frame_desc->parent;
1099
1100 strmh->frame_format = uvc_frame_format_for_guid(format_desc->guidFormat);
1101 if (strmh->frame_format == UVC_FRAME_FORMAT_UNKNOWN) {
1102 ret = UVC_ERROR_NOT_SUPPORTED;
1103 goto fail;
1104 }
1105
1106 // Get the interface that provides the chosen format and frame configuration
1107 interface_id = strmh->stream_if->bInterfaceNumber;
1108 interface = &strmh->devh->info->config->interface[interface_id];
1109
1110 /* A VS interface uses isochronous transfers iff it has multiple altsettings.
1111 * (UVC 1.5: 2.4.3. VideoStreaming Interface) */
1112 isochronous = interface->num_altsetting > 1;
1113
1114 if (isochronous) {
1115 /* For isochronous streaming, we choose an appropriate altsetting for the endpoint
1116 * and set up several transfers */
1117 const struct libusb_interface_descriptor *altsetting = 0;
1118 const struct libusb_endpoint_descriptor *endpoint = 0;
1119 /* The greatest number of bytes that the device might provide, per packet, in this
1120 * configuration */
1121 size_t config_bytes_per_packet;
1122 /* Number of packets per transfer */
1123 size_t packets_per_transfer = 0;
1124 /* Size of packet transferable from the chosen endpoint */
1125 size_t endpoint_bytes_per_packet = 0;
1126 /* Index of the altsetting */
1127 int alt_idx, ep_idx;
1128
1129 config_bytes_per_packet = strmh->cur_ctrl.dwMaxPayloadTransferSize;
1130
1131 /* Go through the altsettings and find one whose packets are at least
1132 * as big as our format's maximum per-packet usage. Assume that the
1133 * packet sizes are increasing. */
1134 for (alt_idx = 0; alt_idx < interface->num_altsetting; alt_idx++) {
1135 altsetting = interface->altsetting + alt_idx;
1136 endpoint_bytes_per_packet = 0;
1137
1138 /* Find the endpoint with the number specified in the VS header */
1139 for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) {
1140 endpoint = altsetting->endpoint + ep_idx;
1141
1142 struct libusb_ss_endpoint_companion_descriptor *ep_comp = 0;
1143 libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
1144 if (ep_comp)
1145 {
1146 endpoint_bytes_per_packet = ep_comp->wBytesPerInterval;
1147 libusb_free_ss_endpoint_companion_descriptor(ep_comp);
1148 break;
1149 }
1150 else
1151 {
1152 if (endpoint->bEndpointAddress == format_desc->parent->bEndpointAddress) {
1153 endpoint_bytes_per_packet = endpoint->wMaxPacketSize;
1154 // wMaxPacketSize: [unused:2 (multiplier-1):3 size:11]
1155 endpoint_bytes_per_packet = (endpoint_bytes_per_packet & 0x07ff) *
1156 (((endpoint_bytes_per_packet >> 11) & 3) + 1);
1157 break;
1158 }
1159 }
1160 }
1161
1162 if (endpoint_bytes_per_packet >= config_bytes_per_packet) {
1163 /* Transfers will be at most one frame long: Divide the maximum frame size
1164 * by the size of the endpoint and round up */
1165 packets_per_transfer = (ctrl->dwMaxVideoFrameSize +
1166 endpoint_bytes_per_packet - 1) / endpoint_bytes_per_packet;
1167
1168 /* But keep a reasonable limit: Otherwise we start dropping data */
1169 if (packets_per_transfer > 32)
1170 packets_per_transfer = 32;
1171
1172 total_transfer_size = packets_per_transfer * endpoint_bytes_per_packet;
1173 break;
1174 }
1175 }
1176
1177 /* If we searched through all the altsettings and found nothing usable */
1178 if (alt_idx == interface->num_altsetting) {
1179 ret = UVC_ERROR_INVALID_MODE;
1180 goto fail;
1181 }
1182
1183 /* Select the altsetting */
1184 ret = libusb_set_interface_alt_setting(strmh->devh->usb_devh,
1185 altsetting->bInterfaceNumber,
1186 altsetting->bAlternateSetting);
1187 if (ret != UVC_SUCCESS) {
1188 UVC_DEBUG("libusb_set_interface_alt_setting failed");
1189 goto fail;
1190 }
1191
1192 /* Set up the transfers */
1193 for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS; ++transfer_id) {
1194 transfer = libusb_alloc_transfer(packets_per_transfer);
1195 strmh->transfers[transfer_id] = transfer;
1196 strmh->transfer_bufs[transfer_id] = malloc(total_transfer_size);
1197
1198 libusb_fill_iso_transfer(
1199 transfer, strmh->devh->usb_devh, format_desc->parent->bEndpointAddress,
1200 strmh->transfer_bufs[transfer_id],
1201 total_transfer_size, packets_per_transfer, _uvc_stream_callback, (void*) strmh, 5000);
1202
1203 libusb_set_iso_packet_lengths(transfer, endpoint_bytes_per_packet);
1204 }
1205 } else {
1206 for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS;
1207 ++transfer_id) {
1208 transfer = libusb_alloc_transfer(0);
1209 strmh->transfers[transfer_id] = transfer;
1210 strmh->transfer_bufs[transfer_id] = malloc (
1211 strmh->cur_ctrl.dwMaxPayloadTransferSize );
1212 libusb_fill_bulk_transfer ( transfer, strmh->devh->usb_devh,
1213 format_desc->parent->bEndpointAddress,
1214 strmh->transfer_bufs[transfer_id],
1215 strmh->cur_ctrl.dwMaxPayloadTransferSize, _uvc_stream_callback,
1216 ( void* ) strmh, 5000 );
1217 }
1218 }
1219
1220 strmh->user_cb = cb;
1221 strmh->user_ptr = user_ptr;
1222
1223 /* If the user wants it, set up a thread that calls the user's function
1224 * with the contents of each frame.
1225 */
1226 if (cb) {
1227 pthread_create(&strmh->cb_thread, NULL, _uvc_user_caller, (void*) strmh);
1228 }
1229
1230 for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS;
1231 transfer_id++) {
1232 ret = libusb_submit_transfer(strmh->transfers[transfer_id]);
1233 if (ret != UVC_SUCCESS) {
1234 UVC_DEBUG("libusb_submit_transfer failed: %d",ret);
1235 break;
1236 }
1237 }
1238
1239 if ( ret != UVC_SUCCESS && transfer_id > 0 ) {
1240 for ( ; transfer_id < LIBUVC_NUM_TRANSFER_BUFS; transfer_id++) {
1241 free ( strmh->transfers[transfer_id]->buffer );
1242 libusb_free_transfer ( strmh->transfers[transfer_id]);
1243 strmh->transfers[transfer_id] = 0;
1244 }
1245 ret = UVC_SUCCESS;
1246 }
1247
1248 UVC_EXIT(ret);
1249 return ret;
1250 fail:
1251 strmh->running = 0;
1252 UVC_EXIT(ret);
1253 return ret;
1254 }
1255
1256 /** Begin streaming video from the stream into the callback function.
1257 * @ingroup streaming
1258 *
1259 * @deprecated The stream type (bulk vs. isochronous) will be determined by the
1260 * type of interface associated with the uvc_stream_ctrl_t parameter, regardless
1261 * of whether the caller requests isochronous streaming. Please switch to
1262 * uvc_stream_start().
1263 *
1264 * @param strmh UVC stream
1265 * @param cb User callback function. See {uvc_frame_callback_t} for restrictions.
1266 */
uvc_stream_start_iso(uvc_stream_handle_t * strmh,uvc_frame_callback_t * cb,void * user_ptr)1267 uvc_error_t uvc_stream_start_iso(
1268 uvc_stream_handle_t *strmh,
1269 uvc_frame_callback_t *cb,
1270 void *user_ptr
1271 ) {
1272 return uvc_stream_start(strmh, cb, user_ptr, 0);
1273 }
1274
1275 /** @internal
1276 * @brief User callback runner thread
1277 * @note There should be at most one of these per currently streaming device
1278 * @param arg Device handle
1279 */
_uvc_user_caller(void * arg)1280 void *_uvc_user_caller(void *arg) {
1281 uvc_stream_handle_t *strmh = (uvc_stream_handle_t *) arg;
1282
1283 uint32_t last_seq = 0;
1284
1285 do {
1286 pthread_mutex_lock(&strmh->cb_mutex);
1287
1288 while (strmh->running && last_seq == strmh->hold_seq) {
1289 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1290 }
1291
1292 if (!strmh->running) {
1293 pthread_mutex_unlock(&strmh->cb_mutex);
1294 break;
1295 }
1296
1297 last_seq = strmh->hold_seq;
1298 _uvc_populate_frame(strmh);
1299
1300 pthread_mutex_unlock(&strmh->cb_mutex);
1301
1302 strmh->user_cb(&strmh->frame, strmh->user_ptr);
1303 } while(1);
1304
1305 return NULL; // return value ignored
1306 }
1307
1308 /** @internal
1309 * @brief Populate the fields of a frame to be handed to user code
1310 * must be called with stream cb lock held!
1311 */
_uvc_populate_frame(uvc_stream_handle_t * strmh)1312 void _uvc_populate_frame(uvc_stream_handle_t *strmh) {
1313 uvc_frame_t *frame = &strmh->frame;
1314 uvc_frame_desc_t *frame_desc;
1315
1316 /** @todo this stuff that hits the main config cache should really happen
1317 * in start() so that only one thread hits these data. all of this stuff
1318 * is going to be reopen_on_change anyway
1319 */
1320
1321 frame_desc = uvc_find_frame_desc(strmh->devh, strmh->cur_ctrl.bFormatIndex,
1322 strmh->cur_ctrl.bFrameIndex);
1323
1324 frame->frame_format = strmh->frame_format;
1325
1326 frame->width = frame_desc->wWidth;
1327 frame->height = frame_desc->wHeight;
1328
1329 switch (frame->frame_format) {
1330 case UVC_FRAME_FORMAT_BGR:
1331 frame->step = frame->width * 3;
1332 break;
1333 case UVC_FRAME_FORMAT_YUYV:
1334 frame->step = frame->width * 2;
1335 break;
1336 case UVC_FRAME_FORMAT_NV12:
1337 frame->step = frame->width;
1338 break;
1339 case UVC_FRAME_FORMAT_MJPEG:
1340 frame->step = 0;
1341 break;
1342 case UVC_FRAME_FORMAT_H264:
1343 frame->step = 0;
1344 break;
1345 default:
1346 frame->step = 0;
1347 break;
1348 }
1349
1350 frame->sequence = strmh->hold_seq;
1351 frame->capture_time_finished = strmh->capture_time_finished;
1352
1353 /* copy the image data from the hold buffer to the frame (unnecessary extra buf?) */
1354 if (frame->data_bytes < strmh->hold_bytes) {
1355 frame->data = realloc(frame->data, strmh->hold_bytes);
1356 }
1357 frame->data_bytes = strmh->hold_bytes;
1358 memcpy(frame->data, strmh->holdbuf, frame->data_bytes);
1359
1360 if (strmh->meta_hold_bytes > 0)
1361 {
1362 if (frame->metadata_bytes < strmh->meta_hold_bytes)
1363 {
1364 frame->metadata = realloc(frame->metadata, strmh->meta_hold_bytes);
1365 }
1366 frame->metadata_bytes = strmh->meta_hold_bytes;
1367 memcpy(frame->metadata, strmh->meta_holdbuf, frame->metadata_bytes);
1368 }
1369 }
1370
1371 /** Poll for a frame
1372 * @ingroup streaming
1373 *
1374 * @param devh UVC device
1375 * @param[out] frame Location to store pointer to captured frame (NULL on error)
1376 * @param timeout_us >0: Wait at most N microseconds; 0: Wait indefinitely; -1: return immediately
1377 */
uvc_stream_get_frame(uvc_stream_handle_t * strmh,uvc_frame_t ** frame,int32_t timeout_us)1378 uvc_error_t uvc_stream_get_frame(uvc_stream_handle_t *strmh,
1379 uvc_frame_t **frame,
1380 int32_t timeout_us) {
1381 time_t add_secs;
1382 time_t add_nsecs;
1383 struct timespec ts;
1384 struct timeval tv;
1385
1386 if (!strmh->running)
1387 return UVC_ERROR_INVALID_PARAM;
1388
1389 if (strmh->user_cb)
1390 return UVC_ERROR_CALLBACK_EXISTS;
1391
1392 pthread_mutex_lock(&strmh->cb_mutex);
1393
1394 if (strmh->last_polled_seq < strmh->hold_seq) {
1395 _uvc_populate_frame(strmh);
1396 *frame = &strmh->frame;
1397 strmh->last_polled_seq = strmh->hold_seq;
1398 } else if (timeout_us != -1) {
1399 if (timeout_us == 0) {
1400 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1401 } else {
1402 add_secs = timeout_us / 1000000;
1403 add_nsecs = (timeout_us % 1000000) * 1000;
1404 ts.tv_sec = 0;
1405 ts.tv_nsec = 0;
1406
1407 #if _POSIX_TIMERS > 0
1408 clock_gettime(CLOCK_REALTIME, &ts);
1409 #else
1410 gettimeofday(&tv, NULL);
1411 ts.tv_sec = tv.tv_sec;
1412 ts.tv_nsec = tv.tv_usec * 1000;
1413 #endif
1414
1415 ts.tv_sec += add_secs;
1416 ts.tv_nsec += add_nsecs;
1417
1418 /* pthread_cond_timedwait FAILS with EINVAL if ts.tv_nsec > 1000000000 (1 billion)
1419 * Since we are just adding values to the timespec, we have to increment the seconds if nanoseconds is greater than 1 billion,
1420 * and then re-adjust the nanoseconds in the correct range.
1421 * */
1422 ts.tv_sec += ts.tv_nsec / 1000000000;
1423 ts.tv_nsec = ts.tv_nsec % 1000000000;
1424
1425 int err = pthread_cond_timedwait(&strmh->cb_cond, &strmh->cb_mutex, &ts);
1426
1427 //TODO: How should we handle EINVAL?
1428 if (err) {
1429 *frame = NULL;
1430 pthread_mutex_unlock(&strmh->cb_mutex);
1431 return err == ETIMEDOUT ? UVC_ERROR_TIMEOUT : UVC_ERROR_OTHER;
1432 }
1433 }
1434
1435 if (strmh->last_polled_seq < strmh->hold_seq) {
1436 _uvc_populate_frame(strmh);
1437 *frame = &strmh->frame;
1438 strmh->last_polled_seq = strmh->hold_seq;
1439 } else {
1440 *frame = NULL;
1441 }
1442 } else {
1443 *frame = NULL;
1444 }
1445
1446 pthread_mutex_unlock(&strmh->cb_mutex);
1447
1448 return UVC_SUCCESS;
1449 }
1450
1451 /** @brief Stop streaming video
1452 * @ingroup streaming
1453 *
1454 * Closes all streams, ends threads and cancels pollers
1455 *
1456 * @param devh UVC device
1457 */
uvc_stop_streaming(uvc_device_handle_t * devh)1458 void uvc_stop_streaming(uvc_device_handle_t *devh) {
1459 uvc_stream_handle_t *strmh, *strmh_tmp;
1460
1461 DL_FOREACH_SAFE(devh->streams, strmh, strmh_tmp) {
1462 uvc_stream_close(strmh);
1463 }
1464 }
1465
1466 /** @brief Stop stream.
1467 * @ingroup streaming
1468 *
1469 * Stops stream, ends threads and cancels pollers
1470 *
1471 * @param devh UVC device
1472 */
uvc_stream_stop(uvc_stream_handle_t * strmh)1473 uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh) {
1474 int i;
1475
1476 if (!strmh->running)
1477 return UVC_ERROR_INVALID_PARAM;
1478
1479 strmh->running = 0;
1480
1481 pthread_mutex_lock(&strmh->cb_mutex);
1482
1483 for(i=0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
1484 if(strmh->transfers[i] != NULL) {
1485 int res = libusb_cancel_transfer(strmh->transfers[i]);
1486 if(res < 0 && res != LIBUSB_ERROR_NOT_FOUND ) {
1487 free(strmh->transfers[i]->buffer);
1488 libusb_free_transfer(strmh->transfers[i]);
1489 strmh->transfers[i] = NULL;
1490 }
1491 }
1492 }
1493
1494 /* Wait for transfers to complete/cancel */
1495 do {
1496 for(i=0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
1497 if(strmh->transfers[i] != NULL)
1498 break;
1499 }
1500 if(i == LIBUVC_NUM_TRANSFER_BUFS )
1501 break;
1502 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1503 } while(1);
1504 // Kick the user thread awake
1505 pthread_cond_broadcast(&strmh->cb_cond);
1506 pthread_mutex_unlock(&strmh->cb_mutex);
1507
1508 /** @todo stop the actual stream, camera side? */
1509
1510 if (strmh->user_cb) {
1511 /* wait for the thread to stop (triggered by
1512 * LIBUSB_TRANSFER_CANCELLED transfer) */
1513 pthread_join(strmh->cb_thread, NULL);
1514 }
1515
1516 return UVC_SUCCESS;
1517 }
1518
1519 /** @brief Close stream.
1520 * @ingroup streaming
1521 *
1522 * Closes stream, frees handle and all streaming resources.
1523 *
1524 * @param strmh UVC stream handle
1525 */
uvc_stream_close(uvc_stream_handle_t * strmh)1526 void uvc_stream_close(uvc_stream_handle_t *strmh) {
1527 if (strmh->running)
1528 uvc_stream_stop(strmh);
1529
1530 uvc_release_if(strmh->devh, strmh->stream_if->bInterfaceNumber);
1531
1532 if (strmh->frame.data)
1533 free(strmh->frame.data);
1534
1535 free(strmh->outbuf);
1536 free(strmh->holdbuf);
1537
1538 free(strmh->meta_outbuf);
1539 free(strmh->meta_holdbuf);
1540
1541 pthread_cond_destroy(&strmh->cb_cond);
1542 pthread_mutex_destroy(&strmh->cb_mutex);
1543
1544 DL_DELETE(strmh->devh->streams, strmh);
1545 free(strmh);
1546 }
1547