Fix issue 1) not recognizes some usb device, 2) reconnect when ffmpeg encoder error
[rtmpclient.git] / app / src / main / jni / libuvc / src / stream.c
1 /*********************************************************************
2  *********************************************************************/
3 /*********************************************************************
4  * modified some function to avoid crash, support Android
5  * Copyright (C) 2014-2016 saki@serenegiant All rights reserved.
6  *********************************************************************/
7 /*********************************************************************
8  * Software License Agreement (BSD License)
9  *
10  *  Copyright (C) 2010-2012 Ken Tossell
11  *  All rights reserved.
12  *
13  *  Redistribution and use in source and binary forms, with or without
14  *  modification, are permitted provided that the following conditions
15  *  are met:
16  *
17  *   * Redistributions of source code must retain the above copyright
18  *     notice, this list of conditions and the following disclaimer.
19  *   * Redistributions in binary form must reproduce the above
20  *     copyright notice, this list of conditions and the following
21  *     disclaimer in the documentation and/or other materials provided
22  *     with the distribution.
23  *   * Neither the name of the author nor other contributors may be
24  *     used to endorse or promote products derived from this software
25  *     without specific prior written permission.
26  *
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  *  POSSIBILITY OF SUCH DAMAGE.
39  *********************************************************************/
40 /**
41  * @defgroup streaming Streaming control functions
42  * @brief Tools for creating, managing and consuming video streams
43  */
44
45 #define LOCAL_DEBUG 0
46
47 #define LOG_TAG "libuvc/stream"
48 #if 1   // デバッグ情報を出さない時1
49         #ifndef LOG_NDEBUG
50                 #define LOG_NDEBUG              // LOGV/LOGD/MARKを出力しない時
51                 #endif
52         #undef USE_LOGALL                       // 指定したLOGxだけを出力
53 #else
54         #define USE_LOGALL
55         #undef LOG_NDEBUG
56         #undef NDEBUG
57         #define GET_RAW_DESCRIPTOR
58 #endif
59
60 #include <assert.h>             // XXX add assert for debugging
61
62 #include "libuvc/libuvc.h"
63 #include "libuvc/libuvc_internal.h"
64
65 uvc_frame_desc_t *uvc_find_frame_desc_stream(uvc_stream_handle_t *strmh,
66                 uint16_t format_id, uint16_t frame_id);
67 uvc_frame_desc_t *uvc_find_frame_desc(uvc_device_handle_t *devh,
68                 uint16_t format_id, uint16_t frame_id);
69 static void *_uvc_user_caller(void *arg);
70 static void _uvc_populate_frame(uvc_stream_handle_t *strmh);
71
72 struct format_table_entry {
73         enum uvc_frame_format format;
74         uint8_t abstract_fmt;
75         uint8_t guid[16];
76         int children_count;
77         enum uvc_frame_format *children;
78 };
79
80 struct format_table_entry *_get_format_entry(enum uvc_frame_format format) {
81 #define ABS_FMT(_fmt, ...) \
82     case _fmt: { \
83     static enum uvc_frame_format _fmt##_children[] = __VA_ARGS__; \
84     static struct format_table_entry _fmt##_entry = { \
85       _fmt, 0, {}, ARRAYSIZE(_fmt##_children), _fmt##_children }; \
86     return &_fmt##_entry; }
87
88 #define FMT(_fmt, ...) \
89     case _fmt: { \
90     static struct format_table_entry _fmt##_entry = { \
91       _fmt, 0, __VA_ARGS__, 0, NULL }; \
92     return &_fmt##_entry; }
93
94         switch (format) {
95         /* Define new formats here */
96         ABS_FMT(UVC_FRAME_FORMAT_ANY,
97                 {UVC_FRAME_FORMAT_UNCOMPRESSED, UVC_FRAME_FORMAT_COMPRESSED})
98
99         ABS_FMT(UVC_FRAME_FORMAT_UNCOMPRESSED,
100                 {UVC_FRAME_FORMAT_YUYV, UVC_FRAME_FORMAT_UYVY, UVC_FRAME_FORMAT_GRAY8})
101         FMT(UVC_FRAME_FORMAT_YUYV,
102                 {'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
103         FMT(UVC_FRAME_FORMAT_UYVY,
104                 {'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
105         FMT(UVC_FRAME_FORMAT_GRAY8,
106                 {'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
107     FMT(UVC_FRAME_FORMAT_BY8,
108         {'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71})
109
110         ABS_FMT(UVC_FRAME_FORMAT_COMPRESSED,
111                 {UVC_FRAME_FORMAT_MJPEG})
112         FMT(UVC_FRAME_FORMAT_MJPEG,
113                 {'M', 'J', 'P', 'G'})
114
115         default:
116                 return NULL;
117         }
118
119 #undef ABS_FMT
120 #undef FMT
121 }
122
123 static uint8_t _uvc_frame_format_matches_guid(enum uvc_frame_format fmt,
124                 uint8_t guid[16]) {
125         struct format_table_entry *format;
126         int child_idx;
127
128         format = _get_format_entry(fmt);
129         if (UNLIKELY(!format))
130                 return 0;
131
132         if (!format->abstract_fmt && !memcmp(guid, format->guid, 16))
133                 return 1;
134
135         for (child_idx = 0; child_idx < format->children_count; child_idx++) {
136                 if (_uvc_frame_format_matches_guid(format->children[child_idx], guid))
137                         return 1;
138         }
139
140         return 0;
141 }
142
143 static enum uvc_frame_format uvc_frame_format_for_guid(uint8_t guid[16]) {
144         struct format_table_entry *format;
145         enum uvc_frame_format fmt;
146
147         for (fmt = 0; fmt < UVC_FRAME_FORMAT_COUNT; ++fmt) {
148                 format = _get_format_entry(fmt);
149                 if (!format || format->abstract_fmt)
150                         continue;
151                 if (!memcmp(format->guid, guid, 16))
152                         return format->format;
153         }
154
155         return UVC_FRAME_FORMAT_UNKNOWN;
156 }
157
158 /** @internal
159  * Run a streaming control query
160  * @param[in] devh UVC device
161  * @param[in,out] ctrl Control block
162  * @param[in] probe Whether this is a probe query or a commit query
163  * @param[in] req Query type
164  */
165 uvc_error_t uvc_query_stream_ctrl(uvc_device_handle_t *devh,
166                 uvc_stream_ctrl_t *ctrl, uint8_t probe, enum uvc_req_code req) {
167         uint8_t buf[48];        // XXX support UVC 1.1 & 1.5
168         size_t len;
169         uvc_error_t err;
170
171         memset(buf, 0, sizeof(buf));    // bzero(buf, sizeof(buf));     // bzero is deprecated
172
173         const uint16_t bcdUVC = devh->info->ctrl_if.bcdUVC;
174         if (bcdUVC >= 0x0150)
175                 len = 48;
176         else if (bcdUVC >= 0x0110)
177                 len = 34;
178         else
179                 len = 26;
180 //      LOGI("bcdUVC:%x,req:0x%02x,probe:%d", bcdUVC, req, probe);
181         /* prepare for a SET transfer */
182         if (req == UVC_SET_CUR) {
183                 SHORT_TO_SW(ctrl->bmHint, buf);
184                 buf[2] = ctrl->bFormatIndex;
185                 buf[3] = ctrl->bFrameIndex;
186                 INT_TO_DW(ctrl->dwFrameInterval, buf + 4);
187                 SHORT_TO_SW(ctrl->wKeyFrameRate, buf + 8);
188                 SHORT_TO_SW(ctrl->wPFrameRate, buf + 10);
189                 SHORT_TO_SW(ctrl->wCompQuality, buf + 12);
190                 SHORT_TO_SW(ctrl->wCompWindowSize, buf + 14);
191                 SHORT_TO_SW(ctrl->wDelay, buf + 16);
192                 INT_TO_DW(ctrl->dwMaxVideoFrameSize, buf + 18);
193                 INT_TO_DW(ctrl->dwMaxPayloadTransferSize, buf + 22);
194
195                 if (len > 26) { // len == 34
196                         // XXX add to support UVC 1.1
197                         INT_TO_DW(ctrl->dwClockFrequency, buf + 26);
198                         buf[30] = ctrl->bmFramingInfo;
199                         buf[31] = ctrl->bPreferedVersion;
200                         buf[32] = ctrl->bMinVersion;
201                         buf[33] = ctrl->bMaxVersion;
202                         if (len == 48) {
203                                 // XXX add to support UVC1.5
204                                 buf[34] = ctrl->bUsage;
205                                 buf[35] = ctrl->bBitDepthLuma;
206                                 buf[36] = ctrl->bmSettings;
207                                 buf[37] = ctrl->bMaxNumberOfRefFramesPlus1;
208                                 SHORT_TO_SW(ctrl->bmRateControlModes, buf + 38);
209                                 LONG_TO_QW(ctrl->bmLayoutPerStream, buf + 40);
210                         }
211                 }
212         }
213
214         /* do the transfer */
215         err = libusb_control_transfer(devh->usb_devh,
216                         req == UVC_SET_CUR ? 0x21 : 0xA1, req,
217                         probe ? (UVC_VS_PROBE_CONTROL << 8) : (UVC_VS_COMMIT_CONTROL << 8),
218                         ctrl->bInterfaceNumber, buf, len, 0);
219
220         if (UNLIKELY(err <= 0)) {
221                 // when libusb_control_transfer returned error or transfer bytes was zero.
222                 if (!err) {
223                         UVC_DEBUG("libusb_control_transfer transfered zero length data");
224                         err = UVC_ERROR_OTHER;
225                 }
226                 return err;
227         }
228         if (err < len) {
229 #if !defined(__LP64__)
230                 LOGE("transfered bytes is smaller than data bytes:%d expected %d", err, len);
231 #else
232                 LOGE("transfered bytes is smaller than data bytes:%d expected %ld", err, len);
233 #endif
234                 return UVC_ERROR_OTHER;
235         }
236         /* now decode following a GET transfer */
237         if (req != UVC_SET_CUR) {
238                 ctrl->bmHint = SW_TO_SHORT(buf);
239                 ctrl->bFormatIndex = buf[2];
240                 ctrl->bFrameIndex = buf[3];
241                 ctrl->dwFrameInterval = DW_TO_INT(buf + 4);
242                 ctrl->wKeyFrameRate = SW_TO_SHORT(buf + 8);
243                 ctrl->wPFrameRate = SW_TO_SHORT(buf + 10);
244                 ctrl->wCompQuality = SW_TO_SHORT(buf + 12);
245                 ctrl->wCompWindowSize = SW_TO_SHORT(buf + 14);
246                 ctrl->wDelay = SW_TO_SHORT(buf + 16);
247                 ctrl->dwMaxVideoFrameSize = DW_TO_INT(buf + 18);
248                 ctrl->dwMaxPayloadTransferSize = DW_TO_INT(buf + 22);
249
250                 if (len > 26) { // len == 34
251                         // XXX add to support UVC 1.1
252                         ctrl->dwClockFrequency = DW_TO_INT(buf + 26);
253                         ctrl->bmFramingInfo = buf[30];
254                         ctrl->bPreferedVersion = buf[31];
255                         ctrl->bMinVersion = buf[32];
256                         ctrl->bMaxVersion = buf[33];
257                         if (len >= 48) {
258                                 // XXX add to support UVC1.5
259                                 ctrl->bUsage = buf[34];
260                                 ctrl->bBitDepthLuma = buf[35];
261                                 ctrl->bmSettings = buf[36];
262                                 ctrl->bMaxNumberOfRefFramesPlus1 = buf[37];
263                                 ctrl->bmRateControlModes = SW_TO_SHORT(buf + 38);
264                                 ctrl->bmLayoutPerStream = QW_TO_LONG(buf + 40);
265                         }
266                 }
267
268                 /* fix up block for cameras that fail to set dwMax */
269                 if (!ctrl->dwMaxVideoFrameSize) {
270                         LOGW("fix up block for cameras that fail to set dwMax");
271                         uvc_frame_desc_t *frame_desc = uvc_find_frame_desc(devh,
272                                         ctrl->bFormatIndex, ctrl->bFrameIndex);
273
274                         if (frame_desc) {
275                                 ctrl->dwMaxVideoFrameSize = frame_desc->dwMaxVideoFrameBufferSize;
276                         }
277                 }
278         }
279
280         return UVC_SUCCESS;
281 }
282
283 /** @brief Reconfigure stream with a new stream format.
284  * @ingroup streaming
285  *
286  * This may be executed whether or not the stream is running.
287  *
288  * @param[in] strmh Stream handle
289  * @param[in] ctrl Control block, processed using {uvc_probe_stream_ctrl} or
290  *             {uvc_get_stream_ctrl_format_size}
291  */
292 uvc_error_t uvc_stream_ctrl(uvc_stream_handle_t *strmh, uvc_stream_ctrl_t *ctrl) {
293         uvc_error_t ret;
294
295         if (UNLIKELY(strmh->stream_if->bInterfaceNumber != ctrl->bInterfaceNumber))
296                 return UVC_ERROR_INVALID_PARAM;
297
298         /* @todo Allow the stream to be modified without restarting the stream */
299         if (UNLIKELY(strmh->running))
300                 return UVC_ERROR_BUSY;
301
302         ret = uvc_query_stream_ctrl(strmh->devh, ctrl, 0, UVC_SET_CUR); // commit query
303         if (UNLIKELY(ret != UVC_SUCCESS))
304                 return ret;
305
306         strmh->cur_ctrl = *ctrl;
307         return UVC_SUCCESS;
308 }
309
310 /** @internal
311  * @brief Find the descriptor for a specific frame configuration
312  * @param stream_if Stream interface
313  * @param format_id Index of format class descriptor
314  * @param frame_id Index of frame descriptor
315  */
316 static uvc_frame_desc_t *_uvc_find_frame_desc_stream_if(
317                 uvc_streaming_interface_t *stream_if, uint16_t format_id,
318                 uint16_t frame_id) {
319
320         uvc_format_desc_t *format = NULL;
321         uvc_frame_desc_t *frame = NULL;
322
323         DL_FOREACH(stream_if->format_descs, format)
324         {
325                 if (format->bFormatIndex == format_id) {
326                         DL_FOREACH(format->frame_descs, frame)
327                         {
328                                 if (frame->bFrameIndex == frame_id)
329                                         return frame;
330                         }
331                 }
332         }
333
334         return NULL ;
335 }
336
337 uvc_error_t uvc_get_frame_desc(uvc_device_handle_t *devh,
338                 uvc_stream_ctrl_t *ctrl, uvc_frame_desc_t **desc) {
339
340         *desc = uvc_find_frame_desc(devh, ctrl->bFormatIndex, ctrl->bFrameIndex);
341         return *desc ? UVC_SUCCESS : UVC_ERROR_INVALID_PARAM;
342 }
343
344 uvc_frame_desc_t *uvc_find_frame_desc_stream(uvc_stream_handle_t *strmh,
345                 uint16_t format_id, uint16_t frame_id) {
346         return _uvc_find_frame_desc_stream_if(strmh->stream_if, format_id, frame_id);
347 }
348
349 /** @internal
350  * @brief Find the descriptor for a specific frame configuration
351  * @param devh UVC device
352  * @param format_id Index of format class descriptor
353  * @param frame_id Index of frame descriptor
354  */
355 uvc_frame_desc_t *uvc_find_frame_desc(uvc_device_handle_t *devh,
356                 uint16_t format_id, uint16_t frame_id) {
357
358         uvc_streaming_interface_t *stream_if;
359         uvc_frame_desc_t *frame;
360
361         DL_FOREACH(devh->info->stream_ifs, stream_if)
362         {
363                 frame = _uvc_find_frame_desc_stream_if(stream_if, format_id, frame_id);
364                 if (frame)
365                         return frame;
366         }
367
368         return NULL;
369 }
370
371 static void _uvc_print_streaming_interface_one(uvc_streaming_interface_t *stream_if) {
372 //      struct uvc_device_info *parent;
373 //      struct uvc_streaming_interface *prev, *next;
374         MARK("bInterfaceNumber:%d", stream_if->bInterfaceNumber);
375         uvc_print_format_desc_one(stream_if->format_descs, NULL);
376         MARK("bEndpointAddress:%d", stream_if->bEndpointAddress);
377         MARK("bTerminalLink:%d", stream_if->bTerminalLink);
378 }
379
380 static uvc_error_t _prepare_stream_ctrl(uvc_device_handle_t *devh, uvc_stream_ctrl_t *ctrl) {
381         // XXX some camera may need to call uvc_query_stream_ctrl with UVC_GET_CUR/UVC_GET_MAX/UVC_GET_MIN
382         // before negotiation otherwise stream stall. added by saki
383         uvc_error_t result = uvc_query_stream_ctrl(devh, ctrl, 1, UVC_GET_CUR); // probe query
384         if (LIKELY(!result)) {
385                 result = uvc_query_stream_ctrl(devh, ctrl, 1, UVC_GET_MIN);                     // probe query
386                 if (LIKELY(!result)) {
387                         result = uvc_query_stream_ctrl(devh, ctrl, 1, UVC_GET_MAX);             // probe query
388                         if (UNLIKELY(result))
389                                 LOGE("uvc_query_stream_ctrl:UVC_GET_MAX:err=%d", result);       // XXX 最大値の方を後で取得しないとだめ
390                 } else {
391                         LOGE("uvc_query_stream_ctrl:UVC_GET_MIN:err=%d", result);
392                 }
393         } else {
394                 LOGE("uvc_query_stream_ctrl:UVC_GET_CUR:err=%d", result);
395         }
396 #if 0
397         if (UNLIKELY(result)) {
398                 enum uvc_error_code_control error_code;
399                 uvc_get_error_code(devh, &error_code, UVC_GET_CUR);
400                 LOGE("uvc_query_stream_ctrl:ret=%d,err_code=%d", result, error_code);
401                 uvc_print_format_desc(devh->info->stream_ifs->format_descs, NULL);
402         }
403 #endif
404         return result;
405 }
406
407 static uvc_error_t _uvc_get_stream_ctrl_format(uvc_device_handle_t *devh,
408         uvc_streaming_interface_t *stream_if, uvc_stream_ctrl_t *ctrl, uvc_format_desc_t *format,
409         const int width, const int height,
410         const int min_fps, const int max_fps) {
411
412         ENTER();
413
414         int i;
415         uvc_frame_desc_t *frame;
416
417         ctrl->bInterfaceNumber = stream_if->bInterfaceNumber;
418         uvc_error_t result = uvc_claim_if(devh, ctrl->bInterfaceNumber);
419         if (UNLIKELY(result)) {
420                 LOGE("uvc_claim_if:err=%d", result);
421                 goto fail;
422         }
423         for (i = 0; i < 2; i++) {
424                 result = _prepare_stream_ctrl(devh, ctrl);
425         }
426         if (UNLIKELY(result)) {
427                 LOGE("_prepare_stream_ctrl:err=%d", result);
428                 goto fail;
429         }
430 #if 0
431         // XXX add check ctrl values
432         uint64_t bmaControl = stream_if->bmaControls[format->bFormatIndex - 1];
433         if (bmaControl & 0x001) {       // wKeyFrameRate
434                 if (UNLIKELY(!ctrl->wKeyFrameRate)) {
435                         LOGE("wKeyFrameRate should be set");
436                         RETURN(UVC_ERROR_INVALID_MODE, uvc_error_t);
437                 }
438         }
439         if (bmaControl & 0x002) {       // wPFrameRate
440                 if (UNLIKELY(!ctrl->wPFrameRate)) {
441                         LOGE("wPFrameRate should be set");
442                         RETURN(UVC_ERROR_INVALID_MODE, uvc_error_t);
443                 }
444         }
445         if (bmaControl & 0x004) {       // wCompQuality
446                 if (UNLIKELY(!ctrl->wCompQuality)) {
447                         LOGE("wCompQuality should be set");
448                         RETURN(UVC_ERROR_INVALID_MODE, uvc_error_t);
449                 }
450         }
451         if (bmaControl & 0x008) {       // wCompWindowSize
452                 if (UNLIKELY(!ctrl->wCompWindowSize)) {
453                         LOGE("wCompWindowSize should be set");
454                         RETURN(UVC_ERROR_INVALID_MODE, uvc_error_t);
455                 }
456         }
457 #endif
458         DL_FOREACH(format->frame_descs, frame)
459         {
460                 if (frame->wWidth != width || frame->wHeight != height)
461                         continue;
462
463                 uint32_t *interval;
464
465                 if (frame->intervals) {
466                         for (interval = frame->intervals; *interval; ++interval) {
467                                 if (UNLIKELY(!(*interval))) continue;
468                                 uint32_t it = 10000000 / *interval;
469                                 LOGV("it:%d", it);
470                                 if ((it >= (uint32_t) min_fps) && (it <= (uint32_t) max_fps)) {
471                                         ctrl->bmHint = (1 << 0); /* don't negotiate interval */
472                                         ctrl->bFormatIndex = format->bFormatIndex;
473                                         ctrl->bFrameIndex = frame->bFrameIndex;
474                                         ctrl->dwFrameInterval = *interval;
475
476                                         goto found;
477                                 }
478                         }
479                 } else {
480                         int32_t fps;
481                         for (fps = max_fps; fps >= min_fps; fps--) {
482                                 if (UNLIKELY(!fps)) continue;
483                                 uint32_t interval_100ns = 10000000 / fps;
484                                 uint32_t interval_offset = interval_100ns - frame->dwMinFrameInterval;
485                                 LOGV("fps:%d", fps);
486                                 if (interval_100ns >= frame->dwMinFrameInterval
487                                         && interval_100ns <= frame->dwMaxFrameInterval
488                                         && !(interval_offset
489                                                 && (interval_offset % frame->dwFrameIntervalStep) ) ) {
490                                         ctrl->bmHint = (1 << 0); /* don't negotiate interval */
491                                         ctrl->bFormatIndex = format->bFormatIndex;
492                                         ctrl->bFrameIndex = frame->bFrameIndex;
493                                         ctrl->dwFrameInterval = interval_100ns;
494
495                                         goto found;
496                                 }
497                         }
498                 }
499         }
500         result = UVC_ERROR_INVALID_MODE;
501 fail:
502         uvc_release_if(devh, ctrl->bInterfaceNumber);
503         RETURN(result, uvc_error_t);
504
505 found:
506         RETURN(UVC_SUCCESS, uvc_error_t);
507 }
508
509 /** Get a negotiated streaming control block for some common parameters.
510  * @ingroup streaming
511  *
512  * @param[in] devh Device handle
513  * @param[in,out] ctrl Control block
514  * @param[in] cf Type of streaming format
515  * @param[in] width Desired frame width
516  * @param[in] height Desired frame height
517  * @param[in] fps Frame rate, frames per second
518  */
519 uvc_error_t uvc_get_stream_ctrl_format_size(uvc_device_handle_t *devh,
520                 uvc_stream_ctrl_t *ctrl, enum uvc_frame_format cf, int width, int height, int fps) {
521
522         return uvc_get_stream_ctrl_format_size_fps(devh, ctrl, cf, width, height, fps, fps);
523 }
524
525 /** Get a negotiated streaming control block for some common parameters.
526  * @ingroup streaming
527  *
528  * @param[in] devh Device handle
529  * @param[in,out] ctrl Control block
530  * @param[in] cf Type of streaming format
531  * @param[in] width Desired frame width
532  * @param[in] height Desired frame height
533  * @param[in] min_fps Frame rate, minimum frames per second, this value is included
534  * @param[in] max_fps Frame rate, maximum frames per second, this value is included
535  */
536 uvc_error_t uvc_get_stream_ctrl_format_size_fps(uvc_device_handle_t *devh,
537                 uvc_stream_ctrl_t *ctrl, enum uvc_frame_format cf, int width,
538                 int height, int min_fps, int max_fps) {
539
540         ENTER();
541
542         uvc_streaming_interface_t *stream_if;
543         uvc_error_t result;
544
545         memset(ctrl, 0, sizeof(*ctrl)); // XXX add
546         /* find a matching frame descriptor and interval */
547         uvc_format_desc_t *format;
548         DL_FOREACH(devh->info->stream_ifs, stream_if)
549         {
550                 DL_FOREACH(stream_if->format_descs, format)
551                 {
552                         if (!_uvc_frame_format_matches_guid(cf, format->guidFormat))
553                                 continue;
554
555                         result = _uvc_get_stream_ctrl_format(devh, stream_if, ctrl, format, width, height, min_fps, max_fps);
556                         if (!result) {  // UVC_SUCCESS
557                                 goto found;
558                         }
559                 }
560         }
561
562         RETURN(UVC_ERROR_INVALID_MODE, uvc_error_t);
563
564 found:
565         RETURN(uvc_probe_stream_ctrl(devh, ctrl), uvc_error_t);
566 }
567
568 /** @internal
569  * Negotiate streaming parameters with the device
570  *
571  * @param[in] devh UVC device
572  * @param[in,out] ctrl Control block
573  */
574 uvc_error_t uvc_probe_stream_ctrl(uvc_device_handle_t *devh,
575                 uvc_stream_ctrl_t *ctrl) {
576         uvc_error_t err;
577
578         err = uvc_claim_if(devh, ctrl->bInterfaceNumber);
579         if (UNLIKELY(err)) {
580                 LOGE("uvc_claim_if:err=%d", err);
581                 return err;
582         }
583
584         err = uvc_query_stream_ctrl(devh, ctrl, 1, UVC_SET_CUR);        // probe query
585         if (UNLIKELY(err)) {
586                 LOGE("uvc_query_stream_ctrl(UVC_SET_CUR):err=%d", err);
587                 return err;
588         }
589
590         err = uvc_query_stream_ctrl(devh, ctrl, 1, UVC_GET_CUR);        // probe query ここでエラーが返ってくる
591         if (UNLIKELY(err)) {
592                 LOGE("uvc_query_stream_ctrl(UVC_GET_CUR):err=%d", err);
593                 return err;
594         }
595
596         return UVC_SUCCESS;
597 }
598
599 /** @internal
600  * @brief Swap the working buffer with the presented buffer and notify consumers
601  */
602 static void _uvc_swap_buffers(uvc_stream_handle_t *strmh) {
603         uint8_t *tmp_buf;
604
605         pthread_mutex_lock(&strmh->cb_mutex);
606         {
607                 /* swap the buffers */
608                 tmp_buf = strmh->holdbuf;
609                 strmh->hold_bfh_err = strmh->bfh_err;   // XXX
610                 strmh->hold_bytes = strmh->got_bytes;
611                 strmh->holdbuf = strmh->outbuf;
612                 strmh->outbuf = tmp_buf;
613                 strmh->hold_last_scr = strmh->last_scr;
614                 strmh->hold_pts = strmh->pts;
615                 strmh->hold_seq = strmh->seq;
616
617                 pthread_cond_broadcast(&strmh->cb_cond);
618         }
619         pthread_mutex_unlock(&strmh->cb_mutex);
620
621         strmh->seq++;
622         strmh->got_bytes = 0;
623         strmh->last_scr = 0;
624         strmh->pts = 0;
625         strmh->bfh_err = 0;     // XXX
626 }
627
628 static void _uvc_delete_transfer(struct libusb_transfer *transfer) {
629         ENTER();
630
631 //      MARK("");
632         uvc_stream_handle_t *strmh = transfer->user_data;
633         if (UNLIKELY(!strmh)) EXIT();           // XXX
634         int i;
635
636         pthread_mutex_lock(&strmh->cb_mutex);   // XXX crash while calling uvc_stop_streaming
637         {
638                 // Mark transfer as deleted.
639                 for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
640                         if (strmh->transfers[i] == transfer) {
641                                 libusb_cancel_transfer(strmh->transfers[i]);    // XXX 20141112追加
642                                 UVC_DEBUG("Freeing transfer %d (%p)", i, transfer);
643                                 free(transfer->buffer);
644                                 libusb_free_transfer(transfer);
645                                 strmh->transfers[i] = NULL;
646                                 break;
647                         }
648                 }
649                 if (UNLIKELY(i == LIBUVC_NUM_TRANSFER_BUFS)) {
650                         UVC_DEBUG("transfer %p not found; not freeing!", transfer);
651                 }
652
653                 pthread_cond_broadcast(&strmh->cb_cond);
654         }
655         pthread_mutex_unlock(&strmh->cb_mutex);
656         EXIT();
657 }
658
659 #define USE_EOF
660
661 /** @internal
662  * @brief Process a payload transfer
663  * 
664  * Processes stream, places frames into buffer, signals listeners
665  * (such as user callback thread and any polling thread) on new frame
666  *
667  * @param payload Contents of the payload transfer, either a packet (isochronous) or a full
668  * transfer (bulk mode)
669  * @param payload_len Length of the payload transfer
670  */
671 static void _uvc_process_payload(uvc_stream_handle_t *strmh, const uint8_t *payload, size_t const payload_len) {
672         size_t header_len;
673         uint8_t header_info;
674         size_t data_len;
675         struct libusb_iso_packet_descriptor *pkt;
676         uvc_vc_error_code_control_t vc_error_code;
677         uvc_vs_error_code_control_t vs_error_code;
678
679         // magic numbers for identifying header packets from some iSight cameras
680         static const uint8_t isight_tag[] = {
681                 0x11, 0x22, 0x33, 0x44,
682                 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce
683         };
684
685         // ignore empty payload transfers
686         if (UNLIKELY(!payload || !payload_len || !strmh->outbuf))
687                 return;
688
689         /* Certain iSight cameras have strange behavior: They send header
690          * information in a packet with no image data, and then the following
691          * packets have only image data, with no more headers until the next frame.
692          *
693          * The iSight header: len(1), flags(1 or 2), 0x11223344(4),
694          * 0xdeadbeefdeadface(8), ??(16)
695         */
696
697         if (UNLIKELY(strmh->devh->is_isight &&
698                 ((payload_len < 14) || memcmp(isight_tag, payload + 2, sizeof(isight_tag)) ) &&
699                 ((payload_len < 15) || memcmp(isight_tag, payload + 3, sizeof(isight_tag)) ) )) {
700                 // The payload transfer doesn't have any iSight magic, so it's all image data
701                 header_len = 0;
702                 data_len = payload_len;
703         } else {
704                 header_len = payload[0];
705
706                 if (UNLIKELY(header_len > payload_len)) {
707                         strmh->bfh_err |= UVC_STREAM_ERR;
708                         UVC_DEBUG("bogus packet: actual_len=%zd, header_len=%zd\n", payload_len, header_len);
709                         return;
710                 }
711
712                 if (UNLIKELY(strmh->devh->is_isight))
713                         data_len = 0;
714                 else
715                         data_len = payload_len - header_len;
716         }
717
718         if (UNLIKELY(header_len < 2)) {
719                 header_info = 0;
720         } else {
721                 //  @todo we should be checking the end-of-header bit
722                 size_t variable_offset = 2;
723
724                 header_info = payload[1];
725
726                 if (UNLIKELY(header_info & UVC_STREAM_ERR)) {
727 //                      strmh->bfh_err |= UVC_STREAM_ERR;
728                         UVC_DEBUG("bad packet: error bit set");
729                         libusb_clear_halt(strmh->devh->usb_devh, strmh->stream_if->bEndpointAddress);
730 //                      uvc_vc_get_error_code(strmh->devh, &vc_error_code, UVC_GET_CUR);
731                         uvc_vs_get_error_code(strmh->devh, &vs_error_code, UVC_GET_CUR);
732 //                      return;
733                 }
734
735                 if ((strmh->fid != (header_info & UVC_STREAM_FID)) && strmh->got_bytes) {
736                         /* The frame ID bit was flipped, but we have image data sitting
737                                 around from prior transfers. This means the camera didn't send
738                                 an EOF for the last transfer of the previous frame. */
739                         _uvc_swap_buffers(strmh);
740                 }
741
742                 strmh->fid = header_info & UVC_STREAM_FID;
743
744                 if (header_info & UVC_STREAM_PTS) {
745                         // XXX saki some camera may send broken packet or failed to receive all data
746                         if (LIKELY(variable_offset + 4 <= header_len)) {
747                                 strmh->pts = DW_TO_INT(payload + variable_offset);
748                                 variable_offset += 4;
749                         } else {
750                                 MARK("bogus packet: header info has UVC_STREAM_PTS, but no data");
751                                 strmh->pts = 0;
752                         }
753                 }
754
755                 if (header_info & UVC_STREAM_SCR) {
756                         // @todo read the SOF token counter
757                         // XXX saki some camera may send broken packet or failed to receive all data
758                         if (LIKELY(variable_offset + 4 <= header_len)) {
759                                 strmh->last_scr = DW_TO_INT(payload + variable_offset);
760                                 variable_offset += 4;
761                         } else {
762                                 MARK("bogus packet: header info has UVC_STREAM_SCR, but no data");
763                                 strmh->last_scr = 0;
764                         }
765                 }
766         }
767
768         if (LIKELY(data_len > 0)) {
769                 if (LIKELY(strmh->got_bytes + data_len < strmh->size_buf)) {
770                         memcpy(strmh->outbuf + strmh->got_bytes, payload + header_len, data_len);
771                         strmh->got_bytes += data_len;
772                 } else {
773                         strmh->bfh_err |= UVC_STREAM_ERR;
774                 }
775
776                 if (header_info & UVC_STREAM_EOF/*(1 << 1)*/) {
777                         // The EOF bit is set, so publish the complete frame
778                         _uvc_swap_buffers(strmh);
779                 }
780         }
781 }
782
783 #if 0
784 static inline void _uvc_process_payload_iso(uvc_stream_handle_t *strmh, struct libusb_transfer *transfer) {
785         /* This is an isochronous mode transfer, so each packet has a payload transfer */
786         int packet_id;
787         for (packet_id = 0; packet_id < transfer->num_iso_packets; packet_id++) {
788                 struct libusb_iso_packet_descriptor *pkt = transfer->iso_packet_desc + packet_id;
789
790                 if UNLIKELY(pkt->status) {
791 //                      UVC_DEBUG("bad packet:status=%d,actual_length=%d", pkt->status, pkt->actual_length);
792                         MARK("bad packet:status=%d,actual_length=%d", pkt->status, pkt->actual_length);
793                         continue;
794                 }
795                 if UNLIKELY(!pkt->actual_length) {
796                         MARK("zero packet (transfer):");
797                         continue;
798                 }
799                 // libusb_get_iso_packet_buffer_simple will return NULL
800                 uint8_t *pktbuf = libusb_get_iso_packet_buffer_simple(transfer, packet_id);
801                 _uvc_process_payload(strmh, pktbuf, pkt->actual_length);
802         }
803 }
804 #else
805 static inline void _uvc_process_payload_iso(uvc_stream_handle_t *strmh, struct libusb_transfer *transfer) {
806         /* per packet */
807         uint8_t *pktbuf;
808         uint8_t check_header;
809         size_t header_len;
810         uint8_t header_info;
811         struct libusb_iso_packet_descriptor *pkt;
812
813         /* magic numbers for identifying header packets from some iSight cameras */
814         static const uint8_t isight_tag[] = {
815                 0x11, 0x22, 0x33, 0x44, 0xde, 0xad,
816                 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
817         int packet_id;
818         uvc_vc_error_code_control_t vc_error_code;
819         uvc_vs_error_code_control_t vs_error_code;
820
821         for (packet_id = 0; packet_id < transfer->num_iso_packets; ++packet_id) {
822                 check_header = 1;
823
824                 pkt = transfer->iso_packet_desc + packet_id;
825
826                 if (UNLIKELY(pkt->status != 0)) {
827                         MARK("bad packet:status=%d,actual_length=%d", pkt->status, pkt->actual_length);
828                         strmh->bfh_err |= UVC_STREAM_ERR;
829                         libusb_clear_halt(strmh->devh->usb_devh, strmh->stream_if->bEndpointAddress);
830 //                      uvc_vc_get_error_code(strmh->devh, &vc_error_code, UVC_GET_CUR);
831 //                      uvc_vs_get_error_code(strmh->devh, &vs_error_code, UVC_GET_CUR);
832                         continue;
833                 }
834
835                 if (UNLIKELY(!pkt->actual_length)) {    // why transfered byte is zero...
836 //                      MARK("zero packet (transfer):");
837 //                      strmh->bfh_err |= UVC_STREAM_ERR;       // don't set this flag here
838                         continue;
839                 }
840                 // XXX accessing to pktbuf could lead to crash on the original implementation
841                 // because the substances of pktbuf will be deleted in uvc_stream_stop.
842                 pktbuf = libusb_get_iso_packet_buffer_simple(transfer, packet_id);
843                 if (LIKELY(pktbuf)) {   // XXX add null check because libusb_get_iso_packet_buffer_simple could return null
844 //                      assert(pktbuf < transfer->buffer + transfer->length - 1);       // XXX
845 #ifdef __ANDROID__
846                         // XXX optimaization because this flag never become true on Android devices
847                         if (UNLIKELY(strmh->devh->is_isight))
848 #else
849                         if (strmh->devh->is_isight)
850 #endif
851                         {
852                                 if (pkt->actual_length < 30
853                                         || (memcmp(isight_tag, pktbuf + 2, sizeof(isight_tag))
854                                                 && memcmp(isight_tag, pktbuf + 3, sizeof(isight_tag)))) {
855                                         check_header = 0;
856                                         header_len = 0;
857                                 } else {
858                                         header_len = pktbuf[0];
859                                 }
860                         } else {
861                                 header_len = pktbuf[0]; // Header length field of Stream Header
862                         }
863
864                         if (LIKELY(check_header)) {
865                                 header_info = pktbuf[1];
866                                 if (UNLIKELY(header_info & UVC_STREAM_ERR)) {
867 //                                      strmh->bfh_err |= UVC_STREAM_ERR;
868                                         MARK("bad packet:status=0x%2x", header_info);
869                                         libusb_clear_halt(strmh->devh->usb_devh, strmh->stream_if->bEndpointAddress);
870 //                                      uvc_vc_get_error_code(strmh->devh, &vc_error_code, UVC_GET_CUR);
871                                         uvc_vs_get_error_code(strmh->devh, &vs_error_code, UVC_GET_CUR);
872                                         continue;
873                                 }
874 #ifdef USE_EOF
875                                 if ((strmh->fid != (header_info & UVC_STREAM_FID)) && strmh->got_bytes) {       // got_bytesを取ると殆ど画面更新されない
876                                 /* The frame ID bit was flipped, but we have image data sitting
877                      around from prior transfers. This means the camera didn't send
878                      an EOF for the last transfer of the previous frame or some frames losted. */
879                                         _uvc_swap_buffers(strmh);
880                                 }
881                                 strmh->fid = header_info & UVC_STREAM_FID;
882 #else
883                                 if (strmh->fid != (header_info & UVC_STREAM_FID)) {     // when FID is toggled
884                                         _uvc_swap_buffers(strmh);
885                                         strmh->fid = header_info & UVC_STREAM_FID;
886                                 }
887 #endif
888                                 if (header_info & UVC_STREAM_PTS) {
889                                         // XXX saki some camera may send broken packet or failed to receive all data
890                                         if (LIKELY(header_len >= 6)) {
891                                                 strmh->pts = DW_TO_INT(pktbuf + 2);
892                                         } else {
893                                                 MARK("bogus packet: header info has UVC_STREAM_PTS, but no data");
894                                                 strmh->pts = 0;
895                                         }
896                                 }
897
898                                 if (header_info & UVC_STREAM_SCR) {
899                                         // XXX saki some camera may send broken packet or failed to receive all data
900                                         if (LIKELY(header_len >= 10)) {
901                                                 strmh->last_scr = DW_TO_INT(pktbuf + 6);
902                                         } else {
903                                                 MARK("bogus packet: header info has UVC_STREAM_SCR, but no data");
904                                                 strmh->last_scr = 0;
905                                         }
906                                 }
907
908 #ifdef __ANDROID__      // XXX optimaization because this flag never become true on Android devices
909                                 if (UNLIKELY(strmh->devh->is_isight))
910                                         continue; // don't look for data after an iSight header
911 #else
912                                 if (strmh->devh->is_isight) {
913                                         MARK("is_isight");
914                                         continue; // don't look for data after an iSight header
915                                 }
916 #endif
917                         } // if LIKELY(check_header)
918
919                         if (UNLIKELY(pkt->actual_length < header_len)) {
920                                 /* Bogus packet received */
921                                 strmh->bfh_err |= UVC_STREAM_ERR;
922                                 MARK("bogus packet: actual_len=%d, header_len=%zd", pkt->actual_length, header_len);
923                                 continue;
924                         }
925
926                         // XXX original implementation could lead to trouble because unsigned values
927                         // and there calculated value never become minus.
928                         // therefor changed to "if (pkt->actual_length > header_len)"
929                         // from "if (pkt->actual_length - header_len > 0)"
930                         if (LIKELY(pkt->actual_length > header_len)) {
931                                 const size_t odd_bytes = pkt->actual_length - header_len;
932                                 assert(strmh->got_bytes + odd_bytes < strmh->size_buf);
933                                 assert(strmh->outbuf);
934                                 assert(pktbuf);
935                                 memcpy(strmh->outbuf + strmh->got_bytes, pktbuf + header_len, odd_bytes);
936                                 strmh->got_bytes += odd_bytes;
937                         }
938 #ifdef USE_EOF
939                         if ((pktbuf[1] & UVC_STREAM_EOF) && strmh->got_bytes != 0) {
940                                 /* The EOF bit is set, so publish the complete frame */
941                                 _uvc_swap_buffers(strmh);
942                         }
943 #endif
944                 } else {        // if (LIKELY(pktbuf))
945                         strmh->bfh_err |= UVC_STREAM_ERR;
946                         MARK("libusb_get_iso_packet_buffer_simple returned null");
947                         continue;
948                 }
949         }       // for
950 }
951 #endif
952
953 /** @internal
954  * @brief Isochronous transfer callback
955  * 
956  * Processes stream, places frames into buffer, signals listeners
957  * (such as user callback thread and any polling thread) on new frame
958  *
959  * @param transfer Active transfer
960  */
961 static void _uvc_stream_callback(struct libusb_transfer *transfer) {
962         if UNLIKELY(!transfer) return;
963
964         uvc_stream_handle_t *strmh = transfer->user_data;
965         if UNLIKELY(!strmh) return;
966
967         int resubmit = 1;
968
969 #ifndef NDEBUG
970         static int cnt = 0;
971         if UNLIKELY((++cnt % 1000) == 0)
972                 MARK("cnt=%d", cnt);
973 #endif
974         switch (transfer->status) {
975         case LIBUSB_TRANSFER_COMPLETED:
976                 if (!transfer->num_iso_packets) {
977                         /* This is a bulk mode transfer, so it just has one payload transfer */
978                         _uvc_process_payload(strmh, transfer->buffer, transfer->actual_length);
979                 } else {
980                         /* This is an isochronous mode transfer, so each packet has a payload transfer */
981                         _uvc_process_payload_iso(strmh, transfer);
982                 }
983             break;
984         case LIBUSB_TRANSFER_NO_DEVICE:
985                 strmh->running = 0;     // this needs for unexpected disconnect of cable otherwise hangup
986                 // pass through to following lines
987         case LIBUSB_TRANSFER_CANCELLED:
988         case LIBUSB_TRANSFER_ERROR:
989                 UVC_DEBUG("not retrying transfer, status = %d", transfer->status);
990 //              MARK("not retrying transfer, status = %d", transfer->status);
991 //              _uvc_delete_transfer(transfer);
992                 resubmit = 0;
993                 break;
994         case LIBUSB_TRANSFER_TIMED_OUT:
995         case LIBUSB_TRANSFER_STALL:
996         case LIBUSB_TRANSFER_OVERFLOW:
997                 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
998 //              MARK("retrying transfer, status = %d", transfer->status);
999                 break;
1000         }
1001
1002         if (LIKELY(strmh->running && resubmit)) {
1003                 libusb_submit_transfer(transfer);
1004         } else {
1005                 // XXX delete non-reusing transfer
1006                 // real implementation of deleting transfer moves to _uvc_delete_transfer
1007                 _uvc_delete_transfer(transfer);
1008         }
1009 }
1010
1011 #if 0
1012 /** @internal
1013  * @brief Isochronous transfer callback
1014  * 
1015  * Processes stream, places frames into buffer, signals listeners
1016  * (such as user callback thread and any polling thread) on new frame
1017  *
1018  * @param transfer Active transfer
1019  */
1020 static void _uvc_iso_callback(struct libusb_transfer *transfer) {
1021         uvc_stream_handle_t *strmh;
1022         int packet_id;
1023
1024         /* per packet */
1025         uint8_t *pktbuf;
1026         uint8_t check_header;
1027         size_t header_len;      // XXX unsigned int header_len
1028         uint8_t header_info;
1029         struct libusb_iso_packet_descriptor *pkt;
1030
1031         /* magic numbers for identifying header packets from some iSight cameras */
1032         static const uint8_t isight_tag[] = {
1033                 0x11, 0x22, 0x33, 0x44, 0xde, 0xad,
1034                 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
1035
1036         strmh = transfer->user_data;
1037 #ifndef NDEBUG
1038         static int cnt = 0;
1039         if ((++cnt % 1000) == 0)
1040                 MARK("cnt=%d", cnt);
1041 #endif
1042         switch (transfer->status) {
1043         case LIBUSB_TRANSFER_COMPLETED:
1044                 if (UNLIKELY(!transfer->num_iso_packets))
1045                         MARK("num_iso_packets is zero");
1046                 for (packet_id = 0; packet_id < transfer->num_iso_packets; ++packet_id) {
1047                         check_header = 1;
1048
1049                         pkt = transfer->iso_packet_desc + packet_id;
1050
1051                         if (UNLIKELY(pkt->status != 0)) {
1052                                 MARK("bad packet:status=%d,actual_length=%d", pkt->status, pkt->actual_length);
1053                                 strmh->bfh_err |= UVC_STREAM_ERR;
1054                                 continue;
1055                         }
1056
1057                         if (UNLIKELY(!pkt->actual_length)) {    // why transfered byte is zero...
1058 //                              MARK("zero packet (transfer):");
1059 //                              strmh->bfh_err |= UVC_STREAM_ERR;       // don't set this flag here
1060                                 continue;
1061                         }
1062                         // XXX accessing to pktbuf could lead to crash on the original implementation
1063                         // because the substances of pktbuf will be deleted in uvc_stream_stop.
1064                         pktbuf = libusb_get_iso_packet_buffer_simple(transfer, packet_id);
1065                         if (LIKELY(pktbuf)) {   // XXX add null check because libusb_get_iso_packet_buffer_simple could return null
1066 //                              assert(pktbuf < transfer->buffer + transfer->length - 1);       // XXX
1067 #ifdef __ANDROID__
1068                                 // XXX optimaization because this flag never become true on Android devices
1069                                 if (UNLIKELY(strmh->devh->is_isight))
1070 #else
1071                                 if (strmh->devh->is_isight)
1072 #endif
1073                                 {
1074                                         if (pkt->actual_length < 30
1075                                                 || (memcmp(isight_tag, pktbuf + 2, sizeof(isight_tag))
1076                                                         && memcmp(isight_tag, pktbuf + 3, sizeof(isight_tag)))) {
1077                                                 check_header = 0;
1078                                                 header_len = 0;
1079                                         } else {
1080                                                 header_len = pktbuf[0];
1081                                         }
1082                                 } else {
1083                                         header_len = pktbuf[0]; // Header length field of Stream Header
1084                                 }
1085
1086                                 if (LIKELY(check_header)) {
1087                                         header_info = pktbuf[1];
1088                                         if (UNLIKELY(header_info & UVC_STREAM_ERR)) {
1089                                                 strmh->bfh_err |= UVC_STREAM_ERR;
1090                                                 MARK("bad packet");
1091 //                                              libusb_clear_halt(strmh->devh->usb_devh, strmh->stream_if->bEndpointAddress);
1092                                                 uvc_vc_get_error_code(strmh->devh, &vc_error_code, UVC_GET_CUR);
1093                                                 uvc_vs_get_error_code(strmh->devh, &vs_error_code, UVC_GET_CUR);
1094                                                 continue;
1095                                         }
1096 #ifdef USE_EOF
1097                                         if ((strmh->fid != (header_info & UVC_STREAM_FID)) && strmh->got_bytes) {       // got_bytesを取ると殆ど画面更新されない
1098                                         /* The frame ID bit was flipped, but we have image data sitting
1099                              around from prior transfers. This means the camera didn't send
1100                              an EOF for the last transfer of the previous frame or some frames losted. */
1101                                                 _uvc_swap_buffers(strmh);
1102                                         }
1103                                         strmh->fid = header_info & UVC_STREAM_FID;
1104 #else
1105                                         if (strmh->fid != (header_info & UVC_STREAM_FID)) {     // when FID is toggled
1106                                                 _uvc_swap_buffers(strmh);
1107                                                 strmh->fid = header_info & UVC_STREAM_FID;
1108                                         }
1109 #endif
1110                                         if (header_info & UVC_STREAM_PTS) {
1111                                                 // XXX saki some camera may send broken packet or failed to receive all data
1112                                                 if (LIKELY(header_len >= 6)) {
1113                                                         strmh->pts = DW_TO_INT(pktbuf + 2);
1114                                                 } else {
1115                                                         MARK("bogus packet: header info has UVC_STREAM_PTS, but no data");
1116                                                         strmh->pts = 0;
1117                                                 }
1118                                         }
1119
1120                                         if (header_info & UVC_STREAM_SCR) {
1121                                                 // XXX saki some camera may send broken packet or failed to receive all data
1122                                                 if (LIKELY(header_len >= 10)) {
1123                                                         strmh->last_scr = DW_TO_INT(pktbuf + 6);
1124                                                 } else {
1125                                                         MARK("bogus packet: header info has UVC_STREAM_SCR, but no data");
1126                                                         strmh->last_scr = 0;
1127                                                 }
1128                                         }
1129
1130 #ifdef __ANDROID__      // XXX optimaization because this flag never become true on Android devices
1131                                         if (UNLIKELY(strmh->devh->is_isight))
1132                                                 continue; // don't look for data after an iSight header
1133 #else
1134                                         if (strmh->devh->is_isight) {
1135                                                 MARK("is_isight");
1136                                                 continue; // don't look for data after an iSight header
1137                                         }
1138 #endif
1139                                 } // if LIKELY(check_header)
1140
1141                                 if (UNLIKELY(pkt->actual_length < header_len)) {
1142                                         /* Bogus packet received */
1143                                         strmh->bfh_err |= UVC_STREAM_ERR;
1144                                         MARK("bogus packet: actual_len=%d, header_len=%zd", pkt->actual_length, header_len);
1145                                         continue;
1146                                 }
1147
1148                                 // XXX original implementation could lead to trouble because unsigned values
1149                                 // and there calculated value never become minus.
1150                                 // therefor changed to "if (pkt->actual_length > header_len)"
1151                                 // from "if (pkt->actual_length - header_len > 0)"
1152                                 if (LIKELY(pkt->actual_length > header_len)) {
1153                                         const size_t odd_bytes = pkt->actual_length - header_len;
1154                                         assert(strmh->got_bytes + odd_bytes < strmh->size_buf);
1155                                         assert(strmh->outbuf);
1156                                         assert(pktbuf);
1157                                         memcpy(strmh->outbuf + strmh->got_bytes, pktbuf + header_len, odd_bytes);
1158                                         strmh->got_bytes += odd_bytes;
1159                                 }
1160 #ifdef USE_EOF
1161                                 if ((pktbuf[1] & STREAM_HEADER_BFH_EOF) && strmh->got_bytes != 0) {
1162                                         /* The EOF bit is set, so publish the complete frame */
1163                                         _uvc_swap_buffers(strmh);
1164                                 }
1165 #endif
1166                         } else {        // if (LIKELY(pktbuf))
1167                                 strmh->bfh_err |= UVC_STREAM_ERR;
1168                                 MARK("libusb_get_iso_packet_buffer_simple returned null");
1169                                 continue;
1170                         }
1171                 }       // for
1172                 break;
1173         case LIBUSB_TRANSFER_NO_DEVICE:
1174                 strmh->running = 0;     // this needs for unexpected disconnect of cable otherwise hangup
1175         case LIBUSB_TRANSFER_CANCELLED:
1176         case LIBUSB_TRANSFER_ERROR:
1177                 UVC_DEBUG("not retrying transfer, status = %d", transfer->status);
1178 //              MARK("not retrying transfer, status = %d", transfer->status);
1179                 _uvc_delete_transfer(transfer);
1180                 break;
1181         case LIBUSB_TRANSFER_TIMED_OUT:
1182         case LIBUSB_TRANSFER_STALL:
1183         case LIBUSB_TRANSFER_OVERFLOW:
1184                 UVC_DEBUG("retrying transfer, status = %d", transfer->status);
1185 //              MARK("retrying transfer, status = %d", transfer->status);
1186                 break;
1187         }
1188
1189         if (LIKELY(strmh->running)) {
1190                 libusb_submit_transfer(transfer);
1191         } else {
1192                 // XXX delete non-reusing transfer
1193                 // real implementation of deleting transfer moves to _uvc_delete_transfer
1194                 _uvc_delete_transfer(transfer);
1195         }
1196 }
1197 #endif
1198
1199 /** Begin streaming video from the camera into the callback function.
1200  * @ingroup streaming
1201  *
1202  * @param devh UVC device
1203  * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
1204  *             {uvc_get_stream_ctrl_format_size}
1205  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1206  * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
1207  * is reserved for backward compatibility.
1208  */
1209 uvc_error_t uvc_start_streaming(uvc_device_handle_t *devh,
1210                 uvc_stream_ctrl_t *ctrl, uvc_frame_callback_t *cb, void *user_ptr,
1211                 uint8_t flags) {
1212         return uvc_start_streaming_bandwidth(devh, ctrl, cb, user_ptr, 0, flags);
1213 }
1214
1215 /** Begin streaming video from the camera into the callback function.
1216  * @ingroup streaming
1217  *
1218  * @param devh UVC device
1219  * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
1220  *             {uvc_get_stream_ctrl_format_size}
1221  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1222  * @param bandwidth_factor [0.0f, 1.0f]
1223  * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
1224  * is reserved for backward compatibility.
1225  */
1226 uvc_error_t uvc_start_streaming_bandwidth(uvc_device_handle_t *devh,
1227                 uvc_stream_ctrl_t *ctrl, uvc_frame_callback_t *cb, void *user_ptr,
1228                 float bandwidth_factor,
1229                 uint8_t flags) {
1230         uvc_error_t ret;
1231         uvc_stream_handle_t *strmh;
1232
1233         ret = uvc_stream_open_ctrl(devh, &strmh, ctrl);
1234         if (UNLIKELY(ret != UVC_SUCCESS))
1235                 return ret;
1236
1237         ret = uvc_stream_start_bandwidth(strmh, cb, user_ptr, bandwidth_factor, flags);
1238         if (UNLIKELY(ret != UVC_SUCCESS)) {
1239                 uvc_stream_close(strmh);
1240                 return ret;
1241         }
1242
1243         return UVC_SUCCESS;
1244 }
1245
1246 /** Begin streaming video from the camera into the callback function.
1247  * @ingroup streaming
1248  *
1249  * @deprecated The stream type (bulk vs. isochronous) will be determined by the
1250  * type of interface associated with the uvc_stream_ctrl_t parameter, regardless
1251  * of whether the caller requests isochronous streaming. Please switch to
1252  * uvc_start_streaming().
1253  *
1254  * @param devh UVC device
1255  * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
1256  *             {uvc_get_stream_ctrl_format_size}
1257  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1258  */
1259 uvc_error_t uvc_start_iso_streaming(uvc_device_handle_t *devh,
1260                 uvc_stream_ctrl_t *ctrl, uvc_frame_callback_t *cb, void *user_ptr) {
1261         return uvc_start_streaming_bandwidth(devh, ctrl, cb, user_ptr, 0.0f, 0);
1262 }
1263
1264 static uvc_stream_handle_t *_uvc_get_stream_by_interface(
1265                 uvc_device_handle_t *devh, int interface_idx) {
1266         uvc_stream_handle_t *strmh;
1267
1268         DL_FOREACH(devh->streams, strmh)
1269         {
1270                 if (strmh->stream_if->bInterfaceNumber == interface_idx)
1271                         return strmh;
1272         }
1273
1274         return NULL;
1275 }
1276
1277 static uvc_streaming_interface_t *_uvc_get_stream_if(uvc_device_handle_t *devh,
1278                 int interface_idx) {
1279         uvc_streaming_interface_t *stream_if;
1280
1281         DL_FOREACH(devh->info->stream_ifs, stream_if)
1282         {
1283                 if (stream_if->bInterfaceNumber == interface_idx)
1284                         return stream_if;
1285         }
1286
1287         return NULL;
1288 }
1289
1290 /** Open a new video stream.
1291  * @ingroup streaming
1292  *
1293  * @param devh UVC device
1294  * @param ctrl Control block, processed using {uvc_probe_stream_ctrl} or
1295  *             {uvc_get_stream_ctrl_format_size}
1296  */
1297 uvc_error_t uvc_stream_open_ctrl(uvc_device_handle_t *devh,
1298                 uvc_stream_handle_t **strmhp, uvc_stream_ctrl_t *ctrl) {
1299         /* Chosen frame and format descriptors */
1300         uvc_stream_handle_t *strmh = NULL;
1301         uvc_streaming_interface_t *stream_if;
1302         uvc_error_t ret;
1303
1304         UVC_ENTER();
1305
1306         if (UNLIKELY(_uvc_get_stream_by_interface(devh, ctrl->bInterfaceNumber) != NULL)) {
1307                 ret = UVC_ERROR_BUSY; /* Stream is already opened */
1308                 goto fail;
1309         }
1310
1311         stream_if = _uvc_get_stream_if(devh, ctrl->bInterfaceNumber);
1312         if (UNLIKELY(!stream_if)) {
1313                 ret = UVC_ERROR_INVALID_PARAM;
1314                 goto fail;
1315         }
1316
1317         strmh = calloc(1, sizeof(*strmh));
1318         if (UNLIKELY(!strmh)) {
1319                 ret = UVC_ERROR_NO_MEM;
1320                 goto fail;
1321         }
1322         strmh->devh = devh;
1323         strmh->stream_if = stream_if;
1324         strmh->frame.library_owns_data = 1;
1325
1326         ret = uvc_claim_if(strmh->devh, strmh->stream_if->bInterfaceNumber);
1327         if (UNLIKELY(ret != UVC_SUCCESS))
1328                 goto fail;
1329
1330         ret = uvc_stream_ctrl(strmh, ctrl);
1331         if (UNLIKELY(ret != UVC_SUCCESS))
1332                 goto fail;
1333
1334         // Set up the streaming status and data space
1335         strmh->running = 0;
1336         /** @todo take only what we need */
1337         strmh->outbuf = malloc(LIBUVC_XFER_BUF_SIZE);
1338         strmh->holdbuf = malloc(LIBUVC_XFER_BUF_SIZE);
1339         strmh->size_buf = LIBUVC_XFER_BUF_SIZE; // xxx for boundary check
1340
1341         pthread_mutex_init(&strmh->cb_mutex, NULL);
1342         pthread_cond_init(&strmh->cb_cond, NULL);
1343
1344         DL_APPEND(devh->streams, strmh);
1345
1346         *strmhp = strmh;
1347
1348         UVC_EXIT(0);
1349         return UVC_SUCCESS;
1350
1351 fail:
1352         if (strmh)
1353                 free(strmh);
1354         UVC_EXIT(ret);
1355         return ret;
1356 }
1357
1358 /** Begin streaming video from the stream into the callback function.
1359  * @ingroup streaming
1360  *
1361  * @param strmh UVC stream
1362  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1363  * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
1364  * is reserved for backward compatibility.
1365  */
1366 uvc_error_t uvc_stream_start(uvc_stream_handle_t *strmh,
1367                 uvc_frame_callback_t *cb, void *user_ptr, uint8_t flags) {
1368         return uvc_stream_start_bandwidth(strmh, cb, user_ptr, 0, flags);
1369 }
1370
1371 /** Begin streaming video from the stream into the callback function.
1372  * @ingroup streaming
1373  *
1374  * @param strmh UVC stream
1375  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1376  * @param bandwidth_factor [0.0f, 1.0f]
1377  * @param flags Stream setup flags, currently undefined. Set this to zero. The lower bit
1378  * is reserved for backward compatibility.
1379  */
1380 uvc_error_t uvc_stream_start_bandwidth(uvc_stream_handle_t *strmh,
1381                 uvc_frame_callback_t *cb, void *user_ptr, float bandwidth_factor, uint8_t flags) {
1382         /* USB interface we'll be using */
1383         const struct libusb_interface *interface;
1384         int interface_id;
1385         char isochronous;
1386         uvc_frame_desc_t *frame_desc;
1387         uvc_format_desc_t *format_desc;
1388         uvc_stream_ctrl_t *ctrl;
1389         uvc_error_t ret;
1390         /* Total amount of data per transfer */
1391         size_t total_transfer_size;
1392         struct libusb_transfer *transfer;
1393         int transfer_id;
1394
1395         ctrl = &strmh->cur_ctrl;
1396
1397         UVC_ENTER();
1398
1399         if (UNLIKELY(strmh->running)) {
1400                 UVC_EXIT(UVC_ERROR_BUSY);
1401                 return UVC_ERROR_BUSY;
1402         }
1403
1404         strmh->running = 1;
1405         strmh->seq = 0;
1406         strmh->fid = 0;
1407         strmh->pts = 0;
1408         strmh->last_scr = 0;
1409         strmh->bfh_err = 0;     // XXX
1410
1411         frame_desc = uvc_find_frame_desc_stream(strmh, ctrl->bFormatIndex, ctrl->bFrameIndex);
1412         if (UNLIKELY(!frame_desc)) {
1413                 ret = UVC_ERROR_INVALID_PARAM;
1414                 LOGE("UVC_ERROR_INVALID_PARAM");
1415                 goto fail;
1416         }
1417         format_desc = frame_desc->parent;
1418
1419         strmh->frame_format = uvc_frame_format_for_guid(format_desc->guidFormat);
1420         if (UNLIKELY(strmh->frame_format == UVC_FRAME_FORMAT_UNKNOWN)) {
1421                 ret = UVC_ERROR_NOT_SUPPORTED;
1422                 LOGE("unlnown frame format");
1423                 goto fail;
1424         }
1425         const uint32_t dwMaxVideoFrameSize = ctrl->dwMaxVideoFrameSize <= frame_desc->dwMaxVideoFrameBufferSize
1426                 ? ctrl->dwMaxVideoFrameSize : frame_desc->dwMaxVideoFrameBufferSize;
1427
1428         // Get the interface that provides the chosen format and frame configuration
1429         interface_id = strmh->stream_if->bInterfaceNumber;
1430         interface = &strmh->devh->info->config->interface[interface_id];
1431
1432         /* A VS interface uses isochronous transfers if it has multiple altsettings.
1433          * (UVC 1.5: 2.4.3. VideoStreaming Interface, on page 19) */
1434         isochronous = interface->num_altsetting > 1;
1435
1436         if (isochronous) {
1437                 MARK("isochronous transfer mode:num_altsetting=%d", interface->num_altsetting);
1438                 /* For isochronous streaming, we choose an appropriate altsetting for the endpoint
1439                  * and set up several transfers */
1440                 const struct libusb_interface_descriptor *altsetting;
1441                 const struct libusb_endpoint_descriptor *endpoint;
1442                 /* The greatest number of bytes that the device might provide, per packet, in this
1443                  * configuration */
1444                 size_t config_bytes_per_packet;
1445                 /* Number of packets per transfer */
1446                 size_t packets_per_transfer;
1447                 /* Total amount of data per transfer */
1448                 size_t total_transfer_size;
1449                 /* Size of packet transferable from the chosen endpoint */
1450                 size_t endpoint_bytes_per_packet;
1451                 /* Index of the altsetting */
1452                 int alt_idx, ep_idx;
1453
1454                 struct libusb_transfer *transfer;
1455                 int transfer_id;
1456                 
1457                 if ((bandwidth_factor > 0) && (bandwidth_factor < 1.0f)) {
1458                         config_bytes_per_packet = (size_t)(strmh->cur_ctrl.dwMaxPayloadTransferSize * bandwidth_factor);
1459                         if (!config_bytes_per_packet) {
1460                                 config_bytes_per_packet = strmh->cur_ctrl.dwMaxPayloadTransferSize;
1461                         }
1462                 } else {
1463                         config_bytes_per_packet = strmh->cur_ctrl.dwMaxPayloadTransferSize;
1464                 }
1465 //#if !defined(__LP64__)
1466 //              LOGI("config_bytes_per_packet=%d", config_bytes_per_packet);
1467 //#else
1468 //              LOGI("config_bytes_per_packet=%ld", config_bytes_per_packet);
1469 //#endif
1470                 if (UNLIKELY(!config_bytes_per_packet)) {       // XXX added to privent zero divided exception at the following code
1471                         ret = UVC_ERROR_IO;
1472                         LOGE("config_bytes_per_packet is zero");
1473                         goto fail;
1474                 }
1475
1476                 /* Go through the altsettings and find one whose packets are at least
1477                  * as big as our format's maximum per-packet usage. Assume that the
1478                  * packet sizes are increasing. */
1479                 const int num_alt = interface->num_altsetting - 1;
1480                 for (alt_idx = 0; alt_idx <= num_alt ; alt_idx++) {
1481                         altsetting = interface->altsetting + alt_idx;
1482                         endpoint_bytes_per_packet = 0;
1483
1484                         /* Find the endpoint with the number specified in the VS header */
1485                         for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) {
1486                                 endpoint = altsetting->endpoint + ep_idx;
1487                                 if (endpoint->bEndpointAddress == format_desc->parent->bEndpointAddress) {
1488                                         endpoint_bytes_per_packet = endpoint->wMaxPacketSize;
1489                                         // wMaxPacketSize: [unused:2 (multiplier-1):3 size:11]
1490                                         // bit10…0:           maximum packet size
1491                                         // bit12…11:  the number of additional transaction opportunities per microframe for high-speed
1492                                         //                              00 = None (1 transaction per microframe)
1493                                         //                              01 = 1 additional (2 per microframe)
1494                                         //                              10 = 2 additional (3 per microframe)
1495                                         //                              11 = Reserved
1496                                         endpoint_bytes_per_packet
1497                                                 = (endpoint_bytes_per_packet & 0x07ff)
1498                                                         * (((endpoint_bytes_per_packet >> 11) & 3) + 1);
1499                                         break;
1500                                 }
1501                         }
1502                         // XXX config_bytes_per_packet should not be zero otherwise zero divided exception occur
1503                         if (LIKELY(endpoint_bytes_per_packet)) {
1504                                 if ( (endpoint_bytes_per_packet >= config_bytes_per_packet)
1505                                         || (alt_idx == num_alt) ) {     // XXX always match to last altsetting for buggy device
1506                                         /* Transfers will be at most one frame long: Divide the maximum frame size
1507                                          * by the size of the endpoint and round up */
1508                                         packets_per_transfer = (dwMaxVideoFrameSize
1509                                                         + endpoint_bytes_per_packet - 1)
1510                                                         / endpoint_bytes_per_packet;            // XXX cashed by zero divided exception occured
1511
1512                                         /* But keep a reasonable limit: Otherwise we start dropping data */
1513                                         if (packets_per_transfer > 32)
1514                                                 packets_per_transfer = 32;
1515
1516                                         total_transfer_size = packets_per_transfer * endpoint_bytes_per_packet;
1517                                         break;
1518                                 }
1519                         }
1520                 }
1521                 if (UNLIKELY(!endpoint_bytes_per_packet)) {
1522                         LOGE("endpoint_bytes_per_packet is zero");
1523                         ret = UVC_ERROR_INVALID_MODE;
1524                         goto fail;
1525                 }
1526                 if (UNLIKELY(!total_transfer_size)) {
1527                         LOGE("total_transfer_size is zero");
1528                         ret = UVC_ERROR_INVALID_MODE;
1529                         goto fail;
1530                 }
1531
1532                 /* If we searched through all the altsettings and found nothing usable */
1533 /*              if (UNLIKELY(alt_idx == interface->num_altsetting)) {   // XXX never hit this condition
1534                         UVC_DEBUG("libusb_set_interface_alt_setting failed");
1535                         ret = UVC_ERROR_INVALID_MODE;
1536                         goto fail;
1537                 } */
1538
1539                 /* Select the altsetting */
1540                 MARK("Select the altsetting");
1541                 ret = libusb_set_interface_alt_setting(strmh->devh->usb_devh,
1542                                 altsetting->bInterfaceNumber, altsetting->bAlternateSetting);
1543                 if (UNLIKELY(ret != UVC_SUCCESS)) {
1544                         UVC_DEBUG("libusb_set_interface_alt_setting failed");
1545                         goto fail;
1546                 }
1547
1548                 /* Set up the transfers */
1549                 MARK("Set up the transfers");
1550                 for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS; ++transfer_id) {
1551                         transfer = libusb_alloc_transfer(packets_per_transfer);
1552                         strmh->transfers[transfer_id] = transfer;
1553                         strmh->transfer_bufs[transfer_id] = malloc(total_transfer_size);
1554
1555                         libusb_fill_iso_transfer(transfer, strmh->devh->usb_devh,
1556                                 format_desc->parent->bEndpointAddress,
1557                                 strmh->transfer_bufs[transfer_id], total_transfer_size,
1558                                 packets_per_transfer, _uvc_stream_callback,
1559                                 (void*) strmh, 5000);
1560
1561                         libusb_set_iso_packet_lengths(transfer, endpoint_bytes_per_packet);
1562                 }
1563         } else {
1564                 MARK("bulk transfer mode");
1565                 /** prepare for bulk transfer */
1566                 for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS; ++transfer_id) {
1567                         transfer = libusb_alloc_transfer(0);
1568                         strmh->transfers[transfer_id] = transfer;
1569                         strmh->transfer_bufs[transfer_id] = malloc(strmh->cur_ctrl.dwMaxPayloadTransferSize);
1570                         libusb_fill_bulk_transfer(transfer, strmh->devh->usb_devh,
1571                                 format_desc->parent->bEndpointAddress,
1572                                 strmh->transfer_bufs[transfer_id],
1573                                 strmh->cur_ctrl.dwMaxPayloadTransferSize, _uvc_stream_callback,
1574                                 (void *)strmh, 5000);
1575                 }
1576         }
1577
1578         strmh->user_cb = cb;
1579         strmh->user_ptr = user_ptr;
1580
1581         /* If the user wants it, set up a thread that calls the user's function
1582          * with the contents of each frame.
1583          */
1584         MARK("create callback thread");
1585         if LIKELY(cb) {
1586                 pthread_create(&strmh->cb_thread, NULL, _uvc_user_caller, (void*) strmh);
1587         }
1588         MARK("submit transfers");
1589         for (transfer_id = 0; transfer_id < LIBUVC_NUM_TRANSFER_BUFS; transfer_id++) {
1590                 ret = libusb_submit_transfer(strmh->transfers[transfer_id]);
1591                 if (UNLIKELY(ret != UVC_SUCCESS)) {
1592                         UVC_DEBUG("libusb_submit_transfer failed");
1593                         break;
1594                 }
1595         }
1596
1597         if (UNLIKELY(ret != UVC_SUCCESS)) {
1598                 /** @todo clean up transfers and memory */
1599                 goto fail;
1600         }
1601
1602         UVC_EXIT(ret);
1603         return ret;
1604 fail:
1605         LOGE("fail");
1606         strmh->running = 0;
1607         UVC_EXIT(ret);
1608         return ret;
1609 }
1610
1611 /** Begin streaming video from the stream into the callback function.
1612  * @ingroup streaming
1613  *
1614  * @deprecated The stream type (bulk vs. isochronous) will be determined by the
1615  * type of interface associated with the uvc_stream_ctrl_t parameter, regardless
1616  * of whether the caller requests isochronous streaming. Please switch to
1617  * uvc_stream_start().
1618  *
1619  * @param strmh UVC stream
1620  * @param cb   User callback function. See {uvc_frame_callback_t} for restrictions.
1621  */
1622 uvc_error_t uvc_stream_start_iso(uvc_stream_handle_t *strmh,
1623                 uvc_frame_callback_t *cb, void *user_ptr) {
1624         return uvc_stream_start(strmh, cb, user_ptr, 0);
1625 }
1626
1627 /** @internal
1628  * @brief User callback runner thread
1629  * @note There should be at most one of these per currently streaming device
1630  * @param arg Device handle
1631  */
1632 static void *_uvc_user_caller(void *arg) {
1633         uvc_stream_handle_t *strmh = (uvc_stream_handle_t *) arg;
1634
1635         uint32_t last_seq = 0;
1636
1637         for (; 1 ;) {
1638                 pthread_mutex_lock(&strmh->cb_mutex);
1639                 {
1640                         for (; strmh->running && (last_seq == strmh->hold_seq) ;) {
1641                                 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1642                         }
1643
1644                         if (UNLIKELY(!strmh->running)) {
1645                                 pthread_mutex_unlock(&strmh->cb_mutex);
1646                                 break;
1647                         }
1648
1649                         last_seq = strmh->hold_seq;
1650                         if (LIKELY(!strmh->hold_bfh_err))       // XXX
1651                                 _uvc_populate_frame(strmh);
1652                 }
1653                 pthread_mutex_unlock(&strmh->cb_mutex);
1654
1655                 if (LIKELY(!strmh->hold_bfh_err))       // XXX
1656                         strmh->user_cb(&strmh->frame, strmh->user_ptr); // call user callback function
1657         }
1658
1659         return NULL; // return value ignored
1660 }
1661
1662 /** @internal
1663  * @brief Populate the fields of a frame to be handed to user code
1664  * must be called with stream cb lock held!
1665  */
1666 void _uvc_populate_frame(uvc_stream_handle_t *strmh) {
1667         size_t alloc_size = strmh->cur_ctrl.dwMaxVideoFrameSize;
1668         uvc_frame_t *frame = &strmh->frame;
1669         uvc_frame_desc_t *frame_desc;
1670
1671         /** @todo this stuff that hits the main config cache should really happen
1672          * in start() so that only one thread hits these data. all of this stuff
1673          * is going to be reopen_on_change anyway
1674          */
1675
1676         frame_desc = uvc_find_frame_desc(strmh->devh, strmh->cur_ctrl.bFormatIndex,
1677                         strmh->cur_ctrl.bFrameIndex);
1678
1679         frame->frame_format = strmh->frame_format;
1680
1681         frame->width = frame_desc->wWidth;
1682         frame->height = frame_desc->wHeight;
1683         // XXX set actual_bytes to zero when erro bits is on
1684         frame->actual_bytes = LIKELY(!strmh->hold_bfh_err) ? strmh->hold_bytes : 0;
1685
1686         switch (frame->frame_format) {
1687         case UVC_FRAME_FORMAT_YUYV:
1688                 frame->step = frame->width * 2;
1689                 break;
1690         case UVC_FRAME_FORMAT_MJPEG:
1691                 frame->step = 0;
1692                 break;
1693         default:
1694                 frame->step = 0;
1695                 break;
1696         }
1697
1698         /* copy the image data from the hold buffer to the frame (unnecessary extra buf?) */
1699         if (UNLIKELY(frame->data_bytes < strmh->hold_bytes)) {
1700                 frame->data = realloc(frame->data, strmh->hold_bytes);  // TODO add error handling when failed realloc
1701                 frame->data_bytes = strmh->hold_bytes;
1702         }
1703         memcpy(frame->data, strmh->holdbuf, strmh->hold_bytes/*frame->data_bytes*/);    // XXX
1704
1705         /** @todo set the frame time */
1706 }
1707
1708 /** Poll for a frame
1709  * @ingroup streaming
1710  *
1711  * @param devh UVC device
1712  * @param[out] frame Location to store pointer to captured frame (NULL on error)
1713  * @param timeout_us >0: Wait at most N microseconds; 0: Wait indefinitely; -1: return immediately
1714  */
1715 uvc_error_t uvc_stream_get_frame(uvc_stream_handle_t *strmh,
1716                 uvc_frame_t **frame, int32_t timeout_us) {
1717         time_t add_secs;
1718         time_t add_nsecs;
1719         struct timespec ts;
1720         struct timeval tv;
1721
1722         if (UNLIKELY(!strmh->running))
1723                 return UVC_ERROR_INVALID_PARAM;
1724
1725         if (UNLIKELY(strmh->user_cb))
1726                 return UVC_ERROR_CALLBACK_EXISTS;
1727
1728         pthread_mutex_lock(&strmh->cb_mutex);
1729         {
1730                 if (strmh->last_polled_seq < strmh->hold_seq) {
1731                         _uvc_populate_frame(strmh);
1732                         *frame = &strmh->frame;
1733                         strmh->last_polled_seq = strmh->hold_seq;
1734                 } else if (timeout_us != -1) {
1735                         if (!timeout_us) {
1736                                 pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1737                         } else {
1738                                 add_secs = timeout_us / 1000000;
1739                                 add_nsecs = (timeout_us % 1000000) * 1000;
1740                                 ts.tv_sec = 0;
1741                                 ts.tv_nsec = 0;
1742
1743 #if _POSIX_TIMERS > 0
1744                                 clock_gettime(CLOCK_REALTIME, &ts);
1745 #else
1746                                 gettimeofday(&tv, NULL);
1747                                 ts.tv_sec = tv.tv_sec;
1748                                 ts.tv_nsec = tv.tv_usec * 1000;
1749 #endif
1750
1751                                 ts.tv_sec += add_secs;
1752                                 ts.tv_nsec += add_nsecs;
1753
1754                                 pthread_cond_timedwait(&strmh->cb_cond, &strmh->cb_mutex, &ts);
1755                         }
1756
1757                         if (LIKELY(strmh->last_polled_seq < strmh->hold_seq)) {
1758                                 _uvc_populate_frame(strmh);
1759                                 *frame = &strmh->frame;
1760                                 strmh->last_polled_seq = strmh->hold_seq;
1761                         } else {
1762                                 *frame = NULL;
1763                         }
1764                 } else {
1765                         *frame = NULL;
1766                 }
1767         }
1768         pthread_mutex_unlock(&strmh->cb_mutex);
1769
1770         return UVC_SUCCESS;
1771 }
1772
1773 /** @brief Stop streaming video
1774  * @ingroup streaming
1775  *
1776  * Closes all streams, ends threads and cancels pollers
1777  *
1778  * @param devh UVC device
1779  */
1780 void uvc_stop_streaming(uvc_device_handle_t *devh) {
1781         uvc_stream_handle_t *strmh, *strmh_tmp;
1782
1783         UVC_ENTER();
1784         DL_FOREACH_SAFE(devh->streams, strmh, strmh_tmp)
1785         {
1786                 uvc_stream_close(strmh);
1787         }
1788         UVC_EXIT_VOID();
1789 }
1790
1791 /** @brief Stop stream.
1792  * @ingroup streaming
1793  *
1794  * Stops stream, ends threads and cancels pollers
1795  *
1796  * @param devh UVC device
1797  */
1798 uvc_error_t uvc_stream_stop(uvc_stream_handle_t *strmh) {
1799
1800         int i;
1801         ENTER();
1802
1803         if (!strmh) RETURN(UVC_SUCCESS, uvc_error_t);
1804
1805         if (UNLIKELY(!strmh->running)) {
1806                 UVC_EXIT(UVC_ERROR_INVALID_PARAM);
1807                 RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
1808         }
1809
1810         strmh->running = 0;
1811
1812         pthread_mutex_lock(&strmh->cb_mutex);
1813         {
1814                 for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
1815                         if (strmh->transfers[i]) {
1816                                 int res = libusb_cancel_transfer(strmh->transfers[i]);
1817                                 if ((res < 0) && (res != LIBUSB_ERROR_NOT_FOUND)) {
1818                                         UVC_DEBUG("libusb_cancel_transfer failed");
1819                                         // XXX originally freed buffers and transfer here
1820                                         // but this could lead to crash in _uvc_callback
1821                                         // therefore we comment out these lines
1822                                         // and free these objects in _uvc_iso_callback when strmh->running is false
1823 /*                                      free(strmh->transfers[i]->buffer);
1824                                         libusb_free_transfer(strmh->transfers[i]);
1825                                         strmh->transfers[i] = NULL; */
1826                                 }
1827                         }
1828                 }
1829
1830                 /* Wait for transfers to complete/cancel */
1831                 for (; 1 ;) {
1832                         for (i = 0; i < LIBUVC_NUM_TRANSFER_BUFS; i++) {
1833                                 if (strmh->transfers[i] != NULL)
1834                                         break;
1835                         }
1836                         if (i == LIBUVC_NUM_TRANSFER_BUFS)
1837                                 break;
1838                         pthread_cond_wait(&strmh->cb_cond, &strmh->cb_mutex);
1839                 }
1840                 // Kick the user thread awake
1841                 pthread_cond_broadcast(&strmh->cb_cond);
1842         }
1843         pthread_mutex_unlock(&strmh->cb_mutex);
1844
1845         /** @todo stop the actual stream, camera side? */
1846
1847         if (strmh->user_cb) {
1848                 /* wait for the thread to stop (triggered by LIBUSB_TRANSFER_CANCELLED transfer) */
1849                 pthread_join(strmh->cb_thread, NULL);
1850         }
1851
1852         RETURN(UVC_SUCCESS, uvc_error_t);
1853 }
1854
1855 /** @brief Close stream.
1856  * @ingroup streaming
1857  *
1858  * Closes stream, frees handle and all streaming resources.
1859  *
1860  * @param strmh UVC stream handle
1861  */
1862 void uvc_stream_close(uvc_stream_handle_t *strmh) {
1863         UVC_ENTER();
1864
1865         if (!strmh) { UVC_EXIT_VOID(); };
1866
1867         if (strmh->running)
1868                 uvc_stream_stop(strmh);
1869
1870         uvc_release_if(strmh->devh, strmh->stream_if->bInterfaceNumber);
1871
1872         if (strmh->frame.data) {
1873                 free(strmh->frame.data);
1874                 strmh->frame.data = NULL;
1875         }
1876
1877         if (strmh->outbuf) {
1878                 free(strmh->outbuf);
1879                 strmh->outbuf = NULL;
1880         }
1881         if (strmh->holdbuf) {
1882                 free(strmh->holdbuf);
1883                 strmh->holdbuf = NULL;
1884         }
1885
1886         pthread_cond_destroy(&strmh->cb_cond);
1887         pthread_mutex_destroy(&strmh->cb_mutex);
1888
1889         DL_DELETE(strmh->devh->streams, strmh);
1890         free(strmh);
1891
1892         UVC_EXIT_VOID();
1893 }