summaryrefslogtreecommitdiffstats
path: root/core/mplayer.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-07 21:18:24 +0100
committerwm4 <wm4@nowhere>2012-12-10 23:27:46 +0100
commit7288834a4c2945729f5a261cba2c007683754b7b (patch)
tree133075a0c353463af4d12e34eab053159aedc1ad /core/mplayer.c
parentdf28eac342ec649068cddd03717f00e81790c523 (diff)
downloadmpv-7288834a4c2945729f5a261cba2c007683754b7b.tar.bz2
mpv-7288834a4c2945729f5a261cba2c007683754b7b.tar.xz
sub: use ffmpeg decoder for DVD subs
Do this only if demux_lavf is used. Using demux_mpg and the ffmpeg DVD subtitle decoder doesn't work. The problem is probably that demux_mpg doesn't join split sub packets, while demux_lavf does. The internal DVD sub decoder (spudec.c) can, while ffmpeg's dvdsub can't. I do not know whether this is the actual problem. If DVD playback is used, create "fake" vobsub-style text extradata (like .idx files) to pass resolution and palette information to the ffmpeg decoder. We could use the "palette" AVOpt and avcodec_set_dimensions() instead, but it's actually simpler this way. Note that the decoder doesn't parse any other fields. Also note that DVD playback still uses demux_mpg by default, so this code is inactive unless -demuxer lavf is specified. This is mainly preparation for the case when we manage to get rid of demux_mpg for DVD playback.
Diffstat (limited to 'core/mplayer.c')
-rw-r--r--core/mplayer.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/core/mplayer.c b/core/mplayer.c
index 04ea0e2597..4eb4ff0e23 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -1841,6 +1841,9 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
}
double duration = d_sub->first->duration;
len = ds_get_packet_sub(d_sub, &packet);
+ mp_dbg(MSGT_CPLAYER, MSGL_V, "Sub: c_pts=%5.3f s_pts=%5.3f "
+ "duration=%5.3f len=%d\n", curpts_s, subpts_s, duration,
+ len);
if (type == 'm') {
if (len < 2)
continue;
@@ -1927,6 +1930,45 @@ static float timing_sleep(struct MPContext *mpctx, float time_frame)
return time_frame;
}
+static void set_dvdsub_fake_extradata(struct sh_sub *sh_sub, struct stream *st,
+ struct sh_video *sh_video)
+{
+#ifdef CONFIG_DVDREAD
+ if (st->type != STREAMTYPE_DVD || !sh_video)
+ return;
+
+ struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
+ csp.int_bits_in = 8;
+ csp.int_bits_out = 8;
+ float cmatrix[3][4];
+ mp_get_yuv2rgb_coeffs(&csp, cmatrix);
+
+ int width = sh_video->disp_w;
+ int height = sh_video->disp_h;
+ int *palette = ((dvd_priv_t *)st->priv)->cur_pgc->palette;
+
+ char *s = NULL;
+ s = talloc_asprintf_append(s, "size: %dx%d\n", width, height);
+ s = talloc_asprintf_append(s, "palette: ");
+ for (int i = 0; i < 16; i++) {
+ int color = palette[i];
+ int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff};
+ mp_map_int_color(cmatrix, 8, c);
+ color = (c[2] << 16) | (c[1] << 8) | c[0];
+
+ if (i != 0)
+ talloc_asprintf_append(s, ", ");
+ s = talloc_asprintf_append(s, "%06x", color);
+ }
+ s = talloc_asprintf_append(s, "\n");
+
+ free(sh_sub->extradata);
+ sh_sub->extradata = strdup(s);
+ sh_sub->extradata_len = strlen(s);
+ talloc_free(s);
+#endif
+}
+
static void reinit_subs(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
@@ -1968,7 +2010,11 @@ static void reinit_subs(struct MPContext *mpctx)
#endif
vo_osd_changed(OSDTYPE_SUBTITLE);
} else if (track->stream) {
- if (mpctx->sh_sub->type == 'v')
+ struct stream *s = track->demuxer ? track->demuxer->stream : NULL;
+ if (s && s->type == STREAMTYPE_DVD)
+ set_dvdsub_fake_extradata(mpctx->sh_sub, s, mpctx->sh_video);
+ if (mpctx->sh_sub->type == 'v' && track->demuxer
+ && track->demuxer->type == DEMUXER_TYPE_MPEG_PS)
init_vo_spudec(mpctx);
else
sub_init(mpctx->sh_sub, mpctx->osd);