Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
997feb29
Commit
997feb29
authored
Oct 08, 2007
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v4l2: replaces bad malloc( sizeof(x) * i )/memset(&, 0, sizeof(x)) by calloc(1, sizeof(x) * i)
removes extra spaces, removes tabs
parent
a2157f6e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
189 additions
and
194 deletions
+189
-194
modules/access/v4l2.c
modules/access/v4l2.c
+189
-194
No files found.
modules/access/v4l2.c
View file @
997feb29
...
...
@@ -22,14 +22,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*
/*
* Sections based on the reference V4L2 capture example at
* http://v4l2spec.bytesex.org/spec/capture-example.html
*/
/*
* TODO: No mjpeg support yet.
* TODO: mmap untested.
* TODO: No mjpeg support yet.
* TODO: mmap untested.
* TODO: Tuner partial implementation.
* TODO: Alsa input support?
*/
...
...
@@ -90,12 +90,12 @@ static void Close( vlc_object_t * );
"Capture the audio stream in stereo." )
#define SAMPLERATE_TEXT N_( "Samplerate" )
#define SAMPLERATE_LONGTEXT N_( \
"Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
"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 " \
"value should be set in milliseconds." )
typedef
enum
{
IO_METHOD_READ
,
IO_METHOD_MMAP
,
...
...
@@ -106,7 +106,7 @@ static int i_standards_list[] =
{
V4L2_STD_UNKNOWN
,
V4L2_STD_SECAM
,
V4L2_STD_PAL
,
V4L2_STD_NTSC
};
static
const
char
*
psz_standards_list_text
[]
=
{
N_
(
"Default"
),
N_
(
"SECAM"
),
N_
(
"PAL"
),
N_
(
"NTSC"
)
};
static
int
i_iomethod_list
[]
=
{
IO_METHOD_READ
,
IO_METHOD_MMAP
,
IO_METHOD_USERPTR
};
static
const
char
*
psz_iomethod_list_text
[]
=
...
...
@@ -189,7 +189,7 @@ static struct
{
0
,
0
}
};
struct
buffer_t
struct
buffer_t
{
void
*
start
;
size_t
length
;
...
...
@@ -198,16 +198,16 @@ struct buffer_t
struct
demux_sys_t
{
char
*
psz_device
;
/* Main device from MRL, can be video or audio */
char
*
psz_vdev
;
int
i_fd_video
;
char
*
psz_adev
;
int
i_fd_audio
;
/* Video */
io_method
io
;
int
i_pts
;
struct
v4l2_capability
dev_cap
;
...
...
@@ -215,7 +215,7 @@ struct demux_sys_t
int
i_input
;
struct
v4l2_input
*
p_inputs
;
int
i_selected_input
;
int
i_standard
;
struct
v4l2_standard
*
p_standards
;
v4l2_std_id
i_selected_standard_id
;
...
...
@@ -229,21 +229,21 @@ struct demux_sys_t
int
i_codec
;
struct
v4l2_fmtdesc
*
p_codecs
;
struct
buffer_t
*
p_buffers
;
unsigned
int
i_nbuffers
;
int
i_width
;
int
i_height
;
float
f_fps
;
/* <= 0.0 mean to grab at full rate */
mtime_t
i_video_pts
;
/* only used when f_fps > 0 */
int
i_fourcc
;
picture_t
pic
;
int
i_video_frame_size
;
es_out_id_t
*
p_es_video
;
/* Audio */
int
i_sample_rate
;
vlc_bool_t
b_stereo
;
...
...
@@ -265,7 +265,7 @@ static int Open( vlc_object_t *p_this )
demux_sys_t
*
p_sys
;
vlc_value_t
val
;
char
*
psz
;
/* Only when selected */
if
(
*
p_demux
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
...
...
@@ -276,32 +276,31 @@ static int Open( vlc_object_t *p_this )
p_demux
->
info
.
i_title
=
0
;
p_demux
->
info
.
i_seekpoint
=
0
;
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_demux
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
memset
(
p_sys
,
0
,
sizeof
(
demux_sys_t
)
);
p_sys
->
i_video_pts
=
-
1
;
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"
);
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
;
psz
=
var_CreateGetString
(
p_demux
,
"v4l2-chroma"
);
p_sys
->
i_fourcc
=
GetChromaFromFourcc
(
psz
);
free
(
psz
);
free
(
psz
);
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
;
...
...
@@ -311,12 +310,12 @@ static int Open( vlc_object_t *p_this )
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
(
p_demux
);
/* Find main device (video or audio) */
if
(
p_sys
->
psz_device
&&
*
p_sys
->
psz_device
)
{
...
...
@@ -327,7 +326,7 @@ static int Open( vlc_object_t *p_this )
if
(
ProbeVideoDev
(
p_demux
,
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
);
p_sys
->
psz_vdev
=
p_sys
->
psz_device
;
p_sys
->
psz_device
=
NULL
;
...
...
@@ -335,12 +334,12 @@ static int Open( vlc_object_t *p_this )
if
(
p_sys
->
i_fd_video
<
0
)
{
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
else
{
/* Try to open as audio device */
/* Try to open as audio device */
msg_Dbg
(
p_demux
,
"trying device '%s' as audio"
,
p_sys
->
psz_device
);
if
(
ProbeAudioDev
(
p_demux
,
p_sys
->
psz_device
)
)
{
...
...
@@ -353,7 +352,7 @@ static int Open( vlc_object_t *p_this )
if
(
p_sys
->
i_fd_audio
<
0
)
{
Close
(
p_this
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
}
...
...
@@ -429,7 +428,7 @@ static void ParseMRL( demux_t *p_demux )
for
(
;;
)
{
*
psz_parser
++
=
'\0'
;
if
(
!
strncmp
(
psz_parser
,
"adev="
,
strlen
(
"adev="
)
)
)
{
int
i_len
;
...
...
@@ -446,7 +445,7 @@ static void ParseMRL( demux_t *p_demux )
p_sys
->
psz_adev
=
strndup
(
psz_parser
,
i_len
);
psz_parser
+=
i_len
;
psz_parser
+=
i_len
;
}
else
if
(
!
strncmp
(
psz_parser
,
"standard="
,
strlen
(
"standard="
)
)
)
{
...
...
@@ -492,15 +491,15 @@ static void ParseMRL( demux_t *p_demux )
char
*
chroma
=
strndup
(
psz_parser
,
i_len
);
p_sys
->
i_fourcc
=
GetChromaFromFourcc
(
chroma
);
free
(
chroma
);
free
(
chroma
);
psz_parser
+=
i_len
;
psz_parser
+=
i_len
;
}
else
if
(
!
strncmp
(
psz_parser
,
"input="
,
strlen
(
"input="
)
)
)
{
p_sys
->
i_selected_input
=
strtol
(
psz_parser
+
strlen
(
"input="
),
&
psz_parser
,
0
);
}
}
else
if
(
!
strncmp
(
psz_parser
,
"fps="
,
strlen
(
"fps="
)
)
)
{
p_sys
->
f_fps
=
strtof
(
psz_parser
+
strlen
(
"fps="
),
...
...
@@ -582,23 +581,23 @@ static void ParseMRL( demux_t *p_demux )
static
void
Close
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
v4l2_buffer
buf
;
enum
v4l2_buf_type
buf_type
;
unsigned
int
i
;
/* Stop video capture */
if
(
p_sys
->
i_fd_video
>=
0
)
if
(
p_sys
->
i_fd_video
>=
0
)
{
switch
(
p_sys
->
io
)
{
case
IO_METHOD_READ
:
/* Nothing to do */
break
;
case
IO_METHOD_MMAP
:
case
IO_METHOD_USERPTR
:
/* Some drivers 'hang' internally if this is not done before streamoff */
case
IO_METHOD_USERPTR
:
/* Some drivers 'hang' internally if this is not done before streamoff */
for
(
unsigned
int
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
i
++
)
{
memset
(
&
buf
,
0
,
sizeof
(
buf
)
);
...
...
@@ -606,17 +605,17 @@ static void Close( vlc_object_t *p_this )
buf
.
memory
=
V4L2_MEMORY_USERPTR
;
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_DQBUF
,
&
buf
);
/* ignore result */
}
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
)
{
msg_Err
(
p_demux
,
"VIDIOC_STREAMOFF failed"
);
}
break
;
}
break
;
}
}
/* Close */
/* Close */
if
(
p_sys
->
i_fd_video
>=
0
)
close
(
p_sys
->
i_fd_video
);
if
(
p_sys
->
i_fd_audio
>=
0
)
close
(
p_sys
->
i_fd_audio
);
...
...
@@ -627,23 +626,23 @@ static void Close( vlc_object_t *p_this )
case
IO_METHOD_READ
:
free
(
p_sys
->
p_buffers
[
0
].
start
);
break
;
case
IO_METHOD_MMAP
:
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
{
if
(
munmap
(
p_sys
->
p_buffers
[
i
].
start
,
p_sys
->
p_buffers
[
i
].
length
)
)
{
msg_Err
(
p_demux
,
"munmap failed"
);
}
}
}
break
;
case
IO_METHOD_USERPTR
:
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
case
IO_METHOD_USERPTR
:
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
{
free
(
p_sys
->
p_buffers
[
i
].
start
);
}
break
;
}
break
;
}
free
(
p_sys
->
p_buffers
);
}
...
...
@@ -703,9 +702,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
es_out_id_t
*
p_es
=
p_sys
->
p_es_audio
;
es_out_id_t
*
p_es
=
p_sys
->
p_es_audio
;
block_t
*
p_block
=
NULL
;
/* Try grabbing audio frames first */
if
(
p_sys
->
i_fd_audio
<
0
||
!
(
p_block
=
GrabAudio
(
p_demux
)
)
)
{
...
...
@@ -713,7 +712,7 @@ static int Demux( demux_t *p_demux )
p_es
=
p_sys
->
p_es_video
;
if
(
p_sys
->
i_fd_video
>
0
)
p_block
=
GrabVideo
(
p_demux
);
}
if
(
!
p_block
)
{
/* Sleep so we do not consume all the cpu, 10ms seems
...
...
@@ -745,14 +744,14 @@ static block_t* GrabVideo( demux_t *p_demux )
/* Did we wait long enough ? (frame rate reduction) */
if
(
p_sys
->
i_video_pts
+
i_dur
>
mdate
()
)
return
0
;
}
/* Grab Video Frame */
switch
(
p_sys
->
io
)
{
case
IO_METHOD_READ
:
if
(
read
(
p_sys
->
i_fd_video
,
p_sys
->
p_buffers
[
0
].
start
,
p_sys
->
p_buffers
[
0
].
length
)
)
{
switch
(
errno
)
switch
(
errno
)
{
case
EAGAIN
:
return
0
;
...
...
@@ -762,23 +761,23 @@ static block_t* GrabVideo( demux_t *p_demux )
default:
msg_Err
(
p_demux
,
"Failed to read frame"
);
return
0
;
}
}
}
p_block
=
ProcessVideoFrame
(
p_demux
,
(
uint8_t
*
)
p_sys
->
p_buffers
[
0
].
start
);
if
(
!
p_block
)
return
0
;
break
;
case
IO_METHOD_MMAP
:
memset
(
&
buf
,
0
,
sizeof
(
buf
)
);
buf
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf
.
memory
=
V4L2_MEMORY_MMAP
;
/* Wait for next frame */
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_DQBUF
,
&
buf
)
<
0
)
{
switch
(
errno
)
switch
(
errno
)
{
case
EAGAIN
:
return
0
;
...
...
@@ -788,35 +787,35 @@ static block_t* GrabVideo( demux_t *p_demux )
default:
msg_Err
(
p_demux
,
"Failed to wait (VIDIOC_DQBUF)"
);
return
0
;
}
}
}
if
(
buf
.
index
>=
p_sys
->
i_nbuffers
)
{
msg_Err
(
p_demux
,
"Failed capturing new frame as i>=nbuffers"
);
return
0
;
}
p_block
=
ProcessVideoFrame
(
p_demux
,
p_sys
->
p_buffers
[
buf
.
index
].
start
);
if
(
!
p_block
)
return
0
;
/* Unlock */
/* Unlock */
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_QBUF
,
&
buf
)
<
0
)
{
msg_Err
(
p_demux
,
"Failed to unlock (VIDIOC_QBUF)"
);
return
0
;
return
0
;
}
break
;
case
IO_METHOD_USERPTR
:
case
IO_METHOD_USERPTR
:
memset
(
&
buf
,
0
,
sizeof
(
buf
)
);
buf
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf
.
memory
=
V4L2_MEMORY_USERPTR
;
/* Wait for next frame */
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_DQBUF
,
&
buf
)
<
0
)
{
switch
(
errno
)
switch
(
errno
)
{
case
EAGAIN
:
return
0
;
...
...
@@ -826,14 +825,14 @@ static block_t* GrabVideo( demux_t *p_demux )
default:
msg_Err
(
p_demux
,
"Failed to wait (VIDIOC_DQBUF)"
);
return
0
;
}
}
}
/* Find frame? */
unsigned
int
i
;
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
i
++
)
{
if
(
buf
.
m
.
userptr
==
(
unsigned
long
)
p_sys
->
p_buffers
[
i
].
start
&&
if
(
buf
.
m
.
userptr
==
(
unsigned
long
)
p_sys
->
p_buffers
[
i
].
start
&&
buf
.
length
==
p_sys
->
p_buffers
[
i
].
length
)
break
;
}
...
...
@@ -841,24 +840,24 @@ static block_t* GrabVideo( demux_t *p_demux )
msg_Err
(
p_demux
,
"Failed capturing new frame as i>=nbuffers"
);
return
0
;
}
p_block
=
ProcessVideoFrame
(
p_demux
,
(
uint8_t
*
)
buf
.
m
.
userptr
);
if
(
!
p_block
)
return
0
;
/* Unlock */
/* Unlock */
if
(
ioctl
(
p_sys
->
i_fd_video
,
VIDIOC_QBUF
,
&
buf
)
<
0
)
{
msg_Err
(
p_demux
,
"Failed to unlock (VIDIOC_QBUF)"
);
return
0
;
}
break
;
}
/* Timestamp */
p_sys
->
i_video_pts
=
p_block
->
i_pts
=
p_block
->
i_dts
=
mdate
();
return
p_block
;
}
...
...
@@ -872,7 +871,7 @@ static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame )
block_t
*
p_block
;
if
(
!
p_frame
)
return
0
;
/* New block */
if
(
!
(
p_block
=
block_New
(
p_demux
,
p_sys
->
i_video_frame_size
)
)
)
{
...
...
@@ -882,7 +881,7 @@ static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame )
/* Copy frame */
memcpy
(
p_block
->
p_buffer
,
p_frame
,
p_sys
->
i_video_frame_size
);
return
p_block
;
}
...
...
@@ -895,7 +894,7 @@ static block_t* GrabAudio( demux_t *p_demux )
struct
audio_buf_info
buf_info
;
int
i_read
,
i_correct
;
block_t
*
p_block
;
/* Copied from v4l.c */
if
(
p_sys
->
p_block_audio
)
p_block
=
p_sys
->
p_block_audio
;
...
...
@@ -910,7 +909,7 @@ static block_t* GrabAudio( demux_t *p_demux )
p_sys
->
p_block_audio
=
p_block
;
i_read
=
read
(
p_sys
->
i_fd_audio
,
p_block
->
p_buffer
,
p_sys
->
i_audio_max_frame_size
);
p_sys
->
i_audio_max_frame_size
);
if
(
i_read
<=
0
)
return
0
;
...
...
@@ -935,7 +934,7 @@ static block_t* GrabAudio( demux_t *p_demux )
/*****************************************************************************
* Helper function to initalise video IO using the Read method
*****************************************************************************/
static
int
InitRead
(
demux_t
*
p_demux
,
int
i_fd
,
unsigned
int
i_buffer_size
)
static
int
InitRead
(
demux_t
*
p_demux
,
int
i_fd
,
unsigned
int
i_buffer_size
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
...
@@ -945,71 +944,71 @@ static int InitRead( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
msg_Err
(
p_demux
,
"Out of memory"
);
goto
open_failed
;
}
p_sys
->
p_buffers
[
0
].
length
=
i_buffer_size
;
p_sys
->
p_buffers
[
0
].
start
=
malloc
(
i_buffer_size
);
if
(
!
p_sys
->
p_buffers
[
0
].
start
)
{
msg_Err
(
p_demux
,
"Out of memory"
);
goto
open_failed
;
}
}
return
VLC_SUCCESS
;
open_failed:
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Helper function to initalise video IO using the mmap method
*****************************************************************************/
static
int
InitMmap
(
demux_t
*
p_demux
,
int
i_fd
)
static
int
InitMmap
(
demux_t
*
p_demux
,
int
i_fd
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
v4l2_requestbuffers
req
;
memset
(
&
req
,
0
,
sizeof
(
req
)
);
req
.
count
=
4
;
req
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
req
.
memory
=
V4L2_MEMORY_MMAP
;
if
(
ioctl
(
i_fd
,
VIDIOC_REQBUFS
,
&
req
)
<
0
)
{
msg_Err
(
p_demux
,
"device does not support mmap i/o"
);
goto
open_failed
;
}
if
(
req
.
count
<
2
)
{
msg_Err
(
p_demux
,
"Insufficient buffer memory"
);
goto
open_failed
;
}
p_sys
->
p_buffers
=
calloc
(
req
.
count
,
sizeof
(
*
p_sys
->
p_buffers
)
);
if
(
!
p_sys
->
p_buffers
)
{
msg_Err
(
p_demux
,
"Out of memory"
);
goto
open_failed
;
}
for
(
p_sys
->
i_nbuffers
=
0
;
p_sys
->
i_nbuffers
<
req
.
count
;
++
p_sys
->
i_nbuffers
)
{
struct
v4l2_buffer
buf
;
memset
(
&
buf
,
0
,
sizeof
(
buf
)
);
buf
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf
.
memory
=
V4L2_MEMORY_MMAP
;
buf
.
index
=
p_sys
->
i_nbuffers
;
if
(
ioctl
(
i_fd
,
VIDIOC_QUERYBUF
,
&
buf
)
<
0
)
{
msg_Err
(
p_demux
,
"VIDIOC_QUERYBUF"
);
goto
open_failed
;
}
p_sys
->
p_buffers
[
p_sys
->
i_nbuffers
].
length
=
buf
.
length
;
p_sys
->
p_buffers
[
p_sys
->
i_nbuffers
].
start
=
p_sys
->
p_buffers
[
p_sys
->
i_nbuffers
].
start
=
mmap
(
NULL
,
buf
.
length
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
p_sys
->
i_fd_video
,
buf
.
m
.
offset
);
if
(
p_sys
->
p_buffers
[
p_sys
->
i_nbuffers
].
start
==
MAP_FAILED
)
...
...
@@ -1018,40 +1017,40 @@ static int InitMmap( demux_t *p_demux, int i_fd )
goto
open_failed
;
}
}
return
VLC_SUCCESS
;
open_failed:
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Helper function to initalise video IO using the userbuf method
*****************************************************************************/
static
int
InitUserP
(
demux_t
*
p_demux
,
int
i_fd
,
unsigned
int
i_buffer_size
)
static
int
InitUserP
(
demux_t
*
p_demux
,
int
i_fd
,
unsigned
int
i_buffer_size
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
v4l2_requestbuffers
req
;
memset
(
&
req
,
0
,
sizeof
(
req
)
);
req
.
count
=
4
;
req
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
req
.
memory
=
V4L2_MEMORY_USERPTR
;
if
(
ioctl
(
i_fd
,
VIDIOC_REQBUFS
,
&
req
)
<
0
)
{
msg_Err
(
p_demux
,
"device does not support user pointer i/o"
);
goto
open_failed
;
}
p_sys
->
p_buffers
=
calloc
(
4
,
sizeof
(
*
p_sys
->
p_buffers
)
);
if
(
!
p_sys
->
p_buffers
)
{
msg_Err
(
p_demux
,
"Out of memory"
);
goto
open_failed
;
}
for
(
p_sys
->
i_nbuffers
=
0
;
p_sys
->
i_nbuffers
<
4
;
++
p_sys
->
i_nbuffers
)
{
p_sys
->
p_buffers
[
p_sys
->
i_nbuffers
].
length
=
i_buffer_size
;
...
...
@@ -1065,10 +1064,10 @@ static int InitUserP( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )
}
return
VLC_SUCCESS
;
open_failed:
return
VLC_EGENERIC
;
}
/*****************************************************************************
...
...
@@ -1089,12 +1088,12 @@ unsigned int GetChromaFromFourcc( char *psz_fourcc )
}
}
}
return
0
;
}
/*****************************************************************************
* IsChromaSupported: returns true if the specified V4L2 chroma constant is
* IsChromaSupported: returns true if the specified V4L2 chroma constant is
* in the array of supported chromas returned by the driver
*****************************************************************************/
vlc_bool_t
IsChromaSupported
(
demux_t
*
p_demux
,
unsigned
int
i_chroma
)
...
...
@@ -1105,8 +1104,8 @@ vlc_bool_t IsChromaSupported( demux_t *p_demux, unsigned int i_chroma )
{
if
(
p_sys
->
p_codecs
[
i_index
].
pixelformat
==
i_chroma
)
return
VLC_TRUE
;
}
return
VLC_FALSE
;
return
VLC_FALSE
;
}
/*****************************************************************************
...
...
@@ -1121,7 +1120,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
struct
v4l2_format
fmt
;
unsigned
int
i_min
;
enum
v4l2_buf_type
buf_type
;
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
{
msg_Err
(
p_demux
,
"cannot open device (%m)"
);
...
...
@@ -1129,7 +1128,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
/* Select standard */
if
(
p_sys
->
i_selected_standard_id
!=
V4L2_STD_UNKNOWN
)
{
if
(
ioctl
(
i_fd
,
VIDIOC_S_STD
,
&
p_sys
->
i_selected_standard_id
)
<
0
)
...
...
@@ -1141,7 +1140,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
/* Select input */
if
(
p_sys
->
i_selected_input
>
p_sys
->
i_input
)
{
msg_Warn
(
p_demux
,
"invalid input. Using the default one"
);
...
...
@@ -1158,38 +1157,38 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
switch
(
p_sys
->
io
)
{
case
IO_METHOD_READ
:
if
(
!
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_READWRITE
)
)
if
(
!
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_READWRITE
)
)
{
msg_Err
(
p_demux
,
"device does not support read i/o"
);
goto
open_failed
;
}
goto
open_failed
;
}
break
;
case
IO_METHOD_MMAP
:
case
IO_METHOD_USERPTR
:
if
(
!
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_STREAMING
)
)
if
(
!
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_STREAMING
)
)
{
msg_Err
(
p_demux
,
"device does not support streaming i/o"
);
goto
open_failed
;
goto
open_failed
;
}
break
;
default:
msg_Err
(
p_demux
,
"io method not supported"
);
goto
open_failed
;
}
/* Reset Cropping */
memset
(
&
cropcap
,
0
,
sizeof
(
cropcap
)
);
cropcap
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
if
(
ioctl
(
i_fd
,
VIDIOC_CROPCAP
,
&
cropcap
)
>=
0
)
{
{
crop
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
crop
.
c
=
cropcap
.
defrect
;
/* reset to default */
if
(
ioctl
(
i_fd
,
VIDIOC_S_CROP
,
&
crop
)
<
0
)
{
{
switch
(
errno
)
{
{
case
EINVAL
:
/* Cropping not supported. */
break
;
...
...
@@ -1199,34 +1198,34 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
}
}
/* Try and find default resolution if not specified */
if
(
!
p_sys
->
i_width
&&
!
p_sys
->
i_height
)
{
if
(
!
p_sys
->
i_width
&&
!
p_sys
->
i_height
)
{
memset
(
&
fmt
,
0
,
sizeof
(
fmt
)
);
fmt
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
if
(
ioctl
(
i_fd
,
VIDIOC_G_FMT
,
&
fmt
)
<
0
)
if
(
ioctl
(
i_fd
,
VIDIOC_G_FMT
,
&
fmt
)
<
0
)
{
msg_Err
(
p_demux
,
"Cannot get default width and height."
);
goto
open_failed
;
}
}
p_sys
->
i_width
=
fmt
.
fmt
.
pix
.
width
;
p_sys
->
i_height
=
fmt
.
fmt
.
pix
.
height
;
if
(
fmt
.
fmt
.
pix
.
field
==
V4L2_FIELD_ALTERNATE
)
{
p_sys
->
i_height
=
p_sys
->
i_height
*
2
;
}
}
fmt
.
fmt
.
pix
.
width
=
p_sys
->
i_width
;
fmt
.
fmt
.
pix
.
height
=
p_sys
->
i_height
;
fmt
.
fmt
.
pix
.
width
=
p_sys
->
i_width
;
fmt
.
fmt
.
pix
.
height
=
p_sys
->
i_height
;
fmt
.
fmt
.
pix
.
field
=
V4L2_FIELD_INTERLACED
;
/* Test and set Chroma */
fmt
.
fmt
.
pix
.
pixelformat
=
0
;
if
(
p_sys
->
i_fourcc
)
if
(
p_sys
->
i_fourcc
)
{
/* User specified chroma */
for
(
int
i
=
0
;
v4l2chroma_to_fourcc
[
i
].
i_v4l2
!=
0
;
i
++
)
...
...
@@ -1238,31 +1237,31 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
}
}
/* Try and set user chroma */
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
(
fmt
.
fmt
.
pix
.
pixelformat
&&
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
)
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
(
fmt
.
fmt
.
pix
.
pixelformat
&&
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
)
{
msg_Warn
(
p_demux
,
"Driver is unable to use specified chroma. Using defaults."
);
fmt
.
fmt
.
pix
.
pixelformat
=
0
;
}
}
/* If no user specified chroma, find best */
if
(
!
fmt
.
fmt
.
pix
.
pixelformat
)
{
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YVU420
;
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
{
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YUV422P
;
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
{
fmt
.
fmt
.
pix
.
pixelformat
=
V4L2_PIX_FMT_YUYV
;
if
(
!
IsChromaSupported
(
p_demux
,
fmt
.
fmt
.
pix
.
pixelformat
)
||
ioctl
(
i_fd
,
VIDIOC_S_FMT
,
&
fmt
)
<
0
)
if
(
!
IsChromaSupported
(
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!"
);
goto
open_failed
;
}
}
}
}
goto
open_failed
;
}
}
}
}
/* Reassign width, height and chroma incase driver override */
p_sys
->
i_width
=
fmt
.
fmt
.
pix
.
width
;
...
...
@@ -1278,15 +1277,15 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
break
;
}
}
/* Buggy driver paranoia */
i_min
=
fmt
.
fmt
.
pix
.
width
*
2
;
if
(
fmt
.
fmt
.
pix
.
bytesperline
<
i_min
)
fmt
.
fmt
.
pix
.
bytesperline
=
i_min
;
i_min
=
fmt
.
fmt
.
pix
.
bytesperline
*
fmt
.
fmt
.
pix
.
height
;
if
(
fmt
.
fmt
.
pix
.
sizeimage
<
i_min
)
fmt
.
fmt
.
pix
.
sizeimage
=
i_min
;
fmt
.
fmt
.
pix
.
sizeimage
=
i_min
;
/* Init vout Picture */
vout_InitPicture
(
VLC_OBJECT
(
p_demux
),
&
p_sys
->
pic
,
p_sys
->
i_fourcc
,
p_sys
->
i_width
,
p_sys
->
i_height
,
p_sys
->
i_width
*
...
...
@@ -1300,31 +1299,31 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
for
(
int
i
=
0
;
i
<
p_sys
->
pic
.
i_planes
;
i
++
)
{
p_sys
->
i_video_frame_size
+=
p_sys
->
pic
.
p
[
i
].
i_visible_lines
*
p_sys
->
pic
.
p
[
i
].
i_visible_pitch
;
}
/* Init IO method */
}
/* Init IO method */
switch
(
p_sys
->
io
)
{
case
IO_METHOD_READ
:
if
(
InitRead
(
p_demux
,
i_fd
,
fmt
.
fmt
.
pix
.
sizeimage
)
!=
VLC_SUCCESS
)
goto
open_failed
;
break
;
case
IO_METHOD_MMAP
:
if
(
InitMmap
(
p_demux
,
i_fd
)
!=
VLC_SUCCESS
)
goto
open_failed
;
break
;
case
IO_METHOD_USERPTR
:
if
(
InitUserP
(
p_demux
,
i_fd
,
fmt
.
fmt
.
pix
.
sizeimage
)
!=
VLC_SUCCESS
)
goto
open_failed
;
break
;
}
/* Add */
/* Add */
es_format_t
es_fmt
;
es_format_Init
(
&
es_fmt
,
VIDEO_ES
,
p_sys
->
i_fourcc
);
es_fmt
.
video
.
i_width
=
p_sys
->
i_width
;
es_fmt
.
video
.
i_height
=
p_sys
->
i_height
;
es_fmt
.
video
.
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
es_fmt
.
video
.
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
/* Setup rgb mask for RGB formats */
if
(
p_sys
->
i_fourcc
==
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
)
)
...
...
@@ -1339,14 +1338,14 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
(
char
*
)
&
es_fmt
.
i_codec
,
es_fmt
.
video
.
i_width
,
es_fmt
.
video
.
i_height
);
p_sys
->
p_es_video
=
es_out_Add
(
p_demux
->
out
,
&
es_fmt
);
/* Start Capture */
/* Start Capture */
switch
(
p_sys
->
io
)
{
case
IO_METHOD_READ
:
/* Nothing to do */
break
;
case
IO_METHOD_MMAP
:
for
(
unsigned
int
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
{
...
...
@@ -1356,7 +1355,7 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
buf
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf
.
memory
=
V4L2_MEMORY_MMAP
;
buf
.
index
=
i
;
if
(
ioctl
(
i_fd
,
VIDIOC_QBUF
,
&
buf
)
<
0
)
{
msg_Err
(
p_demux
,
"VIDIOC_QBUF failed"
);
goto
open_failed
;
...
...
@@ -1368,9 +1367,9 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
msg_Err
(
p_demux
,
"VIDIOC_STREAMON failed"
);
goto
open_failed
;
}
break
;
case
IO_METHOD_USERPTR
:
for
(
unsigned
int
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
{
...
...
@@ -1397,13 +1396,13 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device )
break
;
}
/* report fps */
if
(
p_sys
->
f_fps
>=
0
.
1
)
{
msg_Dbg
(
p_demux
,
"User set fps=%f"
,
p_sys
->
f_fps
);
}
return
i_fd
;
open_failed:
...
...
@@ -1454,7 +1453,7 @@ int OpenAudioDev( demux_t *p_demux, char *psz_device )
p_sys
->
i_sample_rate
);
p_sys
->
i_audio_max_frame_size
=
6
*
1024
;
es_format_t
fmt
;
es_format_Init
(
&
fmt
,
AUDIO_ES
,
VLC_FOURCC
(
'a'
,
'r'
,
'a'
,
'w'
)
);
...
...
@@ -1468,14 +1467,14 @@ int OpenAudioDev( demux_t *p_demux, char *psz_device )
fmt
.
audio
.
i_channels
,
fmt
.
audio
.
i_rate
);
p_sys
->
p_es_audio
=
es_out_Add
(
p_demux
->
out
,
&
fmt
);
return
i_fd
;
adev_fail:
if
(
i_fd
>=
0
)
close
(
i_fd
);
return
-
1
;
return
-
1
;
}
/*****************************************************************************
...
...
@@ -1488,7 +1487,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
int
i_fd
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
/* msg_Dbg( p_demux, "main device='%s'", p_sys->psz_device ); */
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
...
...
@@ -1538,9 +1537,8 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
p_sys
->
i_input
++
;
}
p_sys
->
p_inputs
=
malloc
(
p_sys
->
i_input
*
sizeof
(
struct
v4l2_input
)
);
p_sys
->
p_inputs
=
calloc
(
1
,
p_sys
->
i_input
*
sizeof
(
struct
v4l2_input
)
);
if
(
!
p_sys
->
p_inputs
)
goto
open_failed
;
memset
(
p_sys
->
p_inputs
,
0
,
sizeof
(
struct
v4l2_input
)
);
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_input
;
i_index
++
)
{
...
...
@@ -1560,7 +1558,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
"External analog input"
);
}
}
/* Probe video standards */
if
(
p_sys
->
dev_cap
.
capabilities
&
V4L2_CAP_VIDEO_CAPTURE
)
{
...
...
@@ -1572,9 +1570,8 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
t_standards
.
index
=
p_sys
->
i_standard
;
}
p_sys
->
p_standards
=
malloc
(
p_sys
->
i_standard
*
sizeof
(
struct
v4l2_standard
)
);
p_sys
->
p_standards
=
calloc
(
1
,
p_sys
->
i_standard
*
sizeof
(
struct
v4l2_standard
)
);
if
(
!
p_sys
->
p_standards
)
goto
open_failed
;
memset
(
p_sys
->
p_standards
,
0
,
sizeof
(
struct
v4l2_standard
)
);
for
(
i_standard
=
0
;
i_standard
<
p_sys
->
i_standard
;
i_standard
++
)
{
...
...
@@ -1632,9 +1629,8 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
tuner
.
index
=
p_sys
->
i_tuner
;
}
p_sys
->
p_tuners
=
malloc
(
p_sys
->
i_tuner
*
sizeof
(
struct
v4l2_tuner
)
);
p_sys
->
p_tuners
=
calloc
(
1
,
p_sys
->
i_tuner
*
sizeof
(
struct
v4l2_tuner
)
);
if
(
!
p_sys
->
p_tuners
)
goto
open_failed
;
memset
(
p_sys
->
p_tuners
,
0
,
sizeof
(
struct
v4l2_tuner
)
);
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_tuner
;
i_index
++
)
{
...
...
@@ -1681,8 +1677,7 @@ vlc_bool_t ProbeVideoDev( demux_t *p_demux, char *psz_device )
p_sys
->
i_codec
=
i_index
;
p_sys
->
p_codecs
=
malloc
(
p_sys
->
i_codec
*
sizeof
(
struct
v4l2_fmtdesc
)
);
memset
(
p_sys
->
p_codecs
,
0
,
p_sys
->
i_codec
*
sizeof
(
struct
v4l2_fmtdesc
)
);
p_sys
->
p_codecs
=
calloc
(
1
,
p_sys
->
i_codec
*
sizeof
(
struct
v4l2_fmtdesc
)
);
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_codec
;
i_index
++
)
{
...
...
@@ -1725,19 +1720,19 @@ vlc_bool_t ProbeAudioDev( demux_t *p_demux, char *psz_device )
goto
open_failed
;
}
/* this will fail if the device is video */
/* this will fail if the device is video */
if
(
ioctl
(
i_fd
,
SNDCTL_DSP_GETCAPS
,
&
i_caps
)
<
0
)
{
msg_Err
(
p_demux
,
"cannot get audio caps (%m)"
);
goto
open_failed
;
}
if
(
i_fd
)
close
(
i_fd
);
return
VLC_TRUE
;
open_failed:
if
(
i_fd
)
close
(
i_fd
);
return
VLC_FALSE
;
}
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