1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-24 07:42:17 +00:00
Commit Graph

126 Commits

Author SHA1 Message Date
wm4
c4d0d7a194 sub: fix incorrect commit
Commit c6369933f1 accidentally added an old version of this comment.
2020-05-15 16:37:41 +02:00
wm4
c6369933f1 command: add property to return text subtitles in ASS
See manpage additions. This was requested, sort of. Although what has
been requested might be something completely different. So this is
speculative.

This also changes sub_get_text() to return an allocated copy, because
the buffer shit was too damn messy.
2020-05-14 22:14:49 +02:00
wm4
e9e883e3b2 video: make OSD/subtitle bitmaps refcounted (sort of)
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().

Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.

I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.

I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.

In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
2020-04-26 23:34:32 +02:00
wm4
0b9ed9c274 build: make libass non-optional
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.)
2020-03-18 22:45:59 +01:00
wm4
c4440db744 sub: do not ignore demuxer wakeups
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.
2020-02-27 02:33:51 +01:00
wm4
423323170b sub: fix typo in comment
Reading this commit and this commit message is a waste of time. I
guarantee it.
2020-02-27 02:24:43 +01:00
wm4
cf2b7a4997 sub, demux: improve behavior with negative subtitle delay/muxed subs
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
2020-02-27 02:23:58 +01:00
wm4
0b35b4c917 sub: make filter_sdh a "proper" filter, allow runtime changes
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.
2020-02-16 02:07:24 +01:00
Stefano Pigozzi
cb32ad68f3 command: add sub-start & sub-end properties
These properties contain the current subtitle's start and end times.
Can be useful to cut sample audio through the scripting interface.
2019-09-22 09:19:45 +02:00
wm4
d34421f4f9 dec_sub: remove unused declaration 2019-09-21 19:08:14 +02:00
dudemanguy
48740dfec5 osd: allow sub-text to work even if sub-visibility is disabled 2019-09-21 15:36:58 +02:00
wm4
b9d351f02a Implement backwards playback
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.
2019-09-19 20:37:04 +02:00
wm4
287166b02e sub: remove only user of demux_read_packet()
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).
2019-09-19 20:37:04 +02:00
wm4
6aad532aa3 options: move most subtitle and OSD rendering options to sub structs
Remove them from the big MPOpts struct and move them to their sub
structs. In the places where their fields are used, create a private
copy of the structs, instead of accessing the semi-deprecated global
option struct instance (mpv_global.opts) directly.

This actually makes accessing these options finally thread-safe. They
weren't even if they should have for years. (Including some potential
for undefined behavior when e.g. the OSD font was changed at runtime.)

This is mostly transparent. All options get moved around, but most users
of the options just need to access a different struct (changing sd.opts
to a different type changes a lot of uses, for example).

One thing which has to be considered and could cause potential
regressions is that the new option copies must be explicitly updated.
sub_update_opts() takes care of this for example.

Another thing is that writing to the option structs manually won't work,
because the changes won't be propagated to other copies. Apparently the
only affected case is the implementation of the sub-step command, which
tries to change sub_delay. Handle this one explicitly (osd_changed()
doesn't need to be called anymore, because changing the option triggers
UPDATE_OSD, and updates the OSD as a consequence). The way the option
value is propagated is rather hacky, but for now this will do.
2018-01-02 14:27:37 -08:00
wm4
3bf7df4a5e sub: move all subtitle timestamp messing code to a central place
It was split at least across osd.c and sd_ass.c/sd_lavc.c. sd_lavc.c
actually ignored most of the more obscure subtitle timing things.
There's no reason for this - just move it all to dec_sub.c (mostly from
sd_ass.c, because it has some of the most complex stuff).

Now timestamps are transformed as they enter or leave dec_sub.c.

There appear to have been some subtle mismatches about how subtitle
timestamps were transformed, e.g. sd_functions.accepts_packet didn't
apply the subtitle speed to the timestamp. This patch should fix them,
although it's not clear if they caused actual misbehavior.

