Skip to content

Commit

Permalink
Merge pull request #2039 from dorodnic/libuvc_multicamera
Browse files Browse the repository at this point in the history
Libuvc multicamera
  • Loading branch information
dorodnic committed Jul 12, 2018
2 parents 2e0d5ba + dbe9d88 commit 691cdb0
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 102 deletions.
79 changes: 41 additions & 38 deletions src/libuvc/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,53 +131,56 @@ int uvc_already_open(uvc_context_t *ctx, struct libusb_device *usb_dev) {
*/
uvc_error_t uvc_find_device(
uvc_context_t *ctx, uvc_device_t **dev,
int vid, int pid, const char *sn) {
uvc_error_t ret = UVC_SUCCESS;
int vid, int pid, const char *sn, std::function<bool(uvc_device_t*)> predicate)
{
uvc_error_t ret = UVC_SUCCESS;

uvc_device_t **list;
uvc_device_t *test_dev;
int dev_idx;
int found_dev;
uvc_device_t **list;
uvc_device_t *test_dev;
int dev_idx;
int found_dev;

UVC_ENTER();
UVC_ENTER();

ret = uvc_get_device_list(ctx, &list);
ret = uvc_get_device_list(ctx, &list);

if (ret != UVC_SUCCESS) {
UVC_EXIT(ret);
return ret;
}

dev_idx = 0;
found_dev = 0;

while (!found_dev && (test_dev = list[dev_idx++]) != NULL) {
uvc_device_descriptor_t *desc;

if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
continue;
if (ret != UVC_SUCCESS) {
UVC_EXIT(ret);
return ret;
}

if ((!vid || desc->idVendor == vid)
&& (!pid || desc->idProduct == pid)
&& (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn))))
found_dev = 1;
dev_idx = 0;
found_dev = 0;

while (!found_dev && (test_dev = list[dev_idx++]) != NULL) {
uvc_device_descriptor_t *desc;

if (uvc_get_device_descriptor(test_dev, &desc) != UVC_SUCCESS)
continue;

if ((!vid || desc->idVendor == vid)
&& (!pid || desc->idProduct == pid)
&& (!sn || (desc->serialNumber && !strcmp(desc->serialNumber, sn))))
{
if (predicate(test_dev))
found_dev = 1;
}

uvc_free_device_descriptor(desc);
}
uvc_free_device_descriptor(desc);
}

if (found_dev)
uvc_ref_device(test_dev);
if (found_dev) uvc_ref_device(test_dev);

uvc_free_device_list(list, 1);
uvc_free_device_list(list, 1);

if (found_dev) {
*dev = test_dev;
UVC_EXIT(UVC_SUCCESS);
return UVC_SUCCESS;
} else {
UVC_EXIT(UVC_ERROR_NO_DEVICE);
return UVC_ERROR_NO_DEVICE;
}
if (found_dev) {
*dev = test_dev;
UVC_EXIT(UVC_SUCCESS);
return UVC_SUCCESS;
} else {
UVC_EXIT(UVC_ERROR_NO_DEVICE);
return UVC_ERROR_NO_DEVICE;
}
}

/** @brief Finds all cameras identified by vendor, product and/or serial number
Expand Down
122 changes: 59 additions & 63 deletions src/libuvc/libuvc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ namespace librealsense

/* callback context send for each frame for its specific profile */
struct callback_context {
frame_callback _callback;
stream_profile _profile;
libuvc_uvc_device *_this;
frame_callback _callback;
stream_profile _profile;
libuvc_uvc_device *_this;
};

/* implements uvc_device for libUVC support */
Expand Down Expand Up @@ -281,7 +281,6 @@ namespace librealsense
_state_change_time = 0;
_is_power_thread_alive = true;
_thread_handle = std::thread(std::bind(&libuvc_uvc_device::power_thread,this));

}

~libuvc_uvc_device()
Expand Down Expand Up @@ -309,8 +308,7 @@ namespace librealsense
if (res < 0) {
uvc_close(_device_handle);
uvc_unref_device(_device);
throw linux_backend_exception(
"Could not get stream format.");
throw linux_backend_exception("Could not get stream format.");
}

