Skip to content

New reference to show off a realsense viewer.#20

Open
nicksinas wants to merge 8 commits into
mainfrom
nsinas/realsense
Open

New reference to show off a realsense viewer.#20
nicksinas wants to merge 8 commits into
mainfrom
nsinas/realsense

Conversation

@nicksinas

Copy link
Copy Markdown
Collaborator

No description provided.

@nicksinas
nicksinas requested a review from jetm July 15, 2026 03:30

@jetm jetm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared against the existing python-flask/python-yolo reference pattern; one correctness concern on the load-bearing dependency, plus a minor doc-drift note.

Comment thread realsense/app-compile.sh Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new realsense reference project that demonstrates a native C++ Intel RealSense “web visualizer” system extension for Avocado OS, including build tooling, runtime packaging, and end-user docs.

Changes:

  • Introduces a new realsense/ reference with README + getting-started documentation.
  • Adds a C++17 RealSense capture + libmicrohttpd-based MJPEG/JSON server with an embedded dashboard UI.
  • Adds Avocado extension configuration, systemd service unit, and compile/install/clean scripts.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
realsense/README.md Reference overview and metadata (targets/topics/icon) for the references index.
realsense/getting_started.md Step-by-step instructions for init/build/deploy/verify/customize.
realsense/avocado.yaml Defines supported targets, extensions, packages, and SDK compile steps.
realsense/avocado.lock Locks distro/targets for the reference (currently only raspberrypi5).
realsense/app/src/CMakeLists.txt CMake build for the realsense-visualizer executable linking to packaged deps.
realsense/app/src/app.cpp Implements capture loop, HTTP endpoints, MJPEG streaming, and dashboard HTML.
realsense/app/overlay/usr/lib/systemd/system/realsense-visualizer.service Installs/enables the systemd service to run the visualizer on boot.
realsense/app-install.sh Installs the built binary into the extension sysroot via cmake --install.
realsense/app-compile.sh Cross-compiles via generated toolchain file and CMake build directory.
realsense/app-clean.sh Cleans build artifacts.
realsense/.gitignore Ignores Avocado state and build output for this reference.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/app/src/app.cpp
Comment thread realsense/app/src/app.cpp
Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/README.md

@jetm jetm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Traced all of Copilot's findings against the full app.cpp - they're all valid and worth fixing: feed_reader returning 0 (L256) is non-idiomatic and version-fragile for the MJPEG path; MHD_create_response_from_buffer/_from_callback can return NULL (L280/L294) and are used without a guard (the callback path also leaks the FeedState on that NULL); and /api/distance (L561) returns 503 for missing x/y query params, which is a client error that should be 400, not "no depth data." The README targets vs avocado.yaml supported_targets mismatch is real too - the manifest adds imx8mp-var-dart, imx95-frdm, and ucm-imx8m-plus that the README omits. The one thing not already flagged is the most serious (inline at L175): the capture-thread loop body has no exception handler, so a camera unplug mid-stream aborts the whole process. Lower-priority: g_running is never cleared (no signal handler, so the shutdown atomic is inert), libjpeg's default error_exit calls exit() on a fatal, and app-install.sh writes to DESTDIR=$AVOCADO_BUILD_EXT_SYSROOT without guarding the var is set.

Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/app/src/app.cpp Outdated
- capture loop: wrap start + stream body in try/catch(rs2::error) so a
  mid-stream camera fault (USB unplug) reconnects instead of terminating
- feed_reader: never return 0 mid-stream (MHD reads that as end-of-stream);
  loop until a frame is ready or shutdown
- guard NULL from MHD_create_response_from_buffer/_from_callback; free
  FeedState when MHD doesn't take ownership
- /api/distance: 400 for missing x/y params, 503 only when depth is absent
- clamp the distance lookup against the depth buffer dims, not intrinsics
- SIGTERM/SIGINT handlers so shutdown actually clears g_running
- libjpeg: custom error_exit via setjmp so a bad frame drops the JPEG
  instead of calling exit()
- app-install.sh: fail clearly if AVOCADO_BUILD_EXT_SYSROOT is unset
- README: match frontmatter targets to avocado.yaml supported_targets
@nicksinas

Copy link
Copy Markdown
Collaborator Author

