* ./plugins/dvd/dvd_es.c: error in selecting SPU stream.
authorSam Hocevar <sam@videolan.org>
Thu, 27 Jun 2002 19:46:32 +0000 (19:46 +0000)
committerSam Hocevar <sam@videolan.org>
Thu, 27 Jun 2002 19:46:32 +0000 (19:46 +0000)
  * ./plugins/spudec/spu_decoder.c: endianness fix for subtitles colour.
  * ./plugins/spudec/spu_decoder.c: little hack for preventing blank alpha
    palette.
  * ./plugins/spudec/spu_decoder.c: subtitle transparency support.

   Patches imported from v0_4_1_branch.

AUTHORS
ChangeLog
plugins/dvd/dvd_es.c
plugins/spudec/spu_decoder.c

diff --git a/AUTHORS b/AUTHORS
index e5f2417..abffc0f 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -176,6 +176,10 @@ E: alexis.guillard@bt.com
 D: IPv6
 S: United Kingdom
 
+N: Roine Gustafsson
+E: roine@popstar.com
+D: spudec bug fixes
+
 N: Shane Harper
 E: shanegh@optusnet.com.au
 D: SDL plugin fixes and enhancements
index adb3c88..4bc9837 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -67,8 +67,13 @@ Not released yet
   * ALL: the first libvlc commit.
 
 0.4.2
-Mon, 20 Jun 2002 00:41:26 +0200
+Not released yet
 
+  * ./plugins/dvd/dvd_es.c: error in selecting SPU stream.
+  * ./plugins/spudec/spu_decoder.c: endianness fix for subtitles colour.
+  * ./plugins/spudec/spu_decoder.c: little hack for preventing blank alpha 
+    palette.
+  * ./plugins/spudec/spu_decoder.c: subtitle transparency support.
   * ./plugins/macosx: new controls for audio output, and deinterlacing
     support.
   * ./plugins/macosx: fixed a bug with language and subtitle menus.
index 8348410..c64dee0 100644 (file)
@@ -1,7 +1,7 @@
 /* dvd_es.c: functions to find and select ES
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: dvd_es.c,v 1.13 2002/06/02 13:49:35 sam Exp $
+ * $Id: dvd_es.c,v 1.14 2002/06/27 19:46:32 sam Exp $
  *
  * Author: St├ęphane Borel <stef@via.ecp.fr>
  *
@@ -306,8 +306,19 @@ void DVDLaunchDecoders( input_thread_t * p_input )
         }
         if( i_spu > 0 )
         {
-            i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb;
-            input_SelectES( p_input, p_input->stream.pp_es[i_spu] );
+            int i = 0, j = 0;
+            for( i = 0; i < p_input->stream.i_es_number; i++ )
+            {
+                if ( p_input->stream.pp_es[i]->i_type == DVD_SPU_ES )
+                {
+                    j++;
+                    if ( i_spu == j ) break;
+                }
+            }
+            if( i_spu == j )
+            {
+                input_SelectES( p_input, p_input->stream.pp_es[i] );
+            }
         }
     }
 }
index 5b0f42b..ac68502 100644 (file)
@@ -2,7 +2,7 @@
  * spu_decoder.c : spu decoder thread
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: spu_decoder.c,v 1.28 2002/06/05 18:18:49 stef Exp $
+ * $Id: spu_decoder.c,v 1.29 2002/06/27 19:46:32 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Rudolf Cornelissen <rag.cornelissen@inter.nl.net>
@@ -378,7 +378,7 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
     u8  i_command;
     int i_date;
 
-    int i;
+    int i, pi_alpha[4];
 
     /* XXX: temporary variables */
     vlc_bool_t b_force_display = 0;
@@ -444,9 +444,16 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
                                         p_demux_data + sizeof(int)))[
                                           GetBits(&p_spudec->bit_stream, 4) ];
 
+                            /* FIXME: this job should be done sooner */
+#ifndef WORDS_BIGENDIAN
                             p_spu->p_sys->pi_yuv[3-i][0] = (i_color>>16) & 0xff;
                             p_spu->p_sys->pi_yuv[3-i][1] = (i_color>>0) & 0xff;
                             p_spu->p_sys->pi_yuv[3-i][2] = (i_color>>8) & 0xff;
