# HG changeset patch # User gpoirier # Date 1112537308 0 # Node ID b7aa70b05d7616444e81963c9b41259c500ed3ee # Parent 20ea036e5f0d29daabfa63f8169224635a16e677 Added support of audio stream switching in the MPEG demuxer using the #-key Patch by Michael Behrisch < behrisch $ informatik * hu-berlin * de > commited with the kind blessing of D. Richard Felker III diff -r 20ea036e5f0d -r b7aa70b05d76 ChangeLog --- a/ChangeLog Sun Apr 03 11:47:20 2005 +0000 +++ b/ChangeLog Sun Apr 03 14:08:28 2005 +0000 @@ -45,7 +45,8 @@ * avisynth demuxer * Multichannel MP3 in MP4 files support (MP3on4) * some classes of nonworking 14.4/28.8 RealAudio files fixed - * added code to autodetect and demux mpeg audio layers 1 and 2 + * added code to autodetect and demux mpeg audio layers 1 and 2 + * online audio stream switching in the MPEG demuxer Streaming: * stream selection and bandwidth support for MMS over HTTP diff -r 20ea036e5f0d -r b7aa70b05d76 DOCS/man/en/mplayer.1 --- a/DOCS/man/en/mplayer.1 Sun Apr 03 11:47:20 2005 +0000 +++ b/DOCS/man/en/mplayer.1 Sun Apr 03 14:08:28 2005 +0000 @@ -33,7 +33,7 @@ .\" Title .\" -------------------------------------------------------------------------- . -.TH MPlayer 1 "2005-01-13" "The MPlayer Project" "The Movie Player" +.TH MPlayer 1 "2005-04-03" "The MPlayer Project" "The Movie Player" . .SH NAME mplayer \- movie player @@ -276,6 +276,8 @@ Decrease/\:increase volume. .IPs m\ \ \ \ Mute sound. +.IPs "#" +Cycle through the available audio tracks. .IPs f\ \ \ \ Toggle fullscreen (also see \-fs). .IPs T\ \ \ \ diff -r 20ea036e5f0d -r b7aa70b05d76 input/input.c --- a/input/input.c Sun Apr 03 11:47:20 2005 +0000 +++ b/input/input.c Sun Apr 03 14:08:28 2005 +0000 @@ -82,6 +82,7 @@ { MP_CMD_SUB_LOG, "sub_log", 0, { {-1,{0}} } }, { MP_CMD_GET_PERCENT_POS, "get_percent_pos", 0, { {-1,{0}} } }, { MP_CMD_GET_TIME_LENGTH, "get_time_length", 0, { {-1,{0}} } }, + { MP_CMD_SWITCH_AUDIO, "switch_audio", 0, { {-1,{0}} } }, #ifdef USE_TV { MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", 1, { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} }}, { MP_CMD_TV_STEP_NORM, "tv_step_norm",0, { {-1,{0}} } }, @@ -317,6 +318,7 @@ { { 'b', 0 }, "sub_select" }, { { 'j', 0 }, "vobsub_lang" }, { { 'F', 0 }, "forced_subs_only" }, + { { '#', 0 }, "switch_audio" }, #ifdef USE_EDL { { 'i', 0 }, "edl_mark" }, #endif diff -r 20ea036e5f0d -r b7aa70b05d76 input/input.h --- a/input/input.h Sun Apr 03 11:47:20 2005 +0000 +++ b/input/input.h Sun Apr 03 14:08:28 2005 +0000 @@ -63,6 +63,7 @@ #define MP_CMD_SPEED_SET 59 #define MP_CMD_RUN 60 #define MP_CMD_SUB_LOG 61 +#define MP_CMD_SWITCH_AUDIO 62 #define MP_CMD_GUI_EVENTS 5000 #define MP_CMD_GUI_LOADFILE 5001 diff -r 20ea036e5f0d -r b7aa70b05d76 libmpdemux/demux_mpg.c --- a/libmpdemux/demux_mpg.c Sun Apr 03 11:47:20 2005 +0000 +++ b/libmpdemux/demux_mpg.c Sun Apr 03 14:08:28 2005 +0000 @@ -32,6 +32,8 @@ float final_pts; int has_valid_timestamps; unsigned int es_map[0x40]; //es map of stream types (associated to the pes id) from 0xb0 to 0xef + int num_a_streams; + int a_stream_ids[MAX_A_STREAMS]; } mpg_demuxer_t; static int mpeg_pts_error=0; @@ -109,6 +111,7 @@ demuxer->priv = mpg_d; mpg_d->final_pts = 0.0; mpg_d->has_valid_timestamps = 1; + mpg_d->num_a_streams = 0; if (demuxer->seekable && stream_tell(demuxer->stream) < end_seq_start) { stream_seek(s,(pos + end_seq_start / 2)); while ((!s->eof) && ds_fill_buffer(demuxer->video) && half_pts == 0.0) { @@ -154,6 +157,23 @@ return pts; } +static void new_audio_stream(demuxer_t *demux, int aid){ + if(!demux->a_streams[aid]){ + mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv; + sh_audio_t* sh_a; + new_sh_audio(demux,aid); + sh_a = (sh_audio_t*)demux->a_streams[aid]; + switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id) + case 0x00: sh_a->format=0x50;break; // mpeg + case 0xA0: sh_a->format=0x10001;break; // dvd pcm + case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts + else sh_a->format=0x2000;break; // ac3 + } + if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid; + } + if(demux->audio->id==-1) demux->audio->id=aid; +} + static int demux_mpg_read_packet(demuxer_t *demux,int id){ int d; int len; @@ -267,10 +287,7 @@ // aid=128+(aid&0x7F); // aid=0x80..0xBF - - if(!demux->a_streams[aid]) new_sh_audio(demux,aid); - if(demux->audio->id==-1) demux->audio->id=aid; - + new_audio_stream(demux, aid); if(demux->audio->id==aid){ int type; ds=demux->audio; @@ -327,8 +344,7 @@ if(id>=0x1C0 && id<=0x1DF){ // mpeg audio int aid=id-0x1C0; - if(!demux->a_streams[aid]) new_sh_audio(demux,aid); - if(demux->audio->id==-1) demux->audio->id=aid; + new_audio_stream(demux, aid); if(demux->audio->id==aid){ ds=demux->audio; if(!ds->sh) ds->sh=demux->a_streams[aid]; @@ -602,9 +618,7 @@ } int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){ -/* demux_stream_t *d_audio=demuxer->audio;*/ demux_stream_t *d_video=demuxer->video; -/* sh_audio_t *sh_audio=d_audio->sh;*/ sh_video_t *sh_video=d_video->sh; mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv; @@ -623,6 +637,28 @@ } return DEMUXER_CTRL_DONTKNOW; + case DEMUXER_CTRL_SWITCH_AUDIO: + if (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh) { + demux_stream_t *d_audio = demuxer->audio; + sh_audio_t *sh_audio = d_audio->sh; + sh_audio_t *sh_a; + int i; + for (i = 0; i < mpg_d->num_a_streams; i++) { + if (d_audio->id == mpg_d->a_stream_ids[i]) break; + } + do { + i = (i+1) % mpg_d->num_a_streams; + sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]]; + } while (sh_a->format != sh_audio->format); + if (d_audio->id != mpg_d->a_stream_ids[i]) { + d_audio->id = mpg_d->a_stream_ids[i]; + d_audio->sh = sh_a; + ds_free_packs(d_audio); + } + *((int *)arg)=(int)d_audio->id; + } + return DEMUXER_CTRL_OK; + default: return DEMUXER_CTRL_NOTIMPL; } diff -r 20ea036e5f0d -r b7aa70b05d76 libmpdemux/demuxer.c --- a/libmpdemux/demuxer.c Sun Apr 03 11:47:20 2005 +0000 +++ b/libmpdemux/demuxer.c Sun Apr 03 14:08:28 2005 +0000 @@ -1348,26 +1348,7 @@ break; } - case DEMUXER_TYPE_MPEG_TY: { - sh_video=d_video->sh;sh_video->ds=d_video; - - if(audio_id!=-2) { - if(!ds_fill_buffer(d_audio)){ - mp_msg(MSGT_DEMUXER,MSGL_INFO,"MPEG: " MSGTR_MissingAudioStream); - sh_audio=NULL; - } else { - sh_audio=d_audio->sh;sh_audio->ds=d_audio; - switch(d_audio->id & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id) - case 0x00: sh_audio->format=0x50;break; // mpeg - case 0xA0: sh_audio->format=0x10001;break; // dvd pcm - case 0x80: if((d_audio->id & 0xF8) == 0x88) sh_audio->format=0x2001;//dts - else sh_audio->format=0x2000;break; // ac3 - default: sh_audio=NULL; // unknown type - } - } - } - break; - } + case DEMUXER_TYPE_MPEG_TY: case DEMUXER_TYPE_MPEG_PS: { sh_video=d_video->sh;sh_video->ds=d_video; // if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD @@ -1378,13 +1359,6 @@ sh_audio=NULL; } else { sh_audio=d_audio->sh;sh_audio->ds=d_audio; - switch(d_audio->id & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id) - case 0x00: sh_audio->format=0x50;break; // mpeg - case 0xA0: sh_audio->format=0x10001;break; // dvd pcm - case 0x80: if((d_audio->id & 0xF8) == 0x88) sh_audio->format=0x2001;//dts - else sh_audio->format=0x2000;break; // ac3 - default: sh_audio=NULL; // unknown type - } } } break; @@ -1804,3 +1778,8 @@ return ans; } +int demuxer_switch_audio(demuxer_t *demuxer){ + int ans = 0; + int res = demux_control(demuxer, DEMUXER_CTRL_SWITCH_AUDIO, &ans); + return ans; +} diff -r 20ea036e5f0d -r b7aa70b05d76 libmpdemux/demuxer.h --- a/libmpdemux/demuxer.h Sun Apr 03 11:47:20 2005 +0000 +++ b/libmpdemux/demuxer.h Sun Apr 03 14:08:28 2005 +0000 @@ -70,6 +70,7 @@ #define DEMUXER_CTRL_GUESS 2 #define DEMUXER_CTRL_GET_TIME_LENGTH 10 #define DEMUXER_CTRL_GET_PERCENT_POS 11 +#define DEMUXER_CTRL_SWITCH_AUDIO 12 // Holds one packet/frame/whatever typedef struct demux_packet_st { @@ -286,5 +287,6 @@ extern unsigned long demuxer_get_time_length(demuxer_t *demuxer); extern int demuxer_get_percent_pos(demuxer_t *demuxer); +extern int demuxer_switch_audio(demuxer_t *demuxer); extern int demuxer_type_by_filename(char* filename); diff -r 20ea036e5f0d -r b7aa70b05d76 mplayer.c --- a/mplayer.c Sun Apr 03 11:47:20 2005 +0000 +++ b/mplayer.c Sun Apr 03 14:08:28 2005 +0000 @@ -3495,6 +3495,9 @@ case MP_CMD_GET_PERCENT_POS : { mp_msg(MSGT_GLOBAL,MSGL_INFO,MSGTR_AnsPercentPos, demuxer_get_percent_pos(demuxer)); } break; + case MP_CMD_SWITCH_AUDIO : + demuxer_switch_audio(demuxer); + break; case MP_CMD_RUN : { #ifndef __MINGW32__ if(!fork()) {