Go to the documentation of this file.
   27 #include "config_components.h" 
   46 #define OFFSET(x) offsetof(LUT3DContext, x) 
   47 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM 
   48 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM 
   49 #define COMMON_OPTIONS \ 
   50     { "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, NB_INTERP_MODE-1, TFLAGS, "interp_mode" }, \ 
   51         { "nearest",     "use values from the nearest defined points",            0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_NEAREST},     0, 0, TFLAGS, "interp_mode" }, \ 
   52         { "trilinear",   "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR},   0, 0, TFLAGS, "interp_mode" }, \ 
   53         { "tetrahedral", "interpolate values using a tetrahedron",                0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, 0, TFLAGS, "interp_mode" }, \ 
   54         { "pyramid",     "interpolate values using a pyramid",                    0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PYRAMID},     0, 0, TFLAGS, "interp_mode" }, \ 
   55         { "prism",       "interpolate values using a prism",                      0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PRISM},       0, 0, TFLAGS, "interp_mode" }, \ 
   58 #define EXPONENT_MASK 0x7F800000 
   59 #define MANTISSA_MASK 0x007FFFFF 
   60 #define SIGN_MASK     0x80000000 
   82 static inline float lerpf(
float v0, 
float v1, 
float f)
 
   84     return v0 + (v1 - 
v0) * 
f;
 
   95 #define NEAR(x) ((int)((x) + .5)) 
   96 #define PREV(x) ((int)(x)) 
   97 #define NEXT(x) (FFMIN((int)(x) + 1, lut3d->lutsize - 1)) 
  105     return lut3d->lut[
NEAR(
s->r) * lut3d->lutsize2 + 
NEAR(
s->g) * lut3d->lutsize + 
NEAR(
s->b)];
 
  115     const int lutsize2 = lut3d->lutsize2;
 
  116     const int lutsize  = lut3d->lutsize;
 
  119     const struct rgbvec d = {
s->r - prev[0], 
s->g - prev[1], 
s->b - prev[2]};
 
  120     const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  121     const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  122     const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  123     const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  124     const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  125     const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  126     const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  127     const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  141     const int lutsize2 = lut3d->lutsize2;
 
  142     const int lutsize  = lut3d->lutsize;
 
  145     const struct rgbvec d = {
s->r - prev[0], 
s->g - prev[1], 
s->b - prev[2]};
 
  146     const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  147     const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  150     if (
d.g > 
d.r && 
d.b > 
d.r) {
 
  151         const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  152         const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  153         const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  155         c.r = c000.
r + (c111.
r - c011.
r) * 
d.r + (c010.
r - c000.
r) * 
d.g + (c001.
r - c000.
r) * 
d.b +
 
  156               (c011.
r - c001.
r - c010.
r + c000.
r) * 
d.g * 
d.b;
 
  157         c.g = c000.
g + (c111.
g - c011.
g) * 
d.r + (c010.
g - c000.
g) * 
d.g + (c001.
g - c000.
g) * 
d.b +
 
  158               (c011.
g - c001.
g - c010.
g + c000.
g) * 
d.g * 
d.b;
 
  159         c.b = c000.
b + (c111.
b - c011.
b) * 
d.r + (c010.
b - c000.
b) * 
d.g + (c001.
b - c000.
b) * 
d.b +
 
  160               (c011.
b - c001.
b - c010.
b + c000.
b) * 
d.g * 
d.b;
 
  161     } 
else if (
d.r > 
d.g && 
d.b > 
d.g) {
 
  162         const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  163         const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  164         const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  166         c.r = c000.
r + (c100.
r - c000.
r) * 
d.r + (c111.
r - c101.
r) * 
d.g + (c001.
r - c000.
r) * 
d.b +
 
  167               (c101.
r - c001.
r - c100.
r + c000.
r) * 
d.r * 
d.b;
 
  168         c.g = c000.
g + (c100.
g - c000.
g) * 
d.r + (c111.
g - c101.
g) * 
d.g + (c001.
g - c000.
g) * 
d.b +
 
  169               (c101.
g - c001.
g - c100.
g + c000.
g) * 
d.r * 
d.b;
 
  170         c.b = c000.
b + (c100.
b - c000.
b) * 
d.r + (c111.
b - c101.
b) * 
d.g + (c001.
b - c000.
b) * 
d.b +
 
  171               (c101.
b - c001.
b - c100.
b + c000.
b) * 
d.r * 
d.b;
 
  173         const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  174         const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  175         const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  177         c.r = c000.
r + (c100.
r - c000.
r) * 
d.r + (c010.
r - c000.
r) * 
d.g + (c111.
r - c110.
r) * 
d.b +
 
  178               (c110.
r - c100.
r - c010.
r + c000.
r) * 
d.r * 
d.g;
 
  179         c.g = c000.
g + (c100.
g - c000.
g) * 
d.r + (c010.
g - c000.
g) * 
d.g + (c111.
g - c110.
g) * 
d.b +
 
  180               (c110.
g - c100.
g - c010.
g + c000.
g) * 
d.r * 
d.g;
 
  181         c.b = c000.
b + (c100.
b - c000.
b) * 
d.r + (c010.
b - c000.
b) * 
d.g + (c111.
b - c110.
b) * 
d.b +
 
  182               (c110.
b - c100.
b - c010.
b + c000.
b) * 
d.r * 
d.g;
 
  191     const int lutsize2 = lut3d->lutsize2;
 
  192     const int lutsize  = lut3d->lutsize;
 
  195     const struct rgbvec d = {
s->r - prev[0], 
s->g - prev[1], 
s->b - prev[2]};
 
  196     const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  197     const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  198     const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  199     const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  203         const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  204         const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  206         c.r = c000.
r + (c001.
r - c000.
r) * 
d.b + (c101.
r - c001.
r) * 
d.r + (c010.
r - c000.
r) * 
d.g +
 
  207               (c000.
r - c010.
r - c001.
r + c011.
r) * 
d.b * 
d.g +
 
  208               (c001.
r - c011.
r - c101.
r + c111.
r) * 
d.r * 
d.g;
 
  209         c.g = c000.
g + (c001.
g - c000.
g) * 
d.b + (c101.
g - c001.
g) * 
d.r + (c010.
g - c000.
g) * 
d.g +
 
  210               (c000.
g - c010.
g - c001.
g + c011.
g) * 
d.b * 
d.g +
 
  211               (c001.
g - c011.
g - c101.
g + c111.
g) * 
d.r * 
d.g;
 
  212         c.b = c000.
b + (c001.
b - c000.
b) * 
d.b + (c101.
b - c001.
b) * 
d.r + (c010.
b - c000.
b) * 
d.g +
 
  213               (c000.
b - c010.
b - c001.
b + c011.
b) * 
d.b * 
d.g +
 
  214               (c001.
b - c011.
b - c101.
b + c111.
b) * 
d.r * 
d.g;
 
  216         const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  217         const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  219         c.r = c000.
r + (c101.
r - c100.
r) * 
d.b + (c100.
r - c000.
r) * 
d.r + (c010.
r - c000.
r) * 
d.g +
 
  220               (c100.
r - c110.
r - c101.
r + c111.
r) * 
d.b * 
d.g +
 
  221               (c000.
r - c010.
r - c100.
r + c110.
r) * 
d.r * 
d.g;
 
  222         c.g = c000.
g + (c101.
g - c100.
g) * 
d.b + (c100.
g - c000.
g) * 
d.r + (c010.
g - c000.
g) * 
d.g +
 
  223               (c100.
g - c110.
g - c101.
g + c111.
g) * 
d.b * 
d.g +
 
  224               (c000.
g - c010.
g - c100.
g + c110.
g) * 
d.r * 
d.g;
 
  225         c.b = c000.
b + (c101.
b - c100.
b) * 
d.b + (c100.
b - c000.
b) * 
d.r + (c010.
b - c000.
b) * 
d.g +
 
  226               (c100.
b - c110.
b - c101.
b + c111.
b) * 
d.b * 
d.g +
 
  227               (c000.
b - c010.
b - c100.
b + c110.
b) * 
d.r * 
d.g;
 
  240     const int lutsize2 = lut3d->lutsize2;
 
  241     const int lutsize  = lut3d->lutsize;
 
  244     const struct rgbvec d = {
s->r - prev[0], 
s->g - prev[1], 
s->b - prev[2]};
 
  245     const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  246     const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  250             const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  251             const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  252             c.r = (1-
d.r) * c000.
r + (
d.r-
d.g) * c100.
r + (
d.g-
d.b) * c110.
r + (
d.b) * c111.
r;
 
  253             c.g = (1-
d.r) * c000.
g + (
d.r-
d.g) * c100.
g + (
d.g-
d.b) * c110.
g + (
d.b) * c111.
g;
 
  254             c.b = (1-
d.r) * c000.
b + (
d.r-
d.g) * c100.
b + (
d.g-
d.b) * c110.
b + (
d.b) * c111.
b;
 
  255         } 
