Skip to content

Commit

Permalink
Added backlight compensation camera.backlightCompensation. Added po…
Browse files Browse the repository at this point in the history
…werline frequency `camera.powerlineFrequency`. Can now set focus and focus auto, not just get the values.
  • Loading branch information
larryaasen committed Mar 18, 2024
1 parent 618145c commit f2d821b
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 110 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Next

- Added backlight compensation `camera.backlightCompensation`.
- Added powerline frequency `camera.powerlineFrequency`.
- Can now set focus and focus auto, not just get the values.

## 1.0.0

- Initial version with support for pan, tilt, zoom, and focus. Runs on macOS and Windows.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void main() {
print('zoom: ${camera.zoom.current}');
camera.zoom.current = 225;
camera.close();
uvc.dispose();
}
Expand Down Expand Up @@ -117,6 +118,12 @@ camera.zoom.min;
camera.zoom.resolution;
```

### Backlight Compensation

```
camera.backlightCompensation.current;
```

### Focus

```
Expand All @@ -129,6 +136,12 @@ camera.zoom.current;
camera.focusAuto.current;
```

### Powerline Frequency

```
camera.powerlineFrequency.current;
```

## Debugging

You can enable logging in `UvcLib` for troubleshooting. Just pass `true` to `debugLogging` when creating `UvcLib`.
Expand Down
27 changes: 0 additions & 27 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,8 @@ This is a list of todo items, mostly in the order in which they will be implemen

- Restructure code to be cleaner and more organized.
- Remove all lint ignore_for_file comments.
- Rename UvcLib to UVCLib since UVCControl is that way, or rename UVCControl to UvcControl.
- Finish cleaning up uvc_example.dart for release.
- Finish README.
- Fix the libusb exit errors.
- Publish first version as 1.0.0 on pub.dev.
- Determine how to know if a control, like zoom, is supported.
- Finish using debugLogging everywhere.
- All constants and functions should be moved inside of some class or enum.
- Add support for Linux.
- Add support for video streaming.

## Exit errors from libusb
```
[ 0.198460] [0014c208] libusb: debug [libusb_exit]
[ 0.198467] [0014c208] libusb: debug [libusb_unref_device] destroy device 0.5
[ 0.198470] [0014c208] libusb: debug [libusb_unref_device] destroy device 0.4
[ 0.198473] [0014c208] libusb: debug [libusb_unref_device] destroy device 0.3
[ 0.198475] [0014c208] libusb: debug [libusb_unref_device] destroy device 0.2
[ 0.198476] [0014c208] libusb: debug [libusb_unref_device] destroy device 0.1
[ 0.198478] [0014c208] libusb: debug [libusb_unref_device] destroy device 20.6
[ 0.198480] [0014c208] libusb: debug [libusb_unref_device] destroy device 1.2
[ 0.198482] [0014c208] libusb: debug [libusb_unref_device] destroy device 20.5
[ 0.198506] [0014c209] libusb: debug [darwin_event_thread_main] darwin event thread exiting
[ 0.198613] [0014c208] libusb: error [darwin_cleanup_devices] device still referenced at libusb_exit
[ 0.198797] [0014c208] libusb: error [darwin_cleanup_devices] device still referenced at libusb_exit
[ 0.199063] [0014c208] libusb: error [darwin_cleanup_devices] device still referenced at libusb_exit
[ 0.199507] [0014c208] libusb: debug [usbi_remove_event_source] remove fd 6
[ 0.199522] [0014c208] libusb: warning [libusb_exit] device 20.10 still referenced
[ 0.199524] [0014c208] libusb: warning [libusb_exit] device 20.9 still referenced
[ 0.199526] [0014c208] libusb: warning [libusb_exit] device 20.8 still referenced
[ 0.199528] [0014c208] libusb: warning [libusb_exit] application left some devices open
```
1 change: 1 addition & 0 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void main() {
print('zoom: ${camera.zoom.current}');

camera.zoom.current = 225;
camera.close();

uvc.dispose();
}
32 changes: 12 additions & 20 deletions example/uvc_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import 'package:uvc/uvc.dart';

Future<void> main() async {
final uvc = UvcLib(debugLogging: true, debugLoggingLibUsb: false);
final uvc = UvcLib();

printUvcDevices(uvc);
printUsbDevices(uvc);
Expand All @@ -27,44 +27,36 @@ void printUsbDevices(UvcLib uvc) {
}

Future<void> cameraExample(UvcLib uvc) async {
// final camera = uvc.control(vendorId: 0x1532, productId: 0x0E05); // Razer Kiyo Pro
final camera = uvc.control(vendorId: 0x046D, productId: 0x0825); // Logitech
final camera =
uvc.control(vendorId: 0x1532, productId: 0x0E05); // Razer Kiyo Pro
// final camera = uvc.control(vendorId: 0x046D, productId: 0x0825); // Logitech

try {
// camera.zoom.current;
// camera.zoom.min;
// camera.zoom.max;
// camera.zoom.defaultValue;
// camera.zoom.info;
camera.zoom.current;
camera.zoom.min;
camera.zoom.max;
camera.zoom.defaultValue;
// camera.zoom.information;
// camera.zoom.len;
camera.zoom.resolution;
} catch (e) {
print('example: camera zoom set error: $e');
camera.close();
return;
}

try {
printValues('backlight compensation', camera.backlightCompensation);
printValues('focus (auto)', camera.focusAuto);
printValues('focus', camera.focus);
printValues('zoom', camera.zoom);
printValues('pan', camera.pan);
printValues('tilt', camera.tilt);
printValues('zoom', camera.zoom);
printValues('powerline frequency', camera.powerlineFrequency);
} catch (e) {
print('example: camera error: $e');
}

// print("zoom relative current: ${camera.zoom.current}");
// print("zoom absolute current: ${camera.zoom.current}");

camera.pan.current;
camera.pan.min;
camera.tilt.current;
camera.tilt.min;

camera.focus.current;
camera.focusAuto.current;

await animateValue(
Duration(seconds: 5), 100, 400, (value) => camera.zoom.current = value);

Expand Down
21 changes: 20 additions & 1 deletion lib/src/usb_configuration_descriptor_ext.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ extension UsbConfigurationDescriptorExt on UsbConfigDescriptor {
// ret = uvc_parse_vc_selector_unit(dev, info, block, block_size);
break;
case uvc_vc_desc_subtype.UVC_VC_PROCESSING_UNIT:
// ret = uvc_parse_vc_processing_unit(dev, info, block, block_size);
ret = uvc_parse_vc_processing_unit(usbDevPtr, info, block, block_size);
break;
case uvc_vc_desc_subtype.UVC_VC_EXTENSION_UNIT:
// ret = uvc_parse_vc_extension_unit(dev, info, block, block_size);
Expand Down Expand Up @@ -318,6 +318,25 @@ extension UsbConfigurationDescriptorExt on UsbConfigDescriptor {

return (UVC_SUCCESS, term);
}

/// Parse a VideoControl processing unit.
static int uvc_parse_vc_processing_unit(Pointer<libusb_device> usbDevPtr,
uvc_device_info info, Uint8List block, int block_size) {
int bUnitID = block[3];
int bSourceID = block[4];
int bmControls = 0;

for (var i = 7 + block[7]; i >= 8; --i) {
bmControls = block[i] + (bmControls << 8);
}

final unit = uvc_processing_unit(
bUnitID: bUnitID, bSourceID: bSourceID, bmControls: bmControls);

info.ctrl_if?.processing_unit_descs.add(unit);

return UVC_SUCCESS;
}
}

extension UsbInterfaceDescriptorExt on UsbInterfaceDescriptor {
Expand Down
4 changes: 4 additions & 0 deletions lib/src/usb_device_descriptor_ext.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ extension UsbDeviceDescriptorExt on UsbDeviceDescriptor {
final handlePtr = calloc<Pointer<libusb_device_handle>>();
if (libusb.libusb_open(usbDevPtr, handlePtr) ==
libusb_error.LIBUSB_SUCCESS) {
// print('uvc: opened device');

final handle = handlePtr.value;

manufacturer =
Expand All @@ -34,6 +36,8 @@ extension UsbDeviceDescriptorExt on UsbDeviceDescriptor {

libusb.libusb_close(handle);
calloc.free(handlePtr);

// print('uvc: closed device');
}

final desc = UsbDeviceDescriptor(
Expand Down
10 changes: 6 additions & 4 deletions lib/src/usb_devices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ class UsbDevices {
/// Creates access to all USB devices, including UVC devices.
UsbDevices({required this.libusb});

final Libusb libusb;
final Libusb? libusb;

/// Get all of the USB devices on this system, or just the UVC USB devices.
List<UsbDevice> get({bool onlyUvcDevices = false}) =>
_getDevices(onlyUvcDevices: onlyUvcDevices);

/// Get all of the UVC devices on this system.
List<UsbDevice> _getDevices({bool onlyUvcDevices = false}) {
if (libusb == null) return [];
var deviceListPtr = calloc<Pointer<Pointer<libusb_device>>>();

final numUsbDevices = libusb.libusb_get_device_list(nullptr, deviceListPtr);
final numUsbDevices =
libusb!.libusb_get_device_list(nullptr, deviceListPtr);
if (numUsbDevices < 0) {
calloc.free(deviceListPtr);
return [];
Expand All @@ -35,15 +37,15 @@ class UsbDevices {

for (var devIdx = 0; devIdx < numUsbDevices; devIdx++) {
final usbDevPtr = deviceList[devIdx];
final usbDevice = UsbDeviceExt.fromDev(libusb, usbDevPtr);
final usbDevice = UsbDeviceExt.fromDev(libusb!, usbDevPtr);
if (usbDevice == null) continue;
if (!onlyUvcDevices || usbDevice.isUvc) {
listInternal.add(usbDevice);
}
}

libusb!.libusb_free_device_list(deviceList, 1);
calloc.free(deviceListPtr);
libusb.libusb_free_device_list(deviceList, 1);

return listInternal;
}
Expand Down
Loading

0 comments on commit f2d821b

Please sign in to comment.