style(uvc osx) remove useless file

This commit is contained in:
Tiny 2018-12-26 11:19:43 +08:00
parent 263658834a
commit c490e09de0
5 changed files with 16 additions and 1251 deletions

View File

@ -137,6 +137,9 @@ elseif(OS_MAC)
## set_target_properties(usbBusProber PROPERTIES FRAMEWORK TRUE ) ## set_target_properties(usbBusProber PROPERTIES FRAMEWORK TRUE )
## add_library(vvuvckit SHARED ${MAC_VVUVCKIT_SRC_LIST}) ## add_library(vvuvckit SHARED ${MAC_VVUVCKIT_SRC_LIST})
## set_target_properties(vvuvckit PROPERTIES FRAMEWORK TRUE ) ## set_target_properties(vvuvckit PROPERTIES FRAMEWORK TRUE )
## find_package(libuvc REQUIRED)
## set(UVC_LIB ${libuvc_LIBRARIES})
## include_directories(${libuvc_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(src/mynteye/uvc/macosx/USBBusProber.framework/Headers) INCLUDE_DIRECTORIES(src/mynteye/uvc/macosx/USBBusProber.framework/Headers)
INCLUDE_DIRECTORIES(src/mynteye/uvc/macosx/VVUVCKit.framework/Headers) INCLUDE_DIRECTORIES(src/mynteye/uvc/macosx/VVUVCKit.framework/Headers)
@ -147,11 +150,6 @@ elseif(OS_MAC)
set(UVC_SRC src/mynteye/uvc/macosx/CameraEngine.cpp src/mynteye/uvc/macosx/AVfoundationCamera.mm src/mynteye/uvc/macosx/uvc-vvuvckit.cc ) set(UVC_SRC src/mynteye/uvc/macosx/CameraEngine.cpp src/mynteye/uvc/macosx/AVfoundationCamera.mm src/mynteye/uvc/macosx/uvc-vvuvckit.cc )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework CoreFoundation -framework AVFoundation -framework IOKit -framework AppKit -framework Cocoa -framework CoreMedia -framework CoreData -framework Foundation -framework CoreVideo ${__MACUVCLOG_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework CoreFoundation -framework AVFoundation -framework IOKit -framework AppKit -framework Cocoa -framework CoreMedia -framework CoreData -framework Foundation -framework CoreVideo ${__MACUVCLOG_FLAGS}")
find_package(libuvc REQUIRED)
set(UVC_LIB ${libuvc_LIBRARIES})
include_directories(${libuvc_INCLUDE_DIRS})
elseif(OS_LINUX) elseif(OS_LINUX)
set(UVC_SRC src/mynteye/uvc/linux/uvc-v4l2.cc) set(UVC_SRC src/mynteye/uvc/linux/uvc-v4l2.cc)
else() else()

View File

@ -1,490 +0,0 @@
/*
Copyright (c) 2007-2010, Troy D. Hanson http://uthash.sourceforge.net
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTLIST_H
#define UTLIST_H
#define UTLIST_VERSION 1.9.1
/*
* This file contains macros to manipulate singly and doubly-linked lists.
*
* 1. LL_ macros: singly-linked lists.
* 2. DL_ macros: doubly-linked lists.
* 3. CDL_ macros: circular doubly-linked lists.
*
* To use singly-linked lists, your structure must have a "next" pointer.
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
* Either way, the pointer to the head of the list must be initialized to NULL.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *prev, *next;
* }
*
* struct item *list = NULL:
*
* int main() {
* struct item *item;
* ... allocate and populate item ...
* DL_APPEND(list, item);
* }
* --------------------------------------------------
*
* For doubly-linked lists, the append and delete macros are O(1)
* For singly-linked lists, append and delete are O(n) but prepend is O(1)
* The sort macro is O(n log(n)) for all types of single/double/circular lists.
*/
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ code), this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
#ifdef _MSC_VER /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
#define LDECLTYPE(x) decltype(x)
#else /* VS2008 or older (or VS2010 in C mode) */
#define NO_DECLTYPE
#define LDECLTYPE(x) char*
#endif
#else /* GNU, Sun and other compilers */
#define LDECLTYPE(x) __typeof(x)
#endif
/* for VS2008 we use some workarounds to get around the lack of decltype,
* namely, we always reassign our tmp variable to the list head if we need
* to dereference its prev/next pointers, and save/restore the real head.*/
#ifdef NO_DECLTYPE
#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
#define _NEXT(elt,list) ((char*)((list)->next))
#define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
#define _PREV(elt,list) ((char*)((list)->prev))
#define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
#else
#define _SV(elt,list)
#define _NEXT(elt,list) ((elt)->next)
#define _NEXTASGN(elt,list,to) ((elt)->next)=(to)
#define _PREV(elt,list) ((elt)->prev)
#define _PREVASGN(elt,list,to) ((elt)->prev)=(to)
#define _RS(list)
#define _CASTASGN(a,b) (a)=(b)
#endif
/******************************************************************************
* The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort *
* Unwieldy variable names used here to avoid shadowing passed-in variables. *
*****************************************************************************/
#define LL_SORT(list, cmp) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
LDECLTYPE(list) _ls_oldhead; \
LDECLTYPE(list) _tmp; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
_CASTASGN(_ls_oldhead,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
} else if (_ls_qsize == 0 || !_ls_q) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
} while (0)
#define DL_SORT(list, cmp) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
LDECLTYPE(list) _ls_oldhead; \
LDECLTYPE(list) _tmp; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
_CASTASGN(_ls_oldhead,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
} else if (_ls_qsize == 0 || !_ls_q) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
_CASTASGN(list->prev, _ls_tail); \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
} while (0)
#define CDL_SORT(list, cmp) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
LDECLTYPE(list) _ls_oldhead; \
LDECLTYPE(list) _tmp; \
LDECLTYPE(list) _tmp2; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
_CASTASGN(_ls_oldhead,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); \
if (_NEXT(_ls_q,list) == _ls_oldhead) { \
_ls_q = NULL; \
} else { \
_ls_q = _NEXT(_ls_q,list); \
} \
_RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
} else if (_ls_qsize == 0 || !_ls_q) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
_CASTASGN(list->prev,_ls_tail); \
_CASTASGN(_tmp2,list); \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list); \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
} while (0)
/******************************************************************************
* singly linked list macros (non-circular) *
*****************************************************************************/
#define LL_PREPEND(head,add) \
do { \
(add)->next = head; \
head = add; \
} while (0)
#define LL_APPEND(head,add) \
do { \
LDECLTYPE(head) _tmp; \
(add)->next=NULL; \
if (head) { \
_tmp = head; \
while (_tmp->next) { _tmp = _tmp->next; } \
_tmp->next=(add); \
} else { \
(head)=(add); \
} \
} while (0)
#define LL_DELETE(head,del) \
do { \
LDECLTYPE(head) _tmp; \
if ((head) == (del)) { \
(head)=(head)->next; \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (del))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = ((del)->next); \
} \
} \
} while (0)
/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
#define LL_APPEND_VS2008(head,add) \
do { \
if (head) { \
(add)->next = head; /* use add->next as a temp variable */ \
while ((add)->next->next) { (add)->next = (add)->next->next; } \
(add)->next->next=(add); \
} else { \
(head)=(add); \
} \
(add)->next=NULL; \
} while (0)
#define LL_DELETE_VS2008(head,del) \
do { \
if ((head) == (del)) { \
(head)=(head)->next; \
} else { \
char *_tmp = (char*)(head); \
while (head->next && (head->next != (del))) { \
head = head->next; \
} \
if (head->next) { \
head->next = ((del)->next); \
} \
{ \
char **_head_alias = (char**)&(head); \
*_head_alias = _tmp; \
} \
} \
} while (0)
#ifdef NO_DECLTYPE
#undef LL_APPEND
#define LL_APPEND LL_APPEND_VS2008
#undef LL_DELETE
#define LL_DELETE LL_DELETE_VS2008
#endif
/* end VS2008 replacements */
#define LL_FOREACH(head,el) \
for(el=head;el;el=el->next)
#define LL_FOREACH_SAFE(head,el,tmp) \
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
#define LL_SEARCH_SCALAR(head,out,field,val) \
do { \
LL_FOREACH(head,out) { \
if ((out)->field == (val)) break; \
} \
} while(0)
#define LL_SEARCH(head,out,elt,cmp) \
do { \
LL_FOREACH(head,out) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
/******************************************************************************
* doubly linked list macros (non-circular) *
*****************************************************************************/
#define DL_PREPEND(head,add) \
do { \
(add)->next = head; \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev = (add); \
} else { \
(add)->prev = (add); \
} \
(head) = (add); \
} while (0)
#define DL_APPEND(head,add) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev->next = (add); \
(head)->prev = (add); \
(add)->next = NULL; \
} else { \
(head)=(add); \
(head)->prev = (head); \
(head)->next = NULL; \
} \
} while (0);
#define DL_DELETE(head,del) \
do { \
if ((del)->prev == (del)) { \
(head)=NULL; \
} else if ((del)==(head)) { \
(del)->next->prev = (del)->prev; \
(head) = (del)->next; \
} else { \
(del)->prev->next = (del)->next; \
if ((del)->next) { \
(del)->next->prev = (del)->prev; \
} else { \
(head)->prev = (del)->prev; \
} \
} \
} while (0);
#define DL_FOREACH(head,el) \
for(el=head;el;el=el->next)
/* this version is safe for deleting the elements during iteration */
#define DL_FOREACH_SAFE(head,el,tmp) \
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
/* these are identical to their singly-linked list counterparts */
#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
#define DL_SEARCH LL_SEARCH
/******************************************************************************
* circular doubly linked list macros *
*****************************************************************************/
#define CDL_PREPEND(head,add) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(add)->next = (head); \
(head)->prev = (add); \
(add)->prev->next = (add); \
} else { \
(add)->prev = (add); \
(add)->next = (add); \
} \
(head)=(add); \
} while (0)
#define CDL_DELETE(head,del) \
do { \
if ( ((head)==(del)) && ((head)->next == (head))) { \
(head) = 0L; \
} else { \
(del)->next->prev = (del)->prev; \
(del)->prev->next = (del)->next; \
if ((del) == (head)) (head)=(del)->next; \
} \
} while (0);
#define CDL_FOREACH(head,el) \
for(el=head;el;el=(el->next==head ? 0L : el->next))
#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \
for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \
(el) && ((tmp2)=(el)->next, 1); \
((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
#define CDL_SEARCH_SCALAR(head,out,field,val) \
do { \
CDL_FOREACH(head,out) { \
if ((out)->field == (val)) break; \
} \
} while(0)
#define CDL_SEARCH(head,out,elt,cmp) \
do { \
CDL_FOREACH(head,out) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
#endif /* UTLIST_H */

View File

@ -1,429 +0,0 @@
// Copyright 2018 Slightech Co., Ltd. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <thread>
#include <vector>
#include <atomic>
#include <mutex>
#include "mynteye/logger.h"
#include "mynteye/uvc/uvc.h"
#include "libuvc/libuvc.h"
#include "mynteye/uvc/macosx/uvc_osx_internal.h"
// #define ENABLE_DEBUG_SPAM
MYNTEYE_BEGIN_NAMESPACE
namespace uvc {
static void check(const char *call, uvc_error_t status) {
LOG_IF(FATAL, status < 0)
<< call << "(...) returned " << uvc_strerror(status);
}
#define CALL_UVC_WITHOUT_CHECK(name, ...) name(__VA_ARGS__)
#define CALL_UVC(name, ...) check(#name, name(__VA_ARGS__))
struct context {
uvc_context_t *ctx;
context() : ctx(nullptr) {
VLOG(2) << __func__;
CALL_UVC(uvc_init, &ctx, nullptr);
}
~context() {
VLOG(2) << __func__;
if (ctx)
uvc_exit(ctx);
}
};
/** UVC request code (A.8) */
enum uvc_req_code {
UVC_RC_UNDEFINED = 0x00,
UVC_SET_CUR = 0x01,
UVC_GET_CUR = 0x81,
UVC_GET_MIN = 0x82,
UVC_GET_MAX = 0x83,
UVC_GET_RES = 0x84,
UVC_GET_LEN = 0x85,
UVC_GET_INFO = 0x86,
UVC_GET_DEF = 0x87,
UVC_REQ_TYPE_GET = 0xa1,
UVC_REQ_TYPE_SET = 0x21
};
struct device;
struct device {
const std::shared_ptr<context> parent;
uvc_device_t *uvcdevice = nullptr;
uvc_device_handle_t *handle = nullptr;
/** Serial number (null if unavailable) */
std::string serialNumber = "";
/** Device-reported manufacturer name (or null) */
std::string manufacturer = "";
/** Device-reporter product name (or null) */
std::string product = "";
uvc_device_info_t info;
int width, height, format, fps;
int vid, pid;
video_channel_callback callback = nullptr;
static std::vector <struct device*> s_devices;
std::mutex _devices_mutex;
device(std::shared_ptr<context> parent, uvc_device_t *uvcdevice)
: parent(parent), uvcdevice(uvcdevice) {
VLOG(2) << __func__;
open();
uvc_device_descriptor_t *desc;
CALL_UVC(uvc_get_device_descriptor, uvcdevice, &desc);
serialNumber = std::string(desc->serialNumber);
manufacturer = std::string(desc->manufacturer);
product = std::string(desc->product);
vid = desc->idVendor;
pid = desc->idProduct;
uvc_free_device_descriptor(desc);
std::lock_guard<std::mutex> lock(_devices_mutex);
s_devices.push_back(this);
}
~device() {
VLOG(2) << __func__;
if (handle)
uvc_close(handle);
if (uvcdevice)
uvc_unref_device(uvcdevice);
std::lock_guard<std::mutex> lock(_devices_mutex);
for(unsigned long i = 0 ; i < s_devices.size() ; i++) {
if(this == s_devices[i]) {
s_devices.erase(s_devices.begin()+i);
}
}
}
void open() {
if (!handle)
CALL_UVC(uvc_open, uvcdevice, &handle);
}
void set_format(
int width, int height, int format, int fps,
video_channel_callback callback) {
this->width = width;
this->height = height;
this->format = format;
this->fps = fps;
this->callback = callback;
}
static void uvc_frame_callback (struct uvc_frame *frame, void *user_ptr)
{
for(unsigned long i = 0 ; i < s_devices.size() ; i++) {
if(user_ptr == (void*)s_devices[i]) {
printf("bingo\n");
}
}
}
// int32_t get_data_usb( uvc_req_code action, int control, int unit) const {
// unsigned char buffer[4];
// int status = libusb_control_transfer(handle->usb_devh,
// UVC_REQ_TYPE_GET,
// action,
// control << 8,
// unit << 8 | (1),// _interface
// buffer,
// sizeof(int32_t), 0);
// MYNTEYE_UNUSED(status);
// if (status < 0) throw std::runtime_error(
// to_string() << "libusb_control_transfer(...) returned "
// << libusb_error_name(status));
// if (status != sizeof(int32_t))
// throw std::runtime_error("insufficient data read from USB");
// return DW_TO_INT(buffer);
// }
// void set_data_usb( uvc_req_code action, int control, int unit, int value) const {
// unsigned char buffer[4];
// INT_TO_DW(value, buffer);
// int status = libusb_control_transfer(handle->usb_devh,
// UVC_REQ_TYPE_SET,
// action,
// control << 8,
// unit << 8 | (1),// _interface
// buffer,
// sizeof(int32_t), 0);
// if (status < 0) throw std::runtime_error(
// to_string() << "libusb_control_transfer(...) returned "
// << libusb_error_name(status));
// if (status != sizeof(int32_t))
// throw std::runtime_error("insufficient data writen to USB");
// }
};
std::vector <struct device*> device::s_devices;
std::shared_ptr<context> create_context() {
return std::make_shared<context>();
}
std::vector<std::shared_ptr<device>> query_devices(
std::shared_ptr<context> context) {
std::vector<std::shared_ptr<device>> devices;
uvc_device_t **list;
CALL_UVC(uvc_get_device_list, context->ctx, &list);
for (auto it = list; *it; ++it) {
try {
auto dev = std::make_shared<device>(context, *it);
devices.push_back(dev);
} catch (std::runtime_error &e) {
LOG(WARNING) << "usb:" << static_cast<int>(uvc_get_bus_number(*it)) << ':'
<< static_cast<int>(uvc_get_device_address(*it)) << ": "
<< e.what();
}
}
uvc_free_device_list(list, 1);
return devices;
}
int get_vendor_id(const device &device) {
return device.vid;
}
int get_product_id(const device &device) {
return device.pid;
}
std::string get_name(const device &device) {
return device.serialNumber + "/" + device.manufacturer + "/" + device.product;
}
std::string get_video_name(const device &device) {
return device.serialNumber + "/" + device.manufacturer + "/" + device.product;
}
// class uvc_device
// {
// public:
// virtual void probe_and_commit(stream_profile profile, frame_callback callback, int buffers = DEFAULT_V4L2_FRAME_BUFFERS) = 0;
// virtual void stream_on(std::function<void(const notification& n)> error_handler = [](const notification& n){}) = 0;
// virtual void start_callbacks() = 0;
// virtual void stop_callbacks() = 0;
// virtual void close(stream_profile profile) = 0;
// virtual void set_power_state(power_state state) = 0;
// virtual power_state get_power_state() const = 0;
// virtual void init_xu(const extension_unit& xu) = 0;
// virtual bool set_xu(const extension_unit& xu, uint8_t ctrl, const uint8_t* data, int len) = 0;
// virtual bool get_xu(const extension_unit& xu, uint8_t ctrl, uint8_t* data, int len) const = 0;
// virtual control_range get_xu_range(const extension_unit& xu, uint8_t ctrl, int len) const = 0;
// virtual bool get_pu(rs2_option opt, int32_t& value) const = 0;
// virtual bool set_pu(rs2_option opt, int32_t value) = 0;
// virtual control_range get_pu_range(rs2_option opt) const = 0;
// virtual std::vector<stream_profile> get_profiles() const = 0;
// virtual void lock() const = 0;
// virtual void unlock() const = 0;
// virtual std::string get_device_location() const = 0;
// virtual usb_spec get_usb_specification() const = 0;
// virtual ~uvc_device() = default;
// protected:
// std::function<void(const notification& n)> _error_handler;
// };
bool pu_control_range(
const device &device, Option option, int32_t *min, int32_t *max,
int32_t *def) {
// TODO(JohnZhao)
MYNTEYE_UNUSED(device)
MYNTEYE_UNUSED(option)
MYNTEYE_UNUSED(min)
MYNTEYE_UNUSED(max)
MYNTEYE_UNUSED(def)
// device.uvcdevice -> set_pu(option, *def);
return false;
}
bool pu_control_query(
const device &device, Option option, pu_query query, int32_t *value) {
// TODO(JohnZhao)
MYNTEYE_UNUSED(device)
MYNTEYE_UNUSED(option)
MYNTEYE_UNUSED(query)
MYNTEYE_UNUSED(value)
return false;
}
bool xu_control_range(
const device &device, const xu &xu, uint8_t selector, uint8_t id, int32_t *min,
int32_t *max, int32_t *def) {
// TODO(JohnZhao)
MYNTEYE_UNUSED(device)
MYNTEYE_UNUSED(xu)
MYNTEYE_UNUSED(selector)
MYNTEYE_UNUSED(id)
MYNTEYE_UNUSED(min)
MYNTEYE_UNUSED(max)
MYNTEYE_UNUSED(def)
return false;
}
bool xu_control_query(
const device &device, const xu &xu, uint8_t selector, xu_query query,
uint16_t size, uint8_t *data) {
// TODO(JohnZhao)
MYNTEYE_UNUSED(device)
MYNTEYE_UNUSED(xu)
MYNTEYE_UNUSED(selector)
MYNTEYE_UNUSED(query)
MYNTEYE_UNUSED(size)
MYNTEYE_UNUSED(data)
return false;
}
void set_device_mode(
device &device, int width, int height, int format, int fps, // NOLINT
video_channel_callback callback) {
device.set_format(width, height, format, fps, callback);
}
void start_streaming(device &device, int num_transfer_bufs) { // NOLINT
// MYNTEYE_UNUSED(device)
// MYNTEYE_UNUSED(num_transfer_bufs)
// typedef struct uvc_stream_ctrl {
// uint16_t bmHint;
// uint8_t bFormatIndex;
// uint8_t bFrameIndex;
// uint32_t dwFrameInterval;
// uint16_t wKeyFrameRate;
// uint16_t wPFrameRate;
// uint16_t wCompQuality;
// uint16_t wCompWindowSize;
// uint16_t wDelay;
// uint32_t dwMaxVideoFrameSize;
// uint32_t dwMaxPayloadTransferSize;
// uint32_t dwClockFrequency;
// uint8_t bmFramingInfo;
// uint8_t bPreferredVersion;
// uint8_t bMinVersion;
// uint8_t bMaxVersion;
// uint8_t bInterfaceNumber;
// } uvc_stream_ctrl_t;
// uvc_error_t uvc_get_stream_ctrl_format_size(
// uvc_device_handle_t *devh,
// uvc_stream_ctrl_t *ctrl,
// enum uvc_frame_format format,
// int width, int height,
// int fps
// );
uvc_stream_ctrl_t ctrl_st = {};
/** Color coding of stream, transport-independent
* @ingroup streaming
*/
// enum uvc_frame_format {
// UVC_FRAME_FORMAT_UNKNOWN = 0,
// /** Any supported format */
// UVC_FRAME_FORMAT_ANY = 0,
// UVC_FRAME_FORMAT_UNCOMPRESSED,
// UVC_FRAME_FORMAT_COMPRESSED,
// /** YUYV/YUV2/YUV422: YUV encoding with one luminance value per pixel and
// * one UV (chrominance) pair for every two pixels.
// */
// UVC_FRAME_FORMAT_YUYV,
// UVC_FRAME_FORMAT_UYVY,
// /** 24-bit RGB */
// UVC_FRAME_FORMAT_RGB,
// UVC_FRAME_FORMAT_BGR,
// /** Motion-JPEG (or JPEG) encoded images */
// UVC_FRAME_FORMAT_MJPEG,
// /** Greyscale images */
// UVC_FRAME_FORMAT_GRAY8,
// UVC_FRAME_FORMAT_GRAY16,
// /* Raw colour mosaic images */
// UVC_FRAME_FORMAT_BY8,
// UVC_FRAME_FORMAT_BA81,
// UVC_FRAME_FORMAT_SGRBG8,
// UVC_FRAME_FORMAT_SGBRG8,
// UVC_FRAME_FORMAT_SRGGB8,
// UVC_FRAME_FORMAT_SBGGR8,
// /** Number of formats understood */
// UVC_FRAME_FORMAT_COUNT,
// };
CALL_UVC(uvc_get_stream_ctrl_format_size,
device.handle,
&ctrl_st,
UVC_FRAME_FORMAT_ANY, // UVC_FRAME_FORMAT_YUYV, //(enum uvc_frame_format)device.format,
device.width,
device.height,
device.fps);
/** A callback function to handle incoming assembled UVC frames
* @ingroup streaming
*/
// typedef void(uvc_frame_callback_t)(struct uvc_frame *frame, void *user_ptr);
// uvc_frame_callback_t *cb = nullptr;
CALL_UVC(uvc_start_streaming,
device.handle,
&ctrl_st,
device::uvc_frame_callback,
&device,
num_transfer_bufs);
printf("begin\n");
// uvc_error_t uvc_start_streaming(
// uvc_device_handle_t *devh,
// uvc_stream_ctrl_t *ctrl,
// uvc_frame_callback_t *cb,
// void *user_ptr,
// uint8_t flags);
}
void stop_streaming(device &device) { // NOLINT
// MYNTEYE_UNUSED(device)
CALL_UVC_WITHOUT_CHECK(uvc_stop_streaming, device.handle);
}
} // namespace uvc
MYNTEYE_END_NAMESPACE

View File

@ -168,6 +168,7 @@ struct device : public AVfoundationCamera{
} }
} }
pause_ = true; pause_ = true;
teardown();
} }
void open() { void open() {
@ -187,6 +188,7 @@ struct device : public AVfoundationCamera{
if (!is_capturing) if (!is_capturing)
return; return;
is_capturing = false; is_capturing = false;
stopCamera();
} }
std::string get_name() const { std::string get_name() const {
@ -224,7 +226,7 @@ struct device : public AVfoundationCamera{
pv_sleep(); pv_sleep();
} else { } else {
if ((is_capturing) && (!stillRunning())) { if ((is_capturing) && (!stillRunning())) {
LOG(ERROR) << "error status in camera running."; LOG(ERROR) << "error status in camera running.";
} else { pv_sleep(); } } else { pv_sleep(); }
} }
} else { pv_sleep(5); } } else { pv_sleep(5); }
@ -257,6 +259,12 @@ struct device : public AVfoundationCamera{
} }
} }
void teardown() {
pause_ = true;
stopCamera();
closeCamera();
}
// void reset_options_to_default() { // void reset_options_to_default() {
// setCameraSetting(BRIGHTNESS, 120); // setCameraSetting(BRIGHTNESS, 120);
// setCameraSetting(CONTRAST, 127); // setCameraSetting(CONTRAST, 127);
@ -310,6 +318,7 @@ MYNTEYE_API bool pu_control_range(
MYNTEYE_UNUSED(option); MYNTEYE_UNUSED(option);
MYNTEYE_UNUSED(min); MYNTEYE_UNUSED(min);
MYNTEYE_UNUSED(max); MYNTEYE_UNUSED(max);
return true;
} }
MYNTEYE_API bool pu_control_query( MYNTEYE_API bool pu_control_query(
const device &device, Option option, pu_query query, int32_t *value) { const device &device, Option option, pu_query query, int32_t *value) {
@ -317,6 +326,7 @@ MYNTEYE_API bool pu_control_query(
MYNTEYE_UNUSED(option); MYNTEYE_UNUSED(option);
MYNTEYE_UNUSED(query); MYNTEYE_UNUSED(query);
MYNTEYE_UNUSED(value); MYNTEYE_UNUSED(value);
return true;
} }
// Access XU (Extension Unit) controls // Access XU (Extension Unit) controls
@ -326,6 +336,7 @@ MYNTEYE_API bool xu_control_range(
int32_t * /*min*/, int32_t * /*max*/, int32_t * /*def*/) { int32_t * /*min*/, int32_t * /*max*/, int32_t * /*def*/) {
// not supported on osx // not supported on osx
LOG(WARNING) << __func__ << " failed: this API is not supported on osx"; LOG(WARNING) << __func__ << " failed: this API is not supported on osx";
return false;
} }
MYNTEYE_API bool xu_control_query( // XU_QUERY_SET, XU_QUERY_GET MYNTEYE_API bool xu_control_query( // XU_QUERY_SET, XU_QUERY_GET
const device &/*device*/, const xu &/*xu*/, const device &/*device*/, const xu &/*xu*/,
@ -333,6 +344,7 @@ MYNTEYE_API bool xu_control_query( // XU_QUERY_SET, XU_QUERY_GET
uint16_t /*size*/, uint8_t * /*data*/) { uint16_t /*size*/, uint8_t * /*data*/) {
// not supported on osx // not supported on osx
LOG(WARNING) << __func__ << " failed: this API is not supported on osx"; LOG(WARNING) << __func__ << " failed: this API is not supported on osx";
return false;
} }
MYNTEYE_API void set_device_mode( MYNTEYE_API void set_device_mode(

View File

@ -1,326 +0,0 @@
/** @file libuvc_internal.h
* @brief Implementation-specific UVC constants and structures.
* @cond include_hidden
*/
#ifndef UVC_OSX_INTERNAL_H
#define UVC_OSX_INTERNAL_H
#include <assert.h>
#include <atomic>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <signal.h>
#include "mynteye/uvc/macosx/utlist_osx.h"
#pragma GCC diagnostic ignored "-Wpedantic"
#include <libusb-1.0/libusb.h>
/** Converts an unaligned four-byte little-endian integer into an int32 */
#define DW_TO_INT(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
/** Converts an unaligned two-byte little-endian integer into an int16 */
#define SW_TO_SHORT(p) ((p)[0] | ((p)[1] << 8))
/** Converts an unaligned eight-byte little-endian integer into an int64 */
#define QW_TO_QUAD(p) ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24) | \
((p)[4] << 32) |((p)[5] << 40) |((p)[6] << 48) |((p)[7] << 56))
/** Converts an int16 into an unaligned two-byte little-endian integer */
#define SHORT_TO_SW(s, p) \
(p)[0] = (s); \
(p)[1] = (s) >> 8;
/** Converts an int32 into an unaligned four-byte little-endian integer */
#define INT_TO_DW(i, p) \
(p)[0] = (i); \
(p)[1] = (i) >> 8; \
(p)[2] = (i) >> 16; \
(p)[3] = (i) >> 24;
/** Converts an int64 into an unaligned eight-byte little-endian integer */
#define QUAD_TO_QW(i, p) \
(p)[0] = (i); \
(p)[1] = (i) >> 8; \
(p)[2] = (i) >> 16; \
(p)[3] = (i) >> 24; \
(p)[4] = (i) >> 32; \
(p)[5] = (i) >> 40; \
(p)[6] = (i) >> 48; \
(p)[7] = (i) >> 56; \
/** Selects the nth item in a doubly linked list. n=-1 selects the last item. */
#define DL_NTH(head, out, n) \
do { \
int dl_nth_i = 0; \
LDECLTYPE(head) dl_nth_p = (head); \
if ((n) < 0) { \
while (dl_nth_p && dl_nth_i > (n)) { \
dl_nth_p = dl_nth_p->prev; \
dl_nth_i--; \
} \
} else { \
while (dl_nth_p && dl_nth_i < (n)) { \
dl_nth_p = dl_nth_p->next; \
dl_nth_i++; \
} \
} \
(out) = dl_nth_p; \
} while (0);
#ifdef UVC_DEBUGGING
#include <libgen.h>
#define UVC_DEBUG(format, ...) fprintf(stderr, "[%s:%d/%s] " format "\n", basename(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define UVC_ENTER() fprintf(stderr, "[%s:%d] begin %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
#define UVC_EXIT(code) fprintf(stderr, "[%s:%d] end %s (%d)\n", basename(__FILE__), __LINE__, __FUNCTION__, code)
#define UVC_EXIT_VOID() fprintf(stderr, "[%s:%d] end %s\n", basename(__FILE__), __LINE__, __FUNCTION__)
#else
#define UVC_DEBUG(format, ...)
#define UVC_ENTER()
#define UVC_EXIT_VOID()
#define UVC_EXIT(code)
#endif
/* http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers */
#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
#define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))
/** Video interface subclass code (A.2) */
enum uvc_int_subclass_code {
UVC_SC_UNDEFINED = 0x00,
UVC_SC_VIDEOCONTROL = 0x01,
UVC_SC_VIDEOSTREAMING = 0x02,
UVC_SC_VIDEO_INTERFACE_COLLECTION = 0x03
};
/** Video interface protocol code (A.3) */
enum uvc_int_proto_code {
UVC_PC_PROTOCOL_UNDEFINED = 0x00
};
/** VideoControl interface descriptor subtype (A.5) */
enum uvc_vc_desc_subtype {
UVC_VC_DESCRIPTOR_UNDEFINED = 0x00,
UVC_VC_HEADER = 0x01,
UVC_VC_INPUT_TERMINAL = 0x02,
UVC_VC_OUTPUT_TERMINAL = 0x03,
UVC_VC_SELECTOR_UNIT = 0x04,
UVC_VC_PROCESSING_UNIT = 0x05,
UVC_VC_EXTENSION_UNIT = 0x06
};
/** UVC endpoint descriptor subtype (A.7) */
enum uvc_ep_desc_subtype {
UVC_EP_UNDEFINED = 0x00,
UVC_EP_GENERAL = 0x01,
UVC_EP_ENDPOINT = 0x02,
UVC_EP_INTERRUPT = 0x03
};
/** VideoControl interface control selector (A.9.1) */
enum uvc_vc_ctrl_selector {
UVC_VC_CONTROL_UNDEFINED = 0x00,
UVC_VC_VIDEO_POWER_MODE_CONTROL = 0x01,
UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02
};
/** Terminal control selector (A.9.2) */
enum uvc_term_ctrl_selector {
UVC_TE_CONTROL_UNDEFINED = 0x00
};
/** Selector unit control selector (A.9.3) */
enum uvc_su_ctrl_selector {
UVC_SU_CONTROL_UNDEFINED = 0x00,
UVC_SU_INPUT_SELECT_CONTROL = 0x01
};
/** Extension unit control selector (A.9.6) */
enum uvc_xu_ctrl_selector {
UVC_XU_CONTROL_UNDEFINED = 0x00
};
/** VideoStreaming interface control selector (A.9.7) */
enum uvc_vs_ctrl_selector {
UVC_VS_CONTROL_UNDEFINED = 0x00,
UVC_VS_PROBE_CONTROL = 0x01,
UVC_VS_COMMIT_CONTROL = 0x02,
UVC_VS_STILL_PROBE_CONTROL = 0x03,
UVC_VS_STILL_COMMIT_CONTROL = 0x04,
UVC_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
UVC_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
UVC_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
UVC_VS_SYNC_DELAY_CONTROL = 0x09
};
/** Status packet type (2.4.2.2) */
enum uvc_status_type {
UVC_STATUS_TYPE_CONTROL = 1,
UVC_STATUS_TYPE_STREAMING = 2
};
/** Payload header flags (2.4.3.3) */
#define UVC_STREAM_EOH (1 << 7)
#define UVC_STREAM_ERR (1 << 6)
#define UVC_STREAM_STI (1 << 5)
#define UVC_STREAM_RES (1 << 4)
#define UVC_STREAM_SCR (1 << 3)
#define UVC_STREAM_PTS (1 << 2)
#define UVC_STREAM_EOF (1 << 1)
#define UVC_STREAM_FID (1 << 0)
/** Control capabilities (4.1.2) */
#define UVC_CONTROL_CAP_GET (1 << 0)
#define UVC_CONTROL_CAP_SET (1 << 1)
#define UVC_CONTROL_CAP_DISABLED (1 << 2)
#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
struct uvc_streaming_interface;
struct uvc_device_info;
/** VideoStream interface */
typedef struct uvc_streaming_interface {
struct uvc_device_info *parent;
struct uvc_streaming_interface *prev, *next;
/** Interface number */
uint8_t bInterfaceNumber;
/** Video formats that this interface provides */
struct uvc_format_desc *format_descs;
/** USB endpoint to use when communicating with this interface */
uint8_t bEndpointAddress;
uint8_t bTerminalLink;
} uvc_streaming_interface_t;
/** VideoControl interface */
typedef struct uvc_control_interface {
struct uvc_device_info *parent;
struct uvc_input_terminal *input_term_descs;
// struct uvc_output_terminal *output_term_descs;
struct uvc_selector_unit *selector_unit_descs;
struct uvc_processing_unit *processing_unit_descs;
struct uvc_extension_unit *extension_unit_descs;
uint16_t bcdUVC;
uint32_t dwClockFrequency;
uint8_t bEndpointAddress;
/** Interface number */
uint8_t bInterfaceNumber;
} uvc_control_interface_t;
struct uvc_stream_ctrl;
struct uvc_device {
struct uvc_context *ctx;
int ref;
libusb_device *usb_dev;
int interface;
};
typedef struct uvc_device_info {
/** Configuration descriptor for USB device */
struct libusb_config_descriptor *config;
/** VideoControl interface provided by device */
uvc_control_interface_t ctrl_if;
/** VideoStreaming interfaces on the device */
uvc_streaming_interface_t *stream_ifs;
/** Store the interface for multiple UVCs on a single VID/PID device (Intel RealSense, VF200, e.g) */
int camera_number;
} uvc_device_info_t;
/*
set a high number of transfer buffers. This uses a lot of ram, but
avoids problems with scheduling delays on slow boards causing missed
transfers. A better approach may be to make the transfer thread FIFO
scheduled (if we have root).
We could/should change this to allow reduce it to, say, 5 by default
and then allow the user to change the number of buffers as required.
*/
#define LIBUVC_NUM_TRANSFER_BUFS 1
#define LIBUVC_XFER_BUF_SIZE ( 16 * 1024 * 1024 )
struct uvc_stream_handle {
struct uvc_device_handle *devh;
struct uvc_stream_handle *prev, *next;
struct uvc_streaming_interface *stream_if;
/** if true, stream is running (streaming video to host) */
std::atomic<uint8_t> running;
/** Current control block */
struct uvc_stream_ctrl cur_ctrl;
/* listeners may only access hold*, and only when holding a
* lock on cb_mutex (probably signaled with cb_cond) */
uint8_t fid;
uint32_t seq, hold_seq;
uint32_t pts, hold_pts;
uint32_t last_scr, hold_last_scr;
uint8_t *metadata_buf;
size_t metadata_bytes,metadata_size;
size_t got_bytes, hold_bytes;
uint8_t *outbuf, *holdbuf;
std::mutex cb_mutex;
std::condition_variable cb_cond;
std::thread cb_thread;
uint32_t last_polled_seq;
uvc_frame_callback_t *user_cb;
void *user_ptr;
struct libusb_transfer *transfers[LIBUVC_NUM_TRANSFER_BUFS];
uint8_t *transfer_bufs[LIBUVC_NUM_TRANSFER_BUFS];
std::condition_variable transfer_cancel[LIBUVC_NUM_TRANSFER_BUFS];
struct uvc_frame frame;
enum uvc_frame_format frame_format;
};
/** Handle on an open UVC device
*
* @todo move most of this into a uvc_device struct?
*/
struct uvc_device_handle {
struct uvc_device *dev;
struct uvc_device_handle *prev, *next;
/** Underlying USB device handle */
libusb_device_handle *usb_devh;
struct uvc_device_info *info;
struct libusb_transfer *status_xfer;
uint8_t status_buf[32];
/** Function to call when we receive status updates from the camera */
uvc_status_callback_t *status_cb;
void *status_user_ptr;
/** Function to call when we receive button events from the camera */
uvc_button_callback_t *button_cb;
void *button_user_ptr;
uvc_stream_handle_t *streams;
/** Whether the camera is an iSight that sends one header per frame */
uint8_t is_isight;
};
/** Context within which we communicate with devices */
struct uvc_context {
/** Underlying context for USB communication */
struct libusb_context *usb_ctx;
/** True iff libuvc initialized the underlying USB context */
uint8_t own_usb_ctx;
/** List of open devices in this context */
uvc_device_handle_t *open_devices;
std::thread handler_thread;
int kill_handler_thread;
};
uvc_error_t uvc_query_stream_ctrl(
uvc_device_handle_t *devh,
uvc_stream_ctrl_t *ctrl,
uint8_t probe,
enum uvc_req_code req);
void uvc_start_handler_thread(uvc_context_t *ctx);
uvc_error_t uvc_claim_if(uvc_device_handle_t *devh, int idx);
uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx);
#endif // !def(UVC_OSX_INTERNAL_H)
/** @endcond */