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 )
/* 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 )
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......@@ -642,25 +614,6 @@ static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size
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
*****************************************************************************/
......@@ -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:
......
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