summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-07-12 18:04:05 +0000
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:14:44 +0200
commit8362b060d46f038a1eb5bb810f4ab4818b1ea754 (patch)
treef35918597259b063ca55dabe4e39227f3f801976 /libmpdemux
parent7d17b5e2543f3c8c7c35d780bcfeefd165ee082b (diff)
downloadmpv-8362b060d46f038a1eb5bb810f4ab4818b1ea754.tar.bz2
mpv-8362b060d46f038a1eb5bb810f4ab4818b1ea754.tar.xz
demux_ts: Improve subtitle support
Make it use the infrastructure for subtitle handling so e.g. switching subtitles at runtime works and add support for PGS subtitles. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31724 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_ts.c86
1 files changed, 37 insertions, 49 deletions
diff --git a/libmpdemux/demux_ts.c b/libmpdemux/demux_ts.c
index 46a2853207..ec6718854c 100644
--- a/libmpdemux/demux_ts.c
+++ b/libmpdemux/demux_ts.c
@@ -81,6 +81,7 @@ typedef enum
SPU_DVD = 0x3000000,
SPU_DVB = 0x3000001,
SPU_TELETEXT = 0x3000002,
+ SPU_PGS = 0x3000003,
PES_PRIVATE1 = 0xBD00000,
SL_PES_STREAM = 0xD000000,
SL_SECTION = 0xD100000,
@@ -235,6 +236,7 @@ typedef struct {
int keep_broken;
int last_aid;
int last_vid;
+ int last_sid;
char packet[TS_FEC_PACKET_SIZE];
TS_stream_info vstr, astr;
} ts_priv_t;
@@ -281,6 +283,7 @@ static int IS_SUB(es_stream_type_t type)
switch (type) {
case SPU_DVD:
case SPU_DVB:
+ case SPU_PGS:
case SPU_TELETEXT:
return 1;
}
@@ -397,6 +400,23 @@ static void ts_add_stream(demuxer_t * demuxer, ES_stream_t *es)
}
}
}
+
+ if(IS_SUB(es->type) && priv->last_sid+1 < MAX_S_STREAMS)
+ {
+ sh_sub_t *sh = new_sh_sub_sid_lang(demuxer, priv->last_sid, es->pid, pid_lang_from_pmt(priv, es->pid));
+ if (sh) {
+ switch (es->type) {
+ case SPU_DVD:
+ sh->type = 'v'; break;
+ case SPU_PGS:
+ sh->type = 'p'; break;
+ }
+ priv->ts.streams[es->pid].id = priv->last_aid;
+ priv->ts.streams[es->pid].sh = sh;
+ priv->ts.streams[es->pid].type = TYPE_AUDIO;
+ priv->last_sid++;
+ }
+ }
}
static int ts_check_file(demuxer_t * demuxer)
@@ -599,7 +619,7 @@ static inline int pid_match_lang(ts_priv_t *priv, uint16_t pid, char *lang)
typedef struct {
int32_t atype, vtype, stype; //types
int32_t apid, vpid, spid; //stream ids
- char slang[4], alang[4]; //languages
+ char alang[4]; //languages
uint16_t prog;
off_t probe;
} tsdemux_init_t;
@@ -768,9 +788,6 @@ static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param)
}
else if(is_sub)
{
- mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_SUBTITLE_ID=%d\n", es.pid);
- if (es.lang[0] > 0)
- mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_SID_%d_LANG=%s\n", es.pid, es.lang);
chosen_pid = (req_spid == es.pid);
if((! chosen_pid) && (req_spid > 0))
continue;
@@ -1047,14 +1064,6 @@ static demuxer_t *demux_open_ts(demuxer_t * demuxer)
params.prog = ts_prog;
params.probe = ts_probe;
- if(demuxer->opts->sub_lang != NULL)
- {
- strncpy(params.slang, demuxer->opts->sub_lang, 3);
- params.slang[3] = 0;
- }
- else
- memset(params.slang, 0, 4);
-
if(demuxer->opts->audio_lang != NULL)
{
strncpy(params.alang, demuxer->opts->audio_lang, 3);
@@ -1456,7 +1465,7 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
int ssid = parse_pes_extension_fields(p, pkt_len);
if((audio_substream_id!=-1) && (ssid != audio_substream_id))
return 0;
- if(ssid == 0x72 && type_from_pmt != AUDIO_DTS)
+ if(ssid == 0x72 && type_from_pmt != AUDIO_DTS && type_from_pmt != SPU_PGS)
es->type = type_from_pmt = AUDIO_TRUEHD;
}
@@ -1481,6 +1490,14 @@ static int pes_parse2(unsigned char *buf, uint16_t packet_len, ES_stream_t *es,
*/
+ if(type_from_pmt == SPU_PGS)
+ {
+ es->start = p;
+ es->size = packet_len;
+ es->type = SPU_PGS;
+ es->payload_size -= packet_len;
+ return 1;
+ }
if(
(type_from_pmt == AUDIO_A52) || /* A52 - raw */
(packet_len >= 2 && p[0] == 0x0B && p[1] == 0x77) /* A52 - syncword */
@@ -2570,6 +2587,9 @@ static int parse_pmt(ts_priv_t * priv, uint16_t progid, uint16_t pid, int is_sta
case 0x86:
pmt->es[idx].type = AUDIO_DTS;
break;
+ case 0x90:
+ pmt->es[idx].type = SPU_PGS;
+ break;
case 0xD1:
pmt->es[idx].type = VIDEO_DIRAC;
break;
@@ -2945,14 +2965,9 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
// PES CONTENT STARTS HERE
if(! probe)
{
- if((is_video || is_audio) && is_start && !priv->ts.streams[pid].sh)
+ if((is_video || is_audio || is_sub) && is_start)
ts_add_stream(demuxer, tss);
- if((pid == demuxer->sub->id)) //or the lang is right
- {
- pid_type = SPU_DVD;
- }
-
if(is_video && (demuxer->video->id == priv->ts.streams[pid].id))
{
ds = demuxer->video;
@@ -2971,38 +2986,11 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
buffer_size = &priv->fifo[0].buffer_size;
si = &priv->astr;
}
- else if(is_sub
- || IS_SUB(pid_type))
+ else if(is_sub)
{
- //SUBS are infrequent, so the initial detection may fail
- // and we may need to add them at play-time
- if(demuxer->sub->id == -1)
- {
- uint16_t p;
- p = progid_for_pid(priv, tss->pid, priv->prog);
-
- if(p == priv->prog)
- {
- int asgn = 0;
- uint8_t *lang;
-
- if(demuxer->opts->sub_lang)
- {
- if ((lang = pid_lang_from_pmt(priv, pid)))
- asgn = (strncmp(lang, demuxer->opts->sub_lang, 3) == 0);
- }
- else //no language specified with -slang
- asgn = 1;
-
- if(asgn)
- {
- demuxer->sub->id = tss->pid;
- mp_msg(MSGT_DEMUX, MSGL_INFO, "CHOSEN SUBs pid 0x%x (%d) FROM PROG %d\n", tss->pid, tss->pid, priv->prog);
- }
- }
- }
+ sh_sub_t *sh_sub = demuxer->sub->sh;
- if(demuxer->sub->id == tss->pid)
+ if(sh_sub && sh_sub->sid == tss->pid)
{
ds = demuxer->sub;