Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
566858a7
Commit
566858a7
authored
Aug 26, 2012
by
Loren Merritt
Committed by
Loren Merritt
Aug 26, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vf_hqdn3d: support 16bit colordepth
parent
44b0b85f
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
24 deletions
+46
-24
vf_hqdn3d.c
libavfilter/vf_hqdn3d.c
+46
-24
No files found.
libavfilter/vf_hqdn3d.c
View file @
566858a7
...
@@ -35,21 +35,24 @@
...
@@ -35,21 +35,24 @@
#include "video.h"
#include "video.h"
typedef
struct
{
typedef
struct
{
int16_t
coefs
[
4
][
512
*
16
];
int16_t
*
coefs
[
4
];
uint16_t
*
line
;
uint16_t
*
line
;
uint16_t
*
frame_prev
[
3
];
uint16_t
*
frame_prev
[
3
];
double
strength
[
4
];
int
hsub
,
vsub
;
int
hsub
,
vsub
;
int
depth
;
int
depth
;
}
HQDN3DContext
;
}
HQDN3DContext
;
#define LUT_BITS (depth==16 ? 8 : 4)
#define RIGHTSHIFT(a,b) (((a)+(((1<<(b))-1)>>1))>>(b))
#define RIGHTSHIFT(a,b) (((a)+(((1<<(b))-1)>>1))>>(b))
#define LOAD(x) ((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth))
#define LOAD(x) ((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth))
#define STORE(x,val) (depth==8 ? dst[x] = RIGHTSHIFT(val, 16-depth)\
#define STORE(x,val) (depth==8 ? dst[x] = RIGHTSHIFT(val, 16-depth)\
: AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth)))
: AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth)))
static
inline
uint32_t
lowpass
(
int
prev
,
int
cur
,
int16_t
*
coef
)
av_always_inline
static
inline
uint32_t
lowpass
(
int
prev
,
int
cur
,
int16_t
*
coef
,
int
depth
)
{
{
int
d
=
(
prev
-
cur
)
>>
4
;
int
d
=
(
prev
-
cur
)
>>
(
8
-
LUT_BITS
)
;
return
cur
+
coef
[
d
];
return
cur
+
coef
[
d
];
}
}
...
@@ -62,11 +65,11 @@ static void denoise_temporal(uint8_t *src, uint8_t *dst,
...
@@ -62,11 +65,11 @@ static void denoise_temporal(uint8_t *src, uint8_t *dst,
long
x
,
y
;
long
x
,
y
;
uint32_t
tmp
;
uint32_t
tmp
;
temporal
+=
0x1000
;
temporal
+=
256
<<
LUT_BITS
;
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
{
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
LOAD
(
x
),
temporal
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
LOAD
(
x
),
temporal
,
depth
);
STORE
(
x
,
tmp
);
STORE
(
x
,
tmp
);
}
}
src
+=
sstride
;
src
+=
sstride
;
...
@@ -85,15 +88,15 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
...
@@ -85,15 +88,15 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
uint32_t
pixel_ant
;
uint32_t
pixel_ant
;
uint32_t
tmp
;
uint32_t
tmp
;
spatial
+=
0x1000
;
spatial
+=
256
<<
LUT_BITS
;
temporal
+=
0x1000
;
temporal
+=
256
<<
LUT_BITS
;
/* First line has no top neighbor. Only left one for each tmp and
/* First line has no top neighbor. Only left one for each tmp and
* last frame */
* last frame */
pixel_ant
=
LOAD
(
0
);
pixel_ant
=
LOAD
(
0
);
for
(
x
=
0
;
x
<
w
;
x
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
{
line_ant
[
x
]
=
tmp
=
pixel_ant
=
lowpass
(
pixel_ant
,
LOAD
(
x
),
spatial
);
line_ant
[
x
]
=
tmp
=
pixel_ant
=
lowpass
(
pixel_ant
,
LOAD
(
x
),
spatial
,
depth
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
,
depth
);
STORE
(
x
,
tmp
);
STORE
(
x
,
tmp
);
}
}
...
@@ -103,13 +106,13 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
...
@@ -103,13 +106,13 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
frame_ant
+=
w
;
frame_ant
+=
w
;
pixel_ant
=
LOAD
(
0
);
pixel_ant
=
LOAD
(
0
);
for
(
x
=
0
;
x
<
w
-
1
;
x
++
)
{
for
(
x
=
0
;
x
<
w
-
1
;
x
++
)
{
line_ant
[
x
]
=
tmp
=
lowpass
(
line_ant
[
x
],
pixel_ant
,
spatial
);
line_ant
[
x
]
=
tmp
=
lowpass
(
line_ant
[
x
],
pixel_ant
,
spatial
,
depth
);
pixel_ant
=
lowpass
(
pixel_ant
,
LOAD
(
x
+
1
),
spatial
);
pixel_ant
=
lowpass
(
pixel_ant
,
LOAD
(
x
+
1
),
spatial
,
depth
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
,
depth
);
STORE
(
x
,
tmp
);
STORE
(
x
,
tmp
);
}
}
line_ant
[
x
]
=
tmp
=
lowpass
(
line_ant
[
x
],
pixel_ant
,
spatial
);
line_ant
[
x
]
=
tmp
=
lowpass
(
line_ant
[
x
],
pixel_ant
,
spatial
,
depth
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
);
frame_ant
[
x
]
=
tmp
=
lowpass
(
frame_ant
[
x
],
tmp
,
temporal
,
depth
);
STORE
(
x
,
tmp
);
STORE
(
x
,
tmp
);
}
}
}
}
...
@@ -120,6 +123,8 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
...
@@ -120,6 +123,8 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
int
w
,
int
h
,
int
sstride
,
int
dstride
,
int
w
,
int
h
,
int
sstride
,
int
dstride
,
int16_t
*
spatial
,
int16_t
*
temporal
,
int
depth
)
int16_t
*
spatial
,
int16_t
*
temporal
,
int
depth
)
{
{
// FIXME: For 16bit depth, frame_ant could be a pointer to the previous
// filtered frame rather than a separate buffer.
long
x
,
y
;
long
x
,
y
;
uint16_t
*
frame_ant
=
*
frame_ant_ptr
;
uint16_t
*
frame_ant
=
*
frame_ant_ptr
;
if
(
!
frame_ant
)
{
if
(
!
frame_ant
)
{
...
@@ -145,24 +150,28 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
...
@@ -145,24 +150,28 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
case 8: denoise_depth(__VA_ARGS__, 8); break;\
case 8: denoise_depth(__VA_ARGS__, 8); break;\
case 9: denoise_depth(__VA_ARGS__, 9); break;\
case 9: denoise_depth(__VA_ARGS__, 9); break;\
case 10: denoise_depth(__VA_ARGS__, 10); break;\
case 10: denoise_depth(__VA_ARGS__, 10); break;\
case 16: denoise_depth(__VA_ARGS__, 16); break;\
}
}
static
void
precalc_coefs
(
int16_t
*
ct
,
double
dist25
)
static
int16_t
*
precalc_coefs
(
double
dist25
,
int
depth
)
{
{
int
i
;
int
i
;
double
gamma
,
simil
,
C
;
double
gamma
,
simil
,
C
;
int16_t
*
ct
=
av_malloc
((
512
<<
LUT_BITS
)
*
sizeof
(
int16_t
));
if
(
!
ct
)
return
NULL
;
gamma
=
log
(
0
.
25
)
/
log
(
1
.
0
-
FFMIN
(
dist25
,
252
.
0
)
/
255
.
0
-
0
.
00001
);
gamma
=
log
(
0
.
25
)
/
log
(
1
.
0
-
FFMIN
(
dist25
,
252
.
0
)
/
255
.
0
-
0
.
00001
);
for
(
i
=
-
255
*
16
;
i
<=
255
*
16
;
i
++
)
{
for
(
i
=
-
255
<<
LUT_BITS
;
i
<=
255
<<
LUT_BITS
;
i
++
)
{
// lowpass() truncates (not rounds) the diff, so +15/32 for the midpoint of the bin.
double
f
=
((
i
<<
(
9
-
LUT_BITS
))
+
(
1
<<
(
8
-
LUT_BITS
))
-
1
)
/
512
.
0
;
// midpoint of the bin
double
f
=
(
i
+
15
.
0
/
32
.
0
)
/
16
.
0
;
simil
=
1
.
0
-
FFABS
(
f
)
/
255
.
0
;
simil
=
1
.
0
-
FFABS
(
f
)
/
255
.
0
;
C
=
pow
(
simil
,
gamma
)
*
256
.
0
*
f
;
C
=
pow
(
simil
,
gamma
)
*
256
.
0
*
f
;
ct
[
16
*
256
+
i
]
=
lrint
(
C
);
ct
[
(
256
<<
LUT_BITS
)
+
i
]
=
lrint
(
C
);
}
}
ct
[
0
]
=
!!
dist25
;
ct
[
0
]
=
!!
dist25
;
return
ct
;
}
}
#define PARAM1_DEFAULT 4.0
#define PARAM1_DEFAULT 4.0
...
@@ -210,6 +219,11 @@ static int init(AVFilterContext *ctx, const char *args)
...
@@ -210,6 +219,11 @@ static int init(AVFilterContext *ctx, const char *args)
}
}
}
}
hqdn3d
->
strength
[
0
]
=
lum_spac
;
hqdn3d
->
strength
[
1
]
=
lum_tmp
;
hqdn3d
->
strength
[
2
]
=
chrom_spac
;
hqdn3d
->
strength
[
3
]
=
chrom_tmp
;
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"ls:%lf cs:%lf lt:%lf ct:%lf
\n
"
,
av_log
(
ctx
,
AV_LOG_VERBOSE
,
"ls:%lf cs:%lf lt:%lf ct:%lf
\n
"
,
lum_spac
,
chrom_spac
,
lum_tmp
,
chrom_tmp
);
lum_spac
,
chrom_spac
,
lum_tmp
,
chrom_tmp
);
if
(
lum_spac
<
0
||
chrom_spac
<
0
||
isnan
(
chrom_tmp
))
{
if
(
lum_spac
<
0
||
chrom_spac
<
0
||
isnan
(
chrom_tmp
))
{
...
@@ -219,11 +233,6 @@ static int init(AVFilterContext *ctx, const char *args)
...
@@ -219,11 +233,6 @@ static int init(AVFilterContext *ctx, const char *args)
return
AVERROR
(
EINVAL
);
return
AVERROR
(
EINVAL
);
}
}
precalc_coefs
(
hqdn3d
->
coefs
[
0
],
lum_spac
);
precalc_coefs
(
hqdn3d
->
coefs
[
1
],
lum_tmp
);
precalc_coefs
(
hqdn3d
->
coefs
[
2
],
chrom_spac
);
precalc_coefs
(
hqdn3d
->
coefs
[
3
],
chrom_tmp
);
return
0
;
return
0
;
}
}
...
@@ -231,6 +240,10 @@ static void uninit(AVFilterContext *ctx)
...
@@ -231,6 +240,10 @@ static void uninit(AVFilterContext *ctx)
{
{
HQDN3DContext
*
hqdn3d
=
ctx
->
priv
;
HQDN3DContext
*
hqdn3d
=
ctx
->
priv
;
av_freep
(
&
hqdn3d
->
coefs
[
0
]);
av_freep
(
&
hqdn3d
->
coefs
[
1
]);
av_freep
(
&
hqdn3d
->
coefs
[
2
]);
av_freep
(
&
hqdn3d
->
coefs
[
3
]);
av_freep
(
&
hqdn3d
->
line
);
av_freep
(
&
hqdn3d
->
line
);
av_freep
(
&
hqdn3d
->
frame_prev
[
0
]);
av_freep
(
&
hqdn3d
->
frame_prev
[
0
]);
av_freep
(
&
hqdn3d
->
frame_prev
[
1
]);
av_freep
(
&
hqdn3d
->
frame_prev
[
1
]);
...
@@ -256,6 +269,9 @@ static int query_formats(AVFilterContext *ctx)
...
@@ -256,6 +269,9 @@ static int query_formats(AVFilterContext *ctx)
AV_NE
(
PIX_FMT_YUV420P10BE
,
PIX_FMT_YUV420P10LE
),
AV_NE
(
PIX_FMT_YUV420P10BE
,
PIX_FMT_YUV420P10LE
),
AV_NE
(
PIX_FMT_YUV422P10BE
,
PIX_FMT_YUV422P10LE
),
AV_NE
(
PIX_FMT_YUV422P10BE
,
PIX_FMT_YUV422P10LE
),
AV_NE
(
PIX_FMT_YUV444P10BE
,
PIX_FMT_YUV444P10LE
),
AV_NE
(
PIX_FMT_YUV444P10BE
,
PIX_FMT_YUV444P10LE
),
AV_NE
(
PIX_FMT_YUV420P16BE
,
PIX_FMT_YUV420P16LE
),
AV_NE
(
PIX_FMT_YUV422P16BE
,
PIX_FMT_YUV422P16LE
),
AV_NE
(
PIX_FMT_YUV444P16BE
,
PIX_FMT_YUV444P16LE
),
PIX_FMT_NONE
PIX_FMT_NONE
};
};
...
@@ -276,6 +292,12 @@ static int config_input(AVFilterLink *inlink)
...
@@ -276,6 +292,12 @@ static int config_input(AVFilterLink *inlink)
if
(
!
hqdn3d
->
line
)
if
(
!
hqdn3d
->
line
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
hqdn3d
->
coefs
[
i
]
=
precalc_coefs
(
hqdn3d
->
strength
[
i
],
hqdn3d
->
depth
);
if
(
!
hqdn3d
->
coefs
[
i
])
return
AVERROR
(
ENOMEM
);
}
return
0
;
return
0
;
}
}
...
...
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