[vlc-commits] Switch v4l2-standard from integer to string, add missing choices
Rémi Denis-Courmont
git at videolan.org
Thu Sep 1 20:17:46 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Sep 1 18:39:06 2011 +0300| [b8259fe1c902628b6d2c0fd6eadb3e0898e384cf] | committer: Rémi Denis-Courmont
Switch v4l2-standard from integer to string, add missing choices
Also an integer values in the MRL (v4l2://standard=XXX) is now
interpreted as a v4l2_std_id bit field, just like the command line
option (--v4l2-standard=XXX). This fixes an out-of-bound read with
large values.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b8259fe1c902628b6d2c0fd6eadb3e0898e384cf
---
modules/access/v4l2.c | 137 ++++++++++++++++++++++++++++++++----------------
1 files changed, 91 insertions(+), 46 deletions(-)
diff --git a/modules/access/v4l2.c b/modules/access/v4l2.c
index df94841..2ad6bb3 100644
--- a/modules/access/v4l2.c
+++ b/modules/access/v4l2.c
@@ -222,27 +222,61 @@ typedef enum {
IO_METHOD_USERPTR,
} io_method;
-static const int i_standards_list[] =
- { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC,
- V4L2_STD_PAL_B, V4L2_STD_PAL_B1, V4L2_STD_PAL_G, V4L2_STD_PAL_H,
- V4L2_STD_PAL_I, V4L2_STD_PAL_D, V4L2_STD_PAL_D1, V4L2_STD_PAL_K,
- V4L2_STD_PAL_M, V4L2_STD_PAL_N, V4L2_STD_PAL_Nc, V4L2_STD_PAL_60,
- V4L2_STD_NTSC_M, V4L2_STD_NTSC_M_JP, V4L2_STD_NTSC_443,
- V4L2_STD_NTSC_M_KR,
- V4L2_STD_SECAM_B, V4L2_STD_SECAM_D, V4L2_STD_SECAM_G,
- V4L2_STD_SECAM_H, V4L2_STD_SECAM_K, V4L2_STD_SECAM_K1,
- V4L2_STD_SECAM_L, V4L2_STD_SECAM_LC,
- V4L2_STD_ATSC_8_VSB, V4L2_STD_ATSC_16_VSB,
- };
-static const char *const psz_standards_list_text[] =
- { N_("Default"), "SECAM", "PAL", "NTSC",
- "PAL_B", "PAL_B1", "PAL_G", "PAL_H", "PAL_I", "PAL_D",
- "PAL_D1", "PAL_K", "PAL_M", "PAL_N", "PAL_Nc", "PAL_60",
- "NTSC_M", "NTSC_M_JP", "NTSC_443", "NTSC_M_KR",
- "SECAM_B", "SECAM_D", "SECAM_G", "SECAM_H", "SECAM_K",
- "SECAM_K1", "SECAM_L", "SECAM_LC",
- "ATSC_8_VSB", "ATSC_16_VSB"
- };
+static const v4l2_std_id standards_v4l2[] = { V4L2_STD_UNKNOWN, V4L2_STD_ALL,
+ V4L2_STD_PAL, V4L2_STD_PAL_BG, V4L2_STD_PAL_DK,
+ V4L2_STD_NTSC,
+ V4L2_STD_SECAM, V4L2_STD_SECAM_DK,
+ V4L2_STD_525_60, V4L2_STD_625_50,
+ V4L2_STD_ATSC,
+
+ V4L2_STD_MN, V4L2_STD_B, V4L2_STD_GH, V4L2_STD_DK,
+
+ V4L2_STD_PAL_B, V4L2_STD_PAL_B1, V4L2_STD_PAL_G, V4L2_STD_PAL_H,
+ V4L2_STD_PAL_I, V4L2_STD_PAL_D, V4L2_STD_PAL_D1, V4L2_STD_PAL_K,
+ V4L2_STD_PAL_M, V4L2_STD_PAL_N, V4L2_STD_PAL_Nc, V4L2_STD_PAL_60,
+ V4L2_STD_NTSC_M, V4L2_STD_NTSC_M_JP,V4L2_STD_NTSC_443, V4L2_STD_NTSC_M_KR,
+ V4L2_STD_SECAM_B, V4L2_STD_SECAM_D, V4L2_STD_SECAM_G, V4L2_STD_SECAM_H,
+ V4L2_STD_SECAM_K, V4L2_STD_SECAM_K1, V4L2_STD_SECAM_L, V4L2_STD_SECAM_LC,
+ V4L2_STD_ATSC_8_VSB, V4L2_STD_ATSC_16_VSB,
+};
+static const char *const standards_vlc[] = { "", "ALL",
+ /* Pseudo standards */
+ "PAL", "PAL_BG", "PAL_DK",
+ "NTSC",
+ "SECAM", "SECAM_DK",
+ "525_60", "625_50",
+ "ATSC",
+
+ /* Areas (PAL/NTSC or PAL/SECAM) */
+ "MN", "B", "GH", "DK",
+
+ /* Individual standards */
+ "PAL_B", "PAL_B1", "PAL_G", "PAL_H",
+ "PAL_I", "PAL_D", "PAL_D1", "PAL_K",
+ "PAL_M", "PAL_N", "PAL_Nc", "PAL_60",
+ "NTSC_M", "NTSC_M_JP", "NTSC_443", "NTSC_M_KR",
+ "SECAM_B", "SECAM_D", "SECAM_G", "SECAM_H",
+ "SECAM_K", "SECAM_K1", "SECAM_L", "SECAM_LC",
+ "ATSC_8_VSB", "ATSC_16_VSB",
+};
+static const char *const standards_user[] = { N_("Undefined"), N_("All"),
+ "PAL", "PAL B/G", "PAL D/K",
+ "NTSC",
+ "SECAM", "SECAM D/K",
+ N_("525 lines / 60 Hz"), N_("625 lines / 50 Hz"),
+ "ATSC",
+
+ "PAL/NTSC M/N",
+ "PAL/SECAM B", "PAL/SECAM G/H", "PAL/SECAM D/K",
+
+ "PAL B", "PAL B1", "PAL G", "PAL H",
+ "PAL I", "PAL D", "PAL D1", "PAL K",
+ "PAL M", "PAL N", N_("PAL N Argentina"), "PAL 60",
+ "NTSC M", N_("NTSC M Japan"), "NTSC 443", N_("NTSC M South Korea"),
+ "SECAM B", "SECAM D", "SECAM G", "SECAM H",
+ "SECAM K", "SECAM K1", "SECAM L", "SECAM L/C",
+ "ATSC 8-VSB", "ATSC 16-VSB",
+};
static const int i_iomethod_list[] =
{ IO_METHOD_AUTO, IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR };
@@ -284,9 +318,9 @@ vlc_module_begin ()
set_section( N_( "Video input" ), NULL )
add_string( CFG_PREFIX "dev", "/dev/video0", DEVICE_TEXT, DEVICE_LONGTEXT,
false )
- add_integer( CFG_PREFIX "standard", 0, STANDARD_TEXT,
- STANDARD_LONGTEXT, false )
- change_integer_list( i_standards_list, psz_standards_list_text )
+ add_string( CFG_PREFIX "standard", "",
+ STANDARD_TEXT, STANDARD_LONGTEXT, false )
+ change_string_list( standards_vlc, standards_user, NULL )
add_string( CFG_PREFIX "chroma", NULL, CHROMA_TEXT, CHROMA_LONGTEXT,
true )
add_integer( CFG_PREFIX "input", 0, INPUT_TEXT, INPUT_LONGTEXT,
@@ -545,7 +579,7 @@ struct demux_sys_t
struct v4l2_input *p_inputs;
unsigned i_selected_input;
- v4l2_std_id i_selected_standard_id;
+ char *psz_standard;
uint32_t i_audio;
/* V4L2 devices cannot have more than 32 audio inputs */
@@ -664,8 +698,6 @@ static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj )
{
p_sys->psz_device = var_CreateGetNonEmptyString( p_obj, "v4l2-dev" );
- p_sys->i_selected_standard_id =
- var_CreateGetInteger( p_obj, "v4l2-standard" );
p_sys->i_selected_input = var_CreateGetInteger( p_obj, "v4l2-input" );
p_sys->i_selected_audio_input =
var_CreateGetInteger( p_obj, "v4l2-audio-input" );
@@ -726,23 +758,16 @@ static void ParseMRL( demux_sys_t *p_sys, char *psz_path, vlc_object_t *p_obj )
if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) )
{
+ int i_len;
+
psz_parser += strlen( "standard=" );
- size_t i;
- for( i = 0; i < ARRAY_SIZE(psz_standards_list_text); i++ )
- {
- const char *psz_value = psz_standards_list_text[i];
- size_t i_len = strlen( psz_value );
- if( !strncasecmp( psz_parser, psz_value, i_len ) &&
- ( psz_parser[i_len] == ':' || psz_parser[i_len] == 0 ) )
- {
- p_sys->i_selected_standard_id = i_standards_list[i];
- psz_parser += i_len;
- break;
- }
- }
+ if( strchr( psz_parser, ':' ) )
+ i_len = strchr( psz_parser, ':' ) - psz_parser;
+ else
+ i_len = strlen( psz_parser );
- if( i == ARRAY_SIZE(psz_standards_list_text) )
- p_sys->i_selected_standard_id = i_standards_list[strtol( psz_parser, &psz_parser, 0 )];
+ p_sys->psz_standard = strndup( psz_parser, i_len );
+ psz_parser += i_len;
}
else if( !strncmp( psz_parser, "chroma=", strlen( "chroma=" ) ) )
{
@@ -1053,6 +1078,7 @@ static void CommonClose( vlc_object_t *p_this, demux_sys_t *p_sys )
/* Close */
if( p_sys->i_fd >= 0 ) v4l2_close( p_sys->i_fd );
free( p_sys->psz_device );
+ free( p_sys->psz_standard );
free( p_sys->p_inputs );
free( p_sys->p_tuners );
free( p_sys->p_codecs );
@@ -1778,9 +1804,26 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
#endif
/* Select standard */
- if( p_sys->i_selected_standard_id != V4L2_STD_UNKNOWN )
- {
- v4l2_std_id std = p_sys->i_selected_standard_id;
+ bool bottom_first;
+ const char *stdname = p_sys->psz_standard;
+ if( stdname == NULL )
+ stdname = var_InheritString( p_obj, CFG_PREFIX"standard" );
+ if( stdname != NULL )
+ {
+ v4l2_std_id std = strtoull( stdname, NULL, 0 );
+ if( std == 0 )
+ {
+ const size_t n = sizeof(standards_vlc) / sizeof(*standards_vlc);
+ assert( n == sizeof(standards_v4l2) / sizeof(*standards_v4l2) );
+ assert( n == sizeof(standards_user) / sizeof(*standards_user) );
+ for( size_t i = 0; i < n; i++ )
+ if( strcasecmp( stdname, standards_vlc[i] ) == 0 )
+ {
+ std = standards_v4l2[i];
+ break;
+ }
+ }
+
if( v4l2_ioctl( i_fd, VIDIOC_S_STD, &std ) < 0
|| v4l2_ioctl( i_fd, VIDIOC_G_STD, &std ) < 0 )
{
@@ -1788,8 +1831,10 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
goto error;
}
msg_Dbg( p_obj, "standard set to 0x%"PRIx64":", std );
- p_sys->i_selected_standard_id = std;
+ bottom_first = std == V4L2_STD_NTSC;
}
+ else
+ bottom_first = false;
/* Tune the tuner */
if( p_sys->i_frequency >= 0 )
@@ -2080,7 +2125,7 @@ static int OpenVideoDev( vlc_object_t *p_obj, demux_sys_t *p_sys, bool b_demux )
break;
case V4L2_FIELD_INTERLACED:
msg_Dbg( p_obj, "Interlacing setting: interleaved (bottom top if M/NTSC, top bottom otherwise)" );
- if( p_sys->i_selected_standard_id == V4L2_STD_NTSC )
+ if( bottom_first )
p_sys->i_block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
else
p_sys->i_block_flags = BLOCK_FLAG_TOP_FIELD_FIRST;
More information about the vlc-commits
mailing list