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
8cd3685a
Commit
8cd3685a
authored
Nov 10, 2013
by
Stefano Sabatini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavfi: add elbg filter
parent
fe55c319
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
244 additions
and
2 deletions
+244
-2
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+26
-0
Makefile
libavfilter/Makefile
+2
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+2
-2
vf_elbg.c
libavfilter/vf_elbg.c
+212
-0
No files found.
Changelog
View file @
8cd3685a
...
...
@@ -6,6 +6,7 @@ version <next>
- HNM version 4 demuxer and video decoder
- Live HDS muxer
- setsar/setdar filters now support variables in ratio expressions
- elbg filter
version 2.1:
...
...
doc/filters.texi
View file @
8cd3685a
...
...
@@ -3790,6 +3790,32 @@ ffmpeg -i video.avi -filter_complex 'extractplanes=y+u+v[y][u][v]' -map '[y]' y.
@end example
@end itemize
@section elbg
Apply a posterize effect using the ELBG (Enhanced LBG) algorithm.
For each input image, the filter will compute the optimal mapping from
the input to the output given the codebook length, that is the number
of distinct output colors.
This filter accepts the following options.
@table @option
@item codebook_length, l
Set codebook length. The value must be a positive integer, and
represents the number of distinct output colors. Default value is 256.
@item nb_steps, n
Set the maximum number of iterations to apply for computing the optimal
mapping. The higher the value the better the result and the higher the
computation time. Default value is 1.
@item seed, s
Set a random seed, must be an integer included between 0 and
UINT32_MAX. If not specified, or if explicitly set to -1, the filter
will try to use a good random seed on a best effort basis.
@end table
@section fade
Apply fade-in/out effect to input video.
...
...
libavfilter/Makefile
View file @
8cd3685a
...
...
@@ -9,6 +9,7 @@ FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample
FFLIBS-$(CONFIG_ATEMPO_FILTER)
+=
avcodec
FFLIBS-$(CONFIG_DECIMATE_FILTER)
+=
avcodec
FFLIBS-$(CONFIG_DESHAKE_FILTER)
+=
avcodec
FFLIBS-$(CONFIG_ELBG_FILTER)
+=
avcodec
FFLIBS-$(CONFIG_MCDEINT_FILTER)
+=
avcodec
FFLIBS-$(CONFIG_MOVIE_FILTER)
+=
avformat
avcodec
FFLIBS-$(CONFIG_MP_FILTER)
+=
avcodec
...
...
@@ -130,6 +131,7 @@ OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o
OBJS-$(CONFIG_DRAWBOX_FILTER)
+=
vf_drawbox.o
OBJS-$(CONFIG_DRAWGRID_FILTER)
+=
vf_drawbox.o
OBJS-$(CONFIG_DRAWTEXT_FILTER)
+=
vf_drawtext.o
OBJS-$(CONFIG_ELBG_FILTER)
+=
vf_elbg.o
OBJS-$(CONFIG_EDGEDETECT_FILTER)
+=
vf_edgedetect.o
OBJS-$(CONFIG_EXTRACTPLANES_FILTER)
+=
vf_extractplanes.o
OBJS-$(CONFIG_FADE_FILTER)
+=
vf_fade.o
...
...
libavfilter/allfilters.c
View file @
8cd3685a
...
...
@@ -127,6 +127,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
DRAWGRID
,
drawgrid
,
vf
);
REGISTER_FILTER
(
DRAWTEXT
,
drawtext
,
vf
);
REGISTER_FILTER
(
EDGEDETECT
,
edgedetect
,
vf
);
REGISTER_FILTER
(
ELBG
,
elbg
,
vf
);
REGISTER_FILTER
(
EXTRACTPLANES
,
extractplanes
,
vf
);
REGISTER_FILTER
(
FADE
,
fade
,
vf
);
REGISTER_FILTER
(
FIELD
,
field
,
vf
);
...
...
libavfilter/version.h
View file @
8cd3685a
...
...
@@ -30,8 +30,8 @@
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 9
0
#define LIBAVFILTER_VERSION_MICRO 10
2
#define LIBAVFILTER_VERSION_MINOR 9
1
#define LIBAVFILTER_VERSION_MICRO 10
0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
...
...
libavfilter/vf_elbg.c
0 → 100644
View file @
8cd3685a
/*
* Copyright (c) 2013 Stefano Sabatini
*
* 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
*/
/**
* @file
* video quantizer filter based on ELBG
*/
#include "libavcodec/elbg.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/random_seed.h"
#include "avfilter.h"
#include "drawutils.h"
#include "internal.h"
#include "video.h"
typedef
struct
{
const
AVClass
*
class
;
AVLFG
lfg
;
int
lfg_seed
;
int
max_steps_nb
;
int
*
codeword
;
int
codeword_length
;
int
*
codeword_closest_codebook_idxs
;
int
*
codebook
;
int
codebook_length
;
const
AVPixFmtDescriptor
*
pix_desc
;
uint8_t
rgba_map
[
4
];
}
ELBGContext
;
#define OFFSET(x) offsetof(ELBGContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static
const
AVOption
elbg_options
[]
=
{
{
"codebook_length"
,
"set codebook length"
,
OFFSET
(
codebook_length
),
AV_OPT_TYPE_INT
,
{
.
i64
=
256
},
1
,
INT_MAX
,
FLAGS
},
{
"l"
,
"set codebook length"
,
OFFSET
(
codebook_length
),
AV_OPT_TYPE_INT
,
{
.
i64
=
256
},
1
,
INT_MAX
,
FLAGS
},
{
"nb_steps"
,
"set max number of steps used to compute the mapping"
,
OFFSET
(
max_steps_nb
),
AV_OPT_TYPE_INT
,
{
.
i64
=
1
},
1
,
INT_MAX
,
FLAGS
},
{
"n"
,
"set max number of steps used to compute the mapping"
,
OFFSET
(
max_steps_nb
),
AV_OPT_TYPE_INT
,
{
.
i64
=
1
},
1
,
INT_MAX
,
FLAGS
},
{
"seed"
,
"set the random seed"
,
OFFSET
(
lfg_seed
),
AV_OPT_TYPE_INT
,
{.
i64
=
-
1
},
-
1
,
UINT32_MAX
,
FLAGS
},
{
"s"
,
"set the random seed"
,
OFFSET
(
lfg_seed
),
AV_OPT_TYPE_INT
,
{
.
i64
=
-
1
},
-
1
,
INT_MAX
,
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
elbg
);
static
av_cold
int
init
(
AVFilterContext
*
ctx
)
{
ELBGContext
*
elbg
=
ctx
->
priv
;
if
(
elbg
->
lfg_seed
==
-
1
)
elbg
->
lfg_seed
=
av_get_random_seed
();
av_lfg_init
(
&
elbg
->
lfg
,
elbg
->
lfg_seed
);
return
0
;
}
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
static
const
enum
PixelFormat
pix_fmts
[]
=
{
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_RGB24
,
AV_PIX_FMT_BGR24
,
AV_PIX_FMT_NONE
};
ff_set_common_formats
(
ctx
,
ff_make_format_list
(
pix_fmts
));
return
0
;
}
#define NB_COMPONENTS 3
static
int
config_input
(
AVFilterLink
*
inlink
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
ELBGContext
*
elbg
=
ctx
->
priv
;
elbg
->
pix_desc
=
av_pix_fmt_desc_get
(
inlink
->
format
);
elbg
->
codeword_length
=
inlink
->
w
*
inlink
->
h
;
elbg
->
codeword
=
av_realloc_f
(
elbg
->
codeword
,
elbg
->
codeword_length
,
NB_COMPONENTS
*
sizeof
(
*
elbg
->
codeword
));
if
(
!
elbg
->
codeword
)
return
AVERROR
(
ENOMEM
);
elbg
->
codeword_closest_codebook_idxs
=
av_realloc_f
(
elbg
->
codeword_closest_codebook_idxs
,
elbg
->
codeword_length
,
sizeof
(
*
elbg
->
codeword_closest_codebook_idxs
));
if
(
!
elbg
->
codeword_closest_codebook_idxs
)
return
AVERROR
(
ENOMEM
);
elbg
->
codebook
=
av_realloc_f
(
elbg
->
codebook
,
elbg
->
codebook_length
,
NB_COMPONENTS
*
sizeof
(
*
elbg
->
codebook
));
if
(
!
elbg
->
codebook
)
return
AVERROR
(
ENOMEM
);
ff_fill_rgba_map
(
elbg
->
rgba_map
,
inlink
->
format
);
return
0
;
}
#define R 0
#define G 1
#define B 2
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
frame
)
{
ELBGContext
*
elbg
=
inlink
->
dst
->
priv
;
int
i
,
j
,
k
;
uint8_t
*
p
,
*
p0
;
const
uint8_t
r_idx
=
elbg
->
rgba_map
[
R
];
const
uint8_t
g_idx
=
elbg
->
rgba_map
[
G
];
const
uint8_t
b_idx
=
elbg
->
rgba_map
[
B
];
/* build the codeword */
p0
=
frame
->
data
[
0
];
k
=
0
;
for
(
i
=
0
;
i
<
inlink
->
h
;
i
++
)
{
p
=
p0
;
for
(
j
=
0
;
j
<
inlink
->
w
;
j
++
)
{
elbg
->
codeword
[
k
++
]
=
p
[
r_idx
];
elbg
->
codeword
[
k
++
]
=
p
[
g_idx
];
elbg
->
codeword
[
k
++
]
=
p
[
b_idx
];
p
+=
elbg
->
pix_desc
->
nb_components
;
}
p0
+=
frame
->
linesize
[
0
];
}
/* compute the codebook */
avpriv_init_elbg
(
elbg
->
codeword
,
NB_COMPONENTS
,
elbg
->
codeword_length
,
elbg
->
codebook
,
elbg
->
codebook_length
,
elbg
->
max_steps_nb
,
elbg
->
codeword_closest_codebook_idxs
,
&
elbg
->
lfg
);
avpriv_do_elbg
(
elbg
->
codeword
,
NB_COMPONENTS
,
elbg
->
codeword_length
,
elbg
->
codebook
,
elbg
->
codebook_length
,
elbg
->
max_steps_nb
,
elbg
->
codeword_closest_codebook_idxs
,
&
elbg
->
lfg
);
/* fill the output with the codebook values */
p0
=
frame
->
data
[
0
];
k
=
0
;
for
(
i
=
0
;
i
<
inlink
->
h
;
i
++
)
{
p
=
p0
;
for
(
j
=
0
;
j
<
inlink
->
w
;
j
++
)
{
int
cb_idx
=
NB_COMPONENTS
*
elbg
->
codeword_closest_codebook_idxs
[
k
++
];
p
[
r_idx
]
=
elbg
->
codebook
[
cb_idx
];
p
[
g_idx
]
=
elbg
->
codebook
[
cb_idx
+
1
];
p
[
b_idx
]
=
elbg
->
codebook
[
cb_idx
+
2
];
p
+=
elbg
->
pix_desc
->
nb_components
;
}
p0
+=
frame
->
linesize
[
0
];
}
return
ff_filter_frame
(
inlink
->
dst
->
outputs
[
0
],
frame
);
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
ELBGContext
*
elbg
=
ctx
->
priv
;
av_freep
(
&
elbg
->
codebook
);
av_freep
(
&
elbg
->
codeword
);
av_freep
(
&
elbg
->
codeword_closest_codebook_idxs
);
}
static
const
AVFilterPad
elbg_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
config_input
,
.
filter_frame
=
filter_frame
,
.
needs_writable
=
1
,
},
{
NULL
}
};
static
const
AVFilterPad
elbg_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
},
{
NULL
}
};
AVFilter
ff_vf_elbg
=
{
.
name
=
"elbg"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Apply posterize effect, using the ELBG algorithm."
),
.
priv_size
=
sizeof
(
ELBGContext
),
.
priv_class
=
&
elbg_class
,
.
query_formats
=
query_formats
,
.
init
=
init
,
.
uninit
=
uninit
,
.
inputs
=
elbg_inputs
,
.
outputs
=
elbg_outputs
,
};
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