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
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>:
- RedSpark demuxer
- ADPCM IMA Radical decoder
- zmq filters
- DCT denoiser filter (dctdnoiz)
version 1.2:
...
...
configure
View file @
7b43120c
...
...
@@ -2129,6 +2129,7 @@ blackframe_filter_deps="gpl"
boxblur_filter_deps
=
"gpl"
colormatrix_filter_deps
=
"gpl"
cropdetect_filter_deps
=
"gpl"
dctdnoiz_filter_deps
=
"avcodec"
delogo_filter_deps
=
"gpl"
deshake_filter_deps
=
"avcodec"
deshake_filter_select
=
"dsputil"
...
...
doc/filters.texi
View file @
7b43120c
...
...
@@ -2655,6 +2655,59 @@ curves=psfile='MyCurvesPresets/purple.asv':green='0.45/0.53'
@end example
@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}
@section decimate
...
...
libavfilter/Makefile
View file @
7b43120c
...
...
@@ -116,6 +116,7 @@ OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o
OBJS-$(CONFIG_CROP_FILTER)
+=
vf_crop.o
OBJS-$(CONFIG_CROPDETECT_FILTER)
+=
vf_cropdetect.o
OBJS-$(CONFIG_CURVES_FILTER)
+=
vf_curves.o
OBJS-$(CONFIG_DCTDNOIZ_FILTER)
+=
vf_dctdnoiz.o
OBJS-$(CONFIG_DECIMATE_FILTER)
+=
vf_decimate.o
OBJS-$(CONFIG_DELOGO_FILTER)
+=
vf_delogo.o
OBJS-$(CONFIG_DESHAKE_FILTER)
+=
vf_deshake.o
...
...
libavfilter/allfilters.c
View file @
7b43120c
...
...
@@ -114,6 +114,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
CROP
,
crop
,
vf
);
REGISTER_FILTER
(
CROPDETECT
,
cropdetect
,
vf
);
REGISTER_FILTER
(
CURVES
,
curves
,
vf
);
REGISTER_FILTER
(
DCTDNOIZ
,
dctdnoiz
,
vf
);
REGISTER_FILTER
(
DECIMATE
,
decimate
,
vf
);
REGISTER_FILTER
(
DELOGO
,
delogo
,
vf
);
REGISTER_FILTER
(
DESHAKE
,
deshake
,
vf
);
...
...
libavfilter/version.h
View file @
7b43120c
...
...
@@ -29,7 +29,7 @@
#include "libavutil/avutil.h"
#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_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