Getting subtitle scaling and positioning right even if there are video
filters, which completely change the image (like cropping), doesn't seem
to have a single, correct solution. To some degree, the results are
arbitrary, so we may as well do what is most useful to the user.
In this case, if the PGS resolution aspect ratio and the video output
aspect ratio mismatch, letter-box it, instead of stretching the subs
over the video frame. (This will require additional fixes, should it
turn out that there are PGS subtitles which are stretched by design.)
Fixes#1205.
Now requires newest libass git. Since this feature wasn't part of a
libass release yet, I'm not bothering making the mpv code compatible
with as how it was previously implemented (it will just be disabled
with any older libass).
CC: @mpv-player/stable (because mpv-build uses libass git, and this
breaks the feature)
The one in msg.c was mistakenly removed with commit e99a37f6.
I didn't actually test the change in ao_sndio.c (but obviously "ap"
shouldn't be static).
Simple fix for issue #1137.
Since all sub-bitmaps are packed on a larger texture, there's still a
"fall off" on the border due to the linear scaling. This could be
fixed by constraining each sub-bitmap to its own texture, or by
clamping on the shader level, but I don't care for now.
We don't allow this by default, because it would be silly if random
external data (like filenames or file tags) could accidentally trigger
them.
Add a property that magically disables this ASS tag escaping.
Note that malicious input could still disable ASS tag escaping by
itself. This would be annoying but harmless.
Merges pull request #1094, with some minor changes. mpv expects IEEE,
and IEEE allows divisions by 0 for floats, so these shouldn't actually
be a problem, but do it anyway for the sake of clang.
Signed-off-by: wm4 <wm4@nowhere>
This is a deadlock caused by a lock order issue: sub/osd.c locks the OSD
first, then the subtitle decoder lock. player/sub.c does the reverse.
Fix this by discussing away the requirement for locking (see below),
which allows us to drop the broken sub lock. sub_get_text() still
acquires and releases the sub decoder lock, but it's not held at the
same time as the OSD lock anymore, so it should be fine.
Originally, the sub lock was acquired because sub_get_text() returns a
pointer to a mutable string. We simply declare that it's ok to call it
unlocked, as long as only 1 thread accesses it, which works out fine in
this case.
bstr.c doesn't really deserve its own directory, and compat had just
a few files, most of which may as well be in osdep. There isn't really
any justification for these extra directories, so get rid of them.
The compat/libav.h was empty - just delete it. We changed our approach
to API compatibility, and will likely not need it anymore.
It makes no sense to set the packet duration, because libavcodec doesn't
know the timebase. And in fact, no subtitle decoder accesses the packet
duration, except text subtitle converters, which are not relevant here.
So this code did nothing - drop it.
Also fix a blatantly incorrect comment.
sub_reset() was called on cycling subtitle tracks and on seeking. Since
we don't want that subtitles disppear on cycling, sd_lavc.c didn't clear
its internal subtitle queue on reset, which meant that seeking with PGS
subtitles could leave the subtitle on screen (PGS subtitles usually
don't have a duration set).
Call it only on seeking, so we can also strictly clear the subtitle
queue in sd_lavc.
(This still can go very wrong if you disable a subtitle, seek, and
enable it again - for example, if used with libavformat that uses "SSA"
style demuxed ASS subtitle packets. That shouldn't happen with newer
libavformat versions, and the user can "correct" it anyway by executing
a seek while the subtitle is selected.)
Something like "char *s = ...; isdigit(s[0]);" triggers undefined
behavior, because char can be signed, and thus s[0] can be a negative
value. The is*() functions require unsigned char _or_ EOF. EOF is a
special value outside of unsigned char range, thus the argument to the
is*() functions can't be a char.
This undefined behavior can actually trigger crashes if the
implementation of these functions e.g. uses lookup tables, which are
then indexed with out-of-range values.
Replace all <ctype.h> uses with our own custom mp_is*() functions added
with misc/ctype.h. As a bonus, these functions are locale-independent.
(Although currently, we _require_ C locale for other reasons.)
Search $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS for config files.
This also negates the need to have separate user and global variants of
mp_find_config_file()
Closes#864, #109.
Signed-off-by: wm4 <wm4@nowhere>
Until now, bitmap subtitles were decoded at "some" point, and then
simply replaced the old subtitle. Although the subtitle is selected
by time (PTS), it could happen that a subtitle was replaced too early.
One consequence is that this might lead to flicker even if the
subtitles are timed to follow each other without a gap (although most
subtitles are explicitly timed to introduce such a gap). With this
commit the past 4 subtitles are kept (instead of 1), so that the
correct one can be picked by time. This should fix the aforementioned
cases, but more importantly will allow demuxing/decoding and video
display to be somewhat asynchronous.
Still missing: somehow making sure the correct range of decoded
subtitles is available, instead of just passing along whatever comes
from the demuxer, and hoping that 4 queued subtitles are enough. But it
should certainly be good enough for now.
This removes a check that resets the subtitles if the PTS is 5 minutes
before the end of the current subtitle; this is probably not needed.
Until now, failure to allocate image data resulted in a crash (i.e.
abort() was called). This was intentional, because it's pretty silly to
degrade playback, and in almost all situations, the OOM will probably
kill you anyway. (And then there's the standard Linux overcommit
behavior, which also will kill you at some point.)
But I changed my opinion, so here we go. This change does not affect
_all_ memory allocations, just image data. Now in most failure cases,
the output will just be skipped. For video filters, this coincidentally
means that failure is treated as EOF (because the playback core assumes
EOF if nothing comes out of the video filter chain). In other
situations, output might be in some way degraded, like skipping frames,
not scaling OSD, and such.
Functions whose return values changed semantics:
mp_image_alloc
mp_image_new_copy
mp_image_new_ref
mp_image_make_writeable
mp_image_setrefp
mp_image_to_av_frame_and_unref
mp_image_from_av_frame
mp_image_new_external_ref
mp_image_new_custom_ref
mp_image_pool_make_writeable
mp_image_pool_get
mp_image_pool_new_copy
mp_vdpau_mixed_frame_create
vf_alloc_out_image
vf_make_out_image_writeable
glGetWindowScreenshot
We certainly don't want to maintain and improve the internal converter,
but we still need the internal one for Libav. (In the Libav case,
demux_subreader.c will be used to read the MicroDVD file.)
Let the VOs draw the OSD on their own, instead of making OSD drawing a
separate VO driver call. Further, let it be the VOs responsibility to
request subtitles with the correct PTS. We also basically allow the VO
to request OSD/subtitles at any time.
OSX changes untested.
While I'm not very fond of "const", it's important for declarations
(it decides whether a symbol is emitted in a read-only or read/write
section). Fix all these cases, so we have writeable global data only
when we really need.
(The old "force" choice of that option is renamed to "force-default".)
This allows overriding native ASS script subtitle styles with the style
provided by the --sub-text-* options (like --sub-text-font etc.). This
is disabled by default, and needs to be explicitly enabled with the
--ass-style-override=force option and input property.
This uses in fact exactly the same options (--sub-text-*) and semantics
as the ones used to configure unstyled text subtitles.
It's recommended to combine this with this in the mpv config file:
ass-force-style="ScaledBorderAndShadow=1" # work around dumb libass behavior
Also, adding a key binding to toggle this behavior should be added,
because overriding can easily break:
L cycle ass-style-override
This would cycle override behavior on Shift+L and allows quickly
disabling/enabling style overrides.
Note: ASS should be considered a vector format rather than a subtitle
format. There is no easy or reliable way to determine whether the style
of a given subtitle event can be changed without destroying visuals or
not. This patch relies on a simple heuristic, which often works and
often breaks.
This might shift bits into the sign, which is undefined behavior. Making
the right operand unsigned was supposed to help with this, but it seems
it did nothing, and C99 makes the result type dependent on the left
operand only.
This used an unnamed union, which is allowed in GNU C and C11, but not
C99. This broke the build with some older compilers.
Replaces pull request #744.
The --ass-styles option is implemented by calling ass_read_styles().
This function can take a codepage (so libass will use iconv to convert
it). This was implemented before our --subcp option was changed, and
this code was not updated. Now libass fails opening iconv, because
--subcp is not always (and not by default) a valid iconv codepage.
Just always pass NULL, which means the file passed to --ass-styles must
be in UTF-8. The --ass-styles option is a fringe option anyway (and will
destroy your subtitles), so having codepage support for it isn't
important at all.
Instead of parsing the ASS file in demux_libass.c and trying to pass the
ASS_Track to the subtitle renderer, just read all file data in
demux_libass.c, and let the subtitle renderer pass the file contents to
ass_process_codec_private(). (This happens to parse full files too.)
Makes the code simpler, though it also relies harder on the (messy)
probe logic in demux_libass.c.
--ass-style-override=force now attempts to override the 'Default' style.
May or may not work. In some situations it will work, but also mess up
seemingly unrelated things like signs typeset with ASS.
Set subtitle resolution to video resolution when avctx->width and
avctx->height are zero.
This can happen with broken vobsubs that have no size set in their
.idx file (or Matroska extradata). At least with the test file provided
in issue #551, using the video resolution as fallback instead of what
guess_resolution() does is better.
Note that these files clearly are broken. It seems this particular
file was created by trying to use ffmpeg to transcode DVB subtitles
to vobsub, and ffmpeg "forgot" to set the subtitle resolution in the
destination file. On the other hand, ffmpeg DVB and PGS decoders set
the resolution on the first subtitle packet (or somewhere close), so
it's not really clear what to do here.
Closes#551.
Signed-off-by: wm4 <wm4@nowhere>
Patch by xylosper, rewritten commit message by wm4.
The mplayer decoder (spudec.c) actually handled this. There was explicit
code for binary palettes (16 32 bit values), and the subtitle resolution
was handled by video resolution coincidentally matching the subtitle
resolution.
Whoever puts vobsub into mp4 should be punished.
Fixes the sample gundam_sample.mp4, closes github issue #547.
Not everything in the OSD path handles 0x0 sized sub-bitmaps well. At
least the code implementing --sub-gray had severe problems with it.
Fix this by skipping such bitmaps.
If, for some reason, the subtitle renderer attempts to render a
subtitle before SD_CTRL_SET_VIDEO_PARAMS was called, it passed a
value calculated from invalid values. This can happen with --vf=sub
and --start. The crash happens if 1. there was a subtitle packet that
falls into the timestamp of the rendered video frame, 2. the playloop
hasn't informed the subtitle decoder about the video resolution yet
(normally unneeded, because that is used for weird corner cases only,
so this code is a bit fuzzy), and 3. something actually requests a
frame to be drawn from the subtitle renderer, like with vf_sub.
The actual crash was due to passing NaN as pixel aspect to libass,
which then created glyphs with ridiculous sizes, involving a few
integer overflows and unchecked mallocs.
The sd_lavc.c and sd_spu.c cases probably don't crash, but I'm not
sure, and it's better fix them anyway.
Not bothering with sd_spu.c, this crap is for compatibility and will
be removed soon.
Note that this would have been no problem, had the code checked whether
SD_CTRL_SET_VIDEO_PARAMS was actually called. This commit adds such a
check (although it basically checks after using the parameters).
Regression since 49caa0a7 and 633fde4a.