changeset 31658:66795d9dcb51

Improve MPEG-TS subtitle support: make it use the infrastructure for subtitle handling so e.g. switching subtitles at runtime works and add support for PGS subtitles.
author reimar
date Mon, 12 Jul 2010 18:04:05 +0000
parents fa6671a1b8dc
children a05f97bad2a9
files libmpdemux/demux_ts.c
diffstat 1 files changed, 39 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_ts.c	Mon Jul 12 17:43:37 2010 +0000
+++ b/libmpdemux/demux_ts.c	Mon Jul 12 18:04:05 2010 +0000
@@ -60,7 +60,7 @@
 int ts_keep_broken=0;
 off_t ts_probe = 0;
 int audio_substream_id = -1;
-extern char *dvdsub_lang, *audio_lang;	//for -alang
+extern char *audio_lang;	//for -alang
 
 typedef enum
 {
@@ -82,6 +82,7 @@
 	SPU_DVD		= 0x3000000,
 	SPU_DVB		= 0x3000001,
 	SPU_TELETEXT	= 0x3000002,
+	SPU_PGS		= 0x3000003,
 	PES_PRIVATE1	= 0xBD00000,
 	SL_PES_STREAM	= 0xD000000,
 	SL_SECTION	= 0xD100000,
@@ -236,6 +237,7 @@
 	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;
@@ -282,6 +284,7 @@
 	switch (type) {
 	case SPU_DVD:
 	case SPU_DVB:
+	case SPU_PGS:
 	case SPU_TELETEXT:
 		return 1;
 	}
@@ -395,6 +398,23 @@
 			}
 		}
 	}
+
+	if(IS_SUB(es->type) && priv->last_sid+1 < MAX_S_STREAMS)
+	{
+		sh_sub_t *sh = new_sh_sub_sid(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)
@@ -597,7 +617,7 @@
 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;
@@ -766,9 +786,6 @@
 			}
 			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;
@@ -1045,14 +1062,6 @@
 	params.prog = ts_prog;
 	params.probe = ts_probe;
 
-	if(dvdsub_lang != NULL)
-	{
-		strncpy(params.slang, dvdsub_lang, 3);
-		params.slang[3] = 0;
-	}
-	else
-		memset(params.slang, 0, 4);
-
 	if(audio_lang != NULL)
 	{
 		strncpy(params.alang, audio_lang, 3);
@@ -1454,7 +1463,7 @@
 		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;
 	}
 
@@ -1479,6 +1488,14 @@
 		*/
 
 
+		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 */
@@ -2568,6 +2585,9 @@
 			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;
@@ -2943,14 +2963,9 @@
 			// 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;
@@ -2969,38 +2984,11 @@
 				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(dvdsub_lang)
-						{
-							if ((lang = pid_lang_from_pmt(priv, pid)))
-								asgn = (strncmp(lang, dvdsub_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);
-						}
-					}
-				}
-
-				if(demuxer->sub->id == tss->pid)
+				sh_sub_t *sh_sub = demuxer->sub->sh;
+
+				if(sh_sub && sh_sub->sid == tss->pid)
 				{
 					ds = demuxer->sub;