History

avfilter/vf_colorlevels: add planar rgb formats support

Paul B Mahol committed 4 years ago

Commit 10c2ef11 parent 47c3b341 file · +189 −43Browse files

Unified · Split

libavfilter/vf_colorlevels.c+189−43
@@ -44,6 +44,9 @@ typedef struct ColorLevelsContext { · 43 unmodified lines
4444 int preserve_color;
4545
4646 int nb_comp;
47+ int depth;
48+ int max;
49+ int planar;
4750 int bpp;
4851 int step;
4952 uint8_t rgba_map[4];
@@ -85,8 +88,8 @@ static const AVOption colorlevels_options[] = { · 35 unmodified lines
8588 AVFILTER_DEFINE_CLASS(colorlevels);
8689
8790 typedef struct ThreadData {
88− const uint8_t *srcrow;
89− uint8_t *dstrow;
91+ const uint8_t *srcrow[4];
92+ uint8_t *dstrow[4];
9093 int dst_linesize;
9194 int src_linesize;
9295
@@ -98,8 +101,7 @@ typedef struct ThreadData { · 5 unmodified lines
98101 int omin[4];
99102 } ThreadData;
100103
101−#define DO_COMMON(type, clip, preserve) \
102− ColorLevelsContext *s = ctx->priv; \
104+#define DO_COMMON(type, clip, preserve, planar) \
103105 const ThreadData *td = arg; \
104106 const int linesize = s->linesize; \
105107 const int step = s->step; \
@@ -108,12 +110,14 @@ typedef struct ThreadData { · 2 unmodified lines
108110 const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \
109111 const int src_linesize = td->src_linesize / sizeof(type); \
110112 const int dst_linesize = td->dst_linesize / sizeof(type); \
111− const type *srcrow = (const type *)td->srcrow + src_linesize * slice_start; \
112− type *dstrow = (type *)td->dstrow + dst_linesize * slice_start; \
113− const uint8_t offset_r = s->rgba_map[R]; \
114− const uint8_t offset_g = s->rgba_map[G]; \
115− const uint8_t offset_b = s->rgba_map[B]; \
116− const uint8_t offset_a = s->rgba_map[A]; \
113+ const type *src_r = (const type *)(td->srcrow[R]) + src_linesize * slice_start; \
114+ const type *src_g = (const type *)(td->srcrow[G]) + src_linesize * slice_start; \
115+ const type *src_b = (const type *)(td->srcrow[B]) + src_linesize * slice_start; \
116+ const type *src_a = (const type *)(td->srcrow[A]) + src_linesize * slice_start; \
117+ type *dst_r = (type *)(td->dstrow[R]) + src_linesize * slice_start; \
118+ type *dst_g = (type *)(td->dstrow[G]) + src_linesize * slice_start; \
119+ type *dst_b = (type *)(td->dstrow[B]) + src_linesize * slice_start; \
120+ type *dst_a = (type *)(td->dstrow[A]) + src_linesize * slice_start; \
117121 const int imin_r = td->imin[R]; \
118122 const int imin_g = td->imin[G]; \
119123 const int imin_b = td->imin[B]; \
@@ -126,14 +130,6 @@ typedef struct ThreadData { · 6 unmodified lines
126130 const float coeff_g = td->coeff[G]; \
127131 const float coeff_b = td->coeff[B]; \
128132 const float coeff_a = td->coeff[A]; \
129− const type *src_r = srcrow + offset_r; \
130− const type *src_g = srcrow + offset_g; \
131− const type *src_b = srcrow + offset_b; \
132− const type *src_a = srcrow + offset_a; \
133− type *dst_r = dstrow + offset_r; \
134− type *dst_g = dstrow + offset_g; \
135− type *dst_b = dstrow + offset_b; \
136− type *dst_a = dstrow + offset_a; \
137133 \
138134 for (int y = slice_start; y < slice_end; y++) { \
139135 for (int x = 0; x < linesize; x += step) { \
@@ -142,7 +138,7 @@ typedef struct ThreadData { · 2 unmodified lines
142138 ig = src_g[x]; \
143139 ib = src_b[x]; \
144140 if (preserve) { \
145− float ratio, icolor, ocolor, max = (1<<(8*sizeof(type)))-1; \
141+ float ratio, icolor, ocolor, max = s->max; \
146142 \
147143 or = (ir - imin_r) * coeff_r + omin_r; \
148144 og = (ig - imin_g) * coeff_g + omin_g; \
@@ -158,18 +154,18 @@ typedef struct ThreadData { · 9 unmodified lines
158154 ob *= ratio; \
159155 } \
160156 \
161− dst_r[x] = clip(or); \
162− dst_g[x] = clip(og); \
163− dst_b[x] = clip(ob); \
157+ dst_r[x] = clip(or, depth); \
158+ dst_g[x] = clip(og, depth); \
159+ dst_b[x] = clip(ob, depth); \
164160 } else { \
165− dst_r[x] = clip((ir - imin_r) * coeff_r + omin_r); \
166− dst_g[x] = clip((ig - imin_g) * coeff_g + omin_g); \
167− dst_b[x] = clip((ib - imin_b) * coeff_b + omin_b); \
161+ dst_r[x] = clip((ir - imin_r) * coeff_r + omin_r, depth); \
162+ dst_g[x] = clip((ig - imin_g) * coeff_g + omin_g, depth); \
163+ dst_b[x] = clip((ib - imin_b) * coeff_b + omin_b, depth); \
168164 } \
169165 } \
170166 \
171167 for (int x = 0; x < linesize && s->nb_comp == 4; x += step) \
172− dst_a[x] = clip((src_a[x] - imin_a) * coeff_a + omin_a); \
168+ dst_a[x] = clip((src_a[x] - imin_a) * coeff_a + omin_a, depth); \
173169 \
174170 src_r += src_linesize; \
175171 src_g += src_linesize; \
@@ -182,31 +178,126 @@ typedef struct ThreadData { · 6 unmodified lines
182178 dst_a += dst_linesize; \
183179 }
184180
181+#define CLIP8(x, depth) av_clip_uint8(x)
182+#define CLIP16(x, depth) av_clip_uint16(x)
183+
185184 static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
186185 {
187− DO_COMMON(uint8_t, av_clip_uint8, 0)
188−
186+ ColorLevelsContext *s = ctx->priv;
187+ DO_COMMON(uint8_t, CLIP8, 0, 0)
189188 return 0;
190189 }
191190
192191 static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
193192 {
194− DO_COMMON(uint16_t, av_clip_uint16, 0)
195−
193+ ColorLevelsContext *s = ctx->priv;\
194+ DO_COMMON(uint16_t, CLIP16, 0, 0)
196195 return 0;
197196 }
198197
199198 static int colorlevels_preserve_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
200199 {
201− DO_COMMON(uint8_t, av_clip_uint8, 1)
202−
200+ ColorLevelsContext *s = ctx->priv;
201+ DO_COMMON(uint8_t, CLIP8, 1, 0)
203202 return 0;
204203 }
205204
206205 static int colorlevels_preserve_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
207206 {
208− DO_COMMON(uint16_t, av_clip_uint16, 1)
207+ ColorLevelsContext *s = ctx->priv;
208+ DO_COMMON(uint16_t, CLIP16, 1, 0)
209+ return 0;
210+}
211+
212+static int colorlevels_slice_8_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
213+{
214+ ColorLevelsContext *s = ctx->priv;
215+ DO_COMMON(uint8_t, CLIP8, 0, 1)
216+ return 0;
217+}
218+
219+static int colorlevels_slice_9_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
220+{
221+ ColorLevelsContext *s = ctx->priv;
222+ const int depth = s->depth;
223+ DO_COMMON(uint16_t, av_clip_uintp2, 0, 1)
224+ return 0;
225+}
226+
227+static int colorlevels_slice_10_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
228+{
229+ ColorLevelsContext *s = ctx->priv;
230+ const int depth = s->depth;
231+ DO_COMMON(uint16_t, av_clip_uintp2, 0, 1)
232+ return 0;
233+}
234+
235+static int colorlevels_slice_12_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
236+{
237+ ColorLevelsContext *s = ctx->priv;
238+ const int depth = s->depth;
239+ DO_COMMON(uint16_t, av_clip_uintp2, 0, 1)
240+ return 0;
241+}
242+
243+static int colorlevels_slice_14_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
244+{
245+ ColorLevelsContext *s = ctx->priv;
246+ const int depth = s->depth;
247+ DO_COMMON(uint16_t, av_clip_uintp2, 0, 1)
248+ return 0;
249+}
209250
251+static int colorlevels_slice_16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
252+{
253+ ColorLevelsContext *s = ctx->priv;
254+ DO_COMMON(uint16_t, CLIP16, 0, 1)
255+ return 0;
256+}
257+
258+static int colorlevels_preserve_slice_8_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
259+{
260+ ColorLevelsContext *s = ctx->priv;
261+ DO_COMMON(uint8_t, CLIP8, 1, 1)
262+ return 0;
263+}
264+
265+static int colorlevels_preserve_slice_9_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
266+{
267+ ColorLevelsContext *s = ctx->priv;
268+ const int depth = s->depth;
269+ DO_COMMON(uint16_t, av_clip_uintp2, 1, 1)
270+ return 0;
271+}
272+
273+static int colorlevels_preserve_slice_10_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
274+{
275+ ColorLevelsContext *s = ctx->priv;
276+ const int depth = s->depth;
277+ DO_COMMON(uint16_t, av_clip_uintp2, 1, 1)
278+ return 0;
279+}
280+
281+static int colorlevels_preserve_slice_12_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
282+{
283+ ColorLevelsContext *s = ctx->priv;
284+ const int depth = s->depth;
285+ DO_COMMON(uint16_t, av_clip_uintp2, 1, 1)
286+ return 0;
287+}
288+
289+static int colorlevels_preserve_slice_14_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
290+{
291+ ColorLevelsContext *s = ctx->priv;
292+ const int depth = s->depth;
293+ DO_COMMON(uint16_t, av_clip_uintp2, 1, 1)
294+ return 0;
295+}
296+
297+static int colorlevels_preserve_slice_16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
298+{
299+ ColorLevelsContext *s = ctx->priv;
300+ DO_COMMON(uint16_t, CLIP16, 1, 1)
210301 return 0;
211302 }
212303
@@ -217,16 +308,48 @@ static int config_input(AVFilterLink *inlink) · 4 unmodified lines
217308 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
218309
219310 s->nb_comp = desc->nb_components;
220− s->bpp = desc->comp[0].depth >> 3;
221− s->step = av_get_padded_bits_per_pixel(desc) >> (3 + (s->bpp == 2));
311+ s->planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR;
312+ s->depth = desc->comp[0].depth;
313+ s->max = (1 << s->depth) - 1;
314+ s->bpp = (desc->comp[0].depth + 7) >> 3;
315+ s->step = s->planar ? 1 : av_get_padded_bits_per_pixel(desc) >> (3 + (s->bpp == 2));
222316 s->linesize = inlink->w * s->step;
223317 ff_fill_rgba_map(s->rgba_map, inlink->format);
224318
225− s->colorlevels_slice[0] = colorlevels_slice_8;
226− s->colorlevels_slice[1] = colorlevels_preserve_slice_8;
227− if (s->bpp == 2) {
228− s->colorlevels_slice[0] = colorlevels_slice_16;
229− s->colorlevels_slice[1] = colorlevels_preserve_slice_16;
319+ if (!s->planar) {
320+ s->colorlevels_slice[0] = colorlevels_slice_8;
321+ s->colorlevels_slice[1] = colorlevels_preserve_slice_8;
322+ if (s->bpp == 2) {
323+ s->colorlevels_slice[0] = colorlevels_slice_16;
324+ s->colorlevels_slice[1] = colorlevels_preserve_slice_16;
325+ }
326+ } else {
327+ switch (s->depth) {
328+ case 8:
329+ s->colorlevels_slice[0] = colorlevels_slice_8_planar;
330+ s->colorlevels_slice[1] = colorlevels_preserve_slice_8_planar;
331+ break;
332+ case 9:
333+ s->colorlevels_slice[0] = colorlevels_slice_9_planar;
334+ s->colorlevels_slice[1] = colorlevels_preserve_slice_9_planar;
335+ break;
336+ case 10:
337+ s->colorlevels_slice[0] = colorlevels_slice_10_planar;
338+ s->colorlevels_slice[1] = colorlevels_preserve_slice_10_planar;
339+ break;
340+ case 12:
341+ s->colorlevels_slice[0] = colorlevels_slice_12_planar;
342+ s->colorlevels_slice[1] = colorlevels_preserve_slice_12_planar;
343+ break;
344+ case 14:
345+ s->colorlevels_slice[0] = colorlevels_slice_14_planar;
346+ s->colorlevels_slice[1] = colorlevels_preserve_slice_14_planar;
347+ break;
348+ case 16:
349+ s->colorlevels_slice[0] = colorlevels_slice_16_planar;
350+ s->colorlevels_slice[1] = colorlevels_preserve_slice_16_planar;
351+ break;
352+ }
230353 }
231354
232355 return 0;
@@ -255,8 +378,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 22 unmodified lines
255378 td.h = inlink->h;
256379 td.dst_linesize = out->linesize[0];
257380 td.src_linesize = in->linesize[0];
258− td.srcrow = in->data[0];
259− td.dstrow = out->data[0];
381+ if (s->planar) {
382+ td.srcrow[R] = in->data[2];
383+ td.dstrow[R] = out->data[2];
384+ td.srcrow[G] = in->data[0];
385+ td.dstrow[G] = out->data[0];
386+ td.srcrow[B] = in->data[1];
387+ td.dstrow[B] = out->data[1];
388+ td.srcrow[A] = in->data[3];
389+ td.dstrow[A] = out->data[3];
390+ } else {
391+ td.srcrow[R] = in->data[0] + s->rgba_map[R] * s->bpp;
392+ td.dstrow[R] = out->data[0] + s->rgba_map[R] * s->bpp;
393+ td.srcrow[G] = in->data[0] + s->rgba_map[G] * s->bpp;
394+ td.dstrow[G] = out->data[0] + s->rgba_map[G] * s->bpp;
395+ td.srcrow[B] = in->data[0] + s->rgba_map[B] * s->bpp;
396+ td.dstrow[B] = out->data[0] + s->rgba_map[B] * s->bpp;
397+ td.srcrow[A] = in->data[0] + s->rgba_map[A] * s->bpp;
398+ td.dstrow[A] = out->data[0] + s->rgba_map[A] * s->bpp;
399+ }
260400
261401 switch (s->bpp) {
262402 case 1:
@@ -378,7 +518,13 @@ const AVFilter ff_vf_colorlevels = { · 115 unmodified lines
378518 AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
379519 AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48,
380520 AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64,
381− AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA),
521+ AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
522+ AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
523+ AV_PIX_FMT_GBRP9,
524+ AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
525+ AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
526+ AV_PIX_FMT_GBRP14,
527+ AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16),
382528 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
383529 .process_command = ff_filter_process_command,
384530 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t