Re: [PATCH] DVD subpicture/audio stream mapping

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

On Thu, Jan 19, 2006 at 12:35:26AM +0100, Diego Biurrun wrote:
> [Once again, this time with patch attached, sorry...]

And this time with a patch that actually applies cleanly to libdvdread
CVS.  Apologies for testing everybody's patience so much..

Diego

> 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

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

Index: dvdread/ifo_print.c
===================================================================
RCS file: /cvsroot/ogle/libdvdread/dvdread/ifo_print.c,v
retrieving revision 1.25
diff -u -r1.25 ifo_print.c
--- dvdread/ifo_print.c	15 Sep 2005 16:54:29 -0000	1.25
+++ dvdread/ifo_print.c	18 Jan 2006 23:40:03 -0000
@@ -793,14 +793,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]);
     }
Index: dvdread/ifo_read.c
===================================================================
RCS file: /cvsroot/ogle/libdvdread/dvdread/ifo_read.c,v
retrieving revision 1.33
diff -u -r1.33 ifo_read.c
--- dvdread/ifo_read.c	19 Sep 2005 13:44:27 -0000	1.33
+++ dvdread/ifo_read.c	18 Jan 2006 23:40:03 -0000
@@ -751,10 +751,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]);
   
@@ -763,10 +759,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 */
Index: dvdread/ifo_types.h
===================================================================
RCS file: /cvsroot/ogle/libdvdread/dvdread/ifo_types.h,v
retrieving revision 1.17
diff -u -r1.17 ifo_types.h
--- dvdread/ifo_types.h	18 Sep 2005 18:02:08 -0000	1.17
+++ dvdread/ifo_types.h	18 Jan 2006 23:40:03 -0000
@@ -403,6 +403,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 {
@@ -411,8 +460,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;

--b5gNqxB1S1yM7hjW--