The semantics of SD_CTRL_SUB_STEP are slightly changed, which is the
reason for the changes in command.c and sd_lavc.c.
2018-01-02 14:27:37 -08:00
wm4
a5b51f75dc demux: get rid of demux_packet.new_segment field
The new_segment field was used to track the decoder data flow handler of
timeline boundaries, which are used for ordered chapters etc. (anything
that sets demuxer_desc.load_timeline). This broke seeking with the
demuxer cache enabled. The demuxer is expected to set the new_segment
field after every seek or segment boundary switch, so the cached packets
basically contained incorrect values for this, and the decoders were not
initialized correctly.

Fix this by getting rid of the flag completely. Let the decoders instead
compare the segment information by content, which is hopefully enough.
(In theory, two segments with same information could perhaps appear in
broken-ish corner cases, or in an attempt to simulate looping, and such.
I preferred the simple solution over others, such as generating unique
and stable segment IDs.)

We still add a "segmented" field to make it explicit whether segments
are used, instead of doing something silly like testing arbitrary other
segment fields for validity.

Cached seeking with timeline stuff is still slightly broken even with
this commit: the seek logic is not aware of the overlap that segments
can have, and the timestamp clamping that needs to be performed in
theory to account for the fact that a packet might contain a frame that
is always clipped off by segment handling. This can be fixed later.
2017-10-24 19:35:55 +02:00
wm4
96a45a16af player: add experimental stream recording feature
This is basically a WIP, but it can't remain in a branch forever. A
warning is print when using it as it's still a bit "shaky".
2017-02-07 17:05:17 +01:00
wm4
a55e8ff31c dec_sub: avoid full reinit on switches to the same segment
The previous commit means subtitles were reinitialized on every seek
(even within a segment). This commit restores the old behavior.

To check whether the segment changed at all, we don't reset the current
start/end values. This assumes the decoder wrapper is always fed by a
stream which doesn't mix segment and non-segment packets, which is
currently always true.
2016-11-09 16:44:06 +01:00
wm4
4a8647b6b8 sub: don't potentially discard too many subtitles on seek
The accepts_packet packet callback is supposed to deal with subtitle
decoders which have only a small queue of current subtitle events (i.e.
sd_lavc.c), in case feeding it too many packets would discard events
that are still needed.

Normally, the number of subtitles that need to be preserved is estimated
by the rendering pts (get_bitmaps() argument). Rendering lags behind
decoding, so normally the rendering pts is smaller than the next video
frame pts, and we simply discard all subtitle events until the rendering
pts.

This breaks down in some annoying corner cases. One of them is seeking
backwards: the VO will still try to render the old PTS during seeks,
which passes a high PTS to the subtitle renderer, which in turn would
discard more subtitles than it should. There is a similar issue with
forward seeks. Add hacks to deal with those issues.

There should be a better way to deal with the essentially unknown
"rendering position", which is made worse by screenshots or rendering
with vf_sub. At the very least, we could handle seeks better, and e.g.
either force the VO not to re-render subs after seeks (ugly), or
introduce seek sequence numbers to distinguish attempts to render
earlier subtitles when a seek is done.
2016-08-14 20:27:37 +02:00
wm4
f110552898 sub: pass preferred OSD format to subtitle renderers
The intention is to let mp_ass_packer_pack() produce different output
for the RGBA and LIBASS formats. VOs (or whatever generates the OSD)
currently do not signal a preferred format, and this mechanism just
exists to switch between RGBA and LIBASS formats correctly, preferring
LIBASS if the VO supports it.
2016-07-03 19:31:56 +02:00
wm4
5fe2812494 sub: force segment switch if video is already ahead
In particular, this prevents subtitle packets from building up in the
subtitle queue if e.g. --vo=null is used. In this situation,
sub_get_bitmaps() is never called, and thus the segment never switched.

This also seems to help with flickering at segment switch boundaries (if
subs are supposed to be visible at the transition points).

