+ /* Try to open as video device */
+ p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_device );
+
+ if( p_sys->fd_video < 0 )
+ {
+ /* Try to open as audio device */
+ p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_device );
+ if( p_sys->fd_audio >= 0 )
+ {
+ if( p_sys->psz_adev ) free( p_sys->psz_adev );
+ p_sys->psz_adev = p_sys->psz_device;
+ p_sys->psz_device = NULL;
+ }
+ }
+ else
+ {
+ if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
+ p_sys->psz_vdev = p_sys->psz_device;
+ p_sys->psz_device = NULL;
+ }
+ }
+
+ /* If no device opened, only continue if the access was forced */
+ if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )
+ {
+ if( strcmp( p_demux->psz_access, "v4l" ) )
+ {
+ Close( p_this );
+ return VLC_EGENERIC;
+ }
+ }
+
+ /* Find video device */
+ if( p_sys->fd_video < 0 )
+ {
+ if( !p_sys->psz_vdev || !*p_sys->psz_vdev )
+ {
+ if( p_sys->psz_vdev ) free( p_sys->psz_vdev );
+ p_sys->psz_vdev = var_CreateGetString( p_demux, "v4l-vdev" );;
+ }
+
+ if( p_sys->psz_vdev && *p_sys->psz_vdev )
+ {
+ p_sys->fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev );
+ }
+ }
+
+ /* Find audio device */
+ if( p_sys->fd_audio < 0 )
+ {
+ if( !p_sys->psz_adev || !*p_sys->psz_adev )
+ {
+ if( p_sys->psz_adev ) free( p_sys->psz_adev );
+ p_sys->psz_adev = var_CreateGetString( p_demux, "v4l-adev" );;
+ }
+
+ if( p_sys->psz_adev && *p_sys->psz_adev )
+ {
+ p_sys->fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev );
+ }
+ }
+
+ if( p_sys->fd_video < 0 && p_sys->fd_audio < 0 )
+ {
+ Close( p_this );
+ return VLC_EGENERIC;
+ }
+
+ msg_Dbg( p_demux, "v4l grabbing started" );
+
+ /* Declare elementary streams */
+ if( p_sys->fd_video >= 0 )
+ {
+ es_format_t fmt;
+ es_format_Init( &fmt, VIDEO_ES, p_sys->i_fourcc );
+ fmt.video.i_width = p_sys->i_width;
+ fmt.video.i_height = p_sys->i_height;
+ fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
+
+ /* Setup rgb mask for RGB formats */
+ if( p_sys->i_fourcc == VLC_FOURCC('R','V','2','4') )
+ {
+ /* This is in BGR format */
+ fmt.video.i_bmask = 0x00ff0000;
+ fmt.video.i_gmask = 0x0000ff00;
+ fmt.video.i_rmask = 0x000000ff;
+ }
+
+ msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
+ (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
+ p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
+ }
+
+ if( p_sys->fd_audio >= 0 )
+ {
+ es_format_t fmt;
+ es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
+
+ fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
+ fmt.audio.i_rate = p_sys->i_sample_rate;
+ fmt.audio.i_bitspersample = 16; // FIXME ?
+ fmt.audio.i_blockalign = fmt.audio.i_channels *
+ fmt.audio.i_bitspersample / 8;
+ fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
+ fmt.audio.i_bitspersample;
+
+ msg_Dbg( p_demux, "new audio es %d channels %dHz",
+ fmt.audio.i_channels, fmt.audio.i_rate );
+
+ p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
+ }
+
+ /* Update default_pts to a suitable value for access */
+ var_Create( p_demux, "v4l-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close: close device, free resources
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )