[vlc-commits] Remove memory copy in V4L2 demux in read/write mode

Rémi Denis-Courmont git at videolan.org
Tue Sep 6 19:33:08 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Sep  6 20:32:26 2011 +0300| [bf1b0d63adc001f71377bb40e80932277d3ac4a9] | committer: Rémi Denis-Courmont

Remove memory copy in V4L2 demux in read/write mode

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bf1b0d63adc001f71377bb40e80932277d3ac4a9
---

 modules/access/v4l2/access.c |   12 ++++++--
 modules/access/v4l2/demux.c  |   58 ++++++++++++++++++++++++++++++++---------
 modules/access/v4l2/v4l2.h   |    1 +
 modules/access/v4l2/video.c  |   55 ++-------------------------------------
 4 files changed, 58 insertions(+), 68 deletions(-)

diff --git a/modules/access/v4l2/access.c b/modules/access/v4l2/access.c
index c4ca7dc..7dafa41 100644
--- a/modules/access/v4l2/access.c
+++ b/modules/access/v4l2/access.c
@@ -88,10 +88,16 @@ static block_t *AccessRead( access_t *access )
 
     /* Wait for data */
     /* FIXME: kill timeout */
-    if( poll( &fd, 1, 500 ) > 0 )
-        return GrabVideo( VLC_OBJECT(access), sys );
+    if( poll( &fd, 1, 500 ) <= 0 )
+        return NULL;
 
-    return NULL;
+    block_t *block = GrabVideo( VLC_OBJECT(access), sys );
+    if( block != NULL )
+    {
+        block->i_pts = block->i_dts = mdate();
+        block->i_flags |= sys->i_block_flags;
+    }
+    return block;
 }
 
 static ssize_t AccessReadStream( access_t *access, uint8_t *buf, size_t len )
diff --git a/modules/access/v4l2/demux.c b/modules/access/v4l2/demux.c
index e6008f4..f9c056a 100644
--- a/modules/access/v4l2/demux.c
+++ b/modules/access/v4l2/demux.c
@@ -147,32 +147,64 @@ static int DemuxControl( demux_t *demux, int query, va_list args )
     return VLC_EGENERIC;
 }
 
+/** Gets a frame in read/write mode */
+static block_t *BlockRead( vlc_object_t *obj, int fd, size_t size )
+{
+    block_t *block = block_Alloc( size );
+    if( unlikely(block == NULL) )
+        return NULL;
+
+    ssize_t val = v4l2_read( fd, block->p_buffer, size );
+    if( val == -1 )
+    {
+        block_Release( block );
+        switch( errno )
+        {
+            case EAGAIN:
+                return NULL;
+            case EIO: /* could be ignored per specification */
+                /* fall through */
+            default:
+                msg_Err( obj, "cannot read frame: %m" );
+                return NULL;
+        }
+    }
+    block->i_buffer = val;
+    return block;
+}
+
 static int Demux( demux_t *demux )
 {
     demux_sys_t *sys = demux->p_sys;
-    struct pollfd fd;
+    struct pollfd ufd;
 
-    fd.fd = sys->i_fd;
-    fd.events = POLLIN|POLLPRI;
+    ufd.fd = sys->i_fd;
+    ufd.events = POLLIN|POLLPRI;
     /* Wait for data */
     /* FIXME: remove timeout */
-    while( poll( &fd, 1, 500 ) == -1 )
+    while( poll( &ufd, 1, 500 ) == -1 )
         if( errno != EINTR )
         {
             msg_Err( demux, "poll error: %m" );
             return -1;
         }
 
-    if( fd.revents )
-    {
-         block_t *p_block = GrabVideo( VLC_OBJECT(demux), sys );
-         if( p_block )
-         {
-             es_out_Control( demux->out, ES_OUT_SET_PCR, p_block->i_pts );
-             es_out_Send( demux->out, sys->p_es, p_block );
-        }
-    }
+    if( ufd.revents == 0 )
+        return 1;
+
+    block_t *block;
+
+    if( sys->io == IO_METHOD_READ )
+        block = BlockRead( VLC_OBJECT(demux), ufd.fd, sys->blocksize );
+    else
+        block = GrabVideo( VLC_OBJECT(demux), sys );
+    if( block == NULL )
+        return 1;
 
+    block->i_pts = block->i_dts = mdate();
+    block->i_flags |= sys->i_block_flags;
+    es_out_Control( demux->out, ES_OUT_SET_PCR, block->i_pts );
+    es_out_Send( demux->out, sys->p_es, block );
     return 1;
 }
 
