mirror of https://github.com/mpv-player/mpv
support for audio stream switching
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18691 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
9e47e2b824
commit
be03496d6b
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue