mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
lavfi/unsharp: use named options, and add missing checks on matrix size values
In particular, avoid out-of-buffer access and crashes with too big values, and rework documentation accordingly.
This commit is contained in:
parent
5e947aeb59
commit
fbcc584d3a
@ -4914,39 +4914,34 @@ transpose=1:portrait
|
||||
|
||||
Sharpen or blur the input video.
|
||||
|
||||
It accepts the following parameters:
|
||||
This filter accepts parameters as a list of @var{key}=@var{value} pairs,
|
||||
separated by ":".
|
||||
|
||||
If the key of the first options is omitted, the arguments are
|
||||
interpreted according to the syntax:
|
||||
@var{luma_msize_x}:@var{luma_msize_y}:@var{luma_amount}:@var{chroma_msize_x}:@var{chroma_msize_y}:@var{chroma_amount}
|
||||
|
||||
Negative values for the amount will blur the input video, while positive
|
||||
values will sharpen. All parameters are optional and default to the
|
||||
equivalent of the string '5:5:1.0:5:5:0.0'.
|
||||
A description of the accepted options follows.
|
||||
|
||||
@table @option
|
||||
@item luma_msize_x, lx
|
||||
@item chroma_msize_x, cx
|
||||
Set the luma/chroma matrix horizontal size. It can be an integer
|
||||
between 3 and 63, default value is 5.
|
||||
|
||||
@item luma_msize_x
|
||||
Set the luma matrix horizontal size. It can be an integer between 3
|
||||
and 63, default value is 5.
|
||||
@item luma_msize_y, ly
|
||||
@item chroma_msize_y, cy
|
||||
Set the luma/chroma matrix vertical size. It can be an integer between
|
||||
3 and 63, default value is 5.
|
||||
|
||||
@item luma_msize_y
|
||||
Set the luma matrix vertical size. It can be an integer between 3
|
||||
and 63, default value is 5.
|
||||
|
||||
@item luma_amount
|
||||
Set the luma effect strength. It can be a float number between -2.0
|
||||
and 5.0, default value is 1.0.
|
||||
|
||||
@item chroma_msize_x
|
||||
Set the chroma matrix horizontal size. It can be an integer between 3
|
||||
and 63, default value is 5.
|
||||
|
||||
@item chroma_msize_y
|
||||
Set the chroma matrix vertical size. It can be an integer between 3
|
||||
and 63, default value is 5.
|
||||
|
||||
@item chroma_amount
|
||||
Set the chroma effect strength. It can be a float number between -2.0
|
||||
and 5.0, default value is 0.0.
|
||||
@item luma_amount, la
|
||||
@item chroma_amount, ca
|
||||
Set the luma/chroma effect strength. It can be a float number between
|
||||
-2.0 and 5.0. Default value is 1.0 for @option{luma_amount}, 0.0 for
|
||||
@option{chroma_amount}.
|
||||
|
||||
Negative values will blur the input video, while positive values will
|
||||
sharpen.
|
||||
@end table
|
||||
|
||||
@example
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||
#define LIBAVFILTER_VERSION_MINOR 37
|
||||
#define LIBAVFILTER_VERSION_MICRO 101
|
||||
#define LIBAVFILTER_VERSION_MICRO 102
|
||||
|
||||
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
||||
LIBAVFILTER_VERSION_MINOR, \
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "video.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
|
||||
#define MIN_MATRIX_SIZE 3
|
||||
@ -62,11 +63,36 @@ typedef struct FilterParam {
|
||||
} FilterParam;
|
||||
|
||||
typedef struct {
|
||||
const AVClass *class;
|
||||
FilterParam luma; ///< luma parameters (width, height, amount)
|
||||
FilterParam chroma; ///< chroma parameters (width, height, amount)
|
||||
int hsub, vsub;
|
||||
int luma_msize_x, luma_msize_y, chroma_msize_x, chroma_msize_y;
|
||||
double luma_amount, chroma_amount;
|
||||
} UnsharpContext;
|
||||
|
||||
#define OFFSET(x) offsetof(UnsharpContext, x)
|
||||
|
||||
static const AVOption unsharp_options[] = {
|
||||
{ "luma_msize_x", "set luma matrix x size", OFFSET(luma_msize_x), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "lx", "set luma matrix x size", OFFSET(luma_msize_x), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "luma_msize_y", "set luma matrix y size", OFFSET(luma_msize_y), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "ly", "set luma matrix y size", OFFSET(luma_msize_y), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "luma_amount", "set luma effect amount", OFFSET(luma_amount), AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -2.0, 5.0 },
|
||||
{ "la", "set luma effect amount", OFFSET(luma_amount), AV_OPT_TYPE_DOUBLE, {.dbl=1.0}, -2.0, 5.0 },
|
||||
|
||||
{ "chroma_msize_x", "set chroma matrix x size", OFFSET(chroma_msize_x), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "cx", "set chroma matrix x size", OFFSET(chroma_msize_x), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "chroma_msize_y", "set chroma matrix y size", OFFSET(chroma_msize_y), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "cy" , "set chroma matrix y size", OFFSET(chroma_msize_y), AV_OPT_TYPE_INT, {.i64=5}, 3, 63 },
|
||||
{ "chroma_amount", "set chroma effect strenght", OFFSET(chroma_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -2.0, 5.0 },
|
||||
{ "ca", "set chroma effect strenght", OFFSET(chroma_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.0}, -2.0, 5.0 },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
AVFILTER_DEFINE_CLASS(unsharp);
|
||||
|
||||
static void apply_unsharp( uint8_t *dst, int dst_stride,
|
||||
const uint8_t *src, int src_stride,
|
||||
int width, int height, FilterParam *fp)
|
||||
@ -135,24 +161,21 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
|
||||
static av_cold int init(AVFilterContext *ctx, const char *args)
|
||||
{
|
||||
UnsharpContext *unsharp = ctx->priv;
|
||||
int lmsize_x = 5, cmsize_x = 5;
|
||||
int lmsize_y = 5, cmsize_y = 5;
|
||||
double lamount = 1.0f, camount = 0.0f;
|
||||
static const char *shorthand[] = {
|
||||
"luma_msize_x", "luma_msize_y", "luma_amount",
|
||||
"chroma_msize_x", "chroma_msize_y", "chroma_amount",
|
||||
NULL
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (args)
|
||||
sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount,
|
||||
&cmsize_x, &cmsize_y, &camount);
|
||||
unsharp->class = &unsharp_class;
|
||||
av_opt_set_defaults(unsharp);
|
||||
|
||||
if ((lamount && (lmsize_x < 2 || lmsize_y < 2)) ||
|
||||
(camount && (cmsize_x < 2 || cmsize_y < 2))) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"Invalid value <2 for lmsize_x:%d or lmsize_y:%d or cmsize_x:%d or cmsize_y:%d\n",
|
||||
lmsize_x, lmsize_y, cmsize_x, cmsize_y);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if ((ret = av_opt_set_from_string(unsharp, args, shorthand, "=", ":")) < 0)
|
||||
return ret;
|
||||
|
||||
set_filter_param(&unsharp->luma, lmsize_x, lmsize_y, lamount);
|
||||
set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount);
|
||||
set_filter_param(&unsharp->luma, unsharp->luma_msize_x, unsharp->luma_msize_y, unsharp->luma_amount);
|
||||
set_filter_param(&unsharp->chroma, unsharp->chroma_msize_x, unsharp->chroma_msize_y, unsharp->chroma_amount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -212,6 +235,7 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||
|
||||
free_filter_param(&unsharp->luma);
|
||||
free_filter_param(&unsharp->chroma);
|
||||
av_opt_free(unsharp);
|
||||
}
|
||||
|
||||
static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
|
||||
@ -269,4 +293,6 @@ AVFilter avfilter_vf_unsharp = {
|
||||
.inputs = avfilter_vf_unsharp_inputs,
|
||||
|
||||
.outputs = avfilter_vf_unsharp_outputs,
|
||||
|
||||
.priv_class = &unsharp_class,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user