summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-25 00:43:04 +0200
committerwm4 <wm4@nowhere>2013-06-25 00:43:04 +0200
commit403a266d466850621397c07e0b96cc2c493b2936 (patch)
tree0835a0908b3df8cca8374d173c34e0bf7df7d842
parent536871d7e5848eb385b97202a33b9382b5e8ab0e (diff)
parent54851d60614e912fc422658302d72811a31b80f8 (diff)
downloadmpv-403a266d466850621397c07e0b96cc2c493b2936.tar.bz2
mpv-403a266d466850621397c07e0b96cc2c493b2936.tar.xz
Merge branch 'sub_mess2'
...the return.
-rw-r--r--DOCS/man/en/changes.rst1
-rw-r--r--DOCS/man/en/options.rst55
-rw-r--r--DOCS/tech-overview.txt32
-rw-r--r--Makefile8
-rwxr-xr-xconfigure21
-rw-r--r--core/charset_conv.c266
-rw-r--r--core/charset_conv.h17
-rw-r--r--core/command.c5
-rw-r--r--core/encode_lavc.c2
-rw-r--r--core/input/input.c2
-rw-r--r--core/mp_core.h3
-rw-r--r--core/mplayer.c110
-rw-r--r--core/options.c9
-rw-r--r--core/options.h3
-rw-r--r--demux/demux.c139
-rw-r--r--demux/demux.h19
-rw-r--r--demux/demux_cue.c8
-rw-r--r--demux/demux_edl.c8
-rw-r--r--demux/demux_lavf.c10
-rw-r--r--demux/demux_libass.c121
-rw-r--r--demux/demux_mf.c2
-rw-r--r--demux/demux_sub.c38
-rw-r--r--demux/demux_subreader.c (renamed from sub/subreader.c)666
-rw-r--r--demux/stheader.h3
-rw-r--r--stream/stream.c111
-rw-r--r--stream/stream.h12
-rw-r--r--sub/ass_mp.c29
-rw-r--r--sub/ass_mp.h3
-rw-r--r--sub/dec_sub.c331
-rw-r--r--sub/dec_sub.h2
-rw-r--r--sub/sd_ass.c55
-rw-r--r--sub/sd_lavc_conv.c2
-rw-r--r--sub/sd_lavf_srt.c94
-rw-r--r--sub/sd_movtext.c3
-rw-r--r--sub/sub.c1
-rw-r--r--sub/subreader.h79
-rw-r--r--video/out/gl_lcms.c2
37 files changed, 1348 insertions, 924 deletions
diff --git a/DOCS/man/en/changes.rst b/DOCS/man/en/changes.rst
index de3b24b710..ed83c402f3 100644
--- a/DOCS/man/en/changes.rst
+++ b/DOCS/man/en/changes.rst
@@ -128,6 +128,7 @@ Command line switches
-dumpstream --stream-dump=<filename>
-capture --stream-capture=<filename>
-stop-xscreensaver --stop-screensaver
+ -subfile --sub
=================================== ===================================
*NOTE*: ``-opt val`` becomes ``--opt=val``.
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index 304eeba464..57af5ff209 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -1447,11 +1447,6 @@
``show_progress`` command (by default mapped to ``P``), or in some
non-default cases when seeking. Expands properties. See property_expansion_.
---overlapsub
- Allows the next subtitle to be displayed while the current one is still
- visible (default is to enable the support only for specific formats). This
- only matters for subtitles loaded with ``-sub``.
-
--panscan=<0.0-1.0>
Enables pan-and-scan functionality (cropping the sides of e.g. a 16:9
movie to make it fit a 4:3 display without black bands). The range
@@ -1996,15 +1991,16 @@
Use/display these subtitle files. Only one file can be displayed at the
same time.
+--sub-fix-timing, --no-sub-fix-timing
+ By default, external text subtitles are preprocessed to remove minor gaps
+ or overlaps between subtitles (if the difference is smaller than 200 ms,
+ the gap or overlap is removed). This does not affect image subtitles,
+ subtitles muxed with audio/video, or subtitles in the ASS format.
+
--sub-demuxer=<[+]name>
- Force subtitle demuxer type for ``--subfile``. Using a '+' before the name
- will force it, this will skip some checks! Give the demuxer name as
+ Force subtitle demuxer type for ``--sub``. Give the demuxer name as
printed by ``--sub-demuxer=help``.
---sub-no-text-pp
- Disables any kind of text post processing done after loading the
- subtitles. Used for debug purposes.
-
--sub-paths=<path1:path2:...>
Specify extra directories where to search for subtitles matching the
video. Multiple directories can be separated by ":" (";" on Windows).
@@ -2035,9 +2031,9 @@
``--subcp=enca:<language>:<fallback codepage>``
You can specify your language using a two letter language code to make
- ENCA detect the codepage automatically. If unsure, enter anything and
- watch mpv ``-v`` output for available languages. Fallback codepage
- specifies the codepage to use, when autodetection fails.
+ ENCA detect the codepage automatically. If unsure, enter anything (if the
+ language is invalid, mpv will complain and list valid languages).
+ Fallback codepage specifies the codepage to use if autodetection fails.
*EXAMPLE*:
@@ -2045,17 +2041,20 @@
are Czech, fall back on latin 2, if the detection fails.
- ``--subcp=enca:pl:cp1250`` guess the encoding for Polish, fall back on
cp1250.
+ - ``--subcp=enca:pl`` guess the encoding for Polish, fall back on UTF-8.
+ - ``--subcp=enca`` try universal detection, fall back on UTF-8.
---sub-delay=<sec>
- Delays subtitles by <sec> seconds. Can be negative.
+ If the player was compiled with libguess support you can use it with:
---subfile=<filename>
- Open the given file with a demuxer, and use its subtitle streams. Same as
- ``--audiofile``, but for subtitle streams.
+ ``--subcp=guess:<language>:<fallback codepage>``
- *NOTE*: use ``--sub`` for subtitle files. This option is useless, unless
- you want to force libavformat subtitle parsers instead of libass or
- internal subtitle parsers.
+ Note that libguess always needs a language. There is no universal detection
+ mode. Use ``--subcp=guess:help`` to get a list of languages (like with ENCA,
+ it will be printed only if the conversion code is somehow called, for
+ example when loading an external subtitle).
+
+--sub-delay=<sec>
+ Delays subtitles by <sec> seconds. Can be negative.
--subfps=<rate>
Specify the framerate of the subtitle file (default: movie fps).
@@ -2063,6 +2062,8 @@
*NOTE*: <rate> > movie fps speeds the subtitles up for frame-based
subtitle files and slows them down for time-based ones.
+ Also see ``--sub-speed`` option.
+
--sub-gauss=<0.0-3.0>
Apply gaussian blur to image subtitles (default: 0). This can help making
pixelated DVD/Vobsubs look nicer. A value other than 0 also switches to
@@ -2089,6 +2090,16 @@
*NOTE*: this affects ASS subtitles as well, and may lead to incorrect
subtitle rendering. Use with care, or use ``--sub-text-font-size`` instead.
+--sub-speed=<0.1-10.0>
+ Multiply the subtitle event timestamps with the given value. Can be used
+ to fix the playback speed for frame-based subtitle formats. Works for
+ external text subtitles only.
+
+ *EXAMPLE*:
+
+ - ``--sub-speed=25/23.976`` play frame based subtitles, which have been
+ loaded assuming a framerate of 23.976, at 25 FPS.
+
--sws=<n>
Specify the software scaler algorithm to be used with ``--vf=scale``. This
also affects video output drivers which lack hardware acceleration,
diff --git a/DOCS/tech-overview.txt b/DOCS/tech-overview.txt
index 2037ab653e..e242df1325 100644
--- a/DOCS/tech-overview.txt
+++ b/DOCS/tech-overview.txt
@@ -186,25 +186,31 @@ audio/out/:
why buggy audio drivers can have a bad influence on playback quality.
sub/:
- Contains subtitle rendering, OSD rendering, and parts of subtitle loading.
+ Contains subtitle and OSD rendering.
sub.c/.h is actually the OSD code. It queries dec_sub.c to retrieve
decoded/rendered subtitles. osd_libass.c is the actual implementation of
the OSD text renderer (which uses libass, and takes care of all the tricky
fontconfig/freetype API usage and text layouting).
- Subtitles are loaded either via libass (for .ass), subreader.c (the old
- MPlayer subtitle loader code), or libavformat demuxers. The subtitles are
- then passed to dec_sub.c and the subtitle decoders in sd_*.c. All text
- subtitles are rendered by sd_ass.c. If text subtitles are not in the ASS
- format, subtitle converters are inserted, for example sd_srt.c, which is
- used to convert SRT->ASS. sd_srt.c is also used as general converter for
- text->ASS (to prevent interpretation of text as ASS tags).
-
- subreader.c should eventually go away. It should be replaced by either
- libavformat's demuxers, or by mpv native demuxers for more common formats
- like SRT. See commit message of commit 92ae48d what needs to be done to
- replace subreader.c completely and why.
+ Subtitle loading is now in demux/ instead. demux_libass.c wraps loading
+ .ass subtitles via libass. demux_lavf.c loads most subtitle types via
+ FFmpeg. demux_subreader.c is the old MPlayer code. It's used as last
+ fallback, or to handle some text subtitle types on Libav. (It also can
+ load UTF-16 encoded subtitles without requiring the use of -subcp.)
+ demux_subreader.c should eventually go away (maybe).
+
+ The subtitles are passed to dec_sub.c and the subtitle decoders in sd_*.c
+ as they are demuxed. All text subtitles are rendered by sd_ass.c. If text
+ subtitles are not in the ASS format, subtitle converters are inserted, for
+ example sd_srt.c, which is used to convert SRT->ASS. sd_srt.c is also used
+ as general converter for text->ASS (to prevent interpretation of text as
+ ASS tags).
+
+ Text subtitles can be preloaded, in which case they are read fully as soon
+ as the subtitle is selected, and then effectively stored in an ASS_Track.
+ It's used for external text subtitles, and required to make codepage
+ detection as well as timing postprocessing work.
core/timeline/:
A timeline is the abstraction used by mplayer.c to combine several files
diff --git a/Makefile b/Makefile
index 1460fd7c89..873a5ca64d 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,8 @@ SOURCES-$(DVDREAD) += stream/stream_dvd.c \
SOURCES-$(FTP) += stream/stream_ftp.c
SOURCES-$(HAVE_SYS_MMAN_H) += audio/filter/af_export.c osdep/mmap_anon.c
SOURCES-$(LADSPA) += audio/filter/af_ladspa.c
-SOURCES-$(LIBASS) += sub/ass_mp.c sub/sd_ass.c
+SOURCES-$(LIBASS) += sub/ass_mp.c sub/sd_ass.c \
+ demux/demux_libass.c
SOURCES-$(LIBBLURAY) += stream/stream_bluray.c
SOURCES-$(LIBBS2B) += audio/filter/af_bs2b.c
@@ -169,6 +170,7 @@ SOURCES = talloc.c \
core/av_log.c \
core/av_opts.c \
core/bstr.c \
+ core/charset_conv.c \
core/codecs.c \
core/command.c \
core/cpudetect.c \
@@ -207,7 +209,7 @@ SOURCES = talloc.c \
demux/demux_mf.c \
demux/demux_mkv.c \
demux/demux_mpg.c \
- demux/demux_sub.c \
+ demux/demux_subreader.c \
demux/demux_ts.c \
demux/mp3_hdr.c \
demux/parse_es.c \
@@ -234,13 +236,13 @@ SOURCES = talloc.c \
sub/img_convert.c \
sub/sd_lavc.c \
sub/sd_lavc_conv.c \
+ sub/sd_lavf_srt.c \
sub/sd_microdvd.c \
sub/sd_movtext.c \
sub/sd_spu.c \
sub/sd_srt.c \
sub/spudec.c \
sub/sub.c \
- sub/subreader.c \
video/csputils.c \
video/fmt-conversion.c \
video/image_writer.c \
diff --git a/configure b/configure
index a8ebcce983..3330ab56ee 100755
--- a/configure
+++ b/configure
@@ -292,6 +292,7 @@ Installation directories:
Optional features:
--disable-encoding disable encoding functionality [enable]
+ --disable-libguess disable libguess [autodetect]
--enable-termcap use termcap database for key codes [autodetect]
--enable-termios use termios database for key codes [autodetect]
--disable-iconv disable iconv for encoding conversion [autodetect]
@@ -465,6 +466,7 @@ networking=yes
_winsock2_h=auto
_smb=auto
_libquvi=auto
+_libguess=auto
_joystick=no
_lirc=auto
_lircc=auto
@@ -666,6 +668,8 @@ for ac_option do
--disable-smb) _smb=no ;;
--enable-libquvi) _libquvi=yes ;;
--disable-libquvi) _libquvi=no ;;
+ --enable-libguess) _libguess=yes ;;
+ --disable-libguess) _libguess=no ;;
--enable-joystick) _joystick=yes ;;
--disable-joystick) _joystick=no ;;
--enable-libav) ffmpeg=yes ;;
@@ -1687,6 +1691,21 @@ else
fi
+echocheck "libguess support"
+if test "$_libguess" = auto ; then
+ _libguess=no
+ if pkg_config_add 'libguess >= 1.0' ; then
+ _libguess=yes
+ fi
+fi
+if test "$_libguess" = yes; then
+ def_libguess="#define CONFIG_LIBGUESS 1"
+else
+ def_libguess="#undef CONFIG_LIBGUESS"
+fi
+echores "$_libguess"
+
+
echocheck "Samba support (libsmbclient)"
if test "$_smb" = yes; then
libs_mplayer="$libs_mplayer -lsmbclient"
@@ -3171,6 +3190,7 @@ VF_LAVFI = $vf_lavfi
AF_LAVFI = $af_lavfi
LIBSMBCLIENT = $_smb
LIBQUVI = $_libquvi
+LIBGUESS = $_libguess
LIBTHEORA = $_theora
LIRC = $_lirc
MACOSX_BUNDLE = $_macosx_bundle
@@ -3369,6 +3389,7 @@ $def_inet_pton
$def_networking
$def_smb
$def_libquvi
+$def_libguess
$def_socklen_t
$def_vstream
diff --git a/core/charset_conv.c b/core/charset_conv.c
new file mode 100644
index 0000000000..680c8f83f9
--- /dev/null
+++ b/core/charset_conv.c
@@ -0,0 +1,266 @@
+/*
+ * This file is part of mpv.
+ *
+ * Based on code taken from libass (ISC license), which was originally part
+ * of MPlayer (GPL).
+ * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "config.h"
+
+#include "core/mp_msg.h"
+
+#ifdef CONFIG_ENCA
+#include <enca.h>
+#endif
+
+#ifdef CONFIG_LIBGUESS
+#include <libguess.h>
+#endif
+
+#ifdef CONFIG_ICONV
+#include <iconv.h>
+#endif
+
+#include "charset_conv.h"
+
+// Split the string on ':' into components.
+// out_arr is at least max entries long.
+// Return number of out_arr entries filled.
+static int split_colon(const char *user_cp, int max, bstr *out_arr)
+{
+ if (!user_cp || max < 1)
+ return 0;
+
+ int count = 0;
+ while (1) {
+ const char *next = strchr(user_cp, ':');
+ if (next && max - count > 1) {
+ out_arr[count++] = (bstr){(char *)user_cp, next - user_cp};
+ user_cp = next + 1;
+ } else {
+ out_arr[count++] = (bstr){(char *)user_cp, strlen(user_cp)};
+ break;
+ }
+ }
+ return count;
+}
+
+// Returns true if user_cp implies that calling mp_charset_guess() on the
+// input data is required to determine the real codepage. This is the case
+// if user_cp is not a real iconv codepage, but a magic value that requests
+// for example ENCA charset auto-detection.
+bool mp_charset_requires_guess(const char *user_cp)
+{
+ bstr res[2] = {{0}};
+ split_colon(user_cp, 2, res);
+ return bstrcasecmp0(res[0], "enca") == 0 ||
+ bstrcasecmp0(res[0], "guess") == 0;
+}
+
+#ifdef CONFIG_ENCA
+static const char *enca_guess(bstr buf, const char *language)
+{
+ if (!language || !language[0])
+ language = "__"; // neutral language
+
+ const char *detected_cp = NULL;
+
+ EncaAnalyser analyser = enca_analyser_alloc(language);
+ if (analyser) {
+ enca_set_termination_strictness(analyser, 0);
+ EncaEncoding enc = enca_analyse_const(analyser, buf.start, buf.len);
+ const char *tmp = enca_charset_name(enc.charset, ENCA_NAME_STYLE_ICONV);
+ if (tmp && enc.charset != ENCA_CS_UNKNOWN)
+ detected_cp = tmp;
+ enca_analyser_free(analyser);
+ } else {
+ mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA doesn't know language '%s'\n",
+ language);
+ size_t langcnt;
+ const char **languages = enca_get_languages(&langcnt);
+ mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA supported languages:");
+ for (int i = 0; i < langcnt; i++)
+ mp_msg(MSGT_SUBREADER, MSGL_ERR, " %s", languages[i]);
+ mp_msg(MSGT_SUBREADER, MSGL_ERR, "\n");
+ free(languages);
+ }
+
+ return detected_cp;
+}
+#endif
+
+#ifdef CONFIG_LIBGUESS
+static const char *libguess_guess(bstr buf, const char *language)
+{
+ if (libguess_validate_utf8(buf.start, buf.len))
+ return "UTF-8";
+
+ if (!language || !language[0] || strcmp(language, "help") == 0) {
+ mp_msg(MSGT_SUBREADER, MSGL_ERR, "libguess needs a language: "
+ "japanese taiwanese chinese korean russian arabic turkish "
+ "greek hebrew polish baltic\n");
+ return NULL;
+ }
+
+ return libguess_determine_encoding(buf.start, buf.len, language);
+}
+#endif
+
+// Runs charset auto-detection on the input buffer, and returns the result.
+// If auto-detection fails, NULL is returned.
+// If user_cp doesn't refer to any known auto-detection (for example because
+// it's a real iconv codepage), user_cp is returned without even looking at
+// the buf data.
+const char *mp_charset_guess(bstr buf, const char *user_cp)
+{
+ if (!mp_charset_requires_guess(user_cp))
+ return user_cp;
+
+ bstr params[3] = {{0}};
+ split_colon(user_cp, 3, params);
+
+ bstr type = params[0];
+ char lang[100];
+ snprintf(lang, sizeof(lang), "%.*s", BSTR_P(params[1]));
+ const char *fallback = params[2].start; // last item, already 0-terminated
+
+ const char *res = NULL;
+
+#ifdef CONFIG_ENCA
+ if (bstrcasecmp0(type, "enca") == 0)
+ res = enca_guess(buf, lang);
+#endif
+#ifdef CONFIG_LIBGUESS
+ if (bstrcasecmp0(type, "guess") == 0)
+ res = libguess_guess(buf, lang);
+#endif
+
+ if (res) {
+ mp_msg(MSGT_SUBREADER, MSGL_DBG2, "%.*s detected charset: '%s'\n",
+ BSTR_P(type), res);
+ } else {
+ res = fallback;
+ mp_msg(MSGT_SUBREADER, MSGL_DBG2,
+ "Detection with %.*s failed: fallback to %s\n",
+ BSTR_P(type), res && res[0] ? res : "no conversion");
+ }
+
+ return res;
+}
+
+// Convert the data in buf to UTF-8. The charset argument can be an iconv
+// codepage, a value returned by mp_charset_conv_guess(), or a special value
+// that triggers autodetection of the charset (e.g. using ENCA).
+// The auto-detection is the only difference to mp_iconv_to_utf8().
+// buf: same as mp_iconv_to_utf8()
+// user_cp: iconv codepage, special value, NULL
+// flags: same as mp_iconv_to_utf8()
+// returns: same as mp_iconv_to_utf8()
+bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags)
+{
+ return mp_iconv_to_utf8(buf, mp_charset_guess(buf, user_cp), flags);
+}
+
+// Use iconv to convert buf to UTF-8.
+// Returns buf.start==NULL on error. Returns buf if cp is NULL, or if there is
+// obviously no conversion required (e.g. if cp is "UTF-8").
+// Returns a newly allocated buffer if conversion is done and succeeds. The
+// buffer will be terminated with 0 for convenience (the terminating 0 is not
+// included in the returned length).
+// Free the returned buffer with talloc_free().
+// buf: input data
+// cp: iconv codepage (or NULL)
+// flags: combination of MP_ICONV_* flags
+// returns: buf (no conversion), .start==NULL (error), or allocated buffer
+bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags)
+{
+#ifdef CONFIG_ICONV
+ const char *tocp = "UTF-8";
+
+ if (!cp || !cp[0] || strcasecmp(cp, tocp) == 0)
+ return buf;
+
+ if (strcasecmp(cp, "ASCII") == 0)
+ return buf;
+
+ iconv_t icdsc;
+ if ((icdsc = iconv_open(tocp, cp)) == (iconv_t) (-1)) {
+ if (flags & MP_ICONV_VERBOSE)
+ mp_msg(MSGT_SUBREADER, MSGL_ERR,
+ "Error opening iconv with codepage '%s'\n", cp);
+ goto failure;
+ }
+
+ size_t size = buf.len;
+ size_t osize = size;
+ size_t ileft = size;
+ size_t oleft = size - 1;
+
+ char *outbuf = talloc_size(NULL, osize);
+ char *ip = buf.start;
+ char *op = outbuf;
+
+ while (1) {
+ int clear = 0;
+ size_t rc;
+ if (ileft)
+ rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
+ else {
+ clear = 1; // clear the conversion state and leave
+ rc = iconv(icdsc, NULL, NULL, &op, &oleft);
+ }
+ if (rc == (size_t) (-1)) {
+ if (errno == E2BIG) {
+ size_t offset = op - outbuf;
+ outbuf = talloc_realloc_size(NULL, outbuf, osize + size);
+ op = outbuf + offset;
+ osize += size;
+ oleft += size;
+ } else {
+ if (errno == EINVAL && (flags & MP_ICONV_ALLOW_CUTOFF)) {
+ // This is intended for cases where the input buffer is cut
+ // at a random byte position. If this happens in the middle
+ // of the buffer, it should still be an error. We say it's
+ // fine if the error is within 10 bytes of the end.
+ if (ileft <= 10)
+ break;
+ }
+ if (flags & MP_ICONV_VERBOSE) {
+ mp_msg(MSGT_SUBREADER, MSGL_ERR,
+ "Error recoding text with codepage '%s'\n", cp);
+ }
+ talloc_free(outbuf);
+ iconv_close(icdsc);
+ goto failure;
+ }
+ } else if (clear)
+ break;
+ }
+
+ iconv_close(icdsc);
+
+ outbuf[osize - oleft - 1] = 0;
+ return (bstr){outbuf, osize - oleft - 1};
+#endif
+
+failure:
+ return (bstr){0};
+}
diff --git a/core/charset_conv.h b/core/charset_conv.h
new file mode 100644
index 0000000000..00a2658da3
--- /dev/null
+++ b/core/charset_conv.h
@@ -0,0 +1,17 @@
+#ifndef MP_CHARSET_CONV_H
+#define MP_CHARSET_CONV_H
+
+#include <stdbool.h>
+#include "core/bstr.h"
+
+enum {
+ MP_ICONV_VERBOSE = 1, // print errors instead of failing silently
+ MP_ICONV_ALLOW_CUTOFF = 2, // allow partial input data
+};
+
+bool mp_charset_requires_guess(const char *user_cp);
+const char *mp_charset_guess(bstr buf, const char *user_cp);
+bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags);
+bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags);
+
+#endif
diff --git a/core/command.c b/core/command.c
index 4da0653425..c39bb3c16d 100644
--- a/core/command.c
+++ b/core/command.c
@@ -2281,7 +2281,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
case MP_CMD_SUB_ADD:
if (sh_video) {
- mp_add_subtitles(mpctx, cmd->args[0].v.s, sh_video->fps, 0);
+ mp_add_subtitles(mpctx, cmd->args[0].v.s, 0);
}
break;
@@ -2296,8 +2296,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
struct track *sub = mp_track_by_tid(mpctx, STREAM_SUB, cmd->args[0].v.i);
if (sh_video && sub && sub->is_external && sub->external_filename)
{
- struct track *nsub = mp_add_subtitles(mpctx, sub->external_filename,
- sh_video->fps, 0);
+ struct track *nsub = mp_add_subtitles(mpctx, sub->external_filename, 0);
if (nsub) {
mp_remove_track(mpctx, sub);
mp_switch_track(mpctx, nsub->type, nsub);
diff --git a/core/encode_lavc.c b/core/encode_lavc.c
index b09ecaa1ac..9fada7de58 100644
--- a/core/encode_lavc.c
+++ b/core/encode_lavc.c
@@ -404,7 +404,7 @@ static void encode_2pass_prepare(struct encode_lavc_context *ctx,
set_to_avdictionary(dictp, "flags", "-pass2");
} else {
struct bstr content = stream_read_complete(*bytebuf, NULL,
- 1000000000, 1);
+ 1000000000);
if (content.start == NULL) {
mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not read '%s', "
"disabling 2-pass encoding at pass 1\n",
diff --git a/core/input/input.c b/core/input/input.c
index 2d7569c8e9..dfa7d1e5b4 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -1737,7 +1737,7 @@ static int parse_config_file(struct input_ctx *ictx, char *file, bool warn)
mp_msg(MSGT_INPUT, MSGL_ERR, "Can't open input config file %s.\n", file);
return 0;
}
- bstr res = stream_read_complete(s, NULL, 1000000, 0);
+ bstr res = stream_read_complete(s, NULL, 1000000);
free_stream(s);
mp_msg(MSGT_INPUT, MSGL_V, "Parsing input config file %s\n", file);
int n_binds = parse_config(ictx, false, res, file);
diff --git a/core/mp_core.h b/core/mp_core.h
index 98a92cbea4..0bd6ecda15 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -290,8 +290,7 @@ extern int forced_subs_only;
void uninit_player(struct MPContext *mpctx, unsigned int mask);
void reinit_audio_chain(struct MPContext *mpctx);
double playing_audio_pts(struct MPContext *mpctx);
-struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
- float fps, int noerr);
+struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename, int noerr);
int reinit_video_chain(struct MPContext *mpctx);
int reinit_video_filters(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);
diff --git a/core/mplayer.c b/core/mplayer.c
index d28b5fdc4c..3cdd83021d 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -71,7 +71,6 @@
#include "core/mplayer.h"
#include "core/m_property.h"
-#include "sub/subreader.h"
#include "sub/find_subfiles.h"
#include "sub/dec_sub.h"
#include "sub/sd.h"
@@ -197,9 +196,6 @@ static const char av_desync_help_text[] = _(
static void reset_subtitles(struct MPContext *mpctx);
static void reinit_subs(struct MPContext *mpctx);
-static struct track *open_external_file(struct MPContext *mpctx, char *filename,
- char *demuxer_name, int stream_cache,
- enum stream_type filter);
static double get_relative_time(struct MPContext *mpctx)
{
@@ -982,6 +978,9 @@ static struct track *add_stream_track(struct MPContext *mpctx,
};
MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
+ if (stream->type == STREAM_SUB)
+ track->preloaded = !!stream-&g