marcan / blitzloop

Open source karaoke software
GNU General Public License v2.0
207 stars 31 forks source link

FR: add libass backend #55

Open jose1711 opened 4 years ago

jose1711 commented 4 years ago

This is just an idea. It still can help with issues like #52.

What if next to glut, gles, rpi and other backends there is another called called ass which would work like this:


 - `mpv` is being passed the result as a subtitle file so it will be responsible for displaying it (there won't be an overlay layer)

Of course this won't be on par with other engines but this could greatly benefit boxes with not enough horse power (RPi still needs a `mmal`-enabled `mpv` though, though even more stripped down `.srt` together with `omxplayer` would solve this).
marcan commented 4 years ago

Will it, though?

The point of BlitzLoop's renderer is that it pretty much precomputes the entire lyrics as GPU buffer objects, then each frame is literally one GPU draw call per lyrics line. That's it. Everything else happens on the GPU or ahead of time.

Meanwhile libass is a CPU-based renderer, possibly with GPU-assisted composition? In any case I don't think it precomputes everything like BlitzLoop does.

If libass is actually faster than BlitzLoop then we should figure out why that is.

marcan commented 4 years ago

FWIW, here's an (ugly) script to convert to .ass as you describe:

https://github.com/marcan/blitzloop-tools/blob/master/export_ass.py

That one does \k so it's cheating, but you can easily make it spit out \kf. Then if that is really faster than BlitzLoop I'd be really interested in why.

jose1711 commented 4 years ago

Ok, maybe I should amend that performance improvement assumption. Still .. at least the EGL requirement for RPi would be a history. How difficult would it be to integrate export_ass.py into a new backend?

marcan commented 4 years ago

The main issue is blitzloop's implicit assumption that it has a screen to draw on. You need at least some sort of frame loop for things to run on, and then there's the whole idle screen and other issues. Plus line layout assumes there is a screen and font renderer.

Effectively, you'd need to yank out a bunch of BlitzLoop at a high level, in main.py (and play.py), or perhaps stub out the whole renderer and add a special case to SongLayout to do nothing if it's called with a dummy renderer. Possible, but definitely not as clean or simple as adding a backend at this point.

Implementing a fake screen for layout is something I want to do anyway, for the Joysound exporter (right now it needs GL, though it can use surfaceless EGL like the video generator mode), and ideally we'd use that with ASS too and a bunch of styling so that ASS mode at least tries to approximate what real BlitzLoop looks like. But then there's a bit of a tricky issue with separating the font code from the texture handling code.

So, basically: I don't think it's worth implementing "dumb" ASS mode a la export_ass with the current codebase, it's ugly. I think there's room for refactoring everything to cleanly separate layout/metrics code from rendering/GL/textures/display, and then have an ASS backend at that level.