Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
77787198
Commit
77787198
authored
Dec 24, 2007
by
Richard Hosking
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v4l2.c: Patch by Dennis Lou to add MPEG2 support. Many thanks.
parent
4b295c7c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
463 additions
and
175 deletions
+463
-175
modules/access/v4l2.c
modules/access/v4l2.c
+463
-175
No files found.
modules/access/v4l2.c
View file @
77787198
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
/*
/*
* TODO: Tuner partial implementation.
* TODO: Tuner partial implementation.
* TODO: Add more MPEG stream params
*/
*/
/*****************************************************************************
/*****************************************************************************
...
@@ -66,8 +67,10 @@
...
@@ -66,8 +67,10 @@
* Module descriptior
* Module descriptior
*****************************************************************************/
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
int
DemuxOpen
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
static
int
AccessOpen
(
vlc_object_t
*
);
static
void
AccessClose
(
vlc_object_t
*
);
#define DEV_TEXT N_("Device name")
#define DEV_TEXT N_("Device name")
#define DEV_LONGTEXT N_( \
#define DEV_LONGTEXT N_( \
...
@@ -210,18 +213,30 @@ vlc_module_begin();
...
@@ -210,18 +213,30 @@ vlc_module_begin();
add_shortcut
(
"v4l2"
);
add_shortcut
(
"v4l2"
);
set_capability
(
"access_demux"
,
10
);
set_capability
(
"access_demux"
,
10
);
set_callbacks
(
Open
,
Close
);
set_callbacks
(
DemuxOpen
,
DemuxClose
);
add_submodule
();
set_description
(
_
(
"Video4Linux2 Compressed A/V"
)
);
set_capability
(
"access2"
,
0
);
/* use these when open as access_demux fails; VLC will use another demux */
set_callbacks
(
AccessOpen
,
AccessClose
);
vlc_module_end
();
vlc_module_end
();
/*****************************************************************************
/*****************************************************************************
* Access: local prototypes
* Access: local prototypes
*****************************************************************************/
*****************************************************************************/
static
void
ParseMRL
(
demux_t
*
);
static
void
CommonClose
(
vlc_object_t
*
,
demux_sys_t
*
);
static
void
ParseMRL
(
demux_sys_t
*
,
char
*
,
vlc_object_t
*
);
static
void
GetV4L2Params
(
demux_sys_t
*
,
vlc_object_t
*
);
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
static
int
AccessControl
(
access_t
*
,
int
,
va_list
);
static
int
Demux
(
demux_t
*
);
static
int
Demux
(
demux_t
*
);
static
ssize_t
AccessRead
(
access_t
*
,
uint8_t
*
,
size_t
);
static
block_t
*
GrabVideo
(
demux_t
*
p_demux
);
static
block_t
*
GrabVideo
(
demux_t
*
p_demux
);
static
block_t
*
ProcessVideoFrame
(
demux_t
*
p_demux
,
uint8_t
*
p_frame
,
size_t
);
static
block_t
*
ProcessVideoFrame
(
demux_t
*
p_demux
,
uint8_t
*
p_frame
,
size_t
);
static
block_t
*
GrabAudio
(
demux_t
*
p_demux
);
static
block_t
*
GrabAudio
(
demux_t
*
p_demux
);
...
@@ -229,18 +244,24 @@ static block_t* GrabAudio( demux_t *p_demux );
...
@@ -229,18 +244,24 @@ static block_t* GrabAudio( demux_t *p_demux );
vlc_bool_t
IsPixelFormatSupported
(
demux_t
*
p_demux
,
unsigned
int
i_pixelformat
);
vlc_bool_t
IsPixelFormatSupported
(
demux_t
*
p_demux
,
unsigned
int
i_pixelformat
);
char
*
ResolveALSADeviceName
(
char
*
psz_device
);
char
*
ResolveALSADeviceName
(
char
*
psz_device
);
static
int
OpenVideoDev
(
demux_t
*
,
char
*
psz_device
);
static
int
OpenVideoDev
(
vlc_object_t
*
,
demux_sys_t
*
,
vlc_bool_t
);
static
int
OpenAudioDev
(
demux_t
*
,
char
*
psz_device
);
static
int
OpenAudioDev
(
demux_t
*
,
char
*
psz_device
);
static
vlc_bool_t
ProbeVideoDev
(
demux
_t
*
,
char
*
psz_device
);
static
vlc_bool_t
ProbeVideoDev
(
vlc_object_t
*
,
demux_sys
_t
*
,
char
*
psz_device
);
static
vlc_bool_t
ProbeAudioDev
(
demux_t
*
,
char
*
psz_device
);
static
vlc_bool_t
ProbeAudioDev
(
demux_t
*
,
char
*
psz_device
);
static
int
ControlList
(
demux_t
*
p_demux
,
int
i_fd
,
vlc_bool_t
b_rese
t
);
static
int
ControlList
(
vlc_object_t
*
,
int
,
vlc_bool_t
,
vlc_bool_
t
);
static
int
Control
(
demux
_t
*
,
int
i_fd
,
static
int
Control
(
vlc_object
_t
*
,
int
i_fd
,
const
char
*
psz_name
,
int
i_cid
,
int
i_value
);
const
char
*
psz_name
,
int
i_cid
,
int
i_value
);
static
int
ControlCallback
(
vlc_object_t
*
p_this
,
static
int
DemuxControlCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
);
static
int
DemuxControlResetCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
);
static
int
AccessControlCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
);
void
*
p_data
);
static
int
ControlResetCallback
(
vlc_object_t
*
p_this
,
static
int
Access
ControlResetCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
);
void
*
p_data
);
...
@@ -379,17 +400,16 @@ struct demux_sys_t
...
@@ -379,17 +400,16 @@ struct demux_sys_t
};
};
/*****************************************************************************
/*****************************************************************************
*
Open: opens v4l2 device
*
DemuxOpen: opens v4l2 device, access_demux callback
*****************************************************************************
*****************************************************************************
*
*
* url: <video device>::::
* url: <video device>::::
*
*
*****************************************************************************/
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Demux
Open
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
demux_sys_t
*
p_sys
;
vlc_value_t
val
;
/* Only when selected */
/* Only when selected */
if
(
*
p_demux
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
if
(
*
p_demux
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
...
@@ -404,51 +424,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -404,51 +424,9 @@ static int Open( vlc_object_t *p_this )
p_demux
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
p_demux
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
p_sys
->
i_video_pts
=
-
1
;
GetV4L2Params
(
p_sys
,
(
vlc_object_t
*
)
p_demux
);
var_Create
(
p_demux
,
"v4l2-standard"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_demux
,
"v4l2-standard"
,
&
val
);
p_sys
->
i_selected_standard_id
=
i_standards_list
[
val
.
i_int
];
p_sys
->
i_selected_input
=
var_CreateGetInteger
(
p_demux
,
"v4l2-input"
);
p_sys
->
io
=
var_CreateGetInteger
(
p_demux
,
"v4l2-io"
);
p_sys
->
i_width
=
var_CreateGetInteger
(
p_demux
,
"v4l2-width"
);
p_sys
->
i_height
=
var_CreateGetInteger
(
p_demux
,
"v4l2-height"
);
var_CreateGetBool
(
p_demux
,
"v4l2-controls-reset"
);
var_Create
(
p_demux
,
"v4l2-fps"
,
VLC_VAR_FLOAT
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_demux
,
"v4l2-fps"
,
&
val
);
p_sys
->
f_fps
=
val
.
f_float
;
var_Create
(
p_demux
,
"v4l2-samplerate"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_demux
,
"v4l2-samplerate"
,
&
val
);
p_sys
->
i_sample_rate
=
val
.
i_int
;
p_sys
->
psz_requested_chroma
=
var_CreateGetString
(
p_demux
,
"v4l2-chroma"
);
#ifdef HAVE_ALSA
var_Create
(
p_demux
,
"v4l2-alsa"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_demux
,
"v4l2-alsa"
,
&
val
);
p_sys
->
b_use_alsa
=
val
.
b_bool
;
#endif
var_Create
(
p_demux
,
"v4l2-stereo"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_demux
,
"v4l2-stereo"
,
&
val
);
p_sys
->
b_stereo
=
val
.
b_bool
;
p_sys
->
i_pts
=
var_CreateGetInteger
(
p_demux
,
"v4l2-caching"
);
p_sys
->
psz_device
=
p_sys
->
psz_vdev
=
p_sys
->
psz_adev
=
NULL
;
p_sys
->
i_fd_video
=
-
1
;
p_sys
->
i_fd_audio
=
-
1
;
p_sys
->
p_es_video
=
p_sys
->
p_es_audio
=
0
;
ParseMRL
(
p_sys
,
p_demux
->
psz_path
,
(
vlc_object_t
*
)
p_demux
);
p_sys
->
p_block_audio
=
0
;
ParseMRL
(
p_demux
);
#ifdef HAVE_ALSA
#ifdef HAVE_ALSA
/* Alsa support available? */
/* Alsa support available? */
...
@@ -462,17 +440,17 @@ static int Open( vlc_object_t *p_this )
...
@@ -462,17 +440,17 @@ static int Open( vlc_object_t *p_this )
/* Try to open as video device */
/* Try to open as video device */
msg_Dbg
(
p_demux
,
"trying device '%s' as video"
,
p_sys
->
psz_device
);
msg_Dbg
(
p_demux
,
"trying device '%s' as video"
,
p_sys
->
psz_device
);
if
(
ProbeVideoDev
(
p_demux
,
p_sys
->
psz_device
)
)
if
(
ProbeVideoDev
(
(
vlc_object_t
*
)
p_demux
,
p_sys
,
p_sys
->
psz_device
)
)
{
{
msg_Dbg
(
p_demux
,
"'%s' is a video device"
,
p_sys
->
psz_device
);
msg_Dbg
(
p_demux
,
"'%s' is a video device"
,
p_sys
->
psz_device
);
/* Device was a video device */
/* Device was a video device */
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
p_sys
->
psz_vdev
=
p_sys
->
psz_device
;
p_sys
->
psz_vdev
=
p_sys
->
psz_device
;
p_sys
->
psz_device
=
NULL
;
p_sys
->
psz_device
=
NULL
;
p_sys
->
i_fd_video
=
OpenVideoDev
(
p_demux
,
p_sys
->
psz_vdev
);
p_sys
->
i_fd_video
=
OpenVideoDev
(
(
vlc_object_t
*
)
p_demux
,
p_sys
,
VLC_TRUE
);
if
(
p_sys
->
i_fd_video
<
0
)
if
(
p_sys
->
i_fd_video
<
0
)
{
{
Close
(
p_this
);
Demux
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
}
}
...
@@ -490,7 +468,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -490,7 +468,7 @@ static int Open( vlc_object_t *p_this )
p_sys
->
i_fd_audio
=
OpenAudioDev
(
p_demux
,
p_sys
->
psz_adev
);
p_sys
->
i_fd_audio
=
OpenAudioDev
(
p_demux
,
p_sys
->
psz_adev
);
if
(
p_sys
->
i_fd_audio
<
0
)
if
(
p_sys
->
i_fd_audio
<
0
)
{
{
Close
(
p_this
);
Demux
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
}
}
...
@@ -502,7 +480,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -502,7 +480,7 @@ static int Open( vlc_object_t *p_this )
{
{
if
(
strcmp
(
p_demux
->
psz_access
,
"v4l2"
)
)
if
(
strcmp
(
p_demux
->
psz_access
,
"v4l2"
)
)
{
{
Close
(
p_this
);
Demux
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
}
}
...
@@ -517,9 +495,9 @@ static int Open( vlc_object_t *p_this )
...
@@ -517,9 +495,9 @@ static int Open( vlc_object_t *p_this )
}
}
msg_Dbg
(
p_demux
,
"opening '%s' as video"
,
p_sys
->
psz_vdev
);
msg_Dbg
(
p_demux
,
"opening '%s' as video"
,
p_sys
->
psz_vdev
);
if
(
p_sys
->
psz_vdev
&&
*
p_sys
->
psz_vdev
&&
ProbeVideoDev
(
p_demux
,
p_sys
->
psz_vdev
)
)
if
(
p_sys
->
psz_vdev
&&
*
p_sys
->
psz_vdev
&&
ProbeVideoDev
(
(
vlc_object_t
*
)
p_demux
,
p_sys
,
p_sys
->
psz_vdev
)
)
{
{
p_sys
->
i_fd_video
=
OpenVideoDev
(
p_demux
,
p_sys
->
psz_vdev
);
p_sys
->
i_fd_video
=
OpenVideoDev
(
(
vlc_object_t
*
)
p_demux
,
p_sys
,
VLC_TRUE
);
}
}
}
}
...
@@ -541,7 +519,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -541,7 +519,7 @@ static int Open( vlc_object_t *p_this )
if
(
p_sys
->
i_fd_video
<
0
&&
p_sys
->
i_fd_audio
<
0
)
if
(
p_sys
->
i_fd_video
<
0
&&
p_sys
->
i_fd_audio
<
0
)
{
{
Close
(
p_this
);
Demux
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -549,13 +527,63 @@ static int Open( vlc_object_t *p_this )
...
@@ -549,13 +527,63 @@ static int Open( vlc_object_t *p_this )
}
}
/*****************************************************************************
/*****************************************************************************
*
ParseMRL: parse the options contained in the MRL
*
GetV4L2Params: fill in p_sys parameters (shared by DemuxOpen and AccessOpen)
*****************************************************************************/
*****************************************************************************/
static
void
ParseMRL
(
demux_t
*
p_demux
)
void
GetV4L2Params
(
demux_sys_t
*
p_sys
,
vlc_object_t
*
p_obj
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
vlc_value_t
val
;
p_sys
->
i_video_pts
=
-
1
;
var_Create
(
p_obj
,
"v4l2-standard"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_obj
,
"v4l2-standard"
,
&
val
);
p_sys
->
i_selected_standard_id
=
i_standards_list
[
val
.
i_int
];
p_sys
->
i_selected_input
=
var_CreateGetInteger
(
p_obj
,
"v4l2-input"
);
p_sys
->
io
=
var_CreateGetInteger
(
p_obj
,
"v4l2-io"
);
p_sys
->
i_width
=
var_CreateGetInteger
(
p_obj
,
"v4l2-width"
);
p_sys
->
i_height
=
var_CreateGetInteger
(
p_obj
,
"v4l2-height"
);
var_CreateGetBool
(
p_obj
,
"v4l2-controls-reset"
);
var_Create
(
p_obj
,
"v4l2-fps"
,
VLC_VAR_FLOAT
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_obj
,
"v4l2-fps"
,
&
val
);
p_sys
->
f_fps
=
val
.
f_float
;
var_Create
(
p_obj
,
"v4l2-samplerate"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_obj
,
"v4l2-samplerate"
,
&
val
);
p_sys
->
i_sample_rate
=
val
.
i_int
;
p_sys
->
psz_requested_chroma
=
var_CreateGetString
(
p_obj
,
"v4l2-chroma"
);
#ifdef HAVE_ALSA
var_Create
(
p_obj
,
"v4l2-alsa"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_obj
,
"v4l2-alsa"
,
&
val
);
p_sys
->
b_use_alsa
=
val
.
b_bool
;
#endif
var_Create
(
p_obj
,
"v4l2-stereo"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_obj
,
"v4l2-stereo"
,
&
val
);
p_sys
->
b_stereo
=
val
.
b_bool
;
char
*
psz_dup
=
strdup
(
p_demux
->
psz_path
);
p_sys
->
i_pts
=
var_CreateGetInteger
(
p_obj
,
"v4l2-caching"
);
p_sys
->
psz_device
=
p_sys
->
psz_vdev
=
p_sys
->
psz_adev
=
NULL
;
p_sys
->
i_fd_video
=
-
1
;
p_sys
->
i_fd_audio
=
-
1
;
p_sys
->
p_es_video
=
p_sys
->
p_es_audio
=
0
;
p_sys
->
p_block_audio
=
0
;
}
/*****************************************************************************
* ParseMRL: parse the options contained in the MRL
*****************************************************************************/
static
void
ParseMRL
(
demux_sys_t
*
p_sys
,
char
*
psz_path
,
vlc_object_t
*
p_obj
)
{
char
*
psz_dup
=
strdup
(
psz_path
);
char
*
psz_parser
=
psz_dup
;
char
*
psz_parser
=
psz_dup
;
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
...
@@ -685,42 +713,42 @@ static void ParseMRL( demux_t *p_demux )
...
@@ -685,42 +713,42 @@ static void ParseMRL( demux_t *p_demux )
else
if
(
!
strncmp
(
psz_parser
,
"controls-reset"
,
else
if
(
!
strncmp
(
psz_parser
,
"controls-reset"
,
strlen
(
"controls-reset"
)
)
)
strlen
(
"controls-reset"
)
)
)
{
{
var_SetBool
(
p_
demux
,
"v4l2-controls-reset"
,
VLC_TRUE
);
var_SetBool
(
p_
obj
,
"v4l2-controls-reset"
,
VLC_TRUE
);
psz_parser
+=
strlen
(
"controls-reset"
);
psz_parser
+=
strlen
(
"controls-reset"
);
}
}
#if 0
#if 0
else if( !strncmp( psz_parser, "brightness=",
else if( !strncmp( psz_parser, "brightness=",
strlen( "brightness=" ) ) )
strlen( "brightness=" ) ) )
{
{
var_SetInteger( p_
demux
, "brightness",
var_SetInteger( p_
obj
, "brightness",
strtol( psz_parser + strlen( "brightness=" ),
strtol( psz_parser + strlen( "brightness=" ),
&psz_parser, 0 ) );
&psz_parser, 0 ) );
}
}
else if( !strncmp( psz_parser, "contrast=",
else if( !strncmp( psz_parser, "contrast=",
strlen( "contrast=" ) ) )
strlen( "contrast=" ) ) )
{
{
var_SetInteger( p_
demux
, "contrast",
var_SetInteger( p_
obj
, "contrast",
strtol( psz_parser + strlen( "contrast=" ),
strtol( psz_parser + strlen( "contrast=" ),
&psz_parser, 0 ) );
&psz_parser, 0 ) );
}
}
else if( !strncmp( psz_parser, "saturation=",
else if( !strncmp( psz_parser, "saturation=",
strlen( "saturation=" ) ) )
strlen( "saturation=" ) ) )
{
{
var_SetInteger( p_
demux
, "saturation",
var_SetInteger( p_
obj
, "saturation",
strtol( psz_parser + strlen( "saturation=" ),
strtol( psz_parser + strlen( "saturation=" ),
&psz_parser, 0 ) );
&psz_parser, 0 ) );
}
}
else if( !strncmp( psz_parser, "hue=",
else if( !strncmp( psz_parser, "hue=",
strlen( "hue=" ) ) )
strlen( "hue=" ) ) )
{
{
var_SetInteger( p_
demux
, "hue",
var_SetInteger( p_
obj
, "hue",
strtol( psz_parser + strlen( "hue=" ),
strtol( psz_parser + strlen( "hue=" ),
&psz_parser, 0 ) );
&psz_parser, 0 ) );
}
}
else if( !strncmp( psz_parser, "gamma=",
else if( !strncmp( psz_parser, "gamma=",
strlen( "gamma=" ) ) )
strlen( "gamma=" ) ) )
{
{
var_SetInteger( p_
demux
, "gamma",
var_SetInteger( p_
obj
, "gamma",
strtol( psz_parser + strlen( "gamma=" ),
strtol( psz_parser + strlen( "gamma=" ),
&psz_parser, 0 ) );
&psz_parser, 0 ) );
}
}
...
@@ -756,7 +784,7 @@ static void ParseMRL( demux_t *p_demux )
...
@@ -756,7 +784,7 @@ static void ParseMRL( demux_t *p_demux )
}
}
else
else
{
{
msg_Warn
(
p_
demux
,
"unknown option"
);
msg_Warn
(
p_
obj
,
"unknown option"
);
}
}
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
...
@@ -782,14 +810,23 @@ static void ParseMRL( demux_t *p_demux )
...
@@ -782,14 +810,23 @@ static void ParseMRL( demux_t *p_demux )
/*****************************************************************************
/*****************************************************************************
* Close: close device, free resources
* Close: close device, free resources
*****************************************************************************/
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
static
void
AccessClose
(
vlc_object_t
*
p_this
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_access
->
p_sys
;
CommonClose
(
p_this
,
p_sys
);
}
static
void
DemuxClose
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
v4l2_buffer
buf
;
struct
v4l2_buffer
buf
;
enum
v4l2_buf_type
buf_type
;
enum
v4l2_buf_type
buf_type
;
unsigned
int
i
;
unsigned
int
i
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
/* Stop video capture */
/* Stop video capture */
if
(
p_sys
->
i_fd_video
>=
0
)
if
(
p_sys
->
i_fd_video
>=
0
)
{
{
...
@@ -813,7 +850,7 @@ static void Close( vlc_object_t *p_this )
...
@@ -813,7 +850,7 @@ static void Close( vlc_object_t *p_this )
buf_type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf_type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_STREAMOFF
,
&
buf_type
)
<
0
)
{
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_STREAMOFF
,
&
buf_type
)
<
0
)
{
msg_Err
(
p_
demux
,
"VIDIOC_STREAMOFF failed"
);
msg_Err
(
p_
this
,
"VIDIOC_STREAMOFF failed"
);
}
}
break
;
break
;
...
@@ -833,7 +870,7 @@ static void Close( vlc_object_t *p_this )
...
@@ -833,7 +870,7 @@ static void Close( vlc_object_t *p_this )
{
{
if
(
munmap
(
p_sys
->
p_buffers
[
i
].
start
,
p_sys
->
p_buffers
[
i
].
length
)
)
if
(
munmap
(
p_sys
->
p_buffers
[
i
].
start
,
p_sys
->
p_buffers
[
i
].
length
)
)
{
{
msg_Err
(
p_
demux
,
"munmap failed"
);
msg_Err
(
p_
this
,
"munmap failed"
);
}
}
}
}
break
;
break
;
...
@@ -848,6 +885,11 @@ static void Close( vlc_object_t *p_this )
...
@@ -848,6 +885,11 @@ static void Close( vlc_object_t *p_this )
free
(
p_sys
->
p_buffers
);
free
(
p_sys
->
p_buffers
);
}
}
CommonClose
(
p_this
,
p_sys
);
}
static
void
CommonClose
(
vlc_object_t
*
p_this
,
demux_sys_t
*
p_sys
)
{
/* Close */
/* Close */
if
(
p_sys
->
i_fd_video
>=
0
)
close
(
p_sys
->
i_fd_video
);
if
(
p_sys
->
i_fd_video
>=
0
)
close
(
p_sys
->
i_fd_video
);
#ifdef HAVE_ALSA
#ifdef HAVE_ALSA
...
@@ -874,6 +916,99 @@ static void Close( vlc_object_t *p_this )
...
@@ -874,6 +916,99 @@ static void Close( vlc_object_t *p_this )
free
(
p_sys
);
free
(
p_sys
);
}
}
/*****************************************************************************
* AccessOpen: opens v4l2 device, access2 callback
*****************************************************************************
*
* url: <video device>::::
*
*****************************************************************************/
static
int
AccessOpen
(
vlc_object_t
*
p_this
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
/* Only when selected */
if
(
*
p_access
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
p_access
->
pf_read
=
AccessRead
;
p_access
->
pf_block
=
NULL
;
p_access
->
pf_seek
=
NULL
;
p_access
->
pf_control
=
AccessControl
;
p_access
->
info
.
i_update
=
0
;
p_access
->
info
.
i_size
=
0
;
p_access
->
info
.
i_pos
=
0
;
p_access
->
info
.
b_eof
=
VLC_FALSE
;
p_access
->
info
.
i_title
=
0
;
p_access
->
info
.
i_seekpoint
=
0
;
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
p_access
->
p_sys
=
(
access_sys_t
*
)
p_sys
;
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
GetV4L2Params
(
p_sys
,
(
vlc_object_t
*
)
p_access
);
ParseMRL
(
p_sys
,
p_access
->
psz_path
,
(
vlc_object_t
*
)
p_access
);
/* Find main device (video) */
if
(
p_sys
->
psz_device
&&
*
p_sys
->
psz_device
)
{
msg_Dbg
(
p_access
,
"main device='%s'"
,
p_sys
->
psz_device
);
/* Try to open as video device */
msg_Dbg
(
p_access
,
"trying device '%s' as video"
,
p_sys
->
psz_device
);
if
(
ProbeVideoDev
(
(
vlc_object_t
*
)
p_access
,
p_sys
,
p_sys
->
psz_device
)
)
{
msg_Dbg
(
p_access
,
"'%s' is a video device"
,
p_sys
->
psz_device
);
/* Device was a video device */
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
p_sys
->
psz_vdev
=
p_sys
->
psz_device
;
p_sys
->
psz_device
=
NULL
;
p_sys
->
i_fd_video
=
OpenVideoDev
(
(
vlc_object_t
*
)
p_access
,
p_sys
,
VLC_FALSE
);
if
(
p_sys
->
i_fd_video
<
0
)
{
AccessClose
(
p_this
);
return
VLC_EGENERIC
;
}
}
}
/* If no device opened, only continue if the access was forced */
if
(
p_sys
->
i_fd_video
<
0
)
{
if
(
strcmp
(
p_access
->
psz_access
,
"v4l2"
)
)
{
AccessClose
(
p_this
);
return
VLC_EGENERIC
;
}
}
/* Find video device */
if
(
p_sys
->
i_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_access
,
"v4l2-dev"
);
}
msg_Dbg
(
p_access
,
"opening '%s' as video"
,
p_sys
->
psz_vdev
);
if
(
p_sys
->
psz_vdev
&&
*
p_sys
->
psz_vdev
&&
ProbeVideoDev
(
(
vlc_object_t
*
)
p_access
,
p_sys
,
p_sys
->
psz_vdev
)
)
{
p_sys
->
i_fd_video
=
OpenVideoDev
(
(
vlc_object_t
*
)
p_access
,
p_sys
,
VLC_FALSE
);
}
}
if
(
p_sys
->
i_fd_video
<
0
)
{
AccessClose
(
p_this
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
/*****************************************************************************
* DemuxControl:
* DemuxControl:
*****************************************************************************/
*****************************************************************************/
...
@@ -911,6 +1046,108 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
...
@@ -911,6 +1046,108 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/*****************************************************************************
* AccessControl: access2 callback
*****************************************************************************/
static
int
AccessControl
(
access_t
*
p_access
,
int
i_query
,
va_list
args
)
{
vlc_bool_t
*
pb_bool
;
int
*
pi_int
;
int64_t
*
pi_64
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_access
->
p_sys
;
switch
(
i_query
)
{
/* */
case
ACCESS_CAN_SEEK
:
case
ACCESS_CAN_FASTSEEK
:
pb_bool
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb_bool
=
VLC_FALSE
;
break
;
case
ACCESS_CAN_PAUSE
:
pb_bool
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb_bool
=
VLC_FALSE
;
break
;
case
ACCESS_CAN_CONTROL_PACE
:
pb_bool
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb_bool
=
VLC_FALSE
;
break
;
/* */
case
ACCESS_GET_MTU
:
pi_int
=
(
int
*
)
va_arg
(
args
,
int
*
);
*
pi_int
=
0
;
break
;
case
ACCESS_GET_PTS_DELAY
:
pi_64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi_64
=
(
int64_t
)
p_sys
->
i_pts
*
1000
;
break
;
/* */
case
ACCESS_SET_PAUSE_STATE
:
/* Nothing to do */
break
;
case
ACCESS_GET_TITLE_INFO
:
case
ACCESS_SET_TITLE
:
case
ACCESS_SET_SEEKPOINT
:
case
ACCESS_SET_PRIVATE_ID_STATE
:
case
ACCESS_GET_CONTENT_TYPE
:
case
ACCESS_GET_META
:
return
VLC_EGENERIC
;
default:
msg_Warn
(
p_access
,
"Unimplemented query in control(%d)."
,
i_query
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* AccessRead: access2 callback
******************************************************************************/
static
ssize_t
AccessRead
(
access_t
*
p_access
,
uint8_t
*
p_buffer
,
size_t
i_len
)
{
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_access
->
p_sys
;
struct
pollfd
ufd
;
int
i_ret
;
ufd
.
fd
=
p_sys
->
i_fd_video
;
ufd
.
events
=
POLLIN
;
if
(
p_access
->
info
.
b_eof
)
return
0
;
do
{
if
(
p_access
->
b_die
)
return
0
;
ufd
.
revents
=
0
;
}
while
(
(
i_ret
=
poll
(
&
ufd
,
1
,
500
)
)
==
0
);
if
(
i_ret
<
0
)
{
msg_Err
(
p_access
,
"Polling error (%m)."
);
return
-
1
;
}
i_ret
=
read
(
p_sys
->
i_fd_video
,
p_buffer
,
i_len
);
if
(
i_ret
==
0
)
{
p_access
->
info
.
b_eof
=
VLC_TRUE
;
}
else
if
(
i_ret
>
0
)
{
p_access
->
info
.
i_pos
+=
i_ret
;
}
return
i_ret
;
}
/*****************************************************************************
/*****************************************************************************
* Demux: Processes the audio or video frame
* Demux: Processes the audio or video frame
*****************************************************************************/
*****************************************************************************/
...
@@ -1379,19 +1616,19 @@ vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat
...
@@ -1379,19 +1616,19 @@ vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat
/*****************************************************************************
/*****************************************************************************
* OpenVideoDev: open and set up the video device and probe for capabilities
* OpenVideoDev: open and set up the video device and probe for capabilities
*****************************************************************************/
*****************************************************************************/
int
OpenVideoDev
(
demux_t
*
p_demux
,
char
*
psz_device
)
int
OpenVideoDev
(
vlc_object_t
*
p_obj
,
demux_sys_t
*
p_sys
,
vlc_bool_t
b_demux
)
{
{
int
i_fd
;
int
i_fd
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
v4l2_cropcap
cropcap
;
struct
v4l2_cropcap
cropcap
;
struct
v4l2_crop
crop
;
struct
v4l2_crop
crop
;
struct
v4l2_format
fmt
;
struct
v4l2_format
fmt
;
unsigned
int
i_min
;
unsigned
int
i_min
;
enum
v4l2_buf_type
buf_type
;
enum
v4l2_buf_type
buf_type
;
char
*
psz_device
=
p_sys
->
psz_vdev
;
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot open device (%m)"
);
msg_Err
(
p_
obj
,
"cannot open device (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
...
@@ -1401,26 +1638,38 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -1401,26 +1638,38 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
{
{
if
(
ioctl
(
i_fd
,
VIDIOC_S_STD
,
&
p_sys
->
i_selected_standard_id
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_S_STD
,
&
p_sys
->
i_selected_standard_id
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot set standard (%m)"
);
msg_Err
(
p_
obj
,
"cannot set standard (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"Set standard"
);
msg_Dbg
(
p_
obj
,
"Set standard"
);
}
}
/* Select input */
/* Select input */
if
(
p_sys
->
i_selected_input
>
p_sys
->
i_input
)
if
(
p_sys
->
i_selected_input
>
p_sys
->
i_input
)
{
{
msg_Warn
(
p_
demux
,
"invalid input. Using the default one"
);
msg_Warn
(
p_
obj
,
"invalid input. Using the default one"
);
p_sys
->
i_selected_input
=
0
;
p_sys
->
i_selected_input
=
0
;
}
}
if
(
ioctl
(
i_fd
,
VIDIOC_S_INPUT
,
&
p_sys
->
i_selected_input
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_S_INPUT
,
&
p_sys
->
i_selected_input
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot set input (%m)"
);
msg_Err
(
p_
obj
,
"cannot set input (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
/* TODO: Move the resolution stuff up here */
/* if MPEG encoder card, no need to do anything else after this */
if
(
VLC_FALSE
==
b_demux
)
{
ControlList
(
p_obj
,
i_fd
,
var_GetBool
(
p_obj
,
"v4l2-controls-reset"
),
b_demux
);
return
i_fd
;
}
demux_t
*
p_demux
=
(
demux_t
*
)
p_obj
;
/* Verify device support for the various IO methods */
/* Verify device support for the various IO methods */
switch
(
p_sys
->
io
)
switch
(
p_sys
->
io
)
{
{
...
@@ -1524,6 +1773,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -1524,6 +1773,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
}
/* If no user specified chroma, find best */
/* If no user specified chroma, find best */
/* This also decides if MPEG encoder card or not */
if
(
!
fmt
.
fmt
.
pix
.
pixelformat
)
if
(
!
fmt
.
fmt
.
pix
.
pixelformat
)
{
{
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YVU420
;
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YVU420
;
...
@@ -1535,7 +1785,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -1535,7 +1785,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YUYV
;
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YUYV
;
if
(
!
IsPixelFormatSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
if
(
!
IsPixelFormatSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
{
{
msg_
Err
(
p_demux
,
"Could not select any of the default chromas!
"
);
msg_
Warn
(
p_demux
,
"Could not select any of the default chromas; attempting to open as MPEG encoder card (access2)
"
);
goto
open_failed
;
goto
open_failed
;
}
}
}
}
...
@@ -1612,9 +1862,6 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -1612,9 +1862,6 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
}
#endif
#endif
ControlList
(
p_demux
,
i_fd
,
var_GetBool
(
p_demux
,
"v4l2-controls-reset"
)
);
/* Init IO method */
/* Init IO method */
switch
(
p_sys
->
io
)
switch
(
p_sys
->
io
)
{
{
...
@@ -2000,17 +2247,16 @@ int OpenAudioDev( demux_t *p_demux, char *psz_device )
...
@@ -2000,17 +2247,16 @@ int OpenAudioDev( demux_t *p_demux, char *psz_device )
/*****************************************************************************
/*****************************************************************************
* ProbeVideoDev: probe video for capabilities
* ProbeVideoDev: probe video for capabilities
*****************************************************************************/
*****************************************************************************/
vlc_bool_t
ProbeVideoDev
(
demux_t
*
p_demux
,
char
*
psz_device
)
vlc_bool_t
ProbeVideoDev
(
vlc_object_t
*
p_obj
,
demux_sys_t
*
p_sys
,
char
*
psz_device
)
{
{
int
i_index
;
int
i_index
;
int
i_standard
;
int
i_standard
;
int
i_fd
;
int
i_fd
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot open video device (%m)"
);
msg_Err
(
p_
obj
,
"cannot open video device (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
...
@@ -2018,11 +2264,11 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2018,11 +2264,11 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYCAP
,
&
p_sys
->
dev_cap
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYCAP
,
&
p_sys
->
dev_cap
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot get video capabilities (%m)"
);
msg_Err
(
p_
obj
,
"cannot get video capabilities (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"V4L2 device: %s using driver: %s (version: %u.%u.%u) on %s"
,
msg_Dbg
(
p_
obj
,
"V4L2 device: %s using driver: %s (version: %u.%u.%u) on %s"
,
p_sys
->
dev_cap
.
card
,
p_sys
->
dev_cap
.
card
,
p_sys
->
dev_cap
.
driver
,
p_sys
->
dev_cap
.
driver
,
(
p_sys
->
dev_cap
.
version
>>
16
)
&
0xFF
,
(
p_sys
->
dev_cap
.
version
>>
16
)
&
0xFF
,
...
@@ -2030,14 +2276,14 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2030,14 +2276,14 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
p_sys
->
dev_cap
.
version
&
0xFF
,
p_sys
->
dev_cap
.
version
&
0xFF
,
p_sys
->
dev_cap
.
bus_info
);
p_sys
->
dev_cap
.
bus_info
);
msg_Dbg
(
p_
demux
,
"the device has the capabilities: (%c) Video Capure, "
msg_Dbg
(
p_
obj
,
"the device has the capabilities: (%c) Video Capure, "
"(%c) Audio, "
"(%c) Audio, "
"(%c) Tuner"
,
"(%c) Tuner"
,
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_VIDEO_CAPTURE
?
'X'
:
' '
),
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_VIDEO_CAPTURE
?
'X'
:
' '
),
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_AUDIO
?
'X'
:
' '
),
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_AUDIO
?
'X'
:
' '
),
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_TUNER
?
'X'
:
' '
)
);
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_TUNER
?
'X'
:
' '
)
);
msg_Dbg
(
p_
demux
,
"supported I/O methods are: (%c) Read/Write, "
msg_Dbg
(
p_
obj
,
"supported I/O methods are: (%c) Read/Write, "
"(%c) Streaming, "
"(%c) Streaming, "
"(%c) Asynchronous"
,
"(%c) Asynchronous"
,
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_READWRITE
?
'X'
:
' '
),
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_READWRITE
?
'X'
:
' '
),
...
@@ -2067,10 +2313,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2067,10 +2313,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_ENUMINPUT
,
&
p_sys
->
p_inputs
[
i_index
]
)
)
if
(
ioctl
(
i_fd
,
VIDIOC_ENUMINPUT
,
&
p_sys
->
p_inputs
[
i_index
]
)
)
{
{
msg_Err
(
p_
demux
,
"cannot get video input characteristics (%m)"
);
msg_Err
(
p_
obj
,
"cannot get video input characteristics (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"video input %i (%s) has type: %s"
,
msg_Dbg
(
p_
obj
,
"video input %i (%s) has type: %s"
,
i_index
,
i_index
,
p_sys
->
p_inputs
[
i_index
].
name
,
p_sys
->
p_inputs
[
i_index
].
name
,
p_sys
->
p_inputs
[
i_index
].
type
p_sys
->
p_inputs
[
i_index
].
type
...
@@ -2100,10 +2346,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2100,10 +2346,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_ENUMSTD
,
&
p_sys
->
p_standards
[
i_standard
]
)
)
if
(
ioctl
(
i_fd
,
VIDIOC_ENUMSTD
,
&
p_sys
->
p_standards
[
i_standard
]
)
)
{
{
msg_Err
(
p_
demux
,
"cannot get video input standards (%m)"
);
msg_Err
(
p_
obj
,
"cannot get video input standards (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"video standard %i is: %s"
,
msg_Dbg
(
p_
obj
,
"video standard %i is: %s"
,
i_standard
,
i_standard
,
p_sys
->
p_standards
[
i_standard
].
name
);
p_sys
->
p_standards
[
i_standard
].
name
);
}
}
...
@@ -2123,11 +2369,11 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2123,11 +2369,11 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
{
{
if
(
ioctl
(
i_fd
,
VIDIOC_G_AUDIO
,
&
p_sys
->
p_audios
[
p_sys
->
i_audio
]
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_G_AUDIO
,
&
p_sys
->
p_audios
[
p_sys
->
i_audio
]
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot get audio input characteristics (%m)"
);
msg_Err
(
p_
obj
,
"cannot get audio input characteristics (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"audio device %i (%s) is %s"
,
msg_Dbg
(
p_
obj
,
"audio device %i (%s) is %s"
,
p_sys
->
i_audio
,
p_sys
->
i_audio
,
p_sys
->
p_audios
[
p_sys
->
i_audio
].
name
,
p_sys
->
p_audios
[
p_sys
->
i_audio
].
name
,
p_sys
->
p_audios
[
p_sys
->
i_audio
].
capability
&
p_sys
->
p_audios
[
p_sys
->
i_audio
].
capability
&
...
@@ -2159,10 +2405,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2159,10 +2405,10 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_G_TUNER
,
&
p_sys
->
p_tuners
[
i_index
]
)
)
if
(
ioctl
(
i_fd
,
VIDIOC_G_TUNER
,
&
p_sys
->
p_tuners
[
i_index
]
)
)
{
{
msg_Err
(
p_
demux
,
"cannot get tuner characteristics (%m)"
);
msg_Err
(
p_
obj
,
"cannot get tuner characteristics (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
msg_Dbg
(
p_
demux
,
"tuner %i (%s) has type: %s, "
msg_Dbg
(
p_
obj
,
"tuner %i (%s) has type: %s, "
"frequency range: %.1f %s -> %.1f %s"
,
"frequency range: %.1f %s -> %.1f %s"
,
i_index
,
i_index
,
p_sys
->
p_tuners
[
i_index
].
name
,
p_sys
->
p_tuners
[
i_index
].
name
,
...
@@ -2207,7 +2453,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2207,7 +2453,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FMT
,
&
p_sys
->
p_codecs
[
i_index
]
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FMT
,
&
p_sys
->
p_codecs
[
i_index
]
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"cannot get codec description (%m)"
);
msg_Err
(
p_
obj
,
"cannot get codec description (%m)"
);
goto
open_failed
;
goto
open_failed
;
}
}
...
@@ -2222,7 +2468,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2222,7 +2468,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
char
sz_fourcc
[
5
];
char
sz_fourcc
[
5
];
memset
(
&
sz_fourcc
,
0
,
sizeof
(
sz_fourcc
)
);
memset
(
&
sz_fourcc
,
0
,
sizeof
(
sz_fourcc
)
);
vlc_fourcc_to_char
(
v4l2chroma_to_fourcc
[
i
].
i_fourcc
,
&
sz_fourcc
);
vlc_fourcc_to_char
(
v4l2chroma_to_fourcc
[
i
].
i_fourcc
,
&
sz_fourcc
);
msg_Dbg
(
p_
demux
,
"device supports chroma %4s [%s]"
,
msg_Dbg
(
p_
obj
,
"device supports chroma %4s [%s]"
,
sz_fourcc
,
sz_fourcc
,
p_sys
->
p_codecs
[
i_index
].
description
);
p_sys
->
p_codecs
[
i_index
].
description
);
...
@@ -2235,7 +2481,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2235,7 +2481,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
<
0
)
{
{
/* Not all devices support this ioctl */
/* Not all devices support this ioctl */
msg_Warn
(
p_
demux
,
"Unable to query for frame sizes"
);
msg_Warn
(
p_
obj
,
"Unable to query for frame sizes"
);
}
}
else
else
{
{
...
@@ -2244,21 +2490,21 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2244,21 +2490,21 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
do
do
{
{
msg_Dbg
(
p_
demux
,
msg_Dbg
(
p_
obj
,
" device supports size %dx%d"
,
" device supports size %dx%d"
,
frmsize
.
discrete
.
width
,
frmsize
.
discrete
.
height
);
frmsize
.
discrete
.
width
,
frmsize
.
discrete
.
height
);
frmsize
.
index
++
;
frmsize
.
index
++
;
}
while
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
);
}
while
(
ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
);
break
;
break
;
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
msg_Dbg
(
p_
demux
,
msg_Dbg
(
p_
obj
,
" device supports sizes %dx%d to %dx%d using %dx%d increments"
,
" device supports sizes %dx%d to %dx%d using %dx%d increments"
,
frmsize
.
stepwise
.
min_width
,
frmsize
.
stepwise
.
min_height
,
frmsize
.
stepwise
.
min_width
,
frmsize
.
stepwise
.
min_height
,
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
,
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
,
frmsize
.
stepwise
.
step_width
,
frmsize
.
stepwise
.
step_height
);
frmsize
.
stepwise
.
step_width
,
frmsize
.
stepwise
.
step_height
);
break
;
break
;
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
msg_Dbg
(
p_
demux
,
msg_Dbg
(
p_
obj
,
" device supports all sizes %dx%d to %dx%d"
,
" device supports all sizes %dx%d to %dx%d"
,
frmsize
.
stepwise
.
min_width
,
frmsize
.
stepwise
.
min_height
,
frmsize
.
stepwise
.
min_width
,
frmsize
.
stepwise
.
min_height
,
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
);
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
);
...
@@ -2270,7 +2516,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
...
@@ -2270,7 +2516,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
}
}
if
(
!
b_codec_supported
)
if
(
!
b_codec_supported
)
{
{
msg_Dbg
(
p_
demux
,
"device codec %s not supported
"
,
msg_Dbg
(
p_
obj
,
"device codec %s not supported as access_demux
"
,
p_sys
->
p_codecs
[
i_index
].
description
);
p_sys
->
p_codecs
[
i_index
].
description
);
}
}
...
@@ -2350,9 +2596,9 @@ open_failed:
...
@@ -2350,9 +2596,9 @@ open_failed:
* Print a user-class v4l2 control's details, create the relevant variable,
* Print a user-class v4l2 control's details, create the relevant variable,
* change the value if needed.
* change the value if needed.
*****************************************************************************/
*****************************************************************************/
static
void
ControlListPrint
(
demux_t
*
p_demux
,
int
i_fd
,
static
void
ControlListPrint
(
vlc_object_t
*
p_obj
,
int
i_fd
,
struct
v4l2_queryctrl
queryctrl
,
struct
v4l2_queryctrl
queryctrl
,
vlc_bool_t
b_reset
)
vlc_bool_t
b_reset
,
vlc_bool_t
b_demux
)
{
{
struct
v4l2_querymenu
querymenu
;
struct
v4l2_querymenu
querymenu
;
unsigned
int
i_mid
;
unsigned
int
i_mid
;
...
@@ -2364,9 +2610,9 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2364,9 +2610,9 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
vlc_value_t
val
,
val2
;
vlc_value_t
val
,
val2
;
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_GRABBED
)
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_GRABBED
)
msg_Dbg
(
p_
demux
,
" control is busy"
);
msg_Dbg
(
p_
obj
,
" control is busy"
);
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_READ_ONLY
)
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_READ_ONLY
)
msg_Dbg
(
p_
demux
,
" control is read-only"
);
msg_Dbg
(
p_
obj
,
" control is read-only"
);
for
(
i
=
0
;
controls
[
i
].
psz_name
!=
NULL
;
i
++
)
for
(
i
=
0
;
controls
[
i
].
psz_name
!=
NULL
;
i
++
)
if
(
controls
[
i
].
i_cid
==
queryctrl
.
id
)
break
;
if
(
controls
[
i
].
i_cid
==
queryctrl
.
id
)
break
;
...
@@ -2376,8 +2622,8 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2376,8 +2622,8 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
psz_name
=
strdup
(
controls
[
i
].
psz_name
);
psz_name
=
strdup
(
controls
[
i
].
psz_name
);
char
psz_cfg_name
[
40
];
char
psz_cfg_name
[
40
];
sprintf
(
psz_cfg_name
,
CFG_PREFIX
"%s"
,
psz_name
);
sprintf
(
psz_cfg_name
,
CFG_PREFIX
"%s"
,
psz_name
);
i_val
=
var_CreateGetInteger
(
p_
demux
,
psz_cfg_name
);
i_val
=
var_CreateGetInteger
(
p_
obj
,
psz_cfg_name
);
var_Destroy
(
p_
demux
,
psz_cfg_name
);
var_Destroy
(
p_
obj
,
psz_cfg_name
);
}
}
else
else
{
{
...
@@ -2393,30 +2639,30 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2393,30 +2639,30 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
switch
(
queryctrl
.
type
)
switch
(
queryctrl
.
type
)
{
{
case
V4L2_CTRL_TYPE_INTEGER
:
case
V4L2_CTRL_TYPE_INTEGER
:
msg_Dbg
(
p_
demux
,
" integer control"
);
msg_Dbg
(
p_
obj
,
" integer control"
);
msg_Dbg
(
p_
demux
,
msg_Dbg
(
p_
obj
,
" valid values: %d to %d by steps of %d"
,
" valid values: %d to %d by steps of %d"
,
queryctrl
.
minimum
,
queryctrl
.
maximum
,
queryctrl
.
minimum
,
queryctrl
.
maximum
,
queryctrl
.
step
);
queryctrl
.
step
);
var_Create
(
p_
demux
,
psz_name
,
var_Create
(
p_
obj
,
psz_name
,
VLC_VAR_INTEGER
|
VLC_VAR_HASMIN
|
VLC_VAR_HASMAX
VLC_VAR_INTEGER
|
VLC_VAR_HASMIN
|
VLC_VAR_HASMAX
|
VLC_VAR_HASSTEP
|
VLC_VAR_ISCOMMAND
);
|
VLC_VAR_HASSTEP
|
VLC_VAR_ISCOMMAND
);
val
.
i_int
=
queryctrl
.
minimum
;
val
.
i_int
=
queryctrl
.
minimum
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETMIN
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETMIN
,
&
val
,
NULL
);
val
.
i_int
=
queryctrl
.
maximum
;
val
.
i_int
=
queryctrl
.
maximum
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETMAX
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETMAX
,
&
val
,
NULL
);
val
.
i_int
=
queryctrl
.
step
;
val
.
i_int
=
queryctrl
.
step
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETSTEP
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETSTEP
,
&
val
,
NULL
);
break
;
break
;
case
V4L2_CTRL_TYPE_BOOLEAN
:
case
V4L2_CTRL_TYPE_BOOLEAN
:
msg_Dbg
(
p_
demux
,
" boolean control"
);
msg_Dbg
(
p_
obj
,
" boolean control"
);
var_Create
(
p_
demux
,
psz_name
,
var_Create
(
p_
obj
,
psz_name
,
VLC_VAR_BOOL
|
VLC_VAR_ISCOMMAND
);
VLC_VAR_BOOL
|
VLC_VAR_ISCOMMAND
);
break
;
break
;
case
V4L2_CTRL_TYPE_MENU
:
case
V4L2_CTRL_TYPE_MENU
:
msg_Dbg
(
p_
demux
,
" menu control"
);
msg_Dbg
(
p_
obj
,
" menu control"
);
var_Create
(
p_
demux
,
psz_name
,
var_Create
(
p_
obj
,
psz_name
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
|
VLC_VAR_ISCOMMAND
);
|
VLC_VAR_ISCOMMAND
);
memset
(
&
querymenu
,
0
,
sizeof
(
querymenu
)
);
memset
(
&
querymenu
,
0
,
sizeof
(
querymenu
)
);
...
@@ -2428,22 +2674,22 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2428,22 +2674,22 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
querymenu
.
id
=
queryctrl
.
id
;
querymenu
.
id
=
queryctrl
.
id
;
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYMENU
,
&
querymenu
)
>=
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYMENU
,
&
querymenu
)
>=
0
)
{
{
msg_Dbg
(
p_
demux
,
" %d: %s"
,
msg_Dbg
(
p_
obj
,
" %d: %s"
,
querymenu
.
index
,
querymenu
.
name
);
querymenu
.
index
,
querymenu
.
name
);
val
.
i_int
=
querymenu
.
index
;
val
.
i_int
=
querymenu
.
index
;
val2
.
psz_string
=
(
char
*
)
querymenu
.
name
;
val2
.
psz_string
=
(
char
*
)
querymenu
.
name
;
var_Change
(
p_
demux
,
psz_name
,
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
}
}
}
}
break
;
break
;
case
V4L2_CTRL_TYPE_BUTTON
:
case
V4L2_CTRL_TYPE_BUTTON
:
msg_Dbg
(
p_
demux
,
" button control"
);
msg_Dbg
(
p_
obj
,
" button control"
);
var_Create
(
p_
demux
,
psz_name
,
var_Create
(
p_
obj
,
psz_name
,
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
break
;
break
;
default:
default:
msg_Dbg
(
p_
demux
,
" unknown control type (FIXME)"
);
msg_Dbg
(
p_
obj
,
" unknown control type (FIXME)"
);
/* FIXME */
/* FIXME */
break
;
break
;
}
}
...
@@ -2455,27 +2701,27 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2455,27 +2701,27 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
case
V4L2_CTRL_TYPE_MENU
:
case
V4L2_CTRL_TYPE_MENU
:
{
{
struct
v4l2_control
control
;
struct
v4l2_control
control
;
msg_Dbg
(
p_
demux
,
" default value: %d"
,
msg_Dbg
(
p_
obj
,
" default value: %d"
,
queryctrl
.
default_value
);
queryctrl
.
default_value
);
memset
(
&
control
,
0
,
sizeof
(
control
)
);
memset
(
&
control
,
0
,
sizeof
(
control
)
);
control
.
id
=
queryctrl
.
id
;
control
.
id
=
queryctrl
.
id
;
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
)
{
{
msg_Dbg
(
p_
demux
,
" current value: %d"
,
control
.
value
);
msg_Dbg
(
p_
obj
,
" current value: %d"
,
control
.
value
);
}
}
if
(
i_val
==
-
1
)
if
(
i_val
==
-
1
)
{
{
i_val
=
control
.
value
;
i_val
=
control
.
value
;
if
(
b_reset
&&
queryctrl
.
default_value
!=
control
.
value
)
if
(
b_reset
&&
queryctrl
.
default_value
!=
control
.
value
)
{
{
msg_Dbg
(
p_
demux
,
" reset value to default"
);
msg_Dbg
(
p_
obj
,
" reset value to default"
);
Control
(
p_
demux
,
i_fd
,
psz_name
,
Control
(
p_
obj
,
i_fd
,
psz_name
,
queryctrl
.
id
,
queryctrl
.
default_value
);
queryctrl
.
id
,
queryctrl
.
default_value
);
}
}
}
}
else
else
{
{
Control
(
p_
demux
,
i_fd
,
psz_name
,
Control
(
p_
obj
,
i_fd
,
psz_name
,
queryctrl
.
id
,
i_val
);
queryctrl
.
id
,
i_val
);
}
}
}
}
...
@@ -2485,29 +2731,33 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2485,29 +2731,33 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
}
}
val
.
psz_string
=
(
char
*
)
queryctrl
.
name
;
val
.
psz_string
=
(
char
*
)
queryctrl
.
name
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETTEXT
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETTEXT
,
&
val
,
NULL
);
val
.
i_int
=
queryctrl
.
id
;
val
.
i_int
=
queryctrl
.
id
;
val2
.
psz_string
=
(
char
*
)
psz_name
;
val2
.
psz_string
=
(
char
*
)
psz_name
;
var_Change
(
p_
demux
,
"controls"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
var_Change
(
p_
obj
,
"controls"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
switch
(
var_Type
(
p_
demux
,
psz_name
)
&
VLC_VAR_TYPE
)
switch
(
var_Type
(
p_
obj
,
psz_name
)
&
VLC_VAR_TYPE
)
{
{
case
VLC_VAR_BOOL
:
case
VLC_VAR_BOOL
:
var_SetBool
(
p_
demux
,
psz_name
,
i_val
);
var_SetBool
(
p_
obj
,
psz_name
,
i_val
);
break
;
break
;
case
VLC_VAR_INTEGER
:
case
VLC_VAR_INTEGER
:
var_SetInteger
(
p_
demux
,
psz_name
,
i_val
);
var_SetInteger
(
p_
obj
,
psz_name
,
i_val
);
break
;
break
;
case
VLC_VAR_VOID
:
case
VLC_VAR_VOID
:
break
;
break
;
default:
default:
msg_Warn
(
p_
demux
,
"FIXME: %s %s %d"
,
__FILE__
,
__func__
,
msg_Warn
(
p_
obj
,
"FIXME: %s %s %d"
,
__FILE__
,
__func__
,
__LINE__
);
__LINE__
);
break
;
break
;
}
}
var_AddCallback
(
p_demux
,
psz_name
,
if
(
b_demux
)
ControlCallback
,
(
void
*
)
queryctrl
.
id
);
var_AddCallback
(
p_obj
,
psz_name
,
DemuxControlCallback
,
(
void
*
)
queryctrl
.
id
);
else
var_AddCallback
(
p_obj
,
psz_name
,
AccessControlCallback
,
(
void
*
)
queryctrl
.
id
);
free
(
psz_name
);
free
(
psz_name
);
}
}
...
@@ -2516,7 +2766,7 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
...
@@ -2516,7 +2766,7 @@ static void ControlListPrint( demux_t *p_demux, int i_fd,
* List all user-class v4l2 controls, set them to the user specified
* List all user-class v4l2 controls, set them to the user specified
* value and create the relevant variables to enable runtime changes
* value and create the relevant variables to enable runtime changes
*****************************************************************************/
*****************************************************************************/
static
int
ControlList
(
demux_t
*
p_demux
,
int
i_fd
,
vlc_bool_t
b_reset
)
static
int
ControlList
(
vlc_object_t
*
p_obj
,
int
i_fd
,
vlc_bool_t
b_reset
,
vlc_bool_t
b_demux
)
{
{
struct
v4l2_queryctrl
queryctrl
;
struct
v4l2_queryctrl
queryctrl
;
int
i_cid
;
int
i_cid
;
...
@@ -2526,19 +2776,22 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
...
@@ -2526,19 +2776,22 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
/* A list of available controls (aka the variable name) will be
/* A list of available controls (aka the variable name) will be
* stored as choices in the "controls" variable. We'll thus be able
* stored as choices in the "controls" variable. We'll thus be able
* to use those to create an appropriate interface */
* to use those to create an appropriate interface */
var_Create
(
p_
demux
,
"controls"
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
);
var_Create
(
p_
obj
,
"controls"
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
);
var_Create
(
p_
demux
,
"controls-update"
,
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
var_Create
(
p_
obj
,
"controls-update"
,
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
/* Add a control to reset all controls to their default values */
/* Add a control to reset all controls to their default values */
vlc_value_t
val
,
val2
;
vlc_value_t
val
,
val2
;
var_Create
(
p_
demux
,
"controls-reset"
,
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
var_Create
(
p_
obj
,
"controls-reset"
,
VLC_VAR_VOID
|
VLC_VAR_ISCOMMAND
);
val
.
psz_string
=
_
(
"Reset controls to default"
);
val
.
psz_string
=
_
(
"Reset controls to default"
);
var_Change
(
p_
demux
,
"controls-reset"
,
VLC_VAR_SETTEXT
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
"controls-reset"
,
VLC_VAR_SETTEXT
,
&
val
,
NULL
);
val
.
i_int
=
-
1
;
val
.
i_int
=
-
1
;
val2
.
psz_string
=
(
char
*
)
"controls-reset"
;
val2
.
psz_string
=
(
char
*
)
"controls-reset"
;
var_Change
(
p_demux
,
"controls"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
var_Change
(
p_obj
,
"controls"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
val2
);
var_AddCallback
(
p_demux
,
"controls-reset"
,
ControlResetCallback
,
NULL
);
if
(
b_demux
)
var_AddCallback
(
p_obj
,
"controls-reset"
,
DemuxControlResetCallback
,
NULL
);
else
var_AddCallback
(
p_obj
,
"controls-reset"
,
AccessControlResetCallback
,
NULL
);
/* List public controls */
/* List public controls */
for
(
i_cid
=
V4L2_CID_BASE
;
for
(
i_cid
=
V4L2_CID_BASE
;
...
@@ -2550,9 +2803,9 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
...
@@ -2550,9 +2803,9 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
{
{
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
continue
;
continue
;
msg_Dbg
(
p_
demux
,
"Available control: %s (%x)"
,
msg_Dbg
(
p_
obj
,
"Available control: %s (%x)"
,
queryctrl
.
name
,
queryctrl
.
id
);
queryctrl
.
name
,
queryctrl
.
id
);
ControlListPrint
(
p_
demux
,
i_fd
,
queryctrl
,
b_reset
);
ControlListPrint
(
p_
obj
,
i_fd
,
queryctrl
,
b_reset
,
b_demux
);
}
}
}
}
...
@@ -2566,9 +2819,9 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
...
@@ -2566,9 +2819,9 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
{
{
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
if
(
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
continue
;
continue
;
msg_Dbg
(
p_
demux
,
"Available private control: %s (%x)"
,
msg_Dbg
(
p_
obj
,
"Available private control: %s (%x)"
,
queryctrl
.
name
,
queryctrl
.
id
);
queryctrl
.
name
,
queryctrl
.
id
);
ControlListPrint
(
p_
demux
,
i_fd
,
queryctrl
,
b_reset
);
ControlListPrint
(
p_
obj
,
i_fd
,
queryctrl
,
b_reset
,
b_demux
);
}
}
else
else
break
;
break
;
...
@@ -2579,7 +2832,7 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
...
@@ -2579,7 +2832,7 @@ static int ControlList( demux_t *p_demux, int i_fd, vlc_bool_t b_reset )
/*****************************************************************************
/*****************************************************************************
* Reset all user-class v4l2 controls to their default value
* Reset all user-class v4l2 controls to their default value
*****************************************************************************/
*****************************************************************************/
static
int
ControlReset
(
demux_t
*
p_demux
,
int
i_fd
)
static
int
ControlReset
(
vlc_object_t
*
p_obj
,
int
i_fd
)
{
{
struct
v4l2_queryctrl
queryctrl
;
struct
v4l2_queryctrl
queryctrl
;
int
i_cid
;
int
i_cid
;
...
@@ -2605,7 +2858,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
...
@@ -2605,7 +2858,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
int
i
;
int
i
;
for
(
i
=
0
;
controls
[
i
].
psz_name
!=
NULL
;
i
++
)
for
(
i
=
0
;
controls
[
i
].
psz_name
!=
NULL
;
i
++
)
if
(
controls
[
i
].
i_cid
==
queryctrl
.
id
)
break
;
if
(
controls
[
i
].
i_cid
==
queryctrl
.
id
)
break
;
Control
(
p_
demux
,
i_fd
,
Control
(
p_
obj
,
i_fd
,
controls
[
i
].
psz_name
?
controls
[
i
].
psz_name
controls
[
i
].
psz_name
?
controls
[
i
].
psz_name
:
(
const
char
*
)
queryctrl
.
name
,
:
(
const
char
*
)
queryctrl
.
name
,
queryctrl
.
id
,
queryctrl
.
default_value
);
queryctrl
.
id
,
queryctrl
.
default_value
);
...
@@ -2629,7 +2882,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
...
@@ -2629,7 +2882,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
&&
queryctrl
.
default_value
!=
control
.
value
)
&&
queryctrl
.
default_value
!=
control
.
value
)
{
{
Control
(
p_
demux
,
i_fd
,
(
const
char
*
)
queryctrl
.
name
,
Control
(
p_
obj
,
i_fd
,
(
const
char
*
)
queryctrl
.
name
,
queryctrl
.
id
,
queryctrl
.
default_value
);
queryctrl
.
id
,
queryctrl
.
default_value
);
}
}
}
}
...
@@ -2642,7 +2895,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
...
@@ -2642,7 +2895,7 @@ static int ControlReset( demux_t *p_demux, int i_fd )
/*****************************************************************************
/*****************************************************************************
* Issue user-class v4l2 controls
* Issue user-class v4l2 controls
*****************************************************************************/
*****************************************************************************/
static
int
Control
(
demux_t
*
p_demux
,
int
i_fd
,
static
int
Control
(
vlc_object_t
*
p_obj
,
int
i_fd
,
const
char
*
psz_name
,
int
i_cid
,
int
i_value
)
const
char
*
psz_name
,
int
i_cid
,
int
i_value
)
{
{
struct
v4l2_queryctrl
queryctrl
;
struct
v4l2_queryctrl
queryctrl
;
...
@@ -2658,7 +2911,7 @@ static int Control( demux_t *p_demux, int i_fd,
...
@@ -2658,7 +2911,7 @@ static int Control( demux_t *p_demux, int i_fd,
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYCTRL
,
&
queryctrl
)
<
0
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYCTRL
,
&
queryctrl
)
<
0
||
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
||
queryctrl
.
flags
&
V4L2_CTRL_FLAG_DISABLED
)
{
{
msg_Dbg
(
p_
demux
,
"%s (%x) control is not supported."
,
psz_name
,
msg_Dbg
(
p_
obj
,
"%s (%x) control is not supported."
,
psz_name
,
i_cid
);
i_cid
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -2671,7 +2924,7 @@ static int Control( demux_t *p_demux, int i_fd,
...
@@ -2671,7 +2924,7 @@ static int Control( demux_t *p_demux, int i_fd,
control
.
value
=
i_value
;
control
.
value
=
i_value
;
if
(
ioctl
(
i_fd
,
VIDIOC_S_CTRL
,
&
control
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_S_CTRL
,
&
control
)
<
0
)
{
{
msg_Err
(
p_
demux
,
"unable to set %s to %d (%m)"
,
psz_name
,
msg_Err
(
p_
obj
,
"unable to set %s to %d (%m)"
,
psz_name
,
i_value
);
i_value
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -2679,18 +2932,18 @@ static int Control( demux_t *p_demux, int i_fd,
...
@@ -2679,18 +2932,18 @@ static int Control( demux_t *p_demux, int i_fd,
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_G_CTRL
,
&
control
)
>=
0
)
{
{
vlc_value_t
val
;
vlc_value_t
val
;
msg_Dbg
(
p_
demux
,
"video %s: %d"
,
psz_name
,
control
.
value
);
msg_Dbg
(
p_
obj
,
"video %s: %d"
,
psz_name
,
control
.
value
);
switch
(
var_Type
(
p_
demux
,
psz_name
)
&
VLC_VAR_TYPE
)
switch
(
var_Type
(
p_
obj
,
psz_name
)
&
VLC_VAR_TYPE
)
{
{
case
VLC_VAR_BOOL
:
case
VLC_VAR_BOOL
:
val
.
b_bool
=
control
.
value
;
val
.
b_bool
=
control
.
value
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_SetVoid
(
p_
demux
,
"controls-update"
);
var_SetVoid
(
p_
obj
,
"controls-update"
);
break
;
break
;
case
VLC_VAR_INTEGER
:
case
VLC_VAR_INTEGER
:
val
.
i_int
=
control
.
value
;
val
.
i_int
=
control
.
value
;
var_Change
(
p_
demux
,
psz_name
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_Change
(
p_
obj
,
psz_name
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_SetVoid
(
p_
demux
,
"controls-update"
);
var_SetVoid
(
p_
obj
,
"controls-update"
);
break
;
break
;
}
}
}
}
...
@@ -2700,7 +2953,7 @@ static int Control( demux_t *p_demux, int i_fd,
...
@@ -2700,7 +2953,7 @@ static int Control( demux_t *p_demux, int i_fd,
/*****************************************************************************
/*****************************************************************************
* On the fly change settings callback
* On the fly change settings callback
*****************************************************************************/
*****************************************************************************/
static
int
ControlCallback
(
vlc_object_t
*
p_this
,
static
int
Demux
ControlCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
void
*
p_data
)
{
{
...
@@ -2713,12 +2966,12 @@ static int ControlCallback( vlc_object_t *p_this,
...
@@ -2713,12 +2966,12 @@ static int ControlCallback( vlc_object_t *p_this,
if
(
i_fd
<
0
)
if
(
i_fd
<
0
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
Control
(
p_
demux
,
i_fd
,
psz_var
,
i_cid
,
newval
.
i_int
);
Control
(
p_
this
,
i_fd
,
psz_var
,
i_cid
,
newval
.
i_int
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
static
int
ControlResetCallback
(
vlc_object_t
*
p_this
,
static
int
Demux
ControlResetCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
void
*
p_data
)
{
{
...
@@ -2730,7 +2983,42 @@ static int ControlResetCallback( vlc_object_t *p_this,
...
@@ -2730,7 +2983,42 @@ static int ControlResetCallback( vlc_object_t *p_this,
if
(
i_fd
<
0
)
if
(
i_fd
<
0
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
ControlReset
(
p_demux
,
i_fd
);
ControlReset
(
p_this
,
i_fd
);
return
VLC_EGENERIC
;
}
static
int
AccessControlCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_access
->
p_sys
;
int
i_cid
=
(
int
)
p_data
;
int
i_fd
=
p_sys
->
i_fd_video
;
if
(
i_fd
<
0
)
return
VLC_EGENERIC
;
Control
(
p_this
,
i_fd
,
psz_var
,
i_cid
,
newval
.
i_int
);
return
VLC_EGENERIC
;
}
static
int
AccessControlResetCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_access
->
p_sys
;
int
i_fd
=
p_sys
->
i_fd_video
;
if
(
i_fd
<
0
)
return
VLC_EGENERIC
;
ControlReset
(
p_this
,
i_fd
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment