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