[MPlayer-dev-eng] [PATCH] fix closed caption display for TiVo/tystreams

Doug Swarin dswarin at gmail.com
Wed Aug 16 06:47:59 CEST 2006


Thanks very much to the people who pointed out the rules to patches
for me. I apologize for submitting incorrectly before. This patch has
been updated to apply against the latest SVN trunk and follows all the
rules from http://www.mplayerhq.hu/DOCS/tech/patches.txt.

This patch changes the '-subcc' option to take an integer argument,
where '-subcc 1' displays the normal Closed Caption data, and '-subcc
2' will display the XDS data. '-subcc 3' will display both.

It fixes the tystream code to properly display Closed Caption
subtitles (before, only the XDS data would be displayed, and that
erratically). Also, it corrects roll-up captions to not immediately
overwrite themselves.

All documentation has been updated (although I do not speak any
language other than English, so I was unable to give directions for
anything but -subcc 1 in the other documentation).

Thanks,
Doug
-------------- next part --------------
Index: DOCS/man/zh/mplayer.1
===================================================================
--- DOCS/man/zh/mplayer.1	(revision 19412)
+++ DOCS/man/zh/mplayer.1	(working copy)
@@ -854,7 +854,7 @@
 ??????????OSD????????????. ????????????????????????????????????????????.
 255????????0????????.
 .TP
-.B \-subcc \
+.B \-subcc 1 \
 ????DVD????????????????(CC)????.
 ????????VOB????, ????????????????????????????????ASCII????,
 ??????????????????1??VOB??????????????.
Index: DOCS/man/en/mplayer.1
===================================================================
--- DOCS/man/en/mplayer.1	(revision 19412)
+++ DOCS/man/en/mplayer.1	(working copy)
@@ -1992,14 +1992,17 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
-Display DVD Closed Caption (CC) subtitles.
+.B \-subcc <0\-3> \ 
+Display Closed Caption (CC) or Extended Data Service (XDS) subtitles.
 These are
 .B not
 the VOB subtitles, these are special ASCII subtitles for the
 hearing impaired encoded in the VOB userdata stream on most region 1 DVDs.
 CC subtitles have not been spotted on DVDs from other regions so far.
 .
+Passing -subcc 1 will show Closed Caption subtitles. Passing -subcc 2 will
+show XDS subtitles. Passing -subcc 3 will show both types.
+.
 .TP
 .B \-subcp <codepage> (iconv only)
 If your system supports iconv(3), you can use this option to
Index: DOCS/man/cs/mplayer.1
===================================================================
--- DOCS/man/cs/mplayer.1	(revision 19412)
+++ DOCS/man/cs/mplayer.1	(working copy)
@@ -1877,7 +1877,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Zobrazovat DVD Closed Caption (CC) titulky.
 Toto
 .B nejsou
Index: DOCS/man/es/mplayer.1
===================================================================
--- DOCS/man/es/mplayer.1	(revision 19412)
+++ DOCS/man/es/mplayer.1	(working copy)
@@ -1535,7 +1535,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Muestra subt?culos de DVD Closed Caption (CC).
 Esto no es los subt?tulos VOB, son subt?tulos especiales ASCII codificados
 para el que no oye bien en el flujo de datos de usuario VOB en la mayor?a de los
Index: DOCS/man/fr/mplayer.1
===================================================================
--- DOCS/man/fr/mplayer.1	(revision 19412)
+++ DOCS/man/fr/mplayer.1	(working copy)
@@ -2111,7 +2111,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Affiche les sous-titres DVD Closed Caption (CC).
 Ce ne sont
 .B pas
Index: DOCS/man/de/mplayer.1
===================================================================
--- DOCS/man/de/mplayer.1	(revision 19412)
+++ DOCS/man/de/mplayer.1	(working copy)
@@ -2011,7 +2011,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Zeigt DVD-Closed-Caption-Untertitel (CC) an.
 Diese sind
 .B keine
Index: DOCS/man/sv/mplayer.1
===================================================================
--- DOCS/man/sv/mplayer.1	(revision 19412)
+++ DOCS/man/sv/mplayer.1	(working copy)
@@ -1513,7 +1513,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Display DVD Closed Caption (CC) subtitles.
 These are NOT the VOB subtitles, these are special ASCII subtitles for the
 hearing impaired encoded in the VOB userdata stream on most region 1 DVDs.
