Lots of Kinect bits.

This commit is contained in:
Andrzej Kapolka 2013-06-25 14:27:13 -07:00
parent 9f681c0709
commit 1d578d5b0e
36 changed files with 8268 additions and 28 deletions

View file

@ -0,0 +1,44 @@
# Try to find the Freenect library to read from Kinect
#
# You must provide a FREENECT_ROOT_DIR which contains lib and include directories
#
# Once done this will define
#
# FREENECT_FOUND - system found Freenect
# FREENECT_INCLUDE_DIRS - the Freenect include directory
# FREENECT_LIBRARIES - Link this to use Freenect
#
# Created on 6/25/2013 by Andrzej Kapolka
# Copyright (c) 2013 High Fidelity
#
if (FREENECT_LIBRARIES AND FREENECT_INCLUDE_DIRS)
# in cache already
set(FREENECT_FOUND TRUE)
else (FREENECT_LIBRARIES AND FREENECT_INCLUDE_DIRS)
find_path(FREENECT_INCLUDE_DIRS libfreenect.h ${FREENECT_ROOT_DIR}/include)
if (APPLE)
find_library(FREENECT_LIBRARIES libfreenect.a ${FREENECT_ROOT_DIR}/lib/MacOS/)
elseif (UNIX)
find_library(FREENECT_LIBRARIES libfreenect.a ${FREENECT_ROOT_DIR}/lib/UNIX/)
endif ()
if (FREENECT_INCLUDE_DIRS AND FREENECT_LIBRARIES)
set(FREENECT_FOUND TRUE)
endif (FREENECT_INCLUDE_DIRS AND FREENECT_LIBRARIES)
if (FREENECT_FOUND)
if (NOT FREENECT_FIND_QUIETLY)
message(STATUS "Found Freenect: ${FREENECT_LIBRARIES}")
endif (NOT FREENECT_FIND_QUIETLY)
else (FREENECT_FOUND)
if (FREENECT_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Freenect")
endif (FREENECT_FIND_REQUIRED)
endif (FREENECT_FOUND)
# show the FREENECT_INCLUDE_DIRS and FREENECT_LIBRARIES variables only in the advanced view
mark_as_advanced(FREENECT_INCLUDE_DIRS FREENECT_LIBRARIES)
endif (FREENECT_LIBRARIES AND FREENECT_INCLUDE_DIRS)

View file

@ -0,0 +1,44 @@
# Try to find the LibUSB library to interact with USB devices
#
# You must provide a LIBUSB_ROOT_DIR which contains lib and include directories
#
# Once done this will define
#
# LIBUSB_FOUND - system found LibUSB
# LIBUSB_INCLUDE_DIRS - the LibUSB include directory
# LIBUSB_LIBRARIES - Link this to use LibUSB
#
# Created on 6/25/2013 by Andrzej Kapolka
# Copyright (c) 2013 High Fidelity
#
if (LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIRS)
# in cache already
set(LIBUSB_FOUND TRUE)
else (LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIRS)
find_path(LIBUSB_INCLUDE_DIRS libusb.h ${LIBUSB_ROOT_DIR}/include)
if (APPLE)
find_library(LIBUSB_LIBRARIES libusb-1.0.a ${LIBUSB_ROOT_DIR}/lib/MacOS/)
elseif (UNIX)
find_library(LIBUSB_LIBRARIES libusb-1.0.a ${LIBUSB_ROOT_DIR}/lib/UNIX/)
endif ()
if (LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
set(LIBUSB_FOUND TRUE)
endif (LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
if (LIBUSB_FOUND)
if (NOT LIBUSB_FIND_QUIETLY)
message(STATUS "Found LibUSB: ${LIBUSB_LIBRARIES}")
endif (NOT LIBUSB_FIND_QUIETLY)
else (LIBUSB_FOUND)
if (LIBUSB_FIND_REQUIRED)
message(FATAL_ERROR "Could not find LibUSB")
endif (LIBUSB_FIND_REQUIRED)
endif (LIBUSB_FOUND)
# show the LIBUSB_INCLUDE_DIRS and LIBUSB_LIBRARIES variables only in the advanced view
mark_as_advanced(LIBUSB_INCLUDE_DIRS LIBUSB_LIBRARIES)
endif (LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIRS)

View file

@ -0,0 +1,44 @@
# Try to find the Skeltrack library to perform skeleton tracking via depth camera
#
# You must provide a SKELTRACK_ROOT_DIR which contains lib and include directories
#
# Once done this will define
#
# SKELTRACK_FOUND - system found Skeltrack
# SKELTRACK_INCLUDE_DIRS - the Skeltrack include directory
# SKELTRACK_LIBRARIES - Link this to use Skeltrack
#
# Created on 6/25/2013 by Andrzej Kapolka
# Copyright (c) 2013 High Fidelity
#
if (SKELTRACK_LIBRARIES AND SKELTRACK_INCLUDE_DIRS)
# in cache already
set(SKELTRACK_FOUND TRUE)
else (SKELTRACK_LIBRARIES AND SKELTRACK_INCLUDE_DIRS)
find_path(SKELTRACK_INCLUDE_DIRS skeltrack.h ${SKELTRACK_ROOT_DIR}/include)
if (APPLE)
find_library(SKELTRACK_LIBRARIES libskeltrack.a ${SKELTRACK_ROOT_DIR}/lib/MacOS/)
elseif (UNIX)
find_library(SKELTRACK_LIBRARIES libskeltrack.a ${SKELTRACK_ROOT_DIR}/lib/UNIX/)
endif ()
if (SKELTRACK_INCLUDE_DIRS AND SKELTRACK_LIBRARIES)
set(SKELTRACK_FOUND TRUE)
endif (SKELTRACK_INCLUDE_DIRS AND SKELTRACK_LIBRARIES)
if (SKELTRACK_FOUND)
if (NOT SKELTRACK_FIND_QUIETLY)
message(STATUS "Found Skeltrack: ${SKELTRACK_LIBRARIES}")
endif (NOT SKELTRACK_FIND_QUIETLY)
else (SKELTRACK_FOUND)
if (SKELTRACK_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Skeltrack")
endif (SKELTRACK_FIND_REQUIRED)
endif (SKELTRACK_FOUND)
# show the SKELTRACK_INCLUDE_DIRS and SKELTRACK_LIBRARIES variables only in the advanced view
mark_as_advanced(SKELTRACK_INCLUDE_DIRS SKELTRACK_LIBRARIES)
endif (SKELTRACK_LIBRARIES AND SKELTRACK_INCLUDE_DIRS)

View file

@ -13,6 +13,9 @@ set(PORTAUDIO_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/PortAudio)
set(SPEEX_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Speex)
set(OPENCV_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/OpenCV)
set(UVCCAMERACONTROL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/UVCCameraControl)
set(LIBUSB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibUSB)
set(FREENECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/freenect)
set(SKELTRACK_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/skeltrack)
if (APPLE)
set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>")
@ -91,6 +94,9 @@ find_package(SpeexDSP REQUIRED)
find_package(OpenCV)
find_package(ZLIB)
find_package(UVCCameraControl)
find_package(LibUSB)
find_package(Freenect)
find_package(Skeltrack)
# include headers for interface and InterfaceConfig.
include_directories(
@ -106,9 +112,12 @@ include_directories(
${LIBOVR_INCLUDE_DIRS}
${OPENCV_INCLUDE_DIRS}
${SPEEXDSP_INCLUDE_DIRS}
${FREENECT_INCLUDE_DIRS}
${SKELTRACK_INCLUDE_DIRS}
)
target_link_libraries(${TARGET_NAME} ${QT_LIBRARIES} ${OPENCV_LIBRARIES} ${ZLIB_LIBRARIES} ${SPEEXDSP_LIBRARIES})
target_link_libraries(${TARGET_NAME} ${QT_LIBRARIES} ${OPENCV_LIBRARIES} ${ZLIB_LIBRARIES} ${SPEEXDSP_LIBRARIES}
${FREENECT_LIBRARIES} ${SKELTRACK_LIBRARIES} ${LIBUSB_LIBRARIES})
if (APPLE)
# link in required OS X frameworks and include the right GL headers

1443
interface/external/LibUSB/include/libusb.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,935 @@
/*
* Internal header for libusb
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSBI_H
#define LIBUSBI_H
#include <config.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#include <stdarg.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <libusb.h>
#include <version.h>
/* Inside the libusb code, mark all public functions as follows:
* return_type API_EXPORTED function_name(params) { ... }
* But if the function returns a pointer, mark it as follows:
* DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... }
* In the libusb public header, mark all declarations as:
* return_type LIBUSB_CALL function_name(params);
*/
#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
#define DEVICE_DESC_LENGTH 18
#define USB_MAXENDPOINTS 32
#define USB_MAXINTERFACES 32
#define USB_MAXCONFIG 8
struct list_head {
struct list_head *prev, *next;
};
/* Get an entry from the list
* ptr - the address of this list_head element in "type"
* type - the data type that contains "member"
* member - the list_head element in "type"
*/
#define list_entry(ptr, type, member) \
((type *)((uintptr_t)(ptr) - (uintptr_t)(&((type *)0L)->member)))
/* Get each entry from a list
* pos - A structure pointer has a "member" element
* head - list head
* member - the list_head element in "pos"
* type - the type of the first parameter
*/
#define list_for_each_entry(pos, head, member, type) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
#define list_for_each_entry_safe(pos, n, head, member, type) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#define list_empty(entry) ((entry)->next == (entry))
static inline void list_init(struct list_head *entry)
{
entry->prev = entry->next = entry;
}
static inline void list_add(struct list_head *entry, struct list_head *head)
{
entry->next = head->next;
entry->prev = head;
head->next->prev = entry;
head->next = entry;
}
static inline void list_add_tail(struct list_head *entry,
struct list_head *head)
{
entry->next = head;
entry->prev = head->prev;
head->prev->next = entry;
head->prev = entry;
}
static inline void list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
}
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *mptr = (ptr); \
(type *)( (char *)mptr - offsetof(type,member) );})
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
enum usbi_log_level {
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARNING,
LOG_LEVEL_ERROR,
};
void usbi_log(struct libusb_context *ctx, enum usbi_log_level level,
const char *function, const char *format, ...);
void usbi_log_v(struct libusb_context *ctx, enum usbi_log_level level,
const char *function, const char *format, va_list args);
#if !defined(_MSC_VER) || _MSC_VER >= 1400
#ifdef ENABLE_LOGGING
#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__)
#else
#define _usbi_log(ctx, level, ...) do { (void)(ctx); } while(0)
#endif
#ifdef ENABLE_DEBUG_LOGGING
#define usbi_dbg(...) _usbi_log(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__)
#else
#define usbi_dbg(...) do {} while(0)
#endif
#define usbi_info(ctx, ...) _usbi_log(ctx, LOG_LEVEL_INFO, __VA_ARGS__)
#define usbi_warn(ctx, ...) _usbi_log(ctx, LOG_LEVEL_WARNING, __VA_ARGS__)
#define usbi_err(ctx, ...) _usbi_log(ctx, LOG_LEVEL_ERROR, __VA_ARGS__)
#else /* !defined(_MSC_VER) || _MSC_VER >= 1400 */
/* Old MS compilers don't support variadic macros. The code is simple, so we
* repeat it for each loglevel. Note that the debug case is special.
*
* Support for variadic macros was introduced in Visual C++ 2005.
* http://msdn.microsoft.com/en-us/library/ms177415%28v=VS.80%29.aspx
*/
static inline void usbi_info(struct libusb_context *ctx, const char *fmt, ...)
{
#ifdef ENABLE_LOGGING
va_list args;
va_start(args, fmt);
usbi_log_v(ctx, LOG_LEVEL_INFO, "", fmt, args);
va_end(args);
#else
(void)ctx;
#endif
}
static inline void usbi_warn(struct libusb_context *ctx, const char *fmt, ...)
{
#ifdef ENABLE_LOGGING
va_list args;
va_start(args, fmt);
usbi_log_v(ctx, LOG_LEVEL_WARNING, "", fmt, args);
va_end(args);
#else
(void)ctx;
#endif
}
static inline void usbi_err(struct libusb_context *ctx, const char *fmt, ...)
{
#ifdef ENABLE_LOGGING
va_list args;
va_start(args, fmt);
usbi_log_v(ctx, LOG_LEVEL_ERROR, "", fmt, args);
va_end(args);
#else
(void)ctx;
#endif
}
static inline void usbi_dbg(const char *fmt, ...)
{
#ifdef ENABLE_DEBUG_LOGGING
va_list args;
va_start(args, fmt);
usbi_log_v(NULL, LOG_LEVEL_DEBUG, "", fmt, args);
va_end(args);
#else
(void)fmt;
#endif
}
#endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */
#define USBI_GET_CONTEXT(ctx) if (!(ctx)) (ctx) = usbi_default_context
#define DEVICE_CTX(dev) ((dev)->ctx)
#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
#define ITRANSFER_CTX(transfer) \
(TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)))
#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN))
#define IS_EPOUT(ep) (!IS_EPIN(ep))
#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN))
#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer))
/* Internal abstractions for thread synchronization and poll */
#if defined(THREADS_POSIX)
#include <os/threads_posix.h>
#elif defined(OS_WINDOWS)
#include <os/threads_windows.h>
#endif
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD)
#include <unistd.h>
#include <os/poll_posix.h>
#elif defined(OS_WINDOWS)
#include <os/poll_windows.h>
#endif
#if defined(OS_WINDOWS) && !defined(__GCC__)
#undef HAVE_GETTIMEOFDAY
int usbi_gettimeofday(struct timeval *tp, void *tzp);
#define LIBUSB_GETTIMEOFDAY_WIN32
#define HAVE_USBI_GETTIMEOFDAY
#else
#ifdef HAVE_GETTIMEOFDAY
#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz))
#define HAVE_USBI_GETTIMEOFDAY
#endif
#endif
extern struct libusb_context *usbi_default_context;
struct libusb_context {
int debug;
int debug_fixed;
/* internal control pipe, used for interrupting event handling when
* something needs to modify poll fds. */
int ctrl_pipe[2];
struct list_head usb_devs;
usbi_mutex_t usb_devs_lock;
/* A list of open handles. Backends are free to traverse this if required.
*/
struct list_head open_devs;
usbi_mutex_t open_devs_lock;
/* this is a list of in-flight transfer handles, sorted by timeout
* expiration. URBs to timeout the soonest are placed at the beginning of
* the list, URBs that will time out later are placed after, and urbs with
* infinite timeout are always placed at the very end. */
struct list_head flying_transfers;
usbi_mutex_t flying_transfers_lock;
/* list of poll fds */
struct list_head pollfds;
usbi_mutex_t pollfds_lock;
/* a counter that is set when we want to interrupt event handling, in order
* to modify the poll fd set. and a lock to protect it. */
unsigned int pollfd_modify;
usbi_mutex_t pollfd_modify_lock;
/* user callbacks for pollfd changes */
libusb_pollfd_added_cb fd_added_cb;
libusb_pollfd_removed_cb fd_removed_cb;
void *fd_cb_user_data;
/* ensures that only one thread is handling events at any one time */
usbi_mutex_t events_lock;
/* used to see if there is an active thread doing event handling */
int event_handler_active;
/* used to wait for event completion in threads other than the one that is
* event handling */
usbi_mutex_t event_waiters_lock;
usbi_cond_t event_waiters_cond;
#ifdef USBI_TIMERFD_AVAILABLE
/* used for timeout handling, if supported by OS.
* this timerfd is maintained to trigger on the next pending timeout */
int timerfd;
#endif
};
#ifdef USBI_TIMERFD_AVAILABLE
#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
#else
#define usbi_using_timerfd(ctx) (0)
#endif
struct libusb_device {
/* lock protects refcnt, everything else is finalized at initialization
* time */
usbi_mutex_t lock;
int refcnt;
struct libusb_context *ctx;
uint8_t bus_number;
uint8_t device_address;
uint8_t num_configurations;
enum libusb_speed speed;
struct list_head list;
unsigned long session_data;
unsigned char os_priv[0];
};
struct libusb_device_handle {
/* lock protects claimed_interfaces */
usbi_mutex_t lock;
unsigned long claimed_interfaces;
struct list_head list;
struct libusb_device *dev;
unsigned char os_priv[0];
};
enum {
USBI_CLOCK_MONOTONIC,
USBI_CLOCK_REALTIME
};
/* in-memory transfer layout:
*
* 1. struct usbi_transfer
* 2. struct libusb_transfer (which includes iso packets) [variable size]
* 3. os private data [variable size]
*
* from a libusb_transfer, you can get the usbi_transfer by rewinding the
* appropriate number of bytes.
* the usbi_transfer includes the number of allocated packets, so you can
* determine the size of the transfer and hence the start and length of the
* OS-private data.
*/
struct usbi_transfer {
int num_iso_packets;
struct list_head list;
struct timeval timeout;
int transferred;
uint8_t flags;
/* this lock is held during libusb_submit_transfer() and
* libusb_cancel_transfer() (allowing the OS backend to prevent duplicate
* cancellation, submission-during-cancellation, etc). the OS backend
* should also take this lock in the handle_events path, to prevent the user
* cancelling the transfer from another thread while you are processing
* its completion (presumably there would be races within your OS backend
* if this were possible). */
usbi_mutex_t lock;
};
enum usbi_transfer_flags {
/* The transfer has timed out */
USBI_TRANSFER_TIMED_OUT = 1 << 0,
/* Set by backend submit_transfer() if the OS handles timeout */
USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 1,
/* Cancellation was requested via libusb_cancel_transfer() */
USBI_TRANSFER_CANCELLING = 1 << 2,
/* Operation on the transfer failed because the device disappeared */
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3,
};
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
((struct libusb_transfer *)(((unsigned char *)(transfer)) \
+ sizeof(struct usbi_transfer)))
#define LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \
((struct usbi_transfer *)(((unsigned char *)(transfer)) \
- sizeof(struct usbi_transfer)))
static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer)
{
return ((unsigned char *)transfer) + sizeof(struct usbi_transfer)
+ sizeof(struct libusb_transfer)
+ (transfer->num_iso_packets
* sizeof(struct libusb_iso_packet_descriptor));
}
/* bus structures */
/* All standard descriptors have these 2 fields in common */
struct usb_descriptor_header {
uint8_t bLength;
uint8_t bDescriptorType;
};
/* shared data and functions */
int usbi_io_init(struct libusb_context *ctx);
void usbi_io_exit(struct libusb_context *ctx);
struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
unsigned long session_id);
struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
unsigned long session_id);
int usbi_sanitize_device(struct libusb_device *dev);
void usbi_handle_disconnect(struct libusb_device_handle *handle);
int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
enum libusb_transfer_status status);
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
int usbi_parse_descriptor(unsigned char *source, const char *descriptor,
void *dest, int host_endian);
int usbi_get_config_index_by_value(struct libusb_device *dev,
uint8_t bConfigurationValue, int *idx);
/* polling */
struct usbi_pollfd {
/* must come first */
struct libusb_pollfd pollfd;
struct list_head list;
};
int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
void usbi_fd_notification(struct libusb_context *ctx);
/* device discovery */
/* we traverse usbfs without knowing how many devices we are going to find.
* so we create this discovered_devs model which is similar to a linked-list
* which grows when required. it can be freed once discovery has completed,
* eliminating the need for a list node in the libusb_device structure
* itself. */
struct discovered_devs {
size_t len;
size_t capacity;
struct libusb_device *devices[0];
};
struct discovered_devs *discovered_devs_append(
struct discovered_devs *discdevs, struct libusb_device *dev);
/* OS abstraction */
/* This is the interface that OS backends need to implement.
* All fields are mandatory, except ones explicitly noted as optional. */
struct usbi_os_backend {
/* A human-readable name for your backend, e.g. "Linux usbfs" */
const char *name;
/* Perform initialization of your backend. You might use this function
* to determine specific capabilities of the system, allocate required
* data structures for later, etc.
*
* This function is called when a libusb user initializes the library
* prior to use.
*
* Return 0 on success, or a LIBUSB_ERROR code on failure.
*/
int (*init)(struct libusb_context *ctx);
/* Deinitialization. Optional. This function should destroy anything
* that was set up by init.
*
* This function is called when the user deinitializes the library.
*/
void (*exit)(void);
/* Enumerate all the USB devices on the system, returning them in a list
* of discovered devices.
*
* Your implementation should enumerate all devices on the system,
* regardless of whether they have been seen before or not.
*
* When you have found a device, compute a session ID for it. The session
* ID should uniquely represent that particular device for that particular
* connection session since boot (i.e. if you disconnect and reconnect a
* device immediately after, it should be assigned a different session ID).
* If your OS cannot provide a unique session ID as described above,
* presenting a session ID of (bus_number << 8 | device_address) should
* be sufficient. Bus numbers and device addresses wrap and get reused,
* but that is an unlikely case.
*
* After computing a session ID for a device, call
* usbi_get_device_by_session_id(). This function checks if libusb already
* knows about the device, and if so, it provides you with a libusb_device
* structure for it.
*
* If usbi_get_device_by_session_id() returns NULL, it is time to allocate
* a new device structure for the device. Call usbi_alloc_device() to
* obtain a new libusb_device structure with reference count 1. Populate
* the bus_number and device_address attributes of the new device, and
* perform any other internal backend initialization you need to do. At
* this point, you should be ready to provide device descriptors and so
* on through the get_*_descriptor functions. Finally, call
* usbi_sanitize_device() to perform some final sanity checks on the
* device. Assuming all of the above succeeded, we can now continue.
* If any of the above failed, remember to unreference the device that
* was returned by usbi_alloc_device().
*
* At this stage we have a populated libusb_device structure (either one
* that was found earlier, or one that we have just allocated and
* populated). This can now be added to the discovered devices list
* using discovered_devs_append(). Note that discovered_devs_append()
* may reallocate the list, returning a new location for it, and also
* note that reallocation can fail. Your backend should handle these
* error conditions appropriately.
*
* This function should not generate any bus I/O and should not block.
* If I/O is required (e.g. reading the active configuration value), it is
* OK to ignore these suggestions :)
*
* This function is executed when the user wishes to retrieve a list
* of USB devices connected to the system.
*
* Return 0 on success, or a LIBUSB_ERROR code on failure.
*/
int (*get_device_list)(struct libusb_context *ctx,
struct discovered_devs **discdevs);
/* Open a device for I/O and other USB operations. The device handle
* is preallocated for you, you can retrieve the device in question
* through handle->dev.
*
* Your backend should allocate any internal resources required for I/O
* and other operations so that those operations can happen (hopefully)
* without hiccup. This is also a good place to inform libusb that it
* should monitor certain file descriptors related to this device -
* see the usbi_add_pollfd() function.
*
* This function should not generate any bus I/O and should not block.
*
* This function is called when the user attempts to obtain a device
* handle for a device.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_ACCESS if the user has insufficient permissions
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since
* discovery
* - another LIBUSB_ERROR code on other failure
*
* Do not worry about freeing the handle on failed open, the upper layers
* do this for you.
*/
int (*open)(struct libusb_device_handle *handle);
/* Close a device such that the handle cannot be used again. Your backend
* should destroy any resources that were allocated in the open path.
* This may also be a good place to call usbi_remove_pollfd() to inform
* libusb of any file descriptors associated with this device that should
* no longer be monitored.
*
* This function is called when the user closes a device handle.
*/
void (*close)(struct libusb_device_handle *handle);
/* Retrieve the device descriptor from a device.
*
* The descriptor should be retrieved from memory, NOT via bus I/O to the
* device. This means that you may have to cache it in a private structure
* during get_device_list enumeration. Alternatively, you may be able
* to retrieve it from a kernel interface (some Linux setups can do this)
* still without generating bus I/O.
*
* This function is expected to write DEVICE_DESC_LENGTH (18) bytes into
* buffer, which is guaranteed to be big enough.
*
* This function is called when sanity-checking a device before adding
* it to the list of discovered devices, and also when the user requests
* to read the device descriptor.
*
* This function is expected to return the descriptor in bus-endian format
* (LE). If it returns the multi-byte values in host-endian format,
* set the host_endian output parameter to "1".
*
* Return 0 on success or a LIBUSB_ERROR code on failure.
*/
int (*get_device_descriptor)(struct libusb_device *device,
unsigned char *buffer, int *host_endian);
/* Get the ACTIVE configuration descriptor for a device.
*
* The descriptor should be retrieved from memory, NOT via bus I/O to the
* device. This means that you may have to cache it in a private structure
* during get_device_list enumeration. You may also have to keep track
* of which configuration is active when the user changes it.
*
* This function is expected to write len bytes of data into buffer, which
* is guaranteed to be big enough. If you can only do a partial write,
* return an error code.
*
* This function is expected to return the descriptor in bus-endian format
* (LE). If it returns the multi-byte values in host-endian format,
* set the host_endian output parameter to "1".
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
* - another LIBUSB_ERROR code on other failure
*/
int (*get_active_config_descriptor)(struct libusb_device *device,
unsigned char *buffer, size_t len, int *host_endian);
/* Get a specific configuration descriptor for a device.
*
* The descriptor should be retrieved from memory, NOT via bus I/O to the
* device. This means that you may have to cache it in a private structure
* during get_device_list enumeration.
*
* The requested descriptor is expressed as a zero-based index (i.e. 0
* indicates that we are requesting the first descriptor). The index does
* not (necessarily) equal the bConfigurationValue of the configuration
* being requested.
*
* This function is expected to write len bytes of data into buffer, which
* is guaranteed to be big enough. If you can only do a partial write,
* return an error code.
*
* This function is expected to return the descriptor in bus-endian format
* (LE). If it returns the multi-byte values in host-endian format,
* set the host_endian output parameter to "1".
*
* Return 0 on success or a LIBUSB_ERROR code on failure.
*/
int (*get_config_descriptor)(struct libusb_device *device,
uint8_t config_index, unsigned char *buffer, size_t len,
int *host_endian);
/* Get the bConfigurationValue for the active configuration for a device.
* Optional. This should only be implemented if you can retrieve it from
* cache (don't generate I/O).
*
* If you cannot retrieve this from cache, either do not implement this
* function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause
* libusb to retrieve the information through a standard control transfer.
*
* This function must be non-blocking.
* Return:
* - 0 on success
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - LIBUSB_ERROR_NOT_SUPPORTED if the value cannot be retrieved without
* blocking
* - another LIBUSB_ERROR code on other failure.
*/
int (*get_configuration)(struct libusb_device_handle *handle, int *config);
/* Set the active configuration for a device.
*
* A configuration value of -1 should put the device in unconfigured state.
*
* This function can block.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
* - LIBUSB_ERROR_BUSY if interfaces are currently claimed (and hence
* configuration cannot be changed)
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure.
*/
int (*set_configuration)(struct libusb_device_handle *handle, int config);
/* Claim an interface. When claimed, the application can then perform
* I/O to an interface's endpoints.
*
* This function should not generate any bus I/O and should not block.
* Interface claiming is a logical operation that simply ensures that
* no other drivers/applications are using the interface, and after
* claiming, no other drivers/applicatiosn can use the interface because
* we now "own" it.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if the interface does not exist
* - LIBUSB_ERROR_BUSY if the interface is in use by another driver/app
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*claim_interface)(struct libusb_device_handle *handle, int interface_number);
/* Release a previously claimed interface.
*
* This function should also generate a SET_INTERFACE control request,
* resetting the alternate setting of that interface to 0. It's OK for
* this function to block as a result.
*
* You will only ever be asked to release an interface which was
* successfully claimed earlier.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*release_interface)(struct libusb_device_handle *handle, int interface_number);
/* Set the alternate setting for an interface.
*
* You will only ever be asked to set the alternate setting for an
* interface which was successfully claimed earlier.
*
* It's OK for this function to block.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if the alternate setting does not exist
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*set_interface_altsetting)(struct libusb_device_handle *handle,
int interface_number, int altsetting);
/* Clear a halt/stall condition on an endpoint.
*
* It's OK for this function to block.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*clear_halt)(struct libusb_device_handle *handle,
unsigned char endpoint);
/* Perform a USB port reset to reinitialize a device.
*
* If possible, the handle should still be usable after the reset
* completes, assuming that the device descriptors did not change during
* reset and all previous interface state can be restored.
*
* If something changes, or you cannot easily locate/verify the resetted
* device, return LIBUSB_ERROR_NOT_FOUND. This prompts the application
* to close the old handle and re-enumerate the device.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the device
* has been disconnected since it was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*reset_device)(struct libusb_device_handle *handle);
/* Determine if a kernel driver is active on an interface. Optional.
*
* The presence of a kernel driver on an interface indicates that any
* calls to claim_interface would fail with the LIBUSB_ERROR_BUSY code.
*
* Return:
* - 0 if no driver is active
* - 1 if a driver is active
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*kernel_driver_active)(struct libusb_device_handle *handle,
int interface_number);
/* Detach a kernel driver from an interface. Optional.
*
* After detaching a kernel driver, the interface should be available
* for claim.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
* - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - another LIBUSB_ERROR code on other failure
*/
int (*detach_kernel_driver)(struct libusb_device_handle *handle,
int interface_number);
/* Attach a kernel driver to an interface. Optional.
*
* Reattach a kernel driver to the device.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
* - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
* was opened
* - LIBUSB_ERROR_BUSY if a program or driver has claimed the interface,
* preventing reattachment
* - another LIBUSB_ERROR code on other failure
*/
int (*attach_kernel_driver)(struct libusb_device_handle *handle,
int interface_number);
/* Destroy a device. Optional.
*
* This function is called when the last reference to a device is
* destroyed. It should free any resources allocated in the get_device_list
* path.
*/
void (*destroy_device)(struct libusb_device *dev);
/* Submit a transfer. Your implementation should take the transfer,
* morph it into whatever form your platform requires, and submit it
* asynchronously.
*
* This function must not block.
*
* Return:
* - 0 on success
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* - another LIBUSB_ERROR code on other failure
*/
int (*submit_transfer)(struct usbi_transfer *itransfer);
/* Cancel a previously submitted transfer.
*
* This function must not block. The transfer cancellation must complete
* later, resulting in a call to usbi_handle_transfer_cancellation()
* from the context of handle_events.
*/
int (*cancel_transfer)(struct usbi_transfer *itransfer);
/* Clear a transfer as if it has completed or cancelled, but do not
* report any completion/cancellation to the library. You should free
* all private data from the transfer as if you were just about to report
* completion or cancellation.
*
* This function might seem a bit out of place. It is used when libusb
* detects a disconnected device - it calls this function for all pending
* transfers before reporting completion (with the disconnect code) to
* the user. Maybe we can improve upon this internal interface in future.
*/
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
/* Handle any pending events. This involves monitoring any active
* transfers and processing their completion or cancellation.
*
* The function is passed an array of pollfd structures (size nfds)
* as a result of the poll() system call. The num_ready parameter
* indicates the number of file descriptors that have reported events
* (i.e. the poll() return value). This should be enough information
* for you to determine which actions need to be taken on the currently
* active transfers.
*
* For any cancelled transfers, call usbi_handle_transfer_cancellation().
* For completed transfers, call usbi_handle_transfer_completion().
* For control/bulk/interrupt transfers, populate the "transferred"
* element of the appropriate usbi_transfer structure before calling the
* above functions. For isochronous transfers, populate the status and
* transferred fields of the iso packet descriptors of the transfer.
*
* This function should also be able to detect disconnection of the
* device, reporting that situation with usbi_handle_disconnect().
*
* When processing an event related to a transfer, you probably want to
* take usbi_transfer.lock to prevent races. See the documentation for
* the usbi_transfer structure.
*
* Return 0 on success, or a LIBUSB_ERROR code on failure.
*/
int (*handle_events)(struct libusb_context *ctx,
struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
/* Get time from specified clock. At least two clocks must be implemented
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
Description of clocks:
USBI_CLOCK_REALTIME : clock returns time since system epoch.
USBI_CLOCK_MONOTONIC: clock returns time since unspecified start
time (usually boot).
*/
int (*clock_gettime)(int clkid, struct timespec *tp);
#ifdef USBI_TIMERFD_AVAILABLE
/* clock ID of the clock that should be used for timerfd */
clockid_t (*get_timerfd_clockid)(void);
#endif
/* Number of bytes to reserve for per-device private backend data.
* This private data area is accessible through the "os_priv" field of
* struct libusb_device. */
size_t device_priv_size;
/* Number of bytes to reserve for per-handle private backend data.
* This private data area is accessible through the "os_priv" field of
* struct libusb_device. */
size_t device_handle_priv_size;
/* Number of bytes to reserve for per-transfer private backend data.
* This private data area is accessible by calling
* usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
*/
size_t transfer_priv_size;
/* Mumber of additional bytes for os_priv for each iso packet.
* Can your backend use this? */
/* FIXME: linux can't use this any more. if other OS's cannot either,
* then remove this */
size_t add_iso_packet_size;
};
extern const struct usbi_os_backend * const usbi_backend;
extern const struct usbi_os_backend linux_usbfs_backend;
extern const struct usbi_os_backend darwin_backend;
extern const struct usbi_os_backend openbsd_backend;
extern const struct usbi_os_backend windows_backend;
#endif

View file

@ -0,0 +1,169 @@
/*
* darwin backend for libusb 1.0
* Copyright (C) 2008-2009 Nathan Hjelm <hjelmn@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(LIBUSB_DARWIN_H)
#define LIBUSB_DARWIN_H
#include "libusbi.h"
#include <IOKit/IOTypes.h>
#include <IOKit/IOCFBundle.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/IOCFPlugIn.h>
/* IOUSBInterfaceInferface */
#if defined (kIOUSBInterfaceInterfaceID300)
#define usb_interface_t IOUSBInterfaceInterface300
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
#define InterfaceVersion 300
#elif defined (kIOUSBInterfaceInterfaceID245)
#define usb_interface_t IOUSBInterfaceInterface245
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245
#define InterfaceVersion 245
#elif defined (kIOUSBInterfaceInterfaceID220)
#define usb_interface_t IOUSBInterfaceInterface220
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
#define InterfaceVersion 220
#elif defined (kIOUSBInterfaceInterfaceID197)
#define usb_interface_t IOUSBInterfaceInterface197
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197
#define InterfaceVersion 197
#elif defined (kIOUSBInterfaceInterfaceID190)
#define usb_interface_t IOUSBInterfaceInterface190
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190
#define InterfaceVersion 190
#elif defined (kIOUSBInterfaceInterfaceID182)
#define usb_interface_t IOUSBInterfaceInterface182
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID182
#define InterfaceVersion 182
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
/* IOUSBDeviceInterface */
#if defined (kIOUSBDeviceInterfaceID320)
#define usb_device_t IOUSBDeviceInterface320
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
#define DeviceVersion 320
#elif defined (kIOUSBDeviceInterfaceID300)
#define usb_device_t IOUSBDeviceInterface300
#define DeviceInterfaceID kIOUSBDeviceInterfaceID300
#define DeviceVersion 300
#elif defined (kIOUSBDeviceInterfaceID245)
#define usb_device_t IOUSBDeviceInterface245
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
#define DeviceVersion 245
#elif defined (kIOUSBDeviceInterfaceID197)
#define usb_device_t IOUSBDeviceInterface197
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
#define DeviceVersion 197
#elif defined (kIOUSBDeviceInterfaceID187)
#define usb_device_t IOUSBDeviceInterface187
#define DeviceInterfaceID kIOUSBDeviceInterfaceID187
#define DeviceVersion 187
#elif defined (kIOUSBDeviceInterfaceID182)
#define usb_device_t IOUSBDeviceInterface182
#define DeviceInterfaceID kIOUSBDeviceInterfaceID182
#define DeviceVersion 182
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
#if !defined(IO_OBJECT_NULL)
#define IO_OBJECT_NULL ((io_object_t) 0)
#endif
typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
typedef IONotificationPortRef io_notification_port_t;
/* private structures */
struct darwin_device_priv {
IOUSBDeviceDescriptor dev_descriptor;
UInt32 location;
char sys_path[21];
usb_device_t **device;
int open_count;
UInt8 first_config, active_config;
};
struct darwin_device_handle_priv {
int is_open;
CFRunLoopSourceRef cfSource;
int fds[2];
struct darwin_interface {
usb_interface_t **interface;
uint8_t num_endpoints;
CFRunLoopSourceRef cfSource;
uint64_t frames[256];
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
} interfaces[USB_MAXINTERFACES];
};
struct darwin_transfer_priv {
/* Isoc */
IOUSBIsocFrame *isoc_framelist;
size_t num_iso_packets;
/* Control */
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
IOUSBDevRequestTO req;
#else
IOUSBDevRequest req;
#endif
/* Bulk */
};
enum {
MESSAGE_DEVICE_GONE,
MESSAGE_ASYNC_IO_COMPLETE
};
#endif

View file

@ -0,0 +1,139 @@
/*
* usbfs header structures
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_USBFS_H
#define LIBUSB_USBFS_H
#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices"
struct usbfs_ctrltransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint32_t timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_bulktransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */
unsigned int ep;
unsigned int len;
unsigned int timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_setinterface {
/* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */
unsigned int interface;
unsigned int altsetting;
};
#define USBFS_MAXDRIVERNAME 255
struct usbfs_getdriver {
unsigned int interface;
char driver[USBFS_MAXDRIVERNAME + 1];
};
#define USBFS_URB_SHORT_NOT_OK 0x01
#define USBFS_URB_ISO_ASAP 0x02
#define USBFS_URB_BULK_CONTINUATION 0x04
#define USBFS_URB_QUEUE_BULK 0x10
#define USBFS_URB_ZERO_PACKET 0x40
enum usbfs_urb_type {
USBFS_URB_TYPE_ISO = 0,
USBFS_URB_TYPE_INTERRUPT = 1,
USBFS_URB_TYPE_CONTROL = 2,
USBFS_URB_TYPE_BULK = 3,
};
struct usbfs_iso_packet_desc {
unsigned int length;
unsigned int actual_length;
unsigned int status;
};
#define MAX_ISO_BUFFER_LENGTH 32768
#define MAX_BULK_BUFFER_LENGTH 16384
#define MAX_CTRL_BUFFER_LENGTH 4096
struct usbfs_urb {
unsigned char type;
unsigned char endpoint;
int status;
unsigned int flags;
void *buffer;
int buffer_length;
int actual_length;
int start_frame;
int number_of_packets;
int error_count;
unsigned int signr;
void *usercontext;
struct usbfs_iso_packet_desc iso_frame_desc[0];
};
struct usbfs_connectinfo {
unsigned int devnum;
unsigned char slow;
};
struct usbfs_ioctl {
int ifno; /* interface 0..N ; negative numbers reserved */
int ioctl_code; /* MUST encode size + direction of data so the
* macros in <asm/ioctl.h> give correct values */
void *data; /* param buffer (in, or out) */
};
struct usbfs_hub_portinfo {
unsigned char numports;
unsigned char port[127]; /* port to device num mapping */
};
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface)
#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int)
#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver)
#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb)
#define IOCTL_USBFS_DISCARDURB _IO('U', 11)
#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *)
#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *)
#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int)
#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int)
#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo)
#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl)
#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo)
#define IOCTL_USBFS_RESET _IO('U', 20)
#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int)
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
#define IOCTL_USBFS_CONNECT _IO('U', 23)
#endif

