summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst15
-rw-r--r--Makefile8
-rw-r--r--audio/decode/ad_lavc.c7
-rwxr-xr-xconfigure12
-rw-r--r--core/av_common.c20
-rw-r--r--core/av_common.h2
-rw-r--r--core/cfg-mplayer.h17
-rw-r--r--core/command.c80
-rw-r--r--core/defaultopts.c2
-rw-r--r--core/mp_core.h17
-rw-r--r--core/mplayer.c415
-rw-r--r--core/mplayer.h3
-rw-r--r--core/options.h10
-rw-r--r--demux/demux.c37
-rw-r--r--demux/demux.h9
-rw-r--r--demux/demux_lavf.c7
-rw-r--r--demux/demux_mpg.c2
-rw-r--r--demux/demux_sub.c38
-rw-r--r--demux/stheader.h5
-rw-r--r--sub/ass_mp.c129
-rw-r--r--sub/ass_mp.h9
-rw-r--r--sub/dec_sub.c370
-rw-r--r--sub/dec_sub.h38
-rw-r--r--sub/find_sub.c174
-rw-r--r--sub/find_subfiles.c9
-rw-r--r--sub/osd_libass.c20
-rw-r--r--sub/sd.h74
-rw-r--r--sub/sd_ass.c247
-rw-r--r--sub/sd_lavc.c49
-rw-r--r--sub/sd_lavc_conv.c165
-rw-r--r--sub/sd_microdvd.c346
-rw-r--r--sub/sd_movtext.c55
-rw-r--r--sub/sd_spu.c102
-rw-r--r--sub/sd_srt.c (renamed from sub/subassconvert.c)277
-rw-r--r--sub/spudec.c33
-rw-r--r--sub/spudec.h4
-rw-r--r--sub/sub.c64
-rw-r--r--sub/sub.h26
-rw-r--r--sub/subassconvert.h27
-rw-r--r--sub/subreader.c334
-rw-r--r--sub/subreader.h24
-rw-r--r--video/decode/vd_lavc.c13
42 files changed, 1770 insertions, 1525 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index f1aea822e7..8239375079 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -93,13 +93,11 @@
- ``--aspect=16:9`` or ``--aspect=1.7777``
--ass, --no-ass
- Render ASS subtitles natively, and convert text subtitles in other formats
- to ASS internally (enabled by default).
+ Render ASS subtitles natively (enabled by default).
- If ``--no-ass`` is specified, all subtitles are converted to plain text
- internally. All tags and style declarations are stripped and ignored. The
- subtitle renderer uses the font style as specified by the ``--sub-text-``
- options instead.
+ If ``--no-ass`` is specified, all tags and style declarations are stripped
+ and ignored on display. The subtitle renderer uses the font style as
+ specified by the ``--sub-text-`` options instead.
*NOTE*: Using ``--no-ass`` may lead to incorrect or completely broken
rendering of ASS/SSA subtitles. It can sometimes be useful to forcibly
@@ -1287,7 +1285,10 @@
See ``quit_watch_later`` input command.
--no-sub
- Disables display of internal and external subtitles.
+ Don't select any subtitle when the file is loaded.
+
+--no-sub-visibility
+ Disable display of subtitles, but still select and decode them.
--no-video
Do not play video. With some demuxers this may not work. In those cases
diff --git a/Makefile b/Makefile
index 4671682cd7..ff8eb31341 100644
--- a/Makefile
+++ b/Makefile
@@ -206,6 +206,7 @@ SOURCES = talloc.c \
demux/demux_mf.c \
demux/demux_mkv.c \
demux/demux_mpg.c \
+ demux/demux_sub.c \
demux/demux_ts.c \
demux/mp3_hdr.c \
demux/parse_es.c \
@@ -228,13 +229,16 @@ SOURCES = talloc.c \
stream/url.c \
sub/dec_sub.c \
sub/draw_bmp.c \
- sub/find_sub.c \
sub/find_subfiles.c \
sub/img_convert.c \
sub/sd_lavc.c \
+ sub/sd_lavc_conv.c \
+ sub/sd_microdvd.c \
+ sub/sd_movtext.c \
+ sub/sd_spu.c \
+ sub/sd_srt.c \
sub/spudec.c \
sub/sub.c \
- sub/subassconvert.c \
sub/subreader.c \
video/csputils.c \
video/fmt-conversion.c \
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index 8abc0a6035..b5a4ee1ef8 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -402,13 +402,10 @@ static int decode_new_packet(struct sh_audio *sh)
}
AVPacket pkt;
- av_init_packet(&pkt);
+ mp_set_av_packet(&pkt, mpkt);
pkt.data = start;
pkt.size = insize;
- if (mpkt && mpkt->avpacket) {
- pkt.side_data = mpkt->avpacket->side_data;
- pkt.side_data_elems = mpkt->avpacket->side_data_elems;
- }
+
if (pts != MP_NOPTS_VALUE && !packet_already_used) {
sh->pts = pts;
sh->pts_bytes = 0;
diff --git a/configure b/configure
index e6b77f4595..0b0913bf8c 100755
--- a/configure
+++ b/configure
@@ -2684,6 +2684,17 @@ else
fi
+echocheck "libavcodec AV_CODEC_PROP_TEXT_SUB API"
+_avcodec_has_text_flag_api=no
+statement_check libavcodec/avcodec.h 'int x = AV_CODEC_PROP_TEXT_SUB' && _avcodec_has_text_flag_api=yes
+if test "$_avcodec_has_text_flag_api" = yes ; then
+ def_avcodec_has_text_flag_api='#define HAVE_AV_CODEC_PROP_TEXT_SUB 1'
+else
+ def_avcodec_has_text_flag_api='#define HAVE_AV_CODEC_PROP_TEXT_SUB 0'
+fi
+echores "$_avcodec_has_text_flag_api"
+
+
echocheck "libavutil QP API"
_avutil_has_qp_api=no
statement_check libavutil/frame.h 'av_frame_get_qp_table(NULL, NULL, NULL)' && _avutil_has_qp_api=yes
@@ -3268,6 +3279,7 @@ $def_zlib
$def_avutil_has_refcounting
$def_avutil_has_qp_api
+$def_avcodec_has_text_flag_api
$def_libpostproc
$def_libavdevice
$def_libavfilter
diff --git a/core/av_common.c b/core/av_common.c
index 5e6c8a4352..a4dc525aa9 100644
--- a/core/av_common.c
+++ b/core/av_common.c
@@ -18,8 +18,10 @@
#include <assert.h>
#include <libavutil/common.h>
+#include <libavcodec/avcodec.h>
#include "core/mp_talloc.h"
+#include "demux/demux_packet.h"
#include "av_common.h"
#include "codecs.h"
@@ -58,6 +60,24 @@ void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
avctx->bits_per_coded_sample = st->bits_per_coded_sample;
}
+// Set dst from mpkt. Note that dst is not refcountable.
+// mpkt can be NULL to generate empty packets (used to flush delayed data).
+// Does not set pts or duration fields.
+void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt)
+{
+ av_init_packet(dst);
+ dst->data = mpkt ? mpkt->buffer : NULL;
+ dst->size = mpkt ? mpkt->len : 0;
+ /* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info
+ * from demuxer. */
+ if (mpkt && mpkt->keyframe)
+ dst->flags |= AV_PKT_FLAG_KEY;
+ if (mpkt && mpkt->avpacket) {
+ dst->side_data = mpkt->avpacket->side_data;
+ dst->side_data_elems = mpkt->avpacket->side_data_elems;
+ }
+}
+
void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type)
{
AVCodec *cur = NULL;
diff --git a/core/av_common.h b/core/av_common.h
index 25593ed3d0..2fa8f127b0 100644
--- a/core/av_common.h
+++ b/core/av_common.h
@@ -22,8 +22,10 @@
#include <libavcodec/avcodec.h>
struct mp_decoder_list;
+struct demux_packet;
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
+void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt);
void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type);
int mp_codec_to_av_codec_id(const char *codec);
const char *mp_codec_from_av_codec_id(int codec_id);
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 5a2c32e0d0..c29d4c4060 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -472,17 +472,18 @@ const m_option_t common_opts[] = {
OPT_STRINGLIST("sub", sub_name, 0),
OPT_PATHLIST("sub-paths", sub_paths, 0),
- {"subcp", &sub_cp, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"sub-delay", &sub_delay, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
- {"subfps", &sub_fps, CONF_TYPE_FLOAT, 0, 0.0, 10.0, NULL},
+ OPT_STRING("subcp", sub_cp, 0),
+ OPT_FLOAT("sub-delay", sub_delay, 0),
+ OPT_FLOAT("subfps", sub_fps, 0),
OPT_FLAG("autosub", sub_auto, 0),
+ OPT_FLAG("sub-visibility", sub_visibility, 0),
OPT_FLAG("sub-forced-only", forced_subs_only, 0),
// enable Closed Captioning display
- {"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL},
- {"sub-no-text-pp", &sub_no_text_pp, CONF_TYPE_FLAG, 0, 0, 1, NULL},
- {"autosub-match", &sub_match_fuzziness, CONF_TYPE_CHOICE, 0,
- M_CHOICES(({"exact", 0}, {"fuzzy", 1}, {"all", 2}))},
- {"sub-pos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+ OPT_FLAG_CONSTANTS("overlapsub", suboverlap_enabled, 0, 0, 2),
+ OPT_FLAG_STORE("sub-no-text-pp", sub_no_text_pp, 0, 1),
+ OPT_CHOICE("autosub-match", sub_match_fuzziness, 0,
+ ({"exact", 0}, {"fuzzy", 1}, {"all", 2})),
+ OPT_INTRANGE("sub-pos", sub_pos, 0, 0, 100),
OPT_FLOATRANGE("sub-gauss", sub_gauss, 0, 0.0, 3.0),
OPT_FLAG("sub-gray", sub_gray, 0),
OPT_FLAG("ass", ass_enabled, 0),
diff --git a/core/command.c b/core/command.c
index 3ee8f39c3d..416fbcd06a 100644
--- a/core/command.c
+++ b/core/command.c
@@ -50,7 +50,6 @@
#include "audio/filter/af.h"
#include "video/decode/dec_video.h"
#include "audio/decode/dec_audio.h"
-#include "sub/spudec.h"
#include "core/path.h"
#include "sub/ass_mp.h"
#include "stream/tv.h"
@@ -1273,11 +1272,12 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
static int mp_property_sub_delay(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
+ struct MPOpts *opts = &mpctx->opts;
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_PRINT:
- *(char **)arg = format_delay(sub_delay);
+ *(char **)arg = format_delay(opts->sub_delay);
return M_PROPERTY_OK;
}
return mp_property_generic_option(prop, action, arg, mpctx);
@@ -1286,56 +1286,16 @@ static int mp_property_sub_delay(m_option_t *prop, int action, void *arg,
static int mp_property_sub_pos(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
+ struct MPOpts *opts = &mpctx->opts;
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_PRINT) {
- *(char **)arg = talloc_asprintf(NULL, "%d/100", sub_pos);
+ *(char **)arg = talloc_asprintf(NULL, "%d/100", opts->sub_pos);
return M_PROPERTY_OK;
}
return property_osd_helper(prop, action, arg, mpctx);
}
-/// Subtitle visibility (RW)
-static int mp_property_sub_visibility(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
-{
- struct MPOpts *opts = &mpctx->opts;
-
- if (!mpctx->sh_video)
- return M_PROPERTY_UNAVAILABLE;
-
- switch (action) {
- case M_PROPERTY_SET:
- opts->sub_visibility = *(int *)arg;
- vo_osd_changed(OSDTYPE_SUBTITLE);
- if (vo_spudec)
- vo_osd_changed(OSDTYPE_SPU);
- return M_PROPERTY_OK;
- case M_PROPERTY_GET:
- *(int *)arg = opts->sub_visibility;
- return M_PROPERTY_OK;
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
-}
-
-/// Show only forced subtitles (RW)
-static int mp_property_sub_forced_only(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
-{
- struct MPOpts *opts = &mpctx->opts;
-
- if (!vo_spudec)
- return M_PROPERTY_UNAVAILABLE;
-
- if (action == M_PROPERTY_SET) {
- opts->forced_subs_only = *(int *)arg;
- spudec_set_forced_subs_only(vo_spudec, opts->forced_subs_only);
- return M_PROPERTY_OK;
- }
- return mp_property_generic_option(prop, action, arg, mpctx);
-}
-
-
#ifdef CONFIG_TV
static tvi_handle_t *get_tvh(struct MPContext *mpctx)
@@ -1513,9 +1473,8 @@ static const m_option_t mp_properties[] = {
M_OPTION_PROPERTY_CUSTOM("sid", mp_property_sub),
M_OPTION_PROPERTY_CUSTOM("sub-delay", mp_property_sub_delay),
M_OPTION_PROPERTY_CUSTOM("sub-pos", mp_property_sub_pos),
- { "sub-visibility", mp_property_sub_visibility, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
- M_OPTION_PROPERTY_CUSTOM("sub-forced-only", mp_property_sub_forced_only),
+ M_OPTION_PROPERTY_CUSTOM("sub-visibility", property_osd_helper),
+ M_OPTION_PROPERTY_CUSTOM("sub-forced-only", property_osd_helper),
M_OPTION_PROPERTY_CUSTOM("sub-scale", property_osd_helper),
#ifdef CONFIG_ASS
M_OPTION_PROPERTY_CUSTOM("ass-use-margins", property_osd_helper),
@@ -1991,26 +1950,18 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
case MP_CMD_SUB_STEP:
- if (sh_video) {
- int movement = cmd->args[0].v.i;
- struct track *track = mpctx->current_track[STREAM_SUB];
- bool available = false;
- if (track && track->subdata) {
- available = true;
- step_sub(track->subdata, mpctx->video_pts, movement);
- }
#ifdef CONFIG_ASS
- struct ass_track *ass_track = sub_get_ass_track(mpctx->osd);
+ if (mpctx->osd->dec_sub) {
+ int movement = cmd->args[0].v.i;
+ struct ass_track *ass_track = sub_get_ass_track(mpctx->osd->dec_sub);
if (ass_track) {
- available = true;
- sub_delay += ass_step_sub(ass_track,
- (mpctx->video_pts + sub_delay) * 1000 + .5, movement) / 1000.;
- }
-#endif
- if (available)
set_osd_tmsg(mpctx, OSD_MSG_SUB_DELAY, osdl, osd_duration,
- "Sub delay: %d ms", ROUND(sub_delay * 1000));
+ "Sub delay: %d ms", ROUND(opts->sub_delay * 1000));
+ double cur = (mpctx->video_pts + opts->sub_delay) * 1000 + .5;
+ opts->sub_delay += ass_step_sub(ass_track, cur, movement) / 1000.;
+ }
}
+#endif
break;
case MP_CMD_OSD: {
@@ -2194,7 +2145,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
if (tv_channel_list) {
set_osd_tmsg(mpctx, OSD_MSG_TV_CHANNEL, osdl, osd_duration,
"Channel: %s", tv_channel_current->name);
- //vo_osd_changed(OSDTYPE_SUBTITLE);
}
}
#ifdef CONFIG_PVR
@@ -2232,7 +2182,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
if (tv_channel_list) {
set_osd_tmsg(mpctx, OSD_MSG_TV_CHANNEL, osdl, osd_duration,
"Channel: %s", tv_channel_current->name);
- //vo_osd_changed(OSDTYPE_SUBTITLE);
}
}
#ifdef CONFIG_PVR
@@ -2265,7 +2214,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
if (tv_channel_list) {
set_osd_tmsg(mpctx, OSD_MSG_TV_CHANNEL, osdl, osd_duration,
"Channel: %s", tv_channel_current->name);
- //vo_osd_changed(OSDTYPE_SUBTITLE);
}
}
#ifdef CONFIG_PVR
diff --git a/core/defaultopts.c b/core/defaultopts.c
index 5f6521ebfb..a8a6b26930 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -74,6 +74,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.sub_id = -1,
.audio_display = 1,
.sub_visibility = 1,
+ .sub_pos = 100,
.extension_parsing = 1,
.audio_output_channels = MP_CHMAP_INIT_STEREO,
.audio_output_format = -1, // AF_FORMAT_UNKNOWN
@@ -89,6 +90,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.ass_vsfilter_aspect_compat = 1,
.ass_style_override = 1,
.use_embedded_fonts = 1,
+ .suboverlap_enabled = 1,
.hwdec_codecs = "all",
diff --git a/core/mp_core.h b/core/mp_core.h
index 9e61c8ffa3..d7aa42e38d 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -22,8 +22,6 @@
#include <stdbool.h>
#include "core/options.h"
-#include "sub/subreader.h"
-#include "sub/find_subfiles.h"
#include "audio/mixer.h"
#include "demux/demux.h"
@@ -33,7 +31,6 @@
#define INITIALIZED_AO 2
#define INITIALIZED_VOL 4
#define INITIALIZED_GETCH2 8
-#define INITIALIZED_SPUDEC 32
#define INITIALIZED_STREAM 64
#define INITIALIZED_DEMUXER 512
#define INITIALIZED_ACODEC 1024
@@ -106,15 +103,9 @@ struct track {
// Invariant: (!demuxer && !stream) || stream->demuxer == demuxer
struct sh_stream *stream;
- // NOTE: demuxer subtitles, i.e. if stream!=NULL, do not use the following
- // fields. The data is stored in stream->sub this case.
-
- // External text subtitle using libass subtitle renderer.
- // The sh_sub is a dummy and doesn't belong to a demuxer.
- struct sh_sub *sh_sub;
-
- // External text subtitle using non-libass subtitle renderer.
- struct sub_data *subdata;
+ // For external subtitles, which are read fully on init. Do not attempt
+ // to read packets from them.
+ bool preloaded;
};
enum {
@@ -129,7 +120,6 @@ typedef struct MPContext {
struct osd_state *osd;
struct mp_osd_msg *osd_msg_stack;
char *terminal_osd_text;
- subtitle subs; // subtitle list used when reading subtitles from demuxer
int add_osd_seek_info; // bitfield of enum mp_osd_seek_info
double osd_visible; // for the osd bar only
@@ -299,7 +289,6 @@ extern int forced_subs_only;
void uninit_player(struct MPContext *mpctx, unsigned int mask);
void reinit_audio_chain(struct MPContext *mpctx);
-void init_vo_spudec(struct MPContext *mpctx);
double playing_audio_pts(struct MPContext *mpctx);
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
float fps, int noerr);
diff --git a/core/mplayer.c b/core/mplayer.c
index b5123a3d41..baae55b581 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -74,6 +74,7 @@
#include "sub/subreader.h"
#include "sub/find_subfiles.h"
#include "sub/dec_sub.h"
+#include "sub/sd.h"
#include "core/mp_osd.h"
#include "video/out/vo.h"
@@ -94,8 +95,6 @@
#include "core/codecs.h"
-#include "sub/spudec.h"
-
#include "osdep/getch2.h"
#include "osdep/timer.h"
@@ -282,10 +281,6 @@ static void print_stream(struct MPContext *mpctx, struct track *t)
if (t->title)
mp_msg(MSGT_CPLAYER, MSGL_INFO, " '%s'", t->title);
const char *codec = s ? s->codec : NULL;
- if (!codec && t->sh_sub) // external subs hack
- codec = t->sh_sub->gsh->codec;
- if (!codec && t->subdata)
- codec = t->subdata->codec;
mp_msg(MSGT_CPLAYER, MSGL_INFO, " (%s)", codec ? codec : "<unknown>");
if (t->is_external)
mp_msg(MSGT_CPLAYER, MSGL_INFO, " (external)");
@@ -462,8 +457,10 @@ static void uninit_subs(struct demuxer *demuxer)
{
for (int i = 0; i < MAX_S_STREAMS; i++) {
struct sh_sub *sh = demuxer->s_streams[i];
- if (sh && sh->initialized)
- sub_uninit(sh);
+ if (sh) {
+ sub_destroy(sh->dec_sub);
+ sh->dec_sub = NULL;
+ }
}
}
@@ -485,14 +482,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_SUB) {
mpctx->initialized_flags &= ~INITIALIZED_SUB;
- struct track *track = mpctx->current_track[STREAM_SUB];
- // One of these was active; they can't be both active.
- assert(!(mpctx->sh_sub && track && track->sh_sub));
if (mpctx->sh_sub)
- sub_switchoff(mpctx->sh_sub, mpctx->osd);
- if (track && track->sh_sub)
- sub_switchoff(track->sh_sub, mpctx->osd);
+ sub_reset(mpctx->sh_sub->dec_sub);
cleanup_demux_stream(mpctx, STREAM_SUB);
+ mpctx->osd->dec_sub = NULL;
reset_subtitles(mpctx);
}
@@ -555,12 +548,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
getch2_disable();
}
- if (mask & INITIALIZED_SPUDEC) {
- mpctx->initialized_flags &= ~INITIALIZED_SPUDEC;
- spudec_free(vo_spudec);
- vo_spudec = NULL;
- }
-
if (mask & INITIALIZED_VOL) {
mpctx->initialized_flags &= ~INITIALIZED_VOL;
if (mpctx->mixer.ao) {
@@ -1048,96 +1035,67 @@ static void add_dvd_tracks(struct MPContext *mpctx)
#endif
}
+#ifdef CONFIG_ASS
+static int free_sub_data(void *ptr)
+{
+ struct sh_sub *sh_sub = *(struct sh_sub **)ptr;
+ if (sh_sub->track)
+ ass_free_track(sh_sub->track);
+ talloc_free(sh_sub->sub_data);
+ return 1;
+}
+#endif
+
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
float fps, int noerr)
{
struct MPOpts *opts = &mpctx->opts;
+ struct ass_track *asst = NULL;
sub_data *subd = NULL;
- struct sh_sub *sh = NULL;
if (filename == NULL)
return NULL;
- if (opts->ass_enabled) {
+ // Note: no text subtitles without libass. This is mainly because sd_ass is
+ // used for rendering. Even when showing subtitles with term-osd, going
+ // through sd_ass makes the code much simpler, as sd_ass can handle all
+ // the weird special-cases.
#ifdef CONFIG_ASS
- struct ass_track *asst = mp_ass_read_stream(mpctx->ass_library,
- filename, sub_cp);
- bool is_native_ass = asst;
- const char *codec = NULL;
- if (!asst) {
- subd = sub_read_file(filename, fps, &mpctx->opts);
- if (subd) {
- codec = subd->codec;
- asst = mp_ass_read_subdata(mpctx->ass_library, opts, subd, fps);
- talloc_free(subd);
- subd = NULL;
- }
- }
- if (asst) {
- sh = sd_ass_create_from_track(asst, is_native_ass, opts);
- if (codec)
- sh->gsh->codec = codec;
- }
-#endif
- } else
+ asst = mp_ass_read_stream(mpctx->ass_library, filename, opts->sub_cp);
+ if (!asst)
subd = sub_read_file(filename, fps, &mpctx->opts);
-
-
- if (!sh && !subd) {
- struct track *ext = open_external_file(mpctx, filename, NULL, 0,
- STREAM_SUB);
- if (ext)
- return ext;
- mp_tmsg(MSGT_CPLAYER, noerr ? MSGL_WARN : MSGL_ERR,
- "Cannot load subtitles: %s\n", filename);
- return NULL;
- }
-
- struct track *track = talloc_ptrtype(NULL, track);
- *track = (struct track) {
- .type = STREAM_SUB,
- .title = talloc_strdup(track, filename),
- .user_tid = find_new_tid(mpctx, STREAM_SUB),
- .demuxer_id = -1,
- .is_external = true,
- .sh_sub = talloc_steal(track, sh),
- .subdata = talloc_steal(track, subd),
- .external_filename = talloc_strdup(track, filename),
- };
- MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
- return track;
-}
-
-void init_vo_spudec(struct MPContext *mpctx)
-{
- uninit_player(mpctx, INITIALIZED_SPUDEC);
- unsigned width, height;
-
- // we currently can't work without video stream
- if (!mpctx->sh_video)
- return;
-
- width = mpctx->sh_video->disp_w;
- height = mpctx->sh_video->disp_h;
-
-#ifdef CONFIG_DVDREAD
- if (vo_spudec == NULL && mpctx->stream->type == STREAMTYPE_DVD) {
- vo_spudec = spudec_new_scaled(((dvd_priv_t *)(mpctx->stream->priv))->
- cur_pgc->palette, width, height, NULL, 0);
+ if (asst || subd) {
+ struct demuxer *d = new_sub_pseudo_demuxer(opts);
+ assert(d->num_streams == 1);
+ struct sh_stream *s = d->streams[0];
+ assert(s->type == STREAM_SUB);
+
+ s->codec = asst ? "ass" : subd->codec;
+ s->sub->track = asst;
+ s->sub->sub_data = subd;
+
+ struct sh_sub **pptr = talloc(d, struct sh_sub*);
+ *pptr = s->sub;
+ talloc_set_destructor(pptr, free_sub_data);
+
+ struct track *t = add_stream_track(mpctx, s, false);
+ t->is_external = true;
+ t->preloaded = true;
+ t->title = talloc_strdup(t, filename);
+ t->external_filename = talloc_strdup(t, filename);
+ MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, d);
+ return t;
}
#endif
- if (vo_spudec == NULL && mpctx->sh_sub) {
- sh_sub_t *sh = mpctx->sh_sub;
- vo_spudec = spudec_new_scaled(NULL, width, height, sh->extradata,
- sh->extradata_len);
- }
+ // Used with libavformat subtitles.
+ struct track *ext = open_external_file(mpctx, filename, NULL, 0, STREAM_SUB);
+ if (ext)
+ return ext;
- if (vo_spudec != NULL) {
- mpctx->initialized_flags |= INITIALIZED_SPUDEC;
- mp_property_do("sub-forced-only", M_PROPERTY_SET,
- &mpctx->opts.forced_subs_only, mpctx);
- }
+ mp_tmsg(MSGT_CPLAYER, noerr ? MSGL_WARN : MSGL_ERR,
+ "Cannot load subtitles: %s\n", filename);
+ return NULL;
}
int mp_get_cache_percent(struct MPContext *mpctx)
@@ -1433,7 +1391,7 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx)
if (mpctx->osd_visible && now >= mpctx->osd_visible) {
mpctx->osd_visible = 0;
mpctx->osd->progbar_type = -1; // disable
- vo_osd_changed(OSDTYPE_PROGBAR);
+ osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
}
if (mpctx->osd_function_visible && now >= mpctx->osd_function_visible) {
mpctx->osd_function_visible = 0;
@@ -1492,7 +1450,7 @@ void set_osd_bar(struct MPContext *mpctx, int type, const char *name,
mpctx->osd->progbar_type = type;
mpctx->osd->progbar_value = (val - min) / (max - min);
mpctx->osd->progbar_num_stops = 0;
- vo_osd_changed(OSDTYPE_PROGBAR);
+ osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
return;
}
@@ -1509,7 +1467,7 @@ static void update_osd_bar(struct MPContext *mpctx, int type,
float new_value = (val - min) / (max - min);
if (new_value != mpctx->osd->progbar_value) {
mpctx->osd->progbar_value = new_value;
- vo_osd_changed(OSDTYPE_PROGBAR);
+ osd_changed(mpctx->osd, OSDTYPE_PROGBAR);
}
}
}
@@ -1545,25 +1503,20 @@ void set_osd_function(struct MPContext *mpctx, int osd_function)
/**
* \brief Display text subtitles on the OSD
*/
-void set_osd_subtitle(struct MPContext *mpctx, subtitle *subs)
-{
- int i;
- vo_sub = subs;
- vo_osd_changed(OSDTYPE_SUBTITLE);
- if (!mpctx->sh_video) {
- // reverse order, since newest set_osd_msg is displayed first
- for (i = SUB_MAX_TEXT - 1; i >= 0; i--) {
- if (!subs || i >= subs->lin