You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avfilter/vf_colorchannelmixer: add float formats support
This commit is contained in:
		| @@ -21,10 +21,21 @@ | ||||
| #include <float.h> | ||||
|  | ||||
| #undef pixel | ||||
| #undef cpixel | ||||
| #undef ROUND | ||||
| #if DEPTH == 8 | ||||
| #define pixel uint8_t | ||||
| #define cpixel int | ||||
| #define ROUND lrintf | ||||
| #elif DEPTH == 16 | ||||
| #define pixel uint16_t | ||||
| #define cpixel int | ||||
| #define ROUND lrintf | ||||
| #else | ||||
| #define NOP(x) (x) | ||||
| #define pixel float | ||||
| #define cpixel float | ||||
| #define ROUND NOP | ||||
| #endif | ||||
|  | ||||
| #undef fn | ||||
| @@ -60,8 +71,22 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v | ||||
|             const pixel gin = srcg[j]; | ||||
|             const pixel bin = srcb[j]; | ||||
|             const pixel ain = have_alpha ? srca[j] : 0; | ||||
|             int rout, gout, bout; | ||||
|             cpixel rout, gout, bout; | ||||
|  | ||||
| #if DEPTH == 32 | ||||
|             rout = s->rr * rin + | ||||
|                    s->rg * gin + | ||||
|                    s->rb * bin + | ||||
|                    (have_alpha == 1 ? s->ra * ain : 0); | ||||
|             gout = s->gr * rin + | ||||
|                    s->gg * gin + | ||||
|                    s->gb * bin + | ||||
|                    (have_alpha == 1 ? s->ga * ain : 0); | ||||
|             bout = s->br * rin + | ||||
|                    s->bg * gin + | ||||
|                    s->bb * bin + | ||||
|                    (have_alpha == 1 ? s->ba * ain : 0); | ||||
| #else | ||||
|             rout = s->lut[R][R][rin] + | ||||
|                    s->lut[R][G][gin] + | ||||
|                    s->lut[R][B][bin] + | ||||
| @@ -74,31 +99,52 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v | ||||
|                    s->lut[B][G][gin] + | ||||
|                    s->lut[B][B][bin] + | ||||
|                    (have_alpha == 1 ? s->lut[B][A][ain] : 0); | ||||
| #endif | ||||
|  | ||||
|             if (pc) { | ||||
|                 float frout = av_clipf(rout, 0.f, max); | ||||
|                 float fgout = av_clipf(gout, 0.f, max); | ||||
|                 float fbout = av_clipf(bout, 0.f, max); | ||||
|                 float lin, lout; | ||||
|                 float frout, fgout, fbout, lin, lout; | ||||
|  | ||||
| #if DEPTH < 32 | ||||
|                 frout = av_clipf(rout, 0.f, max); | ||||
|                 fgout = av_clipf(gout, 0.f, max); | ||||
|                 fbout = av_clipf(bout, 0.f, max); | ||||
| #else | ||||
|                 frout = rout; | ||||
|                 fgout = gout; | ||||
|                 fbout = bout; | ||||
| #endif | ||||
|  | ||||
|                 preserve_color(s->preserve_color, rin, gin, bin, | ||||
|                                rout, gout, bout, max, &lin, &lout); | ||||
|                 preservel(&frout, &fgout, &fbout, lin, lout, max); | ||||
|  | ||||
|                 rout = lrintf(lerpf(rout, frout, pa)); | ||||
|                 gout = lrintf(lerpf(gout, fgout, pa)); | ||||
|                 bout = lrintf(lerpf(bout, fbout, pa)); | ||||
|                 rout = ROUND(lerpf(rout, frout, pa)); | ||||
|                 gout = ROUND(lerpf(gout, fgout, pa)); | ||||
|                 bout = ROUND(lerpf(bout, fbout, pa)); | ||||
|             } | ||||
|  | ||||
| #if DEPTH < 32 | ||||
|             dstr[j] = av_clip_uintp2(rout, depth); | ||||
|             dstg[j] = av_clip_uintp2(gout, depth); | ||||
|             dstb[j] = av_clip_uintp2(bout, depth); | ||||
| #else | ||||
|             dstr[j] = rout; | ||||
|             dstg[j] = gout; | ||||
|             dstb[j] = bout; | ||||
| #endif | ||||
|  | ||||
|             if (have_alpha == 1) { | ||||
| #if DEPTH < 32 | ||||
|                 dsta[j] = av_clip_uintp2(s->lut[A][R][rin] + | ||||
|                                          s->lut[A][G][gin] + | ||||
|                                          s->lut[A][B][bin] + | ||||
|                                          s->lut[A][A][ain], depth); | ||||
| #else | ||||
|                 dsta[j] = s->ar * rin + | ||||
|                           s->ag * gin + | ||||
|                           s->ab * bin + | ||||
|                           s->aa * ain; | ||||
| #endif | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -115,6 +161,8 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #if DEPTH < 32 | ||||
|  | ||||
| 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) | ||||
| { | ||||
| @@ -191,3 +239,5 @@ static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, v | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -77,6 +77,10 @@ static void preservel(float *r, float *g, float *b, float lin, float lout, float | ||||
| #define DEPTH 16 | ||||
| #include "colorchannelmixer_template.c" | ||||
|  | ||||
| #undef DEPTH | ||||
| #define DEPTH 32 | ||||
| #include "colorchannelmixer_template.c" | ||||
|  | ||||
| #define OFFSET(x) offsetof(ColorChannelMixerContext, x) | ||||
| #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM | ||||
|  | ||||
| @@ -125,6 +129,7 @@ static const enum AVPixelFormat pix_fmts[] = { | ||||
|     AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, | ||||
|     AV_PIX_FMT_GBRP14, | ||||
|     AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, | ||||
|     AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, | ||||
|     AV_PIX_FMT_NONE | ||||
| }; | ||||
|  | ||||
| @@ -278,6 +283,26 @@ static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int | ||||
|     return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 1, 8); | ||||
| } | ||||
|  | ||||
| static int filter_slice_gbrp32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 0); | ||||
| } | ||||
|  | ||||
| static int filter_slice_gbrap32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 0); | ||||
| } | ||||
|  | ||||
| static int filter_slice_gbrp32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 1); | ||||
| } | ||||
|  | ||||
| static int filter_slice_gbrap32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 1); | ||||
| } | ||||
|  | ||||
| static int config_output(AVFilterLink *outlink) | ||||
| { | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
| @@ -391,6 +416,14 @@ static int config_output(AVFilterLink *outlink) | ||||
|         s->filter_slice[0] = filter_slice_gbrap16; | ||||
|         s->filter_slice[1] = filter_slice_gbrap16_pl; | ||||
|         break; | ||||
|     case AV_PIX_FMT_GBRPF32: | ||||
|         s->filter_slice[0] = filter_slice_gbrp32; | ||||
|         s->filter_slice[1] = filter_slice_gbrp32_pl; | ||||
|         break; | ||||
|     case AV_PIX_FMT_GBRAPF32: | ||||
|         s->filter_slice[0] = filter_slice_gbrap32; | ||||
|         s->filter_slice[1] = filter_slice_gbrap32_pl; | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user