[vlc-devel] [PATCH 2/3] v4l2: make VBI mode work with UserPtr and ReadStream mode

Devin Heitmueller dheitmueller at kernellabs.com
Sun Oct 21 22:01:01 CEST 2012


The commit with the original VBI support only worked with
Mmap mode.  Extend the code to work in the other two modes
as well.
---
 modules/access/v4l2/demux.c |  146 +++++++++++++++++++++++++++++++++----------
 1 file changed, 112 insertions(+), 34 deletions(-)

diff --git a/modules/access/v4l2/demux.c b/modules/access/v4l2/demux.c
index 21e1709..a2dbbb2 100644
--- a/modules/access/v4l2/demux.c
+++ b/modules/access/v4l2/demux.c
@@ -571,11 +571,27 @@ static void *UserPtrThread (void *data)
     demux_t *demux = data;
     demux_sys_t *sys = demux->p_sys;
     int fd = sys->fd;
-    struct pollfd ufd[1];
-
+    struct pollfd ufd[2];
+    nfds_t numfds = 1;
+    
     ufd[0].fd = fd;
     ufd[0].events = POLLIN;
 
+#ifdef ZVBI_COMPILED
+    if ( sys->vbi_cap )
+    {
+        ufd[1].fd = vbi_capture_fd(sys->vbi_cap);
+        ufd[1].events = POLLIN;
+        ufd[1].revents = 0;
+        numfds++;
+
+        /* Do a single read and throw away the results so that ZVBI calls
+           the STREAMON ioctl() */
+        GrabVBI( VLC_OBJECT(demux), sys->vbi_cap, sys->vbi_sliced,
+                 sys->vbi_sliced_size, sys->vbi_raw );
+    }
+#endif
+    
     int canc = vlc_savecancel ();
     for (;;)
     {
@@ -590,25 +606,48 @@ static void *UserPtrThread (void *data)
         /* Wait for data */
         vlc_restorecancel (canc);
         block_cleanup_push (block);
-        while (poll (ufd, 1, -1) == -1)
+        while (poll (ufd, numfds, -1) == -1)
            if (errno != EINTR)
                msg_Err (demux, "poll error: %m");
         vlc_cleanup_pop ();
         canc = vlc_savecancel ();
 
-        if (v4l2_ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
+        if( ufd[0].revents & POLLIN )
         {
-            msg_Err (demux, "cannot dequeue buffer: %m");
-            block_Release (block);
-            continue;
-        }
+            if (v4l2_ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
+            {
+                msg_Err (demux, "cannot dequeue buffer: %m");
+                block_Release (block);
+                continue;
+            }
 
-        assert (block->p_buffer == (void *)buf.m.userptr);
-        block->i_buffer = buf.length;
-        block->i_pts = block->i_dts = mdate ();
-        block->i_flags |= sys->block_flags;
-        es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
-        es_out_Send (demux->out, sys->es, block);
+            assert (block->p_buffer == (void *)buf.m.userptr);
+            block->i_buffer = buf.length;
+            block->i_pts = block->i_dts = mdate ();
+            block->i_flags |= sys->block_flags;
+            es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
+            es_out_Send (demux->out, sys->es, block);
+        }
+#ifdef ZVBI_COMPILED
+        if( sys->vbi_cap && (ufd[1].revents & POLLIN) )
+        {
+            block_t *p_block =  GrabVBI( VLC_OBJECT(demux), sys->vbi_cap,
+                                         sys->vbi_sliced, sys->vbi_sliced_size,
+                                         sys->vbi_raw );
+            if( p_block )
+            {
+                int i;
+                for (i = 0; i < 4; i++)
+                {
+                    if (i == 3)
+                        es_out_Send( demux->out, sys->p_es_subt[i], p_block );
+                    else
+                        es_out_Send( demux->out, sys->p_es_subt[i],
+                                     block_Duplicate(p_block) );
+                }
+            }
+        }
+#endif
     }
     vlc_restorecancel (canc); /* <- hmm, this is purely cosmetic */
     return NULL;
@@ -693,42 +732,81 @@ static void *ReadThread (void *data)
     demux_t *demux = data;
     demux_sys_t *sys = demux->p_sys;
     int fd = sys->fd;
-    struct pollfd ufd[1];
-
+    struct pollfd ufd[2];
+    nfds_t numfds = 1;
+    
     ufd[0].fd = fd;
     ufd[0].events = POLLIN;
 
+#ifdef ZVBI_COMPILED
+    if ( sys->vbi_cap )
+    {
+        ufd[1].fd = vbi_capture_fd(sys->vbi_cap);
+        ufd[1].events = POLLIN;
+        ufd[1].revents = 0;
+        numfds++;
+
+        /* Do a single read and throw away the results so that ZVBI calls
+           the STREAMON ioctl() */
+        GrabVBI( VLC_OBJECT(demux), sys->vbi_cap, sys->vbi_sliced,
+                 sys->vbi_sliced_size, sys->vbi_raw );
+    }
+#endif
+
     for (;;)
     {
         /* Wait for data */
-        if (poll (ufd, 1, -1) == -1)
+        if (poll (ufd, numfds, -1) == -1)
         {
            if (errno != EINTR)
                msg_Err (demux, "poll error: %m");
            continue;
         }
 
-        block_t *block = block_Alloc (sys->blocksize);
-        if (unlikely(block == NULL))
+        if( ufd[0].revents & POLLIN )
         {
-            msg_Err (demux, "read error: %m");
-            v4l2_read (fd, NULL, 0); /* discard frame */
-            continue;
-        }
-        block->i_pts = block->i_dts = mdate ();
-        block->i_flags |= sys->block_flags;
+            block_t *block = block_Alloc (sys->blocksize);
+            if (unlikely(block == NULL))
+            {
+                msg_Err (demux, "read error: %m");
+                v4l2_read (fd, NULL, 0); /* discard frame */
+                continue;
+            }
+            block->i_pts = block->i_dts = mdate ();
+            block->i_flags |= sys->block_flags;
 
-        int canc = vlc_savecancel ();
-        ssize_t val = v4l2_read (fd, block->p_buffer, block->i_buffer);
-        if (val != -1)
+            int canc = vlc_savecancel ();
+            ssize_t val = v4l2_read (fd, block->p_buffer, block->i_buffer);
+            if (val != -1)
+            {
+                block->i_buffer = val;
+                es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
+                es_out_Send (demux->out, sys->es, block);
+            }
+            else
+                block_Release (block);
+            vlc_restorecancel (canc);
+        }
+#ifdef ZVBI_COMPILED
+        if( sys->vbi_cap && (ufd[1].revents & POLLIN) )
         {
-            block->i_buffer = val;
-            es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
-            es_out_Send (demux->out, sys->es, block);
+            block_t *p_block =  GrabVBI( VLC_OBJECT(demux), sys->vbi_cap,
+                                         sys->vbi_sliced, sys->vbi_sliced_size,
+                                         sys->vbi_raw );
+            if( p_block )
+            {
+                int i;
+                for (i = 0; i < 4; i++)
+                {
+                    if (i == 3)
+                        es_out_Send( demux->out, sys->p_es_subt[i], p_block );
+                    else
+                        es_out_Send( demux->out, sys->p_es_subt[i],
+                                     block_Duplicate(p_block) );
+                }
+            }
         }
-        else
-            block_Release (block);
-        vlc_restorecancel (canc);
+#endif
     }
     assert (0);
 }
-- 
1.7.9.5




More information about the vlc-devel mailing list