Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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
Hide 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