changeset 15046:b7aa70b05d76

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
author gpoirier
date Sun, 03 Apr 2005 14:08:28 +0000
parents 20ea036e5f0d
children c9eb0a051ed8
files ChangeLog DOCS/man/en/mplayer.1 input/input.c input/input.h libmpdemux/demux_mpg.c libmpdemux/demuxer.c libmpdemux/demuxer.h mplayer.c
diffstat 8 files changed, 63 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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\ \ \ \ 
--- 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
--- 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
--- 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;
     }
--- 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;
+}
--- 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);
--- 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()) {