fa177318bc5254892038b3e747d9104353aa19b7
[rtmpclient.git] / app / src / main / jni / libuvc-0.0.6 / src / diag.c
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 diag Diagnostics
36  * @brief Interpretation of devices, error codes and negotiated stream parameters
37  */
38
39 #include "libuvc/libuvc.h"
40 #include "libuvc/libuvc_internal.h"
41
42 /** @internal */
43 typedef struct _uvc_error_msg {
44   uvc_error_t err;
45   const char *msg;
46 } _uvc_error_msg_t;
47
48 static const _uvc_error_msg_t uvc_error_msgs[] = {
49   {UVC_SUCCESS, "Success"},
50   {UVC_ERROR_IO, "I/O error"},
51   {UVC_ERROR_INVALID_PARAM, "Invalid parameter"},
52   {UVC_ERROR_ACCESS, "Access denied"},
53   {UVC_ERROR_NO_DEVICE, "No such device"},
54   {UVC_ERROR_NOT_FOUND, "Not found"},
55   {UVC_ERROR_BUSY, "Busy"},
56   {UVC_ERROR_TIMEOUT, "Timeout"},
57   {UVC_ERROR_OVERFLOW, "Overflow"},
58   {UVC_ERROR_PIPE, "Pipe"},
59   {UVC_ERROR_INTERRUPTED, "Interrupted"},
60   {UVC_ERROR_NO_MEM, "Out of memory"},
61   {UVC_ERROR_NOT_SUPPORTED, "Not supported"},
62   {UVC_ERROR_INVALID_DEVICE, "Invalid device"},
63   {UVC_ERROR_INVALID_MODE, "Invalid mode"},
64   {UVC_ERROR_CALLBACK_EXISTS, "Callback exists"}
65 };
66
67 /** @brief Print a message explaining an error in the UVC driver
68  * @ingroup diag
69  *
70  * @param err UVC error code
71  * @param msg Optional custom message, prepended to output
72  */
73 void uvc_perror(uvc_error_t err, const char *msg) {
74   if (msg && *msg) {
75     fputs(msg, stderr);
76     fputs(": ", stderr);
77   }
78
79   fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
80 }
81
82 /** @brief Return a string explaining an error in the UVC driver
83  * @ingroup diag
84  *
85  * @param err UVC error code
86  * @return error message
87  */
88 const char* uvc_strerror(uvc_error_t err) {
89   size_t idx;
90
91   for (idx = 0; idx < sizeof(uvc_error_msgs) / sizeof(*uvc_error_msgs); ++idx) {
92     if (uvc_error_msgs[idx].err == err) {
93       return uvc_error_msgs[idx].msg;
94     }
95   }
96
97   return "Unknown error";
98 }
99
100 /** @brief Print the values in a stream control block
101  * @ingroup diag
102  *
103  * @param devh UVC device
104  * @param stream Output stream (stderr if NULL)
105  */
106 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
107   if (stream == NULL)
108     stream = stderr;
109
110   fprintf(stream, "bmHint: %04x\n", ctrl->bmHint);
111   fprintf(stream, "bFormatIndex: %d\n", ctrl->bFormatIndex);
112   fprintf(stream, "bFrameIndex: %d\n", ctrl->bFrameIndex);
113   fprintf(stream, "dwFrameInterval: %u\n", ctrl->dwFrameInterval);
114   fprintf(stream, "wKeyFrameRate: %d\n", ctrl->wKeyFrameRate);
115   fprintf(stream, "wPFrameRate: %d\n", ctrl->wPFrameRate);
116   fprintf(stream, "wCompQuality: %d\n", ctrl->wCompQuality);
117   fprintf(stream, "wCompWindowSize: %d\n", ctrl->wCompWindowSize);
118   fprintf(stream, "wDelay: %d\n", ctrl->wDelay);
119   fprintf(stream, "dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize);
120   fprintf(stream, "dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize);
121   fprintf(stream, "bInterfaceNumber: %d\n", ctrl->bInterfaceNumber);
122 }
123
124 static const char *_uvc_name_for_format_subtype(uint8_t subtype) {
125   switch (subtype) {
126   case UVC_VS_FORMAT_UNCOMPRESSED:
127     return "UncompressedFormat";
128   case UVC_VS_FORMAT_MJPEG:
129     return "MJPEGFormat";
130   case UVC_VS_FORMAT_FRAME_BASED:
131     return "FrameFormat";
132   default:
133     return "Unknown";
134   }
135 }
136
137 /** @brief Print camera capabilities and configuration.
138  * @ingroup diag
139  *
140  * @param devh UVC device
141  * @param stream Output stream (stderr if NULL)
142  */
143 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
144   if (stream == NULL)
145     stream = stderr;
146
147   if (devh->info->ctrl_if.bcdUVC) {
148     uvc_streaming_interface_t *stream_if;
149     int stream_idx = 0;
150
151     uvc_device_descriptor_t *desc;
152     uvc_get_device_descriptor(devh->dev, &desc);
153
154     fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
155         desc->idVendor, desc->idProduct,
156         desc->serialNumber ? desc->serialNumber : "[none]");
157
158     uvc_free_device_descriptor(desc);
159
160     fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
161
162     fprintf(stream, "VideoControl:\n"
163         "\tbcdUVC: 0x%04x\n",
164         devh->info->ctrl_if.bcdUVC);
165
166     DL_FOREACH(devh->info->stream_ifs, stream_if) {
167       uvc_format_desc_t *fmt_desc;
168
169       ++stream_idx;
170
171       fprintf(stream, "VideoStreaming(%d):\n"
172           "\tbEndpointAddress: %d\n\tFormats:\n",
173           stream_idx, stream_if->bEndpointAddress);
174
175       DL_FOREACH(stream_if->format_descs, fmt_desc) {
176         uvc_frame_desc_t *frame_desc;
177         int i;
178
179         switch (fmt_desc->bDescriptorSubtype) {
180           case UVC_VS_FORMAT_UNCOMPRESSED:
181           case UVC_VS_FORMAT_MJPEG:
182           case UVC_VS_FORMAT_FRAME_BASED:
183             fprintf(stream,
184                 "\t\%s(%d)\n"
185                 "\t\t  bits per pixel: %d\n"
186                 "\t\t  GUID: ",
187                 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
188                 fmt_desc->bFormatIndex,
189                 fmt_desc->bBitsPerPixel);
190
191             for (i = 0; i < 16; ++i)
192               fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
193
194             fprintf(stream, " (%4s)\n", fmt_desc->fourccFormat );
195
196             fprintf(stream,
197                 "\t\t  default frame: %d\n"
198                 "\t\t  aspect ratio: %dx%d\n"
199                 "\t\t  interlace flags: %02x\n"
200                 "\t\t  copy protect: %02x\n",
201                 fmt_desc->bDefaultFrameIndex,
202                 fmt_desc->bAspectRatioX,
203                 fmt_desc->bAspectRatioY,
204                 fmt_desc->bmInterlaceFlags,
205                 fmt_desc->bCopyProtect);
206
207             DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
208               uint32_t *interval_ptr;
209
210               fprintf(stream,
211                   "\t\t\tFrameDescriptor(%d)\n"
212                   "\t\t\t  capabilities: %02x\n"
213                   "\t\t\t  size: %dx%d\n"
214                   "\t\t\t  bit rate: %d-%d\n"
215                   "\t\t\t  max frame size: %d\n"
216                   "\t\t\t  default interval: 1/%d\n",
217                   frame_desc->bFrameIndex,
218                   frame_desc->bmCapabilities,
219                   frame_desc->wWidth,
220                   frame_desc->wHeight,
221                   frame_desc->dwMinBitRate,
222                   frame_desc->dwMaxBitRate,
223                   frame_desc->dwMaxVideoFrameBufferSize,
224                   10000000 / frame_desc->dwDefaultFrameInterval);
225               if (frame_desc->intervals) {
226                 for (interval_ptr = frame_desc->intervals;
227                      *interval_ptr;
228                      ++interval_ptr) {
229                   fprintf(stream,
230                       "\t\t\t  interval[%d]: 1/%d\n",
231                       (int) (interval_ptr - frame_desc->intervals),
232                       10000000 / *interval_ptr);
233                 }
234               } else {
235                 fprintf(stream,
236                     "\t\t\t  min interval[%d] = 1/%d\n"
237                     "\t\t\t  max interval[%d] = 1/%d\n",
238                     frame_desc->dwMinFrameInterval,
239                     10000000 / frame_desc->dwMinFrameInterval,
240                     frame_desc->dwMaxFrameInterval,
241                     10000000 / frame_desc->dwMaxFrameInterval);
242                 if (frame_desc->dwFrameIntervalStep)
243                   fprintf(stream,
244                       "\t\t\t  interval step[%d] = 1/%d\n",
245                       frame_desc->dwFrameIntervalStep,
246                       10000000 / frame_desc->dwFrameIntervalStep);
247               }
248             }
249             break;
250           default:
251             fprintf(stream, "\t-UnknownFormat (%d)\n",
252                 fmt_desc->bDescriptorSubtype );
253         }
254       }
255     }
256
257     fprintf(stream, "END DEVICE CONFIGURATION\n");
258   } else {
259     fprintf(stream, "uvc_print_diag: Device not configured!\n");
260   }
261 }
262
263 /** @brief Print all possible frame configuration.
264  * @ingroup diag
265  *
266  * @param devh UVC device
267  * @param stream Output stream (stderr if NULL)
268  */
269 void uvc_print_frameformats(uvc_device_handle_t *devh) {
270
271   if (devh->info->ctrl_if.bcdUVC) {
272     uvc_streaming_interface_t *stream_if;
273     int stream_idx = 0;
274     DL_FOREACH(devh->info->stream_ifs, stream_if) {
275       uvc_format_desc_t *fmt_desc;
276       ++stream_idx;
277
278       DL_FOREACH(stream_if->format_descs, fmt_desc) {
279         uvc_frame_desc_t *frame_desc;
280         int i;
281
282         switch (fmt_desc->bDescriptorSubtype) {
283           case UVC_VS_FORMAT_UNCOMPRESSED:
284           case UVC_VS_FORMAT_MJPEG:
285           case UVC_VS_FORMAT_FRAME_BASED:
286             printf("         \%s(%d)\n"
287                 "            bits per pixel: %d\n"
288                 "            GUID: ",
289                 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
290                 fmt_desc->bFormatIndex,
291                 fmt_desc->bBitsPerPixel);
292
293             for (i = 0; i < 16; ++i)
294               printf("%02x", fmt_desc->guidFormat[i]);
295
296             printf(" (%4s)\n", fmt_desc->fourccFormat );
297
298             printf("            default frame: %d\n"
299                 "            aspect ratio: %dx%d\n"
300                 "            interlace flags: %02x\n"
301                 "            copy protect: %02x\n",
302                 fmt_desc->bDefaultFrameIndex,
303                 fmt_desc->bAspectRatioX,
304                 fmt_desc->bAspectRatioY,
305                 fmt_desc->bmInterlaceFlags,
306                 fmt_desc->bCopyProtect);
307
308             DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
309               uint32_t *interval_ptr;
310
311               printf("               FrameDescriptor(%d)\n"
312                   "                  capabilities: %02x\n"
313                   "                  size: %dx%d\n"
314                   "                  bit rate: %d-%d\n"
315                   "                  max frame size: %d\n"
316                   "                  default interval: 1/%d\n",
317                   frame_desc->bFrameIndex,
318                   frame_desc->bmCapabilities,
319                   frame_desc->wWidth,
320                   frame_desc->wHeight,
321                   frame_desc->dwMinBitRate,
322                   frame_desc->dwMaxBitRate,
323                   frame_desc->dwMaxVideoFrameBufferSize,
324                   10000000 / frame_desc->dwDefaultFrameInterval);
325               if (frame_desc->intervals) {
326                 for (interval_ptr = frame_desc->intervals;
327                      *interval_ptr;
328                      ++interval_ptr) {
329                   printf("                  interval[%d]: 1/%d\n",
330                       (int) (interval_ptr - frame_desc->intervals),
331                       10000000 / *interval_ptr);
332                 }
333               } else {
334                 printf("                  min interval[%d] = 1/%d\n"
335                     "                  max interval[%d] = 1/%d\n",
336                     frame_desc->dwMinFrameInterval,
337                     10000000 / frame_desc->dwMinFrameInterval,
338                     frame_desc->dwMaxFrameInterval,
339                     10000000 / frame_desc->dwMaxFrameInterval);
340                 if (frame_desc->dwFrameIntervalStep)
341                   printf("                  interval step[%d] = 1/%d\n",
342                       frame_desc->dwFrameIntervalStep,
343                       10000000 / frame_desc->dwFrameIntervalStep);
344               }
345             }
346             break;
347           default:
348             printf("\t-UnknownFormat (%d)\n",fmt_desc->bDescriptorSubtype );
349         }
350       }
351     }
352   } else {
353     printf("uvc_print_frameformats: Device not configured!\n");
354   }
355 }