summaryrefslogtreecommitdiffstats
path: root/mpcommon.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-07-10 13:45:09 +0000
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:14:43 +0200
commit96c17fe68b12104269f70b113d757fbc67b5ed1f (patch)
treeb63db7e8a5b4d090210e621ab5ad948eaf12e788 /mpcommon.c
parentd6322407c503bbca1f1bb48e06e275f7b610a3a8 (diff)
downloadmpv-96c17fe68b12104269f70b113d757fbc67b5ed1f.tar.bz2
mpv-96c17fe68b12104269f70b113d757fbc67b5ed1f.tar.xz
subs: Add support for PGS subtitle decoding via libavcodec
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31665 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'mpcommon.c')
-rw-r--r--mpcommon.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/mpcommon.c b/mpcommon.c
index 47706ed497..66f2eece8c 100644
--- a/mpcommon.c
+++ b/mpcommon.c
@@ -17,6 +17,8 @@
*/
#include <stdlib.h>
+#include <stdbool.h>
+
#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;
}