summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorgpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-04-03 14:08:28 +0000
committergpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-04-03 14:08:28 +0000
commit9e909f0dde36431c457922e1f66fff0c1d6e71ac (patch)
tree008569d4fe4ec81c58af17ad8b25d16138f312ec /libmpdemux
parentacf7defdcf8c22504cee6333b9d9164d34e4f8db (diff)
downloadmpv-9e909f0dde36431c457922e1f66fff0c1d6e71ac.tar.bz2
mpv-9e909f0dde36431c457922e1f66fff0c1d6e71ac.tar.xz
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
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_mpg.c52
-rw-r--r--libmpdemux/demuxer.c33
-rw-r--r--libmpdemux/demuxer.h2
3 files changed, 52 insertions, 35 deletions
diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c
index ffab3b1fca..acd70c6562 100644
--- a/libmpdemux/demux_mpg.c
+++ b/libmpdemux/demux_mpg.c
@@ -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;
}
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 3c72dfe99f..e2fbe222ab 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -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;
+}
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 17b7631db5..9c5f4b12b1 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -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);