Skip to content

Commit

Permalink
Release v0.3.1
Browse files Browse the repository at this point in the history
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
  • Loading branch information
NiklasKroeger-AlliedVision committed Jun 17, 2021
1 parent e3c83a9 commit 3767614
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 30 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
136 changes: 136 additions & 0 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -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.
47 changes: 47 additions & 0 deletions INSTALLING.md
Original file line number Diff line number Diff line change
@@ -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-<GST_API_VERSION>/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
`<GSTREAMER_INSTALLATION_DIRECTORY>\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).
66 changes: 37 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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-<GST_API_VERSION>/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_
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
20 changes: 20 additions & 0 deletions src/gstvimbasrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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
Expand Down

0 comments on commit 3767614

Please sign in to comment.