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

V4L2: only keep codecs data during initialization

parent c588aa1a
...@@ -58,9 +58,6 @@ struct demux_sys_t ...@@ -58,9 +58,6 @@ struct demux_sys_t
/* Video */ /* Video */
io_method io; io_method io;
unsigned i_codec;
struct v4l2_fmtdesc *p_codecs;
struct buffer_t *p_buffers; struct buffer_t *p_buffers;
unsigned int i_nbuffers; unsigned int i_nbuffers;
......
...@@ -419,9 +419,6 @@ static ssize_t AccessReadStream( access_t * p_access, uint8_t * p_buffer, size_t ...@@ -419,9 +419,6 @@ static ssize_t AccessReadStream( access_t * p_access, uint8_t * p_buffer, size_t
static block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys ); static block_t* GrabVideo( vlc_object_t *p_demux, demux_sys_t *p_sys );
static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size_t ); static block_t* ProcessVideoFrame( vlc_object_t *p_demux, uint8_t *p_frame, size_t );
static bool IsPixelFormatSupported( demux_t *p_demux,
unsigned int i_pixelformat );
static int OpenVideoDev( vlc_object_t *, const char *path, demux_sys_t *, bool ); static int OpenVideoDev( vlc_object_t *, const char *path, demux_sys_t *, bool );
static const struct static const struct
...@@ -534,7 +531,6 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -534,7 +531,6 @@ static int DemuxOpen( vlc_object_t *p_this )
free( path ); free( path );
if( p_sys->i_fd == -1 ) if( p_sys->i_fd == -1 )
{ {
free( p_sys->p_codecs );
free( p_sys ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -649,7 +645,6 @@ static void CommonClose( vlc_object_t *p_this, demux_sys_t *p_sys ) ...@@ -649,7 +645,6 @@ static void CommonClose( vlc_object_t *p_this, demux_sys_t *p_sys )
(void)p_this; (void)p_this;
/* Close */ /* Close */
if( p_sys->i_fd >= 0 ) v4l2_close( p_sys->i_fd ); if( p_sys->i_fd >= 0 ) v4l2_close( p_sys->i_fd );
free( p_sys->p_codecs );
free( p_sys ); free( p_sys );
} }
...@@ -697,7 +692,6 @@ static int AccessOpen( vlc_object_t * p_this ) ...@@ -697,7 +692,6 @@ static int AccessOpen( vlc_object_t * p_this )
free( path ); free( path );
if( p_sys->i_fd == -1 ) if( p_sys->i_fd == -1 )
{ {
free( p_sys->p_codecs );
free( p_sys ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1144,20 +1138,16 @@ static int InitUserP( vlc_object_t *p_demux, demux_sys_t *p_sys, int i_fd, unsig ...@@ -1144,20 +1138,16 @@ static int InitUserP( vlc_object_t *p_demux, demux_sys_t *p_sys, int i_fd, unsig
return 0; return 0;
} }
/***************************************************************************** /**
* IsPixelFormatSupported: returns true if the specified V4L2 pixel format is * \return true if the specified V4L2 pixel format is
* in the array of supported formats returned by the driver * in the array of supported formats returned by the driver
*****************************************************************************/ */
static bool IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat ) static bool IsPixelFormatSupported( struct v4l2_fmtdesc *codecs, size_t n,
unsigned int i_pixelformat )
{ {
demux_sys_t *p_sys = p_demux->p_sys; for( size_t i = 0; i < n; i++ )
if( codecs[i].pixelformat == i_pixelformat )
for( unsigned i_index = 0; i_index < p_sys->i_codec; i_index++ )
{
if( p_sys->p_codecs[i_index].pixelformat == i_pixelformat )
return true; return true;
}
return false; return false;
} }
...@@ -1335,6 +1325,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -1335,6 +1325,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
unsigned int i_min; unsigned int i_min;
enum v4l2_buf_type buf_type; enum v4l2_buf_type buf_type;
es_format_t es_fmt; es_format_t es_fmt;
struct v4l2_fmtdesc *codecs = NULL;
msg_Dbg( p_obj, "opening device '%s'", path ); msg_Dbg( p_obj, "opening device '%s'", path );
...@@ -1558,66 +1549,56 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -1558,66 +1549,56 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
} }
/* Probe for available chromas */ /* Probe for available chromas */
uint_fast32_t ncodec = 0;
if( cap.capabilities & V4L2_CAP_VIDEO_CAPTURE ) if( cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
{ {
struct v4l2_fmtdesc codec; struct v4l2_fmtdesc codec = {
.index = 0,
unsigned i_index = 0; .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
memset( &codec, 0, sizeof(codec) ); };
codec.index = i_index;
codec.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while( v4l2_ioctl( i_fd, VIDIOC_ENUM_FMT, &codec ) >= 0 ) while( v4l2_ioctl( i_fd, VIDIOC_ENUM_FMT, &codec ) >= 0 )
{ codec.index = ++ncodec;
if( codec.index != i_index )
break;
i_index++;
codec.index = i_index;
}
p_sys->i_codec = i_index;
free( p_sys->p_codecs ); codecs = malloc( ncodec * sizeof( *codecs ) );
p_sys->p_codecs = calloc( 1, p_sys->i_codec * sizeof( struct v4l2_fmtdesc ) ); if( unlikely(codecs == NULL) )
ncodec = 0;
for( i_index = 0; i_index < p_sys->i_codec; i_index++ ) for( uint_fast32_t i = 0; i < ncodec; i++ )
{ {
p_sys->p_codecs[i_index].index = i_index; codecs[i].index = i;
p_sys->p_codecs[i_index].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; codecs[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FMT, &p_sys->p_codecs[i_index] ) < 0 ) if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FMT, &codecs[i] ) < 0 )
{ {
msg_Err( p_obj, "cannot get codec description: %m" ); msg_Err( p_obj, "cannot get codec description: %m" );
return -1; return -1;
} }
/* only print if vlc supports the format */ /* only print if vlc supports the format */
char psz_fourcc_v4l2[5]; char fourcc_v4l2[5];
memset( &psz_fourcc_v4l2, 0, sizeof( psz_fourcc_v4l2 ) ); memset( fourcc_v4l2, 0, sizeof( fourcc_v4l2 ) );
vlc_fourcc_to_char( p_sys->p_codecs[i_index].pixelformat, vlc_fourcc_to_char( codecs[i].pixelformat, fourcc_v4l2 );
&psz_fourcc_v4l2 );
bool b_codec_supported = false; bool b_codec_supported = false;
for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ ) for( unsigned j = 0; v4l2chroma_to_fourcc[j].i_v4l2 != 0; j++ )
{ {
if( v4l2chroma_to_fourcc[i].i_v4l2 == p_sys->p_codecs[i_index].pixelformat ) if( v4l2chroma_to_fourcc[j].i_v4l2 == codecs[i].pixelformat )
{ {
b_codec_supported = true; char fourcc[5];
memset( fourcc, 0, sizeof( fourcc ) );
char psz_fourcc[5]; vlc_fourcc_to_char( v4l2chroma_to_fourcc[j].i_fourcc,
memset( &psz_fourcc, 0, sizeof( psz_fourcc ) ); fourcc );
vlc_fourcc_to_char( v4l2chroma_to_fourcc[i].i_fourcc,
&psz_fourcc );
msg_Dbg( p_obj, "device supports chroma %4.4s [%s, %s]", msg_Dbg( p_obj, "device supports chroma %4.4s [%s, %s]",
psz_fourcc, fourcc, codecs[i].description, fourcc_v4l2 );
p_sys->p_codecs[i_index].description, b_codec_supported = true;
psz_fourcc_v4l2 );
#ifdef VIDIOC_ENUM_FRAMESIZES #ifdef VIDIOC_ENUM_FRAMESIZES
/* This is new in Linux 2.6.19 */ /* This is new in Linux 2.6.19 */
/* List valid frame sizes for this format */ /* List valid frame sizes for this format */
struct v4l2_frmsizeenum frmsize; struct v4l2_frmsizeenum frmsize;
memset( &frmsize, 0, sizeof(frmsize) ); memset( &frmsize, 0, sizeof(frmsize) );
frmsize.pixel_format = p_sys->p_codecs[i_index].pixelformat; frmsize.pixel_format = codecs[i].pixelformat;
if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) < 0 ) if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) < 0 )
{ {
/* Not all devices support this ioctl */ /* Not all devices support this ioctl */
...@@ -1656,10 +1637,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -1656,10 +1637,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
} }
if( !b_codec_supported ) if( !b_codec_supported )
{ {
msg_Dbg( p_obj, msg_Dbg( p_obj, "device codec %4.4s (%s) not supported",
"device codec %4.4s (%s) not supported", fourcc_v4l2, codecs[i].description );
psz_fourcc_v4l2,
p_sys->p_codecs[i_index].description );
} }
} }
} }
...@@ -1749,7 +1728,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -1749,7 +1728,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
} }
} }
/* Try and set user chroma */ /* Try and set user chroma */
bool b_error = !IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ); bool b_error = !IsPixelFormatSupported( codecs, ncodec,
fmt.fmt.pix.pixelformat );
if( !b_error && fmt.fmt.pix.pixelformat ) if( !b_error && fmt.fmt.pix.pixelformat )
{ {
if( v4l2_ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 ) if( v4l2_ioctl( i_fd, VIDIOC_S_FMT, &fmt ) < 0 )
...@@ -1779,7 +1759,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -1779,7 +1759,8 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
for( i = 0; i < ARRAY_SIZE( p_chroma_fallbacks ); i++ ) for( i = 0; i < ARRAY_SIZE( p_chroma_fallbacks ); i++ )
{ {
fmt.fmt.pix.pixelformat = p_chroma_fallbacks[i]; fmt.fmt.pix.pixelformat = p_chroma_fallbacks[i];
if( IsPixelFormatSupported( p_demux, fmt.fmt.pix.pixelformat ) ) if( IsPixelFormatSupported( codecs, ncodec,
fmt.fmt.pix.pixelformat ) )
{ {
if( v4l2_ioctl( i_fd, VIDIOC_S_FMT, &fmt ) >= 0 ) if( v4l2_ioctl( i_fd, VIDIOC_S_FMT, &fmt ) >= 0 )
break; break;
...@@ -2063,9 +2044,11 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path, ...@@ -2063,9 +2044,11 @@ static int OpenVideoDev( vlc_object_t *p_obj, const char *path,
break; break;
} }
free( codecs );
return i_fd; return i_fd;
error: error:
v4l2_close( i_fd ); v4l2_close( i_fd );
free( codecs );
return -1; return -1;
} }
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