Skip to content

Conversation

@dsaedtler
Copy link
Contributor

Description

Stores and restores original video_t object when GPU scaling is enabled.

Motivation and Context

GPU scaling utilises "encoder only" mixes to create a new, scaled version of the original video_t object set for the encoder. When an encoder gets stopped, this mix gets cleared.

However, when the encoder is configured for a non-default video_t, e.g. in multi-canvas scenarios, then maybe_clear_encoder_core_video_mix() would reset media to the main canvas's video object obtained from obs_get_video() rather than the actual video that was set. This would result in incorrect output if the encoder is restarted as part of the reconnection process.

To avoid this, this change simply stores the pointer to the original video_t that was set when the encoder was configured, and restores it when an encoder-only mix gets deleted.

How Has This Been Tested?

Locally by yanking the ethernet cable to simulate a connection drop and trigger a reconnect.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code has been run through clang-format.
  • I have read the contributing document.
  • My code is not on the master branch.
  • The code has been tested.
  • All commit messages are properly formatted and commits squashed where appropriate.
  • I have included updates to all appropriate documentation.

@RytoEX RytoEX requested a review from PatTheMav January 7, 2026 22:53
@RytoEX RytoEX added the Bug Fix Non-breaking change which fixes an issue label Jan 7, 2026
@PatTheMav
Copy link
Member

Because I haven't spend a lot of time around encoder or output code, do I understand the issue right that:

  • In multi-canvas scenarios each encoder would have its own associated video_t object rather than the single video_t object associated with the main canvas
  • When GPU scaling is thrown into the mix, that object is actually replaced (logically "wrapped") by another video_t object that represents the output of the scaler
  • This process is handled internally by the encoder
  • When the encoder tears down this temporary "wrapper" object, it needs to restore its internal state to the actual video_t object that was wrapped
  • Current code is not aware of canvases (at least to the degree that the encoder might be associated with a specific canvas) and instead resets to the main canvas' video_t object by default

So the fix is obviously to ensure that the video_t object of the associated canvas is used during restoration and this PR adds a new state variable that retains this (without introducing the requirement for the encoder to be aware of canvases at all)?

@dsaedtler
Copy link
Contributor Author

Because I haven't spend a lot of time around encoder or output code, do I understand the issue right that:

  • In multi-canvas scenarios each encoder would have its own associated video_t object rather than the single video_t object associated with the main canvas
  • When GPU scaling is thrown into the mix, that object is actually replaced (logically "wrapped") by another video_t object that represents the output of the scaler
  • This process is handled internally by the encoder
  • When the encoder tears down this temporary "wrapper" object, it needs to restore its internal state to the actual video_t object that was wrapped
  • Current code is not aware of canvases (at least to the degree that the encoder might be associated with a specific canvas) and instead resets to the main canvas' video_t object by default

So the fix is obviously to ensure that the video_t object of the associated canvas is used during restoration and this PR adds a new state variable that retains this (without introducing the requirement for the encoder to be aware of canvases at all)?

Correct, yeah.

@RytoEX RytoEX added this to the OBS Studio 32.1 milestone Jan 9, 2026
@RytoEX RytoEX merged commit 4d7776f into obsproject:master Jan 9, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Fix Non-breaking change which fixes an issue

Projects

Status: Ready For Merge

Development

Successfully merging this pull request may close these issues.

3 participants