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
7b43120c
Commit
7b43120c
authored
Apr 24, 2013
by
Clément Bœsch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: add dctdnoiz filter.
parent
48de04f4
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
489 additions
and
1 deletion
+489
-1
Changelog
Changelog
+1
-0
configure
configure
+1
-0
filters.texi
doc/filters.texi
+53
-0
Makefile
libavfilter/Makefile
+1
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
vf_dctdnoiz.c
libavfilter/vf_dctdnoiz.c
+431
-0
No files found.
Changelog
View file @
7b43120c
...
@@ -46,6 +46,7 @@ version <next>:
...
@@ -46,6 +46,7 @@ version <next>:
- RedSpark demuxer
- RedSpark demuxer
- ADPCM IMA Radical decoder
- ADPCM IMA Radical decoder
- zmq filters
- zmq filters
- DCT denoiser filter (dctdnoiz)
version 1.2:
version 1.2:
...
...
configure
View file @
7b43120c
...
@@ -2129,6 +2129,7 @@ blackframe_filter_deps="gpl"
...
@@ -2129,6 +2129,7 @@ blackframe_filter_deps="gpl"
boxblur_filter_deps
=
"gpl"
boxblur_filter_deps
=
"gpl"
colormatrix_filter_deps
=
"gpl"
colormatrix_filter_deps
=
"gpl"
cropdetect_filter_deps
=
"gpl"
cropdetect_filter_deps
=
"gpl"
dctdnoiz_filter_deps
=
"avcodec"
delogo_filter_deps
=
"gpl"
delogo_filter_deps
=
"gpl"
deshake_filter_deps
=
"avcodec"
deshake_filter_deps
=
"avcodec"
deshake_filter_select
=
"dsputil"
deshake_filter_select
=
"dsputil"
...
...
doc/filters.texi
View file @
7b43120c
...
@@ -2655,6 +2655,59 @@ curves=psfile='MyCurvesPresets/purple.asv':green='0.45/0.53'
...
@@ -2655,6 +2655,59 @@ curves=psfile='MyCurvesPresets/purple.asv':green='0.45/0.53'
@end example
@end example
@end itemize
@end itemize
@section dctdnoiz
Denoise frames using 2D DCT (frequency domain filtering).
This filter is not designed for real time and can be extremely slow.
The filter accepts the following options:
@table @option
@item sigma, s
Set the noise sigma constant.
This @var{sigma} defines a hard threshold of @code{3 * sigma}; every DCT
coefficient (absolute value) below this threshold with be dropped.
If you need a more advanced filtering, see @option{expr}.
Default is @code{0}.
@item overlap
Set number overlapping pixels for each block. Each block is of size
@code{16x16}. Since the filter can be slow, you may want to reduce this value,
at the cost of a less effective filter and the risk of various artefacts.
If the overlapping value doesn't allow to process the whole input width or
height, a warning will be displayed and according borders won't be denoised.
Default value is @code{15}.
@item expr, e
Set the coefficient factor expression.
For each coefficient of a DCT block, this expression will be evaluated as a
multiplier value for the coefficient.
If this is option is set, the @option{sigma} option will be ignored.
The absolute value of the coefficient can be accessed through the @var{c}
variable.
@end table
@subsection Examples
Apply a denoise with a @option{sigma} of @code{4.5}:
@example
dctdnoiz=4.5
@end example
The same operation can be achieved using the expression system:
@example
dctdnoiz=e='gte(c, 4.5*3)'
@end example
@anchor{decimate}
@anchor{decimate}
@section decimate
@section decimate
...
...
libavfilter/Makefile
View file @
7b43120c
...
@@ -116,6 +116,7 @@ OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o
...
@@ -116,6 +116,7 @@ OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o
OBJS-$(CONFIG_CROP_FILTER)
+=
vf_crop.o
OBJS-$(CONFIG_CROP_FILTER)
+=
vf_crop.o
OBJS-$(CONFIG_CROPDETECT_FILTER)
+=
vf_cropdetect.o
OBJS-$(CONFIG_CROPDETECT_FILTER)
+=
vf_cropdetect.o
OBJS-$(CONFIG_CURVES_FILTER)
+=
vf_curves.o
OBJS-$(CONFIG_CURVES_FILTER)
+=
vf_curves.o
OBJS-$(CONFIG_DCTDNOIZ_FILTER)
+=
vf_dctdnoiz.o
OBJS-$(CONFIG_DECIMATE_FILTER)
+=
vf_decimate.o
OBJS-$(CONFIG_DECIMATE_FILTER)
+=
vf_decimate.o
OBJS-$(CONFIG_DELOGO_FILTER)
+=
vf_delogo.o
OBJS-$(CONFIG_DELOGO_FILTER)
+=
vf_delogo.o
OBJS-$(CONFIG_DESHAKE_FILTER)
+=
vf_deshake.o
OBJS-$(CONFIG_DESHAKE_FILTER)
+=
vf_deshake.o
...
...
libavfilter/allfilters.c
View file @
7b43120c
...
@@ -114,6 +114,7 @@ void avfilter_register_all(void)
...
@@ -114,6 +114,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
CROP
,
crop
,
vf
);
REGISTER_FILTER
(
CROP
,
crop
,
vf
);
REGISTER_FILTER
(
CROPDETECT
,
cropdetect
,
vf
);
REGISTER_FILTER
(
CROPDETECT
,
cropdetect
,
vf
);
REGISTER_FILTER
(
CURVES
,
curves
,
vf
);
REGISTER_FILTER
(
CURVES
,
curves
,
vf
);
REGISTER_FILTER
(
DCTDNOIZ
,
dctdnoiz
,
vf
);
REGISTER_FILTER
(
DECIMATE
,
decimate
,
vf
);
REGISTER_FILTER
(
DECIMATE
,
decimate
,
vf
);
REGISTER_FILTER
(
DELOGO
,
delogo
,
vf
);
REGISTER_FILTER
(
DELOGO
,
delogo
,
vf
);
REGISTER_FILTER
(
DESHAKE
,
deshake
,
vf
);
REGISTER_FILTER
(
DESHAKE
,
deshake
,
vf
);
...
...
libavfilter/version.h
View file @
7b43120c
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#include "libavutil/avutil.h"
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 6
6
#define LIBAVFILTER_VERSION_MINOR 6
7
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
...
...
libavfilter/vf_dctdnoiz.c
0 → 100644
View file @
7b43120c
/*
* Copyright (c) 2013 Clément Bœsch
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* A simple, relatively efficient and extremely slow DCT image denoiser.
* @see http://www.ipol.im/pub/art/2011/ys-dct/
*/
#include "libavcodec/avfft.h"
#include "libavutil/eval.h"
#include "libavutil/opt.h"
#include "drawutils.h"
#include "internal.h"
#define NBITS 4
#define BSIZE (1<<(NBITS))
static
const
char
*
const
var_names
[]
=
{
"c"
,
NULL
};
enum
{
VAR_C
,
VAR_VARS_NB
};
typedef
struct
{
const
AVClass
*
class
;
/* coefficient factor expression */
char
*
expr_str
;
AVExpr
*
expr
;
double
var_values
[
VAR_VARS_NB
];
int
pr_width
,
pr_height
;
// width and height to process
float
sigma
;
// used when no expression are st
float
th
;
// threshold (3*sigma)
float
color_dct
[
3
][
3
];
// 3x3 DCT for color decorrelation
float
*
cbuf
[
2
][
3
];
// two planar rgb color buffers
float
*
weights
;
// dct coeff are cumulated with overlapping; these values are used for averaging
int
p_linesize
;
// line sizes for color and weights
int
overlap
;
// number of block overlapping pixels
int
step
;
// block step increment (BSIZE - overlap)
DCTContext
*
dct
,
*
idct
;
// DCT and inverse DCT contexts
float
*
block
,
*
tmp_block
;
// two BSIZE x BSIZE block buffers
}
DCTdnoizContext
;
#define OFFSET(x) offsetof(DCTdnoizContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static
const
AVOption
dctdnoiz_options
[]
=
{
{
"sigma"
,
"set noise sigma constant"
,
OFFSET
(
sigma
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
},
0
,
999
,
.
flags
=
FLAGS
},
{
"s"
,
"set noise sigma constant"
,
OFFSET
(
sigma
),
AV_OPT_TYPE_FLOAT
,
{.
dbl
=
0
},
0
,
999
,
.
flags
=
FLAGS
},
{
"overlap"
,
"set number of block overlapping pixels"
,
OFFSET
(
overlap
),
AV_OPT_TYPE_INT
,
{.
i64
=
(
1
<<
NBITS
)
-
1
},
0
,
(
1
<<
NBITS
)
-
1
,
.
flags
=
FLAGS
},
{
"expr"
,
"set coefficient factor expression"
,
OFFSET
(
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
.
flags
=
FLAGS
},
{
"e"
,
"set coefficient factor expression"
,
OFFSET
(
expr_str
),
AV_OPT_TYPE_STRING
,
{.
str
=
NULL
},
.
flags
=
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
dctdnoiz
);
static
float
*
dct_block
(
DCTdnoizContext
*
ctx
,
const
float
*
src
,
int
src_linesize
)
{
int
x
,
y
;
float
*
column
;
for
(
y
=
0
;
y
<
BSIZE
;
y
++
)
{
float
*
line
=
ctx
->
block
;
memcpy
(
line
,
src
,
BSIZE
*
sizeof
(
*
line
));
src
+=
src_linesize
;
av_dct_calc
(
ctx
->
dct
,
line
);
column
=
ctx
->
tmp_block
+
y
;
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
{
*
line
*=
x
==
0
?
1
.
/
sqrt
(
BSIZE
)
:
sqrt
(
2
.
/
BSIZE
);
*
column
=
*
line
++
;
column
+=
BSIZE
;
}
}
column
=
ctx
->
tmp_block
;
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
{
av_dct_calc
(
ctx
->
dct
,
column
);
for
(
y
=
0
;
y
<
BSIZE
;
y
++
)
column
[
y
]
*=
y
==
0
?
1
.
/
sqrt
(
BSIZE
)
:
sqrt
(
2
.
/
BSIZE
);
column
+=
BSIZE
;
}
for
(
y
=
0
;
y
<
BSIZE
;
y
++
)
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
ctx
->
block
[
y
*
BSIZE
+
x
]
=
ctx
->
tmp_block
[
x
*
BSIZE
+
y
];
return
ctx
->
block
;
}
static
void
idct_block
(
DCTdnoizContext
*
ctx
,
float
*
dst
,
int
dst_linesize
)
{
int
x
,
y
;
float
*
block
=
ctx
->
block
;
float
*
tmp
=
ctx
->
tmp_block
;
for
(
y
=
0
;
y
<
BSIZE
;
y
++
)
{
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
block
[
x
]
*=
x
==
0
?
sqrt
(
BSIZE
)
:
1
.
/
sqrt
(
2
.
/
BSIZE
);
av_dct_calc
(
ctx
->
idct
,
block
);
block
+=
BSIZE
;
}
block
=
ctx
->
block
;
for
(
y
=
0
;
y
<
BSIZE
;
y
++
)
{
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
{
tmp
[
x
]
=
block
[
x
*
BSIZE
+
y
];
tmp
[
x
]
*=
x
==
0
?
sqrt
(
BSIZE
)
:
1
.
/
sqrt
(
2
.
/
BSIZE
);
}
av_dct_calc
(
ctx
->
idct
,
tmp
);
for
(
x
=
0
;
x
<
BSIZE
;
x
++
)
dst
[
x
*
dst_linesize
+
y
]
+=
tmp
[
x
];
}
}
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
DCTdnoizContext
*
s
=
ctx
->
priv
;
int
i
,
x
,
y
,
bx
,
by
,
linesize
,
*
iweights
;
const
float
dct_3x3
[
3
][
3
]
=
{
{
1
.
/
sqrt
(
3
),
1
.
/
sqrt
(
3
),
1
.
/
sqrt
(
3
)
},
{
1
.
/
sqrt
(
2
),
0
,
-
1
.
/
sqrt
(
2
)
},
{
1
.
/
sqrt
(
6
),
-
2
.
/
sqrt
(
6
),
1
.
/
sqrt
(
6
)
},
};
uint8_t
rgba_map
[
4
];
ff_fill_rgba_map
(
rgba_map
,
inlink
->
format
);
for
(
y
=
0
;
y
<
3
;
y
++
)
for
(
x
=
0
;
x
<
3
;
x
++
)
s
->
color_dct
[
y
][
x
]
=
dct_3x3
[
rgba_map
[
y
]][
rgba_map
[
x
]];
s
->
pr_width
=
inlink
->
w
-
(
inlink
->
w
-
BSIZE
)
%
s
->
step
;
s
->
pr_height
=
inlink
->
w
-
(
inlink
->
h
-
BSIZE
)
%
s
->
step
;
if
(
s
->
pr_width
!=
inlink
->
w
)
av_log
(
ctx
,
AV_LOG_WARNING
,
"The last %d horizontal pixels won't be denoised
\n
"
,
inlink
->
w
-
s
->
pr_width
);
if
(
s
->
pr_height
!=
inlink
->
h
)
av_log
(
ctx
,
AV_LOG_WARNING
,
"The last %d vertical pixels won't be denoised
\n
"
,
inlink
->
h
-
s
->
pr_height
);
s
->
p_linesize
=
linesize
=
FFALIGN
(
s
->
pr_width
,
32
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
s
->
cbuf
[
i
][
0
]
=
av_malloc
(
linesize
*
s
->
pr_height
*
sizeof
(
*
s
->
cbuf
[
i
][
0
]));
s
->
cbuf
[
i
][
1
]
=
av_malloc
(
linesize
*
s
->
pr_height
*
sizeof
(
*
s
->
cbuf
[
i
][
1
]));
s
->
cbuf
[
i
][
2
]
=
av_malloc
(
linesize
*
s
->
pr_height
*
sizeof
(
*
s
->
cbuf
[
i
][
2
]));
if
(
!
s
->
cbuf
[
i
][
0
]
||
!
s
->
cbuf
[
i
][
1
]
||
!
s
->
cbuf
[
i
][
2
])
return
AVERROR
(
ENOMEM
);
}
s
->
weights
=
av_malloc
(
s
->
pr_height
*
linesize
*
sizeof
(
*
s
->
weights
));
if
(
!
s
->
weights
)
return
AVERROR
(
ENOMEM
);
iweights
=
av_calloc
(
s
->
pr_height
,
linesize
*
sizeof
(
*
iweights
));
if
(
!
iweights
)
return
AVERROR
(
ENOMEM
);
for
(
y
=
0
;
y
<
s
->
pr_height
-
BSIZE
+
1
;
y
+=
s
->
step
)
for
(
x
=
0
;
x
<
s
->
pr_width
-
BSIZE
+
1
;
x
+=
s
->
step
)
for
(
by
=
0
;
by
<
BSIZE
;
by
++
)
for
(
bx
=
0
;
bx
<
BSIZE
;
bx
++
)
iweights
[(
y
+
by
)
*
linesize
+
x
+
bx
]
++
;
for
(
y
=
0
;
y
<
s
->
pr_height
;
y
++
)
for
(
x
=
0
;
x
<
s
->
pr_width
;
x
++
)
s
->
weights
[
y
*
linesize
+
x
]
=
1
.
/
iweights
[
y
*
linesize
+
x
];
av_free
(
iweights
);
return
0
;
}
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
{
DCTdnoizContext
*
s
=
ctx
->
priv
;
if
(
s
->
expr_str
)
{
int
ret
=
av_expr_parse
(
&
s
->
expr
,
s
->
expr_str
,
var_names
,
NULL
,
NULL
,
NULL
,
NULL
,
0
,
ctx
);
if
(
ret
<
0
)
return
ret
;
}
s
->
th
=
s
->
sigma
*
3
.;
s
->
step
=
BSIZE
-
s
->
overlap
;
s
->
dct
=
av_dct_init
(
NBITS
,
DCT_II
);
s
->
idct
=
av_dct_init
(
NBITS
,
DCT_III
);
s
->
block
=
av_malloc
(
BSIZE
*
BSIZE
*
sizeof
(
*
s
->
block
));
s
->
tmp_block
=
av_malloc
(
BSIZE
*
BSIZE
*
sizeof
(
*
s
->
tmp_block
));
if
(
!
s
->
dct
||
!
s
->
idct
||
!
s
->
tmp_block
||
!
s
->
block
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
static
const
enum
AVPixelFormat
pix_fmts
[]
=
{
AV_PIX_FMT_BGR24
,
AV_PIX_FMT_RGB24
,
AV_PIX_FMT_NONE
};
ff_set_common_formats
(
ctx
,
ff_make_format_list
(
pix_fmts
));
return
0
;
}
static
void
color_decorrelation
(
float
dct3ch
[
3
][
3
],
float
**
dst
,
int
dst_linesize
,
const
uint8_t
*
src
,
int
src_linesize
,
int
w
,
int
h
)
{
int
x
,
y
;
float
*
dstp_r
=
dst
[
0
];
float
*
dstp_g
=
dst
[
1
];
float
*
dstp_b
=
dst
[
2
];
for
(
y
=
0
;
y
<
h
;
y
++
)
{
const
uint8_t
*
srcp
=
src
;
for
(
x
=
0
;
x
<
w
;
x
++
)
{
dstp_r
[
x
]
=
srcp
[
0
]
*
dct3ch
[
0
][
0
]
+
srcp
[
1
]
*
dct3ch
[
0
][
1
]
+
srcp
[
2
]
*
dct3ch
[
0
][
2
];
dstp_g
[
x
]
=
srcp
[
0
]
*
dct3ch
[
1
][
0
]
+
srcp
[
1
]
*
dct3ch
[
1
][
1
]
+
srcp
[
2
]
*
dct3ch
[
1
][
2
];
dstp_b
[
x
]
=
srcp
[
0
]
*
dct3ch
[
2
][
0
]
+
srcp
[
1
]
*
dct3ch
[
2
][
1
]
+
srcp
[
2
]
*
dct3ch
[
2
][
2
];
srcp
+=
3
;
}
src
+=
src_linesize
;
dstp_r
+=
dst_linesize
;
dstp_g
+=
dst_linesize
;
dstp_b
+=
dst_linesize
;
}
}
static
void
color_correlation
(
float
dct3ch
[
3
][
3
],
uint8_t
*
dst
,
int
dst_linesize
,
float
**
src
,
int
src_linesize
,
int
w
,
int
h
)
{
int
x
,
y
;
const
float
*
src_r
=
src
[
0
];
const
float
*
src_g
=
src
[
1
];
const
float
*
src_b
=
src
[
2
];
for
(
y
=
0
;
y
<
h
;
y
++
)
{
uint8_t
*
dstp
=
dst
;
for
(
x
=
0
;
x
<
w
;
x
++
)
{
dstp
[
0
]
=
av_clip_uint8
(
src_r
[
x
]
*
dct3ch
[
0
][
0
]
+
src_g
[
x
]
*
dct3ch
[
1
][
0
]
+
src_b
[
x
]
*
dct3ch
[
2
][
0
]);
dstp
[
1
]
=
av_clip_uint8
(
src_r
[
x
]
*
dct3ch
[
0
][
1
]
+
src_g
[
x
]
*
dct3ch
[
1
][
1
]
+
src_b
[
x
]
*
dct3ch
[
2
][
1
]);
dstp
[
2
]
=
av_clip_uint8
(
src_r
[
x
]
*
dct3ch
[
0
][
2
]
+
src_g
[
x
]
*
dct3ch
[
1
][
2
]
+
src_b
[
x
]
*
dct3ch
[
2
][
2
]);
dstp
+=
3
;
}
dst
+=
dst_linesize
;
src_r
+=
src_linesize
;
src_g
+=
src_linesize
;
src_b
+=
src_linesize
;
}
}
static
void
filter_plane
(
AVFilterContext
*
ctx
,
float
*
dst
,
int
dst_linesize
,
const
float
*
src
,
int
src_linesize
,
int
w
,
int
h
)
{
int
x
,
y
,
bx
,
by
;
DCTdnoizContext
*
s
=
ctx
->
priv
;
float
*
dst0
=
dst
;
const
float
*
weights
=
s
->
weights
;
// reset block sums
memset
(
dst
,
0
,
h
*
dst_linesize
*
sizeof
(
*
dst
));
// block dct sums
for
(
y
=
0
;
y
<
h
-
BSIZE
+
1
;
y
+=
s
->
step
)
{
for
(
x
=
0
;
x
<
w
-
BSIZE
+
1
;
x
+=
s
->
step
)
{
float
*
ftb
=
dct_block
(
s
,
src
+
x
,
src_linesize
);
if
(
s
->
expr
)
{
for
(
by
=
0
;
by
<
BSIZE
;
by
++
)
{
for
(
bx
=
0
;
bx
<
BSIZE
;
bx
++
)
{
s
->
var_values
[
VAR_C
]
=
FFABS
(
*
ftb
);
*
ftb
++
*=
av_expr_eval
(
s
->
expr
,
s
->
var_values
,
s
);
}
}
}
else
{
for
(
by
=
0
;
by
<
BSIZE
;
by
++
)
{
for
(
bx
=
0
;
bx
<
BSIZE
;
bx
++
)
{
if
(
FFABS
(
*
ftb
)
<
s
->
th
)
*
ftb
=
0
;
ftb
++
;
}
}
}
idct_block
(
s
,
dst
+
x
,
dst_linesize
);
}
src
+=
s
->
step
*
src_linesize
;
dst
+=
s
->
step
*
dst_linesize
;
}
// average blocks
dst
=
dst0
;
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
dst
[
x
]
*=
weights
[
x
];
dst
+=
dst_linesize
;
weights
+=
dst_linesize
;
}
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
DCTdnoizContext
*
s
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
inlink
->
dst
->
outputs
[
0
];
int
direct
,
plane
;
AVFrame
*
out
;
if
(
av_frame_is_writable
(
in
))
{
direct
=
1
;
out
=
in
;
}
else
{
direct
=
0
;
out
=
ff_get_video_buffer
(
outlink
,
outlink
->
w
,
outlink
->
h
);
if
(
!
out
)
{
av_frame_free
(
&
in
);
return
AVERROR
(
ENOMEM
);
}
av_frame_copy_props
(
out
,
in
);
}
color_decorrelation
(
s
->
color_dct
,
s
->
cbuf
[
0
],
s
->
p_linesize
,
in
->
data
[
0
],
in
->
linesize
[
0
],
s
->
pr_width
,
s
->
pr_height
);
for
(
plane
=
0
;
plane
<
3
;
plane
++
)
filter_plane
(
ctx
,
s
->
cbuf
[
1
][
plane
],
s
->
p_linesize
,
s
->
cbuf
[
0
][
plane
],
s
->
p_linesize
,
s
->
pr_width
,
s
->
pr_height
);
color_correlation
(
s
->
color_dct
,
out
->
data
[
0
],
out
->
linesize
[
0
],
s
->
cbuf
[
1
],
s
->
p_linesize
,
s
->
pr_width
,
s
->
pr_height
);
if
(
!
direct
)
{
int
y
;
uint8_t
*
dst
=
out
->
data
[
0
];
const
uint8_t
*
src
=
in
->
data
[
0
];
const
int
dst_linesize
=
out
->
linesize
[
0
];
const
int
src_linesize
=
in
->
linesize
[
0
];
const
int
hpad
=
(
inlink
->
w
-
s
->
pr_width
)
*
3
;
const
int
vpad
=
(
inlink
->
h
-
s
->
pr_height
);
if
(
hpad
)
{
uint8_t
*
dstp
=
dst
+
s
->
pr_width
*
3
;
const
uint8_t
*
srcp
=
src
+
s
->
pr_width
*
3
;
for
(
y
=
0
;
y
<
s
->
pr_height
;
y
++
)
{
memcpy
(
dstp
,
srcp
,
hpad
);
dstp
+=
dst_linesize
;
srcp
+=
src_linesize
;
}
}
if
(
vpad
)
{
uint8_t
*
dstp
=
dst
+
s
->
pr_height
*
dst_linesize
;
const
uint8_t
*
srcp
=
src
+
s
->
pr_height
*
src_linesize
;
for
(
y
=
0
;
y
<
vpad
;
y
++
)
{
memcpy
(
dstp
,
srcp
,
inlink
->
w
*
3
);
dstp
+=
dst_linesize
;
srcp
+=
src_linesize
;
}
}
av_frame_free
(
&
in
);
}
return
ff_filter_frame
(
outlink
,
out
);
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
int
i
;
DCTdnoizContext
*
s
=
ctx
->
priv
;
av_dct_end
(
s
->
dct
);
av_dct_end
(
s
->
idct
);
av_free
(
s
->
block
);
av_free
(
s
->
tmp_block
);
av_free
(
s
->
weights
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
av_free
(
s
->
cbuf
[
i
][
0
]);
av_free
(
s
->
cbuf
[
i
][
1
]);
av_free
(
s
->
cbuf
[
i
][
2
]);
}
av_expr_free
(
s
->
expr
);
}
static
const
AVFilterPad
dctdnoiz_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
filter_frame
=
filter_frame
,
.
config_props
=
config_input
,
},
{
NULL
}
};
static
const
AVFilterPad
dctdnoiz_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
},
{
NULL
}
};
AVFilter
avfilter_vf_dctdnoiz
=
{
.
name
=
"dctdnoiz"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Denoise frames using 2D DCT."
),
.
priv_size
=
sizeof
(
DCTdnoizContext
),
.
init
=
init
,
.
uninit
=
uninit
,
.
query_formats
=
query_formats
,
.
inputs
=
dctdnoiz_inputs
,
.
outputs
=
dctdnoiz_outputs
,
.
priv_class
=
&
dctdnoiz_class
,
.
flags
=
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
,
};
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