FFmpeg
Loading...
Searching...
No Matches
colorchannelmixer_template.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <float.h>
22
23#undef pixel
24#undef cpixel
25#undef ROUND
26#if DEPTH == 8
27#define pixel uint8_t
28#define cpixel int
29#define ROUND lrintf
30#elif DEPTH == 16
31#define pixel uint16_t
32#define cpixel int
33#define ROUND lrintf
34#else
35#define NOP(x) (x)
36#define pixel float
37#define cpixel float
38#define ROUND NOP
39#endif
40
41#undef fn
42#undef fn2
43#undef fn3
44#define fn3(a,b) a##_##b
45#define fn2(a,b) fn3(a,b)
46#define fn(a) fn2(a, DEPTH)
47
48static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
49 int have_alpha, int depth, int pc)
50{
52 ThreadData *td = arg;
53 AVFrame *in = td->in;
54 AVFrame *out = td->out;
55 const float pa = s->preserve_amount;
56 const float max = (1 << depth) - 1;
57 const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs);
58 const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs);
59 const pixel *srcg = (const pixel *)(in->data[0] + slice_start * in->linesize[0]);
60 const pixel *srcb = (const pixel *)(in->data[1] + slice_start * in->linesize[1]);
61 const pixel *srcr = (const pixel *)(in->data[2] + slice_start * in->linesize[2]);
62 const pixel *srca = (const pixel *)(in->data[3] + slice_start * in->linesize[3]);
63 pixel *dstg = (pixel *)(out->data[0] + slice_start * out->linesize[0]);
64 pixel *dstb = (pixel *)(out->data[1] + slice_start * out->linesize[1]);
65 pixel *dstr = (pixel *)(out->data[2] + slice_start * out->linesize[2]);
66 pixel *dsta = (pixel *)(out->data[3] + slice_start * out->linesize[3]);
67
68 for (int i = slice_start; i < slice_end; i++) {
69 for (int j = 0; j < out->width; j++) {
70 const pixel rin = srcr[j];
71 const pixel gin = srcg[j];
72 const pixel bin = srcb[j];
73 const pixel ain = have_alpha ? srca[j] : 0;
74 cpixel rout, gout, bout;
75
76#if DEPTH == 32
77 rout = s->rr * rin +
78 s->rg * gin +
79 s->rb * bin +
80 (have_alpha == 1 ? s->ra * ain : 0);
81 gout = s->gr * rin +
82 s->gg * gin +
83 s->gb * bin +
84 (have_alpha == 1 ? s->ga * ain : 0);
85 bout = s->br * rin +
86 s->bg * gin +
87 s->bb * bin +
88 (have_alpha == 1 ? s->ba * ain : 0);
89#else
90 rout = s->lut[R][R][rin] +
91 s->lut[R][G][gin] +
92 s->lut[R][B][bin] +
93 (have_alpha == 1 ? s->lut[R][A][ain] : 0);
94 gout = s->lut[G][R][rin] +
95 s->lut[G][G][gin] +
96 s->lut[G][B][bin] +
97 (have_alpha == 1 ? s->lut[G][A][ain] : 0);
98 bout = s->lut[B][R][rin] +
99 s->lut[B][G][gin] +
100 s->lut[B][B][bin] +
101 (have_alpha == 1 ? s->lut[B][A][ain] : 0);
102#endif
103
104 if (pc) {
105 float frout, fgout, fbout, lin, lout;
106
107#if DEPTH < 32
108 frout = av_clipf(rout, 0.f, max);
109 fgout = av_clipf(gout, 0.f, max);
110 fbout = av_clipf(bout, 0.f, max);
111#else
112 frout = rout;
113 fgout = gout;
114 fbout = bout;
115#endif
116
117 preserve_color(s->preserve_color, rin, gin, bin,
118 rout, gout, bout, max, &lin, &lout);
119 preservel(&frout, &fgout, &fbout, lin, lout, max);
120
121 rout = ROUND(lerpf(rout, frout, pa));
122 gout = ROUND(lerpf(gout, fgout, pa));
123 bout = ROUND(lerpf(bout, fbout, pa));
124 }
125
126#if DEPTH < 32
127 dstr[j] = av_clip_uintp2(rout, depth);
128 dstg[j] = av_clip_uintp2(gout, depth);
129 dstb[j] = av_clip_uintp2(bout, depth);
130#else
131 dstr[j] = rout;
132 dstg[j] = gout;
133 dstb[j] = bout;
134#endif
135
136 if (have_alpha == 1) {
137#if DEPTH < 32
138 dsta[j] = av_clip_uintp2(s->lut[A][R][rin] +
139 s->lut[A][G][gin] +
140 s->lut[A][B][bin] +
141 s->lut[A][A][ain], depth);
142#else
143 dsta[j] = s->ar * rin +
144 s->ag * gin +
145 s->ab * bin +
146 s->aa * ain;
147#endif
148 }
149 }
150
151 srcg += in->linesize[0] / sizeof(pixel);
152 srcb += in->linesize[1] / sizeof(pixel);
153 srcr += in->linesize[2] / sizeof(pixel);
154 srca += in->linesize[3] / sizeof(pixel);
155 dstg += out->linesize[0] / sizeof(pixel);
156 dstb += out->linesize[1] / sizeof(pixel);
157 dstr += out->linesize[2] / sizeof(pixel);
158 dsta += out->linesize[3] / sizeof(pixel);
159 }
160
161 return 0;
162}
163
164#if DEPTH < 32
165
166static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
167 int have_alpha, int step, int pc, int depth)
168{
170 ThreadData *td = arg;
171 AVFrame *in = td->in;
172 AVFrame *out = td->out;
173 const float pa = s->preserve_amount;
174 const float max = (1 << depth) - 1;
175 const int slice_start = ff_slice_pos(out->height, jobnr, nb_jobs);
176 const int slice_end = ff_slice_pos(out->height, jobnr + 1, nb_jobs);
177 const uint8_t roffset = s->rgba_map[R];
178 const uint8_t goffset = s->rgba_map[G];
179 const uint8_t boffset = s->rgba_map[B];
180 const uint8_t aoffset = s->rgba_map[A];
181 const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0];
182 uint8_t *dstrow = out->data[0] + slice_start * out->linesize[0];
183 int i, j;
184
185 for (i = slice_start; i < slice_end; i++) {
186 const pixel *src = (const pixel *)srcrow;
187 pixel *dst = (pixel *)dstrow;
188
189 for (j = 0; j < out->width * step; j += step) {
190 const pixel rin = src[j + roffset];
191 const pixel gin = src[j + goffset];
192 const pixel bin = src[j + boffset];
193 const pixel ain = src[j + aoffset];
194 int rout, gout, bout;
195
196 rout = s->lut[R][R][rin] +
197 s->lut[R][G][gin] +
198 s->lut[R][B][bin] +
199 (have_alpha == 1 ? s->lut[R][A][ain] : 0);
200 gout = s->lut[G][R][rin] +
201 s->lut[G][G][gin] +
202 s->lut[G][B][bin] +
203 (have_alpha == 1 ? s->lut[G][A][ain] : 0);
204 bout = s->lut[B][R][rin] +
205 s->lut[B][G][gin] +
206 s->lut[B][B][bin] +
207 (have_alpha == 1 ? s->lut[B][A][ain] : 0);
208
209 if (pc) {
210 float frout = av_clipf(rout, 0.f, max);
211 float fgout = av_clipf(gout, 0.f, max);
212 float fbout = av_clipf(bout, 0.f, max);
213 float lin, lout;
214
215 preserve_color(s->preserve_color, rin, gin, bin,
216 rout, gout, bout, max, &lin, &lout);
217 preservel(&frout, &fgout, &fbout, lin, lout, max);
218
219 rout = lrintf(lerpf(rout, frout, pa));
220 gout = lrintf(lerpf(gout, fgout, pa));
221 bout = lrintf(lerpf(bout, fbout, pa));
222 }
223
224 dst[j + roffset] = av_clip_uintp2(rout, depth);
225 dst[j + goffset] = av_clip_uintp2(gout, depth);
226 dst[j + boffset] = av_clip_uintp2(bout, depth);
227
228 if (have_alpha == 1) {
229 dst[j + aoffset] = av_clip_uintp2(s->lut[A][R][rin] +
230 s->lut[A][G][gin] +
231 s->lut[A][B][bin] +
232 s->lut[A][A][ain], depth);
233 }
234 }
235
236 srcrow += in->linesize[0];
237 dstrow += out->linesize[0];
238 }
239
240 return 0;
241}
242
243#endif
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define A(x)
Definition vpx_arith.h:28
#define pixel
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static av_always_inline int fn filter_slice_rgba_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int step, int pc, int depth)
#define fn(a)
#define cpixel
static av_always_inline int fn filter_slice_rgba_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int depth, int pc)
#define ROUND
#define av_clip_uintp2
Definition common.h:124
#define av_clipf
Definition common.h:145
#define max(a, b)
#define B
Definition huffyuv.h:42
#define R
Definition huffyuv.h:44
#define G
Definition huffyuv.h:43
const char * arg
Definition jacosubdec.c:65
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define av_always_inline
Definition attributes.h:72
#define lrintf(x)
Definition libm_mips.h:72
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition mpeg12dec.c:1697
static void preserve_color(int preserve_color, float ir, float ig, float ib, float r, float g, float b, float max, float *icolor, float *ocolor)
An instance of a filter.
Definition avfilter.h:273
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
Used for passing data between threads.
Definition dsddec.c:71
AVFrame * out
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static float lerpf(float v0, float v1, float f)
Definition vf_cas.c:42
static void preservel(float *r, float *g, float *b, float l)
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition dec.c:844