From 96c17fe68b12104269f70b113d757fbc67b5ed1f Mon Sep 17 00:00:00 2001 From: reimar Date: Sat, 10 Jul 2010 13:45:09 +0000 Subject: subs: Add support for PGS subtitle decoding via libavcodec git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31665 b3059339-0415-0410-9bf9-f77b7e298cf2 --- mpcommon.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'mpcommon.c') diff --git a/mpcommon.c b/mpcommon.c index 47706ed497..66f2eece8c 100644 --- a/mpcommon.c +++ b/mpcommon.c @@ -17,6 +17,8 @@ */ #include +#include + #include "mpcommon.h" #include "options.h" #include "stream/stream.h" @@ -30,6 +32,7 @@ #include "spudec.h" #include "version.h" #include "vobsub.h" +#include "av_sub.h" #include "libmpcodecs/dec_teletext.h" #include "ffmpeg_files/intreadwrite.h" #include "m_option.h" @@ -84,6 +87,15 @@ if (HAVE_CMOV) #endif /* ARCH_X86 */ } +static bool is_text_sub(int type) +{ + return type == 't' || type == 'm' || type == 'a'; +} + +static bool is_av_sub(int type) +{ + return type == 'p'; +} void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, sh_video_t *sh_video, double refpts, double sub_offset, @@ -92,7 +104,7 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, double curpts = refpts + sub_delay; unsigned char *packet=NULL; int len; - char type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v'; + int type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v'; static subtitle subs; if (reset) { sub_clear_text(&subs, MP_NOPTS_VALUE); @@ -103,6 +115,10 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, spudec_reset(vo_spudec); vo_osd_changed(OSDTYPE_SPU); } +#ifdef CONFIG_LIBAVCODEC + if (is_av_sub(type)) + reset_avsub(d_dvdsub->sh); +#endif return; } // find sub @@ -122,7 +138,6 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, if (vo_spudec && (vobsub_id >= 0 || (opts->sub_id >= 0 && type == 'v'))) { int timestamp; current_module = "spudec"; - spudec_heartbeat(vo_spudec, 90000*curpts); /* Get a sub packet from the DVD or a vobsub */ while(1) { // Vobsub @@ -157,12 +172,7 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, if (vo_vobsub || timestamp >= 0) spudec_assemble(vo_spudec, packet, len, timestamp); } - - if (spudec_changed(vo_spudec)) - vo_osd_changed(OSDTYPE_SPU); - } else if (opts->sub_id >= 0 - && (type == 't' || type == 'm' || type == 'a' || type == 'd')) { - double endpts; + } else if (opts->sub_id >= 0 && (is_text_sub(type) || is_av_sub(type) || type == 'd')) { if (type == 'd' && !d_dvdsub->demuxer->teletext) { tt_stream_props tsp = {0}; void *ptr = &tsp; @@ -171,18 +181,28 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, } if (d_dvdsub->non_interleaved) ds_get_next_pts(d_dvdsub); + + int orig_type = type; while (d_dvdsub->first) { double subpts = ds_get_next_pts(d_dvdsub) + sub_offset; + type = orig_type; if (subpts > curpts) { // Libass handled subs can be fed to it in advance - if (!opts->ass_enabled || type == 'd') + if (!opts->ass_enabled || !is_text_sub(type)) break; // Try to avoid demuxing whole file at once if (d_dvdsub->non_interleaved && subpts > curpts + 1) break; } - endpts = d_dvdsub->first->endpts + sub_offset; + double endpts = d_dvdsub->first->endpts + sub_offset; len = ds_get_packet_sub(d_dvdsub, &packet); + if (is_av_sub(type)) { +#ifdef CONFIG_LIBAVCODEC + type = decode_avsub(d_dvdsub->sh, &packet, &len, &subpts, &endpts); + if (type <= 0) +#endif + continue; + } if (type == 'm') { if (len < 2) continue; len = FFMIN(len - 2, AV_RB16(packet)); @@ -251,6 +271,12 @@ void update_subtitles(struct MPContext *mpctx, struct MPOpts *opts, if (sub_clear_text(&subs, curpts)) set_osd_subtitle(mpctx, &subs); } + if (vo_spudec) { + spudec_heartbeat(vo_spudec, 90000*curpts); + if (spudec_changed(vo_spudec)) + vo_osd_changed(OSDTYPE_SPU); + } + current_module=NULL; } -- cgit v1.2.3