From 34a41aa9a94e16413284b5fdb38e7b819eb5bdff Mon Sep 17 00:00:00 2001 From: Norihiro Kamae Date: Wed, 10 Jul 2024 18:24:14 +0900 Subject: [PATCH] ptz: Gather device-specific information to one place --- CMakeLists.txt | 2 +- src/face-tracker-ptz.cpp | 169 +++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 78 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41bd8ca..d5870f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ option(ENABLE_DATAGEN "Enable generating data" OFF) set(CMAKE_PREFIX_PATH "${QTDIR}") -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(plugin_additional_libs) diff --git a/src/face-tracker-ptz.cpp b/src/face-tracker-ptz.cpp index 0d35742..201963d 100644 --- a/src/face-tracker-ptz.cpp +++ b/src/face-tracker-ptz.cpp @@ -95,6 +95,67 @@ struct ptz_copy_setting_item_s void (*copy)(obs_data_t *, const char *, obs_data_t *, const char *); }; +struct ptz_backend_type_s +{ + const char *backend_name; + class ptz_backend *(*make_device)(obs_data_t *data); + const struct ptz_copy_setting_item_s *list_settings; +}; + +static class ptz_backend *make_device_libvisca_tcp(obs_data_t *data); + +static const struct ptz_copy_setting_item_s list_obsptz[] = { + {"device_id", "ptz-obsptz-device_id", copy_int}, + {NULL, NULL, NULL} +}; + +static const struct ptz_copy_setting_item_s list_viscaip[] = { + {"address", "ptz-viscaip-address", copy_string}, + {"port", "ptz-viscaip-port", copy_int}, + {NULL, NULL, NULL} +}; + +static const struct ptz_backend_type_s backends[] = +{ + { + .backend_name = "obsptz", + .make_device = [](obs_data_t *data) -> class ptz_backend *{ + auto dev = new obsptz_backend(); + dev->set_config(data); + return dev; + }, + .list_settings = list_obsptz, + }, +#ifdef WITH_PTZ_TCP + { + .backend_name = "visca-over-tcp", + .make_device = make_device_libvisca_tcp, + .list_settings = list_viscaip, + }, +#endif // WITH_PTZ_TCP + { + .backend_name = "dummy", + .make_device = [](obs_data_t *) -> class ptz_backend *{ + return new dummy_backend(); + }, + .list_settings = NULL, + }, + {NULL, NULL, NULL} +}; + +static const struct ptz_backend_type_s *get_backend(const char *ptz_type) +{ + if (!ptz_type) + return nullptr; + + for (int i = 0; backends[i].backend_name; i++) { + if (strcmp(ptz_type, backends[i].backend_name) == 0) + return backends + i; + } + + return nullptr; +} + static void ptz_copy_settings(obs_data_t *data, obs_data_t *settings, const struct ptz_copy_setting_item_s *list) { for (int i=0; list[i].dst; i++) @@ -105,62 +166,40 @@ static obs_data_t *get_ptz_settings(obs_data_t *settings) { obs_data_t *data = obs_data_create(); - const struct ptz_copy_setting_item_s list_generic[] = { - {"type", "ptz-type", copy_string}, - {NULL, NULL, NULL} - }; - - const struct ptz_copy_setting_item_s list_obsptz[] = { - {"device_id", "ptz-obsptz-device_id", copy_int}, - {NULL, NULL, NULL} - }; - - const struct ptz_copy_setting_item_s list_viscaip[] = { - {"address", "ptz-viscaip-address", copy_string}, - {"port", "ptz-viscaip-port", copy_int}, - {NULL, NULL, NULL} - }; - - ptz_copy_settings(data, settings, list_generic); - - const char *type = obs_data_get_string(data, "type"); - if (!strcmp(type, "visca-over-tcp")) - ptz_copy_settings(data, settings, list_viscaip); - else if (!strcmp(type, "obsptz")) - ptz_copy_settings(data, settings, list_obsptz); + auto *b = get_backend(obs_data_get_string(settings, "ptz-type")); + if (b && b->list_settings) + ptz_copy_settings(data, settings, b->list_settings); return data; } -static void make_deice_obsptz(struct face_tracker_ptz *s, obs_data_t *data) +static void make_device(struct face_tracker_ptz *s, const char *ptz_type, obs_data_t *data) { s->ftm->release_dev(); - s->ftm->dev = new obsptz_backend(); - s->ftm->dev->set_config(data); + bfree(s->ptz_type); + s->ptz_type = bstrdup(ptz_type); + + auto *b = get_backend(ptz_type); + if (!b) + return; + + s->ftm->dev = b->make_device(data); } #ifdef WITH_PTZ_TCP -static void make_device_libvisca_tcp(struct face_tracker_ptz *s, obs_data_t *data) +static class ptz_backend *make_device_libvisca_tcp(obs_data_t *data) { - s->ftm->release_dev(); - if (!obs_data_get_string(data, "address")) - return; + return nullptr; if (obs_data_get_int(data, "port") <= 0) - return; - s->ftm->dev = new libvisca_thread(); - s->ftm->dev->set_config(data); -} -#endif // WITH_PTZ_TCP + return nullptr; + auto dev = new libvisca_thread(); + dev->set_config(data); -static void make_device_dummy(struct face_tracker_ptz *s, obs_data_t *data) -{ - s->ftm->release_dev(); - - s->ftm->dev = new dummy_backend(); - UNUSED_PARAMETER(data); + return dev; } +#endif // WITH_PTZ_TCP static void ftptz_update(void *data, obs_data_t *settings) { @@ -215,23 +254,8 @@ static void ftptz_update(void *data, obs_data_t *settings) if (!s->ptz_type || strcmp(ptz_type, s->ptz_type)) { obs_data_t *data = get_ptz_settings(settings); - if (!strcmp(ptz_type, "obsptz")) { - make_deice_obsptz(s, data); - } -#ifdef WITH_PTZ_TCP - else if (!strcmp(ptz_type, "visca-over-tcp")) { - make_device_libvisca_tcp(s, data); - } -#endif // WITH_PTZ_TCP - else if (!strcmp(ptz_type, "dummy")) { - make_device_dummy(s, data); - } - else if (s->ftm->dev) { - s->ftm->dev->release(); - s->ftm->dev = NULL; - } - bfree(s->ptz_type); - s->ptz_type = bstrdup(ptz_type); + make_device(s, ptz_type, data); + obs_data_release(data); } else { @@ -313,10 +337,13 @@ static bool ftptz_reset_tracking(obs_properties_t *, obs_property_t *, void *dat return true; } -static void set_properties_visible(obs_properties_t *props, const char **names, bool visible) +static void set_properties_visible(obs_properties_t *props, const struct ptz_copy_setting_item_s *items, bool visible) { - for (; *names; names++) { - obs_property_t *prop = obs_properties_get(props, *names); + if (!items) + return; + + for (; items->src; items++) { + obs_property_t *prop = obs_properties_get(props, items->src); if (prop) obs_property_set_visible(prop, visible); } } @@ -325,23 +352,11 @@ static bool ptz_type_modified(obs_properties_t *props, obs_property_t *, obs_dat { const char *ptz_type = obs_data_get_string(settings, "ptz-type"); - const char *props_obsptz[] = { - "ptz-obsptz-device_id", - NULL - }; - set_properties_visible(props, props_obsptz, !strcmp(ptz_type, "obsptz")); + for (int i = 0; backends[i].backend_name; i++) { + bool sel = strcmp(ptz_type, backends[i].backend_name) == 0; - const char *props_viscaip[] = { - "ptz-viscaip-address", - "ptz-viscaip-port", - NULL - }; - bool en = false; -#ifdef WITH_PTZ_TCP - if (!strcmp(ptz_type, "visca-over-tcp")) - en = true; -#endif // WITH_PTZ_TCP - set_properties_visible(props, props_viscaip, en); + set_properties_visible(props, backends[i].list_settings, sel); + } return true; }