|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to this project are documented here. |
| 4 | +Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). |
| 5 | +Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## [Unreleased] — pre-release, branch `ft/1stversion_w_srt` |
| 10 | + |
| 11 | +### Added |
| 12 | + |
| 13 | +**Node architecture** |
| 14 | +- Modular node split: `src/node/` with one file per responsibility (`core`, `lifecycle`, `modes`, `streaming`, `recovery`, `fallback`, `observability`). Each file stays under 300 lines. |
| 15 | +- Separate `src/core/` (config loading and pipeline building) and `src/runtime/` (capability probe, stream engine, metrics, image format, topic introspector) layers. |
| 16 | + |
| 17 | +**Codec & encoder selection** |
| 18 | +- `codec.name:=auto` resolves the best available codec and encoder using `gst-inspect-1.0` output, scored by machine profile (`jetson`, `x86`, `raspi`, `generic`). |
| 19 | +- Machine profile auto-detection from host CPU architecture when `profile.machine` is left as `generic`. |
| 20 | +- Hardware-to-software encoder fallback after configurable consecutive failures (`runtime.hw_fallback_failures`, default 3). |
| 21 | + |
| 22 | +**Transport × codec pipeline matrix** |
| 23 | +- Full support for `h264`, `h265`, `mjpeg` codecs across `srt`, `udp`, `rtsp`, `file` sinks. |
| 24 | +- Jetson NVMM path for `nvv4l2h264enc` / `nvv4l2h265enc` (CPU → I420 → nvvidconv → NVMM → encoder). |
| 25 | +- Software-only path for `x264enc`, `x265enc`, `jpegenc`, `openh264enc`. |
| 26 | + |
| 27 | +**Image format support** |
| 28 | +- BGR8, RGB8, BGRA8, RGBA8, MONO8, MONO16 (`GRAY16_LE`). |
| 29 | +- Bayer 8-bit and 16-bit encodings streamed as grayscale fallback with a throttled warning to use `image_proc/debayer` for colour output. |
| 30 | +- `validateImageShape` validates width × height × step × data-size consistency before pushing frames. |
| 31 | + |
| 32 | +**Adaptive resilience** |
| 33 | +- Three-level bitrate/fps/gop adaptation loop (levels 0–2) triggered by `Degraded` / `Reconnecting` state transitions and recovered during sustained `Streaming`. |
| 34 | +- Three adaptation profiles: `conservative`, `balanced`, `aggressive`. |
| 35 | +- Configurable interval and cooldown (`runtime.adaptation.interval_ms`, `runtime.adaptation.cooldown_ms`). |
| 36 | +- Pipeline reconfigure on adaptation policy change (stops/rebuilds engine with updated parameters). |
| 37 | + |
| 38 | +**Observability** |
| 39 | +- `~/runtime_status` (`ros2_gst_video_bridge_msgs/msg/RuntimeStatus`): typed status at 1 Hz including fps_in/fps_out, drop counters split by throttle/malformed/backpressure, reconnect count, latency EWMA, push latency estimate + observed max, adaptation profile/level, and codec/encoder/fallback flags. |
| 40 | +- `~/runtime_events` (`ros2_gst_video_bridge_msgs/msg/RuntimeEvent`): asynchronous events for `PIPELINE_STARTED`, `PIPELINE_DEGRADED`, `RECONNECT_FAILED`, `ADAPTATION_APPLIED`, `ENCODER_FALLBACK_SW`, `FIRST_FAILURE_SNAPSHOT`, `OPERATOR_PROFILE_UPDATE`, and others. |
| 41 | +- `~/runtime_metrics` (`std_msgs/msg/String`): backward-compatible legacy key=value string. |
| 42 | +- `~/set_streaming_profile` (`ros2_gst_video_bridge_msgs/srv/SetStreamingProfile`): operator service to switch adaptation profile and optionally reset all counters at runtime. |
| 43 | +- `FIRST_FAILURE_SNAPSHOT` event captures session ID, stream ID, codec, encoder, transport, sink URI, SW-fallback flag, and full effective pipeline on the first streaming failure. |
| 44 | +- Session ID (UUID-like) and stream ID are tracked across all events and status messages. |
| 45 | + |
| 46 | +**Runtime modes** |
| 47 | +- `stream` (default): run the bridge. |
| 48 | +- `list_topics`: print visible `sensor_msgs/msg/Image` topics and exit. |
| 49 | +- `list_capabilities`: run `gst-inspect-1.0` and report detected plugins, encoders, and sinks. |
| 50 | +- `validate_config`: validate parameters and exit with code 0 (valid) or 1 (invalid). |
| 51 | +- `discover`: combines `list_topics` + `list_capabilities`. |
| 52 | + |
| 53 | +**Reconnect** |
| 54 | +- Automatic reconnect with configurable interval and optional maximum attempt limit. |
| 55 | +- SW-fallback is attempted on reconnect if HW encoder has failed repeatedly. |
| 56 | +- `pipeline_reconfigure_requested_` flag ensures a new `StreamEngine` is created with the updated pipeline after adaptation or fallback. |
| 57 | + |
| 58 | +**Launch files** |
| 59 | +- `gst_video_bridge_minimal.launch.py`: essential arguments only. |
| 60 | +- `gst_video_bridge_advanced.launch.py`: full parameter surface + `params_file` support. |
| 61 | +- `gst_video_bridge.launch.py`: compatibility wrapper. |
| 62 | +- All launches support optional `image_proc/debayer` node via `enable_debayer` argument. |
| 63 | + |
| 64 | +**Profile presets** |
| 65 | +- Machine profiles: `jetson`, `x86`, `raspi`, `generic`. |
| 66 | +- Stream profiles: `default`, `low_latency`, `low_bandwidth`, `high_quality`, `monitoring_udp`. |
| 67 | +- Seven curated YAML profile files under `config/profiles/`. |
| 68 | + |
| 69 | +**Testing** |
| 70 | +- `test_config_loader`: profile defaults, invalid mode rejection, alias precedence (4 tests). |
| 71 | +- `test_pipeline_builder`: SRT/UDP h264, HW encoder (Jetson nvv4l2), h265 × 4 transports, mjpeg × 4 transports (5 tests). |
| 72 | +- `test_image_format`: shape validation, unsupported encoding, invalid step, truncated data, Bayer grayscale fallback (5 tests). |
| 73 | +- `test_stream_engine`: synthetic frame pushed through `appsrc → fakesink` pipeline (1 test). |
| 74 | +- `test_detail_utils`: `startsWith`, `extractElementName`, `selectSoftwareEncoderForCodec`, `computeAdaptationScales` — 18 cases covering all profiles and edge conditions. |
| 75 | +- `test_metrics_publisher`: counter accumulation, state reflection, adaptation/encoding metadata in published `RuntimeStatus` (9 tests). |
| 76 | +- Smoke tests: `validate_config`, `list_capabilities`, and `--show-args` for all three launch files. |
| 77 | +- Total: **11 CTest entries** (6 gtest targets + 5 smoke tests), **42 individual test cases**. |
| 78 | + |
| 79 | +**Tooling** |
| 80 | +- `clang-format-15` with `.clang-format` (LLVM style, 100-column limit, C++17). |
| 81 | +- `clang-tidy-15` with `.clang-tidy` (bugprone, performance, readability, modernize, cppcoreguidelines checks). |
| 82 | +- Both tools discovered by versioned binary names in `CMakeLists.txt`; build continues gracefully if not found. |
| 83 | +- CI (`build-and-test` + `nightly-matrix`) on Ubuntu 22.04 / ROS 2 Humble. |
| 84 | +- CI `clang-format-check` job runs `--dry-run --Werror` on all headers and sources. |
| 85 | +- Codec/transport matrix script (`run_transport_codec_matrix.zsh`) and soak script (`run_soak_profile.zsh`). |
| 86 | + |
| 87 | +**Documentation** |
| 88 | +- `docs/CONTROL_PLANE.md`: topic/service contract reference. |
| 89 | +- `docs/DEPENDENCIES.md`: required and optional apt packages, plugin checks. |
| 90 | +- `docs/PLATFORM_MATRIX.md`: tested hardware/OS/ROS combinations. |
| 91 | +- `docs/TROUBLESHOOTING.md`: common failure modes with diagnosis and recovery steps. |
| 92 | +- `README.md`: full parameter reference tables with types, defaults, and descriptions. |
| 93 | +- `CONTRIBUTING.md`: development setup, coding conventions, test requirements, PR checklist. |
| 94 | + |
| 95 | +### Changed |
| 96 | + |
| 97 | +- `appsrc` configured as non-blocking (`block=false`) with a bounded 2-buffer internal queue and upstream leaky policy; back-pressure drops are counted separately and do not cause a reconnect when the queue is the only error. |
| 98 | +- `busLoop` switched from a 100 ms blocking `gst_bus_timed_pop_filtered` call (held mutex) to a non-blocking poll + 10 ms sleep, eliminating push stalls under high frame rates. |
| 99 | +- Modern `transport.*`, `codec.*`, `runtime.*` parameter names always override legacy `gst.*` aliases when both are set. |
| 100 | +- CI checkout uses `path: ws/src/ros2_gst_video_bridge` matching a real colcon workspace layout. |
| 101 | +- Internal duplicate utility functions (`startsWith`, `extractElementName`) extracted to `detail/string_utils.hpp`; adaptation scaling extracted to `detail/adaptation.hpp`; SW encoder selection to `detail/encoder_selection.hpp`. |
| 102 | + |
| 103 | +### Fixed |
| 104 | + |
| 105 | +- `busLoop` mutex stall: the bus thread no longer holds `mutex_` during a potentially blocking GStreamer poll. |
| 106 | +- `buildLegacyPayload` now correctly declared and defined as `static`. |
| 107 | +- Redundant `encoder{""}` default initializer removed from `CodecConfig`. |
| 108 | +- `.gitignore` extended to exclude `TODO*.md` patterns. |
| 109 | + |
| 110 | +### Verified |
| 111 | + |
| 112 | +- Jetson Orin / aarch64, Linux 5.15.148-tegra, ROS Humble, GStreamer 1.20.x. |
| 113 | +- Basler acA2440-35uc USB3 camera at ~30 Hz BayerRG8. |
| 114 | +- MPEG-TS/H.264 file sink validated end-to-end. |
| 115 | +- All 11 CTest tests pass on the Jetson build. |
| 116 | +- `clang-format` check passes on all headers and sources. |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +## [0.1.0] — First tagged release (pending) |
| 121 | + |
| 122 | +_See Unreleased above. This section will be finalised when the first annotated tag is created._ |
| 123 | + |
0 commit comments