View file

@ -0,0 +1,10 @@
#ifndef LIBUSB_POLL_POSIX_H
#define LIBUSB_POLL_POSIX_H
#define usbi_write write
#define usbi_read read
#define usbi_close close
#define usbi_pipe pipe
#define usbi_poll poll
#endif /* LIBUSB_POLL_POSIX_H */

View file

@ -0,0 +1,115 @@
/*
* Windows compat: POSIX compatibility wrapper
* Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#pragma once
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#endif
// Handle synchronous completion through the overlapped structure
#if !defined(STATUS_REPARSE) // reuse the REPARSE status code
#define STATUS_REPARSE ((LONG)0x00000104L)
#endif
#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE
#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY)
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
enum windows_version {
WINDOWS_UNSUPPORTED,
WINDOWS_XP,
WINDOWS_2003, // also includes XP 64
WINDOWS_VISTA_AND_LATER,
};
extern enum windows_version windows_version;
#define MAX_FDS 256
#define POLLIN 0x0001 /* There is data to read */
#define POLLPRI 0x0002 /* There is urgent data to read */
#define POLLOUT 0x0004 /* Writing now will not block */
#define POLLERR 0x0008 /* Error condition */
#define POLLHUP 0x0010 /* Hung up */
#define POLLNVAL 0x0020 /* Invalid request: fd not open */
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
// access modes
enum rw_type {
RW_NONE,
RW_READ,
RW_WRITE,
};
// fd struct that can be used for polling on Windows
struct winfd {
int fd; // what's exposed to libusb core
HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it
OVERLAPPED* overlapped; // what will report our I/O status
enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH)
};
extern const struct winfd INVALID_WINFD;
int usbi_pipe(int pipefd[2]);
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout);
ssize_t usbi_write(int fd, const void *buf, size_t count);
ssize_t usbi_read(int fd, void *buf, size_t count);
int usbi_close(int fd);
void init_polling(void);
void exit_polling(void);
struct winfd usbi_create_fd(HANDLE handle, int access_mode);
void usbi_free_fd(int fd);
struct winfd fd_to_winfd(int fd);
struct winfd handle_to_winfd(HANDLE handle);
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
/*
* Timeval operations
*/
#if defined(DDKBUILD)
#include <winsock.h> // defines timeval functions on DDK
#endif
#if !defined(TIMESPEC_TO_TIMEVAL)
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (long)(ts)->tv_sec; \
(tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \
}
#endif
#if !defined(timersub)
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif

