Add DVD / Blu-Ray menu and DVD-Audio support#18080
Conversation
072b324 to
499ba28
Compare
d698b40 to
ddfc443
Compare
|
Just to mention it in case it might need some adjustment with all these changes before they finalize, but how easily would potential future DVD-Audio support slot in amongst this? I'm not sure if it employs any visual menuing, since most DVD players would pick up the VIDEO_TS part of the disc instead. libdvd{css,read} can properly handle DVD-Audio now, and VLC has it enabled in the nightlies, but I don't know if it can easily be bolted onto mpv's existing DVD-Video parsing or if it would require much deeper changes (or at worst, just get siloed off into its own component if it's too different and accessed via dvda://whatever). |
2e6b66e to
bde486f
Compare
Any comment on why you resolved this? Shouldn't this be sub bitmaps instead of osd_set_external2 like what DVD menu does? |
In DVD case menu buttons and highlights ride the subtitle stream, because they are encoded in the subtitle stream itself. And to avoid duplicating whole subtitle decoding code or doing whole lavc roundtrip we use the existing subtitle renderer. Porting this to overlay would be possible, but is a lot of code to get workable bitmap. In BD case the menu bitmaps are given by the libbluray VM, either in YUV RLE or RGBA directly, depending on the disc type. Those are directly usable to be shown on the screen, hence they are shown as is. Creating virtual subtitle track, muxing it into PGS (or something) would be again a lot of code and would add unnecessary complexity. |
This is separate work, but since libdvdread seems to support DVD-Audio, it's way easier than DVD-Video, with all the libdvdnav annoyance. I don't have much DVD-A discs, but once this lands, we can think about it, it's not bad. |
Does this have to conflict with image overlays instead of adding a new osd part like |
Done. |
|
Added DVD-Audio support as a bonus. MLP works fine. I have doubts for LPCM, which is apparently also supported and would need some changes in ffmpeg, but I couldn't find sample to work on this, so for now this is postponed until someone complains that it doesn't work. |
I'm pretty sure all of mine are just MLP. I don't know if dvda-author ever added MLP support, but it being limited to only authoring using LPCM was a known. Non-commercial discs might well be the largest instance of LPCM. |
I found the sample file on mplayer samples server https://samples.mplayerhq.hu/DVD-Audio/, good enough for now. |
|
Adds support for ARGB callback from libbluray. For some reason they don't have unified support, and sometimes it uses ARGB (for BD-J) and RLE (for HDMV), while they could convery RLE encoded menus into ARGB bitmaps, if only one is supproted. We have to support both. When Java VM is not available, fallbacks to non-menu playback.
VM events are processed in fill_buffer callback, which are called by the demuxer thread. The should be processed close to what user is seeing on screen, else VM will think that we are at different point and may trigger action before user sees whole cache.
We cache some state like title properties, in some cases during deinit player thread may actually try to read it during demuxer thead read. Just add a lock, it shouldn't be called frequently to cause too much synchronization.
This is mostly used for menus.
This is mostly cleanup after adding menu support, where _ext was added, but I also left old bd_read(), which made things unnecessary complex. Also remove constant event drain and do it only in idle mode.
A stream can report a one-shot EOF and then continue producing data (disc-nav jump boundaries).
Menu activations, HOP_CHANNEL and VTS changes jump the source position. On this strictly forward stream the demuxer cannot tell where the old content ends, so buffered pre-jump data would mix with post-jump data. Return a single EOF at the boundary so the demuxer drains and resets before any new content flows.
A full slave reopen makes libavformat re-probe the stream, which eats packets around the jump (losing the one-shot menu SPU) and re-bases the timestamps. DVD cannot change codecs across a jump, so flushing the slave and refreshing duration/chapters/edition is enough. BD keeps the full reopen because codecs can change across titles.
A menu subpicture is not timed subtitle data: its display command keeps it on screen until it is stopped or replaced, independent of the playback time, which is frozen on stills and rebased across menu jumps.
The menu SPU is a single packet on a stream that cannot be re-read. If the sub stream is not selected when it flows by, or the player flushes it before the decoder consumed it, the menu stays blank forever. Retain the last SPU per substream and re-deliver it when the stream is (re)selected. This arguably is getting bit of hacky mess, but the alternative would be to either not use double demuxer or use separate subtitle decoder. Both those solutions carry a lot of code duplication for demuxing and decoding. So we try to plug things togheter in current design. It still not perfect, but works well enough to keep the highlights from disapearing in some corner cases.
Push menu_active to the dvd_subtitle decoders so the menu subpicture is treated as persistent display state, and always pass the real change_id so highlight removal re-renders too. Re-queue the retained menu SPU after the discontinuity flush, closing the race where the playback reset destroyed the subpicture between demuxer and decoder.
This avoids bogus errors when using demux_disc which is seekable by in higher layer only.
This is awkward, because libbluray have single global log callback. libmpv can possibly spawn multiple players in single application, so this will conflict. The instance created last will override the log callback. This is similar to have ffmpeg logging works. In BD-J case this is bit spammy with some bogus java errors, even with mask DBG_CRIT. Allow logging only if our log level is > DEBUG. Since the log callback gives us only a string, not even log severity, we just print them as MSGL_DEBUG, and set mask according to our log level.
Clean up usages of this duplicated fields.
Add a dvda:// protocol backed by libdvdread. Audio title sets are enumerated from the ATS IFOs. Each ATS title is exposed as an mpv title/edition and its tracks as chapters. Menus are not supports, they would need full VM implementation, and libdvdnav currently doesn't support DVD-Audio. Still images (ASVS) may be supported in the future.
still_image streams (AV_DISPOSITION_STILL_IMAGE) consist of sparse frames that can be minutes apart. When such a stream was selected alongside an eager audio/video stream, its empty packet queue forced the demuxer to keep reading ahead, buffering the whole file trying to chase min_secs of "video". Read them lazily when other eager streams exist, so playback drives read-ahead instead.
|
Thank you! Such a fantastic feature. I've tested this on a few discs I have and while it works on some BDs, I experience issues with the majority of them. DVDs seem to be working much better. The following either crash or freeze when selecting 'Play' via keyboard or mouse navigation of the BD menu:
The following don't open at all (includes the following error in the logs):
For comparison, these disc menus work in VLC and Kodi. |
This is regression from my yesterday's change. Will fix. Generally BD works a lot better in practice, minus the regression. |
No description provided.