In theory, this could trigger a switch too early, but the way VO and
subtitle renderer interact wrt. timing is a bit iffy anyway.
2016-03-25 17:40:44 +01:00
wm4
f5bfe01932 osd: refactor how mp_ass_render_frame() is called
Instead of passing an explicit cache to the function, the res parameter
is used. Also, instead of replacing its contents, sub bitmaps are now
appended to it (all assuming the format doesn't actually change).

This is preparation for the following commits.
2016-03-08 21:59:55 +01:00
wm4
05b2cd08dc sub: make preloading more robust
Subtitles can be preloaded, which means they're fully read and copied
into ASS_Track. This in turn is mainly for the sake of being able to do
subtitle seeking (when it comes down to it, subtitle seeking is the
cause for most trouble here).

Commit a714f8e92 broke preloaded subtitles which have events with
unknown duration, such as some MicroDVD samples. The event list gets
cleared on every seek, so the property of being preloaded obviously gets
lost.

Fix this by moving most of the preloading logic to dec_sub.c. If the
subtitle list gets cleared, they are not considered preloaded anymore,
and the logic for demuxed subtitles is used.

As another minor thing, preloadeding subtitles did neither disable the
demux stream, nor did it discard packets. Thus you could get queue
overflows in theory (harmless, but annoying). Fix this by explicitly
discarding packets in preloaded mode.

In summary, now the only difference between preloaded and normal
demuxing are:
1. a seek is issued, and all packets are read on start
2. during playback, discard the packets instead of feeding them to the
   subtitle decoder

This is still petty annoying. It would be nice if maintaining the
subtitle index (and maybe a subtitle packet cache for instant subtitle
presentation when seeking back) could be maintained in the demuxer
instead. Half of all file formats with interleaved subtitles have
this anyway (mp4, mkv muxed with newer mkvmerge).
2016-03-06 15:17:59 +01:00
wm4
3f60548df4 sub: pass all attachments to the subtitle decoder
Commit 8d4a179c made subtitle decoders pick up fonts strictly from the
same source file (i.e. the same demuxer).

It breaks some fucked up use-case, and 2 people on this earth complained
about the change because of this. Add it back.

This copies all attached fonts on each subtitle init. I considered
converting attachments to use refcounting, but it'd probably be much
more complex.

Since it's slightly harder to get a list of active demuxers with
duplicate removed, the prev_demuxer variable serves as a hack to achieve
almost the same thing, except in weird corner cases. (In which fonts
could be added twice.)
2016-03-03 18:48:56 +01:00
wm4
da24cb9e3e sub: always clip subtitles against segment end
This happens only if the new segment wasn't read yet.

This is not quite proper and a problem with dec_sub.c internals.
Ideally, it'd wait with rendering until a new enough segment has been
read. Normally, the new segment is available immediately, so the end
will be automatically clipped by switching to the right segment in the
exact moment it's supposed to become effective.

Usually shouldn't cause any problems, though.
2016-02-20 16:42:32 +01:00
wm4
0af5335383 Rewrite ordered chapters and timeline stuff
This uses a different method to piece segments together. The old
approach basically changes to a new file (with a new start offset) any
time a segment ends. This meant waiting for audio/video end on segment
end, and then changing to the new segment all at once. It had a very
weird impact on the playback core, and some things (like truly gapless
segment transitions, or frame backstepping) just didn't work.

The new approach adds the demux_timeline pseudo-demuxer, which presents
an uniform packet stream from the many segments. This is pretty similar
to how ordered chapters are implemented everywhere else. It also reminds
of the FFmpeg concat pseudo-demuxer.

The "pure" version of this approach doesn't work though. Segments can
actually have different codec configurations (different extradata), and
subtitles are most likely broken too. (Subtitles have multiple corner
cases which break the pure stream-concatenation approach completely.)

To counter this, we do two things:
- Reinit the decoder with each segment. We go as far as allowing
  concatenating files with completely different codecs for the sake
  of EDL (which also uses the timeline infrastructure). A "lighter"
  approach would try to make use of decoder mechanism to update e.g.
  the extradata, but that seems fragile.
- Clip decoded data to segment boundaries. This is equivalent to
  normal playback core mechanisms like hr-seek, but now the playback
  core doesn't need to care about these things.

These two mechanisms are equivalent to what happened in the old
implementation, except they don't happen in the playback core anymore.
In other words, the playback core is completely relieved from timeline
implementation details. (Which honestly is exactly what I'm trying to
do here. I don't think ordered chapter behavior deserves improvement,
even if it's bad - but I want to get it out from the playback core.)

There is code duplication between audio and video decoder common code.
This is awful and could be shareable - but this will happen later.

Note that the audio path has some code to clip audio frames for the
purpose of codec preroll/gapless handling, but it's not shared as
sharing it would cause more pain than it would help.
2016-02-15 21:04:07 +01:00
wm4
8aeaa34a5c sub: move sub decoder init to a function
Preparation for timeline rewrite.
2016-02-15 20:26:22 +01:00
wm4
0287736119 sub: remove always-true check
Confuses Coverity with FORWARD_NULL on the mp_err() at the end of the
function. These pointers are never NULL.

Fixes CID 1350059.
2016-02-12 15:58:48 +01:00
wm4
8a9b64329c Relicense some non-MPlayer source files to LGPL 2.1 or later
This covers source files which were added in mplayer2 and mpv times
only, and where all code is covered by LGPL relicensing agreements.

There are probably more files to which this applies, but I'm being
conservative here.

A file named ao_sdl.c exists in MPlayer too, but the mpv one is a
complete rewrite, and was added some time after the original ao_sdl.c
was removed. The same applies to vo_sdl.c, for which the SDL2 API is
radically different in addition (MPlayer supports SDL 1.2 only).

common.c contains only code written by me. But common.h is a strange
case: although it originally was named mp_common.h and exists in MPlayer
too, by now it contains only definitions written by uau and me. The
exceptions are the CONTROL_ defines - thus not changing the license of
common.h yet.

codec_tags.c contained once large tables generated from MPlayer's
codecs.conf, but all of these tables were removed.

From demux_playlist.c I'm removing a code fragment from someone who was
not asked; this probably could be done later (see commit 15dccc37).

misc.c is a bit complicated to reason about (it was split off mplayer.c
and thus contains random functions out of this file), but actually all
functions have been added post-MPlayer. Except get_relative_time(),
which was written by uau, but looks similar to 3 different versions of
something similar in each of the Unix/win32/OSX timer source files. I'm
not sure what that means in regards to copyright, so I've just moved it
into another still-GPL source file for now.

screenshot.c once had some minor parts of MPlayer's vf_screenshot.c, but
they're all gone.
2016-01-19 18:36:06 +01:00
wm4
671df54e4d demux: merge sh_video/sh_audio/sh_sub
This is mainly a refactor. I'm hoping it will make some things easier
in the future due to cleanly separating codec metadata and stream
metadata.

Also, declare that the "codec" field can not be NULL anymore. demux.c
will set it to "" if it's NULL when added. This gets rid of a corner
case everything had to handle, but which rarely happened.
2016-01-12 23:48:19 +01:00
wm4
0915a8497b sub: read subtitles until their timestamps are past video
Change >= to >, because if the timestamps are equal, further subtitle
packets with the same timestamps could be required (e.g. ASS).
2016-01-11 20:37:16 +01:00
wm4
b47bf06f97 sub: change how subtitles are read
Slightly change how it is decided when a new packet should be read.
Switch to demux_read_packet_async(), and let the player "wait properly"
until required subtitle packets arrive, instead of blocking everything.
Move distinguishing the cases of passive and active reading into the
demuxer, where it belongs.
2015-12-29 01:35:52 +01:00
wm4
9b3daa4974 sub: remove packet list thing
Just a simplification. This packet list lost its function a dozen of
commits ago or so.
2015-12-28 23:31:23 +01:00
wm4
4c1deb680d sub: do charset conversion in demux_lavf.c
Just so I can remove a few lines from dec_sub.c.

This is slightly inelegant, as the whole subtitle file has to be read
into memory, converted at once in memory, and then provided to
libavformat in an awkward way by creating a memory stream instead of
using demuxer->stream. It also won't be possible to force the charset on
subtitles in binary container formats - but this wasn't exposed before,
and we just hope this won't be ever needed. (One motivation was fixing
broken files with non-UTF8 muxed.) It also won't be possible to change
the charset on the fly, but this was not exposed either.
2015-12-28 23:23:30 +01:00
wm4
d85753b79e sub: refactor initialization
Just simplify by removing parts not needed anymore. This includes
merging dec_sub allocation and initialization (since things making
initialization complicated were removed), or format support queries (it
simply tries to create a decoder, and if that fails, tries the next
one).
2015-12-27 02:13:06 +01:00
wm4
50c379e2d8 sub: minor refactor how video FPS for MicroDVD is set
So that the video FPs is not required at initialization, and can be set
later.

(As for whether this MicroDVD crap is worth the trouble to handle it
"correctly": MicroDVD files are unfortunately still around, and in at
least one case using the video FPS seemed to help indeed.)
2015-12-27 02:13:06 +01:00
wm4
190dea149a sub: destroy/recreate ASS_Renderer when disabling/enablings subs
Keeping ASS_Renderers around for a potentially large number of subtitle
tracks could lead to excessive memory usage, especially since the libass
cache is broken (caches even unneeded data), and might consume up to
~500MB of memory for no reason.
2015-12-26 18:35:36 +01:00
wm4
8d4a179c14 sub: always recreate ASS_Renderer on subtitle decoder reinit
This includes the case of switching ordered chapter boundaries. It will
now be recreated on each timeline part switch. This shouldn't be much of
a problem with modern libass. (Older libass versions use fontconfig for
memory fonts, and will be very slow to reinitialize memory fonts.)
2015-12-26 18:34:18 +01:00
Aman Gupta
f8b09658f4 dec_sub: avoid segfault on sub_init_decoder failure
Broken by commit 687b552d.

Signed-off-by: wm4 <wm4@nowhere>
2015-12-22 13:00:05 +01:00
wm4
5dd5dc66c1 sub: remove unused video width/height headers
Apparently, this was replaced by the SD_CTRL_SET_VIDEO_PARAMS set
dimensions. But I can't find out when this happened - possibly, these
fields were never used by sd_lavc.c, and only by the (long removed)
MPlayer dvdsub decoder.
2015-12-18 03:59:52 +01:00
wm4
687b552db1 sub: remove subtitle filter chain concept
It was stupid. The only thing that still effectively used it was
sd_lavc_conv - all other "filters" were the subtitle decoder/renderers
for text (sd_ass) and bitmap (sd_lavc) subtitles.

While having a subtitle filter chain was interesting (and actually
worked in almost the same way as the audio/video ones), I didn't
manage to use it in a meaningful way, and I couldn't e.g. factor
secondary features like fixing subtitle timing into filters.

Refactor the shit and drop unneeded things as it goes.
2015-12-18 03:52:57 +01:00
wm4
2c7db48195 sub: do not clear subtitle list on seeking
This affects non-ASS text subtitles (those which go through libavcodec's
subtitle converter), which are muxed with video/audio. (Typically srt
subs in mkv.)

The problem is that seeking in the file can send a subtitle packet to
the decoder multiple times. These packets are interlaved with video,
and thus can't be all read when opening the file. Rather, subtitle
packets can essentially be randomly skipped or repeated (by seeking).
Until recently, this was solved by scanning the libass event list for
duplicates. Then our builtin srt-to-ass converter was removed, and
the problem was handled by fully clearing the subtitle list on each
seek.

This resulted in sub-seek not working properly for this type of file.
Since the subtitle list was cleared on seek, it was not possible to
do e.g. sub-seeks to subtitles before the current playback position.

Fix this by not clearing the list, and intead explicitly rejecting
duplicate packets. We use the packet file position was unique ID for
subtitles; this is confirmed working for most file formats (although
it is slightly risky - new demuxers may not necessarily set the file
position to something unique, or at all).

The list of seen packets is sorted, and the lookup uses binary search.
This is to avoid quadratic complexity when subtitles are added in
bulks, such as when opening a text subtitle file.

In some places, the code has to be adjusted to pass through the packet
file position correctly.
2015-12-18 03:52:57 +01:00
wm4
04af005c35 sd_ass: remove dead code
With the FFmpeg subtitle decoder used for _all_ non-ASS text subtitle
format, this code is simply unused now.

Ironically, the FFmpeg subtitle decoder does not handle things correctly
in a bunch of cases. Should it turn out they actually matter, they will
have to hack back.

The extend_event one is a candidate, although even though there were
allegedly files which need it, I couldn't get samples from the user who
originally reported such files. As such, extend_event was only confirmed
to handle trailing events with no (endless) duration like with MicroDVD
and LRC, but FFmpeg "fudges" these anyway, so no special handling is
needed.

This code also had logic to handle seeking with muxed srt subtitles,
which made the sub-seek command work. But this has been broken before
this commit already. Currently, seeking with muxed srt subs will clear
all subtitles, as the broken FFmpeg ASS format output by the libavcodec
subtitle converters does not check for duplicates. Since the subtitles
are all cleared, ass_step_sub() can not work properly and sub-seek can
not seek to already seen subtitles.
2015-12-17 01:17:26 +01:00
wm4
74c11f0c84 sub: detect charset in demuxer
Slightly simpler, and removes the need to pre-read all subtitle packets.

This still does the subtitle charset conversion on the packet level
(instead converting when parsing the file), so in theory this still
could provide a way to change the charset at runtime. But maybe even
this should be removed, as FFmpeg is somewhat likely to get its own
charset detection and conversion mechanism in the future. (Would have
to keep the subtitle file in memory to allow changing the charset on
the fly, I guess.)
2015-12-17 01:17:23 +01:00
wm4
e798cf1ff6 sub: remove sd_srt.c
The FFmpeg subtitle converter does the same. There used to be some
deficiencies in FFmpeg's code, but it seems at least some of them have
been fixed. There also used to be the timestamp issue (see previous
commit messages), but this doesn't matter anymore. So no reason to
keep this code - get rid of it.
2015-12-15 21:05:48 +01:00
wm4
cab942acae sub: remove sd_microdvd.c
This can be dropped for the same reasons as in the previous commits. It
removes MicroDVD conversion support on Libav, although MicroDVD files
couldn't be read in the first place ever since demux_subreader.c was
removed.
2015-12-15 21:05:48 +01:00
wm4
c7985fe5f7 sub: remove sd_lavf_srt.c
This restored timestamps when demuxing srt subtitles in Libav, which
was important for avoiding slightly overlapping subtitles. Since the
way this works was changed, there is no real reason to maintain proper
timestamps anymore on this level - this can be dropped without issues.
2015-12-15 21:05:48 +01:00
wm4
29226e6a99 sub: remove sd_movtext.c
libavcodec's movtext-to-ass converter does the same and has more
features. On Libav, this commit disables mp4 subtitle display.
2015-12-15 21:05:48 +01:00
wm4
7d7ea72854 sub: another minor simplification 2015-12-06 18:17:14 +01:00
wm4
48ed48f7b8 sub: minor simplifications
The awkward "preprocess" step of putting the subtitles through single
filters before doing something else was made unnecessary by the recent
changes.

(Fun fact: I originally planned to move these extra things, like fixing
subtitle gaps/overlaps, to filters - but this would suffer from various
complications, and moving them to the renderers seems much simpler.)
2015-12-05 23:56:53 +01:00