1 /*********************************************************************
2 * Software License Agreement (BSD License)
4 * Copyright (C) 2010-2012 Ken Tossell
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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 *********************************************************************/
35 * @defgroup diag Diagnostics
36 * @brief Interpretation of devices, error codes and negotiated stream parameters
39 #include "libuvc/libuvc.h"
40 #include "libuvc/libuvc_internal.h"
43 typedef struct _uvc_error_msg {
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"}
67 /** @brief Print a message explaining an error in the UVC driver
70 * @param err UVC error code
71 * @param msg Optional custom message, prepended to output
73 void uvc_perror(uvc_error_t err, const char *msg) {
80 __android_log_print(ANDROID_LOG_ERROR, "UVC", "%s (%d)\n", uvc_strerror(err), err);
82 fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
86 /** @brief Return a string explaining an error in the UVC driver
89 * @param err UVC error code
90 * @return error message
92 const char* uvc_strerror(uvc_error_t err) {
95 for (idx = 0; idx < sizeof(uvc_error_msgs) / sizeof(*uvc_error_msgs); ++idx) {
96 if (uvc_error_msgs[idx].err == err) {
97 return uvc_error_msgs[idx].msg;
101 return "Unknown error";
104 /** @brief Print the values in a stream control block
107 * @param devh UVC device
108 * @param stream Output stream (stderr if NULL)
110 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
114 fprintf(stream, "bmHint: %04x\n", ctrl->bmHint);
115 fprintf(stream, "bFormatIndex: %d\n", ctrl->bFormatIndex);
116 fprintf(stream, "bFrameIndex: %d\n", ctrl->bFrameIndex);
117 fprintf(stream, "dwFrameInterval: %u\n", ctrl->dwFrameInterval);
118 fprintf(stream, "wKeyFrameRate: %d\n", ctrl->wKeyFrameRate);
119 fprintf(stream, "wPFrameRate: %d\n", ctrl->wPFrameRate);
120 fprintf(stream, "wCompQuality: %d\n", ctrl->wCompQuality);
121 fprintf(stream, "wCompWindowSize: %d\n", ctrl->wCompWindowSize);
122 fprintf(stream, "wDelay: %d\n", ctrl->wDelay);
123 fprintf(stream, "dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize);
124 fprintf(stream, "dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize);
125 fprintf(stream, "bInterfaceNumber: %d\n", ctrl->bInterfaceNumber);
128 static const char *_uvc_name_for_format_subtype(uint8_t subtype) {
130 case UVC_VS_FORMAT_UNCOMPRESSED:
131 return "UncompressedFormat";
132 case UVC_VS_FORMAT_MJPEG:
133 return "MJPEGFormat";
134 case UVC_VS_FORMAT_FRAME_BASED:
135 return "FrameFormat";
141 /** @brief Print camera capabilities and configuration.
144 * @param devh UVC device
145 * @param stream Output stream (stderr if NULL)
147 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
151 if (devh->info->ctrl_if.bcdUVC) {
152 uvc_streaming_interface_t *stream_if;
155 uvc_device_descriptor_t *desc;
156 uvc_get_device_descriptor(devh->dev, &desc);
158 fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
159 desc->idVendor, desc->idProduct,
160 desc->serialNumber ? desc->serialNumber : "[none]");
162 uvc_free_device_descriptor(desc);
164 fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
166 fprintf(stream, "VideoControl:\n"
167 "\tbcdUVC: 0x%04x\n",
168 devh->info->ctrl_if.bcdUVC);
170 DL_FOREACH(devh->info->stream_ifs, stream_if) {
171 uvc_format_desc_t *fmt_desc;
175 fprintf(stream, "VideoStreaming(%d):\n"
176 "\tbEndpointAddress: %d\n\tFormats:\n",
177 stream_idx, stream_if->bEndpointAddress);
179 DL_FOREACH(stream_if->format_descs, fmt_desc) {
180 uvc_frame_desc_t *frame_desc;
183 switch (fmt_desc->bDescriptorSubtype) {
184 case UVC_VS_FORMAT_UNCOMPRESSED:
185 case UVC_VS_FORMAT_MJPEG:
186 case UVC_VS_FORMAT_FRAME_BASED:
189 "\t\t bits per pixel: %d\n"
191 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
192 fmt_desc->bFormatIndex,
193 fmt_desc->bBitsPerPixel);
195 for (i = 0; i < 16; ++i)
196 fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
198 fprintf(stream, " (%4s)\n", fmt_desc->fourccFormat );
201 "\t\t default frame: %d\n"
202 "\t\t aspect ratio: %dx%d\n"
203 "\t\t interlace flags: %02x\n"
204 "\t\t copy protect: %02x\n",
205 fmt_desc->bDefaultFrameIndex,
206 fmt_desc->bAspectRatioX,
207 fmt_desc->bAspectRatioY,
208 fmt_desc->bmInterlaceFlags,
209 fmt_desc->bCopyProtect);
211 DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
212 uint32_t *interval_ptr;
215 "\t\t\tFrameDescriptor(%d)\n"
216 "\t\t\t capabilities: %02x\n"
217 "\t\t\t size: %dx%d\n"
218 "\t\t\t bit rate: %d-%d\n"
219 "\t\t\t max frame size: %d\n"
220 "\t\t\t default interval: 1/%d\n",
221 frame_desc->bFrameIndex,
222 frame_desc->bmCapabilities,
225 frame_desc->dwMinBitRate,
226 frame_desc->dwMaxBitRate,
227 frame_desc->dwMaxVideoFrameBufferSize,
228 10000000 / frame_desc->dwDefaultFrameInterval);
229 if (frame_desc->intervals) {
230 for (interval_ptr = frame_desc->intervals;
234 "\t\t\t interval[%d]: 1/%d\n",
235 (int) (interval_ptr - frame_desc->intervals),
236 10000000 / *interval_ptr);
240 "\t\t\t min interval[%d] = 1/%d\n"
241 "\t\t\t max interval[%d] = 1/%d\n",
242 frame_desc->dwMinFrameInterval,
243 10000000 / frame_desc->dwMinFrameInterval,
244 frame_desc->dwMaxFrameInterval,
245 10000000 / frame_desc->dwMaxFrameInterval);
246 if (frame_desc->dwFrameIntervalStep)
248 "\t\t\t interval step[%d] = 1/%d\n",
249 frame_desc->dwFrameIntervalStep,
250 10000000 / frame_desc->dwFrameIntervalStep);
255 fprintf(stream, "\t-UnknownFormat (%d)\n",
256 fmt_desc->bDescriptorSubtype );
261 fprintf(stream, "END DEVICE CONFIGURATION\n");
263 fprintf(stream, "uvc_print_diag: Device not configured!\n");
267 /** @brief Print all possible frame configuration.
270 * @param devh UVC device
271 * @param stream Output stream (stderr if NULL)
273 void uvc_print_frameformats(uvc_device_handle_t *devh) {
275 if (devh->info->ctrl_if.bcdUVC) {
276 uvc_streaming_interface_t *stream_if;
278 DL_FOREACH(devh->info->stream_ifs, stream_if) {
279 uvc_format_desc_t *fmt_desc;
282 DL_FOREACH(stream_if->format_descs, fmt_desc) {
283 uvc_frame_desc_t *frame_desc;
286 switch (fmt_desc->bDescriptorSubtype) {
287 case UVC_VS_FORMAT_UNCOMPRESSED:
288 case UVC_VS_FORMAT_MJPEG:
289 case UVC_VS_FORMAT_FRAME_BASED:
291 " bits per pixel: %d\n"
293 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
294 fmt_desc->bFormatIndex,
295 fmt_desc->bBitsPerPixel);
297 for (i = 0; i < 16; ++i)
298 printf("%02x", fmt_desc->guidFormat[i]);
300 printf(" (%4s)\n", fmt_desc->fourccFormat );
302 printf(" default frame: %d\n"
303 " aspect ratio: %dx%d\n"
304 " interlace flags: %02x\n"
305 " copy protect: %02x\n",
306 fmt_desc->bDefaultFrameIndex,
307 fmt_desc->bAspectRatioX,
308 fmt_desc->bAspectRatioY,
309 fmt_desc->bmInterlaceFlags,
310 fmt_desc->bCopyProtect);
312 DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
313 uint32_t *interval_ptr;
315 printf(" FrameDescriptor(%d)\n"
316 " capabilities: %02x\n"
319 " max frame size: %d\n"
320 " default interval: 1/%d\n",
321 frame_desc->bFrameIndex,
322 frame_desc->bmCapabilities,
325 frame_desc->dwMinBitRate,
326 frame_desc->dwMaxBitRate,
327 frame_desc->dwMaxVideoFrameBufferSize,
328 10000000 / frame_desc->dwDefaultFrameInterval);
329 if (frame_desc->intervals) {
330 for (interval_ptr = frame_desc->intervals;
333 printf(" interval[%d]: 1/%d\n",
334 (int) (interval_ptr - frame_desc->intervals),
335 10000000 / *interval_ptr);
338 printf(" min interval[%d] = 1/%d\n"
339 " max interval[%d] = 1/%d\n",
340 frame_desc->dwMinFrameInterval,
341 10000000 / frame_desc->dwMinFrameInterval,
342 frame_desc->dwMaxFrameInterval,
343 10000000 / frame_desc->dwMaxFrameInterval);
344 if (frame_desc->dwFrameIntervalStep)
345 printf(" interval step[%d] = 1/%d\n",
346 frame_desc->dwFrameIntervalStep,
347 10000000 / frame_desc->dwFrameIntervalStep);
352 printf("\t-UnknownFormat (%d)\n",fmt_desc->bDescriptorSubtype );
357 printf("uvc_print_frameformats: Device not configured!\n");