Skip to content

Commit

Permalink
Merge branch 'master' into gps_check_diff_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tomashmyh authored Sep 26, 2024
2 parents 14b78eb + 00163ce commit 4cd9440
Show file tree
Hide file tree
Showing 9 changed files with 2,591 additions and 4 deletions.
Binary file added Tools/bootloaders/Nucleo-L496_bl.bin
Binary file not shown.
1,764 changes: 1,764 additions & 0 deletions Tools/bootloaders/Nucleo-L496_bl.hex

Large diffs are not rendered by default.

106 changes: 106 additions & 0 deletions libraries/AP_Camera/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# AP_Camera examples


## GStreamer examples

The following examples demonstrate how to manipulate GStreamer pipelines to
capture and display video streams from a UDP or RTSP source. They are useful
for providing test images to camera algorithms, or forwarding streams from
simulators such as Gazebo to ground control stations.

For further details see:

- [GStreamer tutorials](https://gstreamer.freedesktop.org/documentation/tutorials/index.html?gi-language=c)


### Install dependencies

#### Ubuntu

```bash
sudo apt install libopencv-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl gstreamer1.0-tools gstreamer1.0-plugins-ugly libgstrtspserver-1.0-dev
```

#### macOS

```bash
brew install gstreamer opencv
```

### `gst_rtsp_server.py`

The example provides a number of test images as an RTSP stream that may be accessed at:

- rtsp://127.0.0.1:8554/camera
- rtsp://127.0.0.1:8554/ball
- rtsp://127.0.0.1:8554/snow


Start the RTSP server:

```bash
python ./gst_rtsp_server.py
```

Display the RTSP stream:

```bash
gst-launch-1.0 rtspsrc location=rtsp://localhost:8554/camera latency=50 ! decodebin ! autovideosink
```

### `gst_rtsp_to_wx.py`

The example displays an RTSP stream in a wxPython application.

Start the RTSP server:

```bash
python ./gst_rtsp_server.py
```

Display the RTSP stream in wxPython

```bash
python ./gst_rtsp_to_wx.py
```

### `gst_udp_to_rtsp.py`

Convert a UDP stream to RTSP. This example is configured to use the same UDP
pipeline provided by the ArduPilot Gazebo [`GstCameraPlugin`](https://github.com/ArduPilot/ardupilot_gazebo?tab=readme-ov-file#3-streaming-camera-video). By converting the
UDP stream to RTSP is may be consumed by multiple applications
(e.g. a camera tracking algorithm and a GCS).

Create a UDP video stream

```bash
gst-launch-1.0 -v videotestsrc ! 'video/x-raw,format=I420,width=640,height=480,framerate=50/1' ! queue ! videoconvert ! x264enc bitrate=800 speed-preset=6 tune=4 key-int-max=10 ! rtph264pay ! udpsink host=127.0.0.1 port=5600
```

Convert to RTSP:

```bash
python ./gst_udp_to_rtsp.py
```

Display the RTSP stream:

```bash
gst-launch-1.0 rtspsrc location=rtsp://localhost:8554/camera latency=50 ! decodebin ! autovideosink
```

### `gst_udp_to_wx.py`

The example displays a UDP video stream in a wxPython application.

Create a UDP video stream:

```bash
gst-launch-1.0 -v videotestsrc ! 'video/x-raw,format=I420,width=640,height=480,framerate=50/1' ! queue ! videoconvert ! x264enc bitrate=800 speed-preset=6 tune=4 key-int-max=10 ! rtph264pay ! udpsink host=127.0.0.1 port=5600
```

Display the UDP video stream in wxPython:

```bash
python ./gst_udp_to_wx.py
```
115 changes: 115 additions & 0 deletions libraries/AP_Camera/examples/gst_rtsp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""
GST RTSP Server Example
Usage
-----
1. Start the server:
python ./gst_rtsp_server.py
2. Display the RTSP stream
gst-launch-1.0 rtspsrc location=rtsp://localhost:8554/camera latency=50 ! decodebin ! autovideosink
Acknowledgments
---------------
GStreamer RTSP server example adapted from code by Jerome Carretero (Tamaggo)
https://github.com/tamaggo/gstreamer-examples
https://github.com/tamaggo/gstreamer-examples/blob/master/test_gst_rtsp_server.py
"""

# Copyright (c) 2015 Tamaggo Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

import sys
import gi

gi.require_version("Gst", "1.0")
gi.require_version("GstRtspServer", "1.0")
from gi.repository import Gst
from gi.repository import GstRtspServer
from gi.repository import GLib


class VideoTestMediaFactory(GstRtspServer.RTSPMediaFactory):
"""
Create a GStreamer pipeline for a videotestsrc source.
The default videotestsrc uses the smpte test pattern. Other test patterns
may be specified when initialising the class.
"""
def __init__(self, pattern="smpte"):
GstRtspServer.RTSPMediaFactory.__init__(self)
self.pattern = pattern

def do_create_element(self, url):
s_src = f"videotestsrc pattern={self.pattern} ! video/x-raw,rate=30,width=640,height=480,format=I420"
s_h264 = "x264enc tune=zerolatency"
pipeline_str = f"( {s_src} ! queue max-size-buffers=1 name=q_enc ! {s_h264} ! rtph264pay name=pay0 pt=96 )"
if len(sys.argv) > 1:
pipeline_str = " ".join(sys.argv[1:])
print(pipeline_str)
return Gst.parse_launch(pipeline_str)


class GstServer:
"""
A GStreamer RTSP server streaming three different test patterns:
rtsp://127.0.0.1:8554/camera
rtsp://127.0.0.1:8554/ball
rtsp://127.0.0.1:8554/snow
"""
def __init__(self):
self.server = GstRtspServer.RTSPServer()
self.server.set_address("127.0.0.1")
self.server.set_service("8554")

media_factory1 = VideoTestMediaFactory()
media_factory1.set_shared(True)

media_factory2 = VideoTestMediaFactory("ball")
media_factory2.set_shared(True)

media_factory3 = VideoTestMediaFactory("snow")
media_factory3.set_shared(True)

mount_points = self.server.get_mount_points()
mount_points.add_factory("/camera", media_factory1)
mount_points.add_factory("/ball", media_factory2)
mount_points.add_factory("/snow", media_factory3)

self.server.attach(None)


def main():
Gst.init(None)
server = GstServer()
loop = GLib.MainLoop()
loop.run()


if __name__ == "__main__":
main()
Loading

0 comments on commit 4cd9440

Please sign in to comment.