[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