Commit bf1b0d63 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Remove memory copy in V4L2 demux in read/write mode

parent 4dfaa105
...@@ -88,10 +88,16 @@ static block_t *AccessRead( access_t *access ) ...@@ -88,10 +88,16 @@ static block_t *AccessRead( access_t *access )
/* Wait for data */ /* Wait for data */
/* FIXME: kill timeout */ /* FIXME: kill timeout */
if( poll( &fd, 1, 500 ) > 0 ) if( poll( &fd, 1, 500 ) <= 0 )
return GrabVideo( VLC_OBJECT(access), sys );
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 ) static ssize_t AccessReadStream( access_t *access, uint8_t *buf, size_t len )
......
...@@ -147,32 +147,64 @@ static int DemuxControl( demux_t *demux, int query, va_list args ) ...@@ -147,32 +147,64 @@ static int DemuxControl( demux_t *demux, int query, va_list args )
return VLC_EGENERIC; 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 ) static int Demux( demux_t *demux )
{ {
demux_sys_t *sys = demux->p_sys; demux_sys_t *sys = demux->p_sys;
struct pollfd fd; struct pollfd ufd;
fd.fd = sys->i_fd; ufd.fd = sys->i_fd;
fd.events = POLLIN|POLLPRI; ufd.events = POLLIN|POLLPRI;
/* Wait for data */ /* Wait for data */
/* FIXME: remove timeout */ /* FIXME: remove timeout */
while( poll( &fd, 1, 500 ) == -1 ) while( poll( &ufd, 1, 500 ) == -1 )
if( errno != EINTR ) if( errno != EINTR )
{ {
msg_Err( demux, "poll error: %m" ); msg_Err( demux, "poll error: %m" );
return -1; return -1;
} }
if( fd.revents ) if( ufd.revents == 0 )
{ return 1;
block_t *p_block = GrabVideo( VLC_OBJECT(demux), sys );
if( p_block ) block_t *block;
{
es_out_Control( demux->out, ES_OUT_SET_PCR, p_block->i_pts ); if( sys->io == IO_METHOD_READ )
es_out_Send( demux->out, sys->p_es, p_block ); 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; return 1;
} }
......
...@@ -60,6 +60,7 @@ struct demux_sys_t ...@@ -60,6 +60,7 @@ struct demux_sys_t
struct buffer_t *p_buffers; struct buffer_t *p_buffers;
unsigned int i_nbuffers; unsigned int i_nbuffers;
#define blocksize i_nbuffers /* HACK HACK */
int i_fourcc; int i_fourcc;
uint32_t i_block_flags; uint32_t i_block_flags;
......
...@@ -494,34 +494,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys ) ...@@ -494,34 +494,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys )
{ {
block_t *p_block; block_t *p_block;
struct v4l2_buffer buf; struct v4l2_buffer buf;
ssize_t i_ret;
/* Grab Video Frame */ /* Grab Video Frame */
switch( p_sys->io ) 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: case IO_METHOD_MMAP:
memset( &buf, 0, sizeof(buf) ); memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
...@@ -608,14 +584,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys ) ...@@ -608,14 +584,10 @@ block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys )
block_Release( p_block ); block_Release( p_block );
return NULL; return NULL;
} }
break; 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; return p_block;
} }
...@@ -642,25 +614,6 @@ static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size ...@@ -642,25 +614,6 @@ static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size
return p_block; return p_block;
} }
/*****************************************************************************
* 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 * Helper function to initalise video IO using the mmap method
*****************************************************************************/ *****************************************************************************/
...@@ -1408,13 +1361,11 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys, ...@@ -1408,13 +1361,11 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
} }
#endif #endif
/* Init I/O method */ /* Init I/O method */
switch( p_sys->io ) switch( p_sys->io )
{ {
case IO_METHOD_READ: case IO_METHOD_READ:
if( b_demux && InitRead( p_obj, p_sys, fmt.fmt.pix.sizeimage ) ) p_sys->blocksize = fmt.fmt.pix.sizeimage;
goto error;
break; break;
case IO_METHOD_MMAP: case IO_METHOD_MMAP:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment