changeset 18688:a109f55ad8d8

support for audio stream switching
author nicodvb
date Mon, 12 Jun 2006 23:06:21 +0000
parents 86020c65b1d5
children 4f22d91b6e85
files libmpdemux/demux_ts.c
diffstat 1 files changed, 98 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_ts.c	Mon Jun 12 21:24:43 2006 +0000
+++ b/libmpdemux/demux_ts.c	Mon Jun 12 23:06:21 2006 +0000
@@ -55,6 +55,9 @@
 #define SIZE_MAX ((size_t)-1)
 #endif
 
+#define TYPE_AUDIO 1
+#define TYPE_VIDEO 2
+
 int ts_prog;
 int ts_keep_broken=0;
 off_t ts_probe = TS_MAX_PROBE_SIZE;
@@ -105,10 +108,16 @@
 	} sl;
 } ES_stream_t;
 
+typedef struct {
+	void *sh;
+	int id;
+	int type;
+} sh_av_t;
 
 typedef struct MpegTSContext {
 	int packet_size; 		// raw packet size, including FEC if present e.g. 188 bytes
 	ES_stream_t *pids[NB_PID_MAX];
+	sh_av_t streams[NB_PID_MAX];
 } MpegTSContext;
 
 
@@ -222,6 +231,7 @@
 	uint32_t prog;
 	uint32_t vbitrate;
 	int keep_broken;
+	int last_aid;
 	char packet[TS_FEC_PACKET_SIZE];
 	TS_stream_info vstr, astr;
 } ts_priv_t;
@@ -873,7 +883,10 @@
 	}
 
 	for(i=0; i < 8192; i++)
+	{
 	    priv->ts.pids[i] = NULL;
+	    priv->ts.streams[i].id = -3;
+	}
 	priv->pat.progs = NULL;
 	priv->pat.progs_cnt = 0;
 	priv->pat.section.buffer = NULL;
@@ -918,7 +931,6 @@
 
 	start_pos = ts_detect_streams(demuxer, &params);
 
-	demuxer->audio->id = params.apid;
 	demuxer->video->id = params.vpid;
 	demuxer->sub->id = params.spid;
 	priv->prog = params.prog;
@@ -955,6 +967,11 @@
 	{
 		ES_stream_t *es = priv->ts.pids[params.apid];
 		sh_audio = new_sh_audio(demuxer, 0);
+		priv->ts.streams[params.apid].id = 0;
+		priv->ts.streams[params.apid].sh = sh_audio;
+		priv->ts.streams[params.apid].type = TYPE_AUDIO;
+		priv->last_aid = 0;
+		demuxer->audio->id = 0;
 		sh_audio->ds = demuxer->audio;
 		sh_audio->format = params.atype;
 		demuxer->audio->sh = sh_audio;
@@ -2752,6 +2769,22 @@
 			// PES CONTENT STARTS HERE
 		if(! probe)
 		{
+			if((IS_AUDIO(tss->type) || IS_AUDIO(tss->subtype)) && is_start && !priv->ts.streams[pid].sh && priv->last_aid+1 < MAX_A_STREAMS)
+			{
+				sh_audio_t *sh = new_sh_audio(demuxer, priv->last_aid+1);
+				if(sh)
+				{
+					sh->format = IS_AUDIO(tss->type) ? tss->type : tss->subtype;
+					sh->ds = demuxer->audio;
+
+					priv->last_aid++;
+					priv->ts.streams[pid].id = priv->last_aid;
+					priv->ts.streams[pid].sh = sh;
+					priv->ts.streams[pid].type = TYPE_AUDIO;
+					mp_msg(MSGT_DEMUX, MSGL_V, "\r\nADDED AUDIO PID %d, type: %x stream n. %d\r\n", pid, sh->format, priv->last_aid);
+				}
+			}
+
 			if((pid == demuxer->sub->id))	//or the lang is right
 			{
 				pid_type = SPU_DVD;
@@ -2766,7 +2799,7 @@
 				buffer_size = &priv->fifo[1].buffer_size;
 				si = &priv->vstr;
 			}
-			else if(is_audio && (demuxer->audio->id == tss->pid))
+			else if(is_audio && (demuxer->audio->id == priv->ts.streams[pid].id))
 			{
 				ds = demuxer->audio;
 
@@ -3212,6 +3245,68 @@
     return ts_check_file(demuxer) ? DEMUXER_TYPE_MPEG_TS : 0;
 }
 
+static int demux_ts_control(demuxer_t *demuxer, int cmd, void *arg)
+{
+	ts_priv_t* priv = (ts_priv_t *)demuxer->priv;
+
+	switch(cmd)
+	{
+		case DEMUXER_CTRL_SWITCH_AUDIO:
+		{
+			sh_audio_t *sh_audio = demuxer->audio->sh;
+			sh_audio_t *sh_a = NULL;
+			int i, n;
+			if(!sh_audio)
+				return DEMUXER_CTRL_NOTIMPL;
+			
+			n = *((int*)arg);
+			if(n < 0)
+			{
+				for(i = 0; i < 8192; i++)
+				{
+					if(priv->ts.streams[i].id == demuxer->audio->id && priv->ts.streams[i].type == TYPE_AUDIO)
+						break;
+				}
+
+				while(!sh_a)
+				{
+					i = (i+1) % 8192;
+					if(priv->ts.streams[i].id == demuxer->audio->id)	//we made a complete loop
+						break;
+					if(priv->ts.streams[i].type == TYPE_AUDIO)
+						sh_a = (sh_audio_t*)priv->ts.streams[i].sh;
+				}
+			}
+			else if(n <= priv->last_aid)
+			{
+				for(i = 0; i < 8192; i++)
+				{
+					if(priv->ts.streams[i].id == n && priv->ts.streams[i].type == TYPE_AUDIO)
+					{
+						sh_a = (sh_audio_t*)priv->ts.streams[i].sh;
+						break;
+					}
+				}
+			}
+
+			if(sh_a)
+			{
+				demuxer->audio->id = priv->ts.streams[i].id;
+				demuxer->audio->sh = sh_a;
+				ds_free_packs(demuxer->audio);
+				mp_msg(MSGT_DEMUX, MSGL_V, "\r\ndemux_ts, switched to audio pid %d, id: %d, sh: %p\r\n", i, demuxer->audio->id, sh_a);
+			}
+
+			*((int*)arg) = demuxer->audio->id;
+			return DEMUXER_CTRL_OK;
+		}
+		
+
+		default:
+			return DEMUXER_CTRL_NOTIMPL;
+	}
+}
+
 
 demuxer_desc_t demuxer_desc_mpeg_ts = {
   "MPEG-TS demuxer",
@@ -3226,5 +3321,5 @@
   demux_open_ts,
   demux_close_ts,
   demux_seek_ts,
-  NULL
+  demux_ts_control
 };