APP-16408 handle depth cam#71
Merged
Merged
Conversation
🦋 Changeset detectedLatest commit: 5b30904 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
- export-screenshot: decode depth frames to PNG before download so the exported file is viewable; derive extension from MIME type rather than hardcoding .jpeg; move filename construction after source resolution - decode-viam-depth.spec.ts: replace optional chaining on received values with explicit toBeDefined() guards; add all-zero frame edge case covering the Number.isFinite(min) fallback path - live-or-polling-video: surface decodeViamDepth failure to lastError instead of silently freezing the feed Co-authored-by: Devin T. Currie <DTCurrie@users.noreply.github.com>
This comment was marked as outdated.
This comment was marked as outdated.
Co-authored-by: Devin T. Currie <DTCurrie@users.noreply.github.com>
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
mattmacf98
approved these changes
May 20, 2026
Member
mattmacf98
left a comment
There was a problem hiding this comment.
LGTM with one nit: for containing more of the depth decoding only in decode-viam-depth
Consolidates depth-to-PNG-blob conversion into getBlobForViamDepth in decode-viam-depth.ts. Both live-or-polling-video.svelte and export-screenshot.svelte now use it instead of duplicating the decode → canvas → toBlob pipeline inline. Also adds the DEPTHMAP magic-byte validation to decodeViamDepth, fixing the broken placement introduced in the previous commit. Co-authored-by: Devin T. Currie <DTCurrie@users.noreply.github.com>
97ea30d to
b15b11e
Compare
…nto app-16408-handle-depth-cam
…obotics/test-widgets into app-16408-handle-depth-cam
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the camera widget's source dropdown so switching between sources like
coloranddepthactually updates the displayed image. The dropdown was effectively inert for multi-source cameras (e.g., RealSense), and the depth source rendered as a blank feed because the browser cannot decode Viam's custom depth MIME type.Frontend
pick-image-for-source.ts: new helper that selects theNamedImagematching the chosen source, falling back to the first image. Used as a defensive client-side filter for cameras whoseImages()ignoresfilter_source_namesand returns every source.decode-viam-depth.ts: new decoder forimage/vnd.viam.dep. Parses the 24-byte header (8-byteDEPTHMAPmagic, two big-endianuint64dimensions) and theuint16big-endian depth grid, then emits a colorizedUint8ClampedArrayusing the same hue sweep (30° warm to 230° cool) that RDK'sDepthMap.ToPrettyPictureproduces. Zero-depth pixels render as opaque black to match RDK.live-or-polling-video.svelte: takes a newsourceNameprop. The polling-image effect now usespickImageForSourceinstead ofdata.images[0], and routesimage/vnd.viam.depframes throughdecodeViamDepthto aputImageDatacall on the existing canvas so they participate in the same capture stream and FPS counter as JPEG frames.export-screenshot.svelte: takes asourceNameprop so screenshots respect the dropdown.camera.svelte: passesselectedSourcethrough toLiveOrPollingVideoandExportScreenshot, and usespickImageForSourcein theAdd current image to datasethandler so saved frames also match the selected source.Why?
Why filter client-side when the proto already supports
filter_source_names?The server-side filter is honored by some camera implementations (e.g., the
fakefile source) and ignored by others. The RealSense module on thevino-1left-camreturns every source regardless of the filter, so the existingdata.images[0]indexing always rendered the same frame even though the query key changed. Picking the matchingsourceNameon the client makes the widget work with both kinds of implementations and is a no-op when the server filters.Why decode
image/vnd.viam.depourselves?image/vnd.viam.depis a Viam-specific binary format (defined inrdk/rimage/depth_map_raw.go). Browsers have no codec for it, so settingimg.srcto a blob with that MIME type silently fails to load and the canvas never updates, which is why selectingdepthlooked frozen and the FPS counter stopped advancing. Decoding to anImageDataand writing straight to the existing canvas reuses the samecaptureStreamplumbing as JPEG frames, so the live feed, FPS counter, and picture-in-picture all keep working with no special-casing downstream.Why match RDK's hue sweep instead of grayscale?
The initial grayscale visualization appeared almost entirely black because depth values in a typical room span a narrow range within the
uint16range, and grayscale uses only one channel. RDK'sToPrettyPicturemaps(depth - min) / (max - min)to hue 30° to 230° at full saturation and value, which spreads the same range across all three channels and matches what other Viam tooling shows for depth.Testing
Ran
pnpm check,pnpm lint, andpnpm test. Added two unit test files:pick-image-for-source.spec.ts: covers matching by source name, fallback to first image, empty input, and missing source name.decode-viam-depth.spec.ts: covers header parsing, warm/cool hue mapping, opaque-black handling of zero-depth pixels, and rejection of truncated buffers.Verified visually against
vino-1'sleft-camandright-camin bothcoloranddepthmode that switching the dropdown updates the feed at the polling rate.