From 8362b060d46f038a1eb5bb810f4ab4818b1ea754 Mon Sep 17 00:00:00 2001 From: reimar Date: Mon, 12 Jul 2010 18:04:05 +0000 Subject: 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 --- libmpdemux/demux_ts.c | 86 ++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 49 deletions(-) (limited to 'libmpdemux') 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; -- cgit v1.2.3