changeset 16649:e1d6fbd607e0

Fix DVD audio and subtitle stream mapping, esp. for DVD with both 4:3 and 16:9 subtitles. Patch by Lehel Bernadt (lehel at pmc-services hu) with minor modifications.
author reimar
date Mon, 03 Oct 2005 14:29:01 +0000
parents 5e3e86e8c9b4
children 831cdc896c4c
files libmpdemux/stream_dvd.c libmpdvdkit2/ifo_print.c libmpdvdkit2/ifo_read.c libmpdvdkit2/ifo_types.h
diffstat 4 files changed, 80 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/stream_dvd.c	Mon Oct 03 14:25:04 2005 +0000
+++ b/libmpdemux/stream_dvd.c	Mon Oct 03 14:29:01 2005 +0000
@@ -16,6 +16,11 @@
 #include <sys/cdrio.h>
 #endif
 
+#define FIRST_AC3_AID 128
+#define FIRST_DTS_AID 136
+#define FIRST_MPG_AID 0
+#define FIRST_PCM_AID 160
+
 #include "stream.h"
 #include "../m_option.h"
 #include "../m_struct.h"
@@ -176,8 +181,8 @@
     code=lang[1]|(lang[0]<<8);
     for(i=0;i<d->nr_of_subtitles;i++) {
       if(d->subtitles[i].language==code) {
-        mp_msg(MSGT_OPEN,MSGL_INFO,"Selected DVD subtitle channel: %d language: %c%c\n", d->subtitles[i].id, lang[0],lang[1]);
-        return d->subtitles[i].id;
+        mp_msg(MSGT_OPEN,MSGL_INFO,"Selected DVD subtitle channel: %d language: %c%c\n", i, lang[0],lang[1]);
+        return i;
       }
     }
     lang+=2; 
@@ -577,6 +582,8 @@
       return STREAM_UNSUPORTED;
     }
     --dvd_angle; // remap 1.. -> 0..
+
+    ttn = tt_srpt->title[dvd_title].vts_ttn - 1;
     /**
      * Load the VTS information for the title set our title is in.
      */
@@ -614,15 +621,11 @@
      * Check number of audio channels and types
      */
     {
-      int ac3aid = 128;
-      int mpegaid = 0;
-      int pcmaid = 160;
-
       d->nr_of_channels=0;
       if(vts_file->vts_pgcit) {
         int i;
         for(i=0;i<8;i++)
-          if(vts_file->vts_pgcit->pgci_srp[0].pgc->audio_control[i] & 0x8000) {
+          if(vts_file->vts_pgcit->pgci_srp[ttn].pgc->audio_control[i].present) {
             audio_attr_t * audio = &vts_file->vtsi_mat->vts_audio_attr[i];
             int language = 0;
             char tmp[] = "unknown";
@@ -635,24 +638,20 @@
             }
 
             d->audio_streams[d->nr_of_channels].language=language;
-            d->audio_streams[d->nr_of_channels].id=0;
+            d->audio_streams[d->nr_of_channels].id=vts_file->vts_pgcit->pgci_srp[ttn].pgc->audio_control[i].s_audio;
             switch(audio->audio_format) {
               case 0: // ac3
-                d->audio_streams[d->nr_of_channels].id=ac3aid;
-                ac3aid++;
+                d->audio_streams[d->nr_of_channels].id+=FIRST_AC3_AID;
                 break;
               case 6: // dts
-                d->audio_streams[d->nr_of_channels].id=ac3aid+8;
-                ac3aid++;
+                d->audio_streams[d->nr_of_channels].id+=FIRST_DTS_AID;
                 break;
               case 2: // mpeg layer 1/2/3
               case 3: // mpeg2 ext
-                d->audio_streams[d->nr_of_channels].id=mpegaid;
-                mpegaid++;
+                d->audio_streams[d->nr_of_channels].id+=FIRST_MPG_AID;
                 break;
               case 4: // lpcm
-                d->audio_streams[d->nr_of_channels].id=pcmaid;
-                pcmaid++;
+                d->audio_streams[d->nr_of_channels].id+=FIRST_PCM_AID;
                 break;
            }
 
@@ -688,8 +687,9 @@
 
       d->nr_of_subtitles=0;
       for(i=0;i<32;i++)
-      if(vts_file->vts_pgcit->pgci_srp[0].pgc->subp_control[i] & 0x80000000) {
+      if(vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i].present) {
         subp_attr_t * subtitle = &vts_file->vtsi_mat->vts_subp_attr[i];
+        video_attr_t *video = &vts_file->vtsi_mat->vts_video_attr;
         int language = 0;
         char tmp[] = "unknown";
 
@@ -702,10 +702,14 @@
 
         d->subtitles[ d->nr_of_subtitles ].language=language;
         d->subtitles[ d->nr_of_subtitles ].id=d->nr_of_subtitles;
+        if(video->display_aspect_ratio == 0) /* 4:3 */
+          d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i].s_4p3;
+        else if(video->display_aspect_ratio == 3) /* 16:9 */
+          d->subtitles[d->nr_of_subtitles].id = vts_file->vts_pgcit->pgci_srp[ttn].pgc->subp_control[i].s_lbox;
 
         mp_msg(MSGT_OPEN,MSGL_V,"[open] subtitle ( sid ): %d language: %s\n", d->nr_of_subtitles, tmp);
         if(identify) {
-          mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", d->nr_of_subtitles);
+          mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", d->subtitles[d->nr_of_subtitles].id);
           if(language && tmp[0])
             mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SID_%d_LANG=%s\n", d->nr_of_subtitles, tmp);
         }
@@ -718,16 +722,15 @@
      * Determine which program chain we want to watch.  This is based on the
      * chapter number.
      */
-    ttn = tt_srpt->title[ dvd_title ].vts_ttn; // local
-    pgc_id = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter].pgcn; // local
-    pgn  = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter].pgn;  // local
+    pgc_id = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgcn; // local
+    pgn  = vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_chapter].pgn;  // local
     d->cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;
     d->cur_cell = d->cur_pgc->program_map[pgn-1] - 1; // start playback here
     d->packs_left=-1;      // for Navi stuff
     d->angle_seek=0;
     /* XXX dvd_last_chapter is in the range 1..nr_of_ptts */
     if(dvd_last_chapter > 0 && dvd_last_chapter < tt_srpt->title[dvd_title].nr_of_ptts) {
-      pgn=vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_last_chapter].pgn;
+      pgn=vts_file->vts_ptt_srpt->title[ttn].ptt[dvd_last_chapter].pgn;
       d->last_cell=d->cur_pgc->program_map[pgn-1] - 1;
     } else
       d->last_cell=d->cur_pgc->nr_of_cells;
