Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
aom-rav1e
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
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
Xiph.Org
aom-rav1e
Commits
f0a4485e
Commit
f0a4485e
authored
Jan 29, 2016
by
Debargha Mukherjee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor to separate restoration from loop filter
Change-Id: Iab517862d957f3aa2a664e9349d57bbf424febb3
parent
af99a616
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
477 additions
and
434 deletions
+477
-434
vp10/common/loopfilter.c
vp10/common/loopfilter.c
+1
-340
vp10/common/loopfilter.h
vp10/common/loopfilter.h
+1
-89
vp10/common/onyxc_int.h
vp10/common/onyxc_int.h
+4
-0
vp10/common/restoration.c
vp10/common/restoration.c
+351
-0
vp10/common/restoration.h
vp10/common/restoration.h
+107
-0
vp10/decoder/decodeframe.c
vp10/decoder/decodeframe.c
+2
-2
vp10/decoder/decoder.c
vp10/decoder/decoder.c
+3
-0
vp10/encoder/encoder.c
vp10/encoder/encoder.c
+6
-3
vp10/vp10_common.mk
vp10/vp10_common.mk
+2
-0
No files found.
vp10/common/loopfilter.c
View file @
f0a4485e
...
...
@@ -15,6 +15,7 @@
#include "vp10/common/loopfilter.h"
#include "vp10/common/onyxc_int.h"
#include "vp10/common/reconinter.h"
#include "vp10/common/restoration.h"
#include "vpx_dsp/vpx_dsp_common.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
...
...
@@ -215,318 +216,6 @@ static const int mode_lf_lut[MB_MODE_COUNT] = {
#endif // CONFIG_EXT_INTER
};
#if CONFIG_LOOP_RESTORATION
#define RESTORATION_RANGE 256
#define RESTORATION_RANGE_SYM (2 * RESTORATION_RANGE + 1)
static
double
restoration_filters_r_kf
[
RESTORATION_LEVELS_KF
+
1
]
[
RESTORATION_RANGE_SYM
];
static
double
restoration_filters_r
[
RESTORATION_LEVELS
+
1
]
[
RESTORATION_RANGE_SYM
];
static
double
restoration_filters_s_kf
[
RESTORATION_LEVELS_KF
+
1
]
[
RESTORATION_WIN
][
RESTORATION_WIN
];
static
double
restoration_filters_s
[
RESTORATION_LEVELS
+
1
]
[
RESTORATION_WIN
][
RESTORATION_WIN
];
void
vp10_loop_restoration_precal
()
{
int
i
;
for
(
i
=
1
;
i
<
RESTORATION_LEVELS_KF
+
1
;
i
++
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
i
,
1
);
const
int
sigma_x
=
param
.
sigma_x
;
const
int
sigma_y
=
param
.
sigma_y
;
const
int
sigma_r
=
param
.
sigma_r
;
const
double
sigma_r_d
=
(
double
)
sigma_r
/
RESTORATION_PRECISION
;
const
double
sigma_x_d
=
(
double
)
sigma_x
/
RESTORATION_PRECISION
;
const
double
sigma_y_d
=
(
double
)
sigma_y
/
RESTORATION_PRECISION
;
double
*
fr
=
restoration_filters_r_kf
[
i
]
+
RESTORATION_RANGE
;
int
j
,
x
,
y
;
for
(
j
=
0
;
j
<=
RESTORATION_RANGE
;
j
++
)
{
fr
[
j
]
=
exp
(
-
(
j
*
j
)
/
(
2
*
sigma_r_d
*
sigma_r_d
));
fr
[
-
j
]
=
fr
[
j
];
}
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
y
++
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
x
++
)
{
restoration_filters_s_kf
[
i
][
y
+
RESTORATION_HALFWIN
]
[
x
+
RESTORATION_HALFWIN
]
=
exp
(
-
(
x
*
x
)
/
(
2
*
sigma_x_d
*
sigma_x_d
)
-
(
y
*
y
)
/
(
2
*
sigma_y_d
*
sigma_y_d
));
}
}
}
for
(
i
=
1
;
i
<
RESTORATION_LEVELS
+
1
;
i
++
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
i
,
0
);
const
int
sigma_x
=
param
.
sigma_x
;
const
int
sigma_y
=
param
.
sigma_y
;
const
int
sigma_r
=
param
.
sigma_r
;
const
double
sigma_r_d
=
(
double
)
sigma_r
/
RESTORATION_PRECISION
;
const
double
sigma_x_d
=
(
double
)
sigma_x
/
RESTORATION_PRECISION
;
const
double
sigma_y_d
=
(
double
)
sigma_y
/
RESTORATION_PRECISION
;
double
*
fr
=
restoration_filters_r
[
i
]
+
RESTORATION_RANGE
;
int
j
,
x
,
y
;
for
(
j
=
0
;
j
<=
RESTORATION_RANGE
;
j
++
)
{
fr
[
j
]
=
exp
(
-
(
j
*
j
)
/
(
2
*
sigma_r_d
*
sigma_r_d
));
fr
[
-
j
]
=
fr
[
j
];
}
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
y
++
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
x
++
)
{
restoration_filters_s
[
i
][
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
]
=
exp
(
-
(
x
*
x
)
/
(
2
*
sigma_x_d
*
sigma_x_d
)
-
(
y
*
y
)
/
(
2
*
sigma_y_d
*
sigma_y_d
));
}
}
}
}
int
vp10_restoration_level_bits
(
const
VP10_COMMON
*
const
cm
)
{
return
cm
->
frame_type
==
KEY_FRAME
?
RESTORATION_LEVEL_BITS_KF
:
RESTORATION_LEVEL_BITS
;
}
int
vp10_loop_restoration_used
(
int
level
,
int
kf
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
level
,
kf
);
return
(
param
.
sigma_x
&&
param
.
sigma_y
&&
param
.
sigma_r
);
}
void
vp10_loop_restoration_init
(
loop_filter_info_n
*
lfi
,
int
level
,
int
kf
)
{
lfi
->
restoration_used
=
vp10_loop_restoration_used
(
level
,
kf
);
if
(
lfi
->
restoration_used
)
{
int
i
;
lfi
->
wr_lut
=
kf
?
restoration_filters_r_kf
[
level
]
:
restoration_filters_r
[
level
];
for
(
i
=
0
;
i
<
RESTORATION_WIN
;
i
++
)
lfi
->
wx_lut
[
i
]
=
kf
?
restoration_filters_s_kf
[
level
][
i
]
:
restoration_filters_s
[
level
][
i
];
}
}
static
int
is_in_image
(
int
x
,
int
y
,
int
width
,
int
height
)
{
return
(
x
>=
0
&&
x
<
width
&&
y
>=
0
&&
y
<
height
);
}
void
loop_restoration_filter
(
uint8_t
*
data
,
int
width
,
int
height
,
int
stride
,
loop_filter_info_n
*
lfi
,
uint8_t
*
tmpdata
,
int
tmpstride
)
{
int
i
,
j
;
const
double
*
wr_lut_
=
lfi
->
wr_lut
+
RESTORATION_RANGE
;
uint8_t
*
data_p
=
data
;
uint8_t
*
tmpdata_p
=
tmpdata
;
for
(
i
=
0
;
i
<
height
;
++
i
)
{
for
(
j
=
0
;
j
<
width
;
++
j
)
{
int
x
,
y
;
double
flsum
=
0
,
wtsum
=
0
,
wt
;
uint8_t
*
data_p2
=
data_p
+
j
-
RESTORATION_HALFWIN
*
stride
;
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
++
y
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
++
x
)
{
if
(
!
is_in_image
(
j
+
x
,
i
+
y
,
width
,
height
))
continue
;
wt
=
lfi
->
wx_lut
[
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
]
*
wr_lut_
[
data_p2
[
x
]
-
data_p
[
j
]];
wtsum
+=
wt
;
flsum
+=
wt
*
data_p2
[
x
];
}
data_p2
+=
stride
;
}
assert
(
wtsum
>
0
);
tmpdata_p
[
j
]
=
clip_pixel
((
int
)(
flsum
/
wtsum
+
0
.
5
));
}
tmpdata_p
+=
tmpstride
;
data_p
+=
stride
;
}
for
(
i
=
0
;
i
<
height
;
++
i
)
{
memcpy
(
data
+
i
*
stride
,
tmpdata
+
i
*
tmpstride
,
width
*
sizeof
(
*
data
));
}
}
// Normalized non-separable filter where weights all sum to 1
void
loop_restoration_filter_norm
(
uint8_t
*
data
,
int
width
,
int
height
,
int
stride
,
loop_filter_info_n
*
lfi
,
uint8_t
*
tmpdata
,
int
tmpstride
)
{
int
i
,
j
;
uint8_t
*
data_p
=
data
;
uint8_t
*
tmpdata_p
=
tmpdata
;
for
(
i
=
RESTORATION_HALFWIN
;
i
<
height
-
RESTORATION_HALFWIN
;
++
i
)
{
for
(
j
=
RESTORATION_HALFWIN
;
j
<
width
-
RESTORATION_HALFWIN
;
++
j
)
{
int
x
,
y
;
double
flsum
=
0
;
uint8_t
*
data_p2
=
data_p
+
j
-
RESTORATION_HALFWIN
*
stride
;
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
++
y
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
++
x
)
{
flsum
+=
data_p2
[
x
]
*
lfi
->
wx_lut
[
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
];
}
data_p2
+=
stride
;
}
tmpdata_p
[
j
]
=
clip_pixel
((
int
)(
flsum
+
0
.
5
));
}
tmpdata_p
+=
tmpstride
;
data_p
+=
stride
;
}
for
(
i
=
0
;
i
<
height
;
++
i
)
{
memcpy
(
data
+
i
*
stride
,
tmpdata
+
i
*
tmpstride
,
width
*
sizeof
(
*
data
));
}
}
#if CONFIG_VP9_HIGHBITDEPTH
void
loop_restoration_filter_highbd
(
uint8_t
*
data8
,
int
width
,
int
height
,
int
stride
,
loop_filter_info_n
*
lfi
,
uint8_t
*
tmpdata8
,
int
tmpstride
,
int
bit_depth
)
{
int
i
,
j
;
const
double
*
wr_lut_
=
lfi
->
wr_lut
+
RESTORATION_RANGE
;
uint16_t
*
data
=
CONVERT_TO_SHORTPTR
(
data8
);
uint16_t
*
tmpdata
=
CONVERT_TO_SHORTPTR
(
tmpdata8
);
uint16_t
*
data_p
=
data
;
uint16_t
*
tmpdata_p
=
tmpdata
;
for
(
i
=
0
;
i
<
height
;
++
i
)
{
for
(
j
=
0
;
j
<
width
;
++
j
)
{
int
x
,
y
,
diff_r
;
double
flsum
=
0
,
wtsum
=
0
,
wt
;
uint16_t
*
data_p2
=
data_p
+
j
-
RESTORATION_HALFWIN
*
stride
;
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
++
y
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
++
x
)
{
if
(
!
is_in_image
(
j
+
x
,
i
+
y
,
width
,
height
))
continue
;
diff_r
=
(
data_p2
[
x
]
-
data_p
[
j
])
>>
(
bit_depth
-
8
);
assert
(
diff_r
>=
-
RESTORATION_RANGE
&&
diff_r
<=
RESTORATION_RANGE
);
wt
=
lfi
->
wx_lut
[
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
]
*
wr_lut_
[
diff_r
];
wtsum
+=
wt
;
flsum
+=
wt
*
data_p2
[
x
];
}
data_p2
+=
stride
;
}
assert
(
wtsum
>
0
);
tmpdata_p
[
j
]
=
(
int
)(
flsum
/
wtsum
+
0
.
5
);
}
tmpdata_p
+=
tmpstride
;
data_p
+=
stride
;
}
for
(
i
=
0
;
i
<
height
;
++
i
)
{
memcpy
(
data
+
i
*
stride
,
tmpdata
+
i
*
tmpstride
,
width
*
sizeof
(
*
data
));
}
}
// Normalized non-separable filter where weights all sum to 1
void
loop_restoration_filter_norm
(
uint8_t
*
data8
,
int
width
,
int
height
,
int
stride
,
loop_filter_info_n
*
lfi
,
uint8_t
*
tmpdata8
,
int
tmpstride
)
{
int
i
,
j
;
uint16_t
*
data
=
CONVERT_TO_SHORTPTR
(
data8
);
uint16_t
*
tmpdata
=
CONVERT_TO_SHORTPTR
(
tmpdata8
);
uint16_t
*
data_p
=
data
;
uint16_t
*
tmpdata_p
=
tmpdata
;
for
(
i
=
RESTORATION_HALFWIN
;
i
<
height
-
RESTORATION_HALFWIN
;
++
i
)
{
for
(
j
=
RESTORATION_HALFWIN
;
j
<
width
-
RESTORATION_HALFWIN
;
++
j
)
{
int
x
,
y
;
double
flsum
=
0
;
uint16_t
*
data_p2
=
data_p
+
j
-
RESTORATION_HALFWIN
*
stride
;
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
++
y
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
++
x
)
{
flsum
+=
data_p2
[
x
]
*
lfi
->
wx_lut
[
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
];
}
data_p2
+=
stride
;
}
tmpdata_p
[
j
]
=
(
int
)(
flsum
+
0
.
5
);
}
tmpdata_p
+=
tmpstride
;
data_p
+=
stride
;
}
for
(
i
=
0
;
i
<
height
;
++
i
)
{
memcpy
(
data
+
i
*
stride
,
tmpdata
+
i
*
tmpstride
,
width
*
sizeof
(
*
data
));
}
}
#endif // CONFIG_VP9_HIGHBITDEPTH
void
vp10_loop_restoration_rows
(
YV12_BUFFER_CONFIG
*
frame
,
VP10_COMMON
*
cm
,
int
start_mi_row
,
int
end_mi_row
,
int
y_only
)
{
const
int
ywidth
=
frame
->
y_crop_width
;
const
int
ystride
=
frame
->
y_stride
;
const
int
uvwidth
=
frame
->
uv_crop_width
;
const
int
uvstride
=
frame
->
uv_stride
;
const
int
ystart
=
start_mi_row
<<
MI_SIZE_LOG2
;
const
int
uvstart
=
ystart
>>
cm
->
subsampling_y
;
int
yend
=
end_mi_row
<<
MI_SIZE_LOG2
;
int
uvend
=
yend
>>
cm
->
subsampling_y
;
YV12_BUFFER_CONFIG
*
tmp_buf
;
yend
=
VPXMIN
(
yend
,
cm
->
height
);
uvend
=
VPXMIN
(
uvend
,
cm
->
subsampling_y
?
(
cm
->
height
+
1
)
>>
1
:
cm
->
height
);
if
(
vpx_realloc_frame_buffer
(
&
cm
->
tmp_loop_buf
,
cm
->
width
,
cm
->
height
,
cm
->
subsampling_x
,
cm
->
subsampling_y
,
#if CONFIG_VP9_HIGHBITDEPTH
cm
->
use_highbitdepth
,
#endif
VP9_DEC_BORDER_IN_PIXELS
,
cm
->
byte_alignment
,
NULL
,
NULL
,
NULL
)
<
0
)
vpx_internal_error
(
&
cm
->
error
,
VPX_CODEC_MEM_ERROR
,
"Failed to allocate tmp restoration buffer"
);
tmp_buf
=
&
cm
->
tmp_loop_buf
;
#if CONFIG_VP9_HIGHBITDEPTH
if
(
cm
->
use_highbitdepth
)
loop_restoration_filter_highbd
(
frame
->
y_buffer
+
ystart
*
ystride
,
ywidth
,
yend
-
ystart
,
ystride
,
&
cm
->
lf_info
,
tmp_buf
->
y_buffer
+
ystart
*
tmp_buf
->
y_stride
,
tmp_buf
->
y_stride
,
cm
->
bit_depth
);
else
#endif // CONFIG_VP9_HIGHBITDEPTH
loop_restoration_filter
(
frame
->
y_buffer
+
ystart
*
ystride
,
ywidth
,
yend
-
ystart
,
ystride
,
&
cm
->
lf_info
,
tmp_buf
->
y_buffer
+
ystart
*
tmp_buf
->
y_stride
,
tmp_buf
->
y_stride
);
if
(
!
y_only
)
{
#if CONFIG_VP9_HIGHBITDEPTH
if
(
cm
->
use_highbitdepth
)
{
loop_restoration_filter_highbd
(
frame
->
u_buffer
+
uvstart
*
uvstride
,
uvwidth
,
uvend
-
uvstart
,
uvstride
,
&
cm
->
lf_info
,
tmp_buf
->
u_buffer
+
uvstart
*
tmp_buf
->
uv_stride
,
tmp_buf
->
uv_stride
,
cm
->
bit_depth
);
loop_restoration_filter_highbd
(
frame
->
v_buffer
+
uvstart
*
uvstride
,
uvwidth
,
uvend
-
uvstart
,
uvstride
,
&
cm
->
lf_info
,
tmp_buf
->
v_buffer
+
uvstart
*
tmp_buf
->
uv_stride
,
tmp_buf
->
uv_stride
,
cm
->
bit_depth
);
}
else
{
#endif // CONFIG_VP9_HIGHBITDEPTH
loop_restoration_filter
(
frame
->
u_buffer
+
uvstart
*
uvstride
,
uvwidth
,
uvend
-
uvstart
,
uvstride
,
&
cm
->
lf_info
,
tmp_buf
->
u_buffer
+
uvstart
*
tmp_buf
->
uv_stride
,
tmp_buf
->
uv_stride
);
loop_restoration_filter
(
frame
->
v_buffer
+
uvstart
*
uvstride
,
uvwidth
,
uvend
-
uvstart
,
uvstride
,
&
cm
->
lf_info
,
tmp_buf
->
v_buffer
+
uvstart
*
tmp_buf
->
uv_stride
,
tmp_buf
->
uv_stride
);
#if CONFIG_VP9_HIGHBITDEPTH
}
#endif // CONFIG_VP9_HIGHBITDEPTH
}
}
#endif // CONFIG_LOOP_RESTORATION
static
void
update_sharpness
(
loop_filter_info_n
*
lfi
,
int
sharpness_lvl
)
{
int
lvl
;
...
...
@@ -567,10 +256,6 @@ void vp10_loop_filter_init(VP10_COMMON *cm) {
// init hev threshold const vectors
for
(
lvl
=
0
;
lvl
<=
MAX_LOOP_FILTER
;
lvl
++
)
memset
(
lfi
->
lfthr
[
lvl
].
hev_thr
,
(
lvl
>>
4
),
SIMD_WIDTH
);
#if CONFIG_LOOP_RESTORATION
vp10_loop_restoration_precal
();
#endif // CONFIG_LOOP_RESTORATION
}
void
vp10_loop_filter_frame_init
(
VP10_COMMON
*
cm
,
int
default_filt_lvl
)
{
...
...
@@ -2040,30 +1725,6 @@ void vp10_loop_filter_data_reset(
memcpy
(
lf_data
->
planes
,
planes
,
sizeof
(
lf_data
->
planes
));
}
#if CONFIG_LOOP_RESTORATION
void
vp10_loop_restoration_frame
(
YV12_BUFFER_CONFIG
*
frame
,
VP10_COMMON
*
cm
,
int
restoration_level
,
int
y_only
,
int
partial_frame
)
{
int
start_mi_row
,
end_mi_row
,
mi_rows_to_filter
;
// const int loop_restoration_used = vp10_loop_restoration_used(
// restoration_level, cm->frame_type == KEY_FRAME);
vp10_loop_restoration_init
(
&
cm
->
lf_info
,
restoration_level
,
cm
->
frame_type
==
KEY_FRAME
);
if
(
!
cm
->
lf_info
.
restoration_used
)
return
;
start_mi_row
=
0
;
mi_rows_to_filter
=
cm
->
mi_rows
;
if
(
partial_frame
&&
cm
->
mi_rows
>
8
)
{
start_mi_row
=
cm
->
mi_rows
>>
1
;
start_mi_row
&=
0xfffffff8
;
mi_rows_to_filter
=
VPXMAX
(
cm
->
mi_rows
/
8
,
8
);
}
end_mi_row
=
start_mi_row
+
mi_rows_to_filter
;
vp10_loop_restoration_rows
(
frame
,
cm
,
start_mi_row
,
end_mi_row
,
y_only
);
}
#endif // CONFIG_LOOP_RESTORATION
int
vp10_loop_filter_worker
(
LFWorkerData
*
const
lf_data
,
void
*
unused
)
{
(
void
)
unused
;
vp10_loop_filter_rows
(
lf_data
->
frame_buffer
,
lf_data
->
cm
,
lf_data
->
planes
,
...
...
vp10/common/loopfilter.h
View file @
f0a4485e
...
...
@@ -15,6 +15,7 @@
#include "./vpx_config.h"
#include "vp10/common/blockd.h"
#include "vp10/common/restoration.h"
#include "vp10/common/seg_common.h"
#ifdef __cplusplus
...
...
@@ -28,69 +29,6 @@ extern "C" {
#define MAX_MODE_LF_DELTAS 2
#if CONFIG_LOOP_RESTORATION
#define RESTORATION_LEVEL_BITS_KF 4
#define RESTORATION_LEVELS_KF (1 << RESTORATION_LEVEL_BITS_KF)
#define RESTORATION_LEVEL_BITS 3
#define RESTORATION_LEVELS (1 << RESTORATION_LEVEL_BITS)
#define DEF_RESTORATION_LEVEL 2
#define RESTORATION_PRECISION 16
#define RESTORATION_HALFWIN 3
#define RESTORATION_WIN (2 * RESTORATION_HALFWIN + 1)
typedef
struct
restoration_params
{
int
sigma_x
;
// spatial variance x
int
sigma_y
;
// spatial variance y
int
sigma_r
;
// range variance
}
restoration_params_t
;
static
restoration_params_t
restoration_level_to_params_arr
[
RESTORATION_LEVELS
+
1
]
=
{
// Values are rounded to 1/16 th precision
{
0
,
0
,
0
},
// 0 - default
{
8
,
9
,
30
},
{
9
,
8
,
30
},
{
9
,
11
,
32
},
{
11
,
9
,
32
},
{
14
,
14
,
32
},
{
18
,
18
,
36
},
{
24
,
24
,
40
},
{
32
,
32
,
40
},
};
static
restoration_params_t
restoration_level_to_params_arr_kf
[
RESTORATION_LEVELS_KF
+
1
]
=
{
// Values are rounded to 1/16 th precision
{
0
,
0
,
0
},
// 0 - default
{
8
,
8
,
30
},
{
9
,
9
,
32
},
{
10
,
10
,
32
},
{
12
,
12
,
32
},
{
14
,
14
,
32
},
{
18
,
18
,
36
},
{
24
,
24
,
40
},
{
30
,
30
,
44
},
{
36
,
36
,
48
},
{
42
,
42
,
48
},
{
48
,
48
,
48
},
{
48
,
48
,
56
},
{
56
,
56
,
48
},
{
56
,
56
,
56
},
{
56
,
56
,
64
},
{
64
,
64
,
48
},
};
int
vp10_restoration_level_bits
(
const
struct
VP10Common
*
const
cm
);
int
vp10_loop_restoration_used
(
int
level
,
int
kf
);
static
INLINE
restoration_params_t
vp10_restoration_level_to_params
(
int
index
,
int
kf
)
{
return
kf
?
restoration_level_to_params_arr_kf
[
index
]
:
restoration_level_to_params_arr
[
index
];
}
#endif // CONFIG_LOOP_RESTORATION
enum
lf_path
{
LF_PATH_420
,
LF_PATH_444
,
...
...
@@ -132,14 +70,6 @@ typedef struct {
typedef
struct
{
loop_filter_thresh
lfthr
[
MAX_LOOP_FILTER
+
1
];
uint8_t
lvl
[
MAX_SEGMENTS
][
MAX_REF_FRAMES
][
MAX_MODE_LF_DELTAS
];
#if CONFIG_LOOP_RESTORATION
double
*
wx_lut
[
RESTORATION_WIN
];
double
*
wr_lut
;
int
restoration_sigma_x_set
;
int
restoration_sigma_y_set
;
int
restoration_sigma_r_set
;
int
restoration_used
;
#endif // CONFIG_LOOP_RESTORATION
}
loop_filter_info_n
;
// This structure holds bit masks for all 8x8 blocks in a 64x64 region.
...
...
@@ -209,24 +139,6 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
struct
macroblockd_plane
planes
[
MAX_MB_PLANE
],
int
start
,
int
stop
,
int
y_only
);
#if CONFIG_LOOP_RESTORATION
void
vp10_loop_restoration_frame
(
YV12_BUFFER_CONFIG
*
frame
,
struct
VP10Common
*
cm
,
int
restoration_level
,
int
y_only
,
int
partial_frame
);
void
vp10_loop_filter_restoration_frame
(
YV12_BUFFER_CONFIG
*
frame
,
struct
VP10Common
*
cm
,
struct
macroblockd
*
mbd
,
int
frame_filter_level
,
int
restoration_level
,
int
y_only
,
int
partial_frame
);
void
vp10_loop_restoration_init
(
loop_filter_info_n
*
lfi
,
int
T
,
int
kf
);
void
vp10_loop_restoration_rows
(
YV12_BUFFER_CONFIG
*
frame
,
struct
VP10Common
*
cm
,
int
start_mi_row
,
int
end_mi_row
,
int
y_only
);
#endif // CONFIG_LOOP_RESTORATION
typedef
struct
LoopFilterWorkerData
{
YV12_BUFFER_CONFIG
*
frame_buffer
;
struct
VP10Common
*
cm
;
...
...
vp10/common/onyxc_int.h
View file @
f0a4485e
...
...
@@ -24,6 +24,7 @@
#include "vp10/common/frame_buffers.h"
#include "vp10/common/quant_common.h"
#include "vp10/common/tile_common.h"
#include "vp10/common/restoration.h"
#if CONFIG_VP9_POSTPROC
#include "vp10/common/postproc.h"
...
...
@@ -255,6 +256,9 @@ typedef struct VP10Common {
INTERP_FILTER
interp_filter
;
loop_filter_info_n
lf_info
;
#if CONFIG_LOOP_RESTORATION
restoration_info_n
rst_info
;
#endif // CONFIG_LOOP_RESTORATION
// Flag signaling how frame contexts should be updated at the end of
// a frame decode
...
...
vp10/common/restoration.c
0 → 100644
View file @
f0a4485e
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "vp10/common/onyxc_int.h"
#include "vp10/common/restoration.h"
#include "vpx_dsp/vpx_dsp_common.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
#define RESTORATION_RANGE 256
#define RESTORATION_RANGE_SYM (2 * RESTORATION_RANGE + 1)
static
double
restoration_filters_r_kf
[
RESTORATION_LEVELS_KF
+
1
]
[
RESTORATION_RANGE_SYM
];
static
double
restoration_filters_r
[
RESTORATION_LEVELS
+
1
]
[
RESTORATION_RANGE_SYM
];
static
double
restoration_filters_s_kf
[
RESTORATION_LEVELS_KF
+
1
]
[
RESTORATION_WIN
][
RESTORATION_WIN
];
static
double
restoration_filters_s
[
RESTORATION_LEVELS
+
1
]
[
RESTORATION_WIN
][
RESTORATION_WIN
];
void
vp10_loop_restoration_precal
()
{
int
i
;
for
(
i
=
1
;
i
<
RESTORATION_LEVELS_KF
+
1
;
i
++
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
i
,
1
);
const
int
sigma_x
=
param
.
sigma_x
;
const
int
sigma_y
=
param
.
sigma_y
;
const
int
sigma_r
=
param
.
sigma_r
;
const
double
sigma_r_d
=
(
double
)
sigma_r
/
RESTORATION_PRECISION
;
const
double
sigma_x_d
=
(
double
)
sigma_x
/
RESTORATION_PRECISION
;
const
double
sigma_y_d
=
(
double
)
sigma_y
/
RESTORATION_PRECISION
;
double
*
fr
=
restoration_filters_r_kf
[
i
]
+
RESTORATION_RANGE
;
int
j
,
x
,
y
;
for
(
j
=
0
;
j
<=
RESTORATION_RANGE
;
j
++
)
{
fr
[
j
]
=
exp
(
-
(
j
*
j
)
/
(
2
*
sigma_r_d
*
sigma_r_d
));
fr
[
-
j
]
=
fr
[
j
];
}
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
y
++
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
x
++
)
{
restoration_filters_s_kf
[
i
][
y
+
RESTORATION_HALFWIN
]
[
x
+
RESTORATION_HALFWIN
]
=
exp
(
-
(
x
*
x
)
/
(
2
*
sigma_x_d
*
sigma_x_d
)
-
(
y
*
y
)
/
(
2
*
sigma_y_d
*
sigma_y_d
));
}
}
}
for
(
i
=
1
;
i
<
RESTORATION_LEVELS
+
1
;
i
++
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
i
,
0
);
const
int
sigma_x
=
param
.
sigma_x
;
const
int
sigma_y
=
param
.
sigma_y
;
const
int
sigma_r
=
param
.
sigma_r
;
const
double
sigma_r_d
=
(
double
)
sigma_r
/
RESTORATION_PRECISION
;
const
double
sigma_x_d
=
(
double
)
sigma_x
/
RESTORATION_PRECISION
;
const
double
sigma_y_d
=
(
double
)
sigma_y
/
RESTORATION_PRECISION
;
double
*
fr
=
restoration_filters_r
[
i
]
+
RESTORATION_RANGE
;
int
j
,
x
,
y
;
for
(
j
=
0
;
j
<=
RESTORATION_RANGE
;
j
++
)
{
fr
[
j
]
=
exp
(
-
(
j
*
j
)
/
(
2
*
sigma_r_d
*
sigma_r_d
));
fr
[
-
j
]
=
fr
[
j
];
}
for
(
y
=
-
RESTORATION_HALFWIN
;
y
<=
RESTORATION_HALFWIN
;
y
++
)
{
for
(
x
=
-
RESTORATION_HALFWIN
;
x
<=
RESTORATION_HALFWIN
;
x
++
)
{
restoration_filters_s
[
i
][
y
+
RESTORATION_HALFWIN
][
x
+
RESTORATION_HALFWIN
]
=
exp
(
-
(
x
*
x
)
/
(
2
*
sigma_x_d
*
sigma_x_d
)
-
(
y
*
y
)
/
(
2
*
sigma_y_d
*
sigma_y_d
));
}
}
}
}
int
vp10_restoration_level_bits
(
const
VP10_COMMON
*
const
cm
)
{
return
cm
->
frame_type
==
KEY_FRAME
?
RESTORATION_LEVEL_BITS_KF
:
RESTORATION_LEVEL_BITS
;
}
int
vp10_loop_restoration_used
(
int
level
,
int
kf
)
{
const
restoration_params_t
param
=
vp10_restoration_level_to_params
(
level
,
kf
);
return
(
param
.
sigma_x
&&
param
.
sigma_y
&&
param
.
sigma_r
);
}
void
vp10_loop_restoration_init
(
restoration_info_n
*
rst
,
int
level
,
int
kf
)
{
rst
->
restoration_used
=
vp10_loop_restoration_used
(
level
,
kf
);