obs-studio icon indicating copy to clipboard operation
obs-studio copied to clipboard

libobs: Change scene items to using relative coordinates

Open derrod opened this issue 2 years ago • 9 comments

Description

[!IMPORTANT] Scenes are saved in a backwards-compatible way, stuff might not work correctly and mess up your collection. Make backups of your scene collections before playing around with this!

This change enables the canvas resolution to be changed while maintaining the relative positioning and sizing of items in a scene collection.

Video demo (outdated):

https://github.com/obsproject/obs-studio/assets/3123295/fe3ad89f-d7f7-4b44-b1b1-514a5ffbf693

Implementation notes:

  • (0.0, 0.0) is the center of the canvas
  • Positions are stored as offsets relative to the center
  • The short side of the canvas has the range [-1.0f, 1.0f] while the long side is [-x, x] where x = 1.0f * aspect ratio
  • Items without bounding boxes retain the canvas resolution used during their original creation to adjust their scaling multiplier to the current resolution
  • libobs API is unchanged and converts automatically between absolute and relative positions
  • Scene collections are backwards compatible, the new values are stored separately from the old ones

Visualisation of current and proposed resizing behaviour: explanation_v3_combined

Future considerations

  • adopt new APIs in UI where it makes sense
    • Perhaps we can allow users to switch between pixels and relative positions in the transform UI?
  • How do we handle a situation where a user loaded a scene collection with the wrong canvas resolution and it needs to be re-migrated?

Motivation and Context

This is similar to how other software behaves, and allows much more flexibility when it comes to adjusting a scene collection for different needs. For example, adjustments when switching switching resolutions become simpler if the aspect ratios changes, and no adjustments at all are required when maintaining aspect ratio.

In contrast to previous attempts (#3983) this does not require any changes to the scene collection or user interaction when changing canvas resolutions. The only concern (see ToDos above) is how to handle migration from existing collections.

How Has This Been Tested?

Fiddled with some scene collections.

Types of changes

  • Tweak (non-breaking change to improve existing functionality)

Checklist:

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

derrod avatar Nov 23 '23 18:11 derrod

~~I assume you plan to add v2 functions that accept the new float values?~~

I need to practice my reading

tt2468 avatar Nov 23 '23 20:11 tt2468

Groups should now also work properly so I consider this ready for review. All the other "todo" items are UI changes and I'd like to keep this PR to libobs itself.

derrod avatar Dec 12 '23 00:12 derrod

  1. Are the positions exposed to the user at all, or is it merely a behind the scenes storage change?
  2. Are there any circumstances where due to rounding or something, that the entered size doesn't round trip correctly? At what canvas size do these errors first occur?

ryantheleach avatar Dec 12 '23 12:12 ryantheleach

  1. Are the positions exposed to the user at all, or is it merely a behind the scenes storage change?
  2. Are there any circumstances where due to rounding or something, that the entered size doesn't round trip correctly? At what canvas size do these errors first occur?
  1. Not in this PR, though APIs are added to access the raw values
  2. Any number that is sub-pixel will be rounded to the nearest 0.5 for non-group items (to allow centering of odd-sized sources while keeping things reasonably aligned), within the limits of OBS canvas size (16k x 16k) there should be no issues

derrod avatar Dec 12 '23 18:12 derrod

Updated this PR with a behavioural change to scale to the shorter side instead of the longer one. This makes the maths less "neat" but is probably more intuitive as long as you are resizing within the aspect ratios > 1 or < 1 (swapping between those is still a bit weird, but that's not really fixable).

explanation_v2_to_v3_combined

derrod avatar Feb 19 '24 08:02 derrod

I'd like to hold off on this PR for the time being while we look into storing an "intended resolution" as part of scene collection data.

Starting with 30.1 we store the last used output resolution in the collection, with the new scene collection management we should be able to do automatic migrations with fairly good certainty, though we may still need options for manual corrections.

derrod avatar Feb 21 '24 08:02 derrod

Updated based on conversations off-thread:

  • Migrations are now handled based on resolution saved in scene collection if an output was used
  • Users can remigrate a collection if the wrong base resolution was used (Scene Collections -> Reset Base Resolution)
  • Users can manually migrate a collection if it hasn't been migrated yet (same menu item)
  • The legacy (absolute) mode can still be used by setting a boolean value on the private OBS settings data before loading scene/group sources

derrod avatar Apr 23 '24 03:04 derrod

Made a few improvements to the migration code, this is how users can fix an incorrectly migrated collection:

https://github.com/obsproject/obs-studio/assets/3123295/432c357b-c16b-49da-823e-b96197cdb0d9

derrod avatar Apr 23 '24 19:04 derrod

Updated strings as suggested.

derrod avatar May 03 '24 00:05 derrod

Hey just wanted to say I used the most recent artifact build to resize a 4k canvas into 1080p and then reboot back into my standard OBS install, it worked like a charm. Tools like this are super useful! (I had base at 4k scaled to 1080p, I wanted to lower canvas to 1080p so gpu was doing less scaling since I am also running twitch enhanced broadcast and am generally streamlining things down. I'd rather use a 2nd app to record 4k feeds)

nathaniasSC2 avatar May 29 '24 15:05 nathaniasSC2

Updated the PR to address comments and squash some commits. I've also elected to make a minor change to always scale to height, rather than the shortest side, to make transitions between horizontal and vertical a bit more intuitive.

This also includes a change perhaps of interest to @exeldro in 1423687feb1fcebe898d610705cc203bd456222e and ca27351a4f0a1c8adc5b1e8a055cbcf4ab10cb54 which should get rid of the need to set a custom scene resolution in their vertical plugin since it'll use the current mix's base resolution when rendering, rather than just the main mix.

derrod avatar Aug 18 '24 00:08 derrod

Did code review and tested it, all looks good to me.

exeldro avatar Aug 21 '24 08:08 exeldro

Did code review and tested it, all looks good to me.

Thanks, have you been able to verify that using a custom resolution is no longer required for vertical canvasses since it now uses the mix's base resolution?

derrod avatar Aug 21 '24 08:08 derrod

With vertical I found some issues.

  • when using obs_display_add_draw_callback to render the vertical canvas there is no way to set current_mix, so it does use the main canvas resolution or the custom scene resolution.
  • obs_view_render does not set current_mix, so it does use the main canvas resolution or the custom scene resolution.
  • In obs_transition_start and obs_transition_tick the current_mix is not set, so the calculated size of the transition is wrong here: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-source-transition.c#L210 https://github.com/obsproject/obs-studio/blob/master/libobs/obs-source-transition.c#L395

exeldro avatar Aug 21 '24 09:08 exeldro

I see, we will have to revisit that as it goes a bit beyond the scope of this PR. I'll drop the first two commits then as they don't have any other function that would be useful right now. Perhaps that warrants an RFC at some point to figure these things out. The transitions example is particularly problematic as there's can be one tick but multiple render calls with differing mixes and resolutions, so we might need to have a fixed link between scenes and mixes or something.

derrod avatar Aug 21 '24 09:08 derrod