Add libusb and libuvc
[rtmpclient.git] / app / src / main / jni / libuvc-0.0.6 / src / diag.c
diff --git a/app/src/main/jni/libuvc-0.0.6/src/diag.c b/app/src/main/jni/libuvc-0.0.6/src/diag.c
new file mode 100644 (file)
index 0000000..fa17731
--- /dev/null
@@ -0,0 +1,355 @@
+/*********************************************************************
+* Software License Agreement (BSD License)
+*
+*  Copyright (C) 2010-2012 Ken Tossell
+*  All rights reserved.
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of the author nor other contributors may be
+*     used to endorse or promote products derived from this software
+*     without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+*  POSSIBILITY OF SUCH DAMAGE.
+*********************************************************************/
+/**
+ * @defgroup diag Diagnostics
+ * @brief Interpretation of devices, error codes and negotiated stream parameters
+ */
+
+#include "libuvc/libuvc.h"
+#include "libuvc/libuvc_internal.h"
+
+/** @internal */
+typedef struct _uvc_error_msg {
+  uvc_error_t err;
+  const char *msg;
+} _uvc_error_msg_t;
+
+static const _uvc_error_msg_t uvc_error_msgs[] = {
+  {UVC_SUCCESS, "Success"},
+  {UVC_ERROR_IO, "I/O error"},
+  {UVC_ERROR_INVALID_PARAM, "Invalid parameter"},
+  {UVC_ERROR_ACCESS, "Access denied"},
+  {UVC_ERROR_NO_DEVICE, "No such device"},
+  {UVC_ERROR_NOT_FOUND, "Not found"},
+  {UVC_ERROR_BUSY, "Busy"},
+  {UVC_ERROR_TIMEOUT, "Timeout"},
+  {UVC_ERROR_OVERFLOW, "Overflow"},
+  {UVC_ERROR_PIPE, "Pipe"},
+  {UVC_ERROR_INTERRUPTED, "Interrupted"},
+  {UVC_ERROR_NO_MEM, "Out of memory"},
+  {UVC_ERROR_NOT_SUPPORTED, "Not supported"},
+  {UVC_ERROR_INVALID_DEVICE, "Invalid device"},
+  {UVC_ERROR_INVALID_MODE, "Invalid mode"},
+  {UVC_ERROR_CALLBACK_EXISTS, "Callback exists"}
+};
+
+/** @brief Print a message explaining an error in the UVC driver
+ * @ingroup diag
+ *
+ * @param err UVC error code
+ * @param msg Optional custom message, prepended to output
+ */
+void uvc_perror(uvc_error_t err, const char *msg) {
+  if (msg && *msg) {
+    fputs(msg, stderr);
+    fputs(": ", stderr);
+  }
+
+  fprintf(stderr, "%s (%d)\n", uvc_strerror(err), err);
+}
+
+/** @brief Return a string explaining an error in the UVC driver
+ * @ingroup diag
+ *
+ * @param err UVC error code
+ * @return error message
+ */
+const char* uvc_strerror(uvc_error_t err) {
+  size_t idx;
+
+  for (idx = 0; idx < sizeof(uvc_error_msgs) / sizeof(*uvc_error_msgs); ++idx) {
+    if (uvc_error_msgs[idx].err == err) {
+      return uvc_error_msgs[idx].msg;
+    }
+  }
+
+  return "Unknown error";
+}
+
+/** @brief Print the values in a stream control block
+ * @ingroup diag
+ *
+ * @param devh UVC device
+ * @param stream Output stream (stderr if NULL)
+ */
+void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
+  if (stream == NULL)
+    stream = stderr;
+
+  fprintf(stream, "bmHint: %04x\n", ctrl->bmHint);
+  fprintf(stream, "bFormatIndex: %d\n", ctrl->bFormatIndex);
+  fprintf(stream, "bFrameIndex: %d\n", ctrl->bFrameIndex);
+  fprintf(stream, "dwFrameInterval: %u\n", ctrl->dwFrameInterval);
+  fprintf(stream, "wKeyFrameRate: %d\n", ctrl->wKeyFrameRate);
+  fprintf(stream, "wPFrameRate: %d\n", ctrl->wPFrameRate);
+  fprintf(stream, "wCompQuality: %d\n", ctrl->wCompQuality);
+  fprintf(stream, "wCompWindowSize: %d\n", ctrl->wCompWindowSize);
+  fprintf(stream, "wDelay: %d\n", ctrl->wDelay);
+  fprintf(stream, "dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize);
+  fprintf(stream, "dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize);
+  fprintf(stream, "bInterfaceNumber: %d\n", ctrl->bInterfaceNumber);
+}
+
+static const char *_uvc_name_for_format_subtype(uint8_t subtype) {
+  switch (subtype) {
+  case UVC_VS_FORMAT_UNCOMPRESSED:
+    return "UncompressedFormat";
+  case UVC_VS_FORMAT_MJPEG:
+    return "MJPEGFormat";
+  case UVC_VS_FORMAT_FRAME_BASED:
+    return "FrameFormat";
+  default:
+    return "Unknown";
+  }
+}
+
+/** @brief Print camera capabilities and configuration.
+ * @ingroup diag
+ *
+ * @param devh UVC device
+ * @param stream Output stream (stderr if NULL)
+ */
+void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
+  if (stream == NULL)
+    stream = stderr;
+
+  if (devh->info->ctrl_if.bcdUVC) {
+    uvc_streaming_interface_t *stream_if;
+    int stream_idx = 0;
+
+    uvc_device_descriptor_t *desc;
+    uvc_get_device_descriptor(devh->dev, &desc);
+
+    fprintf(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
+        desc->idVendor, desc->idProduct,
+        desc->serialNumber ? desc->serialNumber : "[none]");
+
+    uvc_free_device_descriptor(desc);
+
+    fprintf(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
+
+    fprintf(stream, "VideoControl:\n"
+        "\tbcdUVC: 0x%04x\n",
+        devh->info->ctrl_if.bcdUVC);
+
+    DL_FOREACH(devh->info->stream_ifs, stream_if) {
+      uvc_format_desc_t *fmt_desc;
+
+      ++stream_idx;
+
+      fprintf(stream, "VideoStreaming(%d):\n"
+          "\tbEndpointAddress: %d\n\tFormats:\n",
+          stream_idx, stream_if->bEndpointAddress);
+
+      DL_FOREACH(stream_if->format_descs, fmt_desc) {
+        uvc_frame_desc_t *frame_desc;
+        int i;
+
+        switch (fmt_desc->bDescriptorSubtype) {
+          case UVC_VS_FORMAT_UNCOMPRESSED:
+          case UVC_VS_FORMAT_MJPEG:
+          case UVC_VS_FORMAT_FRAME_BASED:
+            fprintf(stream,
+                "\t\%s(%d)\n"
+                "\t\t  bits per pixel: %d\n"
+                "\t\t  GUID: ",
+                _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
+                fmt_desc->bFormatIndex,
+                fmt_desc->bBitsPerPixel);
+
+            for (i = 0; i < 16; ++i)
+              fprintf(stream, "%02x", fmt_desc->guidFormat[i]);
+
+            fprintf(stream, " (%4s)\n", fmt_desc->fourccFormat );
+
+            fprintf(stream,
+                "\t\t  default frame: %d\n"
+                "\t\t  aspect ratio: %dx%d\n"
+                "\t\t  interlace flags: %02x\n"
+                "\t\t  copy protect: %02x\n",
+                fmt_desc->bDefaultFrameIndex,
+                fmt_desc->bAspectRatioX,
+                fmt_desc->bAspectRatioY,
+                fmt_desc->bmInterlaceFlags,
+                fmt_desc->bCopyProtect);
+
+            DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
+              uint32_t *interval_ptr;
+
+              fprintf(stream,
+                  "\t\t\tFrameDescriptor(%d)\n"
+                  "\t\t\t  capabilities: %02x\n"
+                  "\t\t\t  size: %dx%d\n"
+                  "\t\t\t  bit rate: %d-%d\n"
+                  "\t\t\t  max frame size: %d\n"
+                  "\t\t\t  default interval: 1/%d\n",
+                  frame_desc->bFrameIndex,
+                  frame_desc->bmCapabilities,
+                  frame_desc->wWidth,
+                  frame_desc->wHeight,
+                  frame_desc->dwMinBitRate,
+                  frame_desc->dwMaxBitRate,
+                  frame_desc->dwMaxVideoFrameBufferSize,
+                  10000000 / frame_desc->dwDefaultFrameInterval);
+              if (frame_desc->intervals) {
+                for (interval_ptr = frame_desc->intervals;
+                     *interval_ptr;
+                     ++interval_ptr) {
+                  fprintf(stream,
+                      "\t\t\t  interval[%d]: 1/%d\n",
+                     (int) (interval_ptr - frame_desc->intervals),
+                     10000000 / *interval_ptr);
+                }
+              } else {
+                fprintf(stream,
+                    "\t\t\t  min interval[%d] = 1/%d\n"
+                    "\t\t\t  max interval[%d] = 1/%d\n",
+                    frame_desc->dwMinFrameInterval,
+                    10000000 / frame_desc->dwMinFrameInterval,
+                    frame_desc->dwMaxFrameInterval,
+                    10000000 / frame_desc->dwMaxFrameInterval);
+                if (frame_desc->dwFrameIntervalStep)
+                  fprintf(stream,
+                      "\t\t\t  interval step[%d] = 1/%d\n",
+                      frame_desc->dwFrameIntervalStep,
+                      10000000 / frame_desc->dwFrameIntervalStep);
+              }
+            }
+            break;
+          default:
+            fprintf(stream, "\t-UnknownFormat (%d)\n",
+                fmt_desc->bDescriptorSubtype );
+        }
+      }
+    }
+
+    fprintf(stream, "END DEVICE CONFIGURATION\n");
+  } else {
+    fprintf(stream, "uvc_print_diag: Device not configured!\n");
+  }
+}
+
+/** @brief Print all possible frame configuration.
+ * @ingroup diag
+ *
+ * @param devh UVC device
+ * @param stream Output stream (stderr if NULL)
+ */
+void uvc_print_frameformats(uvc_device_handle_t *devh) {
+
+  if (devh->info->ctrl_if.bcdUVC) {
+    uvc_streaming_interface_t *stream_if;
+    int stream_idx = 0;
+    DL_FOREACH(devh->info->stream_ifs, stream_if) {
+      uvc_format_desc_t *fmt_desc;
+      ++stream_idx;
+
+      DL_FOREACH(stream_if->format_descs, fmt_desc) {
+        uvc_frame_desc_t *frame_desc;
+        int i;
+
+        switch (fmt_desc->bDescriptorSubtype) {
+          case UVC_VS_FORMAT_UNCOMPRESSED:
+          case UVC_VS_FORMAT_MJPEG:
+          case UVC_VS_FORMAT_FRAME_BASED:
+            printf("         \%s(%d)\n"
+                "            bits per pixel: %d\n"
+                "            GUID: ",
+                _uvc_name_for_format_subtype(fmt_desc->bDescriptorSubtype),
+                fmt_desc->bFormatIndex,
+                fmt_desc->bBitsPerPixel);
+
+            for (i = 0; i < 16; ++i)
+              printf("%02x", fmt_desc->guidFormat[i]);
+
+            printf(" (%4s)\n", fmt_desc->fourccFormat );
+
+            printf("            default frame: %d\n"
+                "            aspect ratio: %dx%d\n"
+                "            interlace flags: %02x\n"
+                "            copy protect: %02x\n",
+                fmt_desc->bDefaultFrameIndex,
+                fmt_desc->bAspectRatioX,
+                fmt_desc->bAspectRatioY,
+                fmt_desc->bmInterlaceFlags,
+                fmt_desc->bCopyProtect);
+
+            DL_FOREACH(fmt_desc->frame_descs, frame_desc) {
+              uint32_t *interval_ptr;
+
+              printf("               FrameDescriptor(%d)\n"
+                  "                  capabilities: %02x\n"
+                  "                  size: %dx%d\n"
+                  "                  bit rate: %d-%d\n"
+                  "                  max frame size: %d\n"
+                  "                  default interval: 1/%d\n",
+                  frame_desc->bFrameIndex,
+                  frame_desc->bmCapabilities,
+                  frame_desc->wWidth,
+                  frame_desc->wHeight,
+                  frame_desc->dwMinBitRate,
+                  frame_desc->dwMaxBitRate,
+                  frame_desc->dwMaxVideoFrameBufferSize,
+                  10000000 / frame_desc->dwDefaultFrameInterval);
+              if (frame_desc->intervals) {
+                for (interval_ptr = frame_desc->intervals;
+                     *interval_ptr;
+                     ++interval_ptr) {
+                  printf("                  interval[%d]: 1/%d\n",
+                     (int) (interval_ptr - frame_desc->intervals),
+                     10000000 / *interval_ptr);
+                }
+              } else {
+                printf("                  min interval[%d] = 1/%d\n"
+                    "                  max interval[%d] = 1/%d\n",
+                    frame_desc->dwMinFrameInterval,
+                    10000000 / frame_desc->dwMinFrameInterval,
+                    frame_desc->dwMaxFrameInterval,
+                    10000000 / frame_desc->dwMaxFrameInterval);
+                if (frame_desc->dwFrameIntervalStep)
+                  printf("                  interval step[%d] = 1/%d\n",
+                      frame_desc->dwFrameIntervalStep,
+                      10000000 / frame_desc->dwFrameIntervalStep);
+              }
+            }
+            break;
+          default:
+            printf("\t-UnknownFormat (%d)\n",fmt_desc->bDescriptorSubtype );
+        }
+      }
+    }
+  } else {
+    printf("uvc_print_frameformats: Device not configured!\n");
+  }
+}