OnvifServiceInterface
- Needs an API for pre-configuring specific camera information with optional fields for the type of authentication method used as well as parameters so that the service can be configured to narrow the search for specific devices of interest rather than dragnetting via multicast/unicast scraping.
- Needs API signalling the need for authentication parameters, async accepting the result, creating the
Devicewrapper and signallingadded.
DefaultOnvifService (i.e., LumeoHQ ONVIF-RS Wrapper)
- Needs interface for accepting the above configuration parameters.
- Needs documentation explaining how 'unicast' is actually probing a whole subnet, not specific devices. This behavior needs to be accounted for with the above new API.
- Tie into the
addedandremovedsignals for maintaining the history of successfully-identifiedDeviceinstances (the local object that wraps the LumeoHQClientsfrom the camera example). - Tie in the authentication behavior.
Device (i.e., LumeoHQ Clients wrapper from the camera example)
- Extend client APIs exposed to include ones helpful for audio vs. video, perhaps create subclasses of
Deviceif thats more helpful downstream. - Identify or develop a LumeoHQ interface for monitoring the removal of the specific device, adding a
disconnectedsignal that theDefaultOnvifServicecan use for emittingremoved.
GstOnvif[SubType]Devices
- Need to develop these classes such that we can map those GStreamer APIs to
Device(above), while also exposing appropriate streaming properties (profiles), etc. - Implement the
get_elementinterface for returning RTSP or other elements already configured for communicating with the specific target in quetsion.
GstOnvifDeviceFactory
- May or may not need to explicitly describe this to GStreamer. See the gst-plugins-rs NDI example.
GstOnvifDeviceProvider
- Map signals between the provider instance to the instantiated
OnvifServiceInterfacerepresentation so that detections emitadded, which then triggers the device provider to put aDEVICE_ADDEDmessage on the bus, save off into its hash map aGstDevicereference.
discover Example app
- Modify to focus on our device provider's devices, do more querying/displaying of information, verify authentication bus behavior works, etc.
- Might need
#[tokio::main]declared ahead offn main(making itasync fn main) to keep the multithreaded service instantiation happy.
Need unit tests with mocks throughout. Many of the included tests are integration tests, leveraging real transports, etc. If we want to keep the integration tests, we should use container orchestration and the mock onvif library to have some pretend devices during testing.
Tests will likely need to be declared as #[tokio::test] to instantiate the runtime (vs. #[test]). This is fairly common throughout the gst-plugins-rs used as a reference here since many elements/plugins use tokio for async operations.
Rename this project as necessary if we want to opensource it as the ONVIF Device Provider plugin.
cargo check
cargo buildYou can run examples by the names listed in the top-level Cargo.toml by using the following:
cargo run --example <name, e.g., 'discover'>This is a helpful link. In particular, you need to have the appropriate debugger tool extension installed for Windows or Linux/MacOS and enable in your settings Allow Breakpoints Everywhere. You can then typically use rust-analyzer: Debug from the CTRL+SHIFT+P menu, or via the code lens, to run the debugger with the active file.
However, for [[example]] -defined binaries, you need a launch configuration. In the preceding paragraph's link, it will suggest to only install the MS C++ plugin, however the CodeLLDB works fine on Windows and provides us the needed hook for the launch.json. For example:
{
"configurations":[
{
"type": "lldb",
"request": "launch",
"name": "Debug example 'discover'",
"cargo": {
"args": [
"build",
"--example",
"discover",
],
"filter": {
"name": "discover",
"kind": "example"
}
},
"args": [],
"cwd": "${workspaceFolder}",
}
],
}Without CodeLLDB, the "type": "lldb" won't work, which will prevent the "cargo": ... object from working at all. The reason this is necessary is because you have to build examples using the --example argument, and rust-analyzer's built-in debug target assumes the target is a [bin] in the Cargo.toml. In theory, this should work for tests too.