Commit 5a1b6873 authored by Jean-Paul Saman's avatar Jean-Paul Saman

v4l2: improve capturing for davinci vpfe driver

- Add option to disable VIDEO_DQBUF workaround for certein capture cards.
- Add workaround for davinci vpfe driver that reports wrong bytesused value
parent 2289c84d
......@@ -99,6 +99,11 @@ static void AccessClose( vlc_object_t * );
"Force usage of the libv4l2 wrapper." )
#endif
#define DQBUF_TEXT N_("Workaround v4l2 driver bug (default on)")
#define DQBUF_LONGTEXT N_( \
"Workaround a driver bug by dequeuing the requested buffers before closing." \
"The bug manifests iteslf by hanging or crashing upon closing of v4l2 device.")
#define CTRL_RESET_TEXT N_( "Reset v4l2 controls" )
#define CTRL_RESET_LONGTEXT N_( \
"Reset controls to defaults provided by the v4l2 driver." )
......@@ -289,6 +294,7 @@ vlc_module_begin ()
#ifdef HAVE_LIBV4L2
add_bool( CFG_PREFIX "use-libv4l2", false, NULL, LIBV4L2_TEXT, LIBV4L2_LONGTEXT, true );
#endif
add_bool( CFG_PREFIX "workaround-dqbuf", true, NULL, DQBUF_TEXT, DQBUF_LONGTEXT, true );
set_section( N_( "Tuner" ), NULL )
add_integer( CFG_PREFIX "tuner", 0, NULL, TUNER_TEXT, TUNER_LONGTEXT,
......@@ -550,6 +556,7 @@ struct demux_sys_t
int i_width;
int i_height;
int i_pitch;
float f_fps; /* <= 0.0 mean to grab at full rate */
mtime_t i_video_pts; /* only used when f_fps > 0 */
int i_fourcc;
......@@ -564,7 +571,6 @@ struct demux_sys_t
/* Controls */
char *psz_set_ctrls;
#ifdef HAVE_LIBV4L2
/* */
int (*pf_close)( int );
......@@ -575,6 +581,8 @@ struct demux_sys_t
int (*pf_munmap)( void *, size_t );
bool b_libv4l2;
#endif
/* V4L2 driver bug workaround */
bool b_workaround_dqbuf;
};
#ifdef HAVE_LIBV4L2
......@@ -690,6 +698,8 @@ static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj )
p_sys->i_selected_standard_id =
i_standards_list[var_CreateGetInteger( p_obj, "v4l2-standard" )];
p_sys->b_workaround_dqbuf = var_CreateGetBool( p_obj, "v4l2-workaround-dqbuf" );
p_sys->i_selected_input = var_CreateGetInteger( p_obj, "v4l2-input" );
p_sys->i_selected_audio_input =
var_CreateGetInteger( p_obj, "v4l2-audio-input" );
......@@ -983,7 +993,6 @@ static void DemuxClose( vlc_object_t *p_this )
{
struct v4l2_buffer buf;
enum v4l2_buf_type buf_type;
unsigned int i;
demux_t *p_demux = (demux_t *)p_this;
demux_sys_t *p_sys = p_demux->p_sys;
......@@ -1000,20 +1009,24 @@ static void DemuxClose( vlc_object_t *p_this )
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
/* Some drivers 'hang' internally if this is not done before streamoff */
for( unsigned int i = 0; i < p_sys->i_nbuffers; i++ )
if( p_sys->b_workaround_dqbuf )
{
memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = ( p_sys->io == IO_METHOD_USERPTR ) ?
V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP;
v4l2_ioctl( p_sys->i_fd, VIDIOC_DQBUF, &buf ); /* ignore result */
for( unsigned int i = 0; i < p_sys->i_nbuffers; i++ )
{
memset( &buf, 0, sizeof(buf) );
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = ( p_sys->io == IO_METHOD_USERPTR ) ?
V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP;
if( v4l2_ioctl( p_sys->i_fd, VIDIOC_DQBUF, &buf ) < 0 ) {
msg_Err( p_this, "VIDIOC_DQBUF %d/%d failed", i, p_sys->i_nbuffers );
}
}
}
buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if( v4l2_ioctl( p_sys->i_fd, VIDIOC_STREAMOFF, &buf_type ) < 0 ) {
msg_Err( p_this, "VIDIOC_STREAMOFF failed" );
}
break;
}
}
......@@ -1027,7 +1040,7 @@ static void DemuxClose( vlc_object_t *p_this )
break;
case IO_METHOD_MMAP:
for( i = 0; i < p_sys->i_nbuffers; ++i )
for( unsigned int i = 0; i < p_sys->i_nbuffers; ++i )
{
if( v4l2_munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) )
{
......@@ -1037,7 +1050,7 @@ static void DemuxClose( vlc_object_t *p_this )
break;
case IO_METHOD_USERPTR:
for( i = 0; i < p_sys->i_nbuffers; ++i )
for( unsigned int i = 0; i < p_sys->i_nbuffers; ++i )
{
free( p_sys->p_buffers[i].start );
}
......@@ -1342,7 +1355,14 @@ static block_t* GrabVideo( demux_t *p_demux )
return 0;
}
p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start, buf.bytesused );
// msg_Err( p_demux, "New frame has size: %d (%d) %d",
// buf.bytesused, p_sys->i_pitch * p_sys->i_height, buf.length );
p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start,
#if 0
buf.bytesused );
#else
p_sys->i_pitch * p_sys->i_height );
#endif
if( !p_block ) return 0;
/* Unlock */
......@@ -2098,6 +2118,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
if( fmt.fmt.pix.sizeimage < i_min )
fmt.fmt.pix.sizeimage = i_min;
p_sys->i_pitch = fmt.fmt.pix.bytesperline;
#ifdef VIDIOC_ENUM_FRAMEINTERVALS
/* This is new in Linux 2.6.19 */
/* List supported frame rates */
......
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