Skip to content

Terminate VAAPI display after capability detection - #1497

Closed
alan-george-lk wants to merge 6 commits into
alan/bugfix-cuda-device-infofrom
alan/bugfix-vaterminate
Closed

alan-george-lk wants to merge 6 commits into
alan/bugfix-cuda-device-infofrom
alan/bugfix-vaterminate

Conversation

@alan-george-lk

@alan-george-lk alan-george-lk commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Stacked directly on #1473. This is the head of the room-deletion lifecycle fix stack.

Summary

  • Call vaTerminate after VAAPI H.264 capability detection succeeds.
  • Also terminate the initialized display on capability-query failure paths.
  • Prevent repeated room creation from retaining VA driver resources and threads.

Validation

  • Release C++ SDK/test build succeeds with LLVM 21.
  • 100 remote-room deletion cycles with three NVENC tracks and MALLOC_ARENA_MAX=1: idle threads remained at 29; RSS was flat from cycles 80-100.

@alan-george-lk
alan-george-lk requested a review from ladvoc as a code owner October 5, 2026 19:23

@devin-ai-integration devin-ai-integration Bot 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.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

}

delete[] entrypoints;
vaTerminate(va_display);

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.

🔴 Encoder receives a terminated VAAPI display

On successful capability detection, vaTerminate invalidates the display that va_open_display_drm returns. init_va then initializes that freed display, so VAAPI encoding can crash or fail.

Learn more

A DRM display is opened by vaGetDisplayDRM and passed through capability detection before VaapiDisplayDrm::Open exposes it to callers. Terminating it here tears down the driver and frees the display context, but va_open_display_drm still returns the same pointer on success. Initialize subsequently passes that pointer to init_va, which calls vaInitialize again; Destroy also uses and terminates it. Those calls operate on an invalid display rather than a fresh one.

Example: With an available H.264 VAAPI render device, factory detection succeeds and terminates display A. Creating and initializing a VAAPI encoder returns display A again and calls vaInitialize(A); the encoder needs a valid, live display instead.

Recommended fix: Keep capability detection's temporary display separate from the encoder's live display. Do not return a terminated handle from va_open_display_drm; arrange for encoder Open() to return a live display and balance each successful initialization with exactly one termination. Add a repeated factory-detection and encode teardown test.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@alan-george-lk

Copy link
Copy Markdown
Contributor Author

Stack-head lifecycle validation completed on Linux/x64 with an RTX 5090.

  • C++ release-tests build used Rust commit 575274a6.
  • 100 server-controlled cycles; each cycle published three 1280x720 H.264 tracks through NVIDIA H264 Encoder, then deleted the room remotely.
  • MALLOC_ARENA_MAX=1, one second of frames per cycle, no settle delay.
  • All 100 RoomDeleted + room-EOS confirmations succeeded; 300/300 track stats confirmed NVENC.
  • Idle threads stayed exactly 32 from cycle 1 through cycle 100.
  • Idle RSS: 226.062 MiB at cycle 1, 230.188 MiB at cycle 20, 233.738 MiB at cycle 100.
  • Cycles 50-100 added 0.062 MiB total; cycles 80-100 were flat.

@alan-george-lk
alan-george-lk added this pull request to stack #1498 October 5, 2026 19:28
@alan-george-lk
alan-george-lk force-pushed the alan/bugfix-cuda-device-info branch from 0a4acda to 6b1b88b Compare October 5, 2026 19:56
@alan-george-lk
alan-george-lk force-pushed the alan/bugfix-vaterminate branch from 575274a to 0166c9d Compare October 5, 2026 19:56
alan-george-lk and others added 2 commits October 5, 2026 12:56
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@alan-george-lk

Copy link
Copy Markdown
Contributor Author

Closing to recreate this branch directly on #1473 after removing the NVIDIA PR from the room-lifecycle stack.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Changeset ✓

This PR includes a changeset covering all affected packages:

Package Bump
libwebrtc patch
livekit patch
livekit-capture patch
livekit-ffi patch
webrtc-sys patch

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

self.inner.rtc_engine.publisher_negotiation_needed();
}

remove_result?;

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.

🟡 Unpublish error contradicts track removal event

When remove_track fails, unpublish_track emits LocalTrackUnpublished but returns an error. The FFI unpublish callback reports failure while the event reports success.

Learn more

unpublish_track removes the publication before calling the RTC engine. If sender removal fails, it now detaches the track and dispatches LocalTrackUnpublished before returning that error. The FFI unpublish handler waits for this event only on a successful return; an error callback can therefore follow or precede an event that says the track was unpublished. The failure is expected when the peer connection has already closed.

Example: An FFI client requests unpublish just after the server deletes its room. Sender removal fails because the connection is closed, but the SDK emits LocalTrackUnpublished and the request callback returns an error.

Recommended fix: Make the return value and event describe the same outcome. If detaching after a closed connection counts as successful unpublish, return the publication and let the FFI handler preserve event-before-callback ordering. Preserve errors for cases where the sender remains active, and distinguish those cases from an already closed connection.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@alan-george-lk
alan-george-lk removed this pull request from stack #1498 October 5, 2026 20:05
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.

1 participant