Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
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-gpu
Commits
41625283
Commit
41625283
authored
Jun 06, 2004
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* v4l: converted to access2, but untested so ...
parent
47912024
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
343 additions
and
312 deletions
+343
-312
modules/access/v4l/v4l.c
modules/access/v4l/v4l.c
+343
-312
No files found.
modules/access/v4l/v4l.c
View file @
41625283
...
...
@@ -103,13 +103,13 @@ vlc_module_begin();
VLC_TRUE
);
add_shortcut
(
"v4l"
);
set_capability
(
"access"
,
10
);
set_capability
(
"access
2
"
,
10
);
set_callbacks
(
AccessOpen
,
AccessClose
);
add_submodule
();
set_description
(
_
(
"Video4Linux demuxer"
)
);
add_shortcut
(
"v4l"
);
set_capability
(
"demux
"
,
20
0
);
set_capability
(
"demux
2"
,
2
0
);
set_callbacks
(
DemuxOpen
,
DemuxClose
);
vlc_module_end
();
...
...
@@ -117,11 +117,17 @@ vlc_module_end();
/*****************************************************************************
* Access: local prototypes
*****************************************************************************/
static
int
Read
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
int
AccessRead
(
access_t
*
,
uint8_t
*
,
int
);
static
int
AccessControl
(
access_t
*
,
int
,
va_list
);
static
void
ParseMRL
(
access_t
*
);
static
int
OpenVideoDev
(
access_t
*
,
char
*
);
static
int
OpenAudioDev
(
access_t
*
,
char
*
);
static
int
GrabAudio
(
access_t
*
,
uint8_t
**
,
int
*
,
mtime_t
*
);
static
int
GrabVideo
(
access_t
*
,
uint8_t
**
,
int
*
,
mtime_t
*
);
static
void
ParseMRL
(
input_thread_t
*
);
static
int
OpenVideoDev
(
input_thread_t
*
,
char
*
);
static
int
OpenAudioDev
(
input_thread_t
*
,
char
*
);
#define MJPEG_BUFFER_SIZE (256*1024)
...
...
@@ -232,7 +238,6 @@ struct access_sys_t
int
i_data_size
;
int
i_data_pos
;
uint8_t
*
p_data
;
// never allocated
};
/*
...
...
@@ -279,12 +284,21 @@ static void SetQWBE( uint8_t *p, uint64_t qw )
*****************************************************************************/
static
int
AccessOpen
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
access_t
*
p_access
=
(
access_t
*
)
p_this
;
access_sys_t
*
p_sys
;
vlc_value_t
val
;
/* create access private data */
p_input
->
p_access_data
=
p_sys
=
malloc
(
sizeof
(
access_sys_t
)
);
/* Set up p_access */
p_access
->
pf_read
=
AccessRead
;
p_access
->
pf_block
=
NULL
;
p_access
->
pf_control
=
AccessControl
;
p_access
->
pf_seek
=
NULL
;
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_access
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
access_sys_t
)
);
memset
(
p_sys
,
0
,
sizeof
(
access_sys_t
)
);
p_sys
->
i_audio
=
-
1
;
...
...
@@ -320,20 +334,20 @@ static int AccessOpen( vlc_object_t *p_this )
p_sys
->
fd_video
=
-
1
;
p_sys
->
fd_audio
=
-
1
;
ParseMRL
(
p_
input
);
ParseMRL
(
p_
access
);
/* Find main device (video or audio) */
if
(
p_sys
->
psz_device
&&
*
p_sys
->
psz_device
)
{
msg_Dbg
(
p_
input
,
"main device=`%s'"
,
p_sys
->
psz_device
);
msg_Dbg
(
p_
access
,
"main device=`%s'"
,
p_sys
->
psz_device
);
/* Try to open as video device */
p_sys
->
fd_video
=
OpenVideoDev
(
p_
input
,
p_sys
->
psz_device
);
p_sys
->
fd_video
=
OpenVideoDev
(
p_
access
,
p_sys
->
psz_device
);
if
(
p_sys
->
fd_video
<
0
)
{
/* Try to open as audio device */
p_sys
->
fd_audio
=
OpenAudioDev
(
p_
input
,
p_sys
->
psz_device
);
p_sys
->
fd_audio
=
OpenAudioDev
(
p_
access
,
p_sys
->
psz_device
);
if
(
p_sys
->
fd_audio
>=
0
)
{
if
(
p_sys
->
psz_adev
)
free
(
p_sys
->
psz_adev
);
...
...
@@ -352,8 +366,7 @@ static int AccessOpen( vlc_object_t *p_this )
/* If no device opened, only continue if the access was forced */
if
(
p_sys
->
fd_video
<
0
&&
p_sys
->
fd_audio
<
0
)
{
if
(
!
p_input
->
psz_access
||
strcmp
(
p_input
->
psz_access
,
"v4l"
)
)
if
(
strcmp
(
p_access
->
psz_access
,
"v4l"
)
)
{
AccessClose
(
p_this
);
return
VLC_EGENERIC
;
...
...
@@ -365,17 +378,13 @@ static int AccessOpen( vlc_object_t *p_this )
{
if
(
!
p_sys
->
psz_vdev
||
!*
p_sys
->
psz_vdev
)
{
var_Create
(
p_input
,
"v4l-vdev"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"v4l-vdev"
,
&
val
);
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
p_sys
->
psz_vdev
=
va
l
.
psz_string
;
p_sys
->
psz_vdev
=
va
r_CreateGetString
(
p_access
,
"v4l-vdev"
);
;
}
if
(
p_sys
->
psz_vdev
&&
*
p_sys
->
psz_vdev
)
{
p_sys
->
fd_video
=
OpenVideoDev
(
p_
input
,
p_sys
->
psz_vdev
);
p_sys
->
fd_video
=
OpenVideoDev
(
p_
access
,
p_sys
->
psz_vdev
);
}
}
...
...
@@ -384,17 +393,13 @@ static int AccessOpen( vlc_object_t *p_this )
{
if
(
!
p_sys
->
psz_adev
||
!*
p_sys
->
psz_adev
)
{
var_Create
(
p_input
,
"v4l-adev"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"v4l-adev"
,
&
val
);
if
(
p_sys
->
psz_adev
)
free
(
p_sys
->
psz_adev
);
p_sys
->
psz_adev
=
va
l
.
psz_string
;
p_sys
->
psz_adev
=
va
r_CreateGetString
(
p_access
,
"v4l-adev"
);
;
}
if
(
p_sys
->
psz_adev
&&
*
p_sys
->
psz_adev
)
{
p_sys
->
fd_audio
=
OpenAudioDev
(
p_
input
,
p_sys
->
psz_adev
);
p_sys
->
fd_audio
=
OpenAudioDev
(
p_
access
,
p_sys
->
psz_adev
);
}
}
...
...
@@ -404,25 +409,7 @@ static int AccessOpen( vlc_object_t *p_this )
return
VLC_EGENERIC
;
}
p_input
->
pf_read
=
Read
;
p_input
->
pf_seek
=
NULL
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
pf_set_program
=
NULL
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
b_pace_control
=
0
;
p_input
->
stream
.
b_seekable
=
0
;
p_input
->
stream
.
p_selected_area
->
i_size
=
0
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
p_input
->
stream
.
i_method
=
INPUT_METHOD_FILE
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
/* Update default_pts to a suitable value for access */
var_Create
(
p_input
,
"v4l-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"v4l-caching"
,
&
val
);
p_input
->
i_pts_delay
=
val
.
i_int
*
1000
;
msg_Info
(
p_input
,
"v4l grabbing started"
);
msg_Dbg
(
p_access
,
"v4l grabbing started"
);
/* create header */
p_sys
->
i_streams
=
0
;
...
...
@@ -468,17 +455,206 @@ static int AccessOpen( vlc_object_t *p_this )
}
p_sys
->
i_header_pos
=
0
;
/* Update default_pts to a suitable value for access */
var_Create
(
p_access
,
"v4l-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
/* Force v4l demuxer */
p_access
->
psz_demux
=
strdup
(
"v4l"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* AccessClose: close device, free resources
*****************************************************************************/
static
void
AccessClose
(
vlc_object_t
*
p_this
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
if
(
p_sys
->
psz_device
)
free
(
p_sys
->
psz_device
);
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
if
(
p_sys
->
psz_adev
)
free
(
p_sys
->
psz_adev
);
if
(
p_sys
->
fd_video
>=
0
)
close
(
p_sys
->
fd_video
);
if
(
p_sys
->
fd_audio
>=
0
)
close
(
p_sys
->
fd_audio
);
if
(
p_sys
->
p_header
)
free
(
p_sys
->
p_header
);
if
(
p_sys
->
p_audio_frame
)
free
(
p_sys
->
p_audio_frame
);
if
(
p_sys
->
b_mjpeg
)
{
int
i_noframe
=
-
1
;
ioctl
(
p_sys
->
fd_video
,
MJPIOC_QBUF_CAPT
,
&
i_noframe
);
}
if
(
p_sys
->
p_video_mmap
&&
p_sys
->
p_video_mmap
!=
MAP_FAILED
)
{
if
(
p_sys
->
b_mjpeg
)
munmap
(
p_sys
->
p_video_mmap
,
p_sys
->
mjpeg_buffers
.
size
*
p_sys
->
mjpeg_buffers
.
count
);
else
munmap
(
p_sys
->
p_video_mmap
,
p_sys
->
vid_mbuf
.
size
);
}
free
(
p_sys
);
}
/*****************************************************************************
* AccessControl:
*****************************************************************************/
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
;
switch
(
i_query
)
{
/* */
case
ACCESS_CAN_SEEK
:
case
ACCESS_CAN_FASTSEEK
:
case
ACCESS_CAN_PAUSE
:
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
)
var_GetInteger
(
p_access
,
"v4l-caching"
)
*
I64C
(
1000
);
break
;
/* */
case
ACCESS_SET_PAUSE_STATE
:
case
ACCESS_GET_TITLE_INFO
:
case
ACCESS_SET_TITLE
:
case
ACCESS_SET_SEEKPOINT
:
return
VLC_EGENERIC
;
default:
msg_Err
(
p_access
,
"unimplemented query in control"
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* AccessRead:
*****************************************************************************/
static
int
AccessRead
(
access_t
*
p_access
,
uint8_t
*
p_buffer
,
int
i_len
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_data
=
0
;
int
i_stream
;
mtime_t
i_pts
;
while
(
i_len
>
0
)
{
/* First copy header if any */
if
(
p_sys
->
i_header_pos
<
p_sys
->
i_header_size
)
{
int
i_copy
;
i_copy
=
__MIN
(
p_sys
->
i_header_size
-
p_sys
->
i_header_pos
,
(
int
)
i_len
);
memcpy
(
p_buffer
,
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
],
i_copy
);
p_sys
->
i_header_pos
+=
i_copy
;
p_buffer
+=
i_copy
;
i_len
-=
i_copy
;
i_data
+=
i_copy
;
}
/* then data */
if
(
i_len
>
0
&&
p_sys
->
i_data_pos
<
p_sys
->
i_data_size
)
{
int
i_copy
;
i_copy
=
__MIN
(
p_sys
->
i_data_size
-
p_sys
->
i_data_pos
,
(
int
)
i_len
);
memcpy
(
p_buffer
,
&
p_sys
->
p_data
[
p_sys
->
i_data_pos
],
i_copy
);
p_sys
->
i_data_pos
+=
i_copy
;
p_buffer
+=
i_copy
;
i_len
-=
i_copy
;
i_data
+=
i_copy
;
}
/* The caller got what he wanted */
if
(
i_len
==
0
)
{
return
i_data
;
}
/* Read no more than one frame at a time.
* That kills latency, especially for encoded v4l streams */
if
(
p_sys
->
i_data_size
&&
p_sys
->
i_data_pos
==
p_sys
->
i_data_size
)
{
p_sys
->
i_data_pos
=
0
;
p_sys
->
i_data_size
=
0
;
return
i_data
;
}
/* Re-fill data by grabbing audio/video */
p_sys
->
i_data_pos
=
p_sys
->
i_data_size
=
0
;
/* Try grabbing audio frames first */
i_stream
=
p_sys
->
i_streams
-
1
;
if
(
p_sys
->
fd_audio
<
0
||
GrabAudio
(
p_access
,
&
p_sys
->
p_data
,
&
p_sys
->
i_data_size
,
&
i_pts
)
!=
VLC_SUCCESS
)
{
int
i_ret
=
VLC_ETIMEOUT
;
/* Try grabbing video frame */
i_stream
=
0
;
if
(
p_sys
->
fd_video
>
0
)
{
i_ret
=
GrabVideo
(
p_access
,
&
p_sys
->
p_data
,
&
p_sys
->
i_data_size
,
&
i_pts
);
}
/* No video or timeout */
if
(
i_ret
==
VLC_ETIMEOUT
)
{
/* Sleep so we do not consume all the cpu, 10ms seems
* like a good value (100fps) */
msleep
(
10000
);
continue
;
}
else
if
(
i_ret
!=
VLC_SUCCESS
)
{
msg_Err
(
p_access
,
"Error during capture!"
);
return
-
1
;
}
}
/* create pseudo header */
p_sys
->
i_header_size
=
16
;
p_sys
->
i_header_pos
=
0
;
SetDWBE
(
&
p_sys
->
p_header
[
0
],
i_stream
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
p_sys
->
i_data_size
);
SetQWBE
(
&
p_sys
->
p_header
[
8
],
i_pts
);
}
return
i_data
;
}
/*****************************************************************************
* ParseMRL: parse the options contained in the MRL
*****************************************************************************/
static
void
ParseMRL
(
input_thread_t
*
p_input
)
static
void
ParseMRL
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_
input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_
access
->
p_sys
;
char
*
psz_dup
=
strdup
(
p_
input
->
psz_name
);
char
*
psz_dup
=
strdup
(
p_
access
->
psz_path
);
char
*
psz_parser
=
psz_dup
;
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
...
...
@@ -533,7 +709,7 @@ static void ParseMRL( input_thread_t *p_input )
&
psz_parser
,
0
);
if
(
p_sys
->
i_frequency
<
30000
)
{
msg_Warn
(
p_
input
,
"v4l syntax has changed : "
msg_Warn
(
p_
access
,
"v4l syntax has changed : "
"'frequency' is now channel frequency in kHz"
);
}
}
...
...
@@ -584,7 +760,7 @@ static void ParseMRL( input_thread_t *p_input )
p_sys
->
i_height
=
strtol
(
psz_parser
+
1
,
&
psz_parser
,
0
);
}
msg_Dbg
(
p_
input
,
"WxH %dx%d"
,
p_sys
->
i_width
,
msg_Dbg
(
p_
access
,
"WxH %dx%d"
,
p_sys
->
i_width
,
p_sys
->
i_height
);
}
}
...
...
@@ -677,7 +853,7 @@ static void ParseMRL( input_thread_t *p_input )
}
else
{
msg_Warn
(
p_
input
,
"unknown option"
);
msg_Warn
(
p_
access
,
"unknown option"
);
}
while
(
*
psz_parser
&&
*
psz_parser
!=
':'
)
...
...
@@ -702,9 +878,9 @@ static void ParseMRL( input_thread_t *p_input )
/*****************************************************************************
* OpenVideoDev:
*****************************************************************************/
int
OpenVideoDev
(
input_thread_t
*
p_input
,
char
*
psz_device
)
static
int
OpenVideoDev
(
access_t
*
p_access
,
char
*
psz_device
)
{
access_sys_t
*
p_sys
=
p_
input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_
access
->
p_sys
;
int
i_fd
;
struct
video_channel
vid_channel
;
...
...
@@ -713,17 +889,17 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
(
i_fd
=
open
(
psz_device
,
O_RDWR
)
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot open device (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot open device (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
if
(
ioctl
(
i_fd
,
VIDIOCGCAP
,
&
p_sys
->
vid_cap
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot get capabilities (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot get capabilities (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
msg_Dbg
(
p_
input
,
msg_Dbg
(
p_
access
,
"V4L device %s %d channels %d audios %d < w < %d %d < h < %d"
,
p_sys
->
vid_cap
.
name
,
p_sys
->
vid_cap
.
channels
,
...
...
@@ -733,42 +909,42 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
p_sys
->
i_channel
<
0
||
p_sys
->
i_channel
>=
p_sys
->
vid_cap
.
channels
)
{
msg_Dbg
(
p_
input
,
"invalid channel, falling back on channel 0"
);
msg_Dbg
(
p_
access
,
"invalid channel, falling back on channel 0"
);
p_sys
->
i_channel
=
0
;
}
if
(
p_sys
->
i_audio
>=
p_sys
->
vid_cap
.
audios
)
{
msg_Dbg
(
p_
input
,
"invalid audio, falling back with no audio"
);
msg_Dbg
(
p_
access
,
"invalid audio, falling back with no audio"
);
p_sys
->
i_audio
=
-
1
;
}
if
(
p_sys
->
i_width
<
p_sys
->
vid_cap
.
minwidth
||
p_sys
->
i_width
>
p_sys
->
vid_cap
.
maxwidth
)
{
msg_Dbg
(
p_
input
,
"invalid width %i"
,
p_sys
->
i_width
);
msg_Dbg
(
p_
access
,
"invalid width %i"
,
p_sys
->
i_width
);
p_sys
->
i_width
=
0
;
}
if
(
p_sys
->
i_height
<
p_sys
->
vid_cap
.
minheight
||
p_sys
->
i_height
>
p_sys
->
vid_cap
.
maxheight
)
{
msg_Dbg
(
p_
input
,
"invalid height %i"
,
p_sys
->
i_height
);
msg_Dbg
(
p_
access
,
"invalid height %i"
,
p_sys
->
i_height
);
p_sys
->
i_height
=
0
;
}
if
(
!
(
p_sys
->
vid_cap
.
type
&
VID_TYPE_CAPTURE
)
)
{
msg_Err
(
p_
input
,
"cannot grab"
);
msg_Err
(
p_
access
,
"cannot grab"
);
goto
vdev_failed
;
}
vid_channel
.
channel
=
p_sys
->
i_channel
;
if
(
ioctl
(
i_fd
,
VIDIOCGCHAN
,
&
vid_channel
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot get channel infos (%s)"
,
msg_Err
(
p_
access
,
"cannot get channel infos (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
msg_Dbg
(
p_
input
,
msg_Dbg
(
p_
access
,
"setting channel %s(%d) %d tuners flags=0x%x type=0x%x norm=0x%x"
,
vid_channel
.
name
,
vid_channel
.
channel
,
...
...
@@ -779,14 +955,14 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
p_sys
->
i_tuner
>=
vid_channel
.
tuners
)
{
msg_Dbg
(
p_
input
,
"invalid tuner, falling back on tuner 0"
);
msg_Dbg
(
p_
access
,
"invalid tuner, falling back on tuner 0"
);
p_sys
->
i_tuner
=
0
;
}
vid_channel
.
norm
=
p_sys
->
i_norm
;
if
(
ioctl
(
i_fd
,
VIDIOCSCHAN
,
&
vid_channel
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set channel (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot set channel (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
...
...
@@ -801,22 +977,22 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
vid_tuner.tuner = p_sys->i_tuner;
if( ioctl( i_fd, VIDIOCGTUNER, &vid_tuner ) < 0 )
{
msg_Err( p_
input
, "cannot get tuner (%s)", strerror( errno ) );
msg_Err( p_
access
, "cannot get tuner (%s)", strerror( errno ) );
goto vdev_failed;
}
msg_Dbg( p_
input
, "tuner %s low=%d high=%d, flags=0x%x "
msg_Dbg( p_
access
, "tuner %s low=%d high=%d, flags=0x%x "
"mode=0x%x signal=0x%x",
vid_tuner.name, vid_tuner.rangelow, vid_tuner.rangehigh,
vid_tuner.flags, vid_tuner.mode, vid_tuner.signal );
msg_Dbg( p_
input
, "setting tuner %s (%d)",
msg_Dbg( p_
access
, "setting tuner %s (%d)",
vid_tuner.name, vid_tuner.tuner );
/* FIXME FIXME to be checked FIXME FIXME */
//vid_tuner.mode = p_sys->i_norm;
if( ioctl( i_fd, VIDIOCSTUNER, &vid_tuner ) < 0 )
{
msg_Err( p_
input
, "cannot set tuner (%s)", strerror( errno ) );
msg_Err( p_
access
, "cannot set tuner (%s)", strerror( errno ) );
goto vdev_failed;
}
}
...
...
@@ -832,11 +1008,11 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
int
driver_frequency
=
p_sys
->
i_frequency
*
16
/
1000
;
if
(
ioctl
(
i_fd
,
VIDIOCSFREQ
,
&
driver_frequency
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set frequency (%s)"
,
msg_Err
(
p_
access
,
"cannot set frequency (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
msg_Dbg
(
p_
input
,
"frequency %d (%d)"
,
p_sys
->
i_frequency
,
msg_Dbg
(
p_
access
,
"frequency %d (%d)"
,
p_sys
->
i_frequency
,
driver_frequency
);
}
}
...
...
@@ -852,7 +1028,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
vid_audio
.
audio
=
p_sys
->
i_audio
;
if
(
ioctl
(
i_fd
,
VIDIOCGAUDIO
,
&
vid_audio
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot get audio (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot get audio (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
...
...
@@ -861,7 +1037,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOCSAUDIO
,
&
vid_audio
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set audio (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot set audio (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
}
...
...
@@ -877,7 +1053,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
MJPIOC_G_PARAMS
,
&
mjpeg
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot get mjpeg params (%s)"
,
msg_Err
(
p_
access
,
"cannot get mjpeg params (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
...
...
@@ -928,7 +1104,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
MJPIOC_S_PARAMS
,
&
mjpeg
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set mjpeg params (%s)"
,
msg_Err
(
p_
access
,
"cannot set mjpeg params (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
...
...
@@ -945,13 +1121,13 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOCGWIN
,
&
vid_win
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot get win (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot get win (%s)"
,
strerror
(
errno
)
);
goto
vdev_failed
;
}
p_sys
->
i_width
=
vid_win
.
width
;
p_sys
->
i_height
=
vid_win
.
height
;
msg_Dbg
(
p_
input
,
"will use %dx%d"
,
p_sys
->
i_width
,
p_sys
->
i_height
);
msg_Dbg
(
p_
access
,
"will use %dx%d"
,
p_sys
->
i_width
,
p_sys
->
i_height
);
}
p_sys
->
p_video_frame
=
NULL
;
...
...
@@ -981,10 +1157,10 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
}
if
(
ioctl
(
i_fd
,
VIDIOCSPICT
,
&
vid_picture
)
==
0
)
{
msg_Dbg
(
p_
input
,
"v4l device uses brightness: %d"
,
vid_picture
.
brightness
);
msg_Dbg
(
p_
input
,
"v4l device uses colour: %d"
,
vid_picture
.
colour
);
msg_Dbg
(
p_
input
,
"v4l device uses hue: %d"
,
vid_picture
.
hue
);
msg_Dbg
(
p_
input
,
"v4l device uses contrast: %d"
,
vid_picture
.
contrast
);
msg_Dbg
(
p_
access
,
"v4l device uses brightness: %d"
,
vid_picture
.
brightness
);
msg_Dbg
(
p_
access
,
"v4l device uses colour: %d"
,
vid_picture
.
colour
);
msg_Dbg
(
p_
access
,
"v4l device uses hue: %d"
,
vid_picture
.
hue
);
msg_Dbg
(
p_
access
,
"v4l device uses contrast: %d"
,
vid_picture
.
contrast
);
p_sys
->
vid_picture
=
vid_picture
;
}
}
...
...
@@ -993,20 +1169,16 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
VIDIOCGPICT
,
&
p_sys
->
vid_picture
)
==
0
)
{
struct
video_picture
vid_picture
=
p_sys
->
vid_picture
;
vlc_value_t
val
;
char
*
psz
;
int
i
;
vid_picture
.
palette
=
0
;
p_sys
->
i_fourcc
=
0
;
var_Create
(
p_input
,
"v4l-chroma"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"v4l-chroma"
,
&
val
);
if
(
val
.
psz_string
&&
strlen
(
val
.
psz_string
)
>=
4
)
psz
=
var_CreateGetString
(
p_access
,
"v4l-chroma"
);
if
(
strlen
(
psz
)
>=
4
)
{
int
i_chroma
=
VLC_FOURCC
(
val
.
psz_string
[
0
],
val
.
psz_string
[
1
],
val
.
psz_string
[
2
],
val
.
psz_string
[
3
]
);
int
i_chroma
=
VLC_FOURCC
(
psz
[
0
],
psz
[
1
],
psz
[
2
],
psz
[
3
]
);
/* Find out v4l chroma code */
for
(
i
=
0
;
v4lchroma_to_fourcc
[
i
].
i_v4l
!=
0
;
i
++
)
...
...
@@ -1018,7 +1190,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
}
}
}
if
(
val
.
psz_string
)
free
(
val
.
psz_string
);
free
(
psz
);
if
(
vid_picture
.
palette
&&
!
ioctl
(
i_fd
,
VIDIOCSPICT
,
&
vid_picture
)
)
...
...
@@ -1056,7 +1228,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
}
else
{
msg_Err
(
p_
input
,
"ioctl VIDIOCGPICT failed"
);
msg_Err
(
p_
access
,
"ioctl VIDIOCGPICT failed"
);
goto
vdev_failed
;
}
}
...
...
@@ -1070,7 +1242,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
MJPIOC_REQBUFS
,
&
p_sys
->
mjpeg_buffers
)
<
0
)
{
msg_Err
(
p_
input
,
"mmap unsupported"
);
msg_Err
(
p_
access
,
"mmap unsupported"
);
goto
vdev_failed
;
}
...
...
@@ -1079,7 +1251,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
i_fd
,
0
);
if
(
p_sys
->
p_video_mmap
==
MAP_FAILED
)
{
msg_Err
(
p_
input
,
"mmap failed"
);
msg_Err
(
p_
access
,
"mmap failed"
);
goto
vdev_failed
;
}
...
...
@@ -1091,7 +1263,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
{
if
(
ioctl
(
i_fd
,
MJPIOC_QBUF_CAPT
,
&
i
)
<
0
)
{
msg_Err
(
p_
input
,
"unable to queue frame"
);
msg_Err
(
p_
access
,
"unable to queue frame"
);
goto
vdev_failed
;
}
}
...
...
@@ -1099,12 +1271,12 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
else
{
/* Fill in picture_t fields */
vout_InitPicture
(
VLC_OBJECT
(
p_
input
),
&
p_sys
->
pic
,
p_sys
->
i_fourcc
,
vout_InitPicture
(
VLC_OBJECT
(
p_
access
),
&
p_sys
->
pic
,
p_sys
->
i_fourcc
,
p_sys
->
i_width
,
p_sys
->
i_height
,
p_sys
->
i_width
*
VOUT_ASPECT_FACTOR
/
p_sys
->
i_height
);
if
(
!
p_sys
->
pic
.
i_planes
)
{
msg_Err
(
p_
input
,
"unsupported chroma"
);
msg_Err
(
p_
access
,
"unsupported chroma"
);
goto
vdev_failed
;
}
p_sys
->
i_video_frame_size
=
0
;
...
...
@@ -1114,15 +1286,15 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
p_sys
->
pic
.
p
[
i
].
i_visible_pitch
;
}
msg_Dbg
(
p_
input
,
"v4l device uses frame size: %i"
,
msg_Dbg
(
p_
access
,
"v4l device uses frame size: %i"
,
p_sys
->
i_video_frame_size
);
msg_Dbg
(
p_
input
,
"v4l device uses chroma: %4.4s"
,
msg_Dbg
(
p_
access
,
"v4l device uses chroma: %4.4s"
,
(
char
*
)
&
p_sys
->
i_fourcc
);
/* Allocate mmap buffer */
if
(
ioctl
(
i_fd
,
VIDIOCGMBUF
,
&
p_sys
->
vid_mbuf
)
<
0
)
{
msg_Err
(
p_
input
,
"mmap unsupported"
);
msg_Err
(
p_
access
,
"mmap unsupported"
);
goto
vdev_failed
;
}
...
...
@@ -1132,7 +1304,7 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
if
(
p_sys
->
p_video_mmap
==
MAP_FAILED
)
{
/* FIXME -> normal read */
msg_Err
(
p_
input
,
"mmap failed"
);
msg_Err
(
p_
access
,
"mmap failed"
);
goto
vdev_failed
;
}
...
...
@@ -1143,8 +1315,8 @@ int OpenVideoDev( input_thread_t *p_input, char *psz_device )
p_sys
->
vid_mmap
.
format
=
p_sys
->
vid_picture
.
palette
;
if
(
ioctl
(
i_fd
,
VIDIOCMCAPTURE
,
&
p_sys
->
vid_mmap
)
<
0
)
{
msg_Warn
(
p_
input
,
"%4.4s refused"
,
(
char
*
)
&
p_sys
->
i_fourcc
);
msg_Err
(
p_
input
,
"chroma selection failed"
);
msg_Warn
(
p_
access
,
"%4.4s refused"
,
(
char
*
)
&
p_sys
->
i_fourcc
);
msg_Err
(
p_
access
,
"chroma selection failed"
);
goto
vdev_failed
;
}
}
...
...
@@ -1159,14 +1331,14 @@ vdev_failed:
/*****************************************************************************
* OpenAudioDev:
*****************************************************************************/
int
OpenAudioDev
(
input_thread_t
*
p_input
,
char
*
psz_device
)
static
int
OpenAudioDev
(
access_t
*
p_access
,
char
*
psz_device
)
{
access_sys_t
*
p_sys
=
p_
input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_
access
->
p_sys
;
int
i_fd
,
i_format
;
if
(
(
i_fd
=
open
(
psz_device
,
O_RDONLY
|
O_NONBLOCK
))
<
0
)
{
msg_Err
(
p_
input
,
"cannot open audio device (%s)"
,
strerror
(
errno
)
);
msg_Err
(
p_
access
,
"cannot open audio device (%s)"
,
strerror
(
errno
)
);
goto
adev_fail
;
}
...
...
@@ -1174,7 +1346,7 @@ int OpenAudioDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
SNDCTL_DSP_SETFMT
,
&
i_format
)
<
0
||
i_format
!=
AFMT_S16_LE
)
{
msg_Err
(
p_
input
,
"cannot set audio format (16b little endian) "
msg_Err
(
p_
access
,
"cannot set audio format (16b little endian) "
"(%s)"
,
strerror
(
errno
)
);
goto
adev_fail
;
}
...
...
@@ -1182,7 +1354,7 @@ int OpenAudioDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
SNDCTL_DSP_STEREO
,
&
p_sys
->
b_stereo
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set audio channels count (%s)"
,
msg_Err
(
p_
access
,
"cannot set audio channels count (%s)"
,
strerror
(
errno
)
);
goto
adev_fail
;
}
...
...
@@ -1190,12 +1362,12 @@ int OpenAudioDev( input_thread_t *p_input, char *psz_device )
if
(
ioctl
(
i_fd
,
SNDCTL_DSP_SPEED
,
&
p_sys
->
i_sample_rate
)
<
0
)
{
msg_Err
(
p_
input
,
"cannot set audio sample rate (%s)"
,
msg_Err
(
p_
access
,
"cannot set audio sample rate (%s)"
,
strerror
(
errno
)
);
goto
adev_fail
;
}
msg_Dbg
(
p_
input
,
"openened adev=`%s' %s %dHz"
,
msg_Dbg
(
p_
access
,
"openened adev=`%s' %s %dHz"
,
psz_device
,
p_sys
->
b_stereo
?
"stereo"
:
"mono"
,
p_sys
->
i_sample_rate
);
...
...
@@ -1211,50 +1383,13 @@ int OpenAudioDev( input_thread_t *p_input, char *psz_device )
return
-
1
;
}
/*****************************************************************************
* AccessClose: close device, free resources
*****************************************************************************/
static
void
AccessClose
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
if
(
p_sys
->
psz_device
)
free
(
p_sys
->
psz_device
);
if
(
p_sys
->
psz_vdev
)
free
(
p_sys
->
psz_vdev
);
if
(
p_sys
->
psz_adev
)
free
(
p_sys
->
psz_adev
);
if
(
p_sys
->
fd_video
>=
0
)
close
(
p_sys
->
fd_video
);
if
(
p_sys
->
fd_audio
>=
0
)
close
(
p_sys
->
fd_audio
);
if
(
p_sys
->
p_header
)
free
(
p_sys
->
p_header
);
if
(
p_sys
->
p_audio_frame
)
free
(
p_sys
->
p_audio_frame
);
if
(
p_sys
->
b_mjpeg
)
{
int
i_noframe
=
-
1
;
ioctl
(
p_sys
->
fd_video
,
MJPIOC_QBUF_CAPT
,
&
i_noframe
);
}
if
(
p_sys
->
p_video_mmap
&&
p_sys
->
p_video_mmap
!=
MAP_FAILED
)
{
if
(
p_sys
->
b_mjpeg
)
munmap
(
p_sys
->
p_video_mmap
,
p_sys
->
mjpeg_buffers
.
size
*
p_sys
->
mjpeg_buffers
.
count
);
else
munmap
(
p_sys
->
p_video_mmap
,
p_sys
->
vid_mbuf
.
size
);
}
free
(
p_sys
);
}
/*****************************************************************************
* GrabAudio: grab audio
*****************************************************************************/
static
int
GrabAudio
(
input_thread_t
*
p_input
,
uint8_t
**
pp_data
,
int
*
pi_data
,
mtime_t
*
pi_pts
)
static
int
GrabAudio
(
access_t
*
p_access
,
uint8_t
**
pp_data
,
int
*
pi_data
,
mtime_t
*
pi_pts
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
struct
audio_buf_info
buf_info
;
int
i_read
;
int
i_correct
;
...
...
@@ -1287,9 +1422,9 @@ static int GrabAudio( input_thread_t * p_input,
/*****************************************************************************
* GrabVideo:
*****************************************************************************/
static
uint8_t
*
GrabCapture
(
input_thread_t
*
p_input
)
static
uint8_t
*
GrabCapture
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_
input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_
access
->
p_sys
;
int
i_captured_frame
=
p_sys
->
i_frame_pos
;
p_sys
->
vid_mmap
.
frame
=
(
p_sys
->
i_frame_pos
+
1
)
%
p_sys
->
vid_mbuf
.
frames
;
...
...
@@ -1298,23 +1433,23 @@ static uint8_t *GrabCapture( input_thread_t *p_input )
{
if
(
errno
!=
EAGAIN
)
{
msg_Err
(
p_
input
,
"failed capturing new frame"
);
msg_Err
(
p_
access
,
"failed capturing new frame"
);
return
NULL
;
}
if
(
p_
input
->
b_die
)
if
(
p_
access
->
b_die
)
{
return
NULL
;
}
msg_Dbg
(
p_
input
,
"grab failed, trying again"
);
msg_Dbg
(
p_
access
,
"grab failed, trying again"
);
}
while
(
ioctl
(
p_sys
->
fd_video
,
VIDIOCSYNC
,
&
p_sys
->
i_frame_pos
)
<
0
)
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EINTR
)
{
msg_Err
(
p_
input
,
"failed syncing new frame"
);
msg_Err
(
p_
access
,
"failed syncing new frame"
);
return
NULL
;
}
}
...
...
@@ -1324,9 +1459,9 @@ static uint8_t *GrabCapture( input_thread_t *p_input )
return
p_sys
->
p_video_mmap
+
p_sys
->
vid_mbuf
.
offsets
[
i_captured_frame
];
}
static
uint8_t
*
GrabMJPEG
(
input_thread_t
*
p_input
)
static
uint8_t
*
GrabMJPEG
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_
input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_
access
->
p_sys
;
struct
mjpeg_sync
sync
;
uint8_t
*
p_frame
,
*
p_field
,
*
p
;
uint16_t
tag
;
...
...
@@ -1341,7 +1476,7 @@ static uint8_t *GrabMJPEG( input_thread_t *p_input )
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EINTR
)
{
msg_Err
(
p_
input
,
"failed capturing new frame"
);
msg_Err
(
p_
access
,
"failed capturing new frame"
);
return
NULL
;
}
}
...
...
@@ -1352,7 +1487,7 @@ static uint8_t *GrabMJPEG( input_thread_t *p_input )
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EINTR
)
{
msg_Err
(
p_
input
,
"failed syncing new frame"
);
msg_Err
(
p_
access
,
"failed syncing new frame"
);
return
NULL
;
}
}
...
...
@@ -1426,12 +1561,10 @@ static uint8_t *GrabMJPEG( input_thread_t *p_input )
return
p_frame
;
}
static
int
GrabVideo
(
input_thread_t
*
p_input
,
uint8_t
**
pp_data
,
int
*
pi_data
,
mtime_t
*
pi_pts
)
static
int
GrabVideo
(
access_t
*
p_access
,
uint8_t
**
pp_data
,
int
*
pi_data
,
mtime_t
*
pi_pts
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
uint8_t
*
p_frame
;
...
...
@@ -1447,9 +1580,9 @@ static int GrabVideo( input_thread_t * p_input,
}
if
(
p_sys
->
b_mjpeg
)
p_frame
=
GrabMJPEG
(
p_
input
);
p_frame
=
GrabMJPEG
(
p_
access
);
else
p_frame
=
GrabCapture
(
p_
input
);
p_frame
=
GrabCapture
(
p_
access
);
if
(
!
p_frame
)
return
VLC_EGENERIC
;
...
...
@@ -1464,113 +1597,6 @@ static int GrabVideo( input_thread_t * p_input,
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Read: reads from the device into PES packets.
*****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* bytes.
*****************************************************************************/
static
int
Read
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
int
i_data
=
0
;
int
i_stream
;
mtime_t
i_pts
;
while
(
i_len
>
0
)
{
/* First copy header if any */
if
(
p_sys
->
i_header_pos
<
p_sys
->
i_header_size
)
{
int
i_copy
;
i_copy
=
__MIN
(
p_sys
->
i_header_size
-
p_sys
->
i_header_pos
,
(
int
)
i_len
);
memcpy
(
p_buffer
,
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
],
i_copy
);
p_sys
->
i_header_pos
+=
i_copy
;
p_buffer
+=
i_copy
;
i_len
-=
i_copy
;
i_data
+=
i_copy
;
}
/* then data */
if
(
i_len
>
0
&&
p_sys
->
i_data_pos
<
p_sys
->
i_data_size
)
{
int
i_copy
;
i_copy
=
__MIN
(
p_sys
->
i_data_size
-
p_sys
->
i_data_pos
,
(
int
)
i_len
);
memcpy
(
p_buffer
,
&
p_sys
->
p_data
[
p_sys
->
i_data_pos
],
i_copy
);
p_sys
->
i_data_pos
+=
i_copy
;
p_buffer
+=
i_copy
;
i_len
-=
i_copy
;
i_data
+=
i_copy
;
}
/* The caller got what he wanted */
if
(
i_len
==
0
)
{
return
i_data
;
}
/* Read no more than one frame at a time.
* That kills latency, especially for encoded v4l streams */
if
(
p_sys
->
i_data_size
&&
p_sys
->
i_data_pos
==
p_sys
->
i_data_size
)
{
p_sys
->
i_data_pos
=
0
;
p_sys
->
i_data_size
=
0
;
return
i_data
;
}
/* Re-fill data by grabbing audio/video */
p_sys
->
i_data_pos
=
p_sys
->
i_data_size
=
0
;
/* Try grabbing audio frames first */
i_stream
=
p_sys
->
i_streams
-
1
;
if
(
p_sys
->
fd_audio
<
0
||
GrabAudio
(
p_input
,
&
p_sys
->
p_data
,
&
p_sys
->
i_data_size
,
&
i_pts
)
!=
VLC_SUCCESS
)
{
int
i_ret
=
VLC_ETIMEOUT
;
/* Try grabbing video frame */
i_stream
=
0
;
if
(
p_sys
->
fd_video
>
0
)
{
i_ret
=
GrabVideo
(
p_input
,
&
p_sys
->
p_data
,
&
p_sys
->
i_data_size
,
&
i_pts
);
}
/* No video or timeout */
if
(
i_ret
==
VLC_ETIMEOUT
)
{
/* Sleep so we do not consume all the cpu, 10ms seems
* like a good value (100fps) */
msleep
(
10000
);
continue
;
}
else
if
(
i_ret
!=
VLC_SUCCESS
)
{
msg_Err
(
p_input
,
"Error during capture!"
);
return
-
1
;
}
}
/* create pseudo header */
p_sys
->
i_header_size
=
16
;
p_sys
->
i_header_pos
=
0
;
SetDWBE
(
&
p_sys
->
p_header
[
0
],
i_stream
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
p_sys
->
i_data_size
);
SetQWBE
(
&
p_sys
->
p_header
[
8
],
i_pts
);
}
return
i_data
;
}
/*****************************************************************************
* Demux: local prototypes
*****************************************************************************/
...
...
@@ -1580,14 +1606,15 @@ struct demux_sys_t
es_out_id_t
**
es
;
};
static
int
Demux
(
input_thread_t
*
);
static
int
Demux
(
demux_t
*
);
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
/****************************************************************************
* DemuxOpen:
****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread
_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux
_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
uint8_t
*
p_peek
;
...
...
@@ -1595,7 +1622,7 @@ static int DemuxOpen( vlc_object_t *p_this )
int
i
;
/* a little test to see if it's a v4l stream */
if
(
stream_Peek
(
p_
input
->
s
,
&
p_peek
,
8
)
<
8
)
if
(
stream_Peek
(
p_
demux
->
s
,
&
p_peek
,
8
)
<
8
)
{
return
VLC_EGENERIC
;
}
...
...
@@ -1605,25 +1632,16 @@ static int DemuxOpen( vlc_object_t *p_this )
return
VLC_EGENERIC
;
}
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
if
(
input_InitStream
(
p_input
,
0
)
==
-
1
)
{
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
msg_Err
(
p_input
,
"cannot init stream"
);
return
VLC_EGENERIC
;
}
p_input
->
stream
.
i_mux_rate
=
0
/
50
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
p_
input
->
pf_demux
=
Demux
;
p_
input
->
pf_demux_control
=
demux_vaControlDefault
;
p_
input
->
p_demux_data
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_
demux
->
pf_demux
=
Demux
;
p_
demux
->
pf_control
=
DemuxControl
;
p_
demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_sys
->
i_es
=
0
;
p_sys
->
es
=
NULL
;
if
(
stream_Peek
(
p_
input
->
s
,
&
p_peek
,
8
+
20
*
i_es
)
<
8
+
20
*
i_es
)
if
(
stream_Peek
(
p_
demux
->
s
,
&
p_peek
,
8
+
20
*
i_es
)
<
8
+
20
*
i_es
)
{
msg_Err
(
p_
input
,
"v4l plugin discarded (cannot peek)"
);
msg_Err
(
p_
demux
,
"v4l plugin discarded (cannot peek)"
);
return
VLC_EGENERIC
;
}
p_peek
+=
8
;
...
...
@@ -1646,11 +1664,11 @@ static int DemuxOpen( vlc_object_t *p_this )
fmt
.
audio
.
i_rate
*
fmt
.
audio
.
i_bitspersample
;
msg_Dbg
(
p_
input
,
"new audio es %d channels %dHz"
,
msg_Dbg
(
p_
demux
,
"new audio es %d channels %dHz"
,
fmt
.
audio
.
i_channels
,
fmt
.
audio
.
i_rate
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
es_out_Add
(
p_
input
->
p_es_
out
,
&
fmt
)
);
es_out_Add
(
p_
demux
->
out
,
&
fmt
)
);
}
else
if
(
!
strncmp
(
p_peek
,
"vids"
,
4
)
)
{
...
...
@@ -1659,18 +1677,18 @@ static int DemuxOpen( vlc_object_t *p_this )
fmt
.
video
.
i_width
=
GetDWBE
(
&
p_peek
[
8
]
);
fmt
.
video
.
i_height
=
GetDWBE
(
&
p_peek
[
12
]
);
msg_Dbg
(
p_
input
,
"added new video es %4.4s %dx%d"
,
msg_Dbg
(
p_
demux
,
"added new video es %4.4s %dx%d"
,
(
char
*
)
&
fmt
.
i_codec
,
fmt
.
video
.
i_width
,
fmt
.
video
.
i_height
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
es_out_Add
(
p_
input
->
p_es_
out
,
&
fmt
)
);
es_out_Add
(
p_
demux
->
out
,
&
fmt
)
);
}
p_peek
+=
20
;
}
/* Skip header */
stream_Read
(
p_
input
->
s
,
NULL
,
8
+
20
*
i_es
);
stream_Read
(
p_
demux
->
s
,
NULL
,
8
+
20
*
i_es
);
return
VLC_SUCCESS
;
}
...
...
@@ -1680,8 +1698,8 @@ static int DemuxOpen( vlc_object_t *p_this )
****************************************************************************/
static
void
DemuxClose
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread
_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_input
->
p_demux_data
;
demux_t
*
p_demux
=
(
demux
_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
p_sys
->
i_es
>
0
)
{
...
...
@@ -1693,9 +1711,9 @@ static void DemuxClose( vlc_object_t *p_this )
/****************************************************************************
* Demux:
****************************************************************************/
static
int
Demux
(
input_thread_t
*
p_input
)
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_
input
->
p_demux_data
;
demux_sys_t
*
p_sys
=
p_
demux
->
p_sys
;
block_t
*
p_block
;
int
i_es
;
...
...
@@ -1704,25 +1722,25 @@ static int Demux( input_thread_t *p_input )
uint8_t
*
p_peek
;
mtime_t
i_pts
;
if
(
stream_Peek
(
p_
input
->
s
,
&
p_peek
,
16
)
<
16
)
if
(
stream_Peek
(
p_
demux
->
s
,
&
p_peek
,
16
)
<
16
)
{
msg_Warn
(
p_
input
,
"cannot peek (EOF ?)"
);
msg_Warn
(
p_
demux
,
"cannot peek (EOF ?)"
);
return
0
;
}
i_es
=
GetDWBE
(
&
p_peek
[
0
]
);
if
(
i_es
<
0
||
i_es
>=
p_sys
->
i_es
)
{
msg_Err
(
p_
input
,
"cannot find ES"
);
msg_Err
(
p_
demux
,
"cannot find ES"
);
return
-
1
;
}
i_size
=
GetDWBE
(
&
p_peek
[
4
]
);
i_pts
=
GetQWBE
(
&
p_peek
[
8
]
);
if
(
(
p_block
=
stream_Block
(
p_
input
->
s
,
16
+
i_size
)
)
==
NULL
)
if
(
(
p_block
=
stream_Block
(
p_
demux
->
s
,
16
+
i_size
)
)
==
NULL
)
{
msg_Warn
(
p_
input
,
"cannot read data"
);
msg_Warn
(
p_
demux
,
"cannot read data"
);
return
0
;
}
...
...
@@ -1730,9 +1748,22 @@ static int Demux( input_thread_t *p_input )
p_block
->
i_buffer
-=
16
;
p_block
->
i_dts
=
p_block
->
i_pts
=
i_pts
+
p_input
->
i_pts_delay
;
p_block
->
i_pts
=
i_pts
;
es_out_Send
(
p_input
->
p_es_out
,
p_sys
->
es
[
i_es
],
p_block
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
i_pts
);
es_out_Send
(
p_demux
->
out
,
p_sys
->
es
[
i_es
],
p_block
);
return
1
;
}
/****************************************************************************
* DemuxControl:
****************************************************************************/
static
int
DemuxControl
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
return
demux2_vaControlHelper
(
p_demux
->
s
,
0
,
-
1
,
0
,
1
,
i_query
,
args
);
}
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