mirror of
https://github.com/mpv-player/mpv
synced 2025-02-11 15:24:30 +01:00
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 git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15047 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
acf7defdcf
commit
9e909f0dde
@ -45,7 +45,8 @@ MPlayer (1.0)
|
||||
* 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
|
||||
|
@ -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.
|
||||
Decrease/\:increase volume.
|
||||
.IPs m\ \ \ \
|
||||
Mute sound.
|
||||
.IPs "#"
|
||||
Cycle through the available audio tracks.
|
||||
.IPs f\ \ \ \
|
||||
Toggle fullscreen (also see \-fs).
|
||||
.IPs T\ \ \ \
|
||||
|
@ -82,6 +82,7 @@ static mp_cmd_t mp_cmds[] = {
|
||||
{ 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 @@ static mp_cmd_bind_t def_cmd_binds[] = {
|
||||
{ { 'b', 0 }, "sub_select" },
|
||||
{ { 'j', 0 }, "vobsub_lang" },
|
||||
{ { 'F', 0 }, "forced_subs_only" },
|
||||
{ { '#', 0 }, "switch_audio" },
|
||||
#ifdef USE_EDL
|
||||
{ { 'i', 0 }, "edl_mark" },
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -32,6 +32,8 @@ typedef struct mpg_demuxer {
|
||||
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 @@ int demux_mpg_open(demuxer_t* demuxer) {
|
||||
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 @@ static unsigned int read_mpeg_timestamp(stream_t *s,int c){
|
||||
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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
|
||||
// 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 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
|
||||
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 @@ void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
||||
}
|
||||
|
||||
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 @@ int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -1348,26 +1348,7 @@ switch(file_format){
|
||||
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 @@ switch(file_format){
|
||||
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 @@ int demuxer_get_percent_pos(demuxer_t *demuxer){
|
||||
return ans;
|
||||
}
|
||||
|
||||
int demuxer_switch_audio(demuxer_t *demuxer){
|
||||
int ans = 0;
|
||||
int res = demux_control(demuxer, DEMUXER_CTRL_SWITCH_AUDIO, &ans);
|
||||
return ans;
|
||||
}
|
||||
|
@ -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 @@ char *demux_ogg_sub_lang(demuxer_t *demuxer, int index);
|
||||
|
||||
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);
|
||||
|
@ -3495,6 +3495,9 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
|
||||
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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user