Conversation
📝 WalkthroughWalkthroughAdds SDL2 via CMake FetchContent and bundles it with the OAK plugin. Introduces a PreviewStream (SDL window) and integrates it into OakCamera with local pipeline creation, dynamic color resolution selection, and a new --preview CLI flag to enable live preview rendering. Changes
Sequence DiagramsequenceDiagram
participant User
participant OakCamera
participant Pipeline
participant PreviewStream
participant Queue as DataOutputQueue
participant SDL as SDL Renderer
User->>OakCamera: init (preview=true)
OakCamera->>OakCamera: create_pipeline(color_resolution)
OakCamera->>PreviewStream: PreviewStream::try_create(name, Pipeline, resolution)
PreviewStream->>Pipeline: find_or_create ColorCamera on CAM_A, add XLinkOut
PreviewStream->>SDL: SDL_CreateWindow / SDL_CreateRenderer
PreviewStream-->>OakCamera: return PreviewStream
OakCamera->>Pipeline: start pipeline on device
OakCamera->>PreviewStream: setOutputQueue(queue)
loop per-frame
OakCamera->>PreviewStream: update()
PreviewStream->>Queue: getImgFrame(timeout)
Queue-->>PreviewStream: ImgFrame
PreviewStream->>SDL: SDL_UpdateTexture(frame data)
SDL->>SDL: SDL_RenderCopy & SDL_RenderPresent
PreviewStream->>PreviewStream: poll SDL events (quit / esc / q)
end
User->>PreviewStream: press q / esc / close window
PreviewStream->>SDL: cleanup texture, renderer, window
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
23be2d5 to
419d8ef
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/plugins/oak/CMakeLists.txt`:
- Around line 4-8: The top-of-file comment block in CMakeLists.txt has malformed
separator lines (e.g., "#== == == ..." with extra spaces); fix by normalizing
those header comment separators to a single consistent, readable pattern (for
example a continuous sequence of "=" or "-" characters) and remove the stray
spaces so the block around the "OAK Camera Plugin" header is uniformly
formatted; update the three affected lines in the header comment to match the
chosen consistent separator style.
- Around line 35-46: The CMakeLists currently pins SDL2 via the SDL2_VERSION
variable set to "2.30.11" (used by FetchContent_Declare sdl2 and the URL)
without explanation; either update SDL2_VERSION to "2.32.10" to use the latest
stable release or add a short comment above the SDL2_VERSION declaration
explaining why 2.30.11 is required (e.g., compatibility, API/ABI constraints, or
CI/test matrix). Ensure the change touches the SDL2_VERSION definition and the
FetchContent_Declare URL reference so they remain consistent.
In `@src/plugins/oak/core/oak_camera.cpp`:
- Around line 56-57: If config.preview is true but
PreviewStream::try_create(kPreviewStreamName, pipeline, color_resolution)
returns nullptr, add a log message indicating preview creation failed so users
know their --preview flag had no effect; check the result assigned to m_preview
and when it is null call an appropriate logger (e.g., warn/error) with context
including kPreviewStreamName and that SDL/preview initialization failed to help
debugging.
In `@src/plugins/oak/core/preview_stream.cpp`:
- Around line 107-110: PreviewStream::setOutputQueue currently dereferences
m_impl without validation; add a defensive null check to avoid a crash when
called on a default-constructed PreviewStream by verifying m_impl is non-null
before using it and returning or logging/throwing if it is null. Specifically,
in PreviewStream::setOutputQueue, check if m_impl (the internal implementation
pointer) is null, and only call m_impl->queue = std::move(queue) when it's
valid; if m_impl is null, handle gracefully (e.g., return early or report an
error via existing logging/error mechanisms).
- Around line 24-33: The Impl destructor currently calls SDL_Quit()
unconditionally which can tear down SDL for other users; update the cleanup in
~Impl() to avoid globally quitting SDL — either call
SDL_QuitSubSystem(SDL_INIT_VIDEO) instead of SDL_Quit() to only shut down the
video subsystem, or implement a simple reference-counted init/teardown for the
video subsystem (increment on Init call and decrement in ~Impl(), calling
SDL_QuitSubSystem(SDL_INIT_VIDEO) when the count reaches zero); modify the
~Impl() body (the destructor of Impl in PreviewStream) to use
SDL_QuitSubSystem(SDL_INIT_VIDEO) or the ref-counting mechanism and remove the
unconditional SDL_Quit() call.
- Around line 112-116: PreviewStream::update currently calls
m_impl->queue->tryGet<dai::ImgFrame>() without ensuring m_impl->queue is set,
which can crash if update() runs before setOutputQueue(); add a defensive null
check for m_impl->queue at the start of PreviewStream::update and return early
if it's null. Reference the m_impl->queue pointer and the setOutputQueue setter
when adding the guard so future callers won't dereference a null queue before
calling tryGet.
- Around line 145-152: The update loop in PreviewStream consumes quit/key events
but doesn't inform callers; change PreviewStream::update() to return a bool
(true = continue, false = quit) by updating the declaration in
preview_stream.hpp and its implementation in preview_stream.cpp so that when
SDL_QUIT or keydown for SDLK_ESCAPE/SDLK_q is seen the method returns false
instead of early-returning void; then update callers (e.g., oak_camera.cpp) to
check the returned bool and initiate shutdown/stop the preview when false.
Ensure all call sites are updated to handle the new bool return and recompile.
In `@src/plugins/oak/main.cpp`:
- Line 6: Remove the unused include "core/preview_stream.hpp" from main.cpp:
inspect the top of the file where `#include` "core/preview_stream.hpp" is present
and delete it if PreviewStream is not referenced; verify that OakCamera (class
OakCamera) provides the preview functionality and that no direct use or forward
declaration of PreviewStream exists in main.cpp before removing; run a build to
confirm there are no missing symbols and only re-add the include if a direct
dependency or forward declaration for PreviewStream is discovered.
- Around line 109-110: The help text incorrectly says "via OpenCV window";
update the usage/help output in main.cpp (the block that prints "\nPreview:\n"
and the line containing "--preview Show live color camera preview via
OpenCV window") to reference SDL2 instead (e.g., "Show live color camera preview
via SDL2 window" or similar). Also ensure any adjacent help wording in the same
printing routine or function (main / usage printing) is consistent with
preview_stream.cpp's SDL2-based implementation.
In `@src/plugins/oak/README.md`:
- Around line 25-27: Update the src/plugins/oak/README.md to document the new
CLI flag --preview: add an entry for --preview in the Configuration/options
table describing its behavior, list any SDL2 system dependencies required to
enable preview mode (e.g., libsdl2-dev or equivalent), and add a short example
command line showing how to build/run with --preview (alongside the existing
cmake examples). Ensure the text clearly notes that preview requires SDL2 and
any platform-specific notes so users know to install the dependency before using
--preview.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
src/plugins/oak/CMakeLists.txtsrc/plugins/oak/README.mdsrc/plugins/oak/core/oak_camera.cppsrc/plugins/oak/core/oak_camera.hppsrc/plugins/oak/core/preview_stream.cppsrc/plugins/oak/core/preview_stream.hppsrc/plugins/oak/main.cpp
src/plugins/oak/CMakeLists.txt
Outdated
| #== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == | ||
| #OAK Camera Plugin | ||
| #== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == | ||
| #Uses FetchContent with HunterGate initialized at top - level for single - pass build. | ||
| #== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Broken comment formatting.
The comment separators appear malformed with extra spaces around the equals signs, which may have resulted from an automated formatting tool. While this doesn't affect functionality, it reduces readability.
Proposed fix
-#== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
-#OAK Camera Plugin
-#== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
-#Uses FetchContent with HunterGate initialized at top - level for single - pass build.
-#== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
+# ==============================================================================
+# OAK Camera Plugin
+# ==============================================================================
+# Uses FetchContent with HunterGate initialized at top-level for single-pass build.
+# ==============================================================================🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/CMakeLists.txt` around lines 4 - 8, The top-of-file comment
block in CMakeLists.txt has malformed separator lines (e.g., "#== == == ..."
with extra spaces); fix by normalizing those header comment separators to a
single consistent, readable pattern (for example a continuous sequence of "=" or
"-" characters) and remove the stray spaces so the block around the "OAK Camera
Plugin" header is uniformly formatted; update the three affected lines in the
header comment to match the chosen consistent separator style.
| set(SDL2_VERSION "2.30.11") | ||
|
|
||
| set(SDL_TEST OFF CACHE BOOL "" FORCE) | ||
| set(SDL_SHARED ON CACHE BOOL "" FORCE) | ||
| set(SDL_STATIC OFF CACHE BOOL "" FORCE) | ||
|
|
||
| FetchContent_Declare( | ||
| sdl2 | ||
| URL "https://github.com/libsdl-org/SDL/releases/download/release-${SDL2_VERSION}/SDL2-${SDL2_VERSION}.tar.gz" | ||
| ) | ||
| FetchContent_MakeAvailable(sdl2) | ||
| message(STATUS "SDL2 ${SDL2_VERSION} — live preview support enabled") |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
🧩 Analysis chain
🌐 Web query:
SDL2 2.30.11 release date latest version
💡 Result:
- SDL2 2.30.11 release date: January 1, 2025. [1][2]
- Latest SDL2 version (as of Feb 27, 2026): 2.32.10 (release artifacts dated September 1, 2025 on libsdl.org). [3]
Sources:
[1] https://libsdl.org/release/ (SDL2-2.30.11 files dated 2025-01-01)
[2] https://discourse.libsdl.org/t/sdl-updated-to-version-2-30-11-for-release/56485 (commit/update for 2.30.11 on 01 Jan 2025)
[3] https://libsdl.org/release/ (SDL2-2.32.10 files dated 2025-09-01)
Consider updating to SDL2 2.32.10 or document the reason for pinning to 2.30.11.
SDL2 2.30.11 is available from libsdl.org, but version 2.32.10 was released in September 2025 and is currently the latest stable release. If remaining on 2.30.11 is intentional, add a comment explaining the rationale; otherwise, consider upgrading to the latest version.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/CMakeLists.txt` around lines 35 - 46, The CMakeLists
currently pins SDL2 via the SDL2_VERSION variable set to "2.30.11" (used by
FetchContent_Declare sdl2 and the URL) without explanation; either update
SDL2_VERSION to "2.32.10" to use the latest stable release or add a short
comment above the SDL2_VERSION declaration explaining why 2.30.11 is required
(e.g., compatibility, API/ABI constraints, or CI/test matrix). Ensure the change
touches the SDL2_VERSION definition and the FetchContent_Declare URL reference
so they remain consistent.
| if (config.preview) | ||
| m_preview = PreviewStream::try_create(kPreviewStreamName, pipeline, color_resolution); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider logging when preview creation fails.
If PreviewStream::try_create returns nullptr (e.g., SDL initialization fails), the pipeline continues without preview but there's no indication to the user that their --preview flag was ineffective. The error is logged inside try_create, but an additional message at this level would improve user experience.
Proposed enhancement
if (config.preview)
+ {
m_preview = PreviewStream::try_create(kPreviewStreamName, pipeline, color_resolution);
+ if (!m_preview)
+ std::cerr << "Warning: Preview requested but could not be initialized" << std::endl;
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/oak_camera.cpp` around lines 56 - 57, If config.preview
is true but PreviewStream::try_create(kPreviewStreamName, pipeline,
color_resolution) returns nullptr, add a log message indicating preview creation
failed so users know their --preview flag had no effect; check the result
assigned to m_preview and when it is null call an appropriate logger (e.g.,
warn/error) with context including kPreviewStreamName and that SDL/preview
initialization failed to help debugging.
| ~Impl() | ||
| { | ||
| if (texture) | ||
| SDL_DestroyTexture(texture); | ||
| if (renderer) | ||
| SDL_DestroyRenderer(renderer); | ||
| if (window) | ||
| SDL_DestroyWindow(window); | ||
| SDL_Quit(); | ||
| } |
There was a problem hiding this comment.
SDL_Quit() called unconditionally in destructor.
Calling SDL_Quit() in the destructor assumes this is the only SDL user. If multiple PreviewStream instances were created (even sequentially), or if other code uses SDL, this could cause issues. Consider using SDL_QuitSubSystem(SDL_INIT_VIDEO) instead, or reference-counting SDL initialization.
Proposed safer cleanup
~Impl()
{
if (texture)
SDL_DestroyTexture(texture);
if (renderer)
SDL_DestroyRenderer(renderer);
if (window)
SDL_DestroyWindow(window);
- SDL_Quit();
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ~Impl() | |
| { | |
| if (texture) | |
| SDL_DestroyTexture(texture); | |
| if (renderer) | |
| SDL_DestroyRenderer(renderer); | |
| if (window) | |
| SDL_DestroyWindow(window); | |
| SDL_Quit(); | |
| } | |
| ~Impl() | |
| { | |
| if (texture) | |
| SDL_DestroyTexture(texture); | |
| if (renderer) | |
| SDL_DestroyRenderer(renderer); | |
| if (window) | |
| SDL_DestroyWindow(window); | |
| SDL_QuitSubSystem(SDL_INIT_VIDEO); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/preview_stream.cpp` around lines 24 - 33, The Impl
destructor currently calls SDL_Quit() unconditionally which can tear down SDL
for other users; update the cleanup in ~Impl() to avoid globally quitting SDL —
either call SDL_QuitSubSystem(SDL_INIT_VIDEO) instead of SDL_Quit() to only shut
down the video subsystem, or implement a simple reference-counted init/teardown
for the video subsystem (increment on Init call and decrement in ~Impl(),
calling SDL_QuitSubSystem(SDL_INIT_VIDEO) when the count reaches zero); modify
the ~Impl() body (the destructor of Impl in PreviewStream) to use
SDL_QuitSubSystem(SDL_INIT_VIDEO) or the ref-counting mechanism and remove the
unconditional SDL_Quit() call.
| void PreviewStream::setOutputQueue(std::shared_ptr<dai::DataOutputQueue> queue) | ||
| { | ||
| m_impl->queue = std::move(queue); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Missing null check on m_impl.
If setOutputQueue is called on a default-constructed PreviewStream (which shouldn't happen with the factory pattern, but could occur if the code evolves), this will crash. Consider adding a defensive check.
Proposed defensive check
void PreviewStream::setOutputQueue(std::shared_ptr<dai::DataOutputQueue> queue)
{
+ if (!m_impl)
+ return;
m_impl->queue = std::move(queue);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void PreviewStream::setOutputQueue(std::shared_ptr<dai::DataOutputQueue> queue) | |
| { | |
| m_impl->queue = std::move(queue); | |
| } | |
| void PreviewStream::setOutputQueue(std::shared_ptr<dai::DataOutputQueue> queue) | |
| { | |
| if (!m_impl) | |
| return; | |
| m_impl->queue = std::move(queue); | |
| } |
🧰 Tools
🪛 Cppcheck (2.19.0)
[style] 107-107: The function 'setOutputQueue' is never used.
(unusedFunction)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/preview_stream.cpp` around lines 107 - 110,
PreviewStream::setOutputQueue currently dereferences m_impl without validation;
add a defensive null check to avoid a crash when called on a default-constructed
PreviewStream by verifying m_impl is non-null before using it and returning or
logging/throwing if it is null. Specifically, in PreviewStream::setOutputQueue,
check if m_impl (the internal implementation pointer) is null, and only call
m_impl->queue = std::move(queue) when it's valid; if m_impl is null, handle
gracefully (e.g., return early or report an error via existing logging/error
mechanisms).
| void PreviewStream::update() | ||
| { | ||
| auto frame = m_impl->queue->tryGet<dai::ImgFrame>(); | ||
| if (!frame) | ||
| return; |
There was a problem hiding this comment.
Missing null check on queue before use.
If update() is called before setOutputQueue(), m_impl->queue will be null and tryGet will likely crash. Consider adding a defensive check.
Proposed fix
void PreviewStream::update()
{
+ if (!m_impl || !m_impl->queue)
+ return;
auto frame = m_impl->queue->tryGet<dai::ImgFrame>();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void PreviewStream::update() | |
| { | |
| auto frame = m_impl->queue->tryGet<dai::ImgFrame>(); | |
| if (!frame) | |
| return; | |
| void PreviewStream::update() | |
| { | |
| if (!m_impl || !m_impl->queue) | |
| return; | |
| auto frame = m_impl->queue->tryGet<dai::ImgFrame>(); | |
| if (!frame) | |
| return; |
🧰 Tools
🪛 Cppcheck (2.19.0)
[style] 112-112: The function 'update' is never used.
(unusedFunction)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/preview_stream.cpp` around lines 112 - 116,
PreviewStream::update currently calls m_impl->queue->tryGet<dai::ImgFrame>()
without ensuring m_impl->queue is set, which can crash if update() runs before
setOutputQueue(); add a defensive null check for m_impl->queue at the start of
PreviewStream::update and return early if it's null. Reference the m_impl->queue
pointer and the setOutputQueue setter when adding the guard so future callers
won't dereference a null queue before calling tryGet.
| SDL_Event event; | ||
| while (SDL_PollEvent(&event)) | ||
| { | ||
| if (event.type == SDL_QUIT) | ||
| return; | ||
| if (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q)) | ||
| return; | ||
| } |
There was a problem hiding this comment.
Key/quit events are silently ignored after first frame.
When the user presses Escape, Q, or closes the window, update() simply returns early without signaling to the caller. The main loop will call update() again on the next iteration, and the event will have been consumed. The preview window will appear unresponsive to quit requests.
Consider either:
- Returning a boolean to indicate if the user requested quit
- Setting a flag accessible to the caller
- Raising
SIGINTto trigger the existing shutdown path
Option 1: Return bool to indicate quit request
In preview_stream.hpp:
- void update();
+ /** `@brief` Poll the queue and display a frame. Returns false if user requested quit. */
+ bool update();In preview_stream.cpp:
-void PreviewStream::update()
+bool PreviewStream::update()
{
auto frame = m_impl->queue->tryGet<dai::ImgFrame>();
if (!frame)
- return;
+ return true;
// ... rendering code ...
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
- return;
+ return false;
if (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q))
- return;
+ return false;
}
+ return true;
}Then in oak_camera.cpp, signal to stop when preview requests quit.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/preview_stream.cpp` around lines 145 - 152, The update
loop in PreviewStream consumes quit/key events but doesn't inform callers;
change PreviewStream::update() to return a bool (true = continue, false = quit)
by updating the declaration in preview_stream.hpp and its implementation in
preview_stream.cpp so that when SDL_QUIT or keydown for SDLK_ESCAPE/SDLK_q is
seen the method returns false instead of early-returning void; then update
callers (e.g., oak_camera.cpp) to check the returned bool and initiate
shutdown/stop the preview when false. Ensure all call sites are updated to
handle the new bool return and recompile.
|
|
||
| #include "core/frame_sink.hpp" | ||
| #include "core/oak_camera.hpp" | ||
| #include "core/preview_stream.hpp" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Potentially unnecessary include.
preview_stream.hpp is included but PreviewStream is not used directly in main.cpp. The preview functionality is managed internally by OakCamera. Consider removing this include unless it's needed for forward declarations or future use.
🧰 Tools
🪛 Cppcheck (2.19.0)
[information] 6-6: Include file
(missingIncludeSystem)
[information] 6-6: Include file
(missingIncludeSystem)
[information] 6-6: Include file
(missingIncludeSystem)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/main.cpp` at line 6, Remove the unused include
"core/preview_stream.hpp" from main.cpp: inspect the top of the file where
`#include` "core/preview_stream.hpp" is present and delete it if PreviewStream is
not referenced; verify that OakCamera (class OakCamera) provides the preview
functionality and that no direct use or forward declaration of PreviewStream
exists in main.cpp before removing; run a build to confirm there are no missing
symbols and only re-add the include if a direct dependency or forward
declaration for PreviewStream is discovered.
| << "\nPreview:\n" | ||
| << " --preview Show live color camera preview via OpenCV window\n" |
There was a problem hiding this comment.
Help text incorrectly mentions OpenCV instead of SDL2.
The help message states "via OpenCV window" but the implementation uses SDL2 for rendering (as per the PR description and preview_stream.cpp). This is misleading to users.
Proposed fix
<< "\nPreview:\n"
- << " --preview Show live color camera preview via OpenCV window\n"
+ << " --preview Show live color camera preview via SDL2 window\n"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| << "\nPreview:\n" | |
| << " --preview Show live color camera preview via OpenCV window\n" | |
| << "\nPreview:\n" | |
| << " --preview Show live color camera preview via SDL2 window\n" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/main.cpp` around lines 109 - 110, The help text incorrectly
says "via OpenCV window"; update the usage/help output in main.cpp (the block
that prints "\nPreview:\n" and the line containing "--preview Show
live color camera preview via OpenCV window") to reference SDL2 instead (e.g.,
"Show live color camera preview via SDL2 window" or similar). Also ensure any
adjacent help wording in the same printing routine or function (main / usage
printing) is consistent with preview_stream.cpp's SDL2-based implementation.
| cmake -B build -DBUILD_PLUGIN_OAK_CAMERA=ON | ||
| cmake --build build --target camera_plugin_oak --parallel | ||
| ``` |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Missing documentation for the new --preview feature.
The README documents all CLI options but does not mention the new --preview flag introduced in this PR. Consider adding documentation for this feature, including:
- The
--previewoption in the Configuration table - Any SDL2 system dependencies that might be needed
- Example usage with
--preview
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/README.md` around lines 25 - 27, Update the
src/plugins/oak/README.md to document the new CLI flag --preview: add an entry
for --preview in the Configuration/options table describing its behavior, list
any SDL2 system dependencies required to enable preview mode (e.g., libsdl2-dev
or equivalent), and add a short example command line showing how to build/run
with --preview (alongside the existing cmake examples). Ensure the text clearly
notes that preview requires SDL2 and any platform-specific notes so users know
to install the dependency before using --preview.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/plugins/oak/core/preview_stream.cpp`:
- Around line 73-98: After SDL_Init succeeds, ensure we clean up SDL state and
any partially-created resources on early returns: when SDL_CreateWindow or
SDL_CreateRenderer fails, call SDL_DestroyRenderer(impl->renderer) if non-null,
SDL_DestroyWindow(impl->window) if non-null, then call
SDL_QuitSubSystem(SDL_INIT_VIDEO) (or SDL_Quit() as appropriate) before
returning nullptr; you can encapsulate this in a small cleanup helper (e.g.,
CleanupPreview(Impl* impl)) and invoke it in the failure branches that follow
SDL_CreateWindow and SDL_CreateRenderer to ensure no SDL subsystem or resources
are leaked.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
src/plugins/oak/CMakeLists.txtsrc/plugins/oak/README.mdsrc/plugins/oak/core/oak_camera.cppsrc/plugins/oak/core/oak_camera.hppsrc/plugins/oak/core/preview_stream.cppsrc/plugins/oak/core/preview_stream.hppsrc/plugins/oak/main.cpp
| if (SDL_Init(SDL_INIT_VIDEO) != 0) | ||
| { | ||
| std::cerr << "Preview: SDL_Init failed: " << SDL_GetError() << std::endl; | ||
| return nullptr; | ||
| } | ||
|
|
||
| auto impl = std::make_unique<Impl>(); | ||
|
|
||
| impl->window = SDL_CreateWindow( | ||
| name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, preview_w, preview_h, SDL_WINDOW_SHOWN); | ||
|
|
||
| if (!impl->window) | ||
| { | ||
| std::cerr << "Preview: SDL_CreateWindow failed: " << SDL_GetError() << std::endl; | ||
| return nullptr; | ||
| } | ||
|
|
||
| impl->renderer = SDL_CreateRenderer(impl->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); | ||
| if (!impl->renderer) | ||
| impl->renderer = SDL_CreateRenderer(impl->window, -1, 0); | ||
|
|
||
| if (!impl->renderer) | ||
| { | ||
| std::cerr << "Preview: SDL_CreateRenderer failed: " << SDL_GetError() << std::endl; | ||
| return nullptr; | ||
| } |
There was a problem hiding this comment.
SDL resource cleanup on early return paths.
If SDL_CreateWindow or SDL_CreateRenderer fails after SDL_Init succeeds, the function returns nullptr but doesn't call SDL_QuitSubSystem. Since the Impl destructor won't run (the object isn't fully constructed), SDL remains initialized.
Proposed fix - add cleanup helper
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
std::cerr << "Preview: SDL_Init failed: " << SDL_GetError() << std::endl;
return nullptr;
}
auto impl = std::make_unique<Impl>();
+ // Ensure SDL cleanup on early return
+ auto cleanup_on_failure = [&]() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
impl->window = SDL_CreateWindow(
name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, preview_w, preview_h, SDL_WINDOW_SHOWN);
if (!impl->window)
{
std::cerr << "Preview: SDL_CreateWindow failed: " << SDL_GetError() << std::endl;
+ cleanup_on_failure();
return nullptr;
}
impl->renderer = SDL_CreateRenderer(impl->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!impl->renderer)
impl->renderer = SDL_CreateRenderer(impl->window, -1, 0);
if (!impl->renderer)
{
std::cerr << "Preview: SDL_CreateRenderer failed: " << SDL_GetError() << std::endl;
+ SDL_DestroyWindow(impl->window);
+ impl->window = nullptr;
+ cleanup_on_failure();
return nullptr;
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/plugins/oak/core/preview_stream.cpp` around lines 73 - 98, After SDL_Init
succeeds, ensure we clean up SDL state and any partially-created resources on
early returns: when SDL_CreateWindow or SDL_CreateRenderer fails, call
SDL_DestroyRenderer(impl->renderer) if non-null, SDL_DestroyWindow(impl->window)
if non-null, then call SDL_QuitSubSystem(SDL_INIT_VIDEO) (or SDL_Quit() as
appropriate) before returning nullptr; you can encapsulate this in a small
cleanup helper (e.g., CleanupPreview(Impl* impl)) and invoke it in the failure
branches that follow SDL_CreateWindow and SDL_CreateRenderer to ensure no SDL
subsystem or resources are leaked.
Summary by CodeRabbit
New Features
Documentation
Chores