#define DEV_LONGTEXT N_( \
"Name of the device to use. " \
"If you don't specify anything, /dev/video0 will be used.")
-#define ADEV_TEXT N_("Audio device name")
-#define ADEV_LONGTEXT N_( \
- "Name of the audio device to use. " \
- "If you don't specify anything, /dev/dsp will be used.")
#define STANDARD_TEXT N_( "Standard" )
#define STANDARD_LONGTEXT N_( \
"Video standard (Default, SECAM, PAL, or NTSC)." )
#define HEIGHT_TEXT N_( "Height" )
#define HEIGHT_LONGTEXT N_( \
"Force height (-1 for autodetect)." )
+#define FPS_TEXT N_( "Framerate" )
+#define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
+ "(-1 for autodetect)." )
+
+#define VIDEOCTRL_RESET_TEXT N_( "Reset video controls" )
+#define VIDEOCTRL_RESET_LONGTEXT N_( \
+ "Reset video controls to defaults provided by the v4l2 driver." )
#define BRIGHTNESS_TEXT N_( "Brightness" )
#define BRIGHTNESS_LONGTEXT N_( \
"Brightness of the video input." )
#define HUE_TEXT N_( "Hue" )
#define HUE_LONGTEXT N_( \
"Hue of the video input." )
-#define FPS_TEXT N_( "Framerate" )
-#define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \
- "(-1 for autodetect)." )
+#define GAMMA_TEXT N_( "Gamma" )
+#define GAMMA_LONGTEXT N_( \
+ "Gamma of the video input." )
+
+#define ADEV_TEXT N_("Audio device name")
+#define ADEV_LONGTEXT N_( \
+ "Name of the audio device to use. " \
+ "If you don't specify anything, /dev/dsp will be used.")
#define ALSA_TEXT N_( "Use Alsa" )
#define ALSA_LONGTEXT N_( \
"Use ALSA instead of OSS for audio" )
#define SAMPLERATE_TEXT N_( "Samplerate" )
#define SAMPLERATE_LONGTEXT N_( \
"Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
+
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Caching value for V4L2 captures. This " \
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ACCESS );
+ set_section( N_( "Video input" ), NULL );
add_string( "v4l2-dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT,
VLC_FALSE );
- add_string( "v4l2-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT,
- VLC_FALSE );
add_integer( "v4l2-standard", 0, NULL, STANDARD_TEXT, STANDARD_LONGTEXT,
VLC_FALSE );
change_integer_list( i_standards_list, psz_standards_list_text, 0 );
WIDTH_LONGTEXT, VLC_TRUE );
add_integer( "v4l2-height", 0, NULL, HEIGHT_TEXT,
HEIGHT_LONGTEXT, VLC_TRUE );
+ add_float( "v4l2-fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
+
+ set_section( N_( "Video controls" ), NULL );
+ add_bool( "v4l2-videocontrol-reset", VLC_FALSE, NULL, VIDEOCTRL_RESET_TEXT,
+ VIDEOCTRL_RESET_LONGTEXT, VLC_TRUE );
add_integer( "v4l2-brightness", -1, NULL, BRIGHTNESS_TEXT,
BRIGHTNESS_LONGTEXT, VLC_TRUE );
add_integer( "v4l2-contrast", -1, NULL, CONTRAST_TEXT,
SATURATION_LONGTEXT, VLC_TRUE );
add_integer( "v4l2-hue", -1, NULL, HUE_TEXT,
HUE_LONGTEXT, VLC_TRUE );
- add_float( "v4l2-fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
+ add_integer( "v4l2-gamma", -1, NULL, GAMMA_TEXT,
+ GAMMA_LONGTEXT, VLC_TRUE );
+
+ set_section( N_( "Audio input" ), NULL );
+ add_string( "v4l2-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT,
+ VLC_FALSE );
#ifdef HAVE_ALSA
add_bool( "v4l2-alsa", VLC_FALSE, NULL, ALSA_TEXT, ALSA_LONGTEXT,
VLC_TRUE );
static vlc_bool_t ProbeVideoDev( demux_t *, char *psz_device );
static vlc_bool_t ProbeAudioDev( demux_t *, char *psz_device );
-static int VideoControlList( demux_t *p_demux, int i_fd );
+static int VideoControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset );
static int VideoControl( demux_t *, int i_fd,
const char *psz_label, int i_cid, int i_value );
static int VideoControlCallback( vlc_object_t *p_this,
mtime_t i_video_pts; /* only used when f_fps > 0 */
int i_fourcc;
+ vlc_bool_t b_videoctrl_reset;
int i_brightness;
int i_contrast;
int i_saturation;
int i_hue;
+ int i_gamma;
picture_t pic;
int i_video_frame_size;
p_sys->i_width = var_CreateGetInteger( p_demux, "v4l2-width" );
p_sys->i_height = var_CreateGetInteger( p_demux, "v4l2-height" );
+ p_sys->b_videoctrl_reset =
+ var_CreateGetBool( p_demux, "v4l2-videocontrol-reset" );
p_sys->i_brightness =
var_CreateGetIntegerCommand( p_demux, "v4l2-brightness" );
p_sys->i_contrast =
var_CreateGetIntegerCommand( p_demux, "v4l2-saturation" );
p_sys->i_hue =
var_CreateGetIntegerCommand( p_demux, "v4l2-hue" );
+ p_sys->i_gamma =
+ var_CreateGetIntegerCommand( p_demux, "v4l2-gamma" );
var_AddCallback( p_demux, "v4l2-brightness", VideoControlCallback, NULL );
var_AddCallback( p_demux, "v4l2-contrast", VideoControlCallback, NULL );
var_AddCallback( p_demux, "v4l2-saturation", VideoControlCallback, NULL );
var_AddCallback( p_demux, "v4l2-hue", VideoControlCallback, NULL );
+ var_AddCallback( p_demux, "v4l2-gamma", VideoControlCallback, NULL );
+
+ var_Create( p_demux, "videocontrol", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
+ var_AddCallback( p_demux, "videocontrol", VideoControlCallback, NULL );
var_Create( p_demux, "v4l2-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
var_Get( p_demux, "v4l2-fps", &val );
strtol( psz_parser + strlen( "height=" ),
&psz_parser, 0 );
}
+ else if( !strncmp( psz_parser, "videocontrol-reset",
+ strlen( "videocontrol-reset" ) ) )
+ {
+ p_sys->b_videoctrl_reset = VLC_TRUE;
+ psz_parser += strlen( "videocontrol-reset" );
+ }
else if( !strncmp( psz_parser, "brightness=",
strlen( "brightness=" ) ) )
{
strtol( psz_parser + strlen( "hue=" ),
&psz_parser, 0 );
}
+ else if( !strncmp( psz_parser, "gamma=",
+ strlen( "gamma=" ) ) )
+ {
+ p_sys->i_gamma =
+ strtol( psz_parser + strlen( "gamma=" ),
+ &psz_parser, 0 );
+ }
else if( !strncmp( psz_parser, "samplerate=",
strlen( "samplerate=" ) ) )
{
}
#endif
- VideoControlList( p_demux, i_fd );
+ VideoControlList( p_demux, i_fd, p_sys->b_videoctrl_reset );
VideoControl( p_demux, i_fd,
"brightness", V4L2_CID_BRIGHTNESS, p_sys->i_brightness );
VideoControl( p_demux, i_fd,
"saturation", V4L2_CID_SATURATION, p_sys->i_saturation );
VideoControl( p_demux, i_fd, "hue", V4L2_CID_HUE, p_sys->i_hue );
+ VideoControl( p_demux, i_fd, "gamma", V4L2_CID_GAMMA, p_sys->i_gamma );
/* Init vout Picture */
vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic, p_sys->i_fourcc,
/*****************************************************************************
* List available controls
*****************************************************************************/
-static int VideoControlList( demux_t *p_demux, int i_fd )
+static void VideoControlListPrint( demux_t *p_demux, int i_fd,
+ struct v4l2_queryctrl queryctrl,
+ vlc_bool_t b_reset )
{
- struct v4l2_queryctrl queryctrl;
struct v4l2_querymenu querymenu;
+ if( queryctrl.flags & V4L2_CTRL_FLAG_GRABBED )
+ msg_Dbg( p_demux, " control is busy" );
+ if( queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY )
+ msg_Dbg( p_demux, " control is read-only" );
+ switch( queryctrl.type )
+ {
+ case V4L2_CTRL_TYPE_INTEGER:
+ msg_Dbg( p_demux, " integer control" );
+ msg_Dbg( p_demux,
+ " valid values: %d to %d by steps of %d",
+ queryctrl.minimum, queryctrl.maximum,
+ queryctrl.step );
+ break;
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ msg_Dbg( p_demux, " boolean control" );
+ break;
+ case V4L2_CTRL_TYPE_MENU:
+ msg_Dbg( p_demux, " menu control" );
+ memset( &querymenu, 0, sizeof( querymenu ) );
+ querymenu.id = queryctrl.id;
+ for( querymenu.index = queryctrl.minimum;
+ querymenu.index <= (unsigned)queryctrl.maximum;
+ querymenu.index++ )
+ {
+ if( ioctl( i_fd, VIDIOC_QUERYMENU, &querymenu ) >= 0 )
+ {
+ msg_Dbg( p_demux, " %d: %s",
+ querymenu.index, querymenu.name );
+ }
+ }
+ break;
+ case V4L2_CTRL_TYPE_BUTTON:
+ msg_Dbg( p_demux, " button control" );
+ break;
+ default:
+ msg_Dbg( p_demux, " unknown control type (FIXME)" );
+ /* FIXME */
+ break;
+ }
+
+ switch( queryctrl.type )
+ {
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ {
+ struct v4l2_control control;
+ msg_Dbg( p_demux, " default value: %d",
+ queryctrl.default_value );
+ memset( &control, 0, sizeof( control ) );
+ control.id = queryctrl.id;
+ if( ioctl( i_fd, VIDIOC_G_CTRL, &control ) >= 0 )
+ {
+ msg_Dbg( p_demux, " current value: %d", control.value );
+ }
+ if( b_reset && queryctrl.default_value != control.value )
+ {
+ msg_Dbg( p_demux, " reset value to default" );
+ VideoControl( p_demux, i_fd, NULL,
+ queryctrl.id, queryctrl.default_value );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static int VideoControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
+{
+ struct v4l2_queryctrl queryctrl;
memset( &queryctrl, 0, sizeof( queryctrl ) );
continue;
msg_Dbg( p_demux, "Available control: %s (%x)",
queryctrl.name, queryctrl.id );
- if( queryctrl.flags & V4L2_CTRL_FLAG_GRABBED )
- msg_Dbg( p_demux, " control is busy" );
- if( queryctrl.flags & V4L2_CTRL_FLAG_READ_ONLY )
- msg_Dbg( p_demux, " control is read-only" );
- switch( queryctrl.type )
- {
- case V4L2_CTRL_TYPE_INTEGER:
- msg_Dbg( p_demux, " integer control" );
- msg_Dbg( p_demux,
- " valid values: %d to %d by steps of %d",
- queryctrl.minimum, queryctrl.maximum,
- queryctrl.step );
- msg_Dbg( p_demux, " default value: %d",
- queryctrl.default_value );
- break;
- case V4L2_CTRL_TYPE_BOOLEAN:
- msg_Dbg( p_demux, " boolean control" );
- msg_Dbg( p_demux, " default value: %d",
- queryctrl.default_value );
- break;
- case V4L2_CTRL_TYPE_MENU:
- msg_Dbg( p_demux, " menu control" );
- memset( &querymenu, 0, sizeof( querymenu ) );
- for( querymenu.index = queryctrl.minimum;
- querymenu.index <= (unsigned)queryctrl.maximum;
- querymenu.index++ )
- {
- if( ioctl( i_fd, VIDIOC_QUERYMENU, &querymenu ) >= 0 )
- {
- msg_Dbg( p_demux, " %d: %s",
- querymenu.index, querymenu.name );
- }
- }
- msg_Dbg( p_demux, " default value: %d",
- queryctrl.default_value );
- break;
- case V4L2_CTRL_TYPE_BUTTON:
- msg_Dbg( p_demux, " button control" );
- break;
- default:
- msg_Dbg( p_demux, " unknown control type (FIXME)" );
- /* FIXME */
- break;
- }
+ VideoControlListPrint( p_demux, i_fd, queryctrl, b_reset );
}
}
{
if( queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
continue;
- msg_Dbg( p_demux, "Available private control: %s",
- queryctrl.name );
+ msg_Dbg( p_demux, "Available private control: %s (%x)",
+ queryctrl.name, queryctrl.id );
+ VideoControlListPrint( p_demux, i_fd, queryctrl, b_reset );
}
else
break;
{
struct v4l2_queryctrl queryctrl;
struct v4l2_control control;
+
+ if( i_value == -1 )
+ return VLC_SUCCESS;
+
memset( &queryctrl, 0, sizeof( queryctrl ) );
queryctrl.id = i_cid;
if( ioctl( i_fd, VIDIOC_QUERYCTRL, &queryctrl ) < 0
|| queryctrl.flags & V4L2_CTRL_FLAG_DISABLED )
{
- msg_Warn( p_demux, "%s (%x) control is not supported.", psz_label,
- i_value );
+ msg_Err( p_demux, "%s (%x) control is not supported.", psz_label,
+ i_cid );
return VLC_EGENERIC;
}
+ if( !psz_label )
+ psz_label = (const char*)queryctrl.name;
+
memset( &control, 0, sizeof( control ) );
control.id = i_cid;
if( i_fd < 0 )
return VLC_EGENERIC;
- if( !strcmp( psz_var, "brightness" ) )
+ if( !strcmp( psz_var, "v4l2-brightness" ) )
{
p_sys->i_brightness = newval.i_int;
return VideoControl( p_demux, i_fd,
"brightness", V4L2_CID_BRIGHTNESS, p_sys->i_brightness );
}
- else if( !strcmp( psz_var, "contrast" ) )
+ else if( !strcmp( psz_var, "v4l2-contrast" ) )
{
p_sys->i_contrast = newval.i_int;
return VideoControl( p_demux, i_fd,
"contrast", V4L2_CID_CONTRAST, p_sys->i_contrast );
}
- else if( !strcmp( psz_var, "saturation" ) )
+ else if( !strcmp( psz_var, "v4l2-saturation" ) )
{
p_sys->i_saturation = newval.i_int;
return VideoControl( p_demux, i_fd,
"saturation", V4L2_CID_SATURATION, p_sys->i_saturation );
}
- else if( !strcmp( psz_var, "hue" ) )
+ else if( !strcmp( psz_var, "v4l2-hue" ) )
{
p_sys->i_hue = newval.i_int;
return VideoControl( p_demux, i_fd,
"hue", V4L2_CID_HUE, p_sys->i_hue );
}
- else
- return VLC_EGENERIC;
- return VLC_SUCCESS;
+ else if( !strcmp( psz_var, "v4l2-gamma" ) )
+ {
+ p_sys->i_gamma = newval.i_int;
+ return VideoControl( p_demux, i_fd,
+ "gamma", V4L2_CID_HUE, p_sys->i_gamma );
+ }
+ else if( !strcmp( psz_var, "videocontrol" ) )
+ {
+ char *psz_var = newval.psz_string;
+ int i_cid = strtol( psz_var, &psz_var, 16 );
+ int i_value = strtol( psz_var, &psz_var, 0 );
+ return VideoControl( p_demux, i_fd, NULL, i_cid, i_value );
+ }
+
+ return VLC_EGENERIC;
}