else if (
d.r > 
d.b) {
 
  256             const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
 
  257             const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  258             c.r = (1-
d.r) * c000.
r + (
d.r-
d.b) * c100.
r + (
d.b-
d.g) * c101.
r + (
d.g) * c111.
r;
 
  259             c.g = (1-
d.r) * c000.
g + (
d.r-
d.b) * c100.
g + (
d.b-
d.g) * c101.
g + (
d.g) * c111.
g;
 
  260             c.b = (1-
d.r) * c000.
b + (
d.r-
d.b) * c100.
b + (
d.b-
d.g) * c101.
b + (
d.g) * c111.
b;
 
  262             const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  263             const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  264             c.r = (1-
d.b) * c000.
r + (
d.b-
d.r) * c001.
r + (
d.r-
d.g) * c101.
r + (
d.g) * c111.
r;
 
  265             c.g = (1-
d.b) * c000.
g + (
d.b-
d.r) * c001.
g + (
d.r-
d.g) * c101.
g + (
d.g) * c111.
g;
 
  266             c.b = (1-
d.b) * c000.
b + (
d.b-
d.r) * c001.
b + (
d.r-
d.g) * c101.
b + (
d.g) * c111.
b;
 
  270             const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
 
  271             const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  272             c.r = (1-
d.b) * c000.
r + (
d.b-
d.g) * c001.
r + (
d.g-
d.r) * c011.
r + (
d.r) * c111.
r;
 
  273             c.g = (1-
d.b) * c000.
g + (
d.b-
d.g) * c001.
g + (
d.g-
d.r) * c011.
g + (
d.r) * c111.
g;
 
  274             c.b = (1-
d.b) * c000.
b + (
d.b-
d.g) * c001.
b + (
d.g-
d.r) * c011.
b + (
d.r) * c111.
b;
 
  275         } 
else if (
d.b > 
d.r) {
 
  276             const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  277             const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
 
  278             c.r = (1-
d.g) * c000.
r + (
d.g-
d.b) * c010.
r + (
d.b-
d.r) * c011.
r + (
d.r) * c111.
r;
 
  279             c.g = (1-
d.g) * c000.
g + (
d.g-
d.b) * c010.
g + (
d.b-
d.r) * c011.
g + (
d.r) * c111.
g;
 
  280             c.b = (1-
d.g) * c000.
b + (
d.g-
d.b) * c010.
b + (
d.b-
d.r) * c011.
b + (
d.r) * c111.
b;
 
  282             const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  283             const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
 
  284             c.r = (1-
d.g) * c000.
r + (
d.g-
d.r) * c010.
r + (
d.r-
d.b) * c110.
r + (
d.b) * c111.
r;
 
  285             c.g = (1-
d.g) * c000.
g + (
d.g-
d.r) * c010.
g + (
d.r-
d.b) * c110.
g + (
d.b) * c111.
g;
 
  286             c.b = (1-
d.g) * c000.
b + (
d.g-
d.r) * c010.
b + (
d.r-
d.b) * c110.
b + (
d.b) * c111.
b;
 
  293                                             int idx, 
const float s)
 
  295     const int lut_max = prelut->
size - 1;
 
  296     const float scaled = (
s - prelut->
min[idx]) * prelut->
scale[idx];
 
  297     const float x = 
av_clipf(scaled, 0.0
f, lut_max);
 
  298     const int prev = 
PREV(x);
 
  299     const int next = 
FFMIN((
int)(x) + 1, lut_max);
 
  300     const float p = prelut->
lut[idx][prev];
 
  301     const float n = prelut->
