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
5c808483
Commit
5c808483
authored
Nov 06, 2009
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
davinci: Partially backport 788db410392dea2bd5c390efff8da3246cfd66d1
Needs more cleaning and rewritting.
parent
fd963914
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
671 additions
and
529 deletions
+671
-529
modules/codec/davinci/Modules.am
modules/codec/davinci/Modules.am
+2
-0
modules/codec/davinci/resizer.c
modules/codec/davinci/resizer.c
+495
-0
modules/codec/davinci/resizer.h
modules/codec/davinci/resizer.h
+55
-0
modules/codec/davinci/viddec.c
modules/codec/davinci/viddec.c
+58
-527
modules/codec/davinci/videnc.c
modules/codec/davinci/videnc.c
+61
-2
No files found.
modules/codec/davinci/Modules.am
View file @
5c808483
...
...
@@ -4,4 +4,6 @@ SOURCES_davinci = \
auddec.c \
viddec.c \
videnc.c \
resizer.c \
reziser.h \
$(NULL)
modules/codec/davinci/resizer.c
0 → 100644
View file @
5c808483
/*****************************************************************************
* resizer.c: Resize pictures directly into framebuffer (DaVinci specific)
*****************************************************************************
* Copyright (C) 2008 M2X BV
*
* Authors: Rafaël Carré <rcarre@m2x.nl>
*
* 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.
*****************************************************************************/
#undef _FILE_OFFSET_BITS
/* mmap() fails on 64 bits offsets */
#include "davinci.h"
/* DAVINCI_HACK defined here */
#ifdef DAVINCI_HACK
#include "resizer.h"
#include <assert.h>
void
Resize_coeff
(
decoder_t
*
p_dec
,
unsigned
int
*
i_width
,
unsigned
int
*
i_height
)
{
unsigned
int
i_vidw
=
p_dec
->
fmt_out
.
video
.
i_width
;
unsigned
int
i_vidh
=
p_dec
->
fmt_out
.
video
.
i_height
;
unsigned
int
i_hratio
=
VOUT_ASPECT_FACTOR
*
*
i_height
/
i_vidh
;
unsigned
int
i_wratio
=
VOUT_ASPECT_FACTOR
*
*
i_width
/
i_vidw
;
msg_Dbg
(
p_dec
,
"Original Video %dx%d, Output destination %dx%d"
,
i_vidw
,
i_vidh
,
*
i_width
,
*
i_height
);
/* Davinci Resizer can only do from x0.25 to x4 */
if
(
i_hratio
>
VOUT_ASPECT_FACTOR
*
4
)
i_hratio
=
VOUT_ASPECT_FACTOR
*
4
;
else
if
(
i_hratio
<
VOUT_ASPECT_FACTOR
/
4
)
i_hratio
=
VOUT_ASPECT_FACTOR
/
4
;
/* do that also for the width */
if
(
i_wratio
>
VOUT_ASPECT_FACTOR
*
4
)
i_wratio
=
VOUT_ASPECT_FACTOR
*
4
;
else
if
(
i_wratio
<
VOUT_ASPECT_FACTOR
/
4
)
i_wratio
=
VOUT_ASPECT_FACTOR
/
4
;
/* choose the minimum for both axes */
i_hratio
=
i_wratio
=
i_hratio
<
i_wratio
?
i_hratio
:
i_wratio
;
/* Now calculate hrsz and vrsz */
int
i_hrsz
=
256
*
VOUT_ASPECT_FACTOR
/
i_wratio
;
int
i_vrsz
=
256
*
VOUT_ASPECT_FACTOR
/
i_hratio
;
/* Then recalculate final resolution */
int
i_htap
=
i_hrsz
>
512
?
7
:
4
;
int
i_vtap
=
i_vrsz
>
512
?
7
:
4
;
*
i_width
=
((
i_vidw
-
7
)
*
256
-
(
i_htap
==
7
?
32
:
16
))
/
i_hrsz
+
1
;
*
i_height
=
((
i_vidh
-
i_vtap
)
*
256
-
(
i_vtap
==
7
?
32
:
16
))
/
i_vrsz
+
1
;
/* width must be a factor of 16 : davinci resizer limitation when doing
* * vertical upscaling, 16 bytes per output line
* * the bpp is 2 so a factor of 8 should be good but not in practice
* */
*
i_width
=
(
*
i_width
+
15
)
&
~
15
;
msg_Dbg
(
p_dec
,
"Destination fixed to %dx%d"
,
*
i_width
,
*
i_height
);
}
/* open() a framebuffer by its name (NOT device path) */
int
OpenFB
(
const
char
*
psz_name
)
{
int
i_fd
=
-
1
;
int
i_tries
=
0
;
/* begin with /dev/fb0 */
char
*
psz_device
;
struct
fb_fix_screeninfo
info
;
do
{
if
(
asprintf
(
&
psz_device
,
"/dev/fb%d"
,
i_tries
++
)
==
-
1
)
return
-
1
;
i_fd
=
open
(
psz_device
,
O_RDWR
);
free
(
psz_device
);
if
(
i_fd
==
-
1
)
return
-
1
;
/* check errno */
if
(
ioctl
(
i_fd
,
FBIOGET_FSCREENINFO
,
&
info
)
==
-
1
)
{
close
(
i_fd
);
continue
;
}
if
(
!
strcmp
(
info
.
id
,
psz_name
)
)
return
i_fd
;
close
(
i_fd
);
}
while
(
1
);
}
static
float
bicubic_core
(
float
s
)
{
if
(
s
<
0
)
s
=
-
s
;
if
(
0
.
<=
s
&&
s
<=
1
.
)
return
1
.
5
*
s
*
s
*
s
-
2
.
5
*
s
*
s
+
1
.;
else
if
(
s
<=
2
.
)
return
-
.
5
*
s
*
s
*
s
+
2
.
5
*
s
*
s
-
4
.
*
s
+
2
.;
else
return
0
.;
}
void
get_coeffs
(
short
coefs
[
32
],
unsigned
int
i_in
,
unsigned
int
i_out
)
{
assert
(
i_out
>
1
);
assert
(
i_in
>
7
);
float
f_deinterleave_coef
[
32
];
float
f_windows
[
32
+
1
];
unsigned
int
i_rsz
;
if
(
i_in
==
i_out
)
i_rsz
=
256
;
else
{
i_rsz
=
((
i_in
-
7
)
*
256
)
/
(
i_out
-
1
);
if
(
i_rsz
<=
512
)
{
i_rsz
=
((
i_in
-
4
)
*
256
)
/
(
i_out
-
1
);
if
(
i_rsz
>
512
)
i_rsz
=
512
;
}
}
int
i_nphases
,
i_ntaps
,
i_winlen
,
i_phase_offset
,
i
,
j
;
float
f_fc
;
if
(
i_rsz
>
512
)
{
i_nphases
=
4
;
i_ntaps
=
7
;
i_phase_offset
=
8
;
}
else
{
i_nphases
=
8
;
i_ntaps
=
4
;
i_phase_offset
=
4
;
}
i_winlen
=
i_nphases
*
i_ntaps
;
/* calculating the cut-off frequency, normalized by fs/2 */
f_fc
=
(
i_rsz
<
256
)
?
(
1
.
/
i_nphases
)
:
256
.
/
(
i_rsz
*
i_nphases
);
for
(
i
=
0
;
i
<=
i_winlen
;
i
++
)
f_windows
[
i
]
=
.
42
-
.
5
*
cos
(
2
*
PI
*
i
/
i_winlen
)
+
.
08
*
cos
(
4
*
PI
*
i
/
i_winlen
);
i_nphases
=
8
;
i_ntaps
=
4
;
i_phase_offset
=
4
;
/* calculating the bi-cubic coefficients */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
float
f_alpha
=
((
float
)
i
)
/
i_nphases
;
f_deinterleave_coef
[
i_phase_offset
*
i
]
=
bicubic_core
(
f_alpha
+
1
.
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
1
]
=
bicubic_core
(
f_alpha
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
2
]
=
bicubic_core
(
1
.
-
f_alpha
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
3
]
=
bicubic_core
(
2
.
-
f_alpha
);
}
/* de-interleave into phases */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
/* i=phase */
float
f_gain
=
0
;
for
(
j
=
0
;
j
<
i_ntaps
;
j
++
)
/* j=tap */
f_gain
+=
f_deinterleave_coef
[
i_phase_offset
*
i
+
j
];
for
(
j
=
0
;
j
<
i_ntaps
;
j
++
)
coefs
[
i_phase_offset
*
i
+
j
]
=
(
short
)
(
f_deinterleave_coef
[
i_phase_offset
*
i
+
j
]
*
256
/
f_gain
+
0
.
5
);
if
(
i_ntaps
==
7
)
coefs
[
i_phase_offset
*
i
+
7
]
=
0
.;
}
/* adjust the gain to make it exactly one */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
int
max
=
coefs
[
i_phase_offset
*
i
];
int
max2
=
0
;
int
index
=
0
;
int
index2
=
0
;
int
total_gain
=
max
;
int
delta
;
for
(
j
=
1
;
j
<
i_ntaps
;
j
++
)
{
total_gain
+=
coefs
[
i_phase_offset
*
i
+
j
];
if
(
abs
(
coefs
[
i_phase_offset
*
i
+
j
]
)
>=
max
)
{
max2
=
max
;
index2
=
index
;
index
=
j
;
max
=
abs
(
coefs
[
i_phase_offset
*
i
+
j
]
);
}
}
delta
=
256
-
total_gain
;
if
(
max
-
max2
<
10
)
{
coefs
[
i_phase_offset
*
i
+
index2
]
+=
(
delta
>>
1
);
coefs
[
i_phase_offset
*
i
+
index
]
+=
(
delta
-
(
delta
>>
1
));
}
else
coefs
[
i_phase_offset
*
i
+
index
]
+=
delta
;
}
if
(
i_rsz
==
256
)
{
/* no resizing, all pass filtering */
for
(
i
=
0
;
i
<
i_nphases
*
i_ntaps
;
i
+=
4
)
{
coefs
[
i
]
=
256
;
coefs
[
i
+
1
]
=
coefs
[
i
+
2
]
=
coefs
[
i
+
3
]
=
0
;
}
}
}
void
Resize
(
decoder_t
*
p_dec
,
vlc_bool_t
b_scale
,
davinci_resizer_t
*
rsz
,
davinci_fb_t
*
fb
,
XDM_BufDesc
out
)
{
if
(
!
rsz
->
i_yuyv
)
{
/* use screen resolution for the buffer, we may be off by a few */
rsz
->
i_yuyv
=
fb
->
var_info
.
xres
*
fb
->
var_info
.
yres_virtual
;
assert
(
rsz
->
i_yuyv
);
rsz_reqbufs_t
reqbufs
;
rsz_buffer_t
buffer
;
memset
(
&
reqbufs
,
0
,
sizeof
(
reqbufs
)
);
memset
(
&
buffer
,
0
,
sizeof
(
buffer
)
);
reqbufs
.
buf_type
=
RSZ_BUF_OUT
;
reqbufs
.
size
=
rsz
->
i_yuyv
;
reqbufs
.
count
=
1
;
if
(
ioctl
(
rsz
->
i_fd
,
RSZ_REQBUF
,
&
reqbufs
)
)
{
msg_Err
(
p_dec
,
"RSZ_REQBUF failed (%m)"
);
return
;
}
buffer
.
buf_type
=
RSZ_BUF_OUT
;
buffer
.
index
=
0
;
if
(
ioctl
(
rsz
->
i_fd
,
RSZ_QUERYBUF
,
&
buffer
)
)
{
msg_Err
(
p_dec
,
"RSZ_QUERYBUF failed (%m)"
);
return
;
}
rsz
->
offset
=
buffer
.
offset
;
rsz
->
p_yuyv
=
mmap
(
NULL
,
reqbufs
.
size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
rsz
->
i_fd
,
buffer
.
offset
);
if
(
rsz
->
p_yuyv
==
MAP_FAILED
)
{
rsz
->
i_yuyv
=
0
;
msg_Err
(
p_dec
,
"mmap resizer to buffer failed (%m)"
);
return
;
}
}
/* Sets resizer parameters when video starts or when resolution changes */
if
(
rsz
->
i_width
!=
p_dec
->
fmt_out
.
video
.
i_width
||
rsz
->
i_height
!=
p_dec
->
fmt_out
.
video
.
i_height
)
{
rsz_params_t
rsz_params
;
memset
(
&
rsz_params
,
0
,
sizeof
(
rsz_params
)
);
rsz_params
.
in_hsize
=
rsz
->
i_width
=
p_dec
->
fmt_out
.
video
.
i_width
;
rsz_params
.
in_vsize
=
rsz
->
i_height
=
p_dec
->
fmt_out
.
video
.
i_height
;
rsz_params
.
in_pitch
=
(
p_dec
->
fmt_out
.
video
.
i_width
*
BPP
/
8
+
31
)
&
~
31
;
rsz_params
.
inptyp
=
RSZ_INTYPE_YCBCR422_16BIT
;
rsz_params
.
pix_fmt
=
RSZ_PIX_FMT_YUYV
;
/* Sets the desired maximum destination resolution */
if
(
b_scale
)
{
rsz_params
.
out_hsize
=
fb
->
var_info
.
xres
;
rsz_params
.
out_vsize
=
fb
->
var_info
.
yres
;
}
else
{
rsz_params
.
out_hsize
=
rsz_params
.
in_hsize
;
rsz_params
.
out_vsize
=
rsz_params
.
in_vsize
;
}
/* And then modify it to keep the same aspect ratio, and make sure
* that the hardware is able to handle it */
Resize_coeff
(
p_dec
,
&
rsz_params
.
out_hsize
,
&
rsz_params
.
out_vsize
);
/* RSZ_PIX_FMT_YUYV is 2 bytes per pixel */
rsz_params
.
out_pitch
=
(
rsz_params
.
out_hsize
*
2
+
15
)
&
~
15
;
rsz
->
b_direct
=
(
unsigned
)
rsz_params
.
out_hsize
==
(
unsigned
)
fb
->
var_info
.
xres
;
rsz
->
i_out_width
=
rsz_params
.
out_hsize
;
rsz
->
i_out_height
=
rsz_params
.
out_vsize
;
short
hcoefs
[
32
],
vcoefs
[
32
];
get_coeffs
(
hcoefs
,
rsz_params
.
in_hsize
,
rsz_params
.
out_hsize
);
get_coeffs
(
vcoefs
,
rsz_params
.
in_vsize
,
rsz_params
.
out_vsize
);
int
i
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
rsz_params
.
hfilt_coeffs
[
i
]
=
hcoefs
[
i
];
rsz_params
.
vfilt_coeffs
[
i
]
=
vcoefs
[
i
];
}
rsz_params
.
yenh_params
.
type
=
RSZ_YENH_DISABLE
;
if
(
ioctl
(
rsz
->
i_fd
,
RSZ_S_PARAM
,
&
rsz_params
)
)
{
msg_Err
(
p_dec
,
"Failed setting resizer parameters: "
"%dx%d (pitch %d) -> %dx%d (pitch %d) : %m"
,
rsz_params
.
in_hsize
,
rsz_params
.
in_vsize
,
rsz_params
.
in_pitch
,
rsz_params
.
out_hsize
,
rsz_params
.
out_vsize
,
rsz_params
.
out_pitch
);
rsz
->
i_width
=
rsz
->
i_height
=
0
;
return
;
}
}
rsz_resize_t
rszh
;
rszh
.
in_buf
.
index
=
-
1
;
rszh
.
in_buf
.
buf_type
=
RSZ_BUF_IN
;
rszh
.
in_buf
.
size
=
p_dec
->
fmt_out
.
video
.
i_height
*
((
p_dec
->
fmt_out
.
video
.
i_width
*
BPP
/
8
+
31
)
&
~
31
);
rszh
.
in_buf
.
offset
=
Memory_getBufferPhysicalAddress
(
out
.
bufs
[
0
],
rszh
.
in_buf
.
size
,
NULL
);
assert
(
rszh
.
in_buf
.
offset
);
rszh
.
out_buf
.
index
=
-
1
;
rszh
.
out_buf
.
buf_type
=
RSZ_BUF_OUT
;
if
(
b_scale
&&
rsz
->
b_direct
/* output video res is screen res */
)
{
/* FIXME: use NUM_BUFFERS if needed */
rszh
.
out_buf
.
offset
=
fb
->
p_physbufs
[
0
];
rszh
.
out_buf
.
size
=
fb
->
var_info
.
xres
*
fb
->
var_info
.
yres_virtual
;
}
else
{
rszh
.
out_buf
.
offset
=
rsz
->
offset
;
rszh
.
out_buf
.
size
=
rsz
->
i_yuyv
;
}
do
{
if
(
ioctl
(
rsz
->
i_fd
,
RSZ_RESIZE
,
&
rszh
)
==
-
1
)
{
if
(
errno
==
EAGAIN
)
continue
;
msg_Err
(
p_dec
,
"Resizing failed (%m)"
);
return
;
}
}
while
(
0
);
}
int
DavinciInit
(
decoder_t
*
p_dec
,
davinci_fb_t
*
fb
,
davinci_resizer_t
*
rsz
)
{
fb
->
i_fd
=
rsz
->
i_fd
=
-
1
;
/* Open framebuffer */
if
(
(
fb
->
i_fd
=
OpenFB
(
"dm_vid0_fb"
)
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to open framebuffer (%m)"
);
goto
error
;
}
if
(
ioctl
(
fb
->
i_fd
,
FBIOGET_VSCREENINFO
,
&
fb
->
var_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to get framebuffer info (%m)"
);
goto
error
;
}
fb
->
var_info
.
yres_virtual
=
fb
->
var_info
.
yres
*
NUM_BUFFERS
;
fb
->
var_info
.
bits_per_pixel
=
BPP
;
if
(
ioctl
(
fb
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
fb
->
var_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Can not set fb info (%m)"
);
goto
error
;
}
if
(
fb
->
var_info
.
bits_per_pixel
!=
BPP
)
{
msg_Err
(
p_dec
,
"Can not use requested size (%dx%d at %d bpp)"
,
fb
->
var_info
.
xres
,
fb
->
var_info
.
yres
,
fb
->
var_info
.
bits_per_pixel
);
goto
error
;
}
if
(
ioctl
(
fb
->
i_fd
,
FBIOGET_FSCREENINFO
,
&
fb
->
fix_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to get framebuffer fixed info (%m)"
);
goto
error
;
}
/* Yes, 32bits * 32bits fills 64 bits.
* * Oh and if you find a screen with 16 billions of billions of pixels ...
* * Keep it for yourself. */
uint64_t
i_display_sz
=
fb
->
fix_info
.
line_length
*
fb
->
var_info
.
yres
;
uint64_t
i_display_total_sz
=
fb
->
fix_info
.
line_length
*
fb
->
var_info
.
yres_virtual
;
fb
->
p_map
=
mmap
(
NULL
,
i_display_total_sz
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fb
->
i_fd
,
0
);
if
(
fb
->
p_map
==
MAP_FAILED
)
{
fb
->
p_map
=
NULL
;
/* set to NULL for error handling */
msg_Err
(
p_dec
,
"Memory mapping of framebuffer failed (%m)"
);
goto
error
;
}
/* Clears fb */
unsigned
int
i
;
for
(
i
=
0
;
i
<
i_display_total_sz
/
4
;
i
++
)
((
uint32_t
*
)
fb
->
p_map
)[
i
]
=
0x10801080
;
for
(
i
=
0
;
i
<
NUM_BUFFERS
;
i
++
)
if
(
(
fb
->
p_physbufs
[
i
]
=
Memory_getBufferPhysicalAddress
(
fb
->
p_map
+
i
*
i_display_sz
,
i_display_sz
,
NULL
)
)
==
0
)
{
msg_Err
(
p_dec
,
"Unable to get physical address of buffer "
"%d/%d (%"
PRId64
" bytes)"
,
i
,
NUM_BUFFERS
,
i_display_sz
);
goto
error
;
}
/* Open and setup resizer */
if
(
(
rsz
->
i_fd
=
open
(
"/dev/davinci_resizer"
,
O_RDWR
)
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to open resizer (%m)"
);
goto
error
;
}
rsz
->
p_yuyv
=
NULL
;
rsz
->
i_yuyv
=
0
;
rsz
->
i_height
=
rsz
->
i_width
=
0
;
return
VLC_SUCCESS
;
error:
DavinciClose
(
fb
,
rsz
);
return
VLC_EGENERIC
;
}
void
DavinciClose
(
davinci_fb_t
*
fb
,
davinci_resizer_t
*
rsz
)
{
if
(
fb
->
p_map
)
{
/* Clears fb */
unsigned
int
i
;
uint64_t
i_display_size
=
fb
->
fix_info
.
line_length
*
fb
->
var_info
.
yres_virtual
/
4
;
for
(
i
=
0
;
i
<
i_display_size
;
i
++
)
((
uint32_t
*
)
fb
->
p_map
)[
i
]
=
0x10801080
;
munmap
(
fb
->
p_map
,
i_display_size
);
}
if
(
fb
->
i_fd
!=
-
1
)
close
(
fb
->
i_fd
);
if
(
rsz
->
i_fd
!=
-
1
)
close
(
rsz
->
i_fd
);
rsz
->
i_fd
=
fb
->
i_fd
=
-
1
;
fb
->
p_map
=
NULL
;
}
#endif
/* DAVINCI_HACK */
modules/codec/davinci/resizer.h
0 → 100644
View file @
5c808483
#ifndef RESIZER_H
#define RESIZER_H
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <video/davincifb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <ti/sdo/ce/osal/Memory.h>
#include <inttypes.h>
#include <asm-arm/arch-davinci/davinci_resizer.h>
#include <math.h>
#define NUM_BUFFERS 1
/* XXX: mesure performance with 3 buffers if needed */
#define BPP 16
#define PI 3.1415926535897932384626
typedef
struct
{
int
i_fd
;
struct
fb_var_screeninfo
var_info
;
struct
fb_fix_screeninfo
fix_info
;
uint8_t
*
p_map
;
UInt32
p_physbufs
[
NUM_BUFFERS
];
}
davinci_fb_t
;
typedef
struct
{
int
i_fd
;
unsigned
int
i_height
;
unsigned
int
i_width
;
uint8_t
*
p_yuyv
;
int
offset
;
int
i_yuyv
;
unsigned
int
i_out_width
;
unsigned
int
i_out_height
;
vlc_bool_t
b_direct
;
}
davinci_resizer_t
;
void
Resize_coeff
(
decoder_t
*
,
unsigned
int
*
,
unsigned
int
*
);
int
OpenFB
(
const
char
*
psz_name
);
void
get_coeffs
(
short
[
32
],
unsigned
int
,
unsigned
int
);
void
Resize
(
decoder_t
*
,
vlc_bool_t
,
davinci_resizer_t
*
,
davinci_fb_t
*
,
XDM_BufDesc
);
int
DavinciInit
(
decoder_t
*
,
davinci_fb_t
*
,
davinci_resizer_t
*
);
void
DavinciClose
(
davinci_fb_t
*
,
davinci_resizer_t
*
);
#endif
/* RESIZER_H */
modules/codec/davinci/viddec.c
View file @
5c808483
...
...
@@ -25,31 +25,13 @@
/*****************************************************************************
* Preamble
*****************************************************************************/
#undef _FILE_OFFSET_BITS
/* mmap() fails on 64 bits offsets */
#include "davinci.h"
#include <assert.h>
#include <ti/sdo/ce/video/viddec.h>
#ifdef DAVINCI_HACK
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <video/davincifb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <ti/sdo/ce/osal/Memory.h>
#include <inttypes.h>
#include <asm-arm/arch-davinci/davinci_resizer.h>
#include <math.h>
#define NUM_BUFFERS 1
/* XXX: mesure performance with 3 buffers if needed */
#define BPP 16
#define PI 3.1415926535897932384626
#include "resizer.h"
#endif
/*****************************************************************************
...
...
@@ -69,29 +51,17 @@ struct decoder_sys_t
XDM_BufDesc
in
;
XDM_BufDesc
out
;
decoder_t
*
p_packetizer
;
/* for avc1 -> h264 */
#ifdef DAVINCI_HACK
/* framebuffer */
int
i_fd_fb
;
struct
fb_var_screeninfo
var_info
;
struct
fb_fix_screeninfo
fix_info
;
uint8_t
*
p_fb_map
;
UInt32
p_physbufs
[
NUM_BUFFERS
];
davinci_fb_t
fb
;
/* resizer */
int
i_fd_resizer
;
unsigned
int
i_height
;
unsigned
int
i_width
;
davinci_resizer_t
rsz
;
vlc_bool_t
b_resize
;
vlc_mutex_t
cb_lock
;
uint8_t
*
p_yuyv
;
int
offset
;
int
i_yuyv
;
vlc_bool_t
b_direct
;
/* resize directly in the fb */
unsigned
int
i_out_width
;
unsigned
int
i_out_height
;
#endif
};
...
...
@@ -108,210 +78,6 @@ int fullscreen_cb( vlc_object_t *p_this, const char *psz_var,
return
VLC_SUCCESS
;
}
static
void
Resize_coeff
(
decoder_t
*
p_dec
,
unsigned
int
*
i_width
,
unsigned
int
*
i_height
)
{
unsigned
int
i_vidw
=
p_dec
->
fmt_out
.
video
.
i_width
;
unsigned
int
i_vidh
=
p_dec
->
fmt_out
.
video
.
i_height
;
unsigned
int
i_hratio
=
VOUT_ASPECT_FACTOR
*
*
i_height
/
i_vidh
;
unsigned
int
i_wratio
=
VOUT_ASPECT_FACTOR
*
*
i_width
/
i_vidw
;
msg_Dbg
(
p_dec
,
"Original Video %dx%d, Output destination %dx%d"
,
i_vidw
,
i_vidh
,
*
i_width
,
*
i_height
);
/* Davinci Resizer can only do from x0.25 to x4 */
if
(
i_hratio
>
VOUT_ASPECT_FACTOR
*
4
)
i_hratio
=
VOUT_ASPECT_FACTOR
*
4
;
else
if
(
i_hratio
<
VOUT_ASPECT_FACTOR
/
4
)
i_hratio
=
VOUT_ASPECT_FACTOR
/
4
;
/* do that also for the width */
if
(
i_wratio
>
VOUT_ASPECT_FACTOR
*
4
)
i_wratio
=
VOUT_ASPECT_FACTOR
*
4
;
else
if
(
i_wratio
<
VOUT_ASPECT_FACTOR
/
4
)
i_wratio
=
VOUT_ASPECT_FACTOR
/
4
;
/* choose the minimum for both axes */
i_hratio
=
i_wratio
=
i_hratio
<
i_wratio
?
i_hratio
:
i_wratio
;
/* Now calculate hrsz and vrsz */
int
i_hrsz
=
256
*
VOUT_ASPECT_FACTOR
/
i_wratio
;
int
i_vrsz
=
256
*
VOUT_ASPECT_FACTOR
/
i_hratio
;
/* Then recalculate final resolution */
int
i_htap
=
i_hrsz
>
512
?
7
:
4
;
int
i_vtap
=
i_vrsz
>
512
?
7
:
4
;
*
i_width
=
((
i_vidw
-
7
)
*
256
-
(
i_htap
==
7
?
32
:
16
))
/
i_hrsz
+
1
;
*
i_height
=
((
i_vidh
-
i_vtap
)
*
256
-
(
i_vtap
==
7
?
32
:
16
))
/
i_vrsz
+
1
;
/* width must be a factor of 16 : davinci resizer limitation when doing
* vertical upscaling, 16 bytes per output line
* the bpp is 2 so a factor of 8 should be good but not in practice
*/
*
i_width
=
(
*
i_width
+
15
)
&
~
15
;
msg_Dbg
(
p_dec
,
"Destination fixed to %dx%d"
,
*
i_width
,
*
i_height
);
}
/* open() a framebuffer by its name (NOT device path) */
static
int
OpenFB
(
const
char
*
psz_name
)
{
int
i_fd
=
-
1
;
int
i_tries
=
0
;
/* begin with /dev/fb0 */
char
*
psz_device
;
struct
fb_fix_screeninfo
info
;
do
{
if
(
asprintf
(
&
psz_device
,
"/dev/fb%d"
,
i_tries
++
)
==
-
1
)
return
-
1
;
i_fd
=
open
(
psz_device
,
O_RDWR
);
free
(
psz_device
);
if
(
i_fd
==
-
1
)
return
-
1
;
/* check errno */
if
(
ioctl
(
i_fd
,
FBIOGET_FSCREENINFO
,
&
info
)
==
-
1
)
{
close
(
i_fd
);
continue
;
}
if
(
!
strcmp
(
info
.
id
,
psz_name
)
)
return
i_fd
;
close
(
i_fd
);
}
while
(
1
);
}
static
float
bicubic_core
(
float
s
)
{
if
(
s
<
0
)
s
=
-
s
;
if
(
0
.
<=
s
&&
s
<=
1
.
)
return
1
.
5
*
s
*
s
*
s
-
2
.
5
*
s
*
s
+
1
.;
else
if
(
s
<=
2
.
)
return
-
.
5
*
s
*
s
*
s
+
2
.
5
*
s
*
s
-
4
.
*
s
+
2
.;
else
return
0
.;
}
static
void
get_coeffs
(
short
coefs
[
32
],
unsigned
int
i_in
,
unsigned
int
i_out
)
{
assert
(
i_out
>
1
);
assert
(
i_in
>
7
);
float
f_deinterleave_coef
[
32
];
float
f_windows
[
32
+
1
];
unsigned
int
i_rsz
;
if
(
i_in
==
i_out
)
i_rsz
=
256
;
else
{
i_rsz
=
((
i_in
-
7
)
*
256
)
/
(
i_out
-
1
);
if
(
i_rsz
<=
512
)
{
i_rsz
=
((
i_in
-
4
)
*
256
)
/
(
i_out
-
1
);
if
(
i_rsz
>
512
)
i_rsz
=
512
;
}
}
int
i_nphases
,
i_ntaps
,
i_winlen
,
i_phase_offset
,
i
,
j
;
float
f_fc
;
if
(
i_rsz
>
512
)
{
i_nphases
=
4
;
i_ntaps
=
7
;
i_phase_offset
=
8
;
}
else
{
i_nphases
=
8
;
i_ntaps
=
4
;
i_phase_offset
=
4
;
}
i_winlen
=
i_nphases
*
i_ntaps
;
/* calculating the cut-off frequency, normalized by fs/2 */
f_fc
=
(
i_rsz
<
256
)
?
(
1
.
/
i_nphases
)
:
256
.
/
(
i_rsz
*
i_nphases
);
for
(
i
=
0
;
i
<=
i_winlen
;
i
++
)
f_windows
[
i
]
=
.
42
-
.
5
*
cos
(
2
*
PI
*
i
/
i_winlen
)
+
.
08
*
cos
(
4
*
PI
*
i
/
i_winlen
);
i_nphases
=
8
;
i_ntaps
=
4
;
i_phase_offset
=
4
;
/* calculating the bi-cubic coefficients */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
float
f_alpha
=
((
float
)
i
)
/
i_nphases
;
f_deinterleave_coef
[
i_phase_offset
*
i
]
=
bicubic_core
(
f_alpha
+
1
.
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
1
]
=
bicubic_core
(
f_alpha
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
2
]
=
bicubic_core
(
1
.
-
f_alpha
);
f_deinterleave_coef
[
i_phase_offset
*
i
+
3
]
=
bicubic_core
(
2
.
-
f_alpha
);
}
/* de-interleave into phases */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
/* i=phase */
float
f_gain
=
0
;
for
(
j
=
0
;
j
<
i_ntaps
;
j
++
)
/* j=tap */
f_gain
+=
f_deinterleave_coef
[
i_phase_offset
*
i
+
j
];
for
(
j
=
0
;
j
<
i_ntaps
;
j
++
)
coefs
[
i_phase_offset
*
i
+
j
]
=
(
short
)
(
f_deinterleave_coef
[
i_phase_offset
*
i
+
j
]
*
256
/
f_gain
+
0
.
5
);
if
(
i_ntaps
==
7
)
coefs
[
i_phase_offset
*
i
+
7
]
=
0
.;
}
/* adjust the gain to make it exactly one */
for
(
i
=
0
;
i
<
i_nphases
;
i
++
)
{
int
max
=
coefs
[
i_phase_offset
*
i
];
int
max2
=
0
;
int
index
=
0
;
int
index2
=
0
;
int
total_gain
=
max
;
int
delta
;
for
(
j
=
1
;
j
<
i_ntaps
;
j
++
)
{
total_gain
+=
coefs
[
i_phase_offset
*
i
+
j
];
if
(
abs
(
coefs
[
i_phase_offset
*
i
+
j
]
)
>=
max
)
{
max2
=
max
;
index2
=
index
;
index
=
j
;
max
=
abs
(
coefs
[
i_phase_offset
*
i
+
j
]
);
}
}
delta
=
256
-
total_gain
;
if
(
max
-
max2
<
10
)
{
coefs
[
i_phase_offset
*
i
+
index2
]
+=
(
delta
>>
1
);
coefs
[
i_phase_offset
*
i
+
index
]
+=
(
delta
-
(
delta
>>
1
));
}
else
coefs
[
i_phase_offset
*
i
+
index
]
+=
delta
;
}
if
(
i_rsz
==
256
)
{
/* no resizing, all pass filtering */
for
(
i
=
0
;
i
<
i_nphases
*
i_ntaps
;
i
+=
4
)
{
coefs
[
i
]
=
256
;
coefs
[
i
+
1
]
=
coefs
[
i
+
2
]
=
coefs
[
i
+
3
]
=
0
;
}
}
}
#endif
/*****************************************************************************
...
...
@@ -431,87 +197,12 @@ int OpenVideoDecoder( vlc_object_t *p_this )
p_dec
->
fmt_out
.
video
.
i_aspect
=
p_dec
->
fmt_in
.
video
.
i_aspect
;
#ifdef DAVINCI_HACK
p_sys
->
i_fd_fb
=
p_sys
->
i_fd_resizer
=
-
1
;
/* Open framebuffer */
if
(
(
p_sys
->
i_fd_fb
=
OpenFB
(
"dm_vid0_fb"
)
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to open framebuffer (%m)"
);
goto
error
;
}
if
(
ioctl
(
p_sys
->
i_fd_fb
,
FBIOGET_VSCREENINFO
,
&
p_sys
->
var_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to get framebuffer info (%m)"
);
goto
error
;
}
p_sys
->
var_info
.
yres_virtual
=
p_sys
->
var_info
.
yres
*
NUM_BUFFERS
;
p_sys
->
var_info
.
bits_per_pixel
=
BPP
;
if
(
ioctl
(
p_sys
->
i_fd_fb
,
FBIOPUT_VSCREENINFO
,
&
p_sys
->
var_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Can not set fb info (%m)"
);
goto
error
;
}
if
(
p_sys
->
var_info
.
bits_per_pixel
!=
BPP
)
{
msg_Err
(
p_dec
,
"Can not use requested size (%dx%d at %d bpp)"
,
p_sys
->
var_info
.
xres
,
p_sys
->
var_info
.
yres
,
p_sys
->
var_info
.
bits_per_pixel
);
goto
error
;
}
if
(
ioctl
(
p_sys
->
i_fd_fb
,
FBIOGET_FSCREENINFO
,
&
p_sys
->
fix_info
)
==
-
1
)
{
msg_Err
(
p_dec
,
"Failed to get framebuffer fixed info (%m)"
);
goto
error
;
}
/* Yes, 32bits * 32bits fills 64 bits.
* Oh and if you find a screen with 16 billions of billions of pixels ...
* Keep it for yourself. */
uint64_t
i_display_sz
=
p_sys
->
fix_info
.
line_length
*
p_sys
->
var_info
.
yres
;
uint64_t
i_display_total_sz
=
p_sys
->
fix_info
.
line_length
*
p_sys
->
var_info
.
yres_virtual
;
p_sys
->
p_fb_map
=
mmap
(
NULL
,
i_display_total_sz
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
p_sys
->
i_fd_fb
,
0
);
if
(
p_sys
->
p_fb_map
==
MAP_FAILED
)
{
p_sys
->
p_fb_map
=
NULL
;
/* set to NULL for error handling */
msg_Err
(
p_dec
,
"Memory mapping of framebuffer failed (%m)"
);
goto
error
;
}
/* Clears fb */
unsigned
int
i
;
for
(
i
=
0
;
i
<
i_display_total_sz
/
4
;
i
++
)
((
uint32_t
*
)
p_sys
->
p_fb_map
)[
i
]
=
0x10801080
;
for
(
i
=
0
;
i
<
NUM_BUFFERS
;
i
++
)
if
(
(
p_sys
->
p_physbufs
[
i
]
=
Memory_getBufferPhysicalAddress
(
p_sys
->
p_fb_map
+
i
*
i_display_sz
,
i_display_sz
,
NULL
)
)
==
0
)
{
msg_Err
(
p_dec
,
"Unable to get physical address of buffer "
"%d/%d (%"
PRId64
" bytes)"
,
i
,
NUM_BUFFERS
,
i_display_sz
);
goto
error
;
}
/* Open and setup resizer */
if
(
(
p_sys
->
i_fd_resizer
=
open
(
"/dev/davinci_resizer"
,
O_RDWR
)
)
==
-
1
)
if
(
DavinciInit
(
p_dec
,
&
p_sys
->
fb
,
&
p_sys
->
rsz
)
!=
VLC_SUCCESS
)
{
msg_Err
(
p_dec
,
"
Failed to open resizer (%m)
"
);
msg_Err
(
p_dec
,
"
Initialization of Davinci devices failed
"
);
goto
error
;
}
p_sys
->
p_yuyv
=
NULL
;
p_sys
->
i_yuyv
=
0
;
p_sys
->
i_height
=
p_sys
->
i_width
=
0
;
p_sys
->
b_resize
=
var_CreateGetBool
(
p_dec
,
"davinci-viddec-fullscreen"
);
var_AddCallback
(
p_dec
,
"davinci-viddec-fullscreen"
,
fullscreen_cb
,
p_sys
);
vlc_mutex_init
(
p_this
,
&
p_sys
->
cb_lock
);
...
...
@@ -528,11 +219,6 @@ int OpenVideoDecoder( vlc_object_t *p_this )
error:
if
(
p_sys
->
e
)
Engine_close
(
p_sys
->
e
);
#ifdef DAVINCI_HACK
if
(
p_sys
->
p_fb_map
)
munmap
(
p_sys
->
p_fb_map
,
i_display_total_sz
);
if
(
p_sys
->
i_fd_fb
!=
-
1
)
close
(
p_sys
->
i_fd_fb
);
if
(
p_sys
->
i_fd_resizer
!=
-
1
)
close
(
p_sys
->
i_fd_resizer
);
#endif
free
(
p_sys
);
free
(
psz_codec
);
return
VLC_EGENERIC
;
...
...
@@ -546,6 +232,12 @@ void CloseVideoDecoder( vlc_object_t *p_this )
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
if
(
p_sys
->
p_packetizer
)
{
module_Unneed
(
p_sys
->
p_packetizer
,
p_sys
->
p_packetizer
->
p_module
);
vlc_object_destroy
(
p_sys
->
p_packetizer
);
}
/* Close our codec handle */
VIDDEC_delete
(
p_sys
->
d
);
...
...
@@ -556,19 +248,7 @@ void CloseVideoDecoder( vlc_object_t *p_this )
CERuntime_exit
();
#ifdef DAVINCI_HACK
/* Clears fb */
unsigned
int
i
;
uint64_t
i_display_size
=
p_sys
->
fix_info
.
line_length
*
p_sys
->
var_info
.
yres_virtual
/
4
;
for
(
i
=
0
;
i
<
i_display_size
;
i
++
)
((
uint32_t
*
)
p_sys
->
p_fb_map
)[
i
]
=
0x10801080
;
if
(
p_sys
->
p_fb_map
)
munmap
(
p_sys
->
p_fb_map
,
i_display_size
);
/* Close file descriptors */
close
(
p_sys
->
i_fd_resizer
);
close
(
p_sys
->
i_fd_fb
);
DavinciClose
(
&
p_sys
->
fb
,
&
p_sys
->
rsz
);
vlc_mutex_destroy
(
&
p_sys
->
cb_lock
);
#endif
...
...
@@ -579,185 +259,6 @@ void CloseVideoDecoder( vlc_object_t *p_this )
free
(
p_sys
);
}
#ifdef DAVINCI_HACK
static
void
Resize
(
decoder_t
*
p_dec
,
vlc_bool_t
b_scale
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
if
(
!
p_sys
->
i_yuyv
)
{
/* use screen resolution for the buffer, we may be off by a few */
p_sys
->
i_yuyv
=
p_sys
->
var_info
.
xres
*
p_sys
->
var_info
.
yres_virtual
;
assert
(
p_sys
->
i_yuyv
);
rsz_reqbufs_t
reqbufs
;
rsz_buffer_t
buffer
;
memset
(
&
reqbufs
,
0
,
sizeof
(
reqbufs
)
);
memset
(
&
buffer
,
0
,
sizeof
(
buffer
)
);
reqbufs
.
buf_type
=
RSZ_BUF_OUT
;
reqbufs
.
size
=
p_sys
->
i_yuyv
;
reqbufs
.
count
=
1
;
if
(
ioctl
(
p_sys
->
i_fd_resizer
,
RSZ_REQBUF
,
&
reqbufs
)
)
{
msg_Err
(
p_dec
,
"RSZ_REQBUF failed (%m)"
);
return
;
}
buffer
.
buf_type
=
RSZ_BUF_OUT
;
buffer
.
index
=
0
;
if
(
ioctl
(
p_sys
->
i_fd_resizer
,
RSZ_QUERYBUF
,
&
buffer
)
)
{
msg_Err
(
p_dec
,
"RSZ_QUERYBUF failed (%m)"
);
return
;
}
p_sys
->
offset
=
buffer
.
offset
;
p_sys
->
p_yuyv
=
mmap
(
NULL
,
reqbufs
.
size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
p_sys
->
i_fd_resizer
,
buffer
.
offset
);
if
(
p_sys
->
p_yuyv
==
MAP_FAILED
)
{
p_sys
->
i_yuyv
=
0
;
msg_Err
(
p_dec
,
"mmap to buffer failed (%m)"
);
return
;
}
}
/* Sets resizer parameters when video starts or when resolution changes */
if
(
p_sys
->
i_width
!=
p_dec
->
fmt_out
.
video
.
i_width
||
p_sys
->
i_height
!=
p_dec
->
fmt_out
.
video
.
i_height
)
{
rsz_params_t
rsz_params
;
memset
(
&
rsz_params
,
0
,
sizeof
(
rsz_params
)
);
rsz_params
.
in_hsize
=
p_sys
->
i_width
=
p_dec
->
fmt_out
.
video
.
i_width
;
rsz_params
.
in_vsize
=
p_sys
->
i_height
=
p_dec
->
fmt_out
.
video
.
i_height
;
rsz_params
.
in_pitch
=
(
p_dec
->
fmt_out
.
video
.
i_width
*
BPP
/
8
+
31
)
&
~
31
;
rsz_params
.
inptyp
=
RSZ_INTYPE_YCBCR422_16BIT
;
rsz_params
.
pix_fmt
=
RSZ_PIX_FMT_YUYV
;
/* Sets the desired maximum destination resolution */
if
(
b_scale
)
{
rsz_params
.
out_hsize
=
p_sys
->
var_info
.
xres
;
rsz_params
.
out_vsize
=
p_sys
->
var_info
.
yres
;
}
else
{
rsz_params
.
out_hsize
=
rsz_params
.
in_hsize
;
rsz_params
.
out_vsize
=
rsz_params
.
in_vsize
;
}
/* And then modify it to keep the same aspect ratio, and make sure
* that the hardware is able to handle it */
Resize_coeff
(
p_dec
,
&
rsz_params
.
out_hsize
,
&
rsz_params
.
out_vsize
);
/* RSZ_PIX_FMT_YUYV is 2 bytes per pixel */
rsz_params
.
out_pitch
=
(
rsz_params
.
out_hsize
*
2
+
15
)
&
~
15
;
p_sys
->
b_direct
=
(
unsigned
)
rsz_params
.
out_hsize
==
(
unsigned
)
p_sys
->
var_info
.
xres
;
p_sys
->
i_out_width
=
rsz_params
.
out_hsize
;
p_sys
->
i_out_height
=
rsz_params
.
out_vsize
;
short
hcoefs
[
32
]
=
{
0
,
256
,
0
,
0
,
-
11
,
245
,
23
,
-
1
,
-
17
,
220
,
58
,
-
5
,
-
18
,
184
,
100
,
-
10
,
-
15
,
143
,
143
,
-
15
,
-
10
,
100
,
184
,
-
18
,
-
5
,
58
,
220
,
-
17
,
-
1
,
23
,
245
,
-
11
};
short
vcoefs
[
32
]
=
{
0
,
256
,
0
,
0
,
-
11
,
245
,
23
,
-
1
,
-
17
,
220
,
58
,
-
5
,
-
18
,
184
,
100
,
-
10
,
-
15
,
143
,
143
,
-
15
,
-
10
,
100
,
184
,
-
18
,
-
5
,
58
,
220
,
-
17
,
-
1
,
23
,
245
,
-
11
};
/* HACK HACK HACK : use --davinci-viddec-chroma resize
* to not compute coefficients */
char
*
psz_chroma
=
var_CreateGetString
(
p_dec
,
"davinci-viddec-chroma"
);
if
(
psz_chroma
&&
strcmp
(
psz_chroma
,
"resize"
)
)
{
get_coeffs
(
hcoefs
,
rsz_params
.
in_hsize
,
rsz_params
.
out_hsize
);
get_coeffs
(
vcoefs
,
rsz_params
.
in_vsize
,
rsz_params
.
out_vsize
);
}
free
(
psz_chroma
);
int
i
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
rsz_params
.
hfilt_coeffs
[
i
]
=
hcoefs
[
i
];
rsz_params
.
vfilt_coeffs
[
i
]
=
vcoefs
[
i
];
}
rsz_params
.
yenh_params
.
type
=
RSZ_YENH_DISABLE
;
if
(
ioctl
(
p_sys
->
i_fd_resizer
,
RSZ_S_PARAM
,
&
rsz_params
)
)
{
msg_Err
(
p_dec
,
"Failed setting resizer parameters: "
"%dx%d (pitch %d) -> %dx%d (pitch %d) : %m"
,
rsz_params
.
in_hsize
,
rsz_params
.
in_vsize
,
rsz_params
.
in_pitch
,
rsz_params
.
out_hsize
,
rsz_params
.
out_vsize
,
rsz_params
.
out_pitch
);
p_sys
->
i_width
=
p_sys
->
i_height
=
0
;
return
;
}
}
rsz_resize_t
rsz
;
rsz
.
in_buf
.
index
=
-
1
;
rsz
.
in_buf
.
buf_type
=
RSZ_BUF_IN
;
rsz
.
in_buf
.
size
=
p_dec
->
fmt_out
.
video
.
i_height
*
((
p_dec
->
fmt_out
.
video
.
i_width
*
BPP
/
8
+
31
)
&
~
31
);
rsz
.
in_buf
.
offset
=
Memory_getBufferPhysicalAddress
(
p_sys
->
out
.
bufs
[
0
],
rsz
.
in_buf
.
size
,
NULL
);
assert
(
rsz
.
in_buf
.
offset
);
rsz
.
out_buf
.
index
=
-
1
;
rsz
.
out_buf
.
buf_type
=
RSZ_BUF_OUT
;
if
(
b_scale
&&
p_sys
->
b_direct
/* output video res is screen res */
)
{
/* FIXME: use NUM_BUFFERS if needed */
rsz
.
out_buf
.
offset
=
p_sys
->
p_physbufs
[
0
];
rsz
.
out_buf
.
size
=
p_sys
->
var_info
.
xres
*
p_sys
->
var_info
.
yres_virtual
;
}
else
{
rsz
.
out_buf
.
offset
=
p_sys
->
offset
;
rsz
.
out_buf
.
size
=
p_sys
->
i_yuyv
;
}
do
{
if
(
ioctl
(
p_sys
->
i_fd_resizer
,
RSZ_RESIZE
,
&
rsz
)
==
-
1
)
{
if
(
errno
==
EAGAIN
)
continue
;
msg_Err
(
p_dec
,
"Resizing failed (%m)"
);
return
;
}
}
while
(
0
);
}
#endif
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
...
...
@@ -776,6 +277,28 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
VIDDEC_Status
status
;
int
i
;
if
(
!
p_sys
->
p_packetizer
&&
p_dec
->
fmt_in
.
i_codec
==
VLC_FOURCC
(
'a'
,
'v'
,
'c'
,
'1'
)
)
{
p_sys
->
p_packetizer
=
vlc_object_create
(
p_dec
,
VLC_OBJECT_PACKETIZER
);
if
(
p_sys
->
p_packetizer
)
{
p_sys
->
p_packetizer
->
pf_decode_audio
=
NULL
;
p_sys
->
p_packetizer
->
pf_decode_video
=
NULL
;
p_sys
->
p_packetizer
->
pf_decode_sub
=
NULL
;
p_sys
->
p_packetizer
->
pf_packetize
=
NULL
;
es_format_Copy
(
&
p_sys
->
p_packetizer
->
fmt_in
,
&
p_dec
->
fmt_in
);
p_sys
->
p_packetizer
->
fmt_in
=
p_dec
->
fmt_in
;
p_sys
->
p_packetizer
->
p_module
=
module_Need
(
p_sys
->
p_packetizer
,
"packetizer"
,
NULL
,
0
);
if
(
!
p_sys
->
p_packetizer
->
p_module
)
{
vlc_object_destroy
(
p_sys
->
p_packetizer
);
p_sys
->
p_packetizer
=
NULL
;
}
}
}
if
(
!
pp_block
||
!*
pp_block
)
return
NULL
;
p_block
=
*
pp_block
;
...
...
@@ -785,6 +308,15 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
return
NULL
;
}
if
(
p_sys
->
p_packetizer
&&
!
i_extra
)
{
block_t
*
p_new_block
=
p_sys
->
p_packetizer
->
pf_packetize
(
p_sys
->
p_packetizer
,
&
p_block
);
p_block
=
p_new_block
;
if
(
!
p_block
)
return
NULL
;
}
memset
(
&
in_args
,
0
,
sizeof
(
in_args
)
);
memset
(
&
out_args
,
0
,
sizeof
(
out_args
)
);
...
...
@@ -877,7 +409,7 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
abort();
}
#endif
if
(
i_extra
==
0
&&
p_dec
->
fmt_in
.
i_extra
>
0
)
if
(
!
p_sys
->
p_packetizer
&&
i_extra
==
0
&&
p_dec
->
fmt_in
.
i_extra
>
0
)
{
/* FIXME : doesn't decode, for example, avc1 (avcC) */
msg_Dbg
(
p_dec
,
"Trying again with p_extra"
);
return
DecodeVideoBlockInner
(
p_dec
,
pp_block
,
p_dec
->
fmt_in
.
i_extra
);
...
...
@@ -966,24 +498,24 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
vlc_bool_t
b_resize
=
p_sys
->
b_resize
;
vlc_mutex_unlock
(
&
p_sys
->
cb_lock
);
Resize
(
p_dec
,
b_resize
);
Resize
(
p_dec
,
b_resize
,
&
p_sys
->
rsz
,
&
p_sys
->
fb
,
p_sys
->
out
);
if
(
!
b_resize
||
!
p_sys
->
b_direct
)
if
(
!
b_resize
)
{
uint32_t
black
=
0x88888888
;
/* for vout YUYV */
/* fb */
/* output top & bottom black */
int
i_line_len
=
p_sys
->
var_info
.
xres
*
BPP
/
8
;
/* in bytes */
int
i_nlines
=
p_sys
->
var_info
.
yres
;
/* in lines */
int
i_line_len
=
p_sys
->
fb
.
var_info
.
xres
*
BPP
/
8
;
/* in bytes */
int
i_nlines
=
p_sys
->
fb
.
var_info
.
yres
;
/* in lines */
/* bytes per input line */
int
i_vidw
=
p_sys
->
i_out_width
*
(
BPP
/
8
);
int
i_vidw
=
p_sys
->
rsz
.
i_out_width
*
(
BPP
/
8
);
/* borders */
int
i_sideborder
=
(
i_line_len
-
i_vidw
)
/
2
;
/* in bytes */
int
i_edgeborder
=
/* in lines */
(
i_nlines
-
p_sys
->
i_out_height
)
/
2
;
(
i_nlines
-
p_sys
->
rsz
.
i_out_height
)
/
2
;
int
i
,
j
;
...
...
@@ -994,7 +526,7 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
{
int
lim
=
i_line_len
/
4
;
for
(
j
=
0
;
j
<
lim
;
j
++
)
((
uint32_t
*
)
p_sys
->
p_fb
_map
)[
i
*
lim
+
j
]
=
black
;
((
uint32_t
*
)
p_sys
->
fb
.
p
_map
)[
i
*
lim
+
j
]
=
black
;
}
else
/* draw video */
{
...
...
@@ -1003,23 +535,23 @@ static picture_t *DecodeVideoBlockInner( decoder_t *p_dec, block_t **pp_block, i
/* draw a line */
int
i_vidw_pad
=
(
i_vidw
+
15
)
&
~
15
;
memcpy
(
&
p_sys
->
p_fb
_map
[
i
*
i_line_len
+
i_sideborder
],
&
p_sys
->
p_yuyv
[(
i
-
i_edgeborder
)
*
i_vidw_pad
],
memcpy
(
&
p_sys
->
fb
.
p
_map
[
i
*
i_line_len
+
i_sideborder
],
&
p_sys
->
rsz
.
p_yuyv
[(
i
-
i_edgeborder
)
*
i_vidw_pad
],
i_vidw_pad
);
/* and black borders */
int
p
;
for
(
p
=
0
;
p
<
i_sideborder
/
4
;
p
++
)
((
uint32_t
*
)
p_sys
->
p_fb
_map
)[
i
*
i_line_len
/
4
+
p
]
=
black
;
((
uint32_t
*
)
p_sys
->
fb
.
p
_map
)[
i
*
i_line_len
/
4
+
p
]
=
black
;
for
(
p
=
(
i_line_len
-
i_sideborder
)
/
4
;
p
<
i_line_len
/
4
;
p
++
)
((
uint32_t
*
)
p_sys
->
p_fb
_map
)[
i
*
i_line_len
/
4
+
p
]
=
black
;
((
uint32_t
*
)
p_sys
->
fb
.
p
_map
)[
i
*
i_line_len
/
4
+
p
]
=
black
;
}
}
}
int
i_dummy
;
ioctl
(
p_sys
->
i_fd_fb
,
FBIO_WAITFORVSYNC
,
&
i_dummy
);
/* ignore return */
ioctl
(
p_sys
->
fb
.
i_fd
,
FBIO_WAITFORVSYNC
,
&
i_dummy
);
/* ignore return */
#endif
#ifndef DAVINCI_HACK
...
...
@@ -1038,4 +570,3 @@ error:
block_Release
(
p_block
);
return
NULL
;
}
modules/codec/davinci/videnc.c
View file @
5c808483
...
...
@@ -5,6 +5,7 @@
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan dot org>
* Rafaël Carré <rcarre@m2x.nl>
*
* 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
...
...
@@ -49,6 +50,58 @@ struct encoder_sys_t
/*****************************************************************************
*
*****************************************************************************/
static
void
picfree
(
picture_t
*
p_pic
)
{
if
(
p_pic
->
i_type
==
MEMORY_PICTURE
)
free
(
p_pic
->
p_data_orig
);
free
(
p_pic
);
}
static
picture_t
*
NewEncoderBuffer
(
encoder_t
*
p_enc
,
decoder_t
*
p_dec
)
{
p_dec
->
fmt_out
.
video
.
i_chroma
=
p_dec
->
fmt_out
.
i_codec
;
picture_t
*
p_pic
=
malloc
(
sizeof
(
picture_t
));
if
(
!
p_pic
)
return
NULL
;
if
(
!
p_enc
->
p_sys
->
in
.
numBufs
)
{
vout_AllocatePicture
(
p_dec
,
p_pic
,
p_dec
->
fmt_out
.
video
.
i_chroma
,
p_dec
->
fmt_out
.
video
.
i_width
,
p_dec
->
fmt_out
.
video
.
i_height
,
p_dec
->
fmt_out
.
video
.
i_aspect
);
if
(
!
p_pic
->
i_planes
)
{
free
(
p_pic
);
return
NULL
;
}
p_pic
->
i_type
=
MEMORY_PICTURE
;
}
else
{
p_pic
->
i_planes
=
1
;
vout_InitPicture
(
p_dec
,
p_pic
,
p_dec
->
fmt_out
.
video
.
i_chroma
,
p_dec
->
fmt_out
.
video
.
i_width
,
p_dec
->
fmt_out
.
video
.
i_height
,
p_dec
->
fmt_out
.
video
.
i_aspect
);
p_pic
->
p_data
=
p_enc
->
p_sys
->
in
.
bufs
[
0
];
p_pic
->
p_data_orig
=
NULL
;
p_pic
->
p
[
0
].
p_pixels
=
p_pic
->
p_data
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
}
p_pic
->
pf_release
=
picfree
;
p_pic
->
i_status
=
RESERVED_PICTURE
;
p_pic
->
p_sys
=
NULL
;
return
p_pic
;
}
int
OpenVideoEncoder
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
...
...
@@ -147,6 +200,7 @@ int OpenVideoEncoder( vlc_object_t *p_this )
/* Initialize random stuff */
p_enc
->
pf_encode_video
=
EncodeVideo
;
p_enc
->
pf_enc_buffer_new
=
NewEncoderBuffer
;
free
(
psz_codec
);
return
VLC_SUCCESS
;
...
...
@@ -257,11 +311,16 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic )
/* Copy input picture */
assert
(
p_pic
->
i_planes
==
p_sys
->
in
.
numBufs
);
assert
(
p_pic
->
i_planes
==
1
);
for
(
i
=
0
;
i
<
p_pic
->
i_planes
;
i
++
)
{
plane_t
*
p
=
p_pic
->
p
+
i
;
memcpy
(
p_sys
->
in
.
bufs
[
i
],
p
->
p_pixels
,
p
->
i_pitch
*
p
->
i_visible_lines
);
if
(
p_pic
->
i_type
==
MEMORY_PICTURE
)
{
plane_t
*
p
=
p_pic
->
p
+
i
;
memcpy
(
p_sys
->
in
.
bufs
[
i
],
p
->
p_pixels
,
p
->
i_pitch
*
p
->
i_visible_lines
);
}
/* if it's our direct buffer, we have nothing to do */
}
/* Configure input */
...
...
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