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
38 #include "libuvc/libuvc.h"
39 #include "libuvc/libuvc_internal.h"
42 typedef struct _uvc_error_msg {
47 static const _uvc_error_msg_t uvc_error_msgs[] = {
48 {UVC_SUCCESS, "Success"},
49 {UVC_ERROR_IO, "I/O error"},
50 {UVC_ERROR_INVALID_PARAM, "Invalid parameter"},
51 {UVC_ERROR_ACCESS, "Access denied"},
52 {UVC_ERROR_NO_DEVICE, "No such device"},
53 {UVC_ERROR_NOT_FOUND, "Not found"},
54 {UVC_ERROR_BUSY, "Busy"},
55 {UVC_ERROR_TIMEOUT, "Timeout"},
56 {UVC_ERROR_OVERFLOW, "Overflow"},
57 {UVC_ERROR_PIPE, "Pipe"},
58 {UVC_ERROR_INTERRUPTED, "Interrupted"},
59 {UVC_ERROR_NO_MEM, "Out of memory"},
60 {UVC_ERROR_NOT_SUPPORTED, "Not supported"},
61 {UVC_ERROR_INVALID_DEVICE, "Invalid device"},
62 {UVC_ERROR_INVALID_MODE, "Invalid mode"},
63 {UVC_ERROR_CALLBACK_EXISTS, "Callback exists"}
66 /** @brief Print a message explaining an error in the UVC driver
69 * @param err UVC error code
70 * @param msg Optional custom message, prepended to output
72 void uvc_perror(uvc_error_t err, const char *msg) {
78 fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
81 /** @brief Return a string explaining an error in the UVC driver
84 * @param err UVC error code
85 * @return error message
87 const char* uvc_strerror(uvc_error_t err) {
90 for (idx = 0; idx < sizeof(uvc_error_msgs) / sizeof(*uvc_error_msgs); ++idx) {
91 if (uvc_error_msgs[idx].err == err) {
92 return uvc_error_msgs[idx].msg;
96 return "Unknown error";
99 /** @brief Print the values in a stream control block
102 * @param devh UVC device
103 * @param stream Output stream (stderr if NULL)
105 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
109 fprintf(stream, "bmHint: %04x\n", ctrl->bmHint);
110 fprintf(stream, "bFormatIndex: %d\n", ctrl->bFormatIndex);
111 fprintf(stream, "bFrameIndex: %d\n", ctrl->bFrameIndex);
112 fprintf(stream, "dwFrameInterval: %u\n", ctrl->dwFrameInterval);
113 fprintf(stream, "wKeyFrameRate: %d\n", ctrl->wKeyFrameRate);
114 fprintf(stream, "wPFrameRate: %d\n", ctrl->wPFrameRate);
115 fprintf(stream, "wCompQuality: %d\n", ctrl->wCompQuality);
116 fprintf(stream, "wCompWindowSize: %d\n", ctrl->wCompWindowSize);
117 fprintf(stream, "wDelay: %d\n", ctrl->wDelay);
118 fprintf(stream, "dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize);
119 fprintf(stream, "dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize);
120 fprintf(stream, "bInterfaceNumber: %d\n", ctrl->bInterfaceNumber);
123 static const char *_uvc_name_for_format_subtype(uint8_t subtype) {
125 case UVC_VS_FORMAT_UNCOMPRESSED:
126 return "UncompressedFormat";
127 case UVC_VS_FORMAT_MJPEG:
128 return "MJPEGFormat";
134 /** @brief Print camera capabilities and configuration.
137 * @param devh UVC device
138 * @param stream Output stream (stderr if NULL)
140 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
144 if (devh->info->ctrl_if.bcdUVC) {
145 uvc_streaming_interface_t *stream_if;
148 uvc_device_descriptor_t *desc;
149 uvc_get_device_descriptor(devh->dev, &desc);
151 fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
152 desc->idVendor, desc->idProduct,
153 desc->serialNumber ? desc->serialNumber : "[none]");
155 uvc_free_device_descriptor(desc);
157 fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
159 fprintf(stream, "VideoControl:\n"
160 "\tbcdUVC: 0x%04x\n",
161 devh->info->ctrl_if.bcdUVC);
163 DL_FOREACH(devh->info->stream_ifs, stream_if) {
164 uvc_format_desc_t *fmt_desc;
168 fprintf(stream, "VideoStreaming(%d):\n"
169 "\tbEndpointAddress: %d\n\tFormats:\n",
170 stream_idx, stream_if->bEndpointAddress);
172 DL_FOREACH(stream_if->format_descs, fmt_desc) {
173 uvc_frame_desc_t *frame_desc;
176 switch (fmt_desc->bDescriptorSubtype) {
177 case UVC_VS_FORMAT_UNCOMPRESSED:
178 case UVC_VS_FORMAT_MJPEG:
181 "\t\t bits per pixel: %d\n"
183 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
184 fmt_desc->bFormatIndex,
185 fmt_desc->bBitsPerPixel);
187 for (i = 0; i < 16; ++i)
188 fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
190 fprintf(stream, "\n");
193 "\t\t default frame: %d\n"
194 "\t\t aspect ration: %dx%d\n"
195 "\t\t interlace flags: %02x\n"
196 "\t\t copy protect: %02x\n",
197 fmt_desc->bDefaultFrameIndex,
198 fmt_desc->bAspectRatioX,
199 fmt_desc->bAspectRatioY,
200 fmt_desc->bmInterlaceFlags,
201 fmt_desc->bCopyProtect);
203 DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
204 uint32_t *interval_ptr;
207 "\t\t\tFrameDescriptor(%d)\n"
208 "\t\t\t capabilities: %02x\n"
209 "\t\t\t size: %dx%d\n"
210 "\t\t\t bit rate: %d-%d\n"
211 "\t\t\t max frame size: %d\n"
212 "\t\t\t default interval: 1/%d\n",
213 frame_desc->bFrameIndex,
214 frame_desc->bmCapabilities,
217 frame_desc->dwMinBitRate,
218 frame_desc->dwMaxBitRate,
219 frame_desc->dwMaxVideoFrameBufferSize,
220 10000000 / frame_desc->dwDefaultFrameInterval);
221 if (frame_desc->intervals) {
222 for (interval_ptr = frame_desc->intervals;
226 "\t\t\t interval[%d]: 1/%d\n",
227 (int) (interval_ptr - frame_desc->intervals),
228 10000000 / *interval_ptr);
232 "\t\t\t min interval[%d] = 1/%d\n"
233 "\t\t\t max interval[%d] = 1/%d\n",
234 frame_desc->dwMinFrameInterval,
235 10000000 / frame_desc->dwMinFrameInterval,
236 frame_desc->dwMaxFrameInterval,
237 10000000 / frame_desc->dwMaxFrameInterval);
238 if (frame_desc->dwFrameIntervalStep)
240 "\t\t\t interval step[%d] = 1/%d\n",
241 frame_desc->dwFrameIntervalStep,
242 10000000 / frame_desc->dwFrameIntervalStep);
247 fprintf(stream, "\t-UnknownFormat\n");
252 fprintf(stream, "END DEVICE CONFIGURATION\n");
254 fprintf(stream, "uvc_print_diag: Device not configured!\n");