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
212960ee
Commit
212960ee
authored
Apr 15, 2013
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
colorchannelmixer filter
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
449cdd54
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
429 additions
and
1 deletion
+429
-1
Changelog
Changelog
+1
-0
filters.texi
doc/filters.texi
+55
-0
Makefile
libavfilter/Makefile
+1
-0
allfilters.c
libavfilter/allfilters.c
+1
-0
version.h
libavfilter/version.h
+1
-1
vf_colorchannelmixer.c
libavfilter/vf_colorchannelmixer.c
+370
-0
No files found.
Changelog
View file @
212960ee
...
@@ -24,6 +24,7 @@ version <next>:
...
@@ -24,6 +24,7 @@ version <next>:
- smptehdbars source
- smptehdbars source
- inverse telecine filters (fieldmatch and decimate)
- inverse telecine filters (fieldmatch and decimate)
- colorbalance filter
- colorbalance filter
- colorchannelmixer filter
version 1.2:
version 1.2:
...
...
doc/filters.texi
View file @
212960ee
...
@@ -2091,6 +2091,61 @@ colorbalance=rs=.3
...
@@ -2091,6 +2091,61 @@ colorbalance=rs=.3
@end example
@end example
@end itemize
@end itemize
@section colorchannelmixer
Adjust video input frames by re-mixing color channels.
This filter modifies a color channel by adding the values associated to
the other channels of the same pixels. For example if the value to
modify is red, the output value will be:
@example
@var{red}=@var{red}*@var{rr} + @var{blue}*@var{rb} + @var{green}*@var{rg} + @var{alpha}*@var{ra}
@end example
The filter accepts the following options:
@table @option
@item rr
@item rg
@item rb
@item ra
Adjust contribution of input red, green, blue and alpha channels for output red channel.
Default is @code{1} for @var{rr}, and @code{0} for @var{rg}, @var{rb} and @var{ra}.
@item gr
@item gg
@item gb
@item ga
Adjust contribution of input red, green, blue and alpha channels for output green channel.
Default is @code{1} for @var{gg}, and @code{0} for @var{gr}, @var{gb} and @var{ga}.
@item br
@item bg
@item bb
@item ba
Adjust contribution of input red, green, blue and alpha channels for output blue channel.
Default is @code{1} for @var{bb}, and @code{0} for @var{br}, @var{bg} and @var{ba}.
@item ar
@item ag
@item ab
@item aa
Adjust contribution of input red, green, blue and alpha channels for output alpha channel.
Default is @code{1} for @var{aa}, and @code{0} for @var{ar}, @var{ag} and @var{ab}.
Allowed ranges for options are @code{[-2.0, 2.0]}.
@end table
@subsection Examples
@itemize
@item
Convert source to grayscale:
@example
colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3
@end example
@end itemize
@section colormatrix
@section colormatrix
Convert color matrix.
Convert color matrix.
...
...
libavfilter/Makefile
View file @
212960ee
...
@@ -105,6 +105,7 @@ OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o
...
@@ -105,6 +105,7 @@ OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o
OBJS-$(CONFIG_BLEND_FILTER)
+=
vf_blend.o
OBJS-$(CONFIG_BLEND_FILTER)
+=
vf_blend.o
OBJS-$(CONFIG_BOXBLUR_FILTER)
+=
vf_boxblur.o
OBJS-$(CONFIG_BOXBLUR_FILTER)
+=
vf_boxblur.o
OBJS-$(CONFIG_COLORBALANCE_FILTER)
+=
vf_colorbalance.o
OBJS-$(CONFIG_COLORBALANCE_FILTER)
+=
vf_colorbalance.o
OBJS-$(CONFIG_COLORCHANNELMIXER_FILTER)
+=
vf_colorchannelmixer.o
OBJS-$(CONFIG_COLORMATRIX_FILTER)
+=
vf_colormatrix.o
OBJS-$(CONFIG_COLORMATRIX_FILTER)
+=
vf_colormatrix.o
OBJS-$(CONFIG_COPY_FILTER)
+=
vf_copy.o
OBJS-$(CONFIG_COPY_FILTER)
+=
vf_copy.o
OBJS-$(CONFIG_CROP_FILTER)
+=
vf_crop.o
OBJS-$(CONFIG_CROP_FILTER)
+=
vf_crop.o
...
...
libavfilter/allfilters.c
View file @
212960ee
...
@@ -103,6 +103,7 @@ void avfilter_register_all(void)
...
@@ -103,6 +103,7 @@ void avfilter_register_all(void)
REGISTER_FILTER
(
BLEND
,
blend
,
vf
);
REGISTER_FILTER
(
BLEND
,
blend
,
vf
);
REGISTER_FILTER
(
BOXBLUR
,
boxblur
,
vf
);
REGISTER_FILTER
(
BOXBLUR
,
boxblur
,
vf
);
REGISTER_FILTER
(
COLORBALANCE
,
colorbalance
,
vf
);
REGISTER_FILTER
(
COLORBALANCE
,
colorbalance
,
vf
);
REGISTER_FILTER
(
COLORCHANNELMIXER
,
colorchannelmixer
,
vf
);
REGISTER_FILTER
(
COLORMATRIX
,
colormatrix
,
vf
);
REGISTER_FILTER
(
COLORMATRIX
,
colormatrix
,
vf
);
REGISTER_FILTER
(
COPY
,
copy
,
vf
);
REGISTER_FILTER
(
COPY
,
copy
,
vf
);
REGISTER_FILTER
(
CROP
,
crop
,
vf
);
REGISTER_FILTER
(
CROP
,
crop
,
vf
);
...
...
libavfilter/version.h
View file @
212960ee
...
@@ -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 5
7
#define LIBAVFILTER_VERSION_MINOR 5
8
#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_colorchannelmixer.c
0 → 100644
View file @
212960ee
/*
* Copyright (c) 2013 Paul B Mahol
*
* 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
*/
#include "libavutil/opt.h"
#include "avfilter.h"
#include "drawutils.h"
#include "formats.h"
#include "internal.h"
#include "video.h"
#define R 0
#define G 1
#define B 2
#define A 3
typedef
struct
{
const
AVClass
*
class
;
double
rr
,
rg
,
rb
,
ra
;
double
gr
,
gg
,
gb
,
ga
;
double
br
,
bg
,
bb
,
ba
;
double
ar
,
ag
,
ab
,
aa
;
int
*
lut
[
4
][
4
];
int
*
buffer
;
uint8_t
rgba_map
[
4
];
}
ColorChannelMixerContext
;
#define OFFSET(x) offsetof(ColorChannelMixerContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static
const
AVOption
colorchannelmixer_options
[]
=
{
{
"rr"
,
"set the red gain for the red channel"
,
OFFSET
(
rr
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
-
2
,
2
,
FLAGS
},
{
"rg"
,
"set the green gain for the red channel"
,
OFFSET
(
rg
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"rb"
,
"set the blue gain for the red channel"
,
OFFSET
(
rb
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"ra"
,
"set the alpha gain for the red channel"
,
OFFSET
(
ra
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"gr"
,
"set the red gain for the green channel"
,
OFFSET
(
gr
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"gg"
,
"set the green gain for the green channel"
,
OFFSET
(
gg
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
-
2
,
2
,
FLAGS
},
{
"gb"
,
"set the blue gain for the green channel"
,
OFFSET
(
gb
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"ga"
,
"set the alpha gain for the green channel"
,
OFFSET
(
ga
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"br"
,
"set the red gain for the blue channel"
,
OFFSET
(
br
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"bg"
,
"set the green gain for the blue channel"
,
OFFSET
(
bg
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"bb"
,
"set the blue gain for the blue channel"
,
OFFSET
(
bb
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
-
2
,
2
,
FLAGS
},
{
"ba"
,
"set the alpha gain for the blue channel"
,
OFFSET
(
ba
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"ar"
,
"set the red gain for the alpha channel"
,
OFFSET
(
ar
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"ag"
,
"set the green gain for the alpha channel"
,
OFFSET
(
ag
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"ab"
,
"set the blue gain for the alpha channel"
,
OFFSET
(
ab
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
0
},
-
2
,
2
,
FLAGS
},
{
"aa"
,
"set the alpha gain for the alpha channel"
,
OFFSET
(
aa
),
AV_OPT_TYPE_DOUBLE
,
{.
dbl
=
1
},
-
2
,
2
,
FLAGS
},
{
NULL
}
};
AVFILTER_DEFINE_CLASS
(
colorchannelmixer
);
static
int
query_formats
(
AVFilterContext
*
ctx
)
{
static
const
enum
AVPixelFormat
pix_fmts
[]
=
{
AV_PIX_FMT_RGB24
,
AV_PIX_FMT_BGR24
,
AV_PIX_FMT_RGBA
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_ARGB
,
AV_PIX_FMT_ABGR
,
AV_PIX_FMT_0RGB
,
AV_PIX_FMT_0BGR
,
AV_PIX_FMT_RGB0
,
AV_PIX_FMT_BGR0
,
AV_PIX_FMT_RGB48
,
AV_PIX_FMT_BGR48
,
AV_PIX_FMT_RGBA64
,
AV_PIX_FMT_BGRA64
,
AV_PIX_FMT_NONE
};
ff_set_common_formats
(
ctx
,
ff_make_format_list
(
pix_fmts
));
return
0
;
}
static
int
config_output
(
AVFilterLink
*
outlink
)
{
AVFilterContext
*
ctx
=
outlink
->
src
;
ColorChannelMixerContext
*
cm
=
ctx
->
priv
;
int
i
,
j
,
size
,
*
buffer
;
switch
(
outlink
->
format
)
{
case
AV_PIX_FMT_RGB48
:
case
AV_PIX_FMT_BGR48
:
case
AV_PIX_FMT_RGBA64
:
case
AV_PIX_FMT_BGRA64
:
if
(
outlink
->
format
==
AV_PIX_FMT_RGB48
||
outlink
->
format
==
AV_PIX_FMT_RGBA64
)
{
cm
->
rgba_map
[
R
]
=
0
;
cm
->
rgba_map
[
G
]
=
1
;
cm
->
rgba_map
[
B
]
=
2
;
cm
->
rgba_map
[
A
]
=
3
;
}
else
{
cm
->
rgba_map
[
R
]
=
2
;
cm
->
rgba_map
[
G
]
=
1
;
cm
->
rgba_map
[
B
]
=
0
;
cm
->
rgba_map
[
A
]
=
3
;
}
size
=
65536
;
break
;
default:
ff_fill_rgba_map
(
cm
->
rgba_map
,
outlink
->
format
);
size
=
256
;
}
cm
->
buffer
=
buffer
=
av_malloc
(
16
*
size
*
sizeof
(
*
cm
->
buffer
));
if
(
!
cm
->
buffer
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
j
=
0
;
j
<
4
;
j
++
,
buffer
+=
size
)
cm
->
lut
[
i
][
j
]
=
buffer
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
cm
->
lut
[
R
][
R
][
i
]
=
i
*
cm
->
rr
;
cm
->
lut
[
R
][
G
][
i
]
=
i
*
cm
->
rg
;
cm
->
lut
[
R
][
B
][
i
]
=
i
*
cm
->
rb
;
cm
->
lut
[
R
][
A
][
i
]
=
i
*
cm
->
ra
;
cm
->
lut
[
G
][
R
][
i
]
=
i
*
cm
->
gr
;
cm
->
lut
[
G
][
G
][
i
]
=
i
*
cm
->
gg
;
cm
->
lut
[
G
][
B
][
i
]
=
i
*
cm
->
gb
;
cm
->
lut
[
G
][
A
][
i
]
=
i
*
cm
->
ga
;
cm
->
lut
[
B
][
R
][
i
]
=
i
*
cm
->
br
;
cm
->
lut
[
B
][
G
][
i
]
=
i
*
cm
->
bg
;
cm
->
lut
[
B
][
B
][
i
]
=
i
*
cm
->
bb
;
cm
->
lut
[
B
][
A
][
i
]
=
i
*
cm
->
ba
;
cm
->
lut
[
A
][
R
][
i
]
=
i
*
cm
->
ar
;
cm
->
lut
[
A
][
G
][
i
]
=
i
*
cm
->
ag
;
cm
->
lut
[
A
][
B
][
i
]
=
i
*
cm
->
ab
;
cm
->
lut
[
A
][
A
][
i
]
=
i
*
cm
->
aa
;
}
return
0
;
}
static
int
filter_frame
(
AVFilterLink
*
inlink
,
AVFrame
*
in
)
{
AVFilterContext
*
ctx
=
inlink
->
dst
;
ColorChannelMixerContext
*
cm
=
ctx
->
priv
;
AVFilterLink
*
outlink
=
ctx
->
outputs
[
0
];
const
uint8_t
roffset
=
cm
->
rgba_map
[
R
];
const
uint8_t
goffset
=
cm
->
rgba_map
[
G
];
const
uint8_t
boffset
=
cm
->
rgba_map
[
B
];
const
uint8_t
aoffset
=
cm
->
rgba_map
[
A
];
const
uint8_t
*
srcrow
=
in
->
data
[
0
];
uint8_t
*
dstrow
;
AVFrame
*
out
;
int
i
,
j
;
if
(
av_frame_is_writable
(
in
))
{
out
=
in
;
}
else
{
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
);
}
dstrow
=
out
->
data
[
0
];
switch
(
outlink
->
format
)
{
case
AV_PIX_FMT_BGR24
:
case
AV_PIX_FMT_RGB24
:
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
{
const
uint8_t
*
src
=
srcrow
;
uint8_t
*
dst
=
dstrow
;
for
(
j
=
0
;
j
<
outlink
->
w
*
3
;
j
+=
3
)
{
const
uint8_t
rin
=
src
[
j
+
roffset
];
const
uint8_t
gin
=
src
[
j
+
goffset
];
const
uint8_t
bin
=
src
[
j
+
boffset
];
dst
[
j
+
roffset
]
=
av_clip_uint8
(
cm
->
lut
[
R
][
R
][
rin
]
+
cm
->
lut
[
R
][
G
][
gin
]
+
cm
->
lut
[
R
][
B
][
bin
]);
dst
[
j
+
goffset
]
=
av_clip_uint8
(
cm
->
lut
[
G
][
R
][
rin
]
+
cm
->
lut
[
G
][
G
][
gin
]
+
cm
->
lut
[
G
][
B
][
bin
]);
dst
[
j
+
boffset
]
=
av_clip_uint8
(
cm
->
lut
[
B
][
R
][
rin
]
+
cm
->
lut
[
B
][
G
][
gin
]
+
cm
->
lut
[
B
][
B
][
bin
]);
}
srcrow
+=
in
->
linesize
[
0
];
dstrow
+=
out
->
linesize
[
0
];
}
break
;
case
AV_PIX_FMT_0BGR
:
case
AV_PIX_FMT_0RGB
:
case
AV_PIX_FMT_BGR0
:
case
AV_PIX_FMT_RGB0
:
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
{
const
uint8_t
*
src
=
srcrow
;
uint8_t
*
dst
=
dstrow
;
for
(
j
=
0
;
j
<
outlink
->
w
*
4
;
j
+=
4
)
{
const
uint8_t
rin
=
src
[
j
+
roffset
];
const
uint8_t
gin
=
src
[
j
+
goffset
];
const
uint8_t
bin
=
src
[
j
+
boffset
];
dst
[
j
+
roffset
]
=
av_clip_uint8
(
cm
->
lut
[
R
][
R
][
rin
]
+
cm
->
lut
[
R
][
G
][
gin
]
+
cm
->
lut
[
R
][
B
][
bin
]);
dst
[
j
+
goffset
]
=
av_clip_uint8
(
cm
->
lut
[
G
][
R
][
rin
]
+
cm
->
lut
[
G
][
G
][
gin
]
+
cm
->
lut
[
G
][
B
][
bin
]);
dst
[
j
+
boffset
]
=
av_clip_uint8
(
cm
->
lut
[
B
][
R
][
rin
]
+
cm
->
lut
[
B
][
G
][
gin
]
+
cm
->
lut
[
B
][
B
][
bin
]);
if
(
in
!=
out
)
dst
[
j
+
aoffset
]
=
0
;
}
srcrow
+=
in
->
linesize
[
0
];
dstrow
+=
out
->
linesize
[
0
];
}
break
;
case
AV_PIX_FMT_ABGR
:
case
AV_PIX_FMT_ARGB
:
case
AV_PIX_FMT_BGRA
:
case
AV_PIX_FMT_RGBA
:
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
{
const
uint8_t
*
src
=
srcrow
;
uint8_t
*
dst
=
dstrow
;
for
(
j
=
0
;
j
<
outlink
->
w
*
4
;
j
+=
4
)
{
const
uint8_t
rin
=
src
[
j
+
roffset
];
const
uint8_t
gin
=
src
[
j
+
goffset
];
const
uint8_t
bin
=
src
[
j
+
boffset
];
const
uint8_t
ain
=
src
[
j
+
aoffset
];
dst
[
j
+
roffset
]
=
av_clip_uint8
(
cm
->
lut
[
R
][
R
][
rin
]
+
cm
->
lut
[
R
][
G
][
gin
]
+
cm
->
lut
[
R
][
B
][
bin
]
+
cm
->
lut
[
R
][
A
][
ain
]);
dst
[
j
+
goffset
]
=
av_clip_uint8
(
cm
->
lut
[
G
][
R
][
rin
]
+
cm
->
lut
[
G
][
G
][
gin
]
+
cm
->
lut
[
G
][
B
][
bin
]
+
cm
->
lut
[
G
][
A
][
ain
]);
dst
[
j
+
boffset
]
=
av_clip_uint8
(
cm
->
lut
[
B
][
R
][
rin
]
+
cm
->
lut
[
B
][
G
][
gin
]
+
cm
->
lut
[
B
][
B
][
bin
]
+
cm
->
lut
[
B
][
A
][
ain
]);
dst
[
j
+
aoffset
]
=
av_clip_uint8
(
cm
->
lut
[
A
][
R
][
rin
]
+
cm
->
lut
[
A
][
G
][
gin
]
+
cm
->
lut
[
A
][
B
][
bin
]
+
cm
->
lut
[
A
][
A
][
ain
]);
}
srcrow
+=
in
->
linesize
[
0
];
dstrow
+=
out
->
linesize
[
0
];
}
break
;
case
AV_PIX_FMT_BGR48
:
case
AV_PIX_FMT_RGB48
:
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
srcrow
;
uint16_t
*
dst
=
(
uint16_t
*
)
dstrow
;
for
(
j
=
0
;
j
<
outlink
->
w
*
3
;
j
+=
3
)
{
const
uint16_t
rin
=
src
[
j
+
roffset
];
const
uint16_t
gin
=
src
[
j
+
goffset
];
const
uint16_t
bin
=
src
[
j
+
boffset
];
dst
[
j
+
roffset
]
=
av_clip_uint16
(
cm
->
lut
[
R
][
R
][
rin
]
+
cm
->
lut
[
R
][
G
][
gin
]
+
cm
->
lut
[
R
][
B
][
bin
]);
dst
[
j
+
goffset
]
=
av_clip_uint16
(
cm
->
lut
[
G
][
R
][
rin
]
+
cm
->
lut
[
G
][
G
][
gin
]
+
cm
->
lut
[
G
][
B
][
bin
]);
dst
[
j
+
boffset
]
=
av_clip_uint16
(
cm
->
lut
[
B
][
R
][
rin
]
+
cm
->
lut
[
B
][
G
][
gin
]
+
cm
->
lut
[
B
][
B
][
bin
]);
}
srcrow
+=
in
->
linesize
[
0
];
dstrow
+=
out
->
linesize
[
0
];
}
break
;
case
AV_PIX_FMT_BGRA64
:
case
AV_PIX_FMT_RGBA64
:
for
(
i
=
0
;
i
<
outlink
->
h
;
i
++
)
{
const
uint16_t
*
src
=
(
const
uint16_t
*
)
srcrow
;
uint16_t
*
dst
=
(
uint16_t
*
)
dstrow
;
for
(
j
=
0
;
j
<
outlink
->
w
*
4
;
j
+=
4
)
{
const
uint16_t
rin
=
src
[
j
+
roffset
];
const
uint16_t
gin
=
src
[
j
+
goffset
];
const
uint16_t
bin
=
src
[
j
+
boffset
];
const
uint16_t
ain
=
src
[
j
+
aoffset
];
dst
[
j
+
roffset
]
=
av_clip_uint16
(
cm
->
lut
[
R
][
R
][
rin
]
+
cm
->
lut
[
R
][
G
][
gin
]
+
cm
->
lut
[
R
][
B
][
bin
]
+
cm
->
lut
[
R
][
A
][
ain
]);
dst
[
j
+
goffset
]
=
av_clip_uint16
(
cm
->
lut
[
G
][
R
][
rin
]
+
cm
->
lut
[
G
][
G
][
gin
]
+
cm
->
lut
[
G
][
B
][
bin
]
+
cm
->
lut
[
G
][
A
][
ain
]);
dst
[
j
+
boffset
]
=
av_clip_uint16
(
cm
->
lut
[
B
][
R
][
rin
]
+
cm
->
lut
[
B
][
G
][
gin
]
+
cm
->
lut
[
B
][
B
][
bin
]
+
cm
->
lut
[
B
][
A
][
ain
]);
dst
[
j
+
aoffset
]
=
av_clip_uint16
(
cm
->
lut
[
A
][
R
][
rin
]
+
cm
->
lut
[
A
][
G
][
gin
]
+
cm
->
lut
[
A
][
B
][
bin
]
+
cm
->
lut
[
A
][
A
][
ain
]);
}
srcrow
+=
in
->
linesize
[
0
];
dstrow
+=
out
->
linesize
[
0
];
}
}
if
(
in
!=
out
)
av_frame_free
(
&
in
);
return
ff_filter_frame
(
ctx
->
outputs
[
0
],
out
);
}
static
av_cold
void
uninit
(
AVFilterContext
*
ctx
)
{
ColorChannelMixerContext
*
cm
=
ctx
->
priv
;
av_freep
(
&
cm
->
buffer
);
}
static
const
AVFilterPad
colorchannelmixer_inputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
filter_frame
=
filter_frame
,
},
{
NULL
}
};
static
const
AVFilterPad
colorchannelmixer_outputs
[]
=
{
{
.
name
=
"default"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
config_props
=
config_output
,
},
{
NULL
}
};
AVFilter
avfilter_vf_colorchannelmixer
=
{
.
name
=
"colorchannelmixer"
,
.
description
=
NULL_IF_CONFIG_SMALL
(
"Adjust colors by mixing color channels."
),
.
priv_size
=
sizeof
(
ColorChannelMixerContext
),
.
priv_class
=
&
colorchannelmixer_class
,
.
uninit
=
uninit
,
.
query_formats
=
query_formats
,
.
inputs
=
colorchannelmixer_inputs
,
.
outputs
=
colorchannelmixer_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