diff --git a/modules/access/v4l2/v4l2.h b/modules/access/v4l2/v4l2.h
index 3959d93..8267e78 100644
--- a/modules/access/v4l2/v4l2.h
+++ b/modules/access/v4l2/v4l2.h
@@ -60,6 +60,7 @@ struct demux_sys_t
 
     struct buffer_t *p_buffers;
     unsigned int i_nbuffers;
+#define blocksize i_nbuffers /* HACK HACK */
 
     int i_fourcc;
     uint32_t i_block_flags;
diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index fb46f80..5a1d022 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -494,34 +494,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys )
 {
     block_t *p_block;
     struct v4l2_buffer buf;
-    ssize_t i_ret;
 
     /* Grab Video Frame */
     switch( p_sys->io )
     {
-    case IO_METHOD_READ:
-        i_ret = v4l2_read( p_sys->i_fd, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length );
-        if( i_ret == -1 )
-        {
-            switch( errno )
-            {
-            case EAGAIN:
-                return NULL;
-            case EIO:
-                /* Could ignore EIO, see spec. */
-                /* fall through */
-            default:
-                msg_Err( p_demux, "Failed to read frame" );
-                return 0;
-               }
-        }
-
-        p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start, i_ret );
-        if( !p_block )
-            return NULL;
-
-        break;
-
     case IO_METHOD_MMAP:
         memset( &buf, 0, sizeof(buf) );
         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -608,14 +584,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys )
             block_Release( p_block );
             return NULL;
         }
-
         break;
+    default:
+        assert(0);
     }
-
-    /* Timestamp */
-    p_block->i_pts = p_block->i_dts = mdate();
-    p_block->i_flags |= p_sys->i_block_flags;
-
     return p_block;
 }
 
@@ -643,25 +615,6 @@ static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size
 }
 
 /*****************************************************************************
- * Helper function to initalise video IO using the Read method
- *****************************************************************************/
-static int InitRead( vlc_object_t *p_demux, demux_sys_t *p_sys, unsigned int i_buffer_size )
-{
-    (void)p_demux;
-
-    p_sys->p_buffers = calloc( 1, sizeof( *p_sys->p_buffers ) );
-    if( unlikely(p_sys->p_buffers == NULL) )
-        return -1;
-
-    p_sys->p_buffers[0].length = i_buffer_size;
-    p_sys->p_buffers[0].start = malloc( i_buffer_size );
-    if( !p_sys->p_buffers[0].start )
-        return -1;
-
-    return 0;
-}
-
-/*****************************************************************************
  * Helper function to initalise video IO using the mmap method
  *****************************************************************************/
 static int InitMmap( vlc_object_t *p_demux, demux_sys_t *p_sys, int i_fd )
@@ -1408,13 +1361,11 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
     }
 #endif
 
-
     /* Init I/O method */
     switch( p_sys->io )
     {
     case IO_METHOD_READ:
-        if( b_demux && InitRead( p_obj, p_sys, fmt.fmt.pix.sizeimage ) )
-            goto error;
+        p_sys->blocksize = fmt.fmt.pix.sizeimage;
         break;
 
     case IO_METHOD_MMAP:



More information about the vlc-commits mailing list