You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
support falling back to alternative decoders, rename parameters, add tests etc
* adopt the new ffmpeg_encoder_api which allows for probing of decoders. The decoder parameter can now contain a list of comma-separated decoders which will be tried in order.
* adds gtests to the repo
* reformat to the black python formatter
* add arguments to some example launch files
* allow arbitrary AVOptions setting via av_option
* remove parameters "preset", "tune", "delay", and "crf" (must now be set via "av_options")
* remove some default values (like bit_rate) to force user to set them explicitly
* change the parameter names: remove the leading ".", so now the parameters are named specify "camera.image_raw.." as opposed to ".camera.image_raw..."
* adapt to new ffmpeg_encoder_decoder API
* change name of parameter from encoding->encoder
* provide encoding when initializing encoder (new encoder/decoder API)
* handle new API for image transport 6.3.0
* deal with Humble bug: topic is passed in without being prefixed by the namespace, but then namespace is removed!
* package splitting functions into utilities file
@@ -59,83 +60,91 @@ should give output (among other transport plugins):
59
60
This plugin decodes frames from ffmpeg compressed packets
60
61
```
61
62
62
-
Remember to install the plugin on both hosts, the one that is encoding and
63
-
the one that is decoding (viewing).
63
+
Remember to install the plugin on both hosts, the one that is publishing and
64
+
the one that is subscribing (viewing).
64
65
65
66
## Parameters
66
67
68
+
Below is a short description of the ROS parameters exposed by the Publisher and Subscriber plugins.
69
+
The parameters refer to encoder and decoder variables described in more detail in the [``ffmpeg_encoder_decoder`` repository](https://github.com/ros-misc-utilities/ffmpeg_encoder_decoder).
70
+
67
71
### Publisher (camera driver)
68
72
69
73
Here is a list of the available encoding parameters:
70
74
71
-
-``encoding``: the libav (ffmpeg) encoder being used. The default is ``libx264``, which is on-CPU unaccelerated encoding.
75
+
-``encoder``: the libav (ffmpeg) encoder being used. The default is ``libx264``, which is on-CPU unaccelerated encoding.
72
76
Depending on your hardware, your encoding options may include the hardware accelerated ``h264_nvenc`` or ``h264_vaapi``.
73
77
You can list all available encoders with ``ffmpeg --codecs``. In the h264 row, look for ``(encoders)``.
74
-
-``preset``: default is empty (""). Valid values can be for instance ``slow``, ``ll`` (low latency) etc.
See the example launch file for a V4L USB camera (``usb_camera.launch.py``).
99
+
If the above parameter settings don't work, use the ``ros2 param dump <your_node_name>``
100
+
command to find out what the proper parameter path is.
99
101
100
102
### Subscriber (viewer)
101
103
102
-
The subscriber has only one parameter (``map``), which is the map between the encoding that
103
-
was used to encode the frames, and the libav decoder to be used for decoding. The mapping is done by creating entries in the ``ffmpeg.map`` parameter, which is prefixed by the image base name, e.g. ``camera``.
104
-
105
-
For example to tell the subscriber to use the ``hevc`` decoder instead of the default ``hevc_cuvid``
106
-
decoder for decoding incoming ``hevc_nvenc`` packets set a parameter like so *after* you started the viewer:
107
-
```
108
-
ros2 param set <name_of_your_viewer_node> camera.image_raw.ffmpeg.map.hevc_nvenc hevc
109
-
```
110
-
This is assuming that your viewer node is subscribing to an image ``/camera/image_raw/ffmpeg``.
111
-
112
-
You also need to refresh the subscription (drop down menu in the viewer) for the parameter to take hold.
113
-
If anyone ever figures out how to set the parameters *when* starting the viewer (rather than afterwards!), please update this document.
114
-
104
+
-``decoder_av_options`` comma-separated list of libav options to pass
105
+
to the decoder, like ``foo:bar,foobar:baz``. Default: empty string.
-``decoders.<codec>.<av_source_pixel_format>.<cv_bridge_target_format>.<original_ros_encoding>`` specifies the decoders to use for a given FFMPEGPacket encoding.
109
+
If no decoders are specified for the full encoding, a less specific parameter will be tested, i.e. ``decoders.<codec>.<av_source_pixel_format>.<cv_bridge_target_format>``, then ``decoders.<codec>.<av_source_pixel_format>``, and finally ``decoders.<codec>``.
110
+
If all parameters are found to be empty, the Subscriber plugin will try to decode with a default set of libav decoders that support the appropriate codec.
111
+
112
+
All parameters are prefixed again by the image topic and the transport, just like for the publisher node.
113
+
The easiest way to find the exact naming of the parameter is to run the node and to use ``ros2 param list`` to find the ``ffmpeg.decoders`` parameter.
114
+
Please also refer to the republisher launch script example.
115
+
116
+
Typically ROS2 parameters are passed to a node by *initializing* the parameters before launching the node, and the node then reads the parameter when it *declares* the parameter.
117
+
Unfortunately, this route is not available for the popular ``rqt`` based suite of image viewing tools such as ``rqt_image_view``, since ``rqt`` does not read command line arguments and therefore no parameters can be initialized. The only workaround there is to:
118
+
1) start e.g. ``rqt_image_view``
119
+
2) select the ffmpeg image transport in the drop down box. This will *declare* the ``decoders`` parameter so you can set it in the next step.
120
+
3) find the node name with ``ros2 node list`` and set the parameter using something like
121
+
``ros2 param set <name_of_your_viewer_node> camera.image_raw.ffmpeg.decoders.hevc hevc_cuvid``. This assumes your viewer node is subscribing to the topic ``/camera/image_raw/ffmpeg``.
122
+
4) again using the drop down box, switch to another image transport and back to ffmpeg. This will cause the ffmpeg transport plugin to apply the updated ``decoders`` parameter.
115
123
116
124
### Republishing
117
125
118
126
The ``image_transport`` allows you to republish the decoded image locally,
119
127
see for instance [here](https://gitlab.com/boldhearts/ros2_v4l2_camera/-/blob/foxy/README.md).
120
-
Here the ROS parameters work as expected to modify the mapping between
121
-
encoding and decoder.
128
+
Here the ROS parameters work as expected to modify the mapping between encoding and decoder.
122
129
123
130
The following lines shows how to specify the decoder when republishing.
124
-
For example to decode incoming ``hevc_nvenc`` packets with the ``hevc`` decoder:
131
+
For example to first try to decode incoming ``hevc`` packets with the ``hevc_cuvid``decoder, and if that fails, with the software ``hevc``decoder:
125
132
126
133
- ROS 2 Humble:
127
134
```
128
-
ros2 run image_transport republish ffmpeg in/ffmpeg:=image_raw/ffmpeg raw out:=image_raw/uncompressed --ros-args -p "ffmpeg_image_transport.map.hevc_nvenc:=hevc"
135
+
ros2 run image_transport republish ffmpeg in/ffmpeg:=image_raw/ffmpeg raw out:=image_raw/uncompressed --ros-args -p "ffmpeg_image_transport.decoders.hevc:=hevc_cuvid,hevc"
Note: The commands below use the Humble syntax and need to be changed as shown here for Jazzy.
136
143
137
144
Republishing is generally not necessary so long as publisher and subscriber both properly use
138
-
an image transport. Some nodes however, notably the rosbag player, do not support a proper transport, rendering republishing necessary.
145
+
an image transport.
146
+
Some nodes however, notably the rosbag player, do not support a proper transport, making republishing necessary.
147
+
Please use the republishing launch file (``republish.launch.py``) in this repo as a starting point for how to set the decoders parameter.
139
148
140
149
#### Republishing raw images from rosbags in ffmpeg format
141
150
@@ -153,15 +162,14 @@ You can record them in ``ffmpeg`` format by e.g ``ros2 bag record /out/ffmpeg``.
153
162
154
163
Let's say you have stored images as ffmpeg packets in a rosbag under the topic ``/camera/image_raw/ffmpeg``. To view them use this line:
155
164
```
156
-
ros2 run image_transport republish ffmpeg --ros-args -r in/ffmpeg:=/camera/image_raw/ffmpeg
157
-
165
+
ros2 run image_transport republish ffmpeg --ros-args -p in_transport:=ffmpeg -r in/ffmpeg:=/camera/image_raw/ffmpeg
158
166
```
159
167
This will republish the topic with full image transport support.
160
168
161
169
### Setting encoding parameters when launching camera driver
162
170
163
-
The ``launch`` directory contains an example launch file ``cam.launch.py`` that demonstrates
164
-
how to set encoding profile and preset for e.g. a usb camera.
171
+
The ``launch`` directory contains an example launch file ``usb_camera.launch.py`` that demonstrates
172
+
how to set encoding profile and preset for a usb camera.
165
173
166
174
167
175
### How to use a custom version of libav (aka ffmpeg)
@@ -170,6 +178,17 @@ See the [``ffmpeg_encoder_decoder`` repository](https://github.com/ros-misc-util
170
178
There you will also find instructions for hardware accelerated
171
179
streaming on the NVidia Jetson.
172
180
181
+
## Trouble shooting
182
+
### Excessive lag
183
+
Many encoders buffer frames to enable inter-frame prediction for improved compression.
184
+
This can lead to very large lag. Use a small ``gop_size`` parameter to increase the frequency of keyframes.
185
+
### Poor quality
186
+
Set the ``bit_rate`` parameter or set the ``crf````av_option`` parameter to something small like ``crf:1``. Experiment with the ffmpeg CLI tool until you get a satisfying quality.
187
+
### Decoder cannot decode image
188
+
Check that the ``av_source_pixel_format`` used by the encoder is actually supported by the decoder.
189
+
Many decoders can only decode a small number of image formats.
190
+
191
+
173
192
## License
174
193
175
194
This software is issued under the Apache License Version 2.0.
0 commit comments