View file

@ -0,0 +1,48 @@
/*
* libusb synchronization using POSIX Threads
*
* Copyright (C) 2010 Peter Stuge <peter@stuge.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_POSIX_H
#define LIBUSB_THREADS_POSIX_H
#include <pthread.h>
#define usbi_mutex_static_t pthread_mutex_t
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define usbi_mutex_static_lock pthread_mutex_lock
#define usbi_mutex_static_unlock pthread_mutex_unlock
#define usbi_mutex_t pthread_mutex_t
#define usbi_mutex_init pthread_mutex_init
#define usbi_mutex_lock pthread_mutex_lock
#define usbi_mutex_unlock pthread_mutex_unlock
#define usbi_mutex_trylock pthread_mutex_trylock
#define usbi_mutex_destroy pthread_mutex_destroy
#define usbi_cond_t pthread_cond_t
#define usbi_cond_init pthread_cond_init
#define usbi_cond_wait pthread_cond_wait
#define usbi_cond_timedwait pthread_cond_timedwait
#define usbi_cond_broadcast pthread_cond_broadcast
#define usbi_cond_destroy pthread_cond_destroy
#define usbi_cond_signal pthread_cond_signal
extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
#endif /* LIBUSB_THREADS_POSIX_H */

View file

@ -0,0 +1,86 @@
/*
* libusb synchronization on Microsoft Windows
*
* Copyright (C) 2010 Michael Plante <michael.plante@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_WINDOWS_H
#define LIBUSB_THREADS_WINDOWS_H
#define usbi_mutex_static_t volatile LONG
#define USBI_MUTEX_INITIALIZER 0
#define usbi_mutex_t HANDLE
struct usbi_cond_perthread {
struct list_head list;
DWORD tid;
HANDLE event;
};
struct usbi_cond_t_ {
// Every time a thread touches the CV, it winds up in one of these lists.
// It stays there until the CV is destroyed, even if the thread
// terminates.
struct list_head waiters;
struct list_head not_waiting;
};
typedef struct usbi_cond_t_ usbi_cond_t;
// We *were* getting timespec from pthread.h:
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
#define HAVE_STRUCT_TIMESPEC 1
#define _TIMESPEC_DEFINED 1
struct timespec {
long tv_sec;
long tv_nsec;
};
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
// We *were* getting ETIMEDOUT from pthread.h:
#ifndef ETIMEDOUT
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
#define usbi_mutexattr_t void
#define usbi_condattr_t void
// all Windows mutexes are recursive
#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
int usbi_mutex_init(usbi_mutex_t *mutex,
const usbi_mutexattr_t *attr);
int usbi_mutex_lock(usbi_mutex_t *mutex);
int usbi_mutex_unlock(usbi_mutex_t *mutex);
int usbi_mutex_trylock(usbi_mutex_t *mutex);
int usbi_mutex_destroy(usbi_mutex_t *mutex);
int usbi_cond_init(usbi_cond_t *cond,
const usbi_condattr_t *attr);
int usbi_cond_destroy(usbi_cond_t *cond);
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
const struct timespec *abstime);
int usbi_cond_broadcast(usbi_cond_t *cond);
int usbi_cond_signal(usbi_cond_t *cond);
#endif /* LIBUSB_THREADS_WINDOWS_H */

View file

