From 376761489f3a73cb97a55b71c47aaf34d1fdedc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Kr=C3=B6ger?= Date: Thu, 17 Jun 2021 11:16:44 +0200 Subject: [PATCH] Release v0.3.1 This includes - Improved installation instructions in `INSTALLING.md` - Additional example usages in `EXAMPLES.md` - Addition of Vimba function calls to ensure camera commands are finished executing --- CMakeLists.txt | 2 +- EXAMPLES.md | 136 ++++++++++++++++++++++++++++++++++++++++++++++ INSTALLING.md | 47 ++++++++++++++++ README.md | 66 ++++++++++++---------- src/gstvimbasrc.c | 20 +++++++ 5 files changed, 241 insertions(+), 30 deletions(-) create mode 100644 EXAMPLES.md create mode 100644 INSTALLING.md diff --git a/CMakeLists.txt b/CMakeLists.txt index e364936..a266537 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12) project( gstvimbasrc - VERSION 0.3.0 + VERSION 0.3.1 LANGUAGES C DESCRIPTION "GStreamer source plugin for Vimba cameras" # TODO: Should this URL instead point to the Github Repo we plan to use for this project? diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 0000000..cd73588 --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,136 @@ +# Usage Examples + +GStreamer provides a larges selection of plugins, which can be used to define flexible pipelines for +many uses. Some examples of common goals are provided in this file. + +## Saving camera frames as pictures + +Recording pictures from a camera and saving them to some common image format allows for quick +inspections of the field of view, brightness and sharpness of the image. GStreamer provides image +encoders for different image formats. The example below uses the `png` encoder. A step by step +explanation of the elements in the pipeline is given below. +``` +gst-launch-1.0 vimbasrc camera=DEV_1AB22D01BBB8 num-buffers=1 ! pngenc ! filesink location=out.png +``` + +- `vimbasrc camera=DEV_1AB22D01BBB8 num-buffers=1`: uses the `gst-vimbasrc` element to grab one + single frame from the camera with the given ID and halt the pipeline afterwards +- `pngenc`: takes the input image and encodes it into a `png` file +- `filesink location=out.png`: writes the data it receives (the encoded `png` image) to the file + `out.png` in the current working directory + +Similarly it is possible to save a number of camera frames to separate image files. This can be +achieved by using the `multifilesink` element to save the images. +``` +gst-launch-1.0 vimbasrc camera=DEV_1AB22D01BBB8 num-buffers=10 ! pngenc ! multifilesink location=out_%03d.png +``` + +Similarly to the previous example, this pipeline uses the `gst-vimbasrc` element to record images +from the camera. Here however 10 images are recorded. The `multifilesink` saves these images to +separate files, named `out_000.png`, `out_001.png`, ... , `out_009.png`. + +Further changes to the pipeline are possible to for example change the format of the recorded images +to ensure RGB images, or adjust the exposure time of the image acquisition process. For more details +see the README of the `gst-vimbasrc` element. + +## Saving camera stream to a video file + +To save a stream of images recorded by a camera to a video file the images should be encoded in some +video format and stored in an appropriate container format. This saves a lot of space compared to +just saving the raw image data. This example uses `h264` encoding for the image data and saves the +resulting video to an `avi` file. An explanation for the separate elements of the pipeline can be +found below. +``` +gst-launch-1.0 vimbasrc camera=DEV_000F315B91E2 ! video/x-raw,format=RGB ! videorate ! video/x-raw,framerate=30/1 ! videoconvert ! queue ! x264enc ! avimux ! filesink location=output.avi +``` + +- `vimbasrc camera=DEV_000F315B91E2`: uses the `gst-vimbasrc` element to grab camera frames from the + Vimba compatible camera with the given ID. For more information on the functionality of + `gst-vimbasrc` see the README +- `video/x-raw,format=RGB`: a gst capsfilter element that limits the available data formats to `RGB` + to ensure color images for the resulting video stream. Without this the pipeline may negotiate + grayscale images +- `videorate ! video/x-raw,framerate=30/1`: `gst-vimbasrc` provides image data in a variable + framerate (due to effects like possible hardware triggers or frame jitter). Because `avi` files + only support fixed framerates, it needs to be modified via the `videorate` plugin. This guarantees + a fixed framerate output by either copying the input data if more frames are requested than + received, or dropping unnecessary frames if more frames are received than requested. +- `videoconvert ! queue`: converts the input image to a compatible video format for the following + element +- `x264enc`: performs the encoding to h264 video +- `avimux`: multiplex the incoming video stream to save it as an `avi` file +- `filesink location=output.avi`: saves the resulting video into a file named `output.avi` in the + current working directory + +## Stream video via RTSP server + +RTSP (Real Time Streaming Protocol) is a network protocol designed to control streaming media +servers. It allows clients to send commands such as "play" or "pause" to the server, to enable +control of the media being streamed. The following example shows a minimal RTSP server using the +`gst-vimbasrc` element to stream image data from a camera via the network to a client machine. This +example uses Python to start a pre-implemented RTSP server that can be imported via the PyGObject +package. To do this a few external dependencies must be installed. + +### Dependencies + +The following instructions assume an Ubuntu system. On other distributions different packages may be +required. It is also assumed, that a working GStreamer installation exists on the system and that +`gst-vimbasrc` is available to that installation. + +To have access to the GStreamer RTSP Server from python the following system packages need to be +installed via the `apt` package manager: +- gir1.2-gst-rtsp-server-1.0 +- libgirepository1.0-dev +- libcairo2-dev + +Additionally the following python package needs to be installed. it is available via the Python +packaging index and can be installed as usual via `pip`: +- PyGObject + +### Example code + +The following python code will start an RTSP server on your machine listing on port `8554`. Be sure +to adjust the ID of the camera you want to use in the pipeline! As before the pipeline may be +adjusted to specify certain image formats to force for example color images or to change camera +settings like the exposure time. + +```python +# import required GStreamer and GLib modules +import gi +gi.require_version('Gst', '1.0') +gi.require_version('GstRtspServer', '1.0') +from gi.repository import Gst, GLib, GstRtspServer + +# initialize GStreamer and start the GLib Mainloop +Gst.init(None) +mainloop = GLib.MainLoop() + +# Create the RTSP Server +server = GstRtspServer.RTSPServer() +mounts = server.get_mount_points() + +# define the pipeline to record images ad attach it to the "stream1" endpoint +vimbasrc_factory = GstRtspServer.RTSPMediaFactory() +vimbasrc_factory.set_launch('vimbasrc camera=DEV_1AB22D01BBB8 ! videoconvert ! x264enc speed-preset=ultrafast tune=zerolatency ! rtph264pay name=pay0') +mounts.add_factory("/stream1", vimbasrc_factory) +server.attach(None) + +mainloop.run() +``` + +To start the server simply save the code above to a file (e.g. `RTSP_Server.py`) and run it with +your python interpreter. The RTSP server can be stopped by halting the process. This is done by +pressing `CTRL + c` in the terminal that is running the python script. + +### Displaying the stream + +After starting the python example a client must connect to the running RTSP server to receive and +display the stream. This can for example be done with the VLC media player. To display the stream on +the same machine that is running the RTSP server, open `rtsp://127.0.0.1:8554/stream1` as a Network +Stream (in VLC open "Media" -> "Open Network Stream"). If you want to play the video on a different +computer, ensure that a network connection between the two systems exists and use the IP address of +the machine running the RTSP server for your Network Stream. + +Upon starting playback in VLC the RTSP Server will start the GStreamer pipeline that was defined in +the python file and start streaming images. It may take some time for the stream to start. Stopping +playback will also stop the GStreamer pipeline and close the connection to the camera being used. diff --git a/INSTALLING.md b/INSTALLING.md new file mode 100644 index 0000000..0216bc1 --- /dev/null +++ b/INSTALLING.md @@ -0,0 +1,47 @@ +# Installation +As mentioned in `README.md` the installation of `vimbasrc` consists of just two necessary files that +need to be placed in appropriate directories. The shared library containing the GStreamer element +must be findable by GStreamer. This can be achieved by defining the `GST_PLUGIN_SYSTEM_PATH` and +placing the shared library file in that directory. Additionally the VimbaC shared library must be +loadable as it is used by the `vimbasrc` element. VimbaC is provided as part of the Vimba SDK. + +Below are more details on the installation on Linux (more specifically Ubuntu) and Windows. + +## Linux (Ubuntu) +If the `GST_PLUGIN_SYSTEM_PATH` variable is not defined, the default paths of the system wide +GStreamer installation, as well as the `~/.local/share/gstreamer-/plugins` +directory of the current user are searched. Installing the `vimbasrc` element is therefore simply a +matter of placing the compiled shared library into this search path and letting GStreamer load it. + +### Installation dependencies +As the shared library containing the `vimbasrc` element is dynamically linked, its linked +dependencies must be loadable. As GStreamer itself is likely installed system wide, the dependencies +on glib and GStreamer libraries should already be satisfied. + +In order to satisfy the dependency on `libVimbaC.so` the shared library needs to be placed in an +appropriate entry of the `LD_LIBRARY_PATH`. The exact method for this is a matter of preference and +distribution dependant. On Ubuntu systems one option would be to copy `libVimbaC.so` into +`/usr/local/lib` or to add the directory containing `libVimbaC.so` to the `LD_LIBRARY_PATH` by +adding an appropriate `.conf` file to `/etc/ld.so.conf.d/`. + +Correct installation of `libVimbaC.so` can be checked, by searching for its file name in the output +of `ldconfig -v` (e.g.: `ldconfig -v | grep libVimbaC.so`). Alternatively correct loading of +dependent shared libraries can be checked with `ldd` (e.g. `ldd libgstvimbasrc.so`). + +## Windows +Adding the directory containing the compiled shared library file to the `GST_PLUGIN_SYSTEM_PATH` is +the easiest way to install the `vimbasrc` element. Alternatively the file can be placed in the +GStreamer installation directory of the system. The installation directory was chosen during the +installation of the GStreamer runtime. The directory the plugin should be placed into is +`\1.0\msvc_x86_64\lib\gstreamer-1.0` on 64 bit systems. + +### Installation dependencies +In addition to the installation of GStreamer runtime and placing the `vimbasrc` shared library into +the GStreamer plugin search path, VimbaC needs to be loadable. This can be achieved by adding a +directory containing `VimbaC.dll` to your systems `PATH` variable. With a working Vimba installation +the directory `%VIMBA_HOME%VimbaC\Bin\Win64` will contain `VimbaC.dll` for 64 bit systems. + +## Further information +More information on the environment variables used by GStreamer to determine directories which +should be searched for elements can be found in [the official +documentation](https://gstreamer.freedesktop.org/documentation/gstreamer/running.html). \ No newline at end of file diff --git a/README.md b/README.md index a93b07a..36d4bd2 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,6 @@ GStreamer is multimedia framework which assembles pipelines from multiple elemen pass them directly into these pipelines. This enables a wide variety of uses such as live displays of the image data or encoding them to a video format. -`vimbasrc` is currently officially supported on the following systems and architectures: -- AMD64 (Validated on Ubuntu 18.04) -- ARM64 (Validated on NVIDIA L4T 32.4.4) - -The following library versions have been validated to work with `vimbasrc`: -- Vimba 4.2 -- GStreamer 1.14 - ## Building A `CMakeLists.txt` file is provided that helps build the plugin. For convenience this repository also contains two scripts (`build.sh` and `build.bat`) that run the appropriate cmake commands for @@ -35,8 +27,8 @@ provided paths accordingly for your build system. ### Docker build environment (Linux only) To simplify the setup of a reproducible build environment, a `Dockerfile` based on an Ubuntu 18.04 base image is provided, which when build includes all necessary dependencies, except the Vimba -version against which `vimbasrc` is linked. This is added when the compile command is run by mounting -a Vimba installation into the Docker container. +version against which `vimbasrc` is linked. This is added when the compile command is run by +mounting a Vimba installation into the Docker container. #### Building the docker image In order to build the docker image from the `Dockerfile`, run the following command inside the @@ -63,25 +55,15 @@ docker run --rm -it --volume /path/to/gst-vimbasrc:/gst-vimbasrc --volume /path/ ## Installation GStreamer plugins become available for use in pipelines, when GStreamer is able to load the shared library containing the desired element. GStreamer typically searches the directories defined in -`GST_PLUGIN_SYSTEM_PATH`. If this variable is not defined, the default paths of the system wide -GStreamer installation, as well as the `~/.local/share/gstreamer-/plugins` -directory of the current user are searched. Installing the `vimbasrc` element is therefore simply a -matter of placing the compiled shared library into this search path and letting GStreamer load it. - -### Installation dependencies -As the shared library containing the `vimbasrc` element is dynamically linked, its linked -dependencies must be loadable. As GStreamer itself is likely installed system wide, the dependencies -on glib and GStreamer libraries should already be satisfied. - -In order to satisfy the dependency on `libVimbaC.so` the shared library needs to be placed in an -appropriate entry of the `LD_LIBRARY_PATH`. The exact method for this is a matter of preference and -distribution dependant. On Ubuntu systems one option would be to copy `libVimbaC.so` into -`/usr/local/lib` or to add the directory containing `libVimbaC.so` to the `LD_LIBRARY_PATH` by -adding an appropriate `.conf` file to `/etc/ld.so.conf.d/`. - -Correct installation of `libVimbaC.so` can be checked, by searching for its file name in the output -of `ldconfig -v` (e.g.: `ldconfig -v | grep libVimbaC.so`). Alternatively correct loading of -dependent shared libraries can be checked with `ldd` (e.g. `ldd libgstvimbasrc.so`). +`GST_PLUGIN_SYSTEM_PATH`. By setting this variable to a directory and placing the shared library +file in it, GStreamer will pick up the `vimbasrc` element for use. + +The `vimbasrc` element uses VimbaC. In order to be usable the VimbaC shared library therefore needs +to also be loadable when the element is started. The VimbaC library is provided as part of the Vimba +SDK. + +More detailed installation instructions for Linux and Windows can be found in the `INSTALLING.md` +file in this repository. ## Usage **The vimbasrc plugin is still in active development. Please keep the _Known issues and limitations_ @@ -96,6 +78,8 @@ The following pipeline can for example be used to display the recorded camera im gst-launch-1.0 vimbasrc camera=DEV_1AB22D01BBB8 ! videoscale ! videoconvert ! queue ! autovideosink ``` +For further usage examples also take a look at the included `EXAMPLES.md` file + ### Setting camera features To adjust the image acquisition process of the camera, access to settings like the exposure time are necessary. The `vimbasrc` element provides access to these camera features in one of two ways. @@ -202,6 +186,16 @@ is able to debayer the data into a widely accepted RGBA format. | BayerBG8 | bggr | ## Troubleshooting +- The `vimbasrc` element is not loadable + - Ensure that the installation of the plugin was successful and that all required dependencies are + available. Installation instructions can be found in `INSTALLING.md`. To verify that the element + can be loaded try to inspect it by calling `gst-inspect-1.0 vimbasrc`. + - It is possible that the `vimbasrc` element is blacklisted by GStreamer. This can be determined + by checking the list ob blacklisted elements with `gst-inspect-1.0 --print-blacklist`. Resetting + the registry may be done by removing the file in which it is stored. It is typically saved in + `~/.cache/gstreamer-1.0/registry.x86_64.bin`. The exact file name depends on the architecture of + the system. For more details see [the official documentation on the + registry](https://gstreamer.freedesktop.org/documentation/gstreamer/gstregistry.html) - How can I enable logging for the plugin - To enable logging set the `GST_DEBUG` environment variable to `GST_DEBUG=vimbasrc:DEBUG` or another appropriate level. For further details see [the official @@ -243,3 +237,17 @@ is able to debayer the data into a widely accepted RGBA format. the stride of the image data in the buffer. This explicit stride information is currently not implemented. For now it is therefore recommended to use `width` settings that are evenly divisible by 4. + +## Compatibility +`vimbasrc` is currently officially supported on the following operating systems and architectures: +- AMD64 (Validated on Ubuntu 20.04, Debian 10, CentOS 8.3) +- ARM64 (Validated on NVIDIA L4T 32.5.1) +- ARM32 (Validated on Raspberry Pi OS) +- WIN64 (Validated on Win10 20H2) +- WIN32 (Validated on Win10 20H2, 32Bit) + +The following library versions have been validated to work with vimbasrc: +- Vimba 5.0 +- GStreamer 1.14 (NVIDIA L4T 32.5.1, Debian 10, Raspberry OS) +- GStreamer 1.16 (Ubuntu 20.04, CentOS 8.3) +- GStreamer 1.18 (Win10 20H2) diff --git a/src/gstvimbasrc.c b/src/gstvimbasrc.c index 0462a37..32bb8e8 100644 --- a/src/gstvimbasrc.c +++ b/src/gstvimbasrc.c @@ -1816,6 +1816,16 @@ VmbError_t start_image_acquisition(GstVimbaSrc *vimbasrc) // Start Acquisition GST_DEBUG_OBJECT(vimbasrc, "Running \"AcquisitionStart\" feature"); result = VmbFeatureCommandRun(vimbasrc->camera.handle, "AcquisitionStart"); + VmbBool_t acquisition_start_done = VmbBoolFalse; + do + { + if (VmbErrorSuccess != VmbFeatureCommandIsDone(vimbasrc->camera.handle, + "AcquisitionStart", + &acquisition_start_done)) + { + break; + } + } while (VmbBoolFalse == acquisition_start_done); vimbasrc->camera.is_acquiring = true; } } @@ -1833,6 +1843,16 @@ VmbError_t stop_image_acquisition(GstVimbaSrc *vimbasrc) // Stop Acquisition GST_DEBUG_OBJECT(vimbasrc, "Running \"AcquisitionStop\" feature"); VmbError_t result = VmbFeatureCommandRun(vimbasrc->camera.handle, "AcquisitionStop"); + VmbBool_t acquisition_stop_done = VmbBoolFalse; + do + { + if (VmbErrorSuccess != VmbFeatureCommandIsDone(vimbasrc->camera.handle, + "AcquisitionStop", + &acquisition_stop_done)) + { + break; + } + } while (VmbBoolFalse == acquisition_stop_done); vimbasrc->camera.is_acquiring = false; // Stop Capture Engine