stream pushing ok without access permission of /dev/video0
[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 #ifdef __ANDROID__
80   __android_log_print(ANDROID_LOG_ERROR, "UVC", "%s (%d)\n", uvc_strerror(err), err);
81 #else
82   fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
83 #endif
84 }
85
86 /** @brief Return a string explaining an error in the UVC driver
87  * @ingroup diag
88  *
89  * @param err UVC error code
90  * @return error message
91  */
92 const char* uvc_strerror(uvc_error_t err) {
93   size_t idx;
94
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;
98     }
99   }
100
101   return "Unknown error";
102 }
103
104 /** @brief Print the values in a stream control block
105  * @ingroup diag
106  *
107  * @param devh UVC device
108  * @param stream Output stream (stderr if NULL)
109  */
110 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
111   if (stream == NULL)
112     stream = stderr;
113
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);
126 }
127
128 static const char *_uvc_name_for_format_subtype(uint8_t subtype) {
129   switch (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";
136   default:
137     return "Unknown";
138   }
139 }
140
141 /** @brief Print camera capabilities and configuration.
142  * @ingroup diag
143  *
144  * @param devh UVC device
145  * @param stream Output stream (stderr if NULL)
146  */
147 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
148   if (stream == NULL)
149     stream = stderr;
150
151   if (devh->info->ctrl_if.bcdUVC) {
152     uvc_streaming_interface_t *stream_if;
153     int stream_idx = 0;
154
155     uvc_device_descriptor_t *desc;
156     uvc_get_device_descriptor(devh->dev, &desc);
157
158     fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
159         desc->idVendor, desc->idProduct,
160         desc->serialNumber ? desc->serialNumber : "[none]");
161
162     uvc_free_device_descriptor(desc);
163
164     fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
165
166     fprintf(stream, "VideoControl:\n"
167         "\tbcdUVC: 0x%04x\n",
168         devh->info->ctrl_if.bcdUVC);
169
170     DL_FOREACH(devh->info->stream_ifs, stream_if) {
171       uvc_format_desc_t *fmt_desc;
172
173       ++stream_idx;
174
175       fprintf(stream, "VideoStreaming(%d):\n"
176           "\tbEndpointAddress: %d\n\tFormats:\n",
177           stream_idx, stream_if->bEndpointAddress);
178
179       DL_FOREACH(stream_if->format_descs, fmt_desc) {
180         uvc_frame_desc_t *frame_desc;
181         int i;
182
183         switch (fmt_desc->bDescriptorSubtype) {
184           case UVC_VS_FORMAT_UNCOMPRESSED:
185           case UVC_VS_FORMAT_MJPEG:
186           case UVC_VS_FORMAT_FRAME_BASED:
187             fprintf(stream,
188                 "\t\%s(%d)\n"
189                 "\t\t  bits per pixel: %d\n"
190                 "\t\t  GUID: ",
191                 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
192                 fmt_desc->bFormatIndex,
193                 fmt_desc->bBitsPerPixel);
194
195             for (i = 0; i < 16; ++i)
196               fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
197
198             fprintf(stream, " (%4s)\n", fmt_desc->fourccFormat );
199
200             fprintf(stream,
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);
210
211             DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
212               uint32_t *interval_ptr;
213
214               fprintf(stream,
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,
223                   frame_desc->wWidth,
224                   frame_desc->wHeight,
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;
231                      *interval_ptr;
232                      ++interval_ptr) {
233                   fprintf(stream,
234                       "\t\t\t  interval[%d]: 1/%d\n",
235                       (int) (interval_ptr - frame_desc->intervals),
236                       10000000 / *interval_ptr);
237                 }
238               } else {
239                 fprintf(stream,
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)
247                   fprintf(stream,
248                       "\t\t\t  interval step[%d] = 1/%d\n",
249                       frame_desc->dwFrameIntervalStep,
250                       10000000 / frame_desc->dwFrameIntervalStep);
251               }
252             }
253             break;
254           default:
255             fprintf(stream, "\t-UnknownFormat (%d)\n",
256                 fmt_desc->bDescriptorSubtype );
257         }
258       }
259     }
260
261     fprintf(stream, "END DEVICE CONFIGURATION\n");
262   } else {
263     fprintf(stream, "uvc_print_diag: Device not configured!\n");
264   }
265 }
266
267 /** @brief Print all possible frame configuration.
268  * @ingroup diag
269  *
270  * @param devh UVC device
271  * @param stream Output stream (stderr if NULL)
272  */
273 void uvc_print_frameformats(uvc_device_handle_t *devh) {
274
275   if (devh->info->ctrl_if.bcdUVC) {
276     uvc_streaming_interface_t *stream_if;
277     int stream_idx = 0;
278     DL_FOREACH(devh->info->stream_ifs, stream_if) {
279       uvc_format_desc_t *fmt_desc;
280       ++stream_idx;
281
282       DL_FOREACH(stream_if->format_descs, fmt_desc) {
283         uvc_frame_desc_t *frame_desc;
284         int i;
285
286         switch (fmt_desc->bDescriptorSubtype) {
287           case UVC_VS_FORMAT_UNCOMPRESSED:
288           case UVC_VS_FORMAT_MJPEG:
289           case UVC_VS_FORMAT_FRAME_BASED:
290             printf("         \%s(%d)\n"
291                 "            bits per pixel: %d\n"
292                 "            GUID: ",
293                 _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
294                 fmt_desc->bFormatIndex,
295                 fmt_desc->bBitsPerPixel);
296
297             for (i = 0; i < 16; ++i)
298               printf("%02x", fmt_desc->guidFormat[i]);
299
300             printf(" (%4s)\n", fmt_desc->fourccFormat );
301
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);
311
312             DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
313               uint32_t *interval_ptr;
314
315               printf("               FrameDescriptor(%d)\n"
316                   "                  capabilities: %02x\n"
317                   "                  size: %dx%d\n"
318                   "                  bit rate: %d-%d\n"
319                   "                  max frame size: %d\n"
320                   "                  default interval: 1/%d\n",
321                   frame_desc->bFrameIndex,
322                   frame_desc->bmCapabilities,
323                   frame_desc->wWidth,
324                   frame_desc->wHeight,
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;
331                      *interval_ptr;
332                      ++interval_ptr) {
333                   printf("                  interval[%d]: 1/%d\n",
334                       (int) (interval_ptr - frame_desc->intervals),
335                       10000000 / *interval_ptr);
336                 }
337               } else {
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);
348               }
349             }
350             break;
351           default:
352             printf("\t-UnknownFormat (%d)\n",fmt_desc->bDescriptorSubtype );
353         }
354       }
355     }
356   } else {
357     printf("uvc_print_frameformats: Device not configured!\n");
358   }
359 }