aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--backends/visca.c28
-rw-r--r--backends/visca.h21
-rw-r--r--backends/visca.md16
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<n>`: Call memory <n> (if incoming event value is greater than 0.9)
* `store<n>`: Store current pan/tilt/zoom setup to memory <n> (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!