@ -0,0 +1,608 @@
/*
* Windows backend for libusb 1.0
* Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4214) // bit field types other than int
#pragma warning(disable:4201) // nameless struct/union
#endif
// Windows API default is uppercase - ugh!
#if !defined(bool)
#define bool BOOL
#endif
#if !defined(true)
#define true TRUE
#endif
#if !defined(false)
#define false FALSE
#endif
// Missing from MSVC6 setupapi.h
#if !defined(SPDRP_ADDRESS)
#define SPDRP_ADDRESS 28
#endif
#if !defined(SPDRP_INSTALL_STATE)
#define SPDRP_INSTALL_STATE 34
#endif
#if defined(__CYGWIN__ )
// cygwin produces a warning unless these prototypes are defined
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
extern char *_strdup(const char *strSource);
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
#endif
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_strlen(str) ((str==NULL)?0:strlen(str))
#define safe_sprintf _snprintf
#define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
#define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
static inline void upperize(char* str) {
size_t i;
if (str == NULL) return;
for (i=0; i<safe_strlen(str); i++)
str[i] = (char)toupper((int)str[i]);
}
#define MAX_CTRL_BUFFER_LENGTH 4096
#define MAX_USB_DEVICES 256
#define MAX_USB_STRING_LENGTH 128
#define MAX_GUID_STRING_LENGTH 40
#define MAX_PATH_LENGTH 128
#define MAX_KEY_LENGTH 256
#define MAX_TIMER_SEMAPHORES 128
#define TIMER_REQUEST_RETRY_MS 100
#define ERR_BUFFER_SIZE 256
#define LIST_SEPARATOR ';'
#define HTAB_SIZE 1021
// http://msdn.microsoft.com/en-us/library/ff545978.aspx
// http://msdn.microsoft.com/en-us/library/ff545972.aspx
// http://msdn.microsoft.com/en-us/library/ff545982.aspx
#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER)
const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_DEVICE)
const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_HUB)
const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
#endif
const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
/*
* Multiple USB API backend support
*/
#define USB_API_UNSUPPORTED 0
#define USB_API_HUB 1
#define USB_API_COMPOSITE 2
#define USB_API_WINUSB 3
#define USB_API_MAX 4
#define CLASS_GUID_UNSUPPORTED GUID_NULL
const GUID CLASS_GUID_LIBUSB_WINUSB = { 0x78A1C341, 0x4539, 0x11D3, {0xB8, 0x8D, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71} };
const GUID CLASS_GUID_COMPOSITE = { 0x36FC9E60, 0xC465, 0x11cF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
struct windows_usb_api_backend {
const uint8_t id;
const char* designation;
const GUID *class_guid; // The Class GUID (for fallback in case the driver name cannot be read)
const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
const uint8_t nb_driver_names;
int (*init)(struct libusb_context *ctx);
int (*exit)(void);
int (*open)(struct libusb_device_handle *dev_handle);
void (*close)(struct libusb_device_handle *dev_handle);
int (*claim_interface)(struct libusb_device_handle *dev_handle, int iface);
int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, int iface, int altsetting);
int (*release_interface)(struct libusb_device_handle *dev_handle, int iface);
int (*clear_halt)(struct libusb_device_handle *dev_handle, unsigned char endpoint);
int (*reset_device)(struct libusb_device_handle *dev_handle);
int (*submit_bulk_transfer)(struct usbi_transfer *itransfer);
int (*submit_iso_transfer)(struct usbi_transfer *itransfer);
int (*submit_control_transfer)(struct usbi_transfer *itransfer);
int (*abort_control)(struct usbi_transfer *itransfer);
int (*abort_transfers)(struct usbi_transfer *itransfer);
int (*copy_transfer_data)(struct usbi_transfer *itransfer, uint32_t io_size);
};
extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
#define PRINT_UNSUPPORTED_API(fname) \
usbi_dbg("unsupported API call for '" \
#fname "' (unrecognized device driver)"); \
return LIBUSB_ERROR_NOT_SUPPORTED;
/*
* private structures definition
* with inline pseudo constructors/destructors
*/
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
struct windows_device_priv {
uint8_t depth; // distance to HCD
uint8_t port; // port number on the hub
struct libusb_device *parent_dev; // access to parent is required for usermode ops
char *path; // device interface path
struct windows_usb_api_backend const *apib;
struct {
char *path; // each interface needs a device interface path,
struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
} usb_interface[USB_MAXINTERFACES];
uint8_t composite_api_flags; // composite devices require additional data
uint8_t active_config;
USB_DEVICE_DESCRIPTOR dev_descriptor;
unsigned char **config_descriptor; // list of pointers to the cached config descriptors
};
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) {
return (struct windows_device_priv *)dev->os_priv;
}
static inline void windows_device_priv_init(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
p->depth = 0;
p->port = 0;
p->parent_dev = NULL;
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->composite_api_flags = 0;
p->active_config = 0;
p->config_descriptor = NULL;
memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR));
for (i=0; i<USB_MAXINTERFACES; i++) {
p->usb_interface[i].path = NULL;
p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->usb_interface[i].nb_endpoints = 0;
p->usb_interface[i].endpoint = NULL;
}
}
static inline void windows_device_priv_release(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
safe_free(p->path);
if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) {
for (i=0; i < dev->num_configurations; i++)
safe_free(p->config_descriptor[i]);
}
safe_free(p->config_descriptor);
for (i=0; i<USB_MAXINTERFACES; i++) {
safe_free(p->usb_interface[i].path);
safe_free(p->usb_interface[i].endpoint);
}
}
struct interface_handle_t {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
};
struct windows_device_handle_priv {
int active_interface;
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
static inline struct windows_device_handle_priv *_device_handle_priv(
struct libusb_device_handle *handle)
{
return (struct windows_device_handle_priv *) handle->os_priv;
}
// used for async polling functions
struct windows_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
};
// used to match a device driver (including filter drivers) against a supported API
struct driver_lookup {
char list[MAX_KEY_LENGTH+1];// REG_MULTI_SZ list of services (driver) names
const DWORD reg_prop; // SPDRP registry key to use to retreive list
const char* designation; // internal designation (for debug output)
};
/*
* API macros - from libusb-win32 1.x
*/
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_t)args; \
static __dll_##name##_t prefixname = NULL
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = GetModuleHandleA(#dll); \
if (!h) \
h = LoadLibraryA(#dll); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; }\
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, #name); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, #name "A"); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, #name "W"); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
} while(0)
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
/* OLE32 dependency */
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
/* SetupAPI dependencies */
DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes
*/
typedef DWORD DEVNODE, DEVINST;
typedef DEVNODE *PDEVNODE, *PDEVINST;
typedef DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
#define CR_SUCCESS 0x00000000
#define CR_NO_SUCH_DEVNODE 0x0000000D
#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE
#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG
#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING
#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE
#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT
#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS
#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE
#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE
#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS
#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR
#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR
#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION
#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION
#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE
#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE
#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#define USB_GET_NODE_CONNECTION_NAME 261
#define USB_GET_HUB_CAPABILITIES 271
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
#endif
#if !defined(USB_GET_HUB_CAPABILITIES_EX)
#define USB_GET_HUB_CAPABILITIES_EX 276
#endif
#ifndef METHOD_BUFFERED
#define METHOD_BUFFERED 0
#endif
#ifndef FILE_ANY_ACCESS
#define FILE_ANY_ACCESS 0x00000000
#endif
#ifndef FILE_DEVICE_UNKNOWN
#define FILE_DEVICE_UNKNOWN 0x00000022
#endif
#ifndef FILE_DEVICE_USB
#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
#endif
#ifndef CTL_CODE
#define CTL_CODE(DeviceType, Function, Method, Access)( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#endif
typedef enum USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
typedef enum USB_HUB_NODE {
UsbHub,
UsbMIParent
} USB_HUB_NODE;
/* Cfgmgr32.dll interface */
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_HUB_CAPABILITIES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_ROOT_HUB_NAME \
CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_INFORMATION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_NAME \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Most of the structures below need to be packed
#pragma pack(push, 1)
typedef struct USB_INTERFACE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bInterfaceNumber;
UCHAR bAlternateSetting;
UCHAR bNumEndpoints;
UCHAR bInterfaceClass;
UCHAR bInterfaceSubClass;
UCHAR bInterfaceProtocol;
UCHAR iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT {
struct {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
} req;
USB_CONFIGURATION_DESCRIPTOR data;
} USB_CONFIGURATION_DESCRIPTOR_SHORT;
typedef struct USB_ENDPOINT_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bEndpointAddress;
UCHAR bmAttributes;
USHORT wMaxPacketSize;
UCHAR bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
typedef struct USB_DESCRIPTOR_REQUEST {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
// UCHAR Data[0];
} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
typedef struct USB_HUB_DESCRIPTOR {
UCHAR bDescriptorLength;
UCHAR bDescriptorType;
UCHAR bNumberOfPorts;
USHORT wHubCharacteristics;
UCHAR bPowerOnToPowerGood;
UCHAR bHubControlCurrent;
UCHAR bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
typedef struct USB_ROOT_HUB_NAME {
ULONG ActualLength;
WCHAR RootHubName[1];
} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
typedef struct USB_ROOT_HUB_NAME_FIXED {
ULONG ActualLength;
WCHAR RootHubName[MAX_PATH_LENGTH];
} USB_ROOT_HUB_NAME_FIXED;
typedef struct USB_NODE_CONNECTION_NAME {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[1];
} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
typedef struct USB_NODE_CONNECTION_NAME_FIXED {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[MAX_PATH_LENGTH];
} USB_NODE_CONNECTION_NAME_FIXED;
typedef struct USB_HUB_NAME_FIXED {
union {
USB_ROOT_HUB_NAME_FIXED root;
USB_NODE_CONNECTION_NAME_FIXED node;
} u;
} USB_HUB_NAME_FIXED;
typedef struct USB_HUB_INFORMATION {
USB_HUB_DESCRIPTOR HubDescriptor;
BOOLEAN HubIsBusPowered;
} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
typedef struct USB_MI_PARENT_INFORMATION {
ULONG NumberOfInterfaces;
} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;
typedef struct USB_NODE_INFORMATION {
USB_HUB_NODE NodeType;
union {
USB_HUB_INFORMATION HubInformation;
USB_MI_PARENT_INFORMATION MiParentInformation;
} u;
} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
typedef struct USB_PIPE_INFO {
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
ULONG ScheduleOffset;
} USB_PIPE_INFO, *PUSB_PIPE_INFO;
typedef struct USB_NODE_CONNECTION_INFORMATION_EX {
ULONG ConnectionIndex;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
UCHAR CurrentConfigurationValue;
UCHAR Speed;
BOOLEAN DeviceIsHub;
USHORT DeviceAddress;
ULONG NumberOfOpenPipes;
USB_CONNECTION_STATUS ConnectionStatus;
// USB_PIPE_INFO PipeList[0];
} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
typedef struct USB_HUB_CAP_FLAGS {
ULONG HubIsHighSpeedCapable:1;
ULONG HubIsHighSpeed:1;
ULONG HubIsMultiTtCapable:1;
ULONG HubIsMultiTt:1;
ULONG HubIsRoot:1;
ULONG HubIsArmedWakeOnConnect:1;
ULONG ReservedMBZ:26;
} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS;
typedef struct USB_HUB_CAPABILITIES {
ULONG HubIs2xCapable : 1;
} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES;
typedef struct USB_HUB_CAPABILITIES_EX {
USB_HUB_CAP_FLAGS CapabilityFlags;
} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX;
#pragma pack(pop)
/* winusb.dll interface */
#define SHORT_PACKET_TERMINATE 0x01
#define AUTO_CLEAR_STALL 0x02
#define PIPE_TRANSFER_TIMEOUT 0x03
#define IGNORE_SHORT_PACKETS 0x04
#define ALLOW_PARTIAL_READS 0x05
#define AUTO_FLUSH 0x06
#define RAW_IO 0x07
#define MAXIMUM_TRANSFER_SIZE 0x08
#define AUTO_SUSPEND 0x81
#define SUSPEND_DELAY 0x83
#define DEVICE_SPEED 0x01
#define LowSpeed 0x01
#define FullSpeed 0x02
#define HighSpeed 0x03
typedef enum USBD_PIPE_TYPE {
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt
} USBD_PIPE_TYPE;
typedef struct {
USBD_PIPE_TYPE PipeType;
UCHAR PipeId;
USHORT MaximumPacketSize;
UCHAR Interval;
} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;
#pragma pack(1)
typedef struct {
UCHAR request_type;
UCHAR request;
USHORT value;
USHORT index;
USHORT length;
} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
#pragma pack()
typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
DLL_DECLARE(WINAPI, BOOL, WinUsb_Initialize, (HANDLE, PWINUSB_INTERFACE_HANDLE));
DLL_DECLARE(WINAPI, BOOL, WinUsb_Free, (WINUSB_INTERFACE_HANDLE));
DLL_DECLARE(WINAPI, BOOL, WinUsb_GetAssociatedInterface, (WINUSB_INTERFACE_HANDLE, UCHAR, PWINUSB_INTERFACE_HANDLE));
DLL_DECLARE(WINAPI, BOOL, WinUsb_GetDescriptor, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, USHORT, PUCHAR, ULONG, PULONG));
DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryInterfaceSettings, (WINUSB_INTERFACE_HANDLE, UCHAR, PUSB_INTERFACE_DESCRIPTOR));
DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryDeviceInformation, (WINUSB_INTERFACE_HANDLE, ULONG, PULONG, PVOID));
DLL_DECLARE(WINAPI, BOOL, WinUsb_SetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, WinUsb_GetCurrentAlternateSetting, (WINUSB_INTERFACE_HANDLE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, WinUsb_QueryPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, UCHAR, PWINUSB_PIPE_INFORMATION));
DLL_DECLARE(WINAPI, BOOL, WinUsb_SetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, ULONG, PVOID));
DLL_DECLARE(WINAPI, BOOL, WinUsb_GetPipePolicy, (WINUSB_INTERFACE_HANDLE, UCHAR, ULONG, PULONG, PVOID));
DLL_DECLARE(WINAPI, BOOL, WinUsb_ReadPipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, WinUsb_WritePipe, (WINUSB_INTERFACE_HANDLE, UCHAR, PUCHAR, ULONG, PULONG, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, WinUsb_ControlTransfer, (WINUSB_INTERFACE_HANDLE, WINUSB_SETUP_PACKET, PUCHAR, ULONG, PULONG, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, WinUsb_ResetPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, WinUsb_AbortPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, WinUsb_FlushPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));

View file

@ -0,0 +1,18 @@
/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */
#ifndef LIBUSB_MAJOR
#define LIBUSB_MAJOR 1
#endif
#ifndef LIBUSB_MINOR
#define LIBUSB_MINOR 0
#endif
#ifndef LIBUSB_MICRO
#define LIBUSB_MICRO 9
#endif
/* LIBUSB_NANO may be used for Windows internal versioning. 0 means unused. */
#ifndef LIBUSB_NANO
#define LIBUSB_NANO 0
#endif
/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */
#ifndef LIBUSB_RC
#define LIBUSB_RC ""
#endif

Binary file not shown.

View file

@ -0,0 +1,41 @@
# libusb-1.0.la - a libtool library file
# Generated by libtool (GNU libtool) 2.2.10
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='libusb-1.0.so.0'
# Names of this library.
library_names='libusb-1.0.so.0.1.0 libusb-1.0.so.0 libusb-1.0.so'
# The name of the static archive.
old_library='libusb-1.0.a'
# Linker flags that can not go in dependency_libs.
inherited_linker_flags=' -pthread'
# Libraries that this one depends upon.
dependency_libs=' -lrt'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libusb-1.0.
current=1
age=1
revision=0
# Is this an already installed library?
installed=no
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/usr/local/lib'

View file

@ -0,0 +1,115 @@
/*
* This file is part of the OpenKinect Project. http://www.openkinect.org
*
* Copyright (c) 2011 individual OpenKinect contributors. See the CONTRIB file
* for details.
*
* This code is licensed to you under the terms of the Apache License, version
* 2.0, or, at your option, the terms of the GNU General Public License,
* version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
* or the following URLs:
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/gpl-2.0.txt
*
* If you redistribute this file in source form, modified or unmodified, you
* may:
* 1) Leave this header intact and distribute it under the same terms,
* accompanying it with the APACHE20 and GPL20 files, or
* 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
* 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
* In all cases you must keep the copyright notice intact and include a copy
* of the CONTRIB file.
*
* Binary distributions must follow the binary distribution requirements of
* either License.
*/
#pragma once
#include <libfreenect.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/// Structure to represent a single 16-bit signed little-endian PCM sample.
typedef struct {
int16_t left;
int16_t right;
int16_t center;
int16_t lfe;
int16_t surround_left;
int16_t surround_right;
} freenect_sample_51;
/**
* Typedef for "you wanted this microphone data, here it is" event callbacks.
* TODO: Timestamp details
* The format of the unknown stream is as of yet undetermined.
*
* @param dev Device which triggered this callback
* @param num_samples Number of samples provided in each of the audio data arrays (mic[1-4] and cancelled)
* @param mic1 Microphone data for the leftmost microphone: 32-bit PCM little-endian samples at 16kHz.
* @param mic2 Microphone data for the left-middle microphone: 32-bit PCM little-endian samples at 16kHz.
* @param mic3 Microphone data for the right-middle microphone: 32-bit PCM little-endian samples at 16kHz.
* @param mic4 Microphone data for the rightmost microphone: 32-bit PCM little-endian samples at 16kHz.
* @param cancelled Noise-cancelled audio data: 16-bit PCM little-endian samples at 16kHz.
*/
typedef void (*freenect_audio_in_cb)(freenect_device *dev, int num_samples,
int32_t* mic1, int32_t* mic2,
int32_t* mic3, int32_t* mic4,
int16_t* cancelled, void *unknown/*, timestamp_t timestamp*/);
/**
* Typedef for "you're playing audio, the library needs you to fill up the outgoing audio buffer" event callbacks
* The library will request samples at a rate of 48000Hz.
*
* @param dev Device this callback was triggered for
* @param samples Pointer to the memory where the library expects you to copy the next sample_count freenect_sample_51's to.
* @param sample_count Bidirectional. in: maximum number of samples the driver wants (don't copy in more than this, you'll clobber memory). out: actual number of samples provided to the driver.
*/
typedef void (*freenect_audio_out_cb)(freenect_device *dev, freenect_sample_51* samples, int* sample_count);
/**
* Set the audio in callback. This is the function called when the library
* has new microphone samples. It will be called approximately 62.5 times per
* second (16kHz sample rate, expect 512 samples/callback)
*
* @param dev Device for which to set the callback
* @param callback Callback function to set
*/
FREENECTAPI void freenect_set_audio_in_callback(freenect_device *dev, freenect_audio_in_cb callback);
/**
* Set the audio out callback. This is the "tell me what audio you're about
* to play through the speakers so the Kinect can subtract it out" callback for
* a given device. If you choose not set an audio_out_callback, the library
* will send silence to the Kinect for you - it requires data either way.
*
* @param dev Device for which to set the callback
* @param callback Callback function to set
*/
FREENECTAPI void freenect_set_audio_out_callback(freenect_device *dev, freenect_audio_out_cb callback);
/**
* Start streaming audio for the specified device.
*
* @param dev Device for which to start audio streaming
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_start_audio(freenect_device* dev);
/**
* Stop streaming audio for the specified device.
*
* @param dev Device for which to stop audio streaming
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_stop_audio(freenect_device* dev);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,126 @@
/*
* This file is part of the OpenKinect Project. http://www.openkinect.org
*
* Copyright (c) 2011 individual OpenKinect contributors. See the CONTRIB file
* for details.
*
* This code is licensed to you under the terms of the Apache License, version
* 2.0, or, at your option, the terms of the GNU General Public License,
* version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
* or the following URLs:
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/gpl-2.0.txt
*
* If you redistribute this file in source form, modified or unmodified, you
* may:
* 1) Leave this header intact and distribute it under the same terms,
* accompanying it with the APACHE20 and GPL20 files, or
* 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
* 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
* In all cases you must keep the copyright notice intact and include a copy
* of the CONTRIB file.
*
* Binary distributions must follow the binary distribution requirements of
* either License.
*/
#pragma once
#include <libfreenect.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/// Internal Kinect registration parameters.
/// Structure matches that of the line protocol
/// of the Kinect.
typedef struct {
int32_t dx_center; // not used by mapping algorithm
int32_t ax;
int32_t bx;
int32_t cx;
int32_t dx;
int32_t dx_start;
int32_t ay;
int32_t by;
int32_t cy;
int32_t dy;
int32_t dy_start;
int32_t dx_beta_start;
int32_t dy_beta_start;
int32_t rollout_blank; // not used by mapping algorithm
int32_t rollout_size; // not used by mapping algorithm
int32_t dx_beta_inc;
int32_t dy_beta_inc;
int32_t dxdx_start;
int32_t dxdy_start;
int32_t dydx_start;
int32_t dydy_start;
int32_t dxdxdx_start;
int32_t dydxdx_start;
int32_t dxdxdy_start;
int32_t dydxdy_start;
int32_t back_comp1; // not used by mapping algorithm
int32_t dydydx_start;
int32_t back_comp2; // not used by mapping algorithm
int32_t dydydy_start;
} freenect_reg_info;
/// registration padding info (?)
typedef struct {
uint16_t start_lines;
uint16_t end_lines;
uint16_t cropping_lines;
} freenect_reg_pad_info;
/// internal Kinect zero plane data
typedef struct {
float dcmos_emitter_dist; // Distance between IR camera and IR emitter, in cm.
float dcmos_rcmos_dist; // Distance between IR camera and RGB camera, in cm.
float reference_distance; // The focal length of the IR camera, in mm.
float reference_pixel_size; // The size of a single pixel on the zero plane, in mm.
} freenect_zero_plane_info;
/// all data needed for depth->RGB mapping
typedef struct {
freenect_reg_info reg_info;
freenect_reg_pad_info reg_pad_info;
freenect_zero_plane_info zero_plane_info;
double const_shift;
uint16_t* raw_to_mm_shift;
int32_t* depth_to_rgb_shift;
int32_t (*registration_table)[2]; // A table of 640*480 pairs of x,y values.
// Index first by pixel, then x:0 and y:1.
} freenect_registration;
// These allow clients to export registration parameters; proper docs will
// come later
FREENECTAPI freenect_registration freenect_copy_registration(freenect_device* dev);
FREENECTAPI int freenect_destroy_registration(freenect_registration* reg);
// convenience function to convert a single x-y coordinate pair from camera
// to world coordinates
FREENECTAPI void freenect_camera_to_world(freenect_device* dev,
int cx, int cy, int wz, double* wx, double* wy);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,619 @@
/*
* This file is part of the OpenKinect Project. http://www.openkinect.org
*
* Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
* for details.
*
* This code is licensed to you under the terms of the Apache License, version
* 2.0, or, at your option, the terms of the GNU General Public License,
* version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
* or the following URLs:
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/gpl-2.0.txt
*
* If you redistribute this file in source form, modified or unmodified, you
* may:
* 1) Leave this header intact and distribute it under the same terms,
* accompanying it with the APACHE20 and GPL20 files, or
* 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
* 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
* In all cases you must keep the copyright notice intact and include a copy
* of the CONTRIB file.
*
* Binary distributions must follow the binary distribution requirements of
* either License.
*/
#pragma once
#include <stdint.h>
/* We need struct timeval */
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/time.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define FREENECT_COUNTS_PER_G 819 /**< Ticks per G for accelerometer as set per http://www.kionix.com/Product%20Sheets/KXSD9%20Product%20Brief.pdf */
/// Maximum value that a uint16_t pixel will take on in the buffer of any of the FREENECT_DEPTH_MM or FREENECT_DEPTH_REGISTERED frame callbacks
#define FREENECT_DEPTH_MM_MAX_VALUE 10000
/// Value indicating that this pixel has no data, when using FREENECT_DEPTH_MM or FREENECT_DEPTH_REGISTERED depth modes
#define FREENECT_DEPTH_MM_NO_VALUE 0
/// Maximum value that a uint16_t pixel will take on in the buffer of any of the FREENECT_DEPTH_11BIT, FREENECT_DEPTH_10BIT, FREENECT_DEPTH_11BIT_PACKED, or FREENECT_DEPTH_10BIT_PACKED frame callbacks
#define FREENECT_DEPTH_RAW_MAX_VALUE 2048
/// Value indicating that this pixel has no data, when using FREENECT_DEPTH_11BIT, FREENECT_DEPTH_10BIT, FREENECT_DEPTH_11BIT_PACKED, or FREENECT_DEPTH_10BIT_PACKED
#define FREENECT_DEPTH_RAW_NO_VALUE 2047
/// Flags representing devices to open when freenect_open_device() is called.
/// In particular, this allows libfreenect to grab only a subset of the devices
/// in the Kinect, so you could (for instance) use libfreenect to handle audio
/// and motor support while letting OpenNI have access to the cameras.
/// If a device is not supported on a particular platform, its flag will be ignored.
typedef enum {
FREENECT_DEVICE_MOTOR = 0x01,
FREENECT_DEVICE_CAMERA = 0x02,
FREENECT_DEVICE_AUDIO = 0x04,
} freenect_device_flags;
/// A struct used in enumeration to give access to serial numbers, so you can
/// open a particular device by serial rather than depending on index. This
/// is most useful if you have more than one Kinect.
struct freenect_device_attributes;
struct freenect_device_attributes {
struct freenect_device_attributes *next; /**< Next device in the linked list */
const char* camera_serial; /**< Serial number of this device's camera subdevice */
};
/// Enumeration of available resolutions.
/// Not all available resolutions are actually supported for all video formats.
/// Frame modes may not perfectly match resolutions. For instance,
/// FREENECT_RESOLUTION_MEDIUM is 640x488 for the IR camera.
typedef enum {
FREENECT_RESOLUTION_LOW = 0, /**< QVGA - 320x240 */
FREENECT_RESOLUTION_MEDIUM = 1, /**< VGA - 640x480 */
FREENECT_RESOLUTION_HIGH = 2, /**< SXGA - 1280x1024 */
FREENECT_RESOLUTION_DUMMY = 2147483647, /**< Dummy value to force enum to be 32 bits wide */
} freenect_resolution;
/// Enumeration of video frame information states.
/// See http://openkinect.org/wiki/Protocol_Documentation#RGB_Camera for more information.
typedef enum {
FREENECT_VIDEO_RGB = 0, /**< Decompressed RGB mode (demosaicing done by libfreenect) */
FREENECT_VIDEO_BAYER = 1, /**< Bayer compressed mode (raw information from camera) */
FREENECT_VIDEO_IR_8BIT = 2, /**< 8-bit IR mode */
FREENECT_VIDEO_IR_10BIT = 3, /**< 10-bit IR mode */
FREENECT_VIDEO_IR_10BIT_PACKED = 4, /**< 10-bit packed IR mode */
FREENECT_VIDEO_YUV_RGB = 5, /**< YUV RGB mode */
FREENECT_VIDEO_YUV_RAW = 6, /**< YUV Raw mode */
FREENECT_VIDEO_DUMMY = 2147483647, /**< Dummy value to force enum to be 32 bits wide */
} freenect_video_format;
/// Enumeration of depth frame states
/// See http://openkinect.org/wiki/Protocol_Documentation#RGB_Camera for more information.
typedef enum {
FREENECT_DEPTH_11BIT = 0, /**< 11 bit depth information in one uint16_t/pixel */
FREENECT_DEPTH_10BIT = 1, /**< 10 bit depth information in one uint16_t/pixel */
FREENECT_DEPTH_11BIT_PACKED = 2, /**< 11 bit packed depth information */
FREENECT_DEPTH_10BIT_PACKED = 3, /**< 10 bit packed depth information */
FREENECT_DEPTH_REGISTERED = 4, /**< processed depth data in mm, aligned to 640x480 RGB */
FREENECT_DEPTH_MM = 5, /**< depth to each pixel in mm, but left unaligned to RGB image */
FREENECT_DEPTH_DUMMY = 2147483647, /**< Dummy value to force enum to be 32 bits wide */
} freenect_depth_format;
/// Structure to give information about the width, height, bitrate,
/// framerate, and buffer size of a frame in a particular mode, as
/// well as the total number of bytes needed to hold a single frame.
typedef struct {
uint32_t reserved; /**< unique ID used internally. The meaning of values may change without notice. Don't touch or depend on the contents of this field. We mean it. */
freenect_resolution resolution; /**< Resolution this freenect_frame_mode describes, should you want to find it again with freenect_find_*_frame_mode(). */
union {
int32_t dummy;
freenect_video_format video_format;
freenect_depth_format depth_format;
}; /**< The video or depth format that this freenect_frame_mode describes. The caller should know which of video_format or depth_format to use, since they called freenect_get_*_frame_mode() */
int32_t bytes; /**< Total buffer size in bytes to hold a single frame of data. Should be equivalent to width * height * (data_bits_per_pixel+padding_bits_per_pixel) / 8 */
int16_t width; /**< Width of the frame, in pixels */
int16_t height; /**< Height of the frame, in pixels */
int8_t data_bits_per_pixel; /**< Number of bits of information needed for each pixel */
int8_t padding_bits_per_pixel; /**< Number of bits of padding for alignment used for each pixel */
int8_t framerate; /**< Approximate expected frame rate, in Hz */
int8_t is_valid; /**< If 0, this freenect_frame_mode is invalid and does not describe a supported mode. Otherwise, the frame_mode is valid. */
} freenect_frame_mode;
/// Enumeration of LED states
/// See http://openkinect.org/wiki/Protocol_Documentation#Setting_LED for more information.
typedef enum {
LED_OFF = 0, /**< Turn LED off */
LED_GREEN = 1, /**< Turn LED to Green */
LED_RED = 2, /**< Turn LED to Red */
LED_YELLOW = 3, /**< Turn LED to Yellow */
LED_BLINK_GREEN = 4, /**< Make LED blink Green */
// 5 is same as 4, LED blink Green
LED_BLINK_RED_YELLOW = 6, /**< Make LED blink Red/Yellow */
} freenect_led_options;
/// Enumeration of tilt motor status
typedef enum {
TILT_STATUS_STOPPED = 0x00, /**< Tilt motor is stopped */
TILT_STATUS_LIMIT = 0x01, /**< Tilt motor has reached movement limit */
TILT_STATUS_MOVING = 0x04, /**< Tilt motor is currently moving to new position */
} freenect_tilt_status_code;
/// Data from the tilt motor and accelerometer
typedef struct {
int16_t accelerometer_x; /**< Raw accelerometer data for X-axis, see FREENECT_COUNTS_PER_G for conversion */
int16_t accelerometer_y; /**< Raw accelerometer data for Y-axis, see FREENECT_COUNTS_PER_G for conversion */
int16_t accelerometer_z; /**< Raw accelerometer data for Z-axis, see FREENECT_COUNTS_PER_G for conversion */
int8_t tilt_angle; /**< Raw tilt motor angle encoder information */
freenect_tilt_status_code tilt_status; /**< State of the tilt motor (stopped, moving, etc...) */
} freenect_raw_tilt_state;
struct _freenect_context;
typedef struct _freenect_context freenect_context; /**< Holds information about the usb context. */
struct _freenect_device;
typedef struct _freenect_device freenect_device; /**< Holds device information. */
// usb backend specific section
typedef void freenect_usb_context; /**< Holds libusb-1.0 context */
//
/// If Win32, export all functions for DLL usage
#ifndef _WIN32
#define FREENECTAPI /**< DLLExport information for windows, set to nothing on other platforms */
#else
/**< DLLExport information for windows, set to nothing on other platforms */
#ifdef __cplusplus
#define FREENECTAPI extern "C" __declspec(dllexport)
#else
// this is required when building from a Win32 port of gcc without being
// forced to compile all of the library files (.c) with g++...
#define FREENECTAPI __declspec(dllexport)
#endif
#endif
/// Enumeration of message logging levels
typedef enum {
FREENECT_LOG_FATAL = 0, /**< Log for crashing/non-recoverable errors */
FREENECT_LOG_ERROR, /**< Log for major errors */
FREENECT_LOG_WARNING, /**< Log for warning messages */
FREENECT_LOG_NOTICE, /**< Log for important messages */
FREENECT_LOG_INFO, /**< Log for normal messages */
FREENECT_LOG_DEBUG, /**< Log for useful development messages */
FREENECT_LOG_SPEW, /**< Log for slightly less useful messages */
FREENECT_LOG_FLOOD, /**< Log EVERYTHING. May slow performance. */
} freenect_loglevel;
/**
* Initialize a freenect context and do any setup required for
* platform specific USB libraries.
*
* @param ctx Address of pointer to freenect context struct to allocate and initialize
* @param usb_ctx USB context to initialize. Can be NULL if not using multiple contexts.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx);
/**
* Closes the device if it is open, and frees the context
*
* @param ctx freenect context to close/free
*
* @return 0 on success
*/
FREENECTAPI int freenect_shutdown(freenect_context *ctx);
/// Typedef for logging callback functions
typedef void (*freenect_log_cb)(freenect_context *dev, freenect_loglevel level, const char *msg);
/**
* Set the log level for the specified freenect context
*
* @param ctx context to set log level for
* @param level log level to use (see freenect_loglevel enum)
*/
FREENECTAPI void freenect_set_log_level(freenect_context *ctx, freenect_loglevel level);
/**
* Callback for log messages (i.e. for rerouting to a file instead of
* stdout)
*
* @param ctx context to set log callback for
* @param cb callback function pointer
*/
FREENECTAPI void freenect_set_log_callback(freenect_context *ctx, freenect_log_cb cb);
/**
* Calls the platform specific usb event processor
*
* @param ctx context to process events for
*
* @return 0 on success, other values on error, platform/library dependant
*/
FREENECTAPI int freenect_process_events(freenect_context *ctx);
/**
* Calls the platform specific usb event processor until either an event occurs
* or the timeout parameter time has passed. If a zero timeval is passed, this
* function will handle any already-pending events, then return immediately.
*
* @param ctx Context to process events for
* @param timeout Pointer to a timeval containing the maximum amount of time to block waiting for events, or zero for nonblocking mode
*
* @return 0 on success, other values on error, platform/library dependant
*/
FREENECTAPI int freenect_process_events_timeout(freenect_context *ctx, struct timeval* timeout);
/**
* Return the number of kinect devices currently connected to the
* system
*
* @param ctx Context to access device count through
*
* @return Number of devices connected, < 0 on error
*/
FREENECTAPI int freenect_num_devices(freenect_context *ctx);
/**
* Scans for kinect devices and produces a linked list of their attributes
* (namely, serial numbers), returning the number of devices.
*
* @param ctx Context to scan for kinect devices with
* @param attribute_list Pointer to where this function will store the resultant linked list
*
* @return Number of devices connected, < 0 on error
*/
FREENECTAPI int freenect_list_device_attributes(freenect_context *ctx, struct freenect_device_attributes** attribute_list);
/**
* Free the linked list produced by freenect_list_device_attributes().
*
* @param attribute_list Linked list of attributes to free.
*/
FREENECTAPI void freenect_free_device_attributes(struct freenect_device_attributes* attribute_list);
/**
* Answer which subdevices this library supports. This is most useful for
* wrappers trying to determine whether the underlying library was built with
* audio support or not, so the wrapper can avoid calling functions that do not
* exist.
*
* @return Flags representing the subdevices that the library supports opening (see freenect_device_flags)
*/
FREENECTAPI int freenect_supported_subdevices(void);
/**
* Set which subdevices any subsequent calls to freenect_open_device()
* should open. This will not affect devices which have already been
* opened. The default behavior, should you choose not to call this
* function at all, is to open all supported subdevices - motor, cameras,
* and audio, if supported on the platform.
*
* @param ctx Context to set future subdevice selection for
* @param subdevs Flags representing the subdevices to select
*/
FREENECTAPI void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs);
/**
* Opens a kinect device via a context. Index specifies the index of
* the device on the current state of the bus. Bus resets may cause
* indexes to shift.
*
* @param ctx Context to open device through
* @param dev Device structure to assign opened device to
* @param index Index of the device on the bus
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index);
/**
* Opens a kinect device (via a context) associated with a particular camera
* subdevice serial number. This function will fail if no device with a
* matching serial number is found.
*
* @param ctx Context to open device through
* @param dev Device structure to assign opened device to
* @param camera_serial Null-terminated ASCII string containing the serial number of the camera subdevice in the device to open
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_open_device_by_camera_serial(freenect_context *ctx, freenect_device **dev, const char* camera_serial);
/**
* Closes a device that is currently open
*
* @param dev Device to close
*
* @return 0 on success
*/
FREENECTAPI int freenect_close_device(freenect_device *dev);
/**
* Set the device user data, for passing generic information into
* callbacks
*
* @param dev Device to attach user data to
* @param user User data to attach
*/
FREENECTAPI void freenect_set_user(freenect_device *dev, void *user);
/**
* Retrieve the pointer to user data from the device struct
*
* @param dev Device from which to get user data
*
* @return Pointer to user data
*/
FREENECTAPI void *freenect_get_user(freenect_device *dev);
/// Typedef for depth image received event callbacks
typedef void (*freenect_depth_cb)(freenect_device *dev, void *depth, uint32_t timestamp);
/// Typedef for video image received event callbacks
typedef void (*freenect_video_cb)(freenect_device *dev, void *video, uint32_t timestamp);
/**
* Set callback for depth information received event
*
* @param dev Device to set callback for
* @param cb Function pointer for processing depth information
*/
FREENECTAPI void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb);
/**
* Set callback for video information received event
*
* @param dev Device to set callback for
* @param cb Function pointer for processing video information
*/
FREENECTAPI void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb);
/**
* Set the buffer to store depth information to. Size of buffer is
* dependant on depth format. See FREENECT_DEPTH_*_SIZE defines for
* more information.
*
* @param dev Device to set depth buffer for.
* @param buf Buffer to store depth information to.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_set_depth_buffer(freenect_device *dev, void *buf);
/**
* Set the buffer to store depth information to. Size of buffer is
* dependant on video format. See FREENECT_VIDEO_*_SIZE defines for
* more information.
*
* @param dev Device to set video buffer for.
* @param buf Buffer to store video information to.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_set_video_buffer(freenect_device *dev, void *buf);
/**
* Start the depth information stream for a device.
*
* @param dev Device to start depth information stream for.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_start_depth(freenect_device *dev);
/**
* Start the video information stream for a device.
*
* @param dev Device to start video information stream for.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_start_video(freenect_device *dev);
/**
* Stop the depth information stream for a device
*
* @param dev Device to stop depth information stream on.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_stop_depth(freenect_device *dev);
/**
* Stop the video information stream for a device
*
* @param dev Device to stop video information stream on.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_stop_video(freenect_device *dev);
/**
* Updates the accelerometer state using a blocking control message
* call.
*
* @param dev Device to get accelerometer data from
*
* @return 0 on success, < 0 on error. Accelerometer data stored to
* device struct.
*/
FREENECTAPI int freenect_update_tilt_state(freenect_device *dev);
/**
* Retrieve the tilt state from a device
*
* @param dev Device to retrieve tilt state from
*
* @return The tilt state struct of the device
*/
FREENECTAPI freenect_raw_tilt_state* freenect_get_tilt_state(freenect_device *dev);
/**
* Return the tilt state, in degrees with respect to the horizon
*
* @param state The tilt state struct from a device
*
* @return Current degree of tilt of the device
*/
FREENECTAPI double freenect_get_tilt_degs(freenect_raw_tilt_state *state);
/**
* Set the tilt state of the device, in degrees with respect to the
* horizon. Uses blocking control message call to update
* device. Function return does not reflect state of device, device
* may still be moving to new position after the function returns. Use
* freenect_get_tilt_status() to find current movement state.
*
* @param dev Device to set tilt state
* @param angle Angle the device should tilt to
*
* @return 0 on success, < 0 on error.
*/
FREENECTAPI int freenect_set_tilt_degs(freenect_device *dev, double angle);
/**
* Return the movement state of the tilt motor (moving, stopped, etc...)
*
* @param state Raw state struct to get the tilt status code from
*
* @return Status code of the tilt device. See
* freenect_tilt_status_code enum for more info.
*/
FREENECTAPI freenect_tilt_status_code freenect_get_tilt_status(freenect_raw_tilt_state *state);
/**
* Set the state of the LED. Uses blocking control message call to
* update device.
*
* @param dev Device to set the LED state
* @param option LED state to set on device. See freenect_led_options enum.
*
* @return 0 on success, < 0 on error
*/
FREENECTAPI int freenect_set_led(freenect_device *dev, freenect_led_options option);
/**
* Get the axis-based gravity adjusted accelerometer state, as laid
* out via the accelerometer data sheet, which is available at
*
* http://www.kionix.com/Product%20Sheets/KXSD9%20Product%20Brief.pdf
*
* @param state State to extract accelerometer data from
* @param x Stores X-axis accelerometer state
* @param y Stores Y-axis accelerometer state
* @param z Stores Z-axis accelerometer state
*/
FREENECTAPI void freenect_get_mks_accel(freenect_raw_tilt_state *state, double* x, double* y, double* z);
/**
* Get the number of video camera modes supported by the driver. This includes both RGB and IR modes.
*
* @return Number of video modes supported by the driver
*/
FREENECTAPI int freenect_get_video_mode_count();
/**
* Get the frame descriptor of the nth supported video mode for the
* video camera.
*
* @param mode_num Which of the supported modes to return information about
*
* @return A freenect_frame_mode describing the nth video mode
*/
FREENECTAPI freenect_frame_mode freenect_get_video_mode(int mode_num);
/**
* Get the frame descriptor of the current video mode for the specified
* freenect device.
*
* @param dev Which device to return the currently-set video mode for
*
* @return A freenect_frame_mode describing the current video mode of the specified device
*/
FREENECTAPI freenect_frame_mode freenect_get_current_video_mode(freenect_device *dev);
/**
* Convenience function to return a mode descriptor matching the
* specified resolution and video camera pixel format, if one exists.
*
* @param res Resolution desired
* @param fmt Pixel format desired
*
* @return A freenect_frame_mode that matches the arguments specified, if such a valid mode exists; otherwise, an invalid freenect_frame_mode.
*/
FREENECTAPI freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt);
/**
* Sets the current video mode for the specified device. If the
* freenect_frame_mode specified is not one provided by the driver
* e.g. from freenect_get_video_mode() or freenect_find_video_mode()
* then behavior is undefined. The current video mode cannot be
* changed while streaming is active.
*
* @param dev Device for which to set the video mode
* @param mode Frame mode to set
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_set_video_mode(freenect_device* dev, freenect_frame_mode mode);
/**
* Get the number of depth camera modes supported by the driver. This includes both RGB and IR modes.
*
* @return Number of depth modes supported by the driver
*/
FREENECTAPI int freenect_get_depth_mode_count();
/**
* Get the frame descriptor of the nth supported depth mode for the
* depth camera.
*
* @param mode_num Which of the supported modes to return information about
*
* @return A freenect_frame_mode describing the nth depth mode
*/
FREENECTAPI freenect_frame_mode freenect_get_depth_mode(int mode_num);
/**
* Get the frame descriptor of the current depth mode for the specified
* freenect device.
*
* @param dev Which device to return the currently-set depth mode for
*
* @return A freenect_frame_mode describing the current depth mode of the specified device
*/
FREENECTAPI freenect_frame_mode freenect_get_current_depth_mode(freenect_device *dev);
/**
* Convenience function to return a mode descriptor matching the
* specified resolution and depth camera pixel format, if one exists.
*
* @param res Resolution desired
* @param fmt Pixel format desired
*
* @return A freenect_frame_mode that matches the arguments specified, if such a valid mode exists; otherwise, an invalid freenect_frame_mode.
*/
FREENECTAPI freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt);
/**
* Sets the current depth mode for the specified device. The mode
* cannot be changed while streaming is active.
*
* @param dev Device for which to set the depth mode
* @param mode Frame mode to set
*
* @return 0 on success, < 0 if error
*/
FREENECTAPI int freenect_set_depth_mode(freenect_device* dev, const freenect_frame_mode mode);
#ifdef __cplusplus
}
#endif

