From d45ca2422fd5bedf48d68a3a537bae924b0cbae7 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 18 Sep 2020 20:12:53 +0200 Subject: Implement additional VISCA channels --- backends/visca.c | 28 ++++++++++++++++++++++++++++ backends/visca.h | 21 ++++++++++++++++++++- backends/visca.md | 16 ++++++++++++++-- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/backends/visca.c b/backends/visca.c index d408b80..32f11c9 100644 --- a/backends/visca.c +++ b/backends/visca.c @@ -8,6 +8,7 @@ /* TODO * VISCA server * Rate limiting + * Inquiry */ MM_PLUGIN_API int init(){ @@ -175,6 +176,13 @@ static size_t ptz_set_ptspeed(instance* inst, channel* c, channel_value* v, uint return 0; } +static size_t ptz_set_stop(instance* inst, channel* c, channel_value* v, uint8_t* msg){ + ptz_instance_data* data = (ptz_instance_data*) inst->impl; + msg[4] = data->panspeed; + msg[5] = data->tiltspeed; + return ptz_channels[stop].bytes; +} + static size_t ptz_set_zoom(instance* inst, channel* c, channel_value* v, uint8_t* msg){ uint16_t position = ((ptz_channels[zoom].max - ptz_channels[zoom].min) * v->normalised) + ptz_channels[zoom].min - ptz_channels[zoom].offset; msg[4] = ((position & 0xF000) >> 12); @@ -193,6 +201,24 @@ static size_t ptz_set_focus(instance* inst, channel* c, channel_value* v, uint8_ return ptz_channels[focus].bytes; } +static size_t ptz_set_focus_mode(instance* inst, channel* c, channel_value* v, uint8_t* msg){ + msg[4] = (v->normalised > 0.9) ? 2 : 3; + return ptz_channels[focus_mode].bytes; +} + +static size_t ptz_set_wb_mode(instance* inst, channel* c, channel_value* v, uint8_t* msg){ + msg[4] = (v->normalised > 0.9) ? 0 : 5; + return ptz_channels[wb_mode].bytes; +} + +static size_t ptz_set_wb(instance* inst, channel* c, channel_value* v, uint8_t* msg){ + uint8_t command = c->ident & 0xFF; + uint8_t value = ((ptz_channels[command].max - ptz_channels[command].min) * v->normalised) + ptz_channels[command].min - ptz_channels[command].offset; + msg[6] = value >> 4; + msg[7] = value & 0x0F; + return ptz_channels[command].bytes; +} + static size_t ptz_set_memory(instance* inst, channel* c, channel_value* v, uint8_t* msg){ if(v->normalised < 0.9){ return 0; @@ -223,6 +249,8 @@ static int ptz_set(instance* inst, size_t num, channel** c, channel_value* v){ if(ptz_channels[command].bytes){ memcpy(tx, ptz_channels[command].pattern, ptz_channels[command].bytes); + //if no handler function set, assume a parameterless command and send verbatim + bytes = ptz_channels[command].bytes; } tx[0] = 0x80 | (data->cam_address & 0xF); diff --git a/backends/visca.h b/backends/visca.h index 09c9057..481f5c7 100644 --- a/backends/visca.h +++ b/backends/visca.h @@ -28,8 +28,14 @@ enum /*ptz_channels*/ { tiltspeed, zoom, focus, + focus_mode, + wb_red, + wb_blue, + wb_mode, call, store, + home, + stop, sentinel }; @@ -38,9 +44,15 @@ static size_t ptz_set_pantilt(instance* inst, channel* c, channel_value* v, uint static size_t ptz_set_ptspeed(instance* inst, channel* c, channel_value* v, uint8_t* msg); static size_t ptz_set_zoom(instance* inst, channel* c, channel_value* v, uint8_t* msg); static size_t ptz_set_focus(instance* inst, channel* c, channel_value* v, uint8_t* msg); +static size_t ptz_set_focus_mode(instance* inst, channel* c, channel_value* v, uint8_t* msg); +static size_t ptz_set_wb_mode(instance* inst, channel* c, channel_value* v, uint8_t* msg); +static size_t ptz_set_wb(instance* inst, channel* c, channel_value* v, uint8_t* msg); static size_t ptz_set_memory(instance* inst, channel* c, channel_value* v, uint8_t* msg); static size_t ptz_set_memory_store(instance* inst, channel* c, channel_value* v, uint8_t* msg); +//relative move test +static size_t ptz_set_stop(instance* inst, channel* c, channel_value* v, uint8_t* msg); + static struct { char* name; size_t bytes; @@ -56,6 +68,13 @@ static struct { [tiltspeed] = {"tiltspeed", 0, {0}, 0x01, 0x14, 0, ptz_set_ptspeed}, [zoom] = {"zoom", 9, {0x80, 0x01, 0x04, 0x47, 0, 0, 0, 0, 0xFF}, 0, 0x4000, 0, ptz_set_zoom}, [focus] = {"focus", 9, {0x80, 0x01, 0x04, 0x48, 0, 0, 0, 0, 0xFF}, 0, 0x4000, 0, ptz_set_focus}, + [focus_mode] = {"autofocus", 6, {0x80, 0x01, 0x04, 0x38, 0, 0xFF}, 0, 1, 0, ptz_set_focus_mode}, + [wb_mode] = {"wb.auto", 6, {0x80, 0x01, 0x04, 0x35, 0, 0xFF}, 0, 1, 0, ptz_set_wb_mode}, + [wb_red] = {"wb.red", 9, {0x80, 0x01, 0x04, 0x43, 0x00, 0x00, 0, 0, 0xFF}, 0, 255, 0, ptz_set_wb}, + [wb_blue] = {"wb.blue", 9, {0x80, 0x01, 0x04, 0x44, 0x00, 0x00, 0, 0, 0xFF}, 0, 255, 0, ptz_set_wb}, [call] = {"memory", 7, {0x80, 0x01, 0x04, 0x3F, 0x02, 0, 0xFF}, 0, 254, 0, ptz_set_memory}, - [store] = {"store", 7, {0x80, 0x01, 0x04, 0x3F, 0x01, 0, 0xFF}, 0, 254, 0, ptz_set_memory_store} + [store] = {"store", 7, {0x80, 0x01, 0x04, 0x3F, 0x01, 0, 0xFF}, 0, 254, 0, ptz_set_memory_store}, + [home] = {"home", 5, {0x80, 0x01, 0x06, 0x04, 0xFF}, 0, 0, 0, NULL}, + //relative move test + [stop] = {"stop", 9, {0x80, 0x01, 0x06, 0x01, 0, 0, 0x03, 0x03, 0xFF}, 0, 0, 0, ptz_set_stop} }; diff --git a/backends/visca.md b/backends/visca.md index 4fe1933..d4fc432 100644 --- a/backends/visca.md +++ b/backends/visca.md @@ -29,6 +29,10 @@ Each instance exposes the following channels * `tiltspeed`: Tilt speed * `zoom`: Zoom position * `focus`: Focus position +* `autofocus`: Switch between autofocus (events > 0.9) and manual focus drive mode +* `wb.auto`: Switch between automatic white balance mode (events > 0.9) and manual white balance mode +* `wb.red`, `wb.blue`: Red/Blue channel white balance gain values +* `home`: Return to home position * `memory`: Call memory (if incoming event value is greater than 0.9) * `store`: Store current pan/tilt/zoom setup to memory (if incoming event value is greater than 0.9) @@ -40,12 +44,20 @@ control.tilt > visca.tilt control.btn1 > visca.memory1 ``` +#### Compatability list + +| Manufacturer | Exact model(s) tested | Compatible models | Result / Notes | +|---------------|-------------------------------|-----------------------------------------------|-------------------------------------------------------| +| ValueHD | VHD-V61 | Probably all ValueHD Visca-capable devices | Everything works except for absolute focus control | +| PTZOptics | | Probably all of their PTZ cameras | See ValueHD | + #### Known bugs / problems Value readback / Inquiry is not yet implemented. This backend currently only does output. Some manufacturers use VISCA, but require special framing for command flow control. This may be implemented -in the future if there is sufficient interest. +in the future if there is sufficient interest. Some commands may not work with some manufacturer's cameras due to +different value ranges or command ordering. Please file a ticket if you can confirm this backend working/nonworking with a new make or model -of camera so we can add it to the compatability list! +of camera so we can add it to the compatibility list! -- cgit v1.2.3