Skip to content

Forward JPEG CompressedImage topics as LiveKit video tracks (2/4) - #111

Merged
stephen-derosa merged 6 commits into
mainfrom
sderosa/video-2-compressed-image-outbound
Oct 22, 2026
Merged

stephen-derosa merged 6 commits into
mainfrom
sderosa/video-2-compressed-image-outbound

Conversation

@stephen-derosa

@stephen-derosa stephen-derosa commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Overview

Forward JPEG sensor_msgs/CompressedImage topics as LiveKit video tracks, and send the ROS header with each video frame.

Stack

This is part of a stack that replaces #109. Review and merge in order:

  1. Send raw images to LiveKit with fewer pixel copies (1/4) #110 Raw image fast path
  2. Forward JPEG CompressedImage topics as LiveKit video tracks (2/4) #111 Outbound CompressedImage to video track (this PR)
  3. Republish LiveKit video tracks as ROS CompressedImage (3/4) #112 Inbound video track to CompressedImage
  4. Add a video pass-through tutorial (4/4) #113 Video pass-through tutorial

Details

  • Adds libturbojpeg (Dockerfile, package.xml, CMake) with JpegDecoder and JpegEncoder. The encoder is used by the inbound path in the next PR and by the tests here.
  • Video tracks keep the full ROS topic name, like DataTracks. /cam/image_raw/compressed publishes /cam/image_raw/compressed; raw and compressed topics can be forwarded independently.
  • Each outbound frame carries header.stamp as user_timestamp_us and header.frame_id as user data (video_frame_metadata). The track is published with frame_metadata_features turned on.
  • Docs: "Outbound video" in docs/configuration.md, outbound rows in docs/diagnostics.md, and docs/limitations.md.

Breaking changes

N/A

Testing

  • Built in an isolated ROS 2 Jazzy devcontainer with compile commands enabled.
  • Unit and integration suites pass: colcon test-result --verbose reports 532 tests, zero errors, zero failures, zero skipped.
  • Integration tests use source scripts/set-test-tokens.sh and local LiveKit 1.13.6 started with livekit-server --dev --enable_participant_data_blob.
  • ./scripts/clang-format.sh passes for all changed C++ files.
  • ./scripts/clang-tidy.sh passes for topic_forwarder.cpp and ros_utils.cpp, with zero reported warnings or errors.

Comment thread docs/configuration.md Resolved
Comment thread docs/configuration.md Resolved
Comment thread docs/diagnostics.md Resolved
Base automatically changed from sderosa/video-1-raw-image-fast-path to main October 21, 2026 23:37
ROS Portal now subscribes to outbound sensor_msgs/CompressedImage topics.
It decodes each JPEG frame with libturbojpeg and sends it as a video
track. A topic named <base>/compressed publishes the track <base>. If two
topics map to the same track name, only the first one is forwarded and
the clash counts in outbound.failures.

Each outbound video frame now carries the ROS header.stamp and
header.frame_id as LiveKit frame metadata, so a receiver can restore the
header. This also adds the JpegEncoder that the inbound path uses.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@stephen-derosa
stephen-derosa force-pushed the sderosa/video-2-compressed-image-outbound branch from cd70c47 to ba3e630 Compare October 21, 2026 23:47
@stephen-derosa
stephen-derosa merged commit 7849ab0 into main Oct 22, 2026
34 checks passed
@stephen-derosa
stephen-derosa deleted the sderosa/video-2-compressed-image-outbound branch October 22, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants