From be03496d6bb422c81c28308271caf7d6d1844363 Mon Sep 17 00:00:00 2001 From: nicodvb Date: Mon, 12 Jun 2006 23:06:21 +0000 Subject: support for audio stream switching git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18691 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpdemux/demux_ts.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) (limited to 'libmpdemux/demux_ts.c') diff --git a/libmpdemux/demux_ts.c b/libmpdemux/demux_ts.c index 01f5d88baa..64da659fb9 100644 --- a/libmpdemux/demux_ts.c +++ b/libmpdemux/demux_ts.c @@ -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 @@ typedef struct { } 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 @@ typedef struct { 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 @@ static demuxer_t *demux_open_ts(demuxer_t * demuxer) } 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 @@ static demuxer_t *demux_open_ts(demuxer_t * demuxer) start_pos = ts_detect_streams(demuxer, ¶ms); - demuxer->audio->id = params.apid; demuxer->video->id = params.vpid; demuxer->sub->id = params.spid; priv->prog = params.prog; @@ -955,6 +967,11 @@ static demuxer_t *demux_open_ts(demuxer_t * demuxer) { 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 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet, // 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 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet, 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 @@ static int ts_check_file_dmx(demuxer_t *demuxer) 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 @@ demuxer_desc_t demuxer_desc_mpeg_ts = { demux_open_ts, demux_close_ts, demux_seek_ts, - NULL + demux_ts_control }; -- cgit v1.2.3