Skip to content

Add options for bounding and scaling the rendering canvas #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 18, 2022

Conversation

TheOneric
Copy link
Member

Cleaned and simplified (keeping the same results for positive saling values) version of #119 backporting a jellyfin feature.
( @dmitrylyzo )

In particular I'd like to get some feedback on the name for the option added in the second commit: While I find hardHeightLimit to be an ok name, I was also considering canvasHeightLimit, maxCanvasHeight and maxRenderingHeight but I'm not sure if eg the canvas-names might cause confusion with the HTML-<canvas> element.

Another previously discussed topic was if I'd be better to bundle the prescale options into one object internally or also externally. I have no particular preference with regards to that.

@TFSThiagoBR98
Copy link
Collaborator

In particular I'd like to get some feedback on the name for the option added in the second commit: While I find hardHeightLimit to be an ok name, I was also considering canvasHeightLimit, maxCanvasHeight and maxRenderingHeight but I'm not sure if eg the canvas-names might cause confusion with the HTML-<canvas> element.

To me maxCanvasHeight or maxRenderingHeight looks good, I don't see any problems using canvas names as it uses canvas element for rendering, so I'll leave it up to you to decide the final name.

@TheOneric
Copy link
Member Author

I don't see any problems using canvas names as it uses canvas element for rendering

I was thinking of possible confusion with the CSS height property of the HTML <canvas> being rendered on. Not sure how likely/problematic this is though.
For now I renmaed the property to maxRenderHeight.

Copy link
Collaborator

@TFSThiagoBR98 TFSThiagoBR98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@TheOneric
Copy link
Member Author

@dmitrylyzo: I don't think I changed any functionality jellyfin relies on during cleanup, but just to make sure could you take a look?

Copy link
Contributor

@dmitrylyzo dmitrylyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably the only thing left is a true noop (skipping multiplications) when scaleFactor is 1.0. But since this function is rarely used, noop doesn't make much sense.

Should we round the result (to pixels)?

JustAMan and others added 2 commits February 16, 2022 20:46
JSO struggles on complex subtitles and higher resolutions,
scaling the sub-canvas down if the canvas gets larger than a size deemed
good enough can be used to somewhat work around this at the expense of
introducing some blurriness. Scaling up is also possible but probably
less useful.

This was ported from jellyfin's fork and jellyfin-web uses this on at
least some devices. However the option names were changed to better
match their actual function.

[Vasily <just.one.man@yandex.ru>]
  Original implementation together with a hard canvas height limit in
  jellyfin@345d701
  jellyfin@bcf4b5f
[Dmitry Lyzo <ashephard0@gmail.com>]
  Rebased for upstream; removed default hardHeightLimit and added docs
[Oneric <oneric@oneric.stub>]
  Simplified scaling logic (identical results for positive values);
  fixed zero and negativity bugs in scaling logic;
  changed option names for clarity;
  split prescaling from hard height limit.

Co-Authored-By: Dmitry Lyzo <ashephard0@gmail.com>
Co-Authored-By: Oneric <oneric@oneric.stub>
JSO struggles with complex subtitles on HiDPI canvasses,
so limiting the size can make sense if such subtitles are expected.

This was ported from jellyfin's fork and jellyfin-web uses this on at
least some devices. In the original implementation prescaleHeightLimit
would override maxRenderHeight if it was larger. This undocumentend
behaviour was dropped here as it seemed unintuitive and unhelpful.

[Vasily <just.one.man@yandex.ru>]
  Original implementation together with prescaling in
  jellyfin@345d701
  jellyfin@4c5f018
[Dmitry Lyzo]
  Rebased for upstream; seperated from the prescaling;
  removed default height limit and added docs
[Oneric]
  Renamed hardHeightLimit to maxRenderHeight;
  split from prescaling.

Co-Authored-By: Dmitry Lyzo <ashephard0@gmail.com>
@TheOneric
Copy link
Member Author

the only thing left is a true noop (skipping multiplications) when scaleFactor is 1.0.

