1 /*****************************************************************************
2 * v4l2.c : Video4Linux2 input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2004 the VideoLAN team
5 * $Id: v4l.c 16084 2006-07-19 09:45:02Z zorglub $
7 * Author: Benjamin Pracht <bigben at videolan dot org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
31 #include <vlc_access.h>
32 #include <vlc_demux.h>
33 #include <vlc_input.h>
38 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <sys/errno.h>
43 #include <asm/types.h> /* for videodev2.h */
45 #include <linux/videodev2.h>
47 /*****************************************************************************
49 *****************************************************************************/
51 static int Open ( vlc_object_t * );
52 static void Close( vlc_object_t * );
54 #define DEV_TEXT N_("Device name")
55 #define DEV_LONGTEXT N_( \
56 "Name of the device to use. " \
57 "If you don't specify anything, /dev/video0 will be used.")
58 #define INPUT_TEXT N_( "Input" )
59 #define INPUT_LONGTEXT N_( \
60 "Input of the card to use (Usually, 0 = tuner, " \
61 "1 = composite, 2 = svideo)." )
65 set_shortname( _("Video4Linux2") );
66 set_description( _("Video4Linux2 input") );
67 set_category( CAT_INPUT );
68 set_subcategory( SUBCAT_INPUT_ACCESS );
70 add_string( "v4l2-dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT,
72 add_integer( "v4l2-input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT,
75 add_shortcut( "v4l2" );
76 set_capability( "access_demux", 10 );
77 set_callbacks( Open, Close );
80 /*****************************************************************************
81 * Access: local prototypes
82 *****************************************************************************/
84 static int DemuxMMAP( demux_t * );
85 static int Control( demux_t *, int, va_list );
87 static int ProbeDev( demux_t * );
88 static int OpenVideoDev( demux_t * );
90 static block_t *GrabVideo( demux_t * );
98 struct v4l2_capability dev_cap;
101 struct v4l2_input *p_inputs;
102 int i_selected_input;
105 /* V4L2 devices cannot have more than 32 audio inputs */
106 struct v4l2_audio p_audios[32];
109 struct v4l2_tuner *p_tuners;
112 struct v4l2_fmtdesc *p_codecs;
115 /*****************************************************************************
116 * Open: opens v4l device
117 *****************************************************************************
119 * url: <video device>::::
121 *****************************************************************************/
122 static int Open( vlc_object_t *p_this )
124 demux_t *p_demux = (demux_t*)p_this;
128 /* Only when selected */
129 if( *p_demux->psz_access == '\0' )
133 p_demux->pf_control = Control;
134 p_demux->info.i_update = 0;
135 p_demux->info.i_title = 0;
136 p_demux->info.i_seekpoint = 0;
138 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
139 if( p_sys == NULL ) return VLC_ENOMEM;
140 memset( p_sys, 0, sizeof( demux_sys_t ) );
142 p_sys->psz_device = var_CreateGetString( p_demux, "v4l2-dev" );
144 if( ProbeDev( p_demux ) < 0 ) return VLC_EGENERIC;
146 if( OpenVideoDev( p_demux ) < 0 ) return VLC_EGENERIC;
151 /*****************************************************************************
152 * Close: close device, free resources
153 *****************************************************************************/
154 static void Close( vlc_object_t *p_this )
156 demux_t *p_demux = (demux_t *)p_this;
157 demux_sys_t *p_sys = p_demux->p_sys;
159 if( p_sys->i_fd_video >= 0 ) close( p_sys->i_fd_video );
161 if( p_sys->psz_device ) free( p_sys->psz_device );
162 if( p_sys->p_inputs ) free( p_sys->p_inputs );
163 if( p_sys->p_tuners ) free( p_sys->p_tuners );
164 if( p_sys->p_codecs ) free( p_sys->p_codecs );
169 /*****************************************************************************
171 *****************************************************************************/
172 static int Control( demux_t *p_demux, int i_query, va_list args )
176 /*****************************************************************************
178 *****************************************************************************/
179 static int DemuxMMAP( demux_t *p_demux )
184 /*****************************************************************************
185 * OpenVideoDev: open and set up the video device and probe for capabilities
186 *****************************************************************************/
187 int OpenVideoDev( demux_t *p_demux )
190 demux_sys_t *p_sys = p_demux->p_sys;
192 if( ( i_fd = open( p_sys->psz_device, O_RDWR ) ) < 0 )
194 msg_Err( p_demux, "cannot open device (%s)", strerror( errno ) );
198 p_sys->i_fd_video = i_fd;
200 if( p_sys->i_selected_input = var_CreateGetInteger( p_demux, "v4l2-input" )
203 msg_Warn( p_demux, "invalid input. Using the default one" );
204 p_sys->i_selected_input = 0;
207 if( ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_selected_input ) < 0 )
209 msg_Err( p_demux, "cannot set input (%s)", strerror( errno ) );
213 if( p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING )
215 struct v4l2_requestbuffers reqbuf;
217 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
218 reqbuf.memory = V4L2_MEMORY_MMAP;
221 if( ioctl( i_fd, VIDIOC_REQBUFS, &reqbuf ) < 0 )
223 msg_Err( p_demux, "cannot initiate I/O operation (%s). "
224 "Only MMAP is supported at the moment", strerror( errno ) );
227 p_demux->pf_demux = DemuxMMAP;
231 msg_Warn( p_demux, "I/O method not supported at the moment" );
238 if( i_fd ) close( i_fd );
239 p_sys->i_fd_video = 0;
244 /*****************************************************************************
245 * ProbeDev: probe for capabilities
246 *****************************************************************************/
247 int ProbeDev( demux_t *p_demux )
252 demux_sys_t *p_sys = p_demux->p_sys;
254 if( ( i_fd = open( p_sys->psz_device, O_RDWR ) ) < 0 )
256 msg_Err( p_demux, "cannot open device (%s)", strerror( errno ) );
260 /* Get device capabilites */
262 if( ioctl( i_fd, VIDIOC_QUERYCAP, &p_sys->dev_cap ) < 0 )
264 msg_Err( p_demux, "cannot get capabilities (%s)", strerror( errno ) );
268 msg_Dbg( p_demux, "V4L2 device: %s using driver: %s (version: %u.%u.%u) on %s",
270 p_sys->dev_cap.driver,
271 (p_sys->dev_cap.version >> 16) & 0xFF,
272 (p_sys->dev_cap.version >> 8) & 0xFF,
273 p_sys->dev_cap.version & 0xFF,
274 p_sys->dev_cap.bus_info );
276 msg_Dbg( p_demux, "the device has the capabilities: (%c) Video Capure, "
279 ( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE ? 'X':' '),
280 ( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO ? 'X':' '),
281 ( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER ? 'X':' ') );
283 msg_Dbg( p_demux, "supported I/O methods are: (%c) Read/Write, "
286 ( p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE ? 'X':' ' ),
287 ( p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING ? 'X':' ' ),
288 ( p_sys->dev_cap.capabilities & V4L2_CAP_ASYNCIO ? 'X':' ' ) );
290 /* Now, enumerate all the video inputs. This is useless at the moment
291 since we have no way to present that info to the user except with
294 if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
296 while( ioctl( i_fd, VIDIOC_S_INPUT, &p_sys->i_input ) >= 0 )
301 p_sys->p_inputs = malloc( p_sys->i_input * sizeof( struct v4l2_input ) );
302 if( !p_sys->p_inputs ) goto open_failed;
303 memset( p_sys->p_inputs, 0, sizeof( struct v4l2_input ) );
305 for( i_index = 0; i_index < p_sys->i_input; i_index++ )
307 p_sys->p_inputs[i_index].index = i_index;
309 if( ioctl( i_fd, VIDIOC_ENUMINPUT, &p_sys->p_inputs[i_index] ) )
311 msg_Err( p_demux, "cannot get video input characteristics (%s)",
315 msg_Dbg( p_demux, "video input %i (%s) has type: %s",
317 p_sys->p_inputs[i_index].name,
318 p_sys->p_inputs[i_index].type
319 == V4L2_INPUT_TYPE_TUNER ?
321 "External analog input" );
325 /* initialize the structures for the ioctls */
326 for( i_index = 0; i_index < 32; i_index++ )
328 p_sys->p_audios[i_index].index = i_index;
331 /* Probe audio inputs */
333 if( p_sys->dev_cap.capabilities & V4L2_CAP_AUDIO )
335 while( p_sys->i_audio < 32 &&
336 ioctl( i_fd, VIDIOC_S_AUDIO, &p_sys->p_audios[p_sys->i_audio] ) >= 0 )
338 if( ioctl( i_fd, VIDIOC_G_AUDIO, &p_sys->p_audios[ p_sys->i_audio] ) < 0 )
340 msg_Err( p_demux, "cannot get video input characteristics (%s)",
345 msg_Dbg( p_demux, "audio device %i (%s) is %s",
347 p_sys->p_audios[p_sys->i_audio].name,
348 p_sys->p_audios[p_sys->i_audio].capability &
356 if( p_sys->dev_cap.capabilities & V4L2_CAP_TUNER )
358 struct v4l2_tuner tuner = {};
360 while( ioctl( i_fd, VIDIOC_S_TUNER, &tuner ) >= 0 )
363 tuner.index = p_sys->i_tuner;
366 p_sys->p_tuners = malloc( p_sys->i_tuner * sizeof( struct v4l2_tuner ) );
367 if( !p_sys->p_tuners ) goto open_failed;
368 memset( p_sys->p_tuners, 0, sizeof( struct v4l2_tuner ) );
370 for( i_index = 0; i_index < p_sys->i_tuner; i_index++ )
372 p_sys->p_tuners[i_index].index = i_index;
374 if( ioctl( i_fd, VIDIOC_G_TUNER, &p_sys->p_tuners[i_index] ) )
376 msg_Err( p_demux, "cannot get tuner characteristics (%s)",
380 msg_Dbg( p_demux, "tuner %i (%s) has type: %s, "
381 "frequency range: %.1f %s -> %.1f %s",
383 p_sys->p_tuners[i_index].name,
384 p_sys->p_tuners[i_index].type
385 == V4L2_TUNER_RADIO ?
386 "Radio" : "Analog TV",
387 p_sys->p_tuners[i_index].rangelow * 62.5,
388 p_sys->p_tuners[i_index].capability &
391 p_sys->p_tuners[i_index].rangehigh * 62.5,
392 p_sys->p_tuners[i_index].capability &
398 /* Probe for available chromas */
399 if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
401 struct v4l2_fmtdesc codec = {};
404 codec.index = i_index;
405 codec.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
407 while( ioctl( i_fd, VIDIOC_ENUM_FMT, &codec ) >= 0 )
410 codec.index = i_index;
413 p_sys->i_codec = i_index;
415 p_sys->p_codecs = malloc( p_sys->i_codec * sizeof( struct v4l2_fmtdesc ) );
416 memset( p_sys->p_codecs, 0, p_sys->i_codec * sizeof( struct v4l2_fmtdesc ) );
418 for( i_index = 0; i_index < p_sys->i_codec; i_index++ )
420 p_sys->p_codecs[i_index].index = i_index;
421 p_sys->p_codecs[i_index].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
423 if( ioctl( i_fd, VIDIOC_ENUM_FMT, &p_sys->p_codecs[i_index] ) < 0 )
425 msg_Err( p_demux, "cannot get codec description (%s)", strerror( errno ) );
429 msg_Dbg( p_demux, "device supports Codec %s",
430 p_sys->p_codecs[i_index].description );
435 if( i_fd >= 0 ) close( i_fd );
440 if( i_fd >= 0 ) close( i_fd );