--- a/libmpdvdkit2/ifo_print.c	Mon Oct 03 14:25:04 2005 +0000
+++ b/libmpdvdkit2/ifo_print.c	Mon Oct 03 14:29:01 2005 +0000
@@ -761,14 +761,14 @@
   ifoPrint_USER_OPS(&pgc->prohibited_ops);
   
     for(i = 0; i < 8; i++) {
-      if(pgc->audio_control[i] & 0x8000) { /* The 'is present' bit */
+      if(pgc->audio_control[i].present) {
 	printf("Audio stream %i control: %04x\n", 
 	       i, pgc->audio_control[i]);
       }
     }
   
   for(i = 0; i < 32; i++) {
-    if(pgc->subp_control[i] & 0x80000000) { /* The 'is present' bit */
+    if(pgc->subp_control[i].present) {
       printf("Subpicture stream %2i control: %08x\n", 
 	     i, pgc->subp_control[i]);
     }
--- a/libmpdvdkit2/ifo_read.c	Mon Oct 03 14:25:04 2005 +0000
+++ b/libmpdvdkit2/ifo_read.c	Mon Oct 03 14:29:01 2005 +0000
@@ -638,10 +638,6 @@
   B2N_16(pgc->cell_playback_offset);
   B2N_16(pgc->cell_position_offset);
 
-  for(i = 0; i < 8; i++)
-    B2N_16(pgc->audio_control[i]);
-  for(i = 0; i < 32; i++)
-    B2N_32(pgc->subp_control[i]);
   for(i = 0; i < 16; i++)
     B2N_32(pgc->palette[i]);
   
@@ -650,10 +646,10 @@
 
   /* verify time (look at print_time) */
   for(i = 0; i < 8; i++)
-    if(!pgc->audio_control[i] & 0x8000) /* The 'is present' bit */
+    if(!pgc->audio_control[i].present)
       CHECK_ZERO(pgc->audio_control[i]);
   for(i = 0; i < 32; i++)
-    if(!pgc->subp_control[i] & 0x80000000) /* The 'is present' bit */
+    if(!pgc->subp_control[i].present)
       CHECK_ZERO(pgc->subp_control[i]);
   
   /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */
--- a/libmpdvdkit2/ifo_types.h	Mon Oct 03 14:25:04 2005 +0000
+++ b/libmpdvdkit2/ifo_types.h	Mon Oct 03 14:29:01 2005 +0000
@@ -398,6 +398,55 @@
 } ATTRIBUTE_PACKED user_ops_t;
 
 /**
+ * Subpicture stream mapping for a subtitle
+ */
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+  unsigned int present   : 1;
+  unsigned int zero1     : 2;
+  unsigned int s_4p3     : 5; /* stream for 4:3 on any display */
+
+  unsigned int zero2     : 3;
+  unsigned int s_wide    : 5; /* stream for 16:9 on widescreen display */
+
+  unsigned int zero3     : 3;
+  unsigned int s_lbox    : 5; /* stream for 16:9 on letterboxed 4:3 display */
+
+  unsigned int zero4     : 3;
+  unsigned int s_panscan : 5; /* stream for 16:9 with pan&scan data on 4:3 display */
+#else
+  unsigned int s_4p3     : 5; /* stream for 4:3 on any display */
+  unsigned int zero1     : 2;
+  unsigned int present   : 1;
+
+  unsigned int s_wide    : 5; /* stream for 16:9 on widescreen display */
+  unsigned int zero2     : 3;
+
+  unsigned int s_lbox    : 5; /* stream for 16:9 on letterboxed 4:3 display */
+  unsigned int zero3     : 3;
+
+  unsigned int s_panscan : 5; /* stream for 16:9 with pan&scan data on 4:3 display */
+  unsigned int zero4     : 3;
+#endif
+} ATTRIBUTE_PACKED subp_mapping_t;
+
+/**
+ * Audio stream mapping for a soundtrack
+ */
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+  unsigned int present : 1;
+  unsigned int zero1   : 4;
+  unsigned int s_audio : 3;
+#else
+  unsigned int s_audio : 3;
+  unsigned int zero1   : 4;
+  unsigned int present : 1;
+#endif
+  uint8_t zero2;
+} ATTRIBUTE_PACKED audio_mapping_t;
+
+/**
  * Program Chain Information.
  */
 typedef struct {
@@ -406,8 +455,8 @@
   uint8_t  nr_of_cells;
   dvd_time_t playback_time;
   user_ops_t prohibited_ops;
-  uint16_t audio_control[8]; /* New type? */
-  uint32_t subp_control[32]; /* New type? */
+  audio_mapping_t audio_control[8];
+  subp_mapping_t subp_control[32];
   uint16_t next_pgc_nr;
   uint16_t prev_pgc_nr;
   uint16_t goup_pgc_nr;