1.0 already is a “true” noop. Afaict for all IEEE-754 compliant floating point implementations, if a represents a real number, then a * 1.0 === a and if a is additionally non-zero a / a === 1.0.
Meaning if scalefactor === 1.0 the passed width and height values will be returned unchanged — a noop.

@dmitrylyzo
Copy link
Contributor

1.0 already is a “true” noop. Afaict for all IEEE-754 compliant floating point implementations, if a represents a real number, then a * 1.0 === a and if a is additionally non-zero a / a === 1.0. Meaning if scalefactor === 1.0 the passed width and height values will be returned unchanged — a noop.

I meant that all this math will be applied even with scalefactor === 1.0, but could be omitted ("true noop").
But...

since this function is rarely used, noop doesn't make much sense.

@TheOneric
Copy link
Member Author

Yeah, _computeCanvas is already lightweight and only runs on resizes and init, so there's no real performance benefit to adding another branch to skip the remaining code.

@ThaUnknown
Copy link

@dmitrylyzo @TheOneric are there any more JS PR's to merge which aren't already made? If not I could start work on v2 and have it finished by the end of the week.

@TheOneric
Copy link
Member Author

are there any more JS PR's to merge which aren't already made?

yes.

@ThaUnknown
Copy link

are there any more JS PR's to merge which aren't already made?

yes.

sorry, i meant from the original pr Dimitry made, any chance you could abridge me what those are?

@TheOneric
Copy link
Member Author

from the original pr Dimitry made [i.e. pr#111], any chance you could abridge me what those are?

Excluding this PR there is:

Merged:

  • fix handling of empty ASS_Images

Created but not final or not reviewed::

  • conditionally redirect C++ output for nicer display in the browser console
  • Refactor buffer struct into C++-class
    • additionally: fixing newly found overflow bugs

Uncreated:

  • drop animations feature
  • renderAhead
    • additionally: improvements to renderAhead to never be worse than wasm-blend (the state in PR#111 is worse when falling behind schedule)

@ThaUnknown
Copy link

ThaUnknown commented Feb 17, 2022

  • additionally: improvements to renderAhead to never be worse than wasm-blend (the state in PR#111 is worse when falling behind schedule)

Here's what I think:

  • drop animations feature: this is really good for a lot of low-end devices and has good applications, so we should do it
  • renderAhead: imho this idea is fundamentally flawed, it should render ahead/buffer measured in time, rather than memory, I plan on creating something like this, additionally some of its components like 'renderOnDemand' arent exactly what they describe, and I plan on creating a renderOnDemand mode

Additionally, ideas which aren't posted here:

  • font improvements: JS & C++: I didn't understand their point in all honesty, but I didn't have to work with massive font files, so there might be valid reason for them
  • onDemandRender: JS: render subtitles as the video player is presenting video frames using requestVideoFrameCallback, chromium only [currently working on this], this allows us to omit all video events, pausing states, etc. additionally its async so if the video decoder drops frames, it wont ask to render subtitles
  • offscreenRender: JS: handling rendering 100% in the worker, chromium only, firefox support soon:tm:
  • C++ decode: the entire code for decoding bitmaps NEEDS to be in C++ rather than JS, blendrender already creates the bitmaps in C++, but it additionally blends them, I'd like an options for C++ to create multiple bitmaps without blending them, rather than creating 1 blended bitmap TLDR moving this code to C++
  • render modifiers [offscreen, async, ondemand], currently you cant use both blendrender and lossy render at once, even tho you could, i plan on adding "render modifiers" options, which will allow you to mix and match, the 2 base """render modes'"" would then be JS blend and WASM blend

requestVideoFrameCallback can potentially allow us to do frame-perfect painting of subtitles if renderahead is done with time, rather than memory.

@TheOneric
Copy link
Member Author

TheOneric commented Feb 17, 2022

@ThaUnknown: this PR is about prescaling and bounding the canvas and not the right place for extended discussion of general ideas/feature requests for the future.

@TheOneric TheOneric merged commit 5ebf13d into libass:master Feb 18, 2022
@TheOneric TheOneric deleted the canvas-bounds branch February 18, 2022 17:38
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.

5 participants