Index: DOCS/man/pl/mplayer.1
===================================================================
--- DOCS/man/pl/mplayer.1	(revision 19412)
+++ DOCS/man/pl/mplayer.1	(working copy)
@@ -1651,7 +1651,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Wy?wietla napisy DVD Closed Caption (CC).
 To
 .B nie
Index: DOCS/man/hu/mplayer.1
===================================================================
--- DOCS/man/hu/mplayer.1	(revision 19412)
+++ DOCS/man/hu/mplayer.1	(working copy)
@@ -1998,7 +1998,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 DVD Closed Caption (CC) feliratok megjelen?t?se.
 Ezek
 .B nem
Index: DOCS/man/it/mplayer.1
===================================================================
--- DOCS/man/it/mplayer.1	(revision 19412)
+++ DOCS/man/it/mplayer.1	(working copy)
@@ -1921,7 +1921,7 @@
 .PD 1
 .
 .TP
-.B \-subcc \ 
+.B \-subcc 1 \ 
 Visualizza i sottotitoli Close Caption (CC) dei DVD.
 Questi
 .B non
Index: cfg-common.h
===================================================================
--- cfg-common.h	(revision 19412)
+++ cfg-common.h	(working copy)
@@ -270,8 +270,7 @@
 	// specify IFO file for VOBSUB subtitle
 	{"ifo", &spudec_ifo, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	// enable Closed Captioning display
-	{"subcc", &subcc_enabled, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-	{"nosubcc", &subcc_enabled, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+	{"subcc", &subcc_enabled, CONF_TYPE_INT, 0, 0, 1, NULL},
 	{"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL},
 	{"nooverlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 0, NULL},
 	{"sub-bg-color", &sub_bg_color, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
Index: libmpdemux/demux_ty.c
===================================================================
--- libmpdemux/demux_ty.c	(revision 19412)
+++ libmpdemux/demux_ty.c	(working copy)
@@ -116,7 +116,7 @@
 } TiVoInfo;
 
 off_t vstream_streamsize( );
-void ty_ClearOSD( int start );
+void ty_ClearOSD( int start, int osd );
 
 // ===========================================================================
 #define TMF_SIG "showing.xml"
@@ -1332,7 +1332,7 @@
    }
 	if ( subcc_enabled )
 	{
-	   ty_ClearOSD( 0 );
+	   ty_ClearOSD( 0, 0 );
 	}
 }
 
Index: libmpdemux/demux_ty_osd.c
===================================================================
--- libmpdemux/demux_ty_osd.c	(revision 19412)
+++ libmpdemux/demux_ty_osd.c	(working copy)
@@ -46,6 +46,7 @@
 #define TY_CCPAINTON  (  1 )
 
 #define TY_CC_MAX_X   ( 45 )
+#define TY_CC_MAX_Y   (  4 )
 
 static int      TY_CC_CUR_X;
 static int      TY_CC_CUR_Y;
@@ -65,20 +66,34 @@
 
 static void ty_DrawOSD(void)
 {
+	int index;
 	// printf( "Calling ty_DrawOSD()\n" );
+    for ( index = 1; index < SUB_MAX_TEXT ; index++ )
+	{
+		memcpy( ty_OSD1.text[ index ], ty_OSD2.text[ index ], TY_CC_MAX_X - 1 );
+		ty_OSD1.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
+	}
 	tyOSDUpdate = 1;
 }
 
-void ty_ClearOSD( int start )
+void ty_ClearOSD( int start, int osd )
 {
 	int index;
 	// printf( "Calling ty_ClearOSD()\n" );
    for ( index = start ; index < SUB_MAX_TEXT ; index++ )
 	{
-		memset( ty_OSD1.text[ index ], ' ', TY_CC_MAX_X - 1 );
-		ty_OSD1.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
-		memset( ty_OSD2.text[ index ], ' ', TY_CC_MAX_X - 1 );
-		ty_OSD2.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
+
+		if ( osd == 0 || osd == 1 )
+		{
+			memset( ty_OSD1.text[ index ], ' ', TY_CC_MAX_X - 1 );
+			ty_OSD1.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
+		}
+
+		if ( osd == 0 || osd == 2 )
+		{
+			memset( ty_OSD2.text[ index ], ' ', TY_CC_MAX_X - 1 );
+			ty_OSD2.text[ index ][ TY_CC_MAX_X - 1 ] = 0;
+		}
 	}
 }
 
@@ -99,11 +114,11 @@
 	   cy = SUB_MAX_TEXT - TY_CC_Y_Offset - 1;
    }
 
-	// printf( "Calling ty_DrawChar() x:%d y:%d %c fg:%d bg:%d\n",
-	// 	cx, cy, disChar, fgColor, bgColor );
+	// printf( "Calling ty_DrawChar() x:%d y:%d '%c' fg:%d bg:%d\n",
+	//	cx, cy, disChar, fgColor, bgColor );
 
-   ty_OSD1.text[ TY_CC_Y_Offset + cy ][ cx ] = disChar;
-   memset( &( ty_OSD1.text[ TY_CC_Y_Offset + cy ][ cx + 1 ] ), ' ',
+   ty_OSD2.text[ TY_CC_Y_Offset + cy ][ cx ] = disChar;
+   memset( &( ty_OSD2.text[ TY_CC_Y_Offset + cy ][ cx + 1 ] ), ' ',
       TY_CC_MAX_X - cx - 2 );
 	( *x )++;
 }
@@ -117,37 +132,37 @@
 	//
 	if ( ( source + TY_CC_Y_Offset + numLines ) > SUB_MAX_TEXT )
 	{
-      ty_ClearOSD( 1 );
+      ty_ClearOSD( 1, 1 );
 		return;
 	}
 
 	if ( ( source + TY_CC_Y_Offset + numLines ) < 0 )
 	{
-      ty_ClearOSD( 1 );
+      ty_ClearOSD( 1, 1 );
 		return;
 	}
 
 	if ( numLines > SUB_MAX_TEXT )
 	{
-      ty_ClearOSD( 1 );
+      ty_ClearOSD( 1, 1 );
 		return;
 	}
 
 	for ( index = 0 ; index < numLines ; index++ )
 	{
-		strcpy( ty_OSD1.text[ TY_CC_Y_Offset + dest ],
-			ty_OSD1.text[ TY_CC_Y_Offset + source ] );
+		strcpy( ty_OSD2.text[ TY_CC_Y_Offset + dest ],
+			ty_OSD2.text[ TY_CC_Y_Offset + source ] );
 	   dest++;
 		source++;
 	}
-	memset( ty_OSD1.text[ TY_CC_Y_Offset + source - 1 ], ' ', TY_CC_MAX_X - 1 );
-	ty_OSD1.text[ TY_CC_Y_Offset + source - 1 ][ TY_CC_MAX_X - 1 ] = 0;
+	memset( ty_OSD2.text[ TY_CC_Y_Offset + source - 1 ], ' ', TY_CC_MAX_X - 1 );
+	ty_OSD2.text[ TY_CC_Y_Offset + source - 1 ][ TY_CC_MAX_X - 1 ] = 0;
 }
 
 static void ty_drawchar( char c )
 {
    if ( c < 2 ) return;
-  
+
    if ( TY_OSD_flags & TY_OSD_MODE && TY_CC_stat != TY_CCNONE && 
       TY_CC_CUR_Y != -1 )
       ty_DrawChar( &TY_CC_CUR_X, &TY_CC_CUR_Y, c, 4, 13 );
@@ -185,6 +200,8 @@
    11, -1, 1, 2, 3, 4, 12, 13, 14, 15, 5, 6, 7, 8, 9, 10 
 };
 
+// these are kind of poor substitutes for the actual special characters
+char specialchar[] = { 'R', 'o', '/', '?', '*', 'c', 'E', '/', 'a', ' ', 'e', 'a', 'e', 'i', 'o', 'u' };
 // char specialchar[] = { '??', '??', '??', '??', '*', '??', '??', 14, '??', ' ', '??', '??', '??', '??', '??', '??' };
 
 static int ty_CCdecode( char b1, char b2 )
@@ -235,15 +252,19 @@
          TY_CC_CUR_Y = CC_row[ ( ( b1 << 1 ) & 14 ) | ( ( b2 >> 5 ) & 1 ) ];
 
 			// Offset into MPlayer's Buffer
-			if ( ( TY_CC_CUR_Y >= 1 ) && ( TY_CC_CUR_Y <= 4 ) )
+         		if ( TY_CC_stat > TY_CCPAINTON ) {
+				TY_CC_CUR_Y = TY_CC_MAX_Y;
+				TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 1;
+			}
+			else if ( ( TY_CC_CUR_Y >= 1 ) && ( TY_CC_CUR_Y <= 4 ) )
 			{
 				TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 1;
 			}
-			if ( ( TY_CC_CUR_Y >= 5 ) && ( TY_CC_CUR_Y <= 10 ) )
+			else if ( ( TY_CC_CUR_Y >= 5 ) && ( TY_CC_CUR_Y <= 10 ) )
 			{
 				TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 5;
 			}
-			if ( ( TY_CC_CUR_Y >= 12 ) && ( TY_CC_CUR_Y <= 15 ) )
+			else if ( ( TY_CC_CUR_Y >= 12 ) && ( TY_CC_CUR_Y <= 15 ) )
 			{
 				TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 12;
 			}
@@ -332,8 +353,8 @@
                      } 
                      else 
                      {
-                        // ty_drawchar(specialchar[ b2 & 0x0f ] );
-                        ty_drawchar( ' ' );
+                        ty_drawchar( specialchar[ b2 & 0x0f ] );
+                        // ty_drawchar( ' ' );
                      }
                      break;
                   }