+#else
+                            p_spu->p_sys->pi_yuv[3-i][0] = (i_color>>8) & 0xff;
+                            p_spu->p_sys->pi_yuv[3-i][1] = (i_color>>24) & 0xff;
+                            p_spu->p_sys->pi_yuv[3-i][2] = (i_color>>16) & 0xff;
+#endif
                         }
                     }
                     else
@@ -460,11 +467,26 @@ static int ParseControlSequences( spudec_thread_t *p_spudec,
                 case SPU_CMD_SET_ALPHACHANNEL:
  
                     /* 04xxxx (alpha channel) */
-                    for( i = 0; i < 4 ; i++ )
+                    pi_alpha[3] = GetBits( &p_spudec->bit_stream, 4 );
+                    pi_alpha[2] = GetBits( &p_spudec->bit_stream, 4 );
+                    pi_alpha[1] = GetBits( &p_spudec->bit_stream, 4 );
+                    pi_alpha[0] = GetBits( &p_spudec->bit_stream, 4 );
+
+                    /* Ignore blank alpha palette. Sometimes spurious blank
+                     * alpha palettes are present - dunno why. */
+                    if( pi_alpha[0] | pi_alpha[1] | pi_alpha[2] | pi_alpha[3] )
+                    {
+                        p_spu->p_sys->pi_alpha[0] = pi_alpha[0];
+                        p_spu->p_sys->pi_alpha[1] = pi_alpha[1];
+                        p_spu->p_sys->pi_alpha[2] = pi_alpha[2];
+                        p_spu->p_sys->pi_alpha[3] = pi_alpha[3];
+                    }
+                    else
                     {
-                        p_spu->p_sys->pi_alpha[3-i]
-                                       = GetBits( &p_spudec->bit_stream, 4 );
+                        msg_Warn( p_spudec->p_fifo,
+                                  "ignoring blank alpha palette" );
                     }
+
                     i_index += 2;
  
                     break;
@@ -827,10 +849,11 @@ static void RenderSPU( vout_thread_t *p_vout, picture_t *p_pic,
     u16  p_clut16[4];
     u32  p_clut32[4];
     u8  *p_dest;
+    u8  *p_destptr = (u8 *)p_dest;
     u16 *p_source = (u16 *)p_spu->p_sys->p_data;
 
     int i_x, i_y;
-    int i_len, i_color;
+    int i_len, i_color, i_colprecomp, i_destalpha;
     u8  i_cnt;
 
     /* RGB-specific */
@@ -856,28 +879,37 @@ static void RenderSPU( vout_thread_t *p_vout, picture_t *p_pic,
         {
             /* Get the RLE part, then draw the line */
             i_color = *p_source & 0x3;
+            i_len = *p_source++ >> 2;
 
             switch( p_spu->p_sys->pi_alpha[ i_color ] )
             {
                 case 0x00:
-                    i_x -= *p_source++ >> 2;
                     break;
 
                 case 0x0f:
-                    i_len = *p_source++ >> 2;
                     memset( p_dest - i_x - i_y,
                             p_spu->p_sys->pi_yuv[i_color][0], i_len );
-                    i_x -= i_len;
                     break;
 
                 default:
-                    /* FIXME: we should do transparency */
-                    i_len = *p_source++ >> 2;
-                    memset( p_dest - i_x - i_y,
-                            p_spu->p_sys->pi_yuv[i_color][0], i_len );
-                    i_x -= i_len;
+                    /* To be able to divide by 16 (>>4) we add 1 to the alpha.
+                     * This means Alpha 0 won't be completely transparent, but
+                     * that's handled in a special case above anyway. */
+                    i_colprecomp = p_spu->p_sys->pi_yuv[i_color][0]
+                                    * (p_spu->p_sys->pi_alpha[ i_color ] + 1);
+                    i_destalpha = 15 - p_spu->p_sys->pi_alpha[ i_color ];
+
+                    for ( p_destptr = p_dest - i_x - i_y;
+                          p_destptr < p_dest - i_x - i_y + i_len;
+                          p_destptr++ )
+                    {
+                        *p_destptr = ( i_colprecomp +
+                                        *p_destptr * i_destalpha ) >> 4;
+                    }
                     break;
+
             }
+            i_x -= i_len;
         }
     }