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
4dfaa105
Commit
4dfaa105
authored
Sep 06, 2011
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Partially segregate access_demux V4L2 code
parent
21ecdaab
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
355 additions
and
350 deletions
+355
-350
modules/access/Modules.am
modules/access/Modules.am
+1
-0
modules/access/v4l2/demux.c
modules/access/v4l2/demux.c
+335
-0
modules/access/v4l2/v4l2.h
modules/access/v4l2/v4l2.h
+13
-0
modules/access/v4l2/video.c
modules/access/v4l2/video.c
+6
-350
No files found.
modules/access/Modules.am
View file @
4dfaa105
...
...
@@ -132,6 +132,7 @@ libvlc_LTLIBRARIES += $(LTLIBaccess_shm)
libv4l2_plugin_la_SOURCES = \
v4l2/video.c \
v4l2/demux.c \
v4l2/access.c \
v4l2/controls.c \
v4l2/v4l2.h
...
...
modules/access/v4l2/demux.c
0 → 100644
View file @
4dfaa105
/*****************************************************************************
* demux.c : V4L2 raw video demux module for vlc
*****************************************************************************
* Copyright (C) 2002-2011 the VideoLAN team
*
* Authors: Benjamin Pracht <bigben at videolan dot org>
* Richard Hosking <richard at hovis dot net>
* Antoine Cellerier <dionoea at videolan d.t org>
* Dennis Lou <dlou99 at yahoo dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "v4l2.h"
#include <vlc_demux.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <poll.h>
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
static
int
Demux
(
demux_t
*
);
int
DemuxOpen
(
vlc_object_t
*
obj
)
{
demux_t
*
demux
=
(
demux_t
*
)
obj
;
demux_sys_t
*
sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
unlikely
(
sys
==
NULL
)
)
return
VLC_ENOMEM
;
demux
->
p_sys
=
sys
;
ParseMRL
(
obj
,
demux
->
psz_location
);
sys
->
i_fd
=
OpenVideo
(
obj
,
sys
,
true
);
if
(
sys
->
i_fd
==
-
1
)
{
free
(
sys
);
return
VLC_EGENERIC
;
}
demux
->
pf_demux
=
Demux
;
demux
->
pf_control
=
DemuxControl
;
demux
->
info
.
i_update
=
0
;
demux
->
info
.
i_title
=
0
;
demux
->
info
.
i_seekpoint
=
0
;
return
VLC_SUCCESS
;
}
void
DemuxClose
(
vlc_object_t
*
obj
)
{
demux_t
*
demux
=
(
demux_t
*
)
obj
;
demux_sys_t
*
sys
=
demux
->
p_sys
;
int
fd
=
sys
->
i_fd
;
/* Stop video capture */
switch
(
sys
->
io
)
{
case
IO_METHOD_READ
:
/* Nothing to do */
break
;
case
IO_METHOD_MMAP
:
case
IO_METHOD_USERPTR
:
{
/* NOTE: Some buggy drivers hang if buffers are not unmapped before
* streamoff */
for
(
unsigned
i
=
0
;
i
<
sys
->
i_nbuffers
;
i
++
)
{
struct
v4l2_buffer
buf
=
{
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
,
.
memory
=
(
sys
->
io
==
IO_METHOD_USERPTR
)
?
V4L2_MEMORY_USERPTR
:
V4L2_MEMORY_MMAP
,
};
v4l2_ioctl
(
fd
,
VIDIOC_DQBUF
,
&
buf
);
}
enum
v4l2_buf_type
buf_type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
v4l2_ioctl
(
sys
->
i_fd
,
VIDIOC_STREAMOFF
,
&
buf_type
);
break
;
}
}
/* Free Video Buffers */
if
(
sys
->
p_buffers
)
{
switch
(
sys
->
io
)
{
case
IO_METHOD_READ
:
free
(
sys
->
p_buffers
[
0
].
start
);
break
;
case
IO_METHOD_MMAP
:
for
(
unsigned
i
=
0
;
i
<
sys
->
i_nbuffers
;
++
i
)
v4l2_munmap
(
sys
->
p_buffers
[
i
].
start
,
sys
->
p_buffers
[
i
].
length
);
break
;
case
IO_METHOD_USERPTR
:
for
(
unsigned
i
=
0
;
i
<
sys
->
i_nbuffers
;
++
i
)
free
(
sys
->
p_buffers
[
i
].
start
);
break
;
}
free
(
sys
->
p_buffers
);
}
v4l2_close
(
fd
);
free
(
sys
);
}
static
int
DemuxControl
(
demux_t
*
demux
,
int
query
,
va_list
args
)
{
switch
(
query
)
{
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_SEEK
:
case
DEMUX_CAN_CONTROL_PACE
:
*
va_arg
(
args
,
bool
*
)
=
false
;
return
VLC_SUCCESS
;
case
DEMUX_GET_PTS_DELAY
:
*
va_arg
(
args
,
int64_t
*
)
=
INT64_C
(
1000
)
*
var_InheritInteger
(
demux
,
"live-caching"
);
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
*
va_arg
(
args
,
int64_t
*
)
=
mdate
();
return
VLC_SUCCESS
;
/* TODO implement others */
default:
return
VLC_EGENERIC
;
}
return
VLC_EGENERIC
;
}
static
int
Demux
(
demux_t
*
demux
)
{
demux_sys_t
*
sys
=
demux
->
p_sys
;
struct
pollfd
fd
;
fd
.
fd
=
sys
->
i_fd
;
fd
.
events
=
POLLIN
|
POLLPRI
;
/* Wait for data */
/* FIXME: remove timeout */
while
(
poll
(
&
fd
,
1
,
500
)
==
-
1
)
if
(
errno
!=
EINTR
)
{
msg_Err
(
demux
,
"poll error: %m"
);
return
-
1
;
}
if
(
fd
.
revents
)
{
block_t
*
p_block
=
GrabVideo
(
VLC_OBJECT
(
demux
),
sys
);
if
(
p_block
)
{
es_out_Control
(
demux
->
out
,
ES_OUT_SET_PCR
,
p_block
->
i_pts
);
es_out_Send
(
demux
->
out
,
sys
->
p_es
,
p_block
);
}
}
return
1
;
}
static
float
GetMaxFPS
(
int
fd
,
uint32_t
pixel_format
,
uint32_t
width
,
uint32_t
height
)
{
#ifdef VIDIOC_ENUM_FRAMEINTERVALS
/* This is new in Linux 2.6.19 */
struct
v4l2_frmivalenum
fie
=
{
.
pixel_format
=
pixel_format
,
.
width
=
width
,
.
height
=
height
,
};
if
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMEINTERVALS
,
&
fie
)
<
0
)
return
-
1
.;
switch
(
fie
.
type
)
{
case
V4L2_FRMIVAL_TYPE_DISCRETE
:
{
float
max
=
-
1
.;
do
{
float
fps
=
(
float
)
fie
.
discrete
.
denominator
/
(
float
)
fie
.
discrete
.
numerator
;
if
(
fps
>
max
)
max
=
fps
;
fie
.
index
++
;
}
while
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMEINTERVALS
,
&
fie
)
>=
0
);
return
max
;
}
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
case
V4L2_FRMIVAL_TYPE_CONTINUOUS
:
return
__MAX
(
(
float
)
fie
.
stepwise
.
max
.
denominator
/
(
float
)
fie
.
stepwise
.
max
.
numerator
,
(
float
)
fie
.
stepwise
.
min
.
denominator
/
(
float
)
fie
.
stepwise
.
min
.
numerator
);
}
#endif
return
-
1
.;
}
float
GetAbsoluteMaxFrameRate
(
vlc_object_t
*
obj
,
int
fd
,
uint32_t
pixel_format
)
{
#ifdef VIDIOC_ENUM_FRAMESIZES
/* This is new in Linux 2.6.19 */
struct
v4l2_frmsizeenum
fse
=
{
.
pixel_format
=
pixel_format
};
if
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
fse
)
<
0
)
return
-
1
.;
float
max
=
-
1
.;
switch
(
fse
.
type
)
{
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
do
{
float
fps
=
GetMaxFPS
(
fd
,
pixel_format
,
fse
.
discrete
.
width
,
fse
.
discrete
.
height
);
if
(
fps
>
max
)
max
=
fps
;
fse
.
index
++
;
}
while
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
fse
)
>=
0
);
break
;
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
for
(
uint32_t
width
=
fse
.
stepwise
.
min_width
,
height
=
fse
.
stepwise
.
min_height
;
width
<=
fse
.
stepwise
.
max_width
&&
height
<=
fse
.
stepwise
.
max_width
;
width
+=
fse
.
stepwise
.
step_width
,
height
+=
fse
.
stepwise
.
step_height
)
{
float
fps
=
GetMaxFPS
(
fd
,
pixel_format
,
width
,
height
);
if
(
fps
>
max
)
max
=
fps
;
}
break
;
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
/* FIXME */
msg_Err
(
obj
,
"V4L2_FRMSIZE_TYPE_CONTINUOUS support incorrect"
);
max
=
GetMaxFPS
(
fd
,
pixel_format
,
fse
.
stepwise
.
max_width
,
fse
.
stepwise
.
max_height
);
break
;
}
return
max
;
#else
return
-
1
.;
#endif
}
void
GetMaxDimensions
(
vlc_object_t
*
obj
,
int
fd
,
uint32_t
pixel_format
,
float
fps_min
,
uint32_t
*
pwidth
,
uint32_t
*
pheight
)
{
*
pwidth
=
0
;
*
pheight
=
0
;
#ifdef VIDIOC_ENUM_FRAMESIZES
/* This is new in Linux 2.6.19 */
struct
v4l2_frmsizeenum
fse
=
{
.
pixel_format
=
pixel_format
};
if
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
fse
)
<
0
)
return
;
switch
(
fse
.
type
)
{
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
do
{
float
fps
=
GetMaxFPS
(
fd
,
pixel_format
,
fse
.
discrete
.
width
,
fse
.
discrete
.
height
);
if
(
fps
>=
fps_min
&&
fse
.
discrete
.
width
>
*
pwidth
)
{
*
pwidth
=
fse
.
discrete
.
width
;
*
pheight
=
fse
.
discrete
.
height
;
}
fse
.
index
++
;
}
while
(
v4l2_ioctl
(
fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
fse
)
>=
0
);
break
;
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
for
(
uint32_t
width
=
fse
.
stepwise
.
min_width
,
height
=
fse
.
stepwise
.
min_height
;
width
<=
fse
.
stepwise
.
max_width
&&
height
<=
fse
.
stepwise
.
max_width
;
width
+=
fse
.
stepwise
.
step_width
,
height
+=
fse
.
stepwise
.
step_height
)
{
float
fps
=
GetMaxFPS
(
fd
,
pixel_format
,
width
,
height
);
if
(
fps
>=
fps_min
&&
width
>
*
pwidth
)
{
*
pwidth
=
width
;
*
pheight
=
height
;
}
}
break
;
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
{
float
fps
=
GetMaxFPS
(
fd
,
pixel_format
,
fse
.
stepwise
.
max_width
,
fse
.
stepwise
.
max_height
);
msg_Err
(
obj
,
"V4L2_FRMSIZE_TYPE_CONTINUOUS support incorrect"
);
if
(
fps
>=
fps_min
&&
fse
.
stepwise
.
max_width
>
*
pwidth
)
{
*
pwidth
=
fse
.
stepwise
.
max_width
;
*
pheight
=
fse
.
stepwise
.
max_height
;
}
break
;
}
}
#endif
}
modules/access/v4l2/v4l2.h
View file @
4dfaa105
...
...
@@ -71,11 +71,24 @@ struct demux_sys_t
#endif
};
struct
buffer_t
{
void
*
start
;
size_t
length
;
};
/* video.c */
void
ParseMRL
(
vlc_object_t
*
,
const
char
*
);
int
OpenVideo
(
vlc_object_t
*
,
demux_sys_t
*
,
bool
);
block_t
*
GrabVideo
(
vlc_object_t
*
,
demux_sys_t
*
);
/* demux.c */
int
DemuxOpen
(
vlc_object_t
*
);
void
DemuxClose
(
vlc_object_t
*
);
float
GetAbsoluteMaxFrameRate
(
vlc_object_t
*
,
int
fd
,
uint32_t
fmt
);
void
GetMaxDimensions
(
vlc_object_t
*
,
int
fd
,
uint32_t
fmt
,
float
fps_min
,
uint32_t
*
pwidth
,
uint32_t
*
pheight
);
/* access.c */
int
AccessOpen
(
vlc_object_t
*
);
void
AccessClose
(
vlc_object_t
*
);
modules/access/v4l2/video.c
View file @
4dfaa105
...
...
@@ -54,9 +54,6 @@
* Module descriptior
*****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
#define DEVICE_TEXT N_( "Device" )
#define DEVICE_LONGTEXT N_( \
"Video device (Default: /dev/video0)." )
...
...
@@ -403,9 +400,6 @@ vlc_module_end ()
* Access: local prototypes
*****************************************************************************/
static
int
DemuxControl
(
demux_t
*
,
int
,
va_list
);
static
int
Demux
(
demux_t
*
);
static
block_t
*
ProcessVideoFrame
(
vlc_object_t
*
p_demux
,
uint8_t
*
p_frame
,
size_t
);
static
const
struct
...
...
@@ -465,44 +459,6 @@ static const uint32_t p_chroma_fallbacks[] =
V4L2_PIX_FMT_YUYV
,
V4L2_PIX_FMT_UYVY
,
V4L2_PIX_FMT_BGR24
,
V4L2_PIX_FMT_BGR32
,
V4L2_PIX_FMT_MJPEG
,
V4L2_PIX_FMT_JPEG
};
struct
buffer_t
{
void
*
start
;
size_t
length
;
};
/*****************************************************************************
* DemuxOpen: opens v4l2 device, access_demux callback
*****************************************************************************
*
* url: <video device>::::
*
*****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
/* Set up p_demux */
p_demux
->
pf_control
=
DemuxControl
;
p_demux
->
pf_demux
=
Demux
;
p_demux
->
info
.
i_update
=
0
;
p_demux
->
info
.
i_title
=
0
;
p_demux
->
info
.
i_seekpoint
=
0
;
p_demux
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
ParseMRL
(
p_this
,
p_demux
->
psz_location
);
p_sys
->
i_fd
=
OpenVideo
(
p_this
,
p_sys
,
true
);
if
(
p_sys
->
i_fd
==
-
1
)
{
free
(
p_sys
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
/**
* Parses a V4L2 MRL into VLC object variables.
*/
...
...
@@ -531,145 +487,6 @@ void ParseMRL( vlc_object_t *obj, const char *mrl )
}
}
/*****************************************************************************
* Close: close device, free resources
*****************************************************************************/
static
void
DemuxClose
(
vlc_object_t
*
p_this
)
{
struct
v4l2_buffer
buf
;
enum
v4l2_buf_type
buf_type
;
unsigned
int
i
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
/* Stop video capture */
if
(
p_sys
->
i_fd
>=
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 */
for
(
unsigned
int
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
i
++
)
{
memset
(
&
buf
,
0
,
sizeof
(
buf
)
);
buf
.
type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
buf
.
memory
=
(
p_sys
->
io
==
IO_METHOD_USERPTR
)
?
V4L2_MEMORY_USERPTR
:
V4L2_MEMORY_MMAP
;
v4l2_ioctl
(
p_sys
->
i_fd
,
VIDIOC_DQBUF
,
&
buf
);
/* ignore result */
}
buf_type
=
V4L2_BUF_TYPE_VIDEO_CAPTURE
;
if
(
v4l2_ioctl
(
p_sys
->
i_fd
,
VIDIOC_STREAMOFF
,
&
buf_type
)
<
0
)
{
msg_Err
(
p_this
,
"VIDIOC_STREAMOFF failed"
);
}
break
;
}
}
/* Free Video Buffers */
if
(
p_sys
->
p_buffers
)
{
switch
(
p_sys
->
io
)
{
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
)
{
if
(
v4l2_munmap
(
p_sys
->
p_buffers
[
i
].
start
,
p_sys
->
p_buffers
[
i
].
length
)
)
{
msg_Err
(
p_this
,
"munmap failed"
);
}
}
break
;
case
IO_METHOD_USERPTR
:
for
(
i
=
0
;
i
<
p_sys
->
i_nbuffers
;
++
i
)
{
free
(
p_sys
->
p_buffers
[
i
].
start
);
}
break
;
}
free
(
p_sys
->
p_buffers
);
}
v4l2_close
(
p_sys
->
i_fd
);
free
(
p_sys
);
}
/*****************************************************************************
* DemuxControl:
*****************************************************************************/
static
int
DemuxControl
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
switch
(
i_query
)
{
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_SEEK
:
case
DEMUX_CAN_CONTROL_PACE
:
*
va_arg
(
args
,
bool
*
)
=
false
;
return
VLC_SUCCESS
;
case
DEMUX_GET_PTS_DELAY
:
*
va_arg
(
args
,
int64_t
*
)
=
INT64_C
(
1000
)
*
var_InheritInteger
(
p_demux
,
"live-caching"
);
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
*
va_arg
(
args
,
int64_t
*
)
=
mdate
();
return
VLC_SUCCESS
;
/* TODO implement others */
default:
return
VLC_EGENERIC
;
}
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Demux: Processes the audio or video frame
*****************************************************************************/
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
struct
pollfd
fd
;
fd
.
fd
=
p_sys
->
i_fd
;
fd
.
events
=
POLLIN
|
POLLPRI
;
fd
.
revents
=
0
;
/* Wait for data */
/* Timeout after 0.5 seconds since I don't know if pf_demux can be blocking. */
while
(
poll
(
&
fd
,
1
,
500
)
==
-
1
)
if
(
errno
!=
EINTR
)
{
msg_Err
(
p_demux
,
"poll error: %m"
);
return
-
1
;
}
if
(
fd
.
revents
)
{
block_t
*
p_block
=
GrabVideo
(
VLC_OBJECT
(
p_demux
),
p_sys
);
if
(
p_block
)
{
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
p_block
->
i_pts
);
es_out_Send
(
p_demux
->
out
,
p_sys
->
p_es
,
p_block
);
}
}
return
1
;
}
/*****************************************************************************
* GrabVideo: Grab a video frame
*****************************************************************************/
...
...
@@ -951,166 +768,6 @@ static bool IsPixelFormatSupported( struct v4l2_fmtdesc *codecs, size_t n,
return
false
;
}
static
float
GetMaxFrameRate
(
int
i_fd
,
uint32_t
i_pixel_format
,
uint32_t
i_width
,
uint32_t
i_height
)
{
#ifdef VIDIOC_ENUM_FRAMEINTERVALS
/* This is new in Linux 2.6.19 */
struct
v4l2_frmivalenum
frmival
;
memset
(
&
frmival
,
0
,
sizeof
(
frmival
)
);
frmival
.
pixel_format
=
i_pixel_format
;
frmival
.
width
=
i_width
;
frmival
.
height
=
i_height
;
if
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMEINTERVALS
,
&
frmival
)
>=
0
)
{
switch
(
frmival
.
type
)
{
case
V4L2_FRMIVAL_TYPE_DISCRETE
:
{
float
f_fps_max
=
-
1
;
do
{
float
f_fps
=
(
float
)
frmival
.
discrete
.
denominator
/
(
float
)
frmival
.
discrete
.
numerator
;
if
(
f_fps
>
f_fps_max
)
f_fps_max
=
f_fps
;
frmival
.
index
++
;
}
while
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMEINTERVALS
,
&
frmival
)
>=
0
);
return
f_fps_max
;
}
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
case
V4L2_FRMIVAL_TYPE_CONTINUOUS
:
return
__MAX
(
(
float
)
frmival
.
stepwise
.
max
.
denominator
/
(
float
)
frmival
.
stepwise
.
max
.
numerator
,
(
float
)
frmival
.
stepwise
.
min
.
denominator
/
(
float
)
frmival
.
stepwise
.
min
.
numerator
);
}
}
#endif
return
-
1
.;
}
static
float
GetAbsoluteMaxFrameRate
(
demux_t
*
p_demux
,
int
i_fd
,
uint32_t
i_pixel_format
)
{
float
f_fps_max
=
-
1
.;
#ifdef VIDIOC_ENUM_FRAMESIZES
/* This is new in Linux 2.6.19 */
struct
v4l2_frmsizeenum
frmsize
;
memset
(
&
frmsize
,
0
,
sizeof
(
frmsize
)
);
frmsize
.
pixel_format
=
i_pixel_format
;
if
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
)
{
switch
(
frmsize
.
type
)
{
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
do
{
frmsize
.
index
++
;
float
f_fps
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
frmsize
.
discrete
.
width
,
frmsize
.
discrete
.
height
);
if
(
f_fps
>
f_fps_max
)
f_fps_max
=
f_fps
;
}
while
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
);
break
;
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
{
uint32_t
i_width
=
frmsize
.
stepwise
.
min_width
;
uint32_t
i_height
=
frmsize
.
stepwise
.
min_height
;
for
(
;
i_width
<=
frmsize
.
stepwise
.
max_width
&&
i_height
<=
frmsize
.
stepwise
.
max_width
;
i_width
+=
frmsize
.
stepwise
.
step_width
,
i_height
+=
frmsize
.
stepwise
.
step_height
)
{
float
f_fps
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
i_width
,
i_height
);
if
(
f_fps
>
f_fps_max
)
f_fps_max
=
f_fps
;
}
break
;
}
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
/* FIXME */
msg_Err
(
p_demux
,
"GetAbsoluteMaxFrameRate implementation for V4L2_FRMSIZE_TYPE_CONTINUOUS isn't correct"
);
f_fps_max
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
);
break
;
}
}
#endif
return
f_fps_max
;
}
static
void
GetMaxDimensions
(
demux_t
*
p_demux
,
int
i_fd
,
uint32_t
i_pixel_format
,
float
f_fps_min
,
uint32_t
*
pi_width
,
uint32_t
*
pi_height
)
{
*
pi_width
=
0
;
*
pi_height
=
0
;
#ifdef VIDIOC_ENUM_FRAMESIZES
/* This is new in Linux 2.6.19 */
struct
v4l2_frmsizeenum
frmsize
;
memset
(
&
frmsize
,
0
,
sizeof
(
frmsize
)
);
frmsize
.
pixel_format
=
i_pixel_format
;
if
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
)
{
switch
(
frmsize
.
type
)
{
case
V4L2_FRMSIZE_TYPE_DISCRETE
:
do
{
frmsize
.
index
++
;
float
f_fps
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
frmsize
.
discrete
.
width
,
frmsize
.
discrete
.
height
);
if
(
f_fps
>=
f_fps_min
&&
frmsize
.
discrete
.
width
>
*
pi_width
)
{
*
pi_width
=
frmsize
.
discrete
.
width
;
*
pi_height
=
frmsize
.
discrete
.
height
;
}
}
while
(
v4l2_ioctl
(
i_fd
,
VIDIOC_ENUM_FRAMESIZES
,
&
frmsize
)
>=
0
);
break
;
case
V4L2_FRMSIZE_TYPE_STEPWISE
:
{
uint32_t
i_width
=
frmsize
.
stepwise
.
min_width
;
uint32_t
i_height
=
frmsize
.
stepwise
.
min_height
;
for
(
;
i_width
<=
frmsize
.
stepwise
.
max_width
&&
i_height
<=
frmsize
.
stepwise
.
max_width
;
i_width
+=
frmsize
.
stepwise
.
step_width
,
i_height
+=
frmsize
.
stepwise
.
step_height
)
{
float
f_fps
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
i_width
,
i_height
);
if
(
f_fps
>=
f_fps_min
&&
i_width
>
*
pi_width
)
{
*
pi_width
=
i_width
;
*
pi_height
=
i_height
;
}
}
break
;
}
case
V4L2_FRMSIZE_TYPE_CONTINUOUS
:
/* FIXME */
msg_Err
(
p_demux
,
"GetMaxDimension implementation for V4L2_FRMSIZE_TYPE_CONTINUOUS isn't correct"
);
float
f_fps
=
GetMaxFrameRate
(
i_fd
,
i_pixel_format
,
frmsize
.
stepwise
.
max_width
,
frmsize
.
stepwise
.
max_height
);
if
(
f_fps
>=
f_fps_min
&&
frmsize
.
stepwise
.
max_width
>
*
pi_width
)
{
*
pi_width
=
frmsize
.
stepwise
.
max_width
;
*
pi_height
=
frmsize
.
stepwise
.
max_height
;
}
break
;
}
}
#endif
}
static
int
InitVideo
(
vlc_object_t
*
p_obj
,
int
i_fd
,
demux_sys_t
*
p_sys
,
bool
b_demux
);
...
...
@@ -1530,7 +1187,6 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
float
f_fps
;
if
(
b_demux
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_obj
;
char
*
reqchroma
=
var_InheritString
(
p_obj
,
CFG_PREFIX
"chroma"
);
/* Test and set Chroma */
...
...
@@ -1594,7 +1250,7 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
}
if
(
i
==
ARRAY_SIZE
(
p_chroma_fallbacks
)
)
{
msg_Warn
(
p_
demux
,
"Could not select any of the default chromas; attempting to open as MPEG encoder card (access)"
);
msg_Warn
(
p_
obj
,
"Could not select any of the default chromas; attempting to open as MPEG encoder card (access)"
);
goto
error
;
}
}
...
...
@@ -1604,17 +1260,17 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
f_fps
=
var_InheritFloat
(
p_obj
,
CFG_PREFIX
"fps"
);
if
(
f_fps
<=
0
.
)
{
f_fps
=
GetAbsoluteMaxFrameRate
(
p_
demux
,
i_fd
,
f_fps
=
GetAbsoluteMaxFrameRate
(
p_
obj
,
i_fd
,
fmt
.
fmt
.
pix
.
pixelformat
);
msg_Dbg
(
p_
demux
,
"Found maximum framerate of %f"
,
f_fps
);
msg_Dbg
(
p_
obj
,
"Found maximum framerate of %f"
,
f_fps
);
}
uint32_t
i_width
,
i_height
;
GetMaxDimensions
(
p_
demux
,
i_fd
,
GetMaxDimensions
(
p_
obj
,
i_fd
,
fmt
.
fmt
.
pix
.
pixelformat
,
f_fps
,
&
i_width
,
&
i_height
);
if
(
i_width
||
i_height
)
{
msg_Dbg
(
p_
demux
,
"Found optimal dimensions for framerate %f "
msg_Dbg
(
p_
obj
,
"Found optimal dimensions for framerate %f "
"of %ux%u"
,
f_fps
,
i_width
,
i_height
);
fmt
.
fmt
.
pix
.
width
=
i_width
;
fmt
.
fmt
.
pix
.
height
=
i_height
;
...
...
@@ -1845,7 +1501,7 @@ static int InitVideo( vlc_object_t *p_obj, int i_fd, demux_sys_t *p_sys,
es_fmt
.
video
.
i_frame_rate_base
=
1000000
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_obj
;
msg_Dbg
(
p_
demux
,
"added new video es %4.4s %dx%d"
,
msg_Dbg
(
p_
obj
,
"added new video es %4.4s %dx%d"
,
(
char
*
)
&
es_fmt
.
i_codec
,
es_fmt
.
video
.
i_width
,
es_fmt
.
video
.
i_height
);
msg_Dbg
(
p_obj
,
" frame rate: %f"
,
f_fps
);
...
...
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