Binary file not shown.

Binary file not shown.

1
interface/external/skeltrack/AUTHORS vendored Normal file
View file

@ -0,0 +1 @@
Joaquim Rocha <jrocha@igalia.com> - Creator

View file

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8)
include_directories(include)
# grab the implementation and header files from src dirs
file(GLOB SKELTRACK_SRCS src/*.c include/*.h)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB2 glib-2.0)
string(REPLACE ";" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GLIB2_STATIC_CFLAGS} ${GLIB2_STATIC_LDFLAGS}")
message("${CMAKE_C_FLAGS}")
add_library(skeltrack ${SKELTRACK_SRCS})

165
interface/external/skeltrack/COPYING vendored Normal file
View file

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View file

@ -0,0 +1,90 @@
/*
* skeltrak-joint.h
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 3, or (at your option) any later version as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#ifndef __SKELTRACK_JOINT_H__
#define __SKELTRACK_JOINT_H__
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
#define SKELTRACK_TYPE_JOINT (skeltrack_joint_get_type ())
#define SKELTRACK_JOINT_MAX_JOINTS 7
typedef struct _SkeltrackJoint SkeltrackJoint;
typedef SkeltrackJoint **SkeltrackJointList;
/**
* SkeltrackJointId:
* @SKELTRACK_JOINT_ID_HEAD: The head
* @SKELTRACK_JOINT_ID_LEFT_SHOULDER: The left shoulder
* @SKELTRACK_JOINT_ID_RIGHT_SHOULDER: The right shoulder
* @SKELTRACK_JOINT_ID_LEFT_ELBOW: The left elbow
* @SKELTRACK_JOINT_ID_RIGHT_ELBOW: The right elbow
* @SKELTRACK_JOINT_ID_LEFT_HAND: The left hand
* @SKELTRACK_JOINT_ID_RIGHT_HAND: The right hand
*
* Available joint ids.
**/
typedef enum {
SKELTRACK_JOINT_ID_HEAD,
SKELTRACK_JOINT_ID_LEFT_SHOULDER,
SKELTRACK_JOINT_ID_RIGHT_SHOULDER,
SKELTRACK_JOINT_ID_LEFT_ELBOW,
SKELTRACK_JOINT_ID_RIGHT_ELBOW,
SKELTRACK_JOINT_ID_LEFT_HAND,
SKELTRACK_JOINT_ID_RIGHT_HAND
} SkeltrackJointId;
/**
* SkeltrackJoint:
* @id: The id of the joint
* @x: The x coordinate of the joint in the space (in mm)
* @y: The y coordinate of the joint in the space (in mm)
* @z: The z coordinate of the joint in the space (in mm)
* @screen_x: The x coordinate of the joint in the screen (in pixels)
* @screen_y: The y coordinate of the joint in the screen (in pixels)
**/
struct _SkeltrackJoint
{
SkeltrackJointId id;
gint x;
gint y;
gint z;
gint screen_x;
gint screen_y;
};
GType skeltrack_joint_get_type (void);
gpointer skeltrack_joint_copy (SkeltrackJoint *joint);
void skeltrack_joint_free (SkeltrackJoint *joint);
void skeltrack_joint_list_free (SkeltrackJointList list);
SkeltrackJointList skeltrack_joint_list_new (void);
SkeltrackJoint * skeltrack_joint_list_get_joint (SkeltrackJointList list,
SkeltrackJointId id);
G_END_DECLS
#endif /* __SKELTRACK_JOINT_H__ */

View file

@ -0,0 +1,95 @@
/*
* skeltrack.h
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 3, or (at your option) any later version as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#ifndef __SKELTRACK_SKELETON_H__
#define __SKELTRACK_SKELETON_H__
#include <skeltrack-joint.h>
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS
#define SKELTRACK_TYPE_SKELETON (skeltrack_skeleton_get_type ())
#define SKELTRACK_SKELETON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKELTRACK_TYPE_SKELETON, SkeltrackSkeleton))
#define SKELTRACK_SKELETON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKELTRACK_TYPE_SKELETON, SkeltrackSkeletonClass))
#define SKELTRACK_IS_SKELETON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKELTRACK_TYPE_SKELETON))
#define SKELTRACK_IS_SKELETON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKELTRACK_TYPE_SKELETON))
#define SKELTRACK_SKELETON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKELTRACK_TYPE_SKELETON, SkeltrackSkeletonClass))
typedef struct _SkeltrackSkeleton SkeltrackSkeleton;
typedef struct _SkeltrackSkeletonClass SkeltrackSkeletonClass;
typedef struct _SkeltrackSkeletonPrivate SkeltrackSkeletonPrivate;
struct _SkeltrackSkeleton
{
GObject parent;
/*< private >*/
SkeltrackSkeletonPrivate *priv;
};
/**
* SkeltrackSkeletonClass:
**/
struct _SkeltrackSkeletonClass
{
GObjectClass parent_class;
};
GType skeltrack_skeleton_get_type (void) G_GNUC_CONST;
SkeltrackSkeleton * skeltrack_skeleton_new (void);
void skeltrack_skeleton_track_joints (SkeltrackSkeleton *self,
guint16 *buffer,
guint width,
guint height,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
SkeltrackJointList skeltrack_skeleton_track_joints_finish (SkeltrackSkeleton *self,
GAsyncResult *result,
GError **error);
SkeltrackJointList skeltrack_skeleton_track_joints_sync (SkeltrackSkeleton *self,
guint16 *buffer,
guint width,
guint height,
GCancellable *cancellable,
GError **error);
void skeltrack_skeleton_get_focus_point (SkeltrackSkeleton *self,
gint *x,
gint *y,
gint *z);
void skeltrack_skeleton_set_focus_point (SkeltrackSkeleton *self,
gint x,
gint y,
gint z);
G_END_DECLS
#endif /* __SKELTRACK_SKELETON_H__ */

View file

@ -0,0 +1,36 @@
/*
* skeltrack-smooth.h
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#include "skeltrack-joint.h"
typedef struct {
SkeltrackJointList smoothed_joints;
SkeltrackJointList trend_joints;
guint joints_persistency;
gfloat smoothing_factor;
guint joints_persistency_counter[SKELTRACK_JOINT_MAX_JOINTS];
} SmoothData;
void reset_joints_persistency_counter (SmoothData *smooth_data);
void smooth_joints (SmoothData *data,
SkeltrackJointList new_joints);

View file

@ -0,0 +1,127 @@
/*
* skeltrack-util.h
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#include <glib.h>
#include "skeltrack-joint.h"
typedef struct _Label Label;
typedef struct _Node Node;
struct _Label {
gint index;
Label *parent;
GList *nodes;
Node *bridge_node;
Node *to_node;
gint lower_screen_y;
gint higher_z;
gint lower_z;
gdouble normalized_num_nodes;
};
struct _Node {
gint i;
gint j;
gint x;
gint y;
gint z;
GList *neighbors;
GList *linked_nodes;
Label *label;
};
Node * get_closest_node_to_joint (GList *extremas,
SkeltrackJoint *joint,
gint *distance);
Node * get_closest_node (GList *node_list, Node *from);
Node * get_closest_torso_node (GList *node_list,
Node *from,
Node *head);
Label * get_main_component (GList *node_list,
Node *from,
gdouble min_normalized_nr_nodes);
Label * label_find (Label *label);
void label_union (Label *a, Label *b);
gint get_distance (Node *a, Node *b);
void free_label (Label *label);
void clean_labels (GList *labels);
void free_node (Node *node,
gboolean unlink_node_first);
void clean_nodes (GList *nodes);
GList * remove_nodes_with_label (GList *nodes,
Node **node_matrix,
gint width,
Label *label);
Label * get_lowest_index_label (Label **neighbor_labels);
Label * new_label (gint index);
void join_components_to_main (GList *nodes,
Label *lowest_component_label,
guint horizontal_max_distance,
guint depth_max_distance,
guint graph_distance_threshold);
void set_joint_from_node (SkeltrackJointList *joints,
Node *node,
SkeltrackJointId id,
gint dimension_reduction);
gint * create_new_dist_matrix (gint matrix_size);
gboolean dijkstra_to (GList *nodes,
Node *source,
Node *target,
gint width,
gint height,
gint *distances,
Node **previous);
void convert_screen_coords_to_mm (guint width,
guint height,
guint dimension_reduction,
guint i,
guint j,
gint z,
gint *x,
gint *y);
void convert_mm_to_screen_coords (guint width,
guint height,
guint dimension_reduction,
gint x,
gint y,
gint z,
guint *i,
guint *j);

View file

@ -0,0 +1,28 @@
/*
* skeltrack.h
*
* skeltrack - A GObject wrapper of the libfreenect library
* Copyright (C) 2011 Igalia S.L.
*
* Authors:
* Joaquim Manuel Pereira Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 3, or (at your option) any later version as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#ifndef __SKELTRACK_H__
#define __SKELTRACK_H__
#include <skeltrack-skeleton.h>
#endif /* __SKELTRACK_H__ */

Binary file not shown.

View file

@ -0,0 +1,159 @@
/*
* skeltrack-joint.c
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
/**
* SECTION:skeltrack-joint
* @short_description: Data structure that holds information about
* a skeleton joint.
*
* A #SkeltrackJoint is built automatically by #SkeltrackSkeleton when
* it finds a skeleton joint and can be used to get information about it.
* Each #SkeltrackJoint holds an id, given by #SkeltrackJointId that indicates
* which of the human skeleton joints it represents.
*
* Spacial information about a joint is given by the @x, @y and @z coordinates.
* To represent the joint in a 2D, the variables @screen_x and
* @screen_y will indicate the joint's position in the screen and are calculated
* taking into account the #SkeltrackSkeleton:dimension-reduction (it will
* be multiplied by this value).
*
* The tracked list of joints is represented by #SkeltrackJointList and given
* by skeltrack_skeleton_track_joints_finish().
* To get a #SkeltrackJoint from a #SkeltrackJointList object, use the
* skeltrack_joint_list_get_joint() indicating the needed #SkeltrackJointId.
*
* A #SkeltrackJointList can be freed by using skeltrack_joint_list_free().
* A #SkeltrackJoint can be copied by skeltrack_joint_copy() and freed by
* skeltrack_joint_free().
**/
#include <string.h>
#include "skeltrack-joint.h"
/**
* skeltrack_joint_get_type:
*
* Returns: The registered #GType for #SkeltrackJoint boxed type
**/
GType
skeltrack_joint_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0))
type = g_boxed_type_register_static ("SkeltrackJoint",
(GBoxedCopyFunc) skeltrack_joint_copy,
(GBoxedFreeFunc) skeltrack_joint_free);
return type;
}
/**
* skeltrack_joint_copy:
* @joint: The #SkeltrackJoint to copy
*
* Makes an exact copy of a #SkeltrackJoint object.
*
* Returns: (transfer full): A newly created #SkeltrackJoint. Use
* skeltrack_joint_free() to free it.
**/
gpointer
skeltrack_joint_copy (SkeltrackJoint *joint)
{
SkeltrackJoint *new_joint;
if (joint == NULL)
return NULL;
new_joint = g_slice_new0 (SkeltrackJoint);
memcpy (new_joint, joint, sizeof (SkeltrackJoint));
return new_joint;
}
/**
* skeltrack_joint_free:
* @joint: The #SkeltrackJoint to free
*
* Frees a #SkeltrackJoint object.
**/
void
skeltrack_joint_free (SkeltrackJoint *joint)
{
g_slice_free (SkeltrackJoint, joint);
}
/**
* skeltrack_joint_list_free:
* @list: The #SkeltrackJointList to free
*
* Frees a #SkeltrackJointList object and each #SkeltrackJoint
* in it.
**/
void
skeltrack_joint_list_free (SkeltrackJointList list)
{
gint i;
if (list == NULL)
return;
for (i = 0; i < SKELTRACK_JOINT_MAX_JOINTS; i++)
{
g_slice_free (SkeltrackJoint, list[i]);
}
g_slice_free1 (SKELTRACK_JOINT_MAX_JOINTS * sizeof (SkeltrackJoint *), list);
}
/**
* skeltrack_joint_list_get_joint:
* @list: The #SkeltrackJointList
* @id: The #SkeltrackJointId of the joint to get
*
* Gets a joint from a list of skeleton joints. The joint
* returned needs to be freed by using skeltrack_joint_free() or,
* alternatively, the whole list and its joints can be freed by using
* skeltrack_joint_list_free().
*
* Returns: (transfer full): The #SkeltrackJoint that corresponds to
* the given @id or %NULL if that joint wasn't found.
**/
SkeltrackJoint *
skeltrack_joint_list_get_joint (SkeltrackJointList list, SkeltrackJointId id)
{
return list[id];
}
/**
* skeltrack_joint_list_new:
*
* Created a new list of #SkeltrackJointsList with its joints as #NULL.
* When it is no longer needed, free it with skeltrack_joint_list_free().
*
* Returns: (transfer full): A newly allocated #SkeltrackJointList
**/
SkeltrackJointList
skeltrack_joint_list_new (void)
{
return (SkeltrackJointList) g_slice_alloc0 (SKELTRACK_JOINT_MAX_JOINTS *
sizeof (SkeltrackJoint *));
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,226 @@
/*
* skeltrack-smooth.c
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#include <glib.h>
#include "skeltrack-smooth.h"
static gfloat
holt_double_exp_formula_st (gfloat alpha,
gfloat previous_trend,
gfloat current_value,
gfloat previous_smoothed_value)
{
return alpha * current_value +
(1.0 - alpha) * (previous_smoothed_value + previous_trend);
}
static gfloat
holt_double_exp_formula_bt (gfloat beta,
gfloat previous_trend,
gfloat current_smoothed_value,
gfloat previous_smoothed_value)
{
return beta * (current_smoothed_value - previous_smoothed_value) +
(1.0 - beta) * previous_trend;
}
static void
holt_double_exp_joint (gfloat alpha,
gfloat beta,
SkeltrackJoint *smoothed_joint,
SkeltrackJoint *current_joint,
SkeltrackJoint *trend_joint)
{
gfloat new_x, new_y, new_z, new_screen_x, new_screen_y;
new_x = holt_double_exp_formula_st (alpha,
trend_joint->x,
current_joint->x,
smoothed_joint->x);
new_y = holt_double_exp_formula_st (alpha,
trend_joint->y,
current_joint->y,
smoothed_joint->y);
new_z = holt_double_exp_formula_st (alpha,
trend_joint->z,
current_joint->z,
smoothed_joint->z);
new_screen_x = holt_double_exp_formula_st (alpha,
trend_joint->screen_x,
current_joint->screen_x,
smoothed_joint->screen_x);
new_screen_y = holt_double_exp_formula_st (alpha,
trend_joint->screen_y,
current_joint->screen_y,
smoothed_joint->screen_y);
trend_joint->x = holt_double_exp_formula_bt (beta,
trend_joint->x,
new_x,
smoothed_joint->x);
trend_joint->y = holt_double_exp_formula_bt (beta,
trend_joint->y,
new_y,
smoothed_joint->y);
trend_joint->z = holt_double_exp_formula_bt (beta,
trend_joint->z,
new_z,
smoothed_joint->z);
trend_joint->screen_x = holt_double_exp_formula_bt (beta,
trend_joint->screen_x,
new_screen_x,
smoothed_joint->screen_x);
trend_joint->screen_y = holt_double_exp_formula_bt (beta,
trend_joint->screen_y,
new_screen_y,
smoothed_joint->screen_y);
smoothed_joint->x = new_x;
smoothed_joint->y = new_y;
smoothed_joint->z = new_z;
smoothed_joint->screen_x = new_screen_x;
smoothed_joint->screen_y = new_screen_y;
}
void
reset_joints_persistency_counter (SmoothData *smooth_data)
{
guint i;
for (i = 0; i < SKELTRACK_JOINT_MAX_JOINTS; i++)
{
smooth_data->joints_persistency_counter[i] =
smooth_data->joints_persistency;
}
}
static void
decrease_joints_persistency (SmoothData *smooth_data)
{
guint i;
for (i = 0; i < SKELTRACK_JOINT_MAX_JOINTS; i++)
{
SkeltrackJoint *smoothed_joint = NULL;
SkeltrackJoint *trend_joint = NULL;
if (smooth_data->smoothed_joints)
smoothed_joint = smooth_data->smoothed_joints[i];
if (smooth_data->trend_joints)
trend_joint = smooth_data->trend_joints[i];
if (smoothed_joint != NULL || trend_joint != NULL)
{
if (smooth_data->joints_persistency_counter[i] > 0)
smooth_data->joints_persistency_counter[i]--;
else
{
skeltrack_joint_free (smoothed_joint);
skeltrack_joint_free (trend_joint);
if (smoothed_joint)
smooth_data->smoothed_joints[i] = NULL;
if (trend_joint)
smooth_data->trend_joints[i] = NULL;
smooth_data->joints_persistency_counter[i] = smooth_data->joints_persistency;
}
}
}
}
void
smooth_joints (SmoothData *data,
SkeltrackJointList new_joints)
{
guint i;
if (new_joints == NULL)
{
decrease_joints_persistency (data);
return;
}
if (data->smoothed_joints == NULL)
{
data->smoothed_joints = skeltrack_joint_list_new ();
for (i = 0; i < SKELTRACK_JOINT_MAX_JOINTS; i++)
{
data->smoothed_joints[i] = skeltrack_joint_copy (new_joints[i]);
}
return;
}
if (data->trend_joints == NULL)
{
data->trend_joints = skeltrack_joint_list_new ();
}
for (i = 0; i < SKELTRACK_JOINT_MAX_JOINTS; i++)
{
SkeltrackJoint *joint, *smoothed_joint, *trend_joint;
smoothed_joint = data->smoothed_joints[i];
trend_joint = data->trend_joints[i];
joint = new_joints[i];
if (joint == NULL)
{
if (smoothed_joint != NULL)
{
if (data->joints_persistency_counter[i] > 0)
data->joints_persistency_counter[i]--;
else
{
skeltrack_joint_free (smoothed_joint);
skeltrack_joint_free (trend_joint);
data->smoothed_joints[i] = NULL;
data->trend_joints[i] = NULL;
data->joints_persistency_counter[i] = data->joints_persistency;
}
}
continue;
}
data->joints_persistency_counter[i] = data->joints_persistency;
if (smoothed_joint == NULL)
{
data->smoothed_joints[i] = skeltrack_joint_copy (joint);
continue;
}
if (trend_joint == NULL)
{
/* First case (when there are only initial values) */
trend_joint = g_slice_new0 (SkeltrackJoint);
trend_joint->x = joint->x - smoothed_joint->x;
trend_joint->y = joint->y - smoothed_joint->y;
trend_joint->z = joint->z - smoothed_joint->z;
trend_joint->screen_x = joint->screen_x - smoothed_joint->screen_x;
trend_joint->screen_y = joint->screen_y - smoothed_joint->screen_y;
data->trend_joints[i] = trend_joint;
}
else
{
/* @TODO: Check if we should give the control of each factor
independently (data-smoothing-factor and trend-smoothing-factor).
*/
holt_double_exp_joint (data->smoothing_factor,
data->smoothing_factor,
smoothed_joint,
joint,
trend_joint);
}
}
}

