summaryrefslogtreecommitdiffstats
path: root/sub
Commit message (Collapse)AuthorAgeFilesLines
* stats: some more performance graphswm42020-04-092-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add an infrastructure for collecting performance-related data, use it in some places. Add rendering of them to stats.lua. There were two main goals: minimal impact on the normal code and normal playback. So all these stats_* function calls either happen only during initialization, or return immediately if no stats collection is going on. That's why it does this lazily adding of stats entries etc. (a first iteration made each stats entry an API thing, instead of just a single stats_ctx, but I thought that was getting too intrusive in the "normal" code, even if everything gets worse inside of stats.c). You could get most of this information from various profilers (including the extremely primitive --dump-stats thing in mpv), but this makes it easier to see the most important information at once (at least in theory), partially because we know best about the context of various things. Not very happy with this. It's all pretty primitive and dumb. At this point I just wanted to get over with it, without necessarily having to revisit it later, but with having my stupid statistics. Somehow the code feels terrible. There are a lot of meh decisions in there that could be better or worse (but mostly could be better), and it just sucks but it's also trivial and uninteresting and does the job. I guess I hate programming. It's so tedious and the result is always shit. Anyway, enjoy.
* build: make libass non-optionalwm42020-03-182-41/+0
| | | | | | | | | | | | | | Using mpv without libass isn't really supported, since it's not only used to display ASS subtitles, but all text subtitles, and even OSD. At least 1 user complained that the player printed a warning if built without libass. Avoid trying to create the impression that using this software without libass is in any way supported or desirable, and make it fully mandatory. (As far as making dependencies optional goes, I'd rather make ffmpeg optional, which is an oversized and bloated library, rather than something tiny like libass.)
* options: change option macros and all option declarationswm42020-03-181-22/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change all OPT_* macros such that they don't define the entire m_option initializer, and instead expand only to a part of it, which sets certain fields. This requires changing almost every option declaration, because they all use these macros. A declaration now always starts with {"name", ... followed by designated initializers only (possibly wrapped in macros). The OPT_* macros now initialize the .offset and .type fields only, sometimes also .priv and others. I think this change makes the option macros less tricky. The old code had to stuff everything into macro arguments (and attempted to allow setting arbitrary fields by letting the user pass designated initializers in the vararg parts). Some of this was made messy due to C99 and C11 not allowing 0-sized varargs with ',' removal. It's also possible that this change is pointless, other than cosmetic preferences. Not too happy about some things. For example, the OPT_CHOICE() indentation I applied looks a bit ugly. Much of this change was done with regex search&replace, but some places required manual editing. In particular, code in "obscure" areas (which I didn't include in compilation) might be broken now. In wayland_common.c the author of some option declarations confused the flags parameter with the default value (though the default value was also properly set below). I fixed this with this change.
* sub: log libass versionwm42020-03-081-0/+2
| | | | | Sometimes helpful. Would be even nicer if libass logged it themselves, including git hash, I guess.
* command: extend osd-overlay command with bounds reportingwm42020-03-065-7/+82
| | | | | | | | | | | | | | | | | | | | This is more or less a minimal hack to make _some_ text measurement functionality available to scripts. Since libass does not support such a thing, this simply uses the bounding box of the rendered text. This is far from ideal. Problems include: - using a bitmap bounding box - additional memory waste and/or flushing caches - dependency on window size - odd small deviations with different window sizes (run osd-test.lua and resize the window after each timer update; the bounding boxes aren't adjusted in an overly useful way) - inability to query the size _after_ actual rendering But I guess it's a start. Since I'm aware that it's crap, add a threat to the manpage that this may be changed/removed again. For now, I'm interested whether anyone will have use for it in its current form, as it's an often requested feature.
* sub: do not ignore demuxer wakeupswm42020-02-271-6/+7
| | | | | | | | | | | | | | | | | | Setting demux_set_stream_wakeup_cb() will make all sh_stream (i.e. track) specific wakeups go to this callback. But the callback takes care of only the sub_preload() case (where it tries to pre-load subtitles from already parsed and memory-present subtitles in a blocking way). The old code assumed that the normal demuxer wakeup callback is called. This was disregarded when the newer code was added. (And actually, the original plan was to make _all_ per-sh_stream wakeups go to specialized callbacks to avoid wasted work. dec_sub really should set the callback always, and propagate wakeups to the playloop code. But it's too far into the night to write coherent code.) I couldn't actually observe any manifestation of this bug. Normally, the playloop wakes up for other reasons (such as driving audio and video decoding), so the lost wakeups rarely matter.
* sub: fix typo in commentwm42020-02-271-1/+1
| | | | | Reading this commit and this commit message is a waste of time. I guarantee it.
* sub, demux: improve behavior with negative subtitle delay/muxed subswm42020-02-271-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | A negative subtitle delay means that subtitles from the future should be shown earlier. With muxed subtitles, subtitle packets are demuxed along with audio and video packets. But since they are demuxed "lazily", nothing guarantees that subtitle packets from the future are available in time. Typically, the user-observed effect is that subtitles do not appear at all (or too late) with large negative --sub-delay values, but that using --cache might fix this. Make this behave better. Automatically extend read-ahead to as much as needed by the subtitles. It seems it's the easiest to pass the subtitle render timestamp to the demuxer in order to guarantee that everything is read. This timestamp based approach might be fragile, so disable it if no negative sub-delay is used. As far as the player frontend part is concerned, this makes use of the code path for external subtitles, which are not lazily demuxed, and may already trigger waiting. Fixes: #7484
* Remove remains of Libav compatibilitywm42020-02-162-19/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Libav seems rather dead: no release for 2 years, no new git commits in master for almost a year (with one exception ~6 months ago). From what I can tell, some developers resigned themselves to the horrifying idea to post patches to ffmpeg-devel instead, while the rest of the developers went on to greener pastures. Libav was a better project than FFmpeg. Unfortunately, FFmpeg won, because it managed to keep the name and website. Libav was pushed more and more into obscurity: while there was initially a big push for Libav, FFmpeg just remained "in place" and visible for most people. FFmpeg was slowly draining all manpower and energy from Libav. A big part of this was that FFmpeg stole code from Libav (regular merges of the entire Libav git tree), making it some sort of Frankenstein mirror of Libav, think decaying zombie with additional legs ("features") nailed to it. "Stealing" surely is the wrong word; I'm just aping the language that some of the FFmpeg members used to use. All that is in the past now, I'm probably the only person left who is annoyed by this, and with this commit I'm putting this decade long problem finally to an end. I just thought I'd express my annoyance about this fucking shitshow one last time. The most intrusive change in this commit is the resample filter, which originally used libavresample. Since the FFmpeg developer refused to enable libavresample by default for drama reasons, and the API was slightly different, so the filter used some big preprocessor mess to make it compatible to libswresample. All that falls away now. The simplification to the build system is also significant.
* sub: add an option to filter subtitles by regexwm42020-02-163-0/+109
| | | | | | | | | | | | | | | | | | | | Works as ad-filter. I had some more plans, for example replacing matching text with different text, but for now it's dropping matches only. There's a big warning in the manpage that I might change semantics. For example, I might turn it into a primitive sed. In a sane world, you'd probably write a simple script that processes downloaded subtitles before giving them to mpv, and avoid all this complexity. But we don't live in a sane world, and the sooner you learn this, the happier you will be. (But I also want to run this on muxed subtitles.) This is pretty straightforward. We use POSIX regexes, which are readily available without additional pain or dependencies. This also means it's (apparently) not available on win32 (MinGW). The regex list is because I hate big monolithic regexes, and this makes it slightly better. Very superficially tested.
* sub: make filter_sdh a "proper" filter, allow runtime changeswm42020-02-165-43/+190
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, filter_sdh was simply a function that was called by sd_ass directly (if enabled). I want to add another filter, so it's time to turn this into a somewhat more general subtitle filtering infrastructure. I pondered whether to reuse the audio/video filtering stuff - but better not. Also, since subtitles are horrible and tend to refuse proper abstraction, it's still messed into sd_ass, instead of working on the dec_sub.c level. Actually mpv used to have subtitle "filters" and even made subtitle converters part of it, but it was fairly horrible, so don't do that again. In addition, make runtime changes possible. Since this was supposed to be a quick hack, I just decided to put all subtitle filter options into a separate option group (=> simpler change notification), to manually push the change through the playloop (like it was sort of before for OSD options), and to recreate the sub filter chain completely in every change. Should be good enough. One strangeness is that due to prefetching and such, most subtitle packets (or those some time ahead) are actually done filtering when we change, so the user still needs to manually seek to actually refresh everything. And since subtitle data is usually cached in ASS_Track (for other terrible but user-friendly reasons), we also must clear the subtitle data, but of course only on seek, since otherwise all subtitles would just disappear. What a fucking mess, but such is life. We could trigger a "refresh seek" to make this more automatic, but I don't feel like it currently. This is slightly inefficient (lots of allocations and copying), but I decided that it doesn't matter. Could matter slightly for crazy ASS subtitles that render with thousands of events. Not very well tested. Still seems to work, but I didn't have many test cases.
* f_decoder_wrapper, sd_add: accept "null" codecwm42020-02-151-1/+5
| | | | | | | | | | | | | This is for easier use with the "delay_open" feature added in the previous commit. The "null" codec is reported if the codec is unknown (because the stream was not opened yet at time the tracks were added). The rest of the timeline mechanism will set the correct codec at runtime. But this means every time a delay-loaded track is selected, it wants to initialize a decoder for the "null" codec. Accept a "null" decoder. But since FFmpeg has no such codec, and out of my own laziness, just let it fall back to "common" codecs that need no other initialization data.
* sub: enhance SDH filteringDan Oscarsson2020-02-091-0/+8
| | | | | It is not uncommon with a speaker label with [xxxx] inside. They should also be filtered out.
* sub: fix SDH filtering after changeDan Oscarsson2020-02-081-1/+1
| | | | | | | | The change, in an earlier commit, in format for ass to handle results in a different number of fields to skip. Correct that so SDH filtering works. Should fix issue #7188
* osd: fix possible misses of osd-dimensions property updateswm42020-01-081-2/+2
| | | | | | | | | | | | | check_obj_resize() in sub/osd.c calls mp_client_broadcast_event(), which calls notify_property_events(). This is pretty unexpected, because check_obj_resize() may be called from the VO thread. While that's sort of awful, it seems to be OK locking-wise. But it breaks an assumption in notify_property_events() that the core doesn't need to be woken up, which could possibly lead to a missed/delayed property update (although rather unlikely). Fix this by explicitly waking up the core when it's called from the OSD code.
* client API, lua: add new API for setting OSD overlayswm42019-12-234-39/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | Lua scripting has an undocumented mp.set_osd_ass() function, which is used by osc.lua and console.lua. Apparently, 3rd party scripts also use this. It's probably time to make this a public API. The Lua implementation just bypassed the libmpv API. To make it usable by any type of client, turn it into a command, "osd-overlay". There's already a "overlay-add". Ignore it (although the manpage admits guiltiness). I don't really want to deal with that old command. Its main problem is that it uses global IDs, while I'd like to avoid that scripts mess with each others overlays (whether that is accidentally or intentionally). Maybe "overlay-add" can eventually be merged into "osd-overlay", but I'm too lazy to do that now. Scripting now uses the commands. There is a helper to manage OSD overlays. The helper is very "thin"; I only want to force script authors to use the ID allocation, which may help with putting multiple scripts into a single .lua file without causing conflicts (basically, avoiding singletons within a script's environment). The old set_osd_ass() is emulated with the new API. The JS scripting wrapper also provides a set_osd_ass() function, which calls internal mpv API. Comment that part (to keep it compiling), but I'm leaving it to @avih to finish the change.
* osc: use custom symbols for window controlsPhilip Langdale2019-12-111-0/+0
| | | | | | | | | | | | | | | | | | | | | | | | I was recently informed that unicode has official symbols for window controls, and I put together a change to use them, which worked, as long as a suitable font was installed. However, it's not that hard to get a normal system that lacks an appropriate font, and libass wants to print warnings if the symbols aren't in the default font, which will almost always be true. So, I gave up and added the symbols to the custom osd font that we already have. This ensures they are always available, and that they are aligned consistently on all platforms. I took the symbols from the `symbola` font, as this has a suitable licence and the symbols look nice enough. Symbola Licence: Fonts are free for any use; they may be opened, edited, modified, regenerated, packaged and redistributed. Finally, as we now have access to an un-maximize symbol, I added logic to use it when the window is maximized.
* sd_lavc: add a hack ontop of another hack to fix completely fucked filewm42019-12-031-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Do what we do best in multimedia: add conflicting hacks on top of other hacks, that fix a single sample, and may break other ones. In this case, it only happens if the file is most likely already broken (subtitle bounding boxes go outside of the subtitle "canvas"), so it's OK. The file still looks broken (and, in fact, the file is completely fucking broken), but you can see the subtitles. But in summary, this is not actually something I should have bothered about. I noticed that MPlayer shows the subtitles "correctly", but this is only because they have a hack that extends subtitles with small resolution to a larger hardcoded resolution. This hack was removed from mpv, because it broke some completely legitimate files. As another really funny fact, MPlayer's default video output (vdpau) appears to display this file correctly, but only because it handles narrow aspect ratios (that extend the height instead of the width) incorrectly. It extends the height, but leaves the video with 1:1 aspect ratio at the top. It seems to repeat the last video line. (-vo xv and -vo gl show it correctly, i.e. stretched like mpv, by the way.) For some reason, the sample file at hand is extended with black, so the subtitles are rendered into a black area below the video, which is almost reasonable. So, MPlayer may display this file "correctly", but in fact it only happens to do so because of 1 hack that breaks legitimate files, and 1 bug. What the fuck. Fixes: #7218 (sort of)
* ass_mp: reset packer when allocation failsDan Elkouby2019-11-021-1/+3
| | | | | | | | | Sometimes the atlas can get so large that it exceeds the maximum allowed size for an mp_image. Since the atlas will never shrink naturally, this breaks subtitles entirely until mpv is restarted. Reset the packer so that subtitles can rendered properly once the atlas fits again. This is a partial workaround for #6286.
* Replace uses of FFMIN/MAX with MPMIN/MAXwm42019-10-314-20/+16
| | | | And remove libavutil includes where possible.
* sub: make font provider user-selectablewm42019-09-253-1/+10
| | | | | | | | | | | | | | | | | | | | libass had an API to configure this since 2013. mpv always used ASS_FONTPROVIDER_AUTODETECT, because usually there's little reason to use anything else. The intention of the now added option is to allow users to disable use of system fonts. I didn't consider it worth the trouble to add the coretext and directwrite enum items from ASS_DefaultFontProvider. The "auto" choice will have the same effect if they're available. Also, the part of the code which defines the option does not necessarily have libass available (it's still optional!), so defining all enum items as choices is icky. I still added fontconfig, since that may be nice to emulate a nostalgic 2010 feeling of mpv freezing on fontconfig. The option for OSD is even less useful. (But you get it for free, and why pass up a chance to add yet another useless option?) This is not quite what was requested in #6947, but as close as it gets.
* draw_bmp: Fix for GBRP formats GBRP9 and upAnton Kindestam2019-09-221-5/+10
| | | | | | | | | | | | | | | | | | | First we shift the values up to the actual amount of bits in draw_ass, so that they will be drawn correctly when using formats with more than 8 bpc. (draw_rgba is already correct w.r.t. RGB formats with 9 or more bpc) Then, in scale_sb_rgba, by setting the amount of bits per channel used for planar RGB formats (formats are always planar at this point in draw_bmp) to be the same as the source from 9 to 16 bpc (in effect all the various GBRP formats) we manage to fit the special case that does not require any conversion in chroma_up and chroma_down when handling these formats (as long as the source itself is a planar format), instead writing directly to the combined dst/src buffer. This in turn works around a bug (incorrect colors) in libswscale when scaling between GBRP formats with 9 or more bpc. Additionally this should be more efficient, since we skip up- and down-conversion and temporary buffers.
* command: add sub-start & sub-end propertiesStefano Pigozzi2019-09-225-7/+88
| | | | | These properties contain the current subtitle's start and end times. Can be useful to cut sample audio through the scripting interface.
* sub/lavc_conv: skip ReadOrder reset when subtitle decoder gets flushedJan Ekström2019-09-211-0/+1
| | | | | | | | | | | During initial testing with US closed captions, ARIB captions, timed text in MP4 or the specific external SRT files I tested with there were no hints that this flag would be needed for seeking to work. Unfortunately, that result seems to have been incorrect. Fixes #6970
* dec_sub: remove unused declarationwm42019-09-211-1/+0
|
* osd: allow sub-text to work even if sub-visibility is disableddudemanguy2019-09-211-1/+1
|
* sd_lavc: support scaling for bitmap subtitleswm42019-09-191-0/+16
|
* sd_lavc: implement --sub-pos for bitmap subtitleswm42019-09-191-0/+17
| | | | | | | | | | | | | Simple enough to do. May have mixed results. Typically, bitmap subtitles will have a tight bounding box around the rendered text. But if for example there is text on the top and bottom, it may be a single big bitmap with a large transparent area between top and bottom. In particular, DVD subtitles are really just a single screen-sized RLE-encoded bitmap, though libavcodec will crop off transparent areas. Like with sd_ass, you can't move subtitles _down_ if they are already in their origin position. This could probably be improved, but I don't want to deal with that right now.
* Implement backwards playbackwm42019-09-192-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This is a huge hack. You can bet there are shit tons of bugs. It's literally forcing square pegs into round holes. Hopefully, the manpage wall of text makes it clear enough that the whole shit can easily crash and burn. (Although it shouldn't literally crash. That would be a bug. It possibly _could_ start a fire by entering some sort of endless loop, not a literal one, just something where it tries to do work without making progress.) (Some obvious bugs I simply ignored for this initial version, but there's a number of potential bugs I can't even imagine. Normal playback should remain completely unaffected, though.) How this works is also described in the manpage. Basically, we demux in reverse, then we decode in reverse, then we render in reverse. The decoding part is the simplest: just reorder the decoder output. This weirdly integrates with the timeline/ordered chapter code, which also has special requirements on feeding the packets to the decoder in a non-straightforward way (it doesn't conflict, although a bugmessmass breaks correct slicing of segments, so EDL/ordered chapter playback is broken in backward direction). Backward demuxing is pretty involved. In theory, it could be much easier: simply iterating the usual demuxer output backward. But this just doesn't fit into our code, so there's a cthulhu nightmare of shit. To be specific, each stream (audio, video) is reversed separately. At least this means we can do backward playback within cached content (for example, you could play backwards in a live stream; on that note, it disables prefetching, which would lead to losing new live video, but this could be avoided). The fuckmess also meant that I didn't bother trying to support subtitles. Subtitles are a problem because they're "sparse" streams. They need to be "passively" demuxed: you don't try to read a subtitle packet, you demux audio and video, and then look whether there was a subtitle packet. This means to get subtitles for a time range, you need to know that you demuxed video and audio over this range, which becomes pretty messy when you demux audio and video backwards separately. Backward display is the most weird (and potentially buggy) part. To avoid that we need to touch a LOT of timing code, we negate all timestamps. The basic idea is that due to the navigation, all comparisons and subtractions of timestamps keep working, and you don't need to touch every single of them to "reverse" them. E.g.: bool before = pts_a < pts_b; would need to be: bool before = forward ? pts_a < pts_b : pts_a > pts_b; or: bool before = pts_a * dir < pts_b * dir; or if you, as it's implemented now, just do this after decoding: pts_a *= dir; pts_b *= dir; and then in the normal timing/renderer code: bool before = pts_a < pts_b; Consequently, we don't need many changes in the latter code. But some assumptions inhererently true for forward playback may have been broken anyway. What is mainly needed is fixing places where values are passed between positive and negative "domains". For example, seeking and timestamp user display always uses positive timestamps. The main mess is that it's not obvious which domain a given variable should or does use. Well, in my tests with a single file, it suddenly started to work when I did this. I'm honestly surprised that it did, and that I didn't have to change a single line in the timing code past decoder (just something minor to make external/cached text subtitles display). I committed it immediately while avoiding thinking about it. But there really likely are subtle problems of all sorts. As far as I'm aware, gstreamer also supports backward playback. When I looked at this years ago, I couldn't find a way to actually try this, and I didn't revisit it now. Back then I also read talk slides from the person who implemented it, and I'm not sure if and which ideas I might have taken from it. It's possible that the timestamp reversal is inspired by it, but I didn't check. (I think it claimed that it could avoid large changes by changing a sign?) VapourSynth has some sort of reverse function, which provides a backward view on a video. The function itself is trivial to implement, as VapourSynth aims to provide random access to video by frame numbers (so you just request decreasing frame numbers). From what I remember, it wasn't exactly fluid, but it worked. It's implemented by creating an index, and seeking to the target on demand, and a bunch of caching. mpv could use it, but it would either require using VapourSynth as demuxer and decoder for everything, or replacing the current file every time something is supposed to be played backwards. FFmpeg's libavfilter has reversal filters for audio and video. These require buffering the entire media data of the file, and don't really fit into mpv's architecture. It could be used by playing a libavfilter graph that also demuxes, but that's like VapourSynth but worse.
* sub: remove only user of demux_read_packet()wm42019-09-191-4/+24
| | | | | | | | | | | | | | | | | | | There are 3 packet reading functions in the demux API, which all function completely differently. One of them, demux_read_packet(), has only 1 caller, which is in dec_sub.c. Change this caller to use demux_read_packet_async() instead. Since it really wants to do a blocking call, setup some proper waiting. This uses mp_dispatch_queue, because even though it's overkill, it needs the least code. In practice, waiting actually never happens. This code is only called on code paths where everything is already read into memory (libavformat's subtitle demuxers simply behave this way). It's still a bit of a "coincidence", so implement it properly anyway. If suubtitle decoder init fails, we still need to unset the demuxer wakeup callback. Add a sub_destroy() call to the failure path. This also happens to fix a missed pthread_mutex_destroy() call (in practice this was a nop, or a memory leak on BSDs).
* sd_lavc: fix some obscure UBwm42019-09-191-4/+4
| | | | | | | | UB-sanitizer complains that we shift bits into the sign (when a is used). Change it to unsigned, which in theory is more correct and silences the warning. Doesn't matter in practice, both the "bug" and the fix have 0 impact.
* sub/sd_ass: always set the libass track type to TRACK_TYPE_ASSJan Ekström2019-09-191-2/+1
| | | | | | | | It would always autodetect it based on the passed style block, but as we are defining it - we might as well define it always. (As far as I can see all decoders in libavcodec utilize 4+ style blocks)
* sub/sd_ass: utilize UINT32_MAX subtitle duration for unknownJan Ekström2019-09-192-9/+12
| | | | | US closed captions, teletext and ARIB caption decoders utilize this value.
* sub/lavc_conv: switch to the newer "ass" subtitle decoding modeJan Ekström2019-09-193-5/+22
| | | | | Existing since 2016, this removes timestamps from the lines, and gives more precision in the timestamps (1:1000).
*