// add to the vector of profiles.
Expand All @@ -322,26 +320,22 @@ namespace librealsense
/* request to start streaming*/
void stream_on(std::function<void(const notification& n)> error_handler) override
{
uvc_error_t res;
// loop over each prfile and start streaming.
for (auto i=0;i< _profiles.size(); ++i) {
callback_context *context = new callback_context();
context->_callback = _callbacks[i];
context->_this = this;
context->_profile = _profiles[i];

res = uvc_start_streaming(_device_handle,
&_stream_ctrls[i],
internal_uvc_callback,
context,
0);

if (res < 0) {
throw linux_backend_exception(
"fail to start streaming.");

uvc_error_t res;
// loop over each prfile and start streaming.
for (auto i=0; i < _profiles.size(); ++i) {
callback_context *context = new callback_context();
context->_callback = _callbacks[i];
context->_this = this;
context->_profile = _profiles[i];

res = uvc_start_streaming(_device_handle,
&_stream_ctrls[i],
internal_uvc_callback,
context,
0);

if (res < 0) throw linux_backend_exception("fail to start streaming.");
}
}
}

void start_callbacks() override
Expand All @@ -362,56 +356,58 @@ namespace librealsense
_is_capturing = false;
_is_started = false;
}

}

void power_D0() {
uvc_error_t res;
uvc_format_t *formats;
uvc_error_t res;
uvc_format_t *formats;

res = uvc_find_device(_ctx, &_device, _info.vid, _info.pid, NULL);
res = uvc_find_device(_ctx, &_device, _info.vid, _info.pid, NULL,
[&](uvc_device_t* device){
auto dev = (uvc_device_internal *) device;
auto usb_params = get_usb_descriptors(dev->usb_dev);
return _info.unique_id == std::get<0>(usb_params);
});

if (res < 0) {
throw linux_backend_exception(
"Could not find the device.");
}
res = uvc_open2(_device, &_device_handle, _interface);
if (res < 0)
throw linux_backend_exception("Could not find the device.");
res = uvc_open2(_device, &_device_handle, _interface);

if (res < 0) {
uvc_unref_device(_device);
_device = NULL;
throw linux_backend_exception(
"Could not open device.");
}
if (res < 0) {
uvc_unref_device(_device);
_device = NULL;
throw linux_backend_exception("Could not open device.");
}

for(auto ct = uvc_get_input_terminals(_device_handle);
ct; ct = ct->next) {
_input_terminal = ct->bTerminalID;
}
for(auto ct = uvc_get_input_terminals(_device_handle);
ct; ct = ct->next) {
_input_terminal = ct->bTerminalID;
}

for(auto pu = uvc_get_processing_units(_device_handle);
pu; pu = pu->next) {
_processing_unit = pu->bUnitID;
}
for(auto pu = uvc_get_processing_units(_device_handle);
pu; pu = pu->next) {
_processing_unit = pu->bUnitID;
}

for(auto eu = uvc_get_extension_units(_device_handle);
eu; eu = eu->next) {
_extension_unit = eu->bUnitID;
}
for(auto eu = uvc_get_extension_units(_device_handle);
eu; eu = eu->next) {
_extension_unit = eu->bUnitID;
}

_real_state = D0;
_real_state = D0;
}

void power_D3() {

uvc_unref_device(_device);
//uvc_stop_streaming(_device_handle);
_profiles.clear();
uvc_close(_device_handle);
_device = NULL;
_device_handle = NULL;
_real_state = D3;
}
//uvc_stop_streaming(_device_handle);
_profiles.clear();
uvc_close(_device_handle);
_device = NULL;
_device_handle = NULL;
_real_state = D3;
}

void set_power_state(power_state state) override {
std::lock_guard<std::mutex> lock(_power_mutex);

Expand All @@ -422,7 +418,7 @@ namespace librealsense
_state_change_time = 0;

if ( _real_state == D3) {
power_D0();
power_D0();
}
}
else {
Expand Down Expand Up @@ -684,8 +680,8 @@ namespace librealsense
_state_change_time = 0;

if (_real_state == D0) {
power_D3();
_real_state = D3;
power_D3();
_real_state = D3;

}
}
Expand Down
5 changes: 4 additions & 1 deletion src/libuvc/libuvc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef LIBUVC_H
#define LIBUVC_H

#include <functional>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -531,7 +533,8 @@ uint8_t uvc_get_device_address(uvc_device_t *dev);
uvc_error_t uvc_find_device(
uvc_context_t *ctx,
uvc_device_t **dev,
int vid, int pid, const char *sn);
int vid, int pid, const char *sn,
std::function<bool(uvc_device_t *)> predicate);

uvc_error_t uvc_find_devices(
uvc_context_t *ctx,
Expand Down

0 comments on commit 691cdb0

Please sign in to comment.