View file

@ -0,0 +1,626 @@
/*
* skeltrack-util.c
*
* Skeltrack - A Free Software skeleton tracking library
* Copyright (C) 2012 Igalia S.L.
*
* Authors:
* Joaquim Rocha <jrocha@igalia.com>
* Eduardo Lima Mitev <elima@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License at http://www.gnu.org/licenses/lgpl-3.0.txt
* for more details.
*/
#include <math.h>
#include "skeltrack-util.h"
/* @TODO: Expose these to the user */
static const gfloat SCALE_FACTOR = .0021;
static const gint MIN_DISTANCE = -10.0;
static SkeltrackJoint *
node_to_joint (Node *node, SkeltrackJointId id, gint dimension_reduction)
{
SkeltrackJoint *joint;
if (node == NULL)
return NULL;
joint = g_slice_new0 (SkeltrackJoint);
joint->id = id;
joint->x = node->x;
joint->y = node->y;
joint->z = node->z;
joint->screen_x = node->i * dimension_reduction;
joint->screen_y = node->j * dimension_reduction;
return joint;
}
static guint
get_distance_from_joint (Node *node, SkeltrackJoint *joint)
{
guint dx, dy, dz;
dx = ABS (node->x - joint->x);
dy = ABS (node->y - joint->y);
dz = ABS (node->z - joint->z);
return sqrt (dx * dx + dy * dy + dz * dz);
}
static void
unlink_node (Node *node)
{
Node *neighbor;
GList *current_neighbor;
for (current_neighbor = g_list_first (node->neighbors);
current_neighbor != NULL;
current_neighbor = g_list_next (current_neighbor))
{
neighbor = (Node *) current_neighbor->data;
neighbor->neighbors = g_list_remove (neighbor->neighbors, node);
}
for (current_neighbor = g_list_first (node->linked_nodes);
current_neighbor != NULL;
current_neighbor = g_list_next (current_neighbor))
{
neighbor = (Node *) current_neighbor->data;
neighbor->linked_nodes = g_list_remove (neighbor->linked_nodes, node);
}
g_list_free (node->neighbors);
g_list_free (node->linked_nodes);
node->neighbors = NULL;
node->linked_nodes = NULL;
}
static Node *
get_closest_node_with_distances (GList *node_list,
Node *from,
guint x_dist,
guint y_dist,
guint z_dist,
gint *closest_node_dist)
{
Node *closest = NULL;
gint distance = -1;
GList *current_node;
/* @TODO: Replace this and use closest pair of points
algorithm and ensure O(n log n) instead of brute-force */
for (current_node = g_list_first (node_list);
current_node != NULL;
current_node = g_list_next (current_node))
{
guint dx, dy, dz;
Node *node;
gint current_distance;
node = (Node *) current_node->data;
dx = ABS (from->x - node->x);
dy = ABS (from->y - node->y);
dz = ABS (from->z - node->z);
if (dx > x_dist || dy > y_dist || dz > z_dist)
continue;
current_distance = sqrt (dx * dx + dy * dy + dz * dz);
if (closest == NULL || distance > current_distance)
{
closest = node;
distance = current_distance;
}
}
*closest_node_dist = distance;
return closest;
}
Node *
get_closest_node_to_joint (GList *extremas,
SkeltrackJoint *joint,
gint *distance)
{
GList *current_node;
gint dist = -1;
Node *closest_node = NULL;
for (current_node = g_list_first (extremas);
current_node != NULL;
current_node = g_list_next (current_node))
{
guint current_dist;
Node *node = (Node *) current_node->data;
if (node == NULL)
continue;
current_dist = get_distance_from_joint (node, joint);
if (dist == -1 || current_dist < dist)
{
closest_node = node;
dist = current_dist;
}
}
*distance = dist;
return closest_node;
}
gint
get_distance (Node *a, Node *b)
{
guint dx, dy, dz;
dx = ABS (a->x - b->x);
dy = ABS (a->y - b->y);
dz = ABS (a->z - b->z);
return sqrt (dx * dx + dy * dy + dz * dz);
}
Node *
get_closest_torso_node (GList *node_list, Node *from, Node *head)
{
Node *closest = NULL;
gint distance = -1;
GList *current_node;
/* @TODO: Replace this and use closest pair of points
algorithm and ensure O(n log n) instead of brute-force */
for (current_node = g_list_first (node_list);
current_node != NULL;
current_node = g_list_next (current_node))
{
Node *node;
gint current_distance;
node = (Node *) current_node->data;
if (node->z >= head->z &&
node->y >= from->y)
{
current_distance = get_distance (node, from);
if (closest == NULL || current_distance < distance)
{
closest = node;
distance = current_distance;
}
}
}
return closest;
}
Node *
get_closest_node (GList *node_list, Node *from)
{
Node *closest = NULL;
gint distance = -1;
GList *current_node;
/* @TODO: Replace this and use closest pair of points
algorithm and ensure O(n log n) instead of brute-force */
for (current_node = g_list_first (node_list);
current_node != NULL;
current_node = g_list_next (current_node))
{
Node *node;
gint current_distance;
node = (Node *) current_node->data;
if (closest == NULL)
{
closest = node;
distance = get_distance (node, from);
continue;
}
current_distance = get_distance (node, from);
if (current_distance < distance)
{
closest = node;
distance = current_distance;
}
}
return closest;
}
Label *
get_main_component (GList *node_list, Node *from, gdouble min_normalized_nr_nodes)
{
Label *main_component = NULL;
gint distance = -1;
GList *current_node;
for (current_node = g_list_first (node_list);
current_node != NULL;
current_node = g_list_next (current_node))
{
Node *node;
Label *label;
gint current_distance;
node = (Node *) current_node->data;
label = node->label;
if (main_component == NULL &&
label->normalized_num_nodes > min_normalized_nr_nodes)
{
main_component = label;
distance = get_distance (node, from);
continue;
}
current_distance = get_distance (node, from);
if (current_distance < distance &&
label->normalized_num_nodes > min_normalized_nr_nodes)
{
main_component = label;
distance = current_distance;
}
}
return main_component;
}
Label *
label_find (Label *label)
{
Label *parent;
g_return_val_if_fail (label != NULL, NULL);
parent = label->parent;
if (parent == label)
return parent;
else
return label_find (parent);
}
void
label_union (Label *a, Label *b)
{
Label *root_a, *root_b;
root_a = label_find (a);
root_b = label_find (b);
if (root_a->index < root_b->index)
{
b->parent = root_a;
}
else
{
a->parent = root_b;
}
}
void
free_label (Label *label)
{
g_list_free (label->nodes);
label->nodes = NULL;
g_slice_free (Label, label);
}
void
clean_labels (GList *labels)
{
GList *current = g_list_first (labels);
while (current != NULL)
{
Label *label;
label = (Label *) current->data;
free_label (label);
current = g_list_next (current);
}
}
void
free_node (Node *node, gboolean unlink_node_first)
{
if (unlink_node_first)
{
unlink_node (node);
}
else
{
g_list_free (node->neighbors);
g_list_free (node->linked_nodes);
node->neighbors = NULL;
node->linked_nodes = NULL;
}
g_slice_free (Node, node);
}
void
clean_nodes (GList *nodes)
{
GList *current = g_list_first (nodes);
while (current != NULL)
{
Node *node;
node = (Node *) current->data;
free_node (node, FALSE);
current = g_list_next (current);
}
}
GList *
remove_nodes_with_label (GList *nodes,
Node **node_matrix,
gint width,
Label *label)
{
Node *node;
GList *link_to_delete, *current_node;
current_node = g_list_first (nodes);
while (current_node != NULL)
{
node = (Node *) current_node->data;
if (node->label == label)
{
link_to_delete = current_node;
current_node = g_list_next (current_node);
nodes = g_list_delete_link (nodes, link_to_delete);
node_matrix[width * node->j + node->i] = NULL;
free_node (node, TRUE);
continue;
}
current_node = g_list_next (current_node);
}
return nodes;
}
Label *
get_lowest_index_label (Label **neighbor_labels)
{
guint index;
Label *lowest_index_label = NULL;
lowest_index_label = neighbor_labels[0];
for (index = 1; index < 4; index++)
{
if (neighbor_labels[index] == NULL)
continue;
if (lowest_index_label == NULL ||
lowest_index_label->index < neighbor_labels[index]->index)
{
lowest_index_label = neighbor_labels[index];
}
}
return lowest_index_label;
}
Label *
new_label (gint index)
{
Label *label = g_slice_new (Label);
label->index = index;
label->parent = label;
label->nodes = NULL;
label->bridge_node = NULL;
label->to_node = NULL;
label->lower_screen_y = -1;
label->higher_z = -1;
label->lower_z = -1;
label->normalized_num_nodes = -1;
return label;
}
void
join_components_to_main (GList *labels,
Label *main_component_label,
guint horizontal_max_distance,
guint depth_max_distance,
guint graph_distance_threshold)
{
GList *current_label;
for (current_label = g_list_first (labels);
current_label != NULL;
current_label = g_list_next (current_label))
{
gint closer_distance = -1;
Label *label;
GList *current_node, *nodes;
label = (Label *) current_label->data;
if (label == main_component_label)
continue;
/* Skip nodes behind main component */
if (label->higher_z > main_component_label->higher_z +
graph_distance_threshold)
continue;
nodes = label->nodes;
for (current_node = g_list_first (nodes);
current_node != NULL;
current_node = g_list_next (current_node))
{
Node *node;
gint current_distance;
node = (Node *) current_node->data;
/* Skip nodes that belong to the same component or
that a not in the edge of their component */
if (g_list_length (node->neighbors) == 8)
continue;
Node *closest_node =
get_closest_node_with_distances (main_component_label->nodes,
node,
horizontal_max_distance,
horizontal_max_distance,
depth_max_distance,
&current_distance);
if (closest_node &&
(current_distance < closer_distance ||
closer_distance == -1))
{
node->label->bridge_node = node;
node->label->to_node = closest_node;
closer_distance = current_distance;
}
}
}
}
void
set_joint_from_node (SkeltrackJointList *joints,
Node *node,
SkeltrackJointId id,
gint dimension_reduction)
{
(*joints)[id] = node_to_joint (node, id, dimension_reduction);
}
gint *
create_new_dist_matrix (gint matrix_size)
{
guint i;
gint *distances;
distances = g_slice_alloc0 (matrix_size * sizeof (gint));
for (i = 0; i < matrix_size; i++)
{
distances[i] = -1;
}
return distances;
}
gboolean
dijkstra_to (GList *nodes, Node *source, Node *target,
gint width, gint height,
gint *distances, Node **previous)
{
gint nr;
GList *unvisited_nodes, *current;
for (current = g_list_first (nodes);
previous != NULL && current != NULL;
current = g_list_next (current))
{
Node *node;
node = (Node *) current->data;
previous[node->j * width + node->i] = NULL;
}
distances[source->j * width + source->i] = 0;
unvisited_nodes = g_list_copy (nodes);
nr = 0;
while (unvisited_nodes != NULL)
{
Node *node;
GList *current_neighbor, *shorter_dist_node, *cur_node;
shorter_dist_node = g_list_first (unvisited_nodes);
cur_node = g_list_next (shorter_dist_node);
while (cur_node != NULL)
{
Node *value, *shorter_dist;
value = (Node *) cur_node->data;
shorter_dist = (Node *) shorter_dist_node->data;
if (distances[shorter_dist->j * width + shorter_dist->i] == -1 ||
(distances[value->j * width + value->i] != -1 &&
distances[value->j * width +
value->i] < distances[shorter_dist->j * width +
shorter_dist->i]))
{
shorter_dist_node = cur_node;
}
cur_node = g_list_next (cur_node);
}
node = (Node *) shorter_dist_node->data;
if (distances[node->j * width + node->i] == -1)
{
break;
}
current_neighbor = g_list_first (node->neighbors);
while (current_neighbor)
{
gint dist;
Node *neighbor;
neighbor = (Node *) current_neighbor->data;
dist = get_distance (node, neighbor) +
distances[node->j * width + node->i];
if (distances[neighbor->j * width + neighbor->i] == -1 ||
dist < distances[neighbor->j * width + neighbor->i])
{
distances[neighbor->j * width + neighbor->i] = dist;
if (previous != NULL)
{
previous[neighbor->j * width + neighbor->i] = node;
}
nr++;
}
if (target != NULL && neighbor == target)
{
g_list_free (unvisited_nodes);
return TRUE;
}
current_neighbor = g_list_next (current_neighbor);
}
unvisited_nodes = g_list_delete_link (unvisited_nodes, shorter_dist_node);
}
g_list_free (unvisited_nodes);
return FALSE;
}
void
convert_screen_coords_to_mm (guint width,
guint height,
guint dimension_reduction,
guint i,
guint j,
gint z,
gint *x,
gint *y)
{
gfloat width_height_relation =
width > height ? (gfloat) width / height : (gfloat) height / width;
/* Formula from http://openkinect.org/wiki/Imaging_Information */
*x = round((i * dimension_reduction - width * dimension_reduction / 2.0) *
(z + MIN_DISTANCE) * SCALE_FACTOR * width_height_relation);
*y = round((j * dimension_reduction - height * dimension_reduction / 2.0) *
(z + MIN_DISTANCE) * SCALE_FACTOR);
}
void
convert_mm_to_screen_coords (guint width,
guint height,
guint dimension_reduction,
gint x,
gint y,
gint z,
guint *i,
guint *j)
{
gfloat width_height_relation =
width > height ? (gfloat) width / height : (gfloat) height / width;
if (z + MIN_DISTANCE == 0)
{
*i = 0;
*j = 0;
return;
}
*i = round (width / 2.0 + x / ((gfloat) (z + MIN_DISTANCE) * SCALE_FACTOR *
dimension_reduction * width_height_relation));
*j = round (height / 2.0 + y / ((gfloat) (z + MIN_DISTANCE) * SCALE_FACTOR *
dimension_reduction));
}