Pushed bc693a1 addressing the review. All inline threads (Copilot's five + the capture-loop crash and latent OOB) are fixed and resolved.

The three lower-priority items from the review summary are also in this commit:

  • g_running was inert — added SIGTERM/SIGINT handlers so a systemd stop clears the flag and the capture loop exits cleanly.
  • libjpeg error_exit calling exit() — installed a custom error manager (setjmp/longjmp); a bad frame now drops the JPEG and the feed continues instead of the process exiting.
  • app-install.sh unguarded DESTDIR — it now fails clearly if AVOCADO_BUILD_EXT_SYSROOT is unset.

Note: I've verified every supported_targets entry (including imx8mp-var-dart, imx95-frdm, ucm-imx8m-plus) has librealsense2 + -dev in the feed, and the README frontmatter now matches the manifest. Still pending a real avocado build on an aarch64 target to confirm the cross-compile before merge.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

realsense/app/src/app.cpp:350

  • /api/distance uses std::atoi, which silently treats non-numeric inputs as 0 (e.g. x=foo => x=0). That makes invalid client requests look like valid measurements. Parse with strtol and return 400 on conversion failure.
    int x = std::atoi(xs);
    int y = std::atoi(ys);

Comment thread realsense/app/src/app.cpp
Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/avocado.yaml
- json_escape: escape control chars (\n, \r, \t, \b, \f, <0x20) so device
  info strings can't produce invalid JSON
- dashboard: build deviceBar with textContent instead of innerHTML, closing
  the XSS surface from /api/device values
- feed_reader: encode only new frames via a frame sequence counter rather
  than a fixed 33ms sleep, matching capture rate (no duplicate encodes)
- /api/distance: parse x/y with strtol, return 400 on non-numeric input
  instead of silently treating it as 0
- avocado.yaml: label the empty root password NOT FOR PRODUCTION
@nicksinas

Copy link
Copy Markdown
Collaborator Author

Pushed e148048 for the second review pass — all four inline threads resolved (json_escape control chars, deviceBar XSS via textContent, duplicate-encode throttle, NOT FOR PRODUCTION password note).

Also addressed the low-confidence suppressed item: /api/distance now parses x/y with strtol and returns 400 on non-numeric input instead of letting atoi silently coerce it to 0.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 12 changed files in this pull request and generated 3 comments.

Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/app/src/app.cpp
Comment thread realsense/app/src/app.cpp
- jpeg_encode: establish setjmp before jpeg_create_compress so a longjmp
  can never land on an uninitialized buffer; guard destroy with a created
  flag and mark it volatile across setjmp
- /api/distance: reject out-of-int-range x/y with 400 before narrowing the
  strtol result (add <limits>)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 12 changed files in this pull request and generated 3 comments.

Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/getting_started.md
Comment thread realsense/app/src/app.cpp Outdated
- serve the static dashboard HTML as a persistent MHD buffer instead of
  copying the whole page on every "/" request
- build g_device_json with std::string instead of a fixed 512-byte buffer
  so a long device string can't truncate it into invalid JSON
- getting_started.md: note the empty root SSH password is dev-only, not
  for production images

@jetm jetm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This revision addresses almost everything from the last round - NULL/lifetime checks on the MHD responses, the content-reader no longer returns a bare 0, 400-vs-503 is cleanly separated, the clamp/index dims are consistent, g_running is now driven by a real SIGTERM/SIGINT handler, the README targets match avocado.yaml, and the device bar switched to textContent (nice XSS close). Two residual items inline. One more (LOW, no clean line to anchor): app-install.sh got the AVOCADO_BUILD_EXT_SYSROOT guard this round, but app-compile.sh still expands OECORE_TARGET_SYSROOT/CROSS_COMPILE unquoted with no guard (set -e, not -u), so run outside the SDK env it emits a silently-wrong host toolchain file instead of failing - add a matching -z check for parity.

Comment thread realsense/app/src/app.cpp Outdated
Comment thread realsense/app/src/app.cpp
- capture_loop: also catch std::exception (e.g. std::bad_alloc from the
  ~1MB per-frame buffers under memory pressure) so it can't escape the
  thread and call std::terminate; factor the stale-mark + backoff into a
  shared recover() used by both handlers
- jpeg_encode: qualify out/out_size volatile so their values stay defined
  across setjmp/longjmp (C11 7.13.2.1) before the recovery-path free

@jetm jetm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two inline fixes from last round are verified good - the capture thread now catches std::bad_alloc, and out/out_size are volatile with the const_cast at jpeg_mem_dest. Three items inline: the same bad_alloc hazard is unguarded on the HTTP-callback side (feed_reader runs in an MHD worker thread) - MEDIUM; app-compile.sh still lacks the env guard app-install.sh got; and the capture-thread config setup runs just outside its try. Everything else re-verified clean (MHD NULL/lifetime, 400-vs-503, thread-safety/bounds, signal-driven shutdown, README/yaml match).

Comment thread realsense/app/src/app.cpp
Comment thread realsense/app-compile.sh Outdated
Comment thread realsense/app/src/app.cpp Outdated
- feed_reader / handle_request: wrap bodies in try/catch(...) so a
  std::bad_alloc (from snapshot copy, jpeg_encode, or chunk concat) can't
  unwind into libmicrohttpd's C worker thread; end the feed with
  MHD_CONTENT_READER_END_WITH_ERROR and return MHD_NO for the request
- capture_loop: construct rs2::config inside the try so a throw during
  stream config can't escape the thread either
- app-compile.sh: guard OECORE_TARGET_SYSROOT (mirrors app-install.sh) and
  quote the sysroot path; fail early with a clear message outside the SDK env

@jetm jetm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed across several rounds; all findings are addressed and verified on 6e3a86c - the HTTP-callback threads (feed_reader/handle_request) now catch exceptions, app-compile.sh guards OECORE_TARGET_SYSROOT, and the capture config setup is inside the try. LGTM.

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.

3 participants