lut[idx][next];
 
  302     const float d = x - (
float)prev;
 
  311     if (prelut->size <= 0)
 
  320 #define DEFINE_INTERP_FUNC_PLANAR(name, nbits, depth)                                                  \ 
  321 static int interp_##nbits##_##name##_p##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ 
  324     const LUT3DContext *lut3d = ctx->priv;                                                             \ 
  325     const Lut3DPreLut *prelut = &lut3d->prelut;                                                        \ 
  326     const ThreadData *td = arg;                                                                        \ 
  327     const AVFrame *in  = td->in;                                                                       \ 
  328     const AVFrame *out = td->out;                                                                      \ 
  329     const int direct = out == in;                                                                      \ 
  330     const int slice_start = (in->height *  jobnr   ) / nb_jobs;                                        \ 
  331     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;                                        \ 
  332     uint8_t *grow = out->data[0] + slice_start * out->linesize[0];                                     \ 
  333     uint8_t *brow = out->data[1] + slice_start * out->linesize[1];                                     \ 
  334     uint8_t *rrow = out->data[2] + slice_start * out->linesize[2];                                     \ 
  335     uint8_t *arow = out->data[3] + slice_start * out->linesize[3];                                     \ 
  336     const uint8_t *srcgrow = in->data[0] + slice_start * in->linesize[0];                              \ 
  337     const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1];                              \ 
  338     const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2];                              \ 
  339     const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3];                              \ 
  340     const float lut_max = lut3d->lutsize - 1;                                                          \ 
  341     const float scale_f = 1.0f / ((1<<depth) - 1);                                                     \ 
  342     const float scale_r = lut3d->scale.r * lut_max;                                                    \ 
  343     const float scale_g = lut3d->scale.g * lut_max;                                                    \ 
  344     const float scale_b = lut3d->scale.b * lut_max;                                                    \ 
  346     for (y = slice_start; y < slice_end; y++) {                                                        \ 
  347         uint##nbits##_t *dstg = (uint##nbits##_t *)grow;                                               \ 
  348         uint##nbits##_t *dstb = (uint##nbits##_t *)brow;                                               \ 
  349         uint##nbits##_t *dstr = (uint##nbits##_t *)rrow;                                               \ 
  350         uint##nbits##_t *dsta = (uint##nbits##_t *)arow;                                               \ 
  351         const uint##nbits##_t *srcg = (const uint##nbits##_t *)srcgrow;                                \ 
  352         const uint##nbits##_t *srcb = (const uint##nbits##_t *)srcbrow;                                \ 
  353         const uint##nbits##_t *srcr = (const uint##nbits##_t *)srcrrow;                                \ 
  354         const uint##nbits##_t *srca = (const uint##nbits##_t *)srcarow;                                \ 
  355         for (x = 0; x < in->width; x++) {                                                              \ 
  356             const struct rgbvec rgb = {srcr[x] * scale_f,                                              \ 
  358                                        srcb[x] * scale_f};                                             \ 
  359             const struct rgbvec prelut_rgb = apply_prelut(prelut, &rgb);                               \ 
  360             const struct rgbvec scaled_rgb = {av_clipf(prelut_rgb.r * scale_r, 0, lut_max),            \ 
  361                                               av_clipf(prelut_rgb.g * scale_g, 0, lut_max),            \ 
  362                                               av_clipf(prelut_rgb.b * scale_b, 0, lut_max)};           \ 
  363             struct rgbvec vec = interp_##name(lut3d, &scaled_rgb);                                     \ 
  364             dstr[x] = av_clip_uintp2(vec.r * (float)((1<<depth) - 1), depth);                          \ 
  365             dstg[x] = av_clip_uintp2(vec.g * (float)((1<<depth) - 1), depth);                          \ 
  366             dstb[x] = av_clip_uintp2(vec.b * (float)((1<<depth) - 1), depth);                          \ 
  367             if (!direct && in->linesize[3])                                                            \ 
  370         grow += out->linesize[0];                                                                      \ 
  371         brow += out->linesize[1];                                                                      \ 
  372         rrow += out->linesize[2];                                                                      \ 
  373         arow += out->linesize[3];                                                                      \ 
  374         srcgrow += in->linesize[0];                                                                    \ 
  375         srcbrow += in->linesize[1];                                                                    \ 
  376         srcrrow += in->linesize[2];                                                                    \ 
  377         srcarow += in->linesize[3];                                                                    \ 
  418 #define DEFINE_INTERP_FUNC_PLANAR_FLOAT(name, depth)                                                   \ 
  419 static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)          \ 
  422     const LUT3DContext *lut3d = ctx->priv;                                                             \ 
  423     const Lut3DPreLut *prelut = &lut3d->prelut;                                                        \ 
  424     const ThreadData *td = arg;                                                                        \ 
  425     const AVFrame *in  = td->in;                                                                       \ 
  426     const AVFrame *out = td->out;                                                                      \ 
  427     const int direct = out == in;                                                                      \ 
  428     const int slice_start = (in->height *  jobnr   ) / nb_jobs;                                        \ 
  429     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;                                        \ 
  430     uint8_t *grow = out->data[0] + slice_start * out->linesize[0];                                     \ 
  431     uint8_t *brow = out->data[1] + slice_start * out->linesize[1];                                     \ 
  432     uint8_t *rrow = out->data[2] + slice_start * out->linesize[2];                                     \ 
  433     uint8_t *arow = out->data[3] + slice_start * out->linesize[3];                                     \ 
  434     const uint8_t *srcgrow = in->data[0] + slice_start * in->linesize[0];                              \ 
  435     const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1];                              \ 
  436     const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2];                              \ 
  437     const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3];                              \ 
  438     const float lut_max = lut3d->lutsize - 1;                                                          \ 
  439     const float scale_r = lut3d->scale.r * lut_max;                                                    \ 
  440     const float scale_g = lut3d->scale.g * lut_max;                                                    \ 
  441     const float scale_b = lut3d->scale.b * lut_max;                                                    \ 
  443     for (y = slice_start; y < slice_end; y++) {                                                        \ 
  444         float *dstg = (float *)grow;                                                                   \ 
  445         float *dstb = (float *)brow;                                                                   \ 
  446         float *dstr = (float *)rrow;                                                                   \ 
  447         float *dsta = (float *)arow;                                                                   \ 
  448         const float *srcg = (const float *)srcgrow;                                                    \ 
  449         const float *srcb = (const float *)srcbrow;                                                    \ 
  450         const float *srcr = (const float *)srcrrow;                                                    \ 
  451         const float *srca = (const float *)srcarow;                                                    \ 
  452         for (x = 0; x < in->width; x++) {                                                              \ 
  453             const struct rgbvec rgb = {sanitizef(srcr[x]),                                             \ 
  454                                        sanitizef(srcg[x]),                                             \ 
  455                                        sanitizef(srcb[x])};                                            \ 
  456             const struct rgbvec prelut_rgb = apply_prelut(prelut, &rgb);                               \ 
  457             const struct rgbvec scaled_rgb = {av_clipf(prelut_rgb.r * scale_r, 0, lut_max),            \ 
  458                                               av_clipf(prelut_rgb.g * scale_g, 0, lut_max),            \ 
  459                                               av_clipf(prelut_rgb.b * scale_b, 0, lut_max)};           \ 
  460             struct rgbvec vec = interp_##name(lut3d, &scaled_rgb);                                     \ 
  464             if (!direct && in->linesize[3])                                                            \ 
  467         grow += out->linesize[0];                                                                      \ 
  468         brow += out->linesize[1];                                                                      \ 
  469         rrow += out->linesize[2];                                                                      \ 
  470         arow += out->linesize[3];                                                                      \ 
  471         srcgrow += in->linesize[0];                                                                    \ 
  472         srcbrow += in->linesize[1];                                                                    \ 
  473         srcrrow += in->linesize[2];                                                                    \ 
  474         srcarow += in->linesize[3];                                                                    \ 
  485 #define DEFINE_INTERP_FUNC(name, nbits)                                                             \ 
  486 static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)         \ 
  489     const LUT3DContext *lut3d = ctx->priv;                                                          \ 
  490     const Lut3DPreLut *prelut = &lut3d->prelut;                                                     \ 
  491     const ThreadData *td = arg;                                                                     \ 
  492     const AVFrame *in  = td->in;                                                                    \ 
  493     const AVFrame *out = td->out;                                                                   \ 
  494     const int direct = out == in;                                                                   \ 
  495     const int step = lut3d->step;                                                                   \ 
  496     const uint8_t r = lut3d->rgba_map[R];                                                           \ 
  497     const uint8_t g = lut3d->rgba_map[G];                                                           \ 
  498     const uint8_t b = lut3d->rgba_map[B];                                                           \ 
  499     const uint8_t a = lut3d->rgba_map[A];                                                           \ 
  500     const int slice_start = (in->height *  jobnr   ) / nb_jobs;                                     \ 
  501     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;                                     \ 
  502     uint8_t       *dstrow = out->data[0] + slice_start * out->linesize[0];                          \ 
  503     const uint8_t *srcrow = in ->data[0] + slice_start * in ->linesize[0];                          \ 
  504     const float lut_max = lut3d->lutsize - 1;                                                       \ 
  505     const float scale_f = 1.0f / ((1<<nbits) - 1);                                                  \ 
  506     const float scale_r = lut3d->scale.r * lut_max;                                                 \ 
  507     const float scale_g = lut3d->scale.g * lut_max;                                                 \ 
  508     const float scale_b = lut3d->scale.b * lut_max;                                                 \ 
  510     for (y = slice_start; y < slice_end; y++) {                                                     \ 
  511         uint##nbits##_t *dst = (uint##nbits##_t *)dstrow;                                           \ 
  512         const uint##nbits##_t *src = (const uint##nbits##_t *)srcrow;                               \ 
  513         for (x = 0; x < in->width * step; x += step) {                                              \ 
  514             const struct rgbvec rgb = {src[x + r] * scale_f,                                        \ 
  515                                        src[x + g] * scale_f,                                        \ 
  516                                        src[x + b] * scale_f};                                       \ 
  517             const struct rgbvec prelut_rgb = apply_prelut(prelut, &rgb);                            \ 
  518             const struct rgbvec scaled_rgb = {av_clipf(prelut_rgb.r * scale_r, 0, lut_max),         \ 
  519                                               av_clipf(prelut_rgb.g * scale_g, 0, lut_max),         \ 
  520                                               av_clipf(prelut_rgb.b * scale_b, 0, lut_max)};        \ 
  521             struct rgbvec vec = interp_##name(lut3d, &scaled_rgb);                                  \ 
  522             dst[x + r] = av_clip_uint##nbits(vec.r * (float)((1<<nbits) - 1));                      \ 
  523             dst[x + g] = av_clip_uint##nbits(vec.g * (float)((1<<nbits) - 1));                      \ 
  524             dst[x + b] = av_clip_uint##nbits(vec.b * (float)((1<<nbits) - 1));                      \ 
  525             if (!direct && step == 4)                                                               \ 
  526                 dst[x + a] = src[x + a];                                                            \ 
  528         dstrow += out->linesize[0];                                                                 \ 
  529         srcrow += in ->linesize[0];                                                                 \ 
  546 #define MAX_LINE_SIZE 512 
  552     return !*p || *p == 
'#';
 
  563     while ((
c = fgetc(
f)) != EOF) {
 
  574         if ((
c = fgetc(
f)) == EOF)
 
  589 #define NEXT_LINE(loop_cond) do {                           \ 
  590     if (!fgets(line, sizeof(line), f)) {                    \ 
  591         av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \ 
  592         return AVERROR_INVALIDDATA;                         \ 
  596 #define NEXT_LINE_OR_GOTO(loop_cond, label) do {            \ 
  597     if (!fgets(line, sizeof(line), f)) {                    \ 
  598         av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \ 
  599         ret = AVERROR_INVALIDDATA;                          \ 
  608     if (lutsize < 2 || lutsize > 
MAX_LEVEL) {
 
  620         for (
i = 0; 
i < 3; 
i++) {
 
  628         for (
i = 0; 
i < 3; 
i++) {
 
  633     lut3d->
lutsize2 = lutsize * lutsize;
 
  649     if (!strncmp(
line, 
"3DLUTSIZE ", 10)) {
 
  659     for (k = 0; k < 
size; k++) {
 
  660         for (j = 0; j < 
size; j++) {
 
  663                 if (k != 0 || j != 0 || 
i != 0)
 
  678     float min[3] = {0.0, 0.0, 0.0};
 
  679     float max[3] = {1.0, 1.0, 1.0};
 
  682         if (!strncmp(
line, 
"LUT_3D_SIZE", 11)) {
 
  691             for (k = 0; k < 
size; k++) {
 
  692                 for (j = 0; j < 
size; j++) {
 
  699                             if (!strncmp(
line, 
"DOMAIN_", 7)) {
 
  701                                 if      (!strncmp(
line + 7, 
"MIN ", 4)) vals = 
min;
 
  702                                 else if (!strncmp(
line + 7, 
"MAX ", 4)) vals = 
max;
 
  709                             } 
else if (!strncmp(
line, 
"TITLE", 5)) {
 
  737     const int size2 = 17 * 17;
 
  738     const float scale = 16*16*16;
 
  747     for (k = 0; k < 
size; k++) {
 
  748         for (j = 0; j < 
size; j++) {
 
  772     uint8_t rgb_map[3] = {0, 1, 2};
 
  775         if      (!strncmp(
line, 
"in",  2)) in  = strtol(
line + 2, 
NULL, 0);
 
  777         else if (!strncmp(
line, 
"values", 6)) {
 
  778             const char *p = 
line + 6;
 
  779 #define SET_COLOR(id) do {                  \ 
  780     while (av_isspace(*p))                  \ 
  783     case 'r': rgb_map[id] = 0; break;       \ 
  784     case 'g': rgb_map[id] = 1; break;       \ 
  785     case 'b': rgb_map[id] = 2; break;       \ 
  787     while (*p && !av_isspace(*p))           \ 
  797     if (in == -1 || 
out == -1) {
 
  801     if (in < 2 || 
out < 2 ||
 
  817     for (k = 0; k < 
size; k++) {
 
  818         for (j = 0; j < 
size; j++) {
 
  852         mid = (low + hi) / 2;
 
  863 #define NEXT_FLOAT_OR_GOTO(value, label)                    \ 
  864     if (!fget_next_word(line, sizeof(line) ,f)) {           \ 
  865         ret = AVERROR_INVALIDDATA;                          \ 
  868     if (av_sscanf(line, "%f", &value) != 1) {               \ 
  869         ret = AVERROR_INVALIDDATA;                          \ 
  877     float in_min[3]  = {0.0, 0.0, 0.0};
 
  878     float in_max[3]  = {1.0, 1.0, 1.0};
 
  879     float out_min[3] = {0.0, 0.0, 0.0};
 
  880     float out_max[3] = {1.0, 1.0, 1.0};
 
  881     int inside_metadata = 0, 
size, size2;
 
  885     int prelut_sizes[3] = {0, 0, 0};
 
  890     if (strncmp(
line, 
"CSPLUTV100", 10)) {
 
  897     if (strncmp(
line, 
"3D", 2)) {
 
  906         if (!strncmp(
line, 
"BEGIN METADATA", 14)) {
 
  910         if (!strncmp(
line, 
"END METADATA", 12)) {
 
  914         if (inside_metadata == 0) {
 
  915             int size_r, size_g, size_b;
 
  917             for (
int i = 0; 
i < 3; 
i++) {
 
  918                 int npoints = strtol(
line, 
NULL, 0);
 
  929                     if (in_prelut[
i] || out_prelut[
i]) {
 
  935                     in_prelut[
i]  = (
float*)
av_malloc(npoints * 
sizeof(
float));
 
  936                     out_prelut[
i] = (
float*)
av_malloc(npoints * 
sizeof(
float));
 
  937                     if (!in_prelut[
i] || !out_prelut[
i]) {
 
  942                     prelut_sizes[
i] = npoints;
 
  944                     in_max[
i] = -FLT_MAX;
 
  945                     out_min[
i] = FLT_MAX;
 
  946                     out_max[
i] = -FLT_MAX;
 
  948                     for (
int j = 0; j < npoints; j++) {
 
  950                         in_min[
i] = 
FFMIN(in_min[
i], v);
 
  951                         in_max[
i] = 
FFMAX(in_max[
i], v);
 
  953                         if (j > 0 && v < last) {
 
  961                     for (
int j = 0; j < npoints; j++) {
 
  963                         out_min[
i] = 
FFMIN(out_min[
i], v);
 
  964                         out_max[
i] = 
FFMAX(out_max[
i], v);
 
  965                         out_prelut[
i][j] = v;
 
  968                 } 
else if (npoints == 2)  {
 
  989             if (
av_sscanf(
line, 
"%d %d %d", &size_r, &size_g, &size_b) != 3) {
 
  993             if (size_r != size_g || size_r != size_b) {
 
 1002             if (prelut_sizes[0] && prelut_sizes[1] && prelut_sizes[2])
 
 1009             for (
int k = 0; k < 
size; k++) {
 
 1010                 for (
int j = 0; j < 
size; j++) {
 
 1011                     for (
int i = 0; 
i < 
size; 
i++) {
 
 1020                         vec->
r *= out_max[0] - out_min[0];
 
 1021                         vec->
g *= out_max[1] - out_min[1];
 
 1022                         vec->
b *= out_max[2] - out_min[2];
 
 1032         for (
int c = 0; 
c < 3; 
c++) {
 
 1045                 a   = out_prelut[
c][idx + 0];
 
 1046                 b   = out_prelut[
c][idx + 1];
 
 1047                 mix = x - in_prelut[
c][idx];
 
 1063     for (
int c = 0; 
c < 3; 
c++) {
 
 1075     const float c = 1. / (
size - 1);
 
 1081     for (k = 0; k < 
size; k++) {
 
 1082         for (j = 0; j < 
size; j++) {
 
 1115     int depth, is16bit, isfloat, 
planar;
 
 1119     depth = 
desc->comp[0].depth;
 
 1120     is16bit = 
desc->comp[0].depth > 8;
 
 1126 #define SET_FUNC(name) do {                                     \ 
 1127     if (planar && !isfloat) {                                   \ 
 1129         case  8: lut3d->interp = interp_8_##name##_p8;   break; \ 
 1130         case  9: lut3d->interp = interp_16_##name##_p9;  break; \ 
 1131         case 10: lut3d->interp = interp_16_##name##_p10; break; \ 
 1132         case 12: lut3d->interp = interp_16_##name##_p12; break; \ 
 1133         case 14: lut3d->interp = interp_16_##name##_p14; break; \ 
 1134         case 16: lut3d->interp = interp_16_##name##_p16; break; \ 
 1136     } else if (isfloat) { lut3d->interp = interp_##name##_pf32; \ 
 1137     } else if (is16bit) { lut3d->interp = interp_16_##name;     \ 
 1138     } else {       lut3d->interp = interp_8_##name; }           \ 
 1198                            char *res, 
int res_len, 
int flags)
 
 1209 #if CONFIG_LUT3D_FILTER || CONFIG_HALDCLUT_FILTER 
 1214 #define COMMON_OPTIONS_OFFSET CONFIG_LUT3D_FILTER 
 1215 static const AVOption lut3d_haldclut_options[] = {
 
 1216 #if CONFIG_LUT3D_FILTER 
 1219 #if CONFIG_HALDCLUT_FILTER 
 1227 #if CONFIG_LUT3D_FILTER 
 1251     ext = strrchr(lut3d->
file, 
'.');
 
 1290     for (
i = 0; 
i < 3; 
i++) {
 
 1313     .priv_class    = &lut3d_class,
 
 1319 #if CONFIG_HALDCLUT_FILTER 
 1325     const int w = lut3d->clut_width;
 
 1326     const int step = lut3d->clut_step;
 
 1327     const uint8_t *rgba_map = lut3d->clut_rgba_map;
 
 1329     const int level2 = lut3d->
lutsize2;
 
 1331 #define LOAD_CLUT(nbits) do {                                           \ 
 1332     int i, j, k, x = 0, y = 0;                                          \ 
 1334     for (k = 0; k < level; k++) {                                       \ 
 1335         for (j = 0; j < level; j++) {                                   \ 
 1336             for (i = 0; i < level; i++) {                               \ 
 1337                 const uint##nbits##_t *src = (const uint##nbits##_t *)  \ 
 1338                     (data + y*linesize + x*step);                       \ 
 1339                 struct rgbvec *vec = &lut3d->lut[i * level2 + j * level + k]; \ 
 1340                 vec->r = src[rgba_map[0]] / (float)((1<<(nbits)) - 1);  \ 
 1341                 vec->g = src[rgba_map[1]] / (float)((1<<(nbits)) - 1);  \ 
 1342                 vec->b = src[rgba_map[2]] / (float)((1<<(nbits)) - 1);  \ 
 1352     switch (lut3d->clut_bits) {
 
 1353     case  8: LOAD_CLUT(8);  
break;
 
 1354     case 16: LOAD_CLUT(16); 
break;
 
 1366     const int w = lut3d->clut_width;
 
 1368     const int level2 = lut3d->
lutsize2;
 
 1370 #define LOAD_CLUT_PLANAR(nbits, depth) do {                             \ 
 1371     int i, j, k, x = 0, y = 0;                                          \ 
 1373     for (k = 0; k < level; k++) {                                       \ 
 1374         for (j = 0; j < level; j++) {                                   \ 
 1375             for (i = 0; i < level; i++) {                               \ 
 1376                 const uint##nbits##_t *gsrc = (const uint##nbits##_t *) \ 
 1377                     (datag + y*glinesize);                              \ 
 1378                 const uint##nbits##_t *bsrc = (const uint##nbits##_t *) \ 
 1379                     (datab + y*blinesize);                              \ 
 1380                 const uint##nbits##_t *rsrc = (const uint##nbits##_t *) \ 
 1381                     (datar + y*rlinesize);                              \ 
 1382                 struct rgbvec *vec = &lut3d->lut[i * level2 + j * level + k]; \ 
 1383                 vec->r = gsrc[x] / (float)((1<<(depth)) - 1);           \ 
 1384                 vec->g = bsrc[x] / (float)((1<<(depth)) - 1);           \ 
 1385                 vec->b = rsrc[x] / (float)((1<<(depth)) - 1);           \ 
 1395     switch (lut3d->clut_bits) {
 
 1396     case  8: LOAD_CLUT_PLANAR(8, 8);   
break;
 
 1397     case  9: LOAD_CLUT_PLANAR(16, 9);  
break;
 
 1398     case 10: LOAD_CLUT_PLANAR(16, 10); 
break;
 
 1399     case 12: LOAD_CLUT_PLANAR(16, 12); 
break;
 
 1400     case 14: LOAD_CLUT_PLANAR(16, 14); 
break;
 
 1401     case 16: LOAD_CLUT_PLANAR(16, 16); 
break;
 
 1413     const int w = lut3d->clut_width;
 
 1415     const int level2 = lut3d->
lutsize2;
 
 1417     int i, j, k, x = 0, y = 0;
 
 1419     for (k = 0; k < 
level; k++) {
 
 1420         for (j = 0; j < 
level; j++) {
 
 1422                 const float *gsrc = (
const float *)(datag + y*glinesize);
 
 1423                 const float *bsrc = (
const float *)(datab + y*blinesize);
 
 1424                 const float *rsrc = (
const float *)(datar + y*rlinesize);
 
 1447     outlink->
w = 
ctx->inputs[0]->w;
 
 1448     outlink->
h = 
ctx->inputs[0]->h;
 
 1470     lut3d->clut_bits = 
desc->comp[0].depth;
 
 1494         const int max_clut_level = sqrt(
MAX_LEVEL);
 
 1495         const int max_clut_size  = max_clut_level*max_clut_level*max_clut_level;
 
 1497                "(maximum level is %d, or %dx%d CLUT)\n",
 
 1498                max_clut_level, max_clut_size, max_clut_size);
 
 1518     if (lut3d->clut || !lut3d->got_clut) {
 
 1519         if (lut3d->clut_float)
 
 1520             update_clut_float(
ctx->priv, second);
 
 1521         else if (lut3d->clut_planar)
 
 1522             update_clut_planar(
ctx->priv, second);
 
 1524             update_clut_packed(
ctx->priv, second);
 
 1525         lut3d->got_clut = 1;
 
 1535     lut3d->fs.on_event = update_apply_clut;
 
 1547                            &lut3d_haldclut_options[COMMON_OPTIONS_OFFSET]);
 
 1557         .config_props = config_clut,
 
 1573     .
preinit       = haldclut_framesync_preinit,
 
 1574     .
init          = haldclut_init,
 
 1575     .
uninit        = haldclut_uninit,
 
 1580     .priv_class    = &haldclut_class,
 
 1588 #if CONFIG_LUT1D_FILTER 
 1590 enum interp_1d_mode {
 
 1591     INTERPOLATE_1D_NEAREST,
 
 1592     INTERPOLATE_1D_LINEAR,
 
 1593     INTERPOLATE_1D_CUBIC,
 
 1594     INTERPOLATE_1D_COSINE,
 
 1595     INTERPOLATE_1D_SPLINE,
 
 1599 #define MAX_1D_LEVEL 65536 
 1601 typedef struct LUT1DContext {
 
 1606     uint8_t rgba_map[4];
 
 1608     float lut[3][MAX_1D_LEVEL];
 
 1614 #define OFFSET(x) offsetof(LUT1DContext, x) 
 1616 static void set_identity_matrix_1d(LUT1DContext *lut1d, 
int size)
 
 1618     const float c = 1. / (
size - 1);
 
 1621     lut1d->lutsize = 
size;
 
 1623         lut1d->lut[0][
i] = 
i * 
c;
 
 1624         lut1d->lut[1][
i] = 
i * 
c;
 
 1625         lut1d->lut[2][
i] = 
i * 
c;
 
 1631     LUT1DContext *lut1d = 
ctx->priv;
 
 1633     float in_min[3]  = {0.0, 0.0, 0.0};
 
 1634     float in_max[3]  = {1.0, 1.0, 1.0};
 
 1635     float out_min[3] = {0.0, 0.0, 0.0};
 
 1636     float out_max[3] = {1.0, 1.0, 1.0};
 
 1637     int inside_metadata = 0, 
size;
 
 1640     if (strncmp(
line, 
"CSPLUTV100", 10)) {
 
 1646     if (strncmp(
line, 
"1D", 2)) {
 
 1654         if (!strncmp(
line, 
"BEGIN METADATA", 14)) {
 
 1655             inside_metadata = 1;
 
 1658         if (!strncmp(
line, 
"END METADATA", 12)) {
 
 1659             inside_metadata = 0;
 
 1662         if (inside_metadata == 0) {
 
 1663             for (
int i = 0; 
i < 3; 
i++) {
 
 1664                 int npoints = strtol(
line, 
NULL, 0);
 
 1682             if (size < 2 || size > MAX_1D_LEVEL) {
 
 1687             lut1d->lutsize = 
size;
 
 1689             for (
int i = 0; 
i < 
size; 
i++) {
 
 1691                 if (
av_sscanf(
line, 
"%f %f %f", &lut1d->lut[0][
i], &lut1d->lut[1][
i], &lut1d->lut[2][
i]) != 3)
 
 1693                 lut1d->lut[0][
i] *= out_max[0] - out_min[0];
 
 1694                 lut1d->lut[1][
i] *= out_max[1] - out_min[1];
 
 1695                 lut1d->lut[2][
i] *= out_max[2] - out_min[2];
 
 1702     lut1d->scale.r = 
av_clipf(1. / (in_max[0] - in_min[0]), 0.
f, 1.
f);
 
 1703     lut1d->scale.g = 
av_clipf(1. / (in_max[1] - in_min[1]), 0.
f, 1.
f);
 
 1704     lut1d->scale.b = 
av_clipf(1. / (in_max[2] - in_min[2]), 0.
f, 1.
f);
 
 1711     LUT1DContext *lut1d = 
ctx->priv;
 
 1713     float min[3] = {0.0, 0.0, 0.0};
 
 1714     float max[3] = {1.0, 1.0, 1.0};
 
 1717         if (!strncmp(
line, 
"LUT_1D_SIZE", 11)) {
 
 1721             if (size < 2 || size > MAX_1D_LEVEL) {
 
 1725             lut1d->lutsize = 
size;
 
 1730                     if (!strncmp(
line, 
"DOMAIN_", 7)) {
 
 1732                         if      (!strncmp(
line + 7, 
"MIN ", 4)) vals = 
min;
 
 1733                         else if (!strncmp(
line + 7, 
"MAX ", 4)) vals = 
max;
 
 1740                     } 
else if (!strncmp(
line, 
"LUT_1D_INPUT_RANGE ", 19)) {
 
 1745                     } 
else if (!strncmp(
line, 
"TITLE", 5)) {
 
 1749                 if (
av_sscanf(
line, 
"%f %f %f", &lut1d->lut[0][
i], &lut1d->lut[1][
i], &lut1d->lut[2][
i]) != 3)
 
 1763 static const AVOption lut1d_options[] = {
 
 1766         { 
"nearest", 
"use values from the nearest defined points", 0, 
AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_NEAREST},   0, 0, 
TFLAGS, 
"interp_mode" },
 
 1767         { 
"linear",  
"use values from the linear interpolation",   0, 
AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_LINEAR},    0, 0, 
TFLAGS, 
"interp_mode" },
 
 1768         { 
"cosine",  
"use values from the cosine interpolation",   0, 
AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_COSINE},    0, 0, 
TFLAGS, 
"interp_mode" },
 
 1769         { 
"cubic",   
"use values from the cubic interpolation",    0, 
AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_CUBIC},     0, 0, 
TFLAGS, 
"interp_mode" },
 
 1770         { 
"spline",  
"use values from the spline interpolation",   0, 
AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_1D_SPLINE},    0, 0, 
TFLAGS, 
"interp_mode" },
 
 1776 static inline float interp_1d_nearest(
const LUT1DContext *lut1d,
 
 1777                                       int idx, 
const float s)
 
 1779     return lut1d->lut[idx][
NEAR(
s)];
 
 1782 #define NEXT1D(x) (FFMIN((int)(x) + 1, lut1d->lutsize - 1)) 
 1784 static inline float interp_1d_linear(
const LUT1DContext *lut1d,
 
 1785                                      int idx, 
const float s)
 
 1787     const int prev = 
PREV(
s);
 
 1788     const int next = NEXT1D(
s);
 
 1789     const float d = 
s - prev;
 
 1790     const float p = lut1d->lut[idx][prev];
 
 1791     const float n = lut1d->lut[idx][next];
 
 1796 static inline float interp_1d_cosine(
const LUT1DContext *lut1d,
 
 1797                                      int idx, 
const float s)
 
 1799     const int prev = 
PREV(
s);
 
 1800     const int next = NEXT1D(
s);
 
 1801     const float d = 
s - prev;
 
 1802     const float p = lut1d->lut[idx][prev];
 
 1803     const float n = lut1d->lut[idx][next];
 
 1804     const float m = (1.f - 
cosf(
d * 
M_PI)) * .5
f;
 
 1806     return lerpf(p, n, m);
 
 1809 static inline float interp_1d_cubic(
const LUT1DContext *lut1d,
 
 1810                                     int idx, 
const float s)
 
 1812     const int prev = 
PREV(
s);
 
 1813     const int next = NEXT1D(
s);
 
 1814     const float mu = 
s - prev;
 
 1817     float y0 = lut1d->lut[idx][
FFMAX(prev - 1, 0)];
 
 1818     float y1 = lut1d->lut[idx][prev];
 
 1819     float y2 = lut1d->lut[idx][next];
 
 1820     float y3 = lut1d->lut[idx][
FFMIN(next + 1, lut1d->lutsize - 1)];
 
 1824     a0 = y3 - y2 - y0 + y1;
 
 1829     return a0 * mu * mu2 + 
a1 * mu2 + 
a2 * mu + 
a3;
 
 1832 static inline float interp_1d_spline(
const LUT1DContext *lut1d,
 
 1833                                      int idx, 
const float s)
 
 1835     const int prev = 
PREV(
s);
 
 1836     const int next = NEXT1D(
s);
 
 1837     const float x = 
s - prev;
 
 1838     float c0, 
c1, 
c2, c3;
 
 1840     float y0 = lut1d->lut[idx][
FFMAX(prev - 1, 0)];
 
 1841     float y1 = lut1d->lut[idx][prev];
 
 1842     float y2 = lut1d->lut[idx][next];
 
 1843     float y3 = lut1d->lut[idx][
FFMIN(next + 1, lut1d->lutsize - 1)];
 
 1846     c1 = .5f * (y2 - y0);
 
 1847     c2 = y0 - 2.5f * y1 + 2.f * y2 - .5f * y3;
 
 1848     c3 = .5f * (y3 - y0) + 1.5
f * (y1 - y2);
 
 1850     return ((c3 * x + 
c2) * x + 
c1) * x + c0;
 
 1853 #define DEFINE_INTERP_FUNC_PLANAR_1D(name, nbits, depth)                     \ 
 1854 static int interp_1d_##nbits##_##name##_p##depth(AVFilterContext *ctx,       \ 
 1855                                                  void *arg, int jobnr,       \ 
 1859     const LUT1DContext *lut1d = ctx->priv;                                   \ 
 1860     const ThreadData *td = arg;                                              \ 
 1861     const AVFrame *in  = td->in;                                             \ 
 1862     const AVFrame *out = td->out;                                            \ 
 1863     const int direct = out == in;                                            \ 
 1864     const int slice_start = (in->height *  jobnr   ) / nb_jobs;              \ 
 1865     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;              \ 
 1866     uint8_t *grow = out->data[0] + slice_start * out->linesize[0];           \ 
 1867     uint8_t *brow = out->data[1] + slice_start * out->linesize[1];           \ 
 1868     uint8_t *rrow = out->data[2] + slice_start * out->linesize[2];           \ 
 1869     uint8_t *arow = out->data[3] + slice_start * out->linesize[3];           \ 
 1870     const uint8_t *srcgrow = in->data[0] + slice_start * in->linesize[0];    \ 
 1871     const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1];    \ 
 1872     const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2];    \ 
 1873     const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3];    \ 
 1874     const float factor = (1 << depth) - 1;                                   \ 
 1875     const float scale_r = (lut1d->scale.r / factor) * (lut1d->lutsize - 1);  \ 
 1876     const float scale_g = (lut1d->scale.g / factor) * (lut1d->lutsize - 1);  \ 
 1877     const float scale_b = (lut1d->scale.b / factor) * (lut1d->lutsize - 1);  \ 
 1879     for (y = slice_start; y < slice_end; y++) {                              \ 
 1880         uint##nbits##_t *dstg = (uint##nbits##_t *)grow;                     \ 
 1881         uint##nbits##_t *dstb = (uint##nbits##_t *)brow;                     \ 
 1882         uint##nbits##_t *dstr = (uint##nbits##_t *)rrow;                     \ 
 1883         uint##nbits##_t *dsta = (uint##nbits##_t *)arow;                     \ 
 1884         const uint##nbits##_t *srcg = (const uint##nbits##_t *)srcgrow;      \ 
 1885         const uint##nbits##_t *srcb = (const uint##nbits##_t *)srcbrow;      \ 
 1886         const uint##nbits##_t *srcr = (const uint##nbits##_t *)srcrrow;      \ 
 1887         const uint##nbits##_t *srca = (const uint##nbits##_t *)srcarow;      \ 
 1888         for (x = 0; x < in->width; x++) {                                    \ 
 1889             float r = srcr[x] * scale_r;                                     \ 
 1890             float g = srcg[x] * scale_g;                                     \ 
 1891             float b = srcb[x] * scale_b;                                     \ 
 1892             r = interp_1d_##name(lut1d, 0, r);                               \ 
 1893             g = interp_1d_##name(lut1d, 1, g);                               \ 
 1894             b = interp_1d_##name(lut1d, 2, b);                               \ 
 1895             dstr[x] = av_clip_uintp2(r * factor, depth);                     \ 
 1896             dstg[x] = av_clip_uintp2(g * factor, depth);                     \ 
 1897             dstb[x] = av_clip_uintp2(b * factor, depth);                     \ 
 1898             if (!direct && in->linesize[3])                                  \ 
 1899                 dsta[x] = srca[x];                                           \ 
 1901         grow += out->linesize[0];                                            \ 
 1902         brow += out->linesize[1];                                            \ 
 1903         rrow += out->linesize[2];                                            \ 
 1904         arow += out->linesize[3];                                            \ 
 1905         srcgrow += in->linesize[0];                                          \ 
 1906         srcbrow += in->linesize[1];                                          \ 
 1907         srcrrow += in->linesize[2];                                          \ 
 1908         srcarow += in->linesize[3];                                          \ 
 1913 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     8, 8)
 
 1914 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      8, 8)
 
 1915 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      8, 8)
 
 1916 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       8, 8)
 
 1917 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      8, 8)
 
 1919 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     16, 9)
 
 1920 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      16, 9)
 
 1921 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      16, 9)
 
 1922 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       16, 9)
 
 1923 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      16, 9)
 
 1925 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     16, 10)
 
 1926 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      16, 10)
 
 1927 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      16, 10)
 
 1928 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       16, 10)
 
 1929 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      16, 10)
 
 1931 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     16, 12)
 
 1932 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      16, 12)
 
 1933 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      16, 12)
 
 1934 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       16, 12)
 
 1935 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      16, 12)
 
 1937 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     16, 14)
 
 1938 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      16, 14)
 
 1939 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      16, 14)
 
 1940 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       16, 14)
 
 1941 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      16, 14)
 
 1943 DEFINE_INTERP_FUNC_PLANAR_1D(nearest,     16, 16)
 
 1944 DEFINE_INTERP_FUNC_PLANAR_1D(
linear,      16, 16)
 
 1945 DEFINE_INTERP_FUNC_PLANAR_1D(cosine,      16, 16)
 
 1946 DEFINE_INTERP_FUNC_PLANAR_1D(cubic,       16, 16)
 
 1947 DEFINE_INTERP_FUNC_PLANAR_1D(spline,      16, 16)
 
 1949 #define DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(name, depth)                      \ 
 1950 static int interp_1d_##name##_pf##depth(AVFilterContext *ctx,                \ 
 1951                                                  void *arg, int jobnr,       \ 
 1955     const LUT1DContext *lut1d = ctx->priv;                                   \ 
 1956     const ThreadData *td = arg;                                              \ 
 1957     const AVFrame *in  = td->in;                                             \ 
 1958     const AVFrame *out = td->out;                                            \ 
 1959     const int direct = out == in;                                            \ 
 1960     const int slice_start = (in->height *  jobnr   ) / nb_jobs;              \ 
 1961     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;              \ 
 1962     uint8_t *grow = out->data[0] + slice_start * out->linesize[0];           \ 
 1963     uint8_t *brow = out->data[1] + slice_start * out->linesize[1];           \ 
 1964     uint8_t *rrow = out->data[2] + slice_start * out->linesize[2];           \ 
 1965     uint8_t *arow = out->data[3] + slice_start * out->linesize[3];           \ 
 1966     const uint8_t *srcgrow = in->data[0] + slice_start * in->linesize[0];    \ 
 1967     const uint8_t *srcbrow = in->data[1] + slice_start * in->linesize[1];    \ 
 1968     const uint8_t *srcrrow = in->data[2] + slice_start * in->linesize[2];    \ 
 1969     const uint8_t *srcarow = in->data[3] + slice_start * in->linesize[3];    \ 
 1970     const float lutsize = lut1d->lutsize - 1;                                \ 
 1971     const float scale_r = lut1d->scale.r * lutsize;                          \ 
 1972     const float scale_g = lut1d->scale.g * lutsize;                          \ 
 1973     const float scale_b = lut1d->scale.b * lutsize;                          \ 
 1975     for (y = slice_start; y < slice_end; y++) {                              \ 
 1976         float *dstg = (float *)grow;                                         \ 
 1977         float *dstb = (float *)brow;                                         \ 
 1978         float *dstr = (float *)rrow;                                         \ 
 1979         float *dsta = (float *)arow;                                         \ 
 1980         const float *srcg = (const float *)srcgrow;                          \ 
 1981         const float *srcb = (const float *)srcbrow;                          \ 
 1982         const float *srcr = (const float *)srcrrow;                          \ 
 1983         const float *srca = (const float *)srcarow;                          \ 
 1984         for (x = 0; x < in->width; x++) {                                    \ 
 1985             float r = av_clipf(sanitizef(srcr[x]) * scale_r, 0.0f, lutsize); \ 
 1986             float g = av_clipf(sanitizef(srcg[x]) * scale_g, 0.0f, lutsize); \ 
 1987             float b = av_clipf(sanitizef(srcb[x]) * scale_b, 0.0f, lutsize); \ 
 1988             r = interp_1d_##name(lut1d, 0, r);                               \ 
 1989             g = interp_1d_##name(lut1d, 1, g);                               \ 
 1990             b = interp_1d_##name(lut1d, 2, b);                               \ 
 1994             if (!direct && in->linesize[3])                                  \ 
 1995                 dsta[x] = srca[x];                                           \ 
 1997         grow += out->linesize[0];                                            \ 
 1998         brow += out->linesize[1];                                            \ 
 1999         rrow += out->linesize[2];                                            \ 
 2000         arow += out->linesize[3];                                            \ 
 2001         srcgrow += in->linesize[0];                                          \ 
 2002         srcbrow += in->linesize[1];                                          \ 
 2003         srcrrow += in->linesize[2];                                          \ 
 2004         srcarow += in->linesize[3];                                          \ 
 2009 DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(nearest, 32)
 
 2010 DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(
linear,  32)
 
 2011 DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(cosine,  32)
 
 2012 DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(cubic,   32)
 
 2013 DEFINE_INTERP_FUNC_PLANAR_1D_FLOAT(spline,  32)
 
 2015 #define DEFINE_INTERP_FUNC_1D(name, nbits)                                   \ 
 2016 static int interp_1d_##nbits##_##name(AVFilterContext *ctx, void *arg,       \ 
 2017                                       int jobnr, int nb_jobs)                \ 
 2020     const LUT1DContext *lut1d = ctx->priv;                                   \ 
 2021     const ThreadData *td = arg;                                              \ 
 2022     const AVFrame *in  = td->in;                                             \ 
 2023     const AVFrame *out = td->out;                                            \ 
 2024     const int direct = out == in;                                            \ 
 2025     const int step = lut1d->step;                                            \ 
 2026     const uint8_t r = lut1d->rgba_map[R];                                    \ 
 2027     const uint8_t g = lut1d->rgba_map[G];                                    \ 
 2028     const uint8_t b = lut1d->rgba_map[B];                                    \ 
 2029     const uint8_t a = lut1d->rgba_map[A];                                    \ 
 2030     const int slice_start = (in->height *  jobnr   ) / nb_jobs;              \ 
 2031     const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;              \ 
 2032     uint8_t       *dstrow = out->data[0] + slice_start * out->linesize[0];   \ 
 2033     const uint8_t *srcrow = in ->data[0] + slice_start * in ->linesize[0];   \ 
 2034     const float factor = (1 << nbits) - 1;                                   \ 
 2035     const float scale_r = (lut1d->scale.r / factor) * (lut1d->lutsize - 1);  \ 
 2036     const float scale_g = (lut1d->scale.g / factor) * (lut1d->lutsize - 1);  \ 
 2037     const float scale_b = (lut1d->scale.b / factor) * (lut1d->lutsize - 1);  \ 
 2039     for (y = slice_start; y < slice_end; y++) {                              \ 
 2040         uint##nbits##_t *dst = (uint##nbits##_t *)dstrow;                    \ 
 2041         const uint##nbits##_t *src = (const uint##nbits##_t *)srcrow;        \ 
 2042         for (x = 0; x < in->width * step; x += step) {                       \ 
 2043             float rr = src[x + r] * scale_r;                                 \ 
 2044             float gg = src[x + g] * scale_g;                                 \ 
 2045             float bb = src[x + b] * scale_b;                                 \ 
 2046             rr = interp_1d_##name(lut1d, 0, rr);                             \ 
 2047             gg = interp_1d_##name(lut1d, 1, gg);                             \ 
 2048             bb = interp_1d_##name(lut1d, 2, bb);                             \ 
 2049             dst[x + r] = av_clip_uint##nbits(rr * factor);                   \ 
 2050             dst[x + g] = av_clip_uint##nbits(gg * factor);                   \ 
 2051             dst[x + b] = av_clip_uint##nbits(bb * factor);                   \ 
 2052             if (!direct && step == 4)                                        \ 
 2053                 dst[x + a] = src[x + a];                                     \ 
 2055         dstrow += out->linesize[0];                                          \ 
 2056         srcrow += in ->linesize[0];                                          \ 
 2061 DEFINE_INTERP_FUNC_1D(nearest,     8)
 
 2062 DEFINE_INTERP_FUNC_1D(
linear,      8)
 
 2063 DEFINE_INTERP_FUNC_1D(cosine,      8)
 
 2064 DEFINE_INTERP_FUNC_1D(cubic,       8)
 
 2065 DEFINE_INTERP_FUNC_1D(spline,      8)
 
 2067 DEFINE_INTERP_FUNC_1D(nearest,     16)
 
 2068 DEFINE_INTERP_FUNC_1D(
linear,      16)
 
 2069 DEFINE_INTERP_FUNC_1D(cosine,      16)
 
 2070 DEFINE_INTERP_FUNC_1D(cubic,       16)
 
 2071 DEFINE_INTERP_FUNC_1D(spline,      16)
 
 2075     int depth, is16bit, isfloat, 
planar;
 
 2076     LUT1DContext *lut1d = 
inlink->dst->priv;
 
 2079     depth = 
desc->comp[0].depth;
 
 2080     is16bit = 
desc->comp[0].depth > 8;
 
 2086 #define SET_FUNC_1D(name) do {                                     \ 
 2087     if (planar && !isfloat) {                                      \ 
 2089         case  8: lut1d->interp = interp_1d_8_##name##_p8;   break; \ 
 2090         case  9: lut1d->interp = interp_1d_16_##name##_p9;  break; \ 
 2091         case 10: lut1d->interp = interp_1d_16_##name##_p10; break; \ 
 2092         case 12: lut1d->interp = interp_1d_16_##name##_p12; break; \ 
 2093         case 14: lut1d->interp = interp_1d_16_##name##_p14; break; \ 
 2094         case 16: lut1d->interp = interp_1d_16_##name##_p16; break; \ 
 2096     } else if (isfloat) { lut1d->interp = interp_1d_##name##_pf32; \ 
 2097     } else if (is16bit) { lut1d->interp = interp_1d_16_##name;     \ 
 2098     } else {              lut1d->interp = interp_1d_8_##name; }    \ 
 2101     switch (lut1d->interpolation) {
 
 2102     case INTERPOLATE_1D_NEAREST:     SET_FUNC_1D(nearest);  
break;
 
 2103     case INTERPOLATE_1D_LINEAR:      SET_FUNC_1D(
linear);   
break;
 
 2104     case INTERPOLATE_1D_COSINE:      SET_FUNC_1D(cosine);   
break;
 
 2105     case INTERPOLATE_1D_CUBIC:       SET_FUNC_1D(cubic);    
break;
 
 2106     case INTERPOLATE_1D_SPLINE:      SET_FUNC_1D(spline);   
break;
 
 2119     LUT1DContext *lut1d = 
ctx->priv;
 
 2121     lut1d->scale.r = lut1d->scale.g = lut1d->scale.b = 1.f;
 
 2124         set_identity_matrix_1d(lut1d, 32);
 
 2135     ext = strrchr(lut1d->file, 
'.');
 
 2146         ret = parse_cinespace_1d(
ctx, 
f);
 
 2152     if (!
ret && !lut1d->lutsize) {
 
 2165     LUT1DContext *lut1d = 
ctx->priv;
 
 2201 static int lut1d_process_command(
AVFilterContext *
ctx, 
const char *cmd, 
const char *args,
 
 2202                            char *res, 
int res_len, 
int flags)
 
 2204     LUT1DContext *lut1d = 
ctx->priv;
 
 2213         set_identity_matrix_1d(lut1d, 32);
 
 2216     return config_input_1d(
ctx->inputs[0]);
 
 2223         .filter_frame = filter_frame_1d,
 
 2224         .config_props = config_input_1d,
 
 2231     .priv_size     = 
sizeof(LUT1DContext),
 
 2236     .priv_class    = &lut1d_class,
 
 2238     .process_command = lut1d_process_command,
 
  
static AVFrame * apply_lut(AVFilterLink *inlink, AVFrame *in)
 
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
 
static int config_input(AVFilterLink *inlink)
 
#define AV_PIX_FMT_GBRAP16
 
#define DEFINE_INTERP_FUNC_PLANAR_FLOAT(name, depth)
 
static float lerpf(float v0, float v1, float f)
 
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
 
#define AV_LOG_WARNING
Something somehow does not look correct.
 
AVPixelFormat
Pixel format.
 
static int mix(int c0, int c1)
 
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
 
static int parse_m3d(AVFilterContext *ctx, FILE *f)
 
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
 
#define NEXT_FLOAT_OR_GOTO(value, label)
 
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
 
int() avfilter_action_func(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
A function pointer passed to the AVFilterGraph::execute callback to be executed multiple times,...
 
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
 
static struct rgbvec apply_prelut(const Lut3DPreLut *prelut, const struct rgbvec *s)
 
static struct rgbvec lerp(const struct rgbvec *v0, const struct rgbvec *v1, float f)
 
#define FILTER_PIXFMTS_ARRAY(array)
 
static int parse_dat(AVFilterContext *ctx, FILE *f)
 
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
 
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
 
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
 
static av_const int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
 
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
 
This structure describes decoded (raw) audio or video data.
 
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
 
static int skip_line(const char *p)
 
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
 
static struct rgbvec interp_tetrahedral(const LUT3DContext *lut3d, const struct rgbvec *s)
Tetrahedral interpolation.
 
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
 
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
 
static av_cold int preinit(AVFilterContext *ctx)
 
static struct rgbvec interp_prism(const LUT3DContext *lut3d, const struct rgbvec *s)
 
const char * name
Filter name.
 
#define AVFILTER_DEFINE_CLASS_EXT(name, desc, options)
 
static int parse_cube(AVFilterContext *ctx, FILE *f)
 
A link between two filters.
 
const AVFilter ff_vf_lut3d
 
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
 
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
 
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
 
static int parse_3dl(AVFilterContext *ctx, FILE *f)
 
#define AV_PIX_FMT_GBRP14
 
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
 
#define AV_PIX_FMT_GBRP10
 
static double val(void *priv, double ch)
 
static av_always_inline float scale(float x, float s)
 
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out->ch+ch,(const uint8_t **) in->ch+ch, off *(out-> planar
 
static struct rgbvec interp_trilinear(const LUT3DContext *lut3d, const struct rgbvec *s)
Interpolate using the 8 vertices of a cube.
 
A filter pad used for either input or output.
 
static enum AVPixelFormat pix_fmts[]
 
static int config_output(AVFilterLink *outlink)
 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
 
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
 
#define AV_PIX_FMT_GBRAP10
 
#define AV_PIX_FMT_GBRAP12
 
int(* init)(AVBSFContext *ctx)
 
#define av_assert0(cond)
assert() equivalent, that is always enabled.
 
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
 
static char * fget_next_word(char *dst, int max, FILE *f)
 
#define DEFINE_INTERP_FUNC(name, nbits)
 
#define FILTER_INPUTS(array)
 
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
 
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
#define AV_PIX_FMT_GBRP16
 
#define AV_PIX_FMT_RGBA64
 
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
 
static float prelut_interp_1d_linear(const Lut3DPreLut *prelut, int idx, const float s)
 
Describe the class of an AVClass context structure.
 
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
 
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
 
#define fs(width, name, subs,...)
 
filter_frame For filters that do not use the activate() callback
 
#define FRAMESYNC_DEFINE_CLASS_EXT(name, context, field, options)
 
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
 
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
 
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
 
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
 
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
 
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
 
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
 
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
 
#define AV_PIX_FMT_GBRPF32
 
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
 
AVFilterContext * src
source filter
 
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
 
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
 
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
 
static int set_identity_matrix(AVFilterContext *ctx, int size)
 
static int interpolation(DeclickChannel *c, const double *src, int ar_order, double *acoefficients, int *index, int nb_errors, double *auxiliary, double *interpolated)
 
#define AV_LOG_INFO
Standard information.
 
#define AVFILTER_DEFINE_CLASS(fname)
 
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
 
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
 
#define AV_PIX_FMT_BGRA64
 
#define i(width, name, range_min, range_max)
 
avfilter_action_func * interp
 
int w
agreed upon image width
 
#define DEFINE_INTERP_FUNC_PLANAR(name, nbits, depth)
 
#define AV_PIX_FMT_GBRP12
 
#define av_malloc_array(a, b)
 
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
 
Used for passing data between threads.
 
@ INTERPOLATE_TETRAHEDRAL
 
static struct rgbvec interp_pyramid(const LUT3DContext *lut3d, const struct rgbvec *s)
 
const char * name
Pad name.
 
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
 
static int parse_cinespace(AVFilterContext *ctx, FILE *f)
 
static float sanitizef(float f)
 
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
 
static int allocate_3dlut(AVFilterContext *ctx, int lutsize, int prelut)
 
#define NEXT_LINE_OR_GOTO(loop_cond, label)
 
const AVFilter ff_vf_haldclut
 
int h
agreed upon image height
 
#define AV_PIX_FMT_GBRAPF32
 
static struct rgbvec interp_nearest(const LUT3DContext *lut3d, const struct rgbvec *s)
Get the nearest defined point.
 
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
 
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
 
#define NEXT_LINE(loop_cond)
 
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
 
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
 
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
 
#define FILTER_OUTPUTS(array)
 
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
 
void ff_lut3d_init_x86(LUT3DContext *s, const AVPixFmtDescriptor *desc)
 
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
 
#define flags(name, subs,...)
 
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
 
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
 
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
 
static av_cold int uninit(AVCodecContext *avctx)
 
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
 
const AVFilter ff_vf_lut1d
 
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
 
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
 
int interpolation
interp_mode
 
static int nearest_sample_index(float *data, float x, int low, int hi)