[PATCH] DVD subpicture/audio stream mapping

Diego Biurrun <[email protected]> Thu, 19 Jan 2006 00:35:26 +0100
Newsgroups gmane.comp.video.ogle.devel
Message-ID <[email protected]>
--G4iJoqBmSsgzjUCe
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

[Once again, this time with patch attached, sorry...]

Hi,

this patch was submitted in August 2005 to MPlayer.  It was applied with
slight modifications, please review and maybe apply it to libdvdread.
The patch is attached, the message the author sent is pasted below.

Regards

Diego


http://mplayerhq.hu/pipermail/mplayer-dev-eng/2005-August/036580.html

Hi all!

I had to realise that mplayer entirely ignores the logical mapping info 
between the various dvd audio/subtitle tracks and the corresponding mpeg 
streams, and does an identity mapping instead.
But I guess it's because libdvdread lacks the support for it :)
So here is the patch that fixes this shortcoming...

Some background info:
The audio and subtitle streams as specified in the IFO do not correspond
one-to-one to the streams in the mpeg-ps, but there is a mapping table
which specifies the assignments. In case of audio this hasn't been a big
problem unless the dvd has been really screwed up, because there are
the same number of logical streams as mpeg streams. So maybe you have a
0->1, 1->0 mapping in which case selecting one language in mplayer gets
you the other soundtrack, but both tracks are accessible.

Subtitles are not so simple however, because for one logical stream you
can have multiple mpeg subpicture streams. If you create a dvd for a
16:9 movie, you have to specify a spu stream for 4:3 letterboxed display
and also for 16:9 widescreen display. Up to this time I have run across
only one dvd which did not map the same stream to both modes. So not a
frequent case, but until now mplayer could not display the subtitles
correctly for these dvds, because it considered logical stream N to map
to mpeg stream N. But in this case the mapping is e.g. lang1->{0,1}
lang2->{2,3}, so when selecting lang1 mplayer would play lang1 stream
for letterbox, and when selecting lang2, it would play lang1 stream for
widescreen. The lang2 sub would be totally inaccessible, even with -sid,
because the code ignores values higher than the maximum number of subs.

So if you had problems like this, hopefully this will fix it. Patch is
against the last CVS snapshot accessible from the webpage (20050806).

Regards,
Lehel

--G4iJoqBmSsgzjUCe
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="libdvdread_mapping.patch"

diff -Naur dvdread.orig/ifo_print.c dvdread/ifo_print.c
--- dvdread.orig/ifo_print.c	30 Jun 2005 22:48:26 -0000	1.4
+++ dvdread/ifo_print.c	3 Oct 2005 14:29:01 -0000	1.5
@@ -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]);
     }

diff -Naur dvdread.orig/ifo_read.c dvdread/ifo_read.c
--- dvdread.orig/ifo_read.c	30 Jun 2005 22:48:26 -0000	1.4
+++ dvdread/ifo_read.c	3 Oct 2005 14:29:01 -0000	1.5
@@ -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 */

diff -Naur dvdread.orig/ifo_types.h dvdread/ifo_types.h
--- dvdread.orig/ifo_types.h	2005-06-23 00:18:54.000000000 +0200
+++ dvdread/ifo_types.h	2005-06-23 00:19:10.000000000 +0200
@@ -394,6 +394,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 {
@@ -402,8 +451,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;

--G4iJoqBmSsgzjUCe--