@@ -352,7 +373,7 @@
                   {
                      if ( TY_OSD_flags & TY_OSD_MODE && 
                         TY_CC_stat != TY_CCPOPUP ) 
-								ty_ClearOSD( 1 );
+								ty_ClearOSD( 1, 2 );
                      TY_CC_stat = TY_CCPOPUP;
                      break;
                   }
@@ -365,9 +386,10 @@
               
                   case 0x25 ... 0x27:       // 2-4 row captions
                   {
-                     if ( TY_CC_stat == TY_CCPOPUP ) ty_ClearOSD( 1 );
+                     if ( TY_CC_stat == TY_CCPOPUP ) ty_ClearOSD( 1, 2 );
                      TY_CC_stat = b2 - 0x23;
-                     if ( TY_CC_CUR_Y < TY_CC_stat ) TY_CC_CUR_Y = TY_CC_stat;
+		     TY_CC_CUR_Y = TY_CC_MAX_Y;
+		     TY_CC_Y_Offset = SUB_MAX_TEXT - 5 - 1;
                      break;
                   }
 
@@ -396,12 +418,12 @@
                      {
                         if ( TY_CC_stat > TY_CCPOPUP || TY_CC_ptr == TY_CC_buf ) 
                         {
-                           ty_ClearOSD( 1 );
+                           ty_ClearOSD( 1, 1 );
                            ty_draw();
                         } 
                         else 
                         { 
-                           ty_ClearOSD( 1 );
+                           ty_ClearOSD( 1, 1 );
 
                            // CRW - 
                            // new buffer
@@ -441,7 +463,7 @@
                      if ( TY_OSD_debug && TY_CC_ptr != TY_CC_buf )
                         mp_msg( MSGT_DEMUX, MSGL_DBG3, "(TY_OSD_debug) %s\n", 
                            TY_CC_buf );
-                     if ( TY_OSD_flags & TY_OSD_MODE ) ty_ClearOSD( 1 );
+                     if ( TY_OSD_flags & TY_OSD_MODE ) ty_ClearOSD( 1, 2 );
 
                      TY_CC_CUR_X = 1;
                      TY_CC_CUR_Y = -1;
@@ -870,7 +892,7 @@
 				ty_OSD1.text[ index ] = malloc( TY_CC_MAX_X );
 				ty_OSD2.text[ index ] = malloc( TY_CC_MAX_X );
 			}
-			ty_ClearOSD( 0 );
+			ty_ClearOSD( 0, 0 );
 			ty_OSD1.lines = SUB_MAX_TEXT;
 			ty_OSD2.lines = SUB_MAX_TEXT;
 			ty_pOSD1 = &ty_OSD1;
@@ -879,11 +901,11 @@
 			tyOSDInited = 1;
 		}
 
-		if ( buf[ 0 ] == 0x01 )
+		if ( buf[ 0 ] == 0x01 && ( subcc_enabled & 0x01 ) )
 		{
 			ty_CCdecode( buf[ 1 ], buf[ 2 ] );
 		}
-		if ( buf[ 0 ] == 0x02 )
+		if ( buf[ 0 ] == 0x02 && ( subcc_enabled & 0x02 ) )
 		{
 			ty_XDSdecode( buf[ 1 ], buf[ 2 ] );
 		}


More information about the MPlayer-dev-eng mailing list