By Date: <-- -->
By Thread: <-- -->

Patch to fix tvtime with CX88 and Closed Captions, on 525 lines standards



For those who use tvtime with cx88 boards, this is a fix for tvtime for Closed Captions.

There's a trouble with tvtime's vbi support. It just assumes that all
VBI data have 2048 samples, and 16 lines. This is not true for cx88
boards, with collects 17 lines, instead of 16. The enclosed patch is a
quick fix that uses V4L api to check if VBI is receiving 2048
samples/line and if it collects enough data. The VBI size/frame is
calculated based on samples/line and numbers of captured vbi lines.

After this patch and some fixes on VBI code for cx88, CC will now work
fine for NTSC and PAL/M.

Cheers, 
Mauro.
Index: tvtime.c
===================================================================
RCS file: /cvsroot/tvtime/tvtime/src/tvtime.c,v
retrieving revision 1.486
diff -u -p -r1.486 tvtime.c
--- tvtime.c	16 Nov 2005 05:09:37 -0000	1.486
+++ tvtime.c	13 May 2006 14:42:31 -0000
 (at)  (at)  -1204,6 +1204,7  (at)  (at)  int tvtime_main( rtctimer_t *rtctimer, i
     int matte_y = 0;
     int matte_h = 0;
     int matte_mode = 0;
+    int vbi_size = 0;
     int restarttvtime = 0;
     int return_value = 0;
     int last_current_id = -1;
 (at)  (at)  -1526,7 +1527,11  (at)  (at)  int tvtime_main( rtctimer_t *rtctimer, i
     }
 
     /* Setup VBI stuff for NTSC-like norms. */
-    if( vidin && height == 480 ) {
+    vbi_size = videoinput_get_vbi_size ( vidin );
+    if( verbose ) {
+        fprintf( stderr, "tvtime: vbi size is %d bytes\n", vbi_size );
+    }
+    if( vidin && height == 480 && vbi_size > 0 ) {
         vs = vbiscreen_new( width, height, pixel_aspect, verbose );
         if( !vs ) {
             lfputs( _("Closed caption display failed to "
 (at)  (at)  -2359,11 +2364,12  (at)  (at)  int tvtime_main( rtctimer_t *rtctimer, i
                 if( secondlastframeid >= 0 )
                     videoinput_free_frame( vidin, secondlastframeid );
                 if( vbidata )
-                    vbidata_process_frame( vbidata, printdebug );
+                    vbidata_process_frame( vbidata, vbi_size, printdebug );
             } else if( fieldsavailable == 2 ) {
                if( lastframeid >= 0 )
                    videoinput_free_frame( vidin, lastframeid );
-                if( vbidata ) vbidata_process_frame( vbidata, printdebug );
+                if( vbidata )
+                   vbidata_process_frame( vbidata, vbi_size, printdebug );
             }
         }
 
 (at)  (at)  -2508,7 +2514,8  (at)  (at)  int tvtime_main( rtctimer_t *rtctimer, i
             } else {
                 if( curframeid >= 0 )
                     videoinput_free_frame( vidin, curframeid );
-                if( vbidata ) vbidata_process_frame( vbidata, printdebug );
+                if( vbidata )
+                    vbidata_process_frame( vbidata, vbi_size, printdebug );
             }
         }
     }
Index: vbidata.c
===================================================================
RCS file: /cvsroot/tvtime/tvtime/src/vbidata.c,v
retrieving revision 1.49
diff -u -p -r1.49 vbidata.c
--- vbidata.c	15 Nov 2005 14:27:31 -0000	1.49
+++ vbidata.c	13 May 2006 14:42:32 -0000
 (at)  (at)  -43,7 +43,8  (at)  (at)  struct vbidata_s
     int fd;
     int open;
     vbiscreen_t *vs;
-    uint8_t buf[ 65536 ];
+    uint8_t *buf;
+    int size;
     int wanttop;
     int wanttext;
 
 (at)  (at)  -979,6 +980,8  (at)  (at)  vbidata_t *vbidata_new( const char *file
     }
 
     vbi->open = 0;
+    vbi->buf = NULL;
+    vbi->size = 0;
     vbi->usexds = 0;
     vbi->vs = vs;
     vbi->verbose = verbose;
 (at)  (at)  -1008,6 +1011,7  (at)  (at)  static void vbidata_close_device( vbidat
 void vbidata_delete( vbidata_t *vbi )
 {
     if( vbi->open ) vbidata_close_device( vbi );
+    if ( vbi->buf ) free ( vbi->buf );
     free( vbi );
 }
 
 (at)  (at)  -1149,10 +1153,18  (at)  (at)  void vbidata_capture_xds( vbidata_t *vbi
     }
 }
 
-void vbidata_process_frame( vbidata_t *vbi, int printdebug )
+void vbidata_process_frame( vbidata_t *vbi, int size, int printdebug )
 {
+    /* At least, 11 VBI lines with 2048 samples is required */
+    if ( size < 2048*12-1 )
+	return;
     if( vbi->open ) {
-        if( read( vbi->fd, vbi->buf, 65536 ) < 65536 ) {
+	if ( vbi->size<size ) {
+		free ( vbi->buf );
+		vbi->buf=malloc( size );
+		vbi->size=size;
+	}
+        if ( read( vbi->fd, vbi->buf, size ) != size ) {
             if( vbi->verbose ) {
                 fprintf( stderr, "vbidata: Can't read vbi data: %s\n",
                          strerror( errno ) );
Index: vbidata.h
===================================================================
RCS file: /cvsroot/tvtime/tvtime/src/vbidata.h,v
retrieving revision 1.13
diff -u -p -r1.13 vbidata.h
--- vbidata.h	9 Sep 2003 17:30:18 -0000	1.13
+++ vbidata.h	13 May 2006 14:42:32 -0000
 (at)  (at)  -55,7 +55,7  (at)  (at)  vbidata_t *vbidata_new( const char *file
 void vbidata_delete( vbidata_t *vbi );
 void vbidata_reset( vbidata_t *vbi );
 void vbidata_capture_mode( vbidata_t *vbi, int mode );
-void vbidata_process_frame( vbidata_t *vbi, int printdebug );
+void vbidata_process_frame( vbidata_t *vbi, int size, int printdebug );
 
 void vbidata_capture_xds( vbidata_t *vbi, int xds );
 
Index: videoinput.c
===================================================================
RCS file: /cvsroot/tvtime/tvtime/src/videoinput.c,v
retrieving revision 1.124
diff -u -p -r1.124 videoinput.c
--- videoinput.c	8 Sep 2005 03:20:05 -0000	1.124
+++ videoinput.c	13 May 2006 14:42:35 -0000
 (at)  (at)  -424,6 +424,49  (at)  (at)  int videoinput_buffer_invalid( videoinpu
     }
 }
 
+int videoinput_get_vbi_size ( videoinput_t *vidin )
+{
+    int ret, samples=0, count0=0, count1=0;
+
+    if( vidin->isv4l2 ) {
+        struct v4l2_format v2;
+
+        memset( &v2,0,sizeof(v2) );
+        v2.type = V4L2_BUF_TYPE_VBI_CAPTURE;
+        ret = ioctl( vidin->grab_fd, VIDIOC_G_FMT, (void *) &v2 );
+	if (!ret) {
+            samples = v2.fmt.vbi.samples_per_line;
+            count0 = v2.fmt.vbi.count[0];
+	    count1 = v2.fmt.vbi.count[1];
+        }
+    } else {
+        struct vbi_format  v1;
+
+        memset(&v1,0,sizeof(v1));
+        ret=ioctl(vidin->grab_fd, VIDIOCGVBIFMT, (void *) &v1);
+	if (!ret) {
+            samples = v1.samples_per_line;
+            count0 = v1.count[0];
+	    count1 = v1.count[1];
+        }
+    }
+    if ( ret<0 ) {
+       fprintf( stderr, "videoinput: VBI is not supported by device.\n");
+       return ( 0 );
+    }
+    if (samples != 2048) {
+        fprintf( stderr, "videoinput: VBI number of samples by line (%d) is not supported.\n",
+                 samples);
+	return ( 0 );
+    }
+    if (count0 < 12) {
+        fprintf( stderr, "videoinput: VBI capture lines is not enough for CC (%d).\n",
+                 count0);
+	return ( 0 );
+    }
+    return ( count0 + count1 ) * samples;
+}
+
 videoinput_t *videoinput_new( const char *v4l_device, int capwidth,
                               int volume, int norm, int verbose, char *error_string )
 {
Index: videoinput.h
===================================================================
RCS file: /cvsroot/tvtime/tvtime/src/videoinput.h,v
retrieving revision 1.33
diff -u -p -r1.33 videoinput.h
--- videoinput.h	8 Sep 2005 03:20:05 -0000	1.33
+++ videoinput.h	13 May 2006 14:42:36 -0000
 (at)  (at)  -99,6 +99,11  (at)  (at)  int videoinput_get_time_per_field( int n
 const char *videoinput_get_audio_mode_name( videoinput_t *vidin, int mode );
 
 /**
+ * Checks for expected VBI parameters and calculates packet size
+ */
+int videoinput_get_vbi_size ( videoinput_t *vidin );
+
+/**
  * Create a new input device from the given device name and which input
  * number (cable, composite1, composite2, etc) to use.
  *
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request (at) redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list