View file

@ -176,11 +176,15 @@ void Webcam::setFrame(const Mat& frame, const RotatedRect& faceRect) {
QTimer::singleShot(qMax((int)remaining / 1000, 0), _grabber, SLOT(grabFrame()));
}
FrameGrabber::FrameGrabber() : _capture(0), _searchWindow(0, 0, 0, 0) {
FrameGrabber::FrameGrabber() : _capture(0), _searchWindow(0, 0, 0, 0), _freenectContext(0) {
}
FrameGrabber::~FrameGrabber() {
if (_capture != 0) {
if (_freenectContext != 0) {
freenect_close_device(_freenectDevice);
freenect_shutdown(_freenectContext);
} else if (_capture != 0) {
cvReleaseCapture(&_capture);
}
}
@ -190,32 +194,14 @@ void FrameGrabber::reset() {
}
void FrameGrabber::grabFrame() {
if (_capture == 0) {
if ((_capture = cvCaptureFromCAM(-1)) == 0) {
printLog("Failed to open webcam.\n");
return;
}
const int IDEAL_FRAME_WIDTH = 320;
const int IDEAL_FRAME_HEIGHT = 240;
cvSetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH, IDEAL_FRAME_WIDTH);
cvSetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT, IDEAL_FRAME_HEIGHT);
#ifdef __APPLE__
configureCamera(0x5ac, 0x8510, false, 0.975, 0.5, 1.0, 0.5, true, 0.5);
#else
cvSetCaptureProperty(_capture, CV_CAP_PROP_EXPOSURE, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_CONTRAST, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_SATURATION, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_BRIGHTNESS, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_HUE, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_GAIN, 0.5);
#endif
switchToResourcesParentIfRequired();
if (!_faceCascade.load("resources/haarcascades/haarcascade_frontalface_alt.xml")) {
printLog("Failed to load Haar cascade for face tracking.\n");
}
if (_capture == 0 && _freenectContext == 0 && !init()) {
return;
}
if (_freenectContext != 0) {
return;
}
IplImage* image = cvQueryFrame(_capture);
if (image == 0) {
// try again later
@ -264,6 +250,47 @@ void FrameGrabber::grabFrame() {
Q_ARG(cv::Mat, frame), Q_ARG(cv::RotatedRect, faceRect));
}
bool FrameGrabber::init() {
// first try for a Kinect
if (freenect_init(&_freenectContext, 0) >= 0) {
if (freenect_num_devices(_freenectContext) > 0) {
if (freenect_open_device(_freenectContext, &_freenectDevice, 0) >= 0) {
return true;
}
}
freenect_shutdown(_freenectContext);
_freenectContext = 0;
}
// next, an ordinary webcam
if ((_capture = cvCaptureFromCAM(-1)) == 0) {
printLog("Failed to open webcam.\n");
return false;
}
const int IDEAL_FRAME_WIDTH = 320;
const int IDEAL_FRAME_HEIGHT = 240;
cvSetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH, IDEAL_FRAME_WIDTH);
cvSetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT, IDEAL_FRAME_HEIGHT);
#ifdef __APPLE__
configureCamera(0x5ac, 0x8510, false, 0.975, 0.5, 1.0, 0.5, true, 0.5);
#else
cvSetCaptureProperty(_capture, CV_CAP_PROP_EXPOSURE, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_CONTRAST, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_SATURATION, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_BRIGHTNESS, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_HUE, 0.5);
cvSetCaptureProperty(_capture, CV_CAP_PROP_GAIN, 0.5);
#endif
switchToResourcesParentIfRequired();
if (!_faceCascade.load("resources/haarcascades/haarcascade_frontalface_alt.xml")) {
printLog("Failed to load Haar cascade for face tracking.\n");
return false;
}
return true;
}
void FrameGrabber::updateHSVFrame(const Mat& frame) {
cvtColor(frame, _hsvFrame, CV_BGR2HSV);
inRange(_hsvFrame, Scalar(0, 55, 65), Scalar(180, 256, 256), _mask);

View file

@ -15,6 +15,8 @@
#include <glm/glm.hpp>
#include <libfreenect.h>
#include <opencv2/opencv.hpp>
#include "InterfaceConfig.h"
@ -82,6 +84,7 @@ public slots:
private:
bool init();
void updateHSVFrame(const cv::Mat& frame);
CvCapture* _capture;
@ -91,6 +94,9 @@ private:
cv::SparseMat _histogram;
cv::Mat _backProject;
cv::Rect _searchWindow;
freenect_context* _freenectContext;
freenect_device* _freenectDevice;
};
Q_DECLARE_METATYPE(cv::Mat)