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) {
79 fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
82 /** @brief Return a string explaining an error in the UVC driver
85 * @param err UVC error code
86 * @return error message
88 const char* uvc_strerror(uvc_error_t err) {
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;
97 return "Unknown error";
100 /** @brief Print the values in a stream control block
103 * @param devh UVC device
104 * @param stream Output stream (stderr if NULL)
106 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
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);
124 static const char *_uvc_name_for_format_subtype(uint8_t 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";
137 /** @brief Print camera capabilities and configuration.
140 * @param devh UVC device
141 * @param stream Output stream (stderr if NULL)
143 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
147 if (devh->info->ctrl_if.bcdUVC) {
148 uvc_streaming_interface_t *stream_if;
151 uvc_device_descriptor_t *desc;
152 uvc_get_device_descriptor(devh->dev, &desc);
154 fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
155 desc->idVendor, desc->idProduct,
156 desc->serialNumber ? desc->serialNumber : "[none]");
158 uvc_free_device_descriptor(desc);
160 fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
162 fprintf(stream, "VideoControl:\n"
163 "\tbcdUVC: 0x%04x\n",
164 devh->info->ctrl_if.bcdUVC);
166 DL_FOREACH(devh->info->stream_ifs, stream_if) {
167 uvc_format_desc_t *fmt_desc;
171 fprintf(stream, "VideoStreaming(%d):\n"
172 "\tbEndpointAddress: %d\n\tFormats:\n",
173 stream_idx, stream_if->bEndpointAddress);
175 DL_FOREACH(stream_if->format_descs, fmt_desc) {
176 uvc_frame_desc_t *frame_desc;
179 switch (fmt_desc->bDescriptorSubtype) {
180 case UVC_VS_FORMAT_UNCOMPRESSED:
181 case UVC_VS_FORMAT_MJPEG:
182 case UVC_VS_FORMAT_FRAME_BASED:
185 "\t\t bits per pixel: %d\n"
187 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
188 fmt_desc->bFormatIndex,
189 fmt_desc->bBitsPerPixel);
191 for (i = 0; i < 16; ++i)
192 fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
194 fprintf(stream, " (%4s)\n", fmt_desc->fourccFormat );
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);
207 DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
208 uint32_t *interval_ptr;
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,
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;
230 "\t\t\t interval[%d]: 1/%d\n",
231 (int) (interval_ptr - frame_desc->intervals),
232 10000000 / *interval_ptr);
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)
244 "\t\t\t interval step[%d] = 1/%d\n",
245 frame_desc->dwFrameIntervalStep,
246 10000000 / frame_desc->dwFrameIntervalStep);
251 fprintf(stream, "\t-UnknownFormat (%d)\n",
252 fmt_desc->bDescriptorSubtype );
257 fprintf(stream, "END DEVICE CONFIGURATION\n");
259 fprintf(stream, "uvc_print_diag: Device not configured!\n");
263 /** @brief Print all possible frame configuration.
266 * @param devh UVC device
267 * @param stream Output stream (stderr if NULL)
269 void uvc_print_frameformats(uvc_device_handle_t *devh) {
271 if (devh->info->ctrl_if.bcdUVC) {
272 uvc_streaming_interface_t *stream_if;
274 DL_FOREACH(devh->info->stream_ifs, stream_if) {
275 uvc_format_desc_t *fmt_desc;
278 DL_FOREACH(stream_if->format_descs, fmt_desc) {
279 uvc_frame_desc_t *frame_desc;
282 switch (fmt_desc->bDescriptorSubtype) {
283 case UVC_VS_FORMAT_UNCOMPRESSED:
284 case UVC_VS_FORMAT_MJPEG:
285 case UVC_VS_FORMAT_FRAME_BASED:
287 " bits per pixel: %d\n"
289 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
290 fmt_desc->bFormatIndex,
291 fmt_desc->bBitsPerPixel);
293 for (i = 0; i < 16; ++i)
294 printf("%02x", fmt_desc->guidFormat[i]);
296 printf(" (%4s)\n", fmt_desc->fourccFormat );
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);
308 DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
309 uint32_t *interval_ptr;
311 printf(" FrameDescriptor(%d)\n"
312 " capabilities: %02x\n"
315 " max frame size: %d\n"
316 " default interval: 1/%d\n",
317 frame_desc->bFrameIndex,
318 frame_desc->bmCapabilities,
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;
329 printf(" interval[%d]: 1/%d\n",
330 (int) (interval_ptr - frame_desc->intervals),
331 10000000 / *interval_ptr);
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);
348 printf("\t-UnknownFormat (%d)\n",fmt_desc->bDescriptorSubtype );
353 printf("uvc_print_frameformats: Device not configured!\n");