Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file
@ 2024-01-20 15:14 Chen Yufei
  2024-01-20 15:14 ` [FFmpeg-devel] [PATCH v2 1/1] " Chen Yufei
  2024-01-23  1:59 ` [FFmpeg-devel] [PATCH v2 0/1] " Xiang, Haihao
  0 siblings, 2 replies; 20+ messages in thread
From: Chen Yufei @ 2024-01-20 15:14 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: haihao.xiang, Chen Yufei

This patch adds support for applying 3D LUT from file using oneVPL VPP.

PATCH v1 uses VA-API to create LUT surface. Because oneVPL can't work with VA-API on Windows,
this version now creates LUT in system memory (MFX_RESOURCE_SYSTEM_SURFACE) and let oneVPL
copy LUT to video memory.

Note: requires oneVPL-intel-gpu version >= 24.1.1 because this version contains
a fix for creating LUT in video memory.
(For details, refer to https://github.com/oneapi-src/oneVPL-intel-gpu/issues/307)

Chen Yufei (1):
  avfilter/vf_vpp_qsv: apply 3D LUT from file.

 libavfilter/Makefile     |   8 +-
 libavfilter/lut3d.c      | 669 +++++++++++++++++++++++++++++++++++++++
 libavfilter/lut3d.h      |  13 +
 libavfilter/vf_lut3d.c   | 590 +---------------------------------
 libavfilter/vf_vpp_qsv.c | 113 ++++++-
 5 files changed, 799 insertions(+), 594 deletions(-)
 create mode 100644 libavfilter/lut3d.c

-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-20 15:14 [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file Chen Yufei
@ 2024-01-20 15:14 ` Chen Yufei
  2024-01-24 11:39   ` Anton Khirnov
  2024-01-23  1:59 ` [FFmpeg-devel] [PATCH v2 0/1] " Xiang, Haihao
  1 sibling, 1 reply; 20+ messages in thread
From: Chen Yufei @ 2024-01-20 15:14 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: haihao.xiang, Chen Yufei

Usage: "vpp_qsv=lut3d_file=<path to file>"

Requires oneVPL, using system memory 3D LUT surface.

Signed-off-by: Chen Yufei <cyfdecyf@gmail.com>
---
 libavfilter/Makefile     |   8 +-
 libavfilter/lut3d.c      | 669 +++++++++++++++++++++++++++++++++++++++
 libavfilter/lut3d.h      |  13 +
 libavfilter/vf_lut3d.c   | 590 +---------------------------------
 libavfilter/vf_vpp_qsv.c | 113 ++++++-
 5 files changed, 799 insertions(+), 594 deletions(-)
 create mode 100644 libavfilter/lut3d.c

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index bba0219876..f682ea53c2 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -332,7 +332,7 @@ OBJS-$(CONFIG_GRAPHMONITOR_FILTER)           += f_graphmonitor.o
 OBJS-$(CONFIG_GRAYWORLD_FILTER)              += vf_grayworld.o
 OBJS-$(CONFIG_GREYEDGE_FILTER)               += vf_colorconstancy.o
 OBJS-$(CONFIG_GUIDED_FILTER)                 += vf_guided.o
-OBJS-$(CONFIG_HALDCLUT_FILTER)               += vf_lut3d.o framesync.o
+OBJS-$(CONFIG_HALDCLUT_FILTER)               += vf_lut3d.o lut3d.o framesync.o
 OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
 OBJS-$(CONFIG_HFLIP_VULKAN_FILTER)           += vf_flip_vulkan.o vulkan.o
 OBJS-$(CONFIG_HISTEQ_FILTER)                 += vf_histeq.o
@@ -370,10 +370,10 @@ OBJS-$(CONFIG_LIMITDIFF_FILTER)              += vf_limitdiff.o framesync.o
 OBJS-$(CONFIG_LIMITER_FILTER)                += vf_limiter.o
 OBJS-$(CONFIG_LOOP_FILTER)                   += f_loop.o
 OBJS-$(CONFIG_LUMAKEY_FILTER)                += vf_lumakey.o
-OBJS-$(CONFIG_LUT1D_FILTER)                  += vf_lut3d.o
+OBJS-$(CONFIG_LUT1D_FILTER)                  += vf_lut3d.o lut3d.o
 OBJS-$(CONFIG_LUT_FILTER)                    += vf_lut.o
 OBJS-$(CONFIG_LUT2_FILTER)                   += vf_lut2.o framesync.o
-OBJS-$(CONFIG_LUT3D_FILTER)                  += vf_lut3d.o framesync.o
+OBJS-$(CONFIG_LUT3D_FILTER)                  += vf_lut3d.o lut3d.o framesync.o
 OBJS-$(CONFIG_LUTRGB_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_LUTYUV_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_MASKEDCLAMP_FILTER)            += vf_maskedclamp.o framesync.o
@@ -553,7 +553,7 @@ OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER)       += vidstabutils.o vf_vidstabtransfo
 OBJS-$(CONFIG_VIF_FILTER)                    += vf_vif.o framesync.o
 OBJS-$(CONFIG_VIGNETTE_FILTER)               += vf_vignette.o
 OBJS-$(CONFIG_VMAFMOTION_FILTER)             += vf_vmafmotion.o framesync.o
-OBJS-$(CONFIG_VPP_QSV_FILTER)                += vf_vpp_qsv.o
+OBJS-$(CONFIG_VPP_QSV_FILTER)                += vf_vpp_qsv.o lut3d.o
 OBJS-$(CONFIG_VSTACK_FILTER)                 += vf_stack.o framesync.o
 OBJS-$(CONFIG_W3FDIF_FILTER)                 += vf_w3fdif.o
 OBJS-$(CONFIG_WAVEFORM_FILTER)               += vf_waveform.o
diff --git a/libavfilter/lut3d.c b/libavfilter/lut3d.c
new file mode 100644
index 0000000000..173979adcc
--- /dev/null
+++ b/libavfilter/lut3d.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2013 Clément Bœsch
+ * Copyright (c) 2018 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lut3d.h"
+
+#include <float.h>
+
+#include "libavutil/avstring.h"
+#include "libavutil/file_open.h"
+
+#define EXPONENT_MASK 0x7F800000
+#define MANTISSA_MASK 0x007FFFFF
+#define SIGN_MASK     0x80000000
+
+static inline float sanitizef(float f)
+{
+    union av_intfloat32 t;
+    t.f = f;
+
+    if ((t.i & EXPONENT_MASK) == EXPONENT_MASK) {
+        if ((t.i & MANTISSA_MASK) != 0) {
+            // NAN
+            return 0.0f;
+        } else if (t.i & SIGN_MASK) {
+            // -INF
+            return -FLT_MAX;
+        } else {
+            // +INF
+            return FLT_MAX;
+        }
+    }
+    return f;
+}
+
+static inline float lerpf(float v0, float v1, float f)
+{
+    return v0 + (v1 - v0) * f;
+}
+
+static inline struct rgbvec lerp(const struct rgbvec *v0, const struct rgbvec *v1, float f)
+{
+    struct rgbvec v = {
+        lerpf(v0->r, v1->r, f), lerpf(v0->g, v1->g, f), lerpf(v0->b, v1->b, f)
+    };
+    return v;
+}
+
+int ff_allocate_3dlut(AVFilterContext *ctx, LUT3DContext *lut3d, int lutsize, int prelut)
+{
+    int i;
+    if (lutsize < 2 || lutsize > MAX_LEVEL) {
+        av_log(ctx, AV_LOG_ERROR, "Too large or invalid 3D LUT size\n");
+        return AVERROR(EINVAL);
+    }
+
+    av_freep(&lut3d->lut);
+    lut3d->lut = av_malloc_array(lutsize * lutsize * lutsize, sizeof(*lut3d->lut));
+    if (!lut3d->lut)
+        return AVERROR(ENOMEM);
+
+    if (prelut) {
+        lut3d->prelut.size = PRELUT_SIZE;
+        for (i = 0; i < 3; i++) {
+            av_freep(&lut3d->prelut.lut[i]);
+            lut3d->prelut.lut[i] = av_malloc_array(PRELUT_SIZE, sizeof(*lut3d->prelut.lut[0]));
+            if (!lut3d->prelut.lut[i])
+                return AVERROR(ENOMEM);
+        }
+    } else {
+        lut3d->prelut.size = 0;
+        for (i = 0; i < 3; i++) {
+            av_freep(&lut3d->prelut.lut[i]);
+        }
+    }
+    lut3d->lutsize = lutsize;
+    lut3d->lutsize2 = lutsize * lutsize;
+    return 0;
+}
+
+static int set_identity_matrix(AVFilterContext *ctx, LUT3DContext *lut3d, int size)
+{
+    int ret, i, j, k;
+    const int size2 = size * size;
+    const float c = 1. / (size - 1);
+
+    ret = ff_allocate_3dlut(ctx, lut3d, size, 0);
+    if (ret < 0)
+        return ret;
+
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
+                vec->r = k * c;
+                vec->g = j * c;
+                vec->b = i * c;
+            }
+        }
+    }
+
+    return 0;
+}
+
+#define MAX_LINE_SIZE 512
+
+static int skip_line(const char *p)
+{
+    while (*p && av_isspace(*p))
+        p++;
+    return !*p || *p == '#';
+}
+
+static char* fget_next_word(char* dst, int max, FILE* f)
+{
+    int c;
+    char *p = dst;
+
+    /* for null */
+    max--;
+    /* skip until next non whitespace char */
+    while ((c = fgetc(f)) != EOF) {
+        if (av_isspace(c))
+            continue;
+
+        *p++ = c;
+        max--;
+        break;
+    }
+
+    /* get max bytes or up until next whitespace char */
+    for (; max > 0; max--) {
+        if ((c = fgetc(f)) == EOF)
+            break;
+
+        if (av_isspace(c))
+            break;
+
+        *p++ = c;
+    }
+
+    *p = 0;
+    if (p == dst)
+        return NULL;
+    return p;
+}
+
+
+#define NEXT_LINE(loop_cond) do {                           \
+    if (!fgets(line, sizeof(line), f)) {                    \
+        av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \
+        return AVERROR_INVALIDDATA;                         \
+    }                                                       \
+} while (loop_cond)
+
+#define NEXT_LINE_OR_GOTO(loop_cond, label) do {            \
+    if (!fgets(line, sizeof(line), f)) {                    \
+        av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \
+        ret = AVERROR_INVALIDDATA;                          \
+        goto label;                                         \
+    }                                                       \
+} while (loop_cond)
+
+/* Basically r g and b float values on each line, with a facultative 3DLUTSIZE
+ * directive; seems to be generated by Davinci */
+static int parse_dat(AVFilterContext *ctx, LUT3DContext *lut3d, FILE *f)
+{
+    char line[MAX_LINE_SIZE];
+    int ret, i, j, k, size, size2;
+
+    lut3d->lutsize = size = 33;
+    size2 = size * size;
+
+    NEXT_LINE(skip_line(line));
+    if (!strncmp(line, "3DLUTSIZE ", 10)) {
+        size = strtol(line + 10, NULL, 0);
+
+        NEXT_LINE(skip_line(line));
+    }
+
+    ret = ff_allocate_3dlut(ctx, lut3d, size, 0);
+    if (ret < 0)
+        return ret;
+
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
+                if (k != 0 || j != 0 || i != 0)
+                    NEXT_LINE(skip_line(line));
+                if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3)
+                    return AVERROR_INVALIDDATA;
+            }
+        }
+    }
+    return 0;
+}
+
+/* Iridas format */
+static int parse_cube(AVFilterContext *ctx, LUT3DContext *lut3d, FILE *f)
+{
+    char line[MAX_LINE_SIZE];
+    float min[3] = {0.0, 0.0, 0.0};
+    float max[3] = {1.0, 1.0, 1.0};
+
+    while (fgets(line, sizeof(line), f)) {
+        if (!strncmp(line, "LUT_3D_SIZE", 11)) {
+            int ret, i, j, k;
+            const int size = strtol(line + 12, NULL, 0);
+            const int size2 = size * size;
+
+            ret = ff_allocate_3dlut(ctx, lut3d, size, 0);
+            if (ret < 0)
+                return ret;
+
+            for (k = 0; k < size; k++) {
+                for (j = 0; j < size; j++) {
+                    for (i = 0; i < size; i++) {
+                        struct rgbvec *vec = &lut3d->lut[i * size2 + j * size + k];
+
+                        do {
+try_again:
+                            NEXT_LINE(0);
+                            if (!strncmp(line, "DOMAIN_", 7)) {
+                                float *vals = NULL;
+                                if      (!strncmp(line + 7, "MIN ", 4)) vals = min;
+                                else if (!strncmp(line + 7, "MAX ", 4)) vals = max;
+                                if (!vals)
+                                    return AVERROR_INVALIDDATA;
+                                av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2);
+                                av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n",
+                                       min[0], min[1], min[2], max[0], max[1], max[2]);
+                                goto try_again;
+                            } else if (!strncmp(line, "TITLE", 5)) {
+                                goto try_again;
+                            }
+                        } while (skip_line(line));
+                        if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3)
+                            return AVERROR_INVALIDDATA;
+                    }
+                }
+            }
+            break;
+        }
+    }
+
+    lut3d->scale.r = av_clipf(1. / (max[0] - min[0]), 0.f, 1.f);
+    lut3d->scale.g = av_clipf(1. / (max[1] - min[1]), 0.f, 1.f);
+    lut3d->scale.b = av_clipf(1. / (max[2] - min[2]), 0.f, 1.f);
+
+    return 0;
+}
+
+/* Assume 17x17x17 LUT with a 16-bit depth
+ * FIXME: it seems there are various 3dl formats */
+static int parse_3dl(AVFilterContext *ctx, LUT3DContext *lut3d, FILE *f)
+{
+    char line[MAX_LINE_SIZE];
+    int ret, i, j, k;
+    const int size = 17;
+    const int size2 = 17 * 17;
+    const float scale = 16*16*16;
+
+    lut3d->lutsize = size;
+
+    ret = ff_allocate_3dlut(ctx, lut3d, size, 0);
+    if (ret < 0)
+        return ret;
+
+    NEXT_LINE(skip_line(line));
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                int r, g, b;
+                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
+
+                NEXT_LINE(skip_line(line));
+                if (av_sscanf(line, "%d %d %d", &r, &g, &b) != 3)
+                    return AVERROR_INVALIDDATA;
+                vec->r = r / scale;
+                vec->g = g / scale;
+                vec->b = b / scale;
+            }
+        }
+    }
+    return 0;
+}
+
+/* Pandora format */
+static int parse_m3d(AVFilterContext *ctx, LUT3DContext *lut3d, FILE *f)
+{
+    float scale;
+    int ret, i, j, k, size, size2, in = -1, out = -1;
+    char line[MAX_LINE_SIZE];
+    uint8_t rgb_map[3] = {0, 1, 2};
+
+    while (fgets(line, sizeof(line), f)) {
+        if      (!strncmp(line, "in",  2)) in  = strtol(line + 2, NULL, 0);
+        else if (!strncmp(line, "out", 3)) out = strtol(line + 3, NULL, 0);
+        else if (!strncmp(line, "values", 6)) {
+            const char *p = line + 6;
+#define SET_COLOR(id) do {                  \
+    while (av_isspace(*p))                  \
+        p++;                                \
+    switch (*p) {                           \
+    case 'r': rgb_map[id] = 0; break;       \
+    case 'g': rgb_map[id] = 1; break;       \
+    case 'b': rgb_map[id] = 2; break;       \
+    }                                       \
+    while (*p && !av_isspace(*p))           \
+        p++;                                \
+} while (0)
+            SET_COLOR(0);
+            SET_COLOR(1);
+            SET_COLOR(2);
+            break;
+        }
+    }
+
+    if (in == -1 || out == -1) {
+        av_log(ctx, AV_LOG_ERROR, "in and out must be defined\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (in < 2 || out < 2 ||
+        in  > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL ||
+        out > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL) {
+        av_log(ctx, AV_LOG_ERROR, "invalid in (%d) or out (%d)\n", in, out);
+        return AVERROR_INVALIDDATA;
+    }
+    for (size = 1; size*size*size < in; size++);
+    lut3d->lutsize = size;
+    size2 = size * size;
+
+    ret = ff_allocate_3dlut(ctx, lut3d, size, 0);
+    if (ret < 0)
+        return ret;
+
+    scale = 1. / (out - 1);
+
+    for (k = 0; k < size; k++) {
+        for (j = 0; j < size; j++) {
+            for (i = 0; i < size; i++) {
+                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
+                float val[3];
+
+                NEXT_LINE(0);
+                if (av_sscanf(line, "%f %f %f", val, val + 1, val + 2) != 3)
+                    return AVERROR_INVALIDDATA;
+                vec->r = val[rgb_map[0]] * scale;
+                vec->g = val[rgb_map[1]] * scale;
+                vec->b = val[rgb_map[2]] * scale;
+            }
+        }
+    }
+    return 0;
+}
+
+static int nearest_sample_index(float *data, float x, int low, int hi)
+{
+    int mid;
+    if (x < data[low])
+        return low;
+
+    if (x > data[hi])
+        return hi;
+
+    for (;;) {
+        av_assert0(x >= data[low]);
+        av_assert0(x <= data[hi]);
+        av_assert0((hi-low) > 0);
+
+        if (hi - low == 1)
+            return low;
+
+        mid = (low + hi) / 2;
+
+        if (x < data[mid])
+            hi = mid;
+        else
+            low = mid;
+    }
+
+    return 0;
+}
+
+#define NEXT_FLOAT_OR_GOTO(value, label)                    \
+    if (!fget_next_word(line, sizeof(line) ,f)) {           \
+        ret = AVERROR_INVALIDDATA;                          \
+        goto label;                                         \
+    }                                                       \
+    if (av_sscanf(line, "%f", &value) != 1) {               \
+        ret = AVERROR_INVALIDDATA;                          \
+        goto label;                                         \
+    }
+
+static int parse_cinespace(AVFilterContext *ctx, LUT3DContext *lut3d, FILE *f)
+{
+    char line[MAX_LINE_SIZE];
+    float in_min[3]  = {0.0, 0.0, 0.0};
+    float in_max[3]  = {1.0, 1.0, 1.0};
+    float out_min[3] = {0.0, 0.0, 0.0};
+    float out_max[3] = {1.0, 1.0, 1.0};
+    int inside_metadata = 0, size, size2;
+    int prelut = 0;
+    int ret = 0;
+
+    int prelut_sizes[3] = {0, 0, 0};
+    float *in_prelut[3]  = {NULL, NULL, NULL};
+    float *out_prelut[3] = {NULL, NULL, NULL};
+
+    NEXT_LINE_OR_GOTO(skip_line(line), end);
+    if (strncmp(line, "CSPLUTV100", 10)) {
+        av_log(ctx, AV_LOG_ERROR, "Not cineSpace LUT format\n");
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    NEXT_LINE_OR_GOTO(skip_line(line), end);
+    if (strncmp(line, "3D", 2)) {
+        av_log(ctx, AV_LOG_ERROR, "Not 3D LUT format\n");
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    while (1) {
+        NEXT_LINE_OR_GOTO(skip_line(line), end);
+
+        if (!strncmp(line, "BEGIN METADATA", 14)) {
+            inside_metadata = 1;
+            continue;
+        }
+        if (!strncmp(line, "END METADATA", 12)) {
+            inside_metadata = 0;
+            continue;
+        }
+        if (inside_metadata == 0) {
+            int size_r, size_g, size_b;
+
+            for (int i = 0; i < 3; i++) {
+                int npoints = strtol(line, NULL, 0);
+
+                if (npoints > 2) {
+                    float v,last;
+
+                    if (npoints > PRELUT_SIZE) {
+                        av_log(ctx, AV_LOG_ERROR, "Prelut size too large.\n");
+                        ret = AVERROR_INVALIDDATA;
+                        goto end;
+                    }
+
+                    if (in_prelut[i] || out_prelut[i]) {
+                        av_log(ctx, AV_LOG_ERROR, "Invalid file has multiple preluts.\n");
+                        ret = AVERROR_INVALIDDATA;
+                        goto end;
+                    }
+
+                    in_prelut[i]  = (float*)av_malloc(npoints * sizeof(float));
+                    out_prelut[i] = (float*)av_malloc(npoints * sizeof(float));
+                    if (!in_prelut[i] || !out_prelut[i]) {
+                        ret = AVERROR(ENOMEM);
+                        goto end;
+                    }
+
+                    prelut_sizes[i] = npoints;
+                    in_min[i] = FLT_MAX;
+                    in_max[i] = -FLT_MAX;
+                    out_min[i] = FLT_MAX;
+                    out_max[i] = -FLT_MAX;
+
+                    for (int j = 0; j < npoints; j++) {
+                        NEXT_FLOAT_OR_GOTO(v, end)
+                        in_min[i] = FFMIN(in_min[i], v);
+                        in_max[i] = FFMAX(in_max[i], v);
+                        in_prelut[i][j] = v;
+                        if (j > 0 && v < last) {
+                            av_log(ctx, AV_LOG_ERROR, "Invalid file, non increasing prelut.\n");
+                            ret = AVERROR(ENOMEM);
+                            goto end;
+                        }
+                        last = v;
+                    }
+
+                    for (int j = 0; j < npoints; j++) {
+                        NEXT_FLOAT_OR_GOTO(v, end)
+                        out_min[i] = FFMIN(out_min[i], v);
+                        out_max[i] = FFMAX(out_max[i], v);
+                        out_prelut[i][j] = v;
+                    }
+
+                } else if (npoints == 2)  {
+                    NEXT_LINE_OR_GOTO(skip_line(line), end);
+                    if (av_sscanf(line, "%f %f", &in_min[i], &in_max[i]) != 2) {
+                        ret = AVERROR_INVALIDDATA;
+                        goto end;
+                    }
+                    NEXT_LINE_OR_GOTO(skip_line(line), end);
+                    if (av_sscanf(line, "%f %f", &out_min[i], &out_max[i]) != 2) {
+                        ret = AVERROR_INVALIDDATA;
+                        goto end;
+                    }
+
+                } else {
+                    av_log(ctx, AV_LOG_ERROR, "Unsupported number of pre-lut points.\n");
+                    ret = AVERROR_PATCHWELCOME;
+                    goto end;
+                }
+
+                NEXT_LINE_OR_GOTO(skip_line(line), end);
+            }
+
+            if (av_sscanf(line, "%d %d %d", &size_r, &size_g, &size_b) != 3) {
+                ret = AVERROR(EINVAL);
+                goto end;
+            }
+            if (size_r != size_g || size_r != size_b) {
+                av_log(ctx, AV_LOG_ERROR, "Unsupported size combination: %dx%dx%d.\n", size_r, size_g, size_b);
+                ret = AVERROR_PATCHWELCOME;
+                goto end;
+            }
+
+            size = size_r;
+            size2 = size * size;
+
+            if (prelut_sizes[0] && prelut_sizes[1] && prelut_sizes[2])
+                prelut = 1;
+
+            ret = ff_allocate_3dlut(ctx, lut3d, size, prelut);
+            if (ret < 0)
+                return ret;
+
+            for (int k = 0; k < size; k++) {
+                for (int j = 0; j < size; j++) {
+                    for (int i = 0; i < size; i++) {
+                        struct rgbvec *vec = &lut3d->lut[i * size2 + j * size + k];
+
+                        NEXT_LINE_OR_GOTO(skip_line(line), end);
+                        if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3) {
+                            ret = AVERROR_INVALIDDATA;
+                            goto end;
+                        }
+
+                        vec->r *= out_max[0] - out_min[0];
+                        vec->g *= out_max[1] - out_min[1];
+                        vec->b *= out_max[2] - out_min[2];
+                    }
+                }
+            }
+
+            break;
+        }
+    }
+
+    if (prelut) {
+        for (int c = 0; c < 3; c++) {
+
+            lut3d->prelut.min[c] = in_min[c];
+            lut3d->prelut.max[c] = in_max[c];
+            lut3d->prelut.scale[c] =  (1.0f / (float)(in_max[c] - in_min[c])) * (lut3d->prelut.size - 1);
+
+            for (int i = 0; i < lut3d->prelut.size; ++i) {
+                float mix = (float) i / (float)(lut3d->prelut.size - 1);
+                float x = lerpf(in_min[c], in_max[c], mix), a, b;
+
+                int idx = nearest_sample_index(in_prelut[c], x, 0, prelut_sizes[c]-1);
+                av_assert0(idx + 1 < prelut_sizes[c]);
+
+                a   = out_prelut[c][idx + 0];
+                b   = out_prelut[c][idx + 1];
+                mix = x - in_prelut[c][idx];
+
+                lut3d->prelut.lut[c][i] = sanitizef(lerpf(a, b, mix));
+            }
+        }
+        lut3d->scale.r = 1.00f;
+        lut3d->scale.g = 1.00f;
+        lut3d->scale.b = 1.00f;
+
+    } else {
+        lut3d->scale.r = av_clipf(1. / (in_max[0] - in_min[0]), 0.f, 1.f);
+        lut3d->scale.g = av_clipf(1. / (in_max[1] - in_min[1]), 0.f, 1.f);
+        lut3d->scale.b = av_clipf(1. / (in_max[2] - in_min[2]), 0.f, 1.f);
+    }
+
+end:
+    for (int c = 0; c < 3; c++) {
+        av_freep(&in_prelut[c]);
+        av_freep(&out_prelut[c]);
+    }
+    return ret;
+}
+
+av_cold int ff_lut3d_init(AVFilterContext *ctx, LUT3DContext *lut3d)
+{
+    int ret;
+    FILE *f;
+    const char *ext;
+
+    lut3d->scale.r = lut3d->scale.g = lut3d->scale.b = 1.f;
+
+    if (!lut3d->file) {
+        return set_identity_matrix(ctx, lut3d, 32);
+    }
+
+    f = avpriv_fopen_utf8(lut3d->file, "r");
+    if (!f) {
+        ret = AVERROR(errno);
+        av_log(ctx, AV_LOG_ERROR, "%s: %s\n", lut3d->file, av_err2str(ret));
+        return ret;
+    }
+
+    ext = strrchr(lut3d->file, '.');
+    if (!ext) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to guess the format from the extension\n");
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
+    ext++;
+
+    if (!av_strcasecmp(ext, "dat")) {
+        ret = parse_dat(ctx, lut3d, f);
+    } else if (!av_strcasecmp(ext, "3dl")) {
+        ret = parse_3dl(ctx, lut3d, f);
+    } else if (!av_strcasecmp(ext, "cube")) {
+        ret = parse_cube(ctx, lut3d, f);
+    } else if (!av_strcasecmp(ext, "m3d")) {
+        ret = parse_m3d(ctx, lut3d, f);
+    } else if (!av_strcasecmp(ext, "csp")) {
+        ret = parse_cinespace(ctx, lut3d, f);
+    } else {
+        av_log(ctx, AV_LOG_ERROR, "Unrecognized '.%s' file type\n", ext);
+        ret = AVERROR(EINVAL);
+    }
+
+    if (!ret && !lut3d->lutsize) {
+        av_log(ctx, AV_LOG_ERROR, "3D LUT is empty\n");
+        ret = AVERROR_INVALIDDATA;
+    }
+
+end:
+    fclose(f);
+    return ret;
+}
+
+av_cold void ff_lut3d_uninit(LUT3DContext *lut3d)
+{
+    int i;
+    av_freep(&lut3d->lut);
+
+    for (i = 0; i < 3; i++) {
+        av_freep(&lut3d->prelut.lut[i]);
+    }
+}
diff --git a/libavfilter/lut3d.h b/libavfilter/lut3d.h
index 14e3c7fea6..b6aaed85f1 100644
--- a/libavfilter/lut3d.h
+++ b/libavfilter/lut3d.h
@@ -84,4 +84,17 @@ typedef struct ThreadData {
 
 void ff_lut3d_init_x86(LUT3DContext *s, const AVPixFmtDescriptor *desc);
 
+int ff_allocate_3dlut(AVFilterContext *ctx, LUT3DContext *lut3d, int lutsize, int prelut);
+
+/**
+ * Load 3D LUT from file.
+ *
+ * @param lut3d LUT3DContext Load 3D LUT from path specified by `lut3d->file`.
+ *     If `lut3d->file` is NULL, initialize an identity 3D LUT.
+ */
+int ff_lut3d_init(AVFilterContext *ctx, LUT3DContext *lut3d);
+
+/**  Release memory used to hold 3D LUT. */
+void ff_lut3d_uninit(LUT3DContext *lut3d);
+
 #endif /* AVFILTER_LUT3D_H */
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 4edcc2c7a7..1da798e210 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -552,39 +552,6 @@ static int skip_line(const char *p)
     return !*p || *p == '#';
 }
 
-static char* fget_next_word(char* dst, int max, FILE* f)
-{
-    int c;
-    char *p = dst;
-
-    /* for null */
-    max--;
-    /* skip until next non whitespace char */
-    while ((c = fgetc(f)) != EOF) {
-        if (av_isspace(c))
-            continue;
-
-        *p++ = c;
-        max--;
-        break;
-    }
-
-    /* get max bytes or up until next whitespace char */
-    for (; max > 0; max--) {
-        if ((c = fgetc(f)) == EOF)
-            break;
-
-        if (av_isspace(c))
-            break;
-
-        *p++ = c;
-    }
-
-    *p = 0;
-    if (p == dst)
-        return NULL;
-    return p;
-}
 
 #define NEXT_LINE(loop_cond) do {                           \
     if (!fgets(line, sizeof(line), f)) {                    \
@@ -593,505 +560,6 @@ static char* fget_next_word(char* dst, int max, FILE* f)
     }                                                       \
 } while (loop_cond)
 
-#define NEXT_LINE_OR_GOTO(loop_cond, label) do {            \
-    if (!fgets(line, sizeof(line), f)) {                    \
-        av_log(ctx, AV_LOG_ERROR, "Unexpected EOF\n");      \
-        ret = AVERROR_INVALIDDATA;                          \
-        goto label;                                         \
-    }                                                       \
-} while (loop_cond)
-
-static int allocate_3dlut(AVFilterContext *ctx, int lutsize, int prelut)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    int i;
-    if (lutsize < 2 || lutsize > MAX_LEVEL) {
-        av_log(ctx, AV_LOG_ERROR, "Too large or invalid 3D LUT size\n");
-        return AVERROR(EINVAL);
-    }
-
-    av_freep(&lut3d->lut);
-    lut3d->lut = av_malloc_array(lutsize * lutsize * lutsize, sizeof(*lut3d->lut));
-    if (!lut3d->lut)
-        return AVERROR(ENOMEM);
-
-    if (prelut) {
-        lut3d->prelut.size = PRELUT_SIZE;
-        for (i = 0; i < 3; i++) {
-            av_freep(&lut3d->prelut.lut[i]);
-            lut3d->prelut.lut[i] = av_malloc_array(PRELUT_SIZE, sizeof(*lut3d->prelut.lut[0]));
-            if (!lut3d->prelut.lut[i])
-                return AVERROR(ENOMEM);
-        }
-    } else {
-        lut3d->prelut.size = 0;
-        for (i = 0; i < 3; i++) {
-            av_freep(&lut3d->prelut.lut[i]);
-        }
-    }
-    lut3d->lutsize = lutsize;
-    lut3d->lutsize2 = lutsize * lutsize;
-    return 0;
-}
-
-/* Basically r g and b float values on each line, with a facultative 3DLUTSIZE
- * directive; seems to be generated by Davinci */
-static int parse_dat(AVFilterContext *ctx, FILE *f)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    char line[MAX_LINE_SIZE];
-    int ret, i, j, k, size, size2;
-
-    lut3d->lutsize = size = 33;
-    size2 = size * size;
-
-    NEXT_LINE(skip_line(line));
-    if (!strncmp(line, "3DLUTSIZE ", 10)) {
-        size = strtol(line + 10, NULL, 0);
-
-        NEXT_LINE(skip_line(line));
-    }
-
-    ret = allocate_3dlut(ctx, size, 0);
-    if (ret < 0)
-        return ret;
-
-    for (k = 0; k < size; k++) {
-        for (j = 0; j < size; j++) {
-            for (i = 0; i < size; i++) {
-                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
-                if (k != 0 || j != 0 || i != 0)
-                    NEXT_LINE(skip_line(line));
-                if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3)
-                    return AVERROR_INVALIDDATA;
-            }
-        }
-    }
-    return 0;
-}
-
-/* Iridas format */
-static int parse_cube(AVFilterContext *ctx, FILE *f)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    char line[MAX_LINE_SIZE];
-    float min[3] = {0.0, 0.0, 0.0};
-    float max[3] = {1.0, 1.0, 1.0};
-
-    while (fgets(line, sizeof(line), f)) {
-        if (!strncmp(line, "LUT_3D_SIZE", 11)) {
-            int ret, i, j, k;
-            const int size = strtol(line + 12, NULL, 0);
-            const int size2 = size * size;
-
-            ret = allocate_3dlut(ctx, size, 0);
-            if (ret < 0)
-                return ret;
-
-            for (k = 0; k < size; k++) {
-                for (j = 0; j < size; j++) {
-                    for (i = 0; i < size; i++) {
-                        struct rgbvec *vec = &lut3d->lut[i * size2 + j * size + k];
-
-                        do {
-try_again:
-                            NEXT_LINE(0);
-                            if (!strncmp(line, "DOMAIN_", 7)) {
-                                float *vals = NULL;
-                                if      (!strncmp(line + 7, "MIN ", 4)) vals = min;
-                                else if (!strncmp(line + 7, "MAX ", 4)) vals = max;
-                                if (!vals)
-                                    return AVERROR_INVALIDDATA;
-                                av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2);
-                                av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n",
-                                       min[0], min[1], min[2], max[0], max[1], max[2]);
-                                goto try_again;
-                            } else if (!strncmp(line, "TITLE", 5)) {
-                                goto try_again;
-                            }
-                        } while (skip_line(line));
-                        if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3)
-                            return AVERROR_INVALIDDATA;
-                    }
-                }
-            }
-            break;
-        }
-    }
-
-    lut3d->scale.r = av_clipf(1. / (max[0] - min[0]), 0.f, 1.f);
-    lut3d->scale.g = av_clipf(1. / (max[1] - min[1]), 0.f, 1.f);
-    lut3d->scale.b = av_clipf(1. / (max[2] - min[2]), 0.f, 1.f);
-
-    return 0;
-}
-
-/* Assume 17x17x17 LUT with a 16-bit depth
- * FIXME: it seems there are various 3dl formats */
-static int parse_3dl(AVFilterContext *ctx, FILE *f)
-{
-    char line[MAX_LINE_SIZE];
-    LUT3DContext *lut3d = ctx->priv;
-    int ret, i, j, k;
-    const int size = 17;
-    const int size2 = 17 * 17;
-    const float scale = 16*16*16;
-
-    lut3d->lutsize = size;
-
-    ret = allocate_3dlut(ctx, size, 0);
-    if (ret < 0)
-        return ret;
-
-    NEXT_LINE(skip_line(line));
-    for (k = 0; k < size; k++) {
-        for (j = 0; j < size; j++) {
-            for (i = 0; i < size; i++) {
-                int r, g, b;
-                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
-
-                NEXT_LINE(skip_line(line));
-                if (av_sscanf(line, "%d %d %d", &r, &g, &b) != 3)
-                    return AVERROR_INVALIDDATA;
-                vec->r = r / scale;
-                vec->g = g / scale;
-                vec->b = b / scale;
-            }
-        }
-    }
-    return 0;
-}
-
-/* Pandora format */
-static int parse_m3d(AVFilterContext *ctx, FILE *f)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    float scale;
-    int ret, i, j, k, size, size2, in = -1, out = -1;
-    char line[MAX_LINE_SIZE];
-    uint8_t rgb_map[3] = {0, 1, 2};
-
-    while (fgets(line, sizeof(line), f)) {
-        if      (!strncmp(line, "in",  2)) in  = strtol(line + 2, NULL, 0);
-        else if (!strncmp(line, "out", 3)) out = strtol(line + 3, NULL, 0);
-        else if (!strncmp(line, "values", 6)) {
-            const char *p = line + 6;
-#define SET_COLOR(id) do {                  \
-    while (av_isspace(*p))                  \
-        p++;                                \
-    switch (*p) {                           \
-    case 'r': rgb_map[id] = 0; break;       \
-    case 'g': rgb_map[id] = 1; break;       \
-    case 'b': rgb_map[id] = 2; break;       \
-    }                                       \
-    while (*p && !av_isspace(*p))           \
-        p++;                                \
-} while (0)
-            SET_COLOR(0);
-            SET_COLOR(1);
-            SET_COLOR(2);
-            break;
-        }
-    }
-
-    if (in == -1 || out == -1) {
-        av_log(ctx, AV_LOG_ERROR, "in and out must be defined\n");
-        return AVERROR_INVALIDDATA;
-    }
-    if (in < 2 || out < 2 ||
-        in  > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL ||
-        out > MAX_LEVEL*MAX_LEVEL*MAX_LEVEL) {
-        av_log(ctx, AV_LOG_ERROR, "invalid in (%d) or out (%d)\n", in, out);
-        return AVERROR_INVALIDDATA;
-    }
-    for (size = 1; size*size*size < in; size++);
-    lut3d->lutsize = size;
-    size2 = size * size;
-
-    ret = allocate_3dlut(ctx, size, 0);
-    if (ret < 0)
-        return ret;
-
-    scale = 1. / (out - 1);
-
-    for (k = 0; k < size; k++) {
-        for (j = 0; j < size; j++) {
-            for (i = 0; i < size; i++) {
-                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
-                float val[3];
-
-                NEXT_LINE(0);
-                if (av_sscanf(line, "%f %f %f", val, val + 1, val + 2) != 3)
-                    return AVERROR_INVALIDDATA;
-                vec->r = val[rgb_map[0]] * scale;
-                vec->g = val[rgb_map[1]] * scale;
-                vec->b = val[rgb_map[2]] * scale;
-            }
-        }
-    }
-    return 0;
-}
-
-static int nearest_sample_index(float *data, float x, int low, int hi)
-{
-    int mid;
-    if (x < data[low])
-        return low;
-
-    if (x > data[hi])
-        return hi;
-
-    for (;;) {
-        av_assert0(x >= data[low]);
-        av_assert0(x <= data[hi]);
-        av_assert0((hi-low) > 0);
-
-        if (hi - low == 1)
-            return low;
-
-        mid = (low + hi) / 2;
-
-        if (x < data[mid])
-            hi = mid;
-        else
-            low = mid;
-    }
-
-    return 0;
-}
-
-#define NEXT_FLOAT_OR_GOTO(value, label)                    \
-    if (!fget_next_word(line, sizeof(line) ,f)) {           \
-        ret = AVERROR_INVALIDDATA;                          \
-        goto label;                                         \
-    }                                                       \
-    if (av_sscanf(line, "%f", &value) != 1) {               \
-        ret = AVERROR_INVALIDDATA;                          \
-        goto label;                                         \
-    }
-
-static int parse_cinespace(AVFilterContext *ctx, FILE *f)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    char line[MAX_LINE_SIZE];
-    float in_min[3]  = {0.0, 0.0, 0.0};
-    float in_max[3]  = {1.0, 1.0, 1.0};
-    float out_min[3] = {0.0, 0.0, 0.0};
-    float out_max[3] = {1.0, 1.0, 1.0};
-    int inside_metadata = 0, size, size2;
-    int prelut = 0;
-    int ret = 0;
-
-    int prelut_sizes[3] = {0, 0, 0};
-    float *in_prelut[3]  = {NULL, NULL, NULL};
-    float *out_prelut[3] = {NULL, NULL, NULL};
-
-    NEXT_LINE_OR_GOTO(skip_line(line), end);
-    if (strncmp(line, "CSPLUTV100", 10)) {
-        av_log(ctx, AV_LOG_ERROR, "Not cineSpace LUT format\n");
-        ret = AVERROR(EINVAL);
-        goto end;
-    }
-
-    NEXT_LINE_OR_GOTO(skip_line(line), end);
-    if (strncmp(line, "3D", 2)) {
-        av_log(ctx, AV_LOG_ERROR, "Not 3D LUT format\n");
-        ret = AVERROR(EINVAL);
-        goto end;
-    }
-
-    while (1) {
-        NEXT_LINE_OR_GOTO(skip_line(line), end);
-
-        if (!strncmp(line, "BEGIN METADATA", 14)) {
-            inside_metadata = 1;
-            continue;
-        }
-        if (!strncmp(line, "END METADATA", 12)) {
-            inside_metadata = 0;
-            continue;
-        }
-        if (inside_metadata == 0) {
-            int size_r, size_g, size_b;
-
-            for (int i = 0; i < 3; i++) {
-                int npoints = strtol(line, NULL, 0);
-
-                if (npoints > 2) {
-                    float v,last;
-
-                    if (npoints > PRELUT_SIZE) {
-                        av_log(ctx, AV_LOG_ERROR, "Prelut size too large.\n");
-                        ret = AVERROR_INVALIDDATA;
-                        goto end;
-                    }
-
-                    if (in_prelut[i] || out_prelut[i]) {
-                        av_log(ctx, AV_LOG_ERROR, "Invalid file has multiple preluts.\n");
-                        ret = AVERROR_INVALIDDATA;
-                        goto end;
-                    }
-
-                    in_prelut[i]  = (float*)av_malloc(npoints * sizeof(float));
-                    out_prelut[i] = (float*)av_malloc(npoints * sizeof(float));
-                    if (!in_prelut[i] || !out_prelut[i]) {
-                        ret = AVERROR(ENOMEM);
-                        goto end;
-                    }
-
-                    prelut_sizes[i] = npoints;
-                    in_min[i] = FLT_MAX;
-                    in_max[i] = -FLT_MAX;
-                    out_min[i] = FLT_MAX;
-                    out_max[i] = -FLT_MAX;
-
-                    for (int j = 0; j < npoints; j++) {
-                        NEXT_FLOAT_OR_GOTO(v, end)
-                        in_min[i] = FFMIN(in_min[i], v);
-                        in_max[i] = FFMAX(in_max[i], v);
-                        in_prelut[i][j] = v;
-                        if (j > 0 && v < last) {
-                            av_log(ctx, AV_LOG_ERROR, "Invalid file, non increasing prelut.\n");
-                            ret = AVERROR(ENOMEM);
-                            goto end;
-                        }
-                        last = v;
-                    }
-
-                    for (int j = 0; j < npoints; j++) {
-                        NEXT_FLOAT_OR_GOTO(v, end)
-                        out_min[i] = FFMIN(out_min[i], v);
-                        out_max[i] = FFMAX(out_max[i], v);
-                        out_prelut[i][j] = v;
-                    }
-
-                } else if (npoints == 2)  {
-                    NEXT_LINE_OR_GOTO(skip_line(line), end);
-                    if (av_sscanf(line, "%f %f", &in_min[i], &in_max[i]) != 2) {
-                        ret = AVERROR_INVALIDDATA;
-                        goto end;
-                    }
-                    NEXT_LINE_OR_GOTO(skip_line(line), end);
-                    if (av_sscanf(line, "%f %f", &out_min[i], &out_max[i]) != 2) {
-                        ret = AVERROR_INVALIDDATA;
-                        goto end;
-                    }
-
-                } else {
-                    av_log(ctx, AV_LOG_ERROR, "Unsupported number of pre-lut points.\n");
-                    ret = AVERROR_PATCHWELCOME;
-                    goto end;
-                }
-
-                NEXT_LINE_OR_GOTO(skip_line(line), end);
-            }
-
-            if (av_sscanf(line, "%d %d %d", &size_r, &size_g, &size_b) != 3) {
-                ret = AVERROR(EINVAL);
-                goto end;
-            }
-            if (size_r != size_g || size_r != size_b) {
-                av_log(ctx, AV_LOG_ERROR, "Unsupported size combination: %dx%dx%d.\n", size_r, size_g, size_b);
-                ret = AVERROR_PATCHWELCOME;
-                goto end;
-            }
-
-            size = size_r;
-            size2 = size * size;
-
-            if (prelut_sizes[0] && prelut_sizes[1] && prelut_sizes[2])
-                prelut = 1;
-
-            ret = allocate_3dlut(ctx, size, prelut);
-            if (ret < 0)
-                return ret;
-
-            for (int k = 0; k < size; k++) {
-                for (int j = 0; j < size; j++) {
-                    for (int i = 0; i < size; i++) {
-                        struct rgbvec *vec = &lut3d->lut[i * size2 + j * size + k];
-
-                        NEXT_LINE_OR_GOTO(skip_line(line), end);
-                        if (av_sscanf(line, "%f %f %f", &vec->r, &vec->g, &vec->b) != 3) {
-                            ret = AVERROR_INVALIDDATA;
-                            goto end;
-                        }
-
-                        vec->r *= out_max[0] - out_min[0];
-                        vec->g *= out_max[1] - out_min[1];
-                        vec->b *= out_max[2] - out_min[2];
-                    }
-                }
-            }
-
-            break;
-        }
-    }
-
-    if (prelut) {
-        for (int c = 0; c < 3; c++) {
-
-            lut3d->prelut.min[c] = in_min[c];
-            lut3d->prelut.max[c] = in_max[c];
-            lut3d->prelut.scale[c] =  (1.0f / (float)(in_max[c] - in_min[c])) * (lut3d->prelut.size - 1);
-
-            for (int i = 0; i < lut3d->prelut.size; ++i) {
-                float mix = (float) i / (float)(lut3d->prelut.size - 1);
-                float x = lerpf(in_min[c], in_max[c], mix), a, b;
-
-                int idx = nearest_sample_index(in_prelut[c], x, 0, prelut_sizes[c]-1);
-                av_assert0(idx + 1 < prelut_sizes[c]);
-
-                a   = out_prelut[c][idx + 0];
-                b   = out_prelut[c][idx + 1];
-                mix = x - in_prelut[c][idx];
-
-                lut3d->prelut.lut[c][i] = sanitizef(lerpf(a, b, mix));
-            }
-        }
-        lut3d->scale.r = 1.00f;
-        lut3d->scale.g = 1.00f;
-        lut3d->scale.b = 1.00f;
-
-    } else {
-        lut3d->scale.r = av_clipf(1. / (in_max[0] - in_min[0]), 0.f, 1.f);
-        lut3d->scale.g = av_clipf(1. / (in_max[1] - in_min[1]), 0.f, 1.f);
-        lut3d->scale.b = av_clipf(1. / (in_max[2] - in_min[2]), 0.f, 1.f);
-    }
-
-end:
-    for (int c = 0; c < 3; c++) {
-        av_freep(&in_prelut[c]);
-        av_freep(&out_prelut[c]);
-    }
-    return ret;
-}
-
-static int set_identity_matrix(AVFilterContext *ctx, int size)
-{
-    LUT3DContext *lut3d = ctx->priv;
-    int ret, i, j, k;
-    const int size2 = size * size;
-    const float c = 1. / (size - 1);
-
-    ret = allocate_3dlut(ctx, size, 0);
-    if (ret < 0)
-        return ret;
-
-    for (k = 0; k < size; k++) {
-        for (j = 0; j < size; j++) {
-            for (i = 0; i < size; i++) {
-                struct rgbvec *vec = &lut3d->lut[k * size2 + j * size + i];
-                vec->r = k * c;
-                vec->g = j * c;
-                vec->b = i * c;
-            }
-        }
-    }
-
-    return 0;
-}
-
 static const enum AVPixelFormat pix_fmts[] = {
     AV_PIX_FMT_RGB24,  AV_PIX_FMT_BGR24,
     AV_PIX_FMT_RGBA,   AV_PIX_FMT_BGRA,
@@ -1230,66 +698,14 @@ AVFILTER_DEFINE_CLASS_EXT(lut3d, "lut3d", lut3d_haldclut_options);
 
 static av_cold int lut3d_init(AVFilterContext *ctx)
 {
-    int ret;
-    FILE *f;
-    const char *ext;
     LUT3DContext *lut3d = ctx->priv;
-
-    lut3d->scale.r = lut3d->scale.g = lut3d->scale.b = 1.f;
-
-    if (!lut3d->file) {
-        return set_identity_matrix(ctx, 32);
-    }
-
-    f = avpriv_fopen_utf8(lut3d->file, "r");
-    if (!f) {
-        ret = AVERROR(errno);
-        av_log(ctx, AV_LOG_ERROR, "%s: %s\n", lut3d->file, av_err2str(ret));
-        return ret;
-    }
-
-    ext = strrchr(lut3d->file, '.');
-    if (!ext) {
-        av_log(ctx, AV_LOG_ERROR, "Unable to guess the format from the extension\n");
-        ret = AVERROR_INVALIDDATA;
-        goto end;
-    }
-    ext++;
-
-    if (!av_strcasecmp(ext, "dat")) {
-        ret = parse_dat(ctx, f);
-    } else if (!av_strcasecmp(ext, "3dl")) {
-        ret = parse_3dl(ctx, f);
-    } else if (!av_strcasecmp(ext, "cube")) {
-        ret = parse_cube(ctx, f);
-    } else if (!av_strcasecmp(ext, "m3d")) {
-        ret = parse_m3d(ctx, f);
-    } else if (!av_strcasecmp(ext, "csp")) {
-        ret = parse_cinespace(ctx, f);
-    } else {
-        av_log(ctx, AV_LOG_ERROR, "Unrecognized '.%s' file type\n", ext);
-        ret = AVERROR(EINVAL);
-    }
-
-    if (!ret && !lut3d->lutsize) {
-        av_log(ctx, AV_LOG_ERROR, "3D LUT is empty\n");
-        ret = AVERROR_INVALIDDATA;
-    }
-
-end:
-    fclose(f);
-    return ret;
+    return ff_lut3d_init(ctx, lut3d);
 }
 
 static av_cold void lut3d_uninit(AVFilterContext *ctx)
 {
     LUT3DContext *lut3d = ctx->priv;
-    int i;
-    av_freep(&lut3d->lut);
-
-    for (i = 0; i < 3; i++) {
-        av_freep(&lut3d->prelut.lut[i]);
-    }
+    ff_lut3d_uninit(lut3d);
 }
 
 static const AVFilterPad lut3d_inputs[] = {
@@ -1499,7 +915,7 @@ static int config_clut(AVFilterLink *inlink)
         return AVERROR(EINVAL);
     }
 
-    return allocate_3dlut(ctx, level, 0);
+    return ff_allocate_3dlut(ctx, lut3d, level, 0);
 }
 
 static int update_apply_clut(FFFrameSync *fs)
diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index fdf9910186..f8ae3b7de7 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -37,6 +37,7 @@
 #include "internal.h"
 #include "avfilter.h"
 #include "filters.h"
+#include "lut3d.h"
 
 #include "qsvvpp.h"
 #include "transpose.h"
@@ -67,6 +68,13 @@ typedef struct VPPContext{
     /** HDR parameters attached on the input frame */
     mfxExtMasteringDisplayColourVolume mdcv_conf;
     mfxExtContentLightLevelInfo clli_conf;
+
+    /** LUT parameters attached on the input frame */
+    mfxExtVPP3DLut lut3d_conf;
+    LUT3DContext lut3d;
+    mfxU16* lut3d_r;
+    mfxU16* lut3d_g;
+    mfxU16* lut3d_b;
 #endif
 
     /**
@@ -388,6 +396,75 @@ static mfxStatus get_mfx_version(const AVFilterContext *ctx, mfxVersion *mfx_ver
     return MFXQueryVersion(device_hwctx->session, mfx_version);
 }
 
+#if QSV_ONEVPL
+// Create 3D LUT surface using system memory.
+// Reference https://spec.oneapi.io/onevpl/2.9.0/programming_guide/VPL_prg_vpp.html#video-processing-3dlut
+static void init_3dlut_surface(AVFilterContext *ctx)
+{
+    VPPContext *vpp = ctx->priv;
+    LUT3DContext *lut3d = &vpp->lut3d;
+    mfxExtVPP3DLut *lut3d_conf = &vpp->lut3d_conf;
+    int r, g, b, idx;
+    struct rgbvec *v = NULL;
+    int lut_size = lut3d->lutsize;
+    int lut_size2 = lut_size * lut_size;
+    int lut_size3 = lut_size * lut_size2;
+
+    av_log(ctx, AV_LOG_DEBUG, "create 3D LUT surface with system memory, LUT size: %d.\n", lut_size);
+
+    vpp->lut3d_r = av_calloc(lut_size3, sizeof(mfxU16));
+    vpp->lut3d_g = av_calloc(lut_size3, sizeof(mfxU16));
+    vpp->lut3d_b = av_calloc(lut_size3, sizeof(mfxU16));
+
+    // Copy 3D LUT to system memory surface.
+    for (r = 0, idx = 0; r < lut_size; ++r) {
+        for (g = 0; g < lut_size; ++g) {
+            for (b = 0; b < lut_size; ++b) {
+                v = &lut3d->lut[r * lut_size2 + g * lut_size + b];
+
+                vpp->lut3d_r[idx] = (mfxU16)(v->r * UINT16_MAX);
+                vpp->lut3d_g[idx] = (mfxU16)(v->g * UINT16_MAX);
+                vpp->lut3d_b[idx] = (mfxU16)(v->b * UINT16_MAX);
+                idx++;
+            }
+        }
+    }
+
+    memset(lut3d_conf, 0, sizeof(*lut3d_conf));
+    lut3d_conf->Header.BufferId = MFX_EXTBUFF_VPP_3DLUT;
+    lut3d_conf->Header.BufferSz = sizeof(*lut3d_conf);
+    lut3d_conf->ChannelMapping = MFX_3DLUT_CHANNEL_MAPPING_RGB_RGB;
+    lut3d_conf->BufferType = MFX_RESOURCE_SYSTEM_SURFACE;
+
+    lut3d_conf->SystemBuffer.Channel[0].DataType = MFX_DATA_TYPE_U16;
+    lut3d_conf->SystemBuffer.Channel[0].Size = lut_size;
+    lut3d_conf->SystemBuffer.Channel[0].Data16 = vpp->lut3d_r;
+
+    lut3d_conf->SystemBuffer.Channel[1].DataType = MFX_DATA_TYPE_U16;
+    lut3d_conf->SystemBuffer.Channel[1].Size = lut_size;
+    lut3d_conf->SystemBuffer.Channel[1].Data16 = vpp->lut3d_g;
+
+    lut3d_conf->SystemBuffer.Channel[2].DataType = MFX_DATA_TYPE_U16;
+    lut3d_conf->SystemBuffer.Channel[2].Size = lut_size;
+    lut3d_conf->SystemBuffer.Channel[2].Data16 = vpp->lut3d_b;
+}
+
+static void uninit_3dlut_surface(AVFilterContext *ctx) {
+    VPPContext *vpp = ctx->priv;
+    mfxExtVPP3DLut *lut3d_conf = &vpp->lut3d_conf;
+
+    if (lut3d_conf->Header.BufferId == MFX_EXTBUFF_VPP_3DLUT) {
+        av_free(vpp->lut3d_r);
+        av_free(vpp->lut3d_g);
+        av_free(vpp->lut3d_b);
+        vpp->lut3d_r = NULL;
+        vpp->lut3d_g = NULL;
+        vpp->lut3d_b = NULL;
+    }
+    memset(lut3d_conf, 0, sizeof(*lut3d_conf));
+}
+#endif // QSV_ONEVPL
+
 static int vpp_set_frame_ext_params(AVFilterContext *ctx, const AVFrame *in, AVFrame *out,  QSVVPPFrameParam *fp)
 {
 #if QSV_ONEVPL
@@ -499,6 +576,10 @@ static int vpp_set_frame_ext_params(AVFilterContext *ctx, const AVFrame *in, AVF
     outvsi_conf.MatrixCoefficients       = (out->colorspace == AVCOL_SPC_UNSPECIFIED) ? AVCOL_SPC_BT709 : out->colorspace;
     outvsi_conf.ColourDescriptionPresent = 1;
 
+    // 3D LUT does not depend on in/out frame, so initialize just once.
+    if (vpp->lut3d.file && (vpp->lut3d_conf.Header.BufferId == 0))
+        init_3dlut_surface(ctx);
+
     if (memcmp(&vpp->invsi_conf, &invsi_conf, sizeof(mfxExtVideoSignalInfo)) ||
         memcmp(&vpp->mdcv_conf, &mdcv_conf, sizeof(mfxExtMasteringDisplayColourVolume)) ||
         memcmp(&vpp->clli_conf, &clli_conf, sizeof(mfxExtContentLightLevelInfo)) ||
@@ -516,6 +597,9 @@ static int vpp_set_frame_ext_params(AVFilterContext *ctx, const AVFrame *in, AVF
         vpp->clli_conf                     = clli_conf;
         if (clli_conf.Header.BufferId)
             fp->ext_buf[fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->clli_conf;
+
+        if (vpp->lut3d_conf.Header.BufferId)
+            fp->ext_buf[fp->num_ext_buf++] = (mfxExtBuffer *)&vpp->lut3d_conf;
     }
 #endif
 
@@ -711,9 +795,22 @@ static int config_output(AVFilterLink *outlink)
         vpp->color_transfer != AVCOL_TRC_UNSPECIFIED ||
         vpp->color_matrix != AVCOL_SPC_UNSPECIFIED ||
         vpp->tonemap ||
-        !vpp->has_passthrough)
+#if QSV_ONEVPL
+        vpp->lut3d.file ||
+#endif
+        !vpp->has_passthrough) {
+#if QSV_ONEVPL
+        if (vpp->lut3d.file) {
+            int ret;
+            av_log(ctx, AV_LOG_INFO, "Load 3D LUT from file: %s\n", vpp->lut3d.file);
+            av_log(ctx, AV_LOG_INFO, "For oneVPL-intel-gpu, must use version >= 24.1.1 to correctly apply 3D LUT.\n");
+            ret = ff_lut3d_init(ctx, &vpp->lut3d);
+            if (ret != 0)
+                return ret;
+        }
+#endif
         return ff_qsvvpp_init(ctx, &param);
-    else {
+    } else {
         /* No MFX session is created in this case */
         av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
         if (inlink->hw_frames_ctx)
@@ -801,6 +898,14 @@ eof:
 
 static av_cold void vpp_uninit(AVFilterContext *ctx)
 {
+    VPPContext *vpp = ctx->priv;
+
+#if QSV_ONEVPL
+    uninit_3dlut_surface(ctx);
+    if (vpp->lut3d.file)
+        ff_lut3d_uninit(&vpp->lut3d);
+#endif
+
     ff_qsvvpp_close(ctx);
 }
 
@@ -923,7 +1028,9 @@ static const AVOption vpp_options[] = {
       OFFSET(color_transfer_str),  AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
 
     {"tonemap", "Perform tonemapping (0=disable tonemapping, 1=perform tonemapping if the input has HDR metadata)", OFFSET(tonemap), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, .flags = FLAGS},
-
+#if QSV_ONEVPL
+    { "lut3d_file", "Load and apply 3D LUT file", OFFSET(lut3d) + offsetof(LUT3DContext, file), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
+#endif
     { NULL }
 };
 
-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file
  2024-01-20 15:14 [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file Chen Yufei
  2024-01-20 15:14 ` [FFmpeg-devel] [PATCH v2 1/1] " Chen Yufei
@ 2024-01-23  1:59 ` Xiang, Haihao
  2024-01-23 12:09   ` Chen Yufei
  1 sibling, 1 reply; 20+ messages in thread
From: Xiang, Haihao @ 2024-01-23  1:59 UTC (permalink / raw)
  To: ffmpeg-devel, cyfdecyf

On Sa, 2024-01-20 at 23:14 +0800, Chen Yufei wrote:
> This patch adds support for applying 3D LUT from file using oneVPL VPP.
> 
> PATCH v1 uses VA-API to create LUT surface. Because oneVPL can't work with VA-
> API on Windows,
> this version now creates LUT in system memory (MFX_RESOURCE_SYSTEM_SURFACE)
> and let oneVPL
> copy LUT to video memory.
> 
> Note: requires oneVPL-intel-gpu version >= 24.1.1 because this version
> contains
> a fix for creating LUT in video memory.
> (For details, refer to
> https://github.com/oneapi-src/oneVPL-intel-gpu/issues/307)

Please bump a new runtime version, then you may check the runtime version for
this feature. 

Thanks
Haihao


> 
> Chen Yufei (1):
>   avfilter/vf_vpp_qsv: apply 3D LUT from file.
> 
>  libavfilter/Makefile     |   8 +-
>  libavfilter/lut3d.c      | 669 +++++++++++++++++++++++++++++++++++++++
>  libavfilter/lut3d.h      |  13 +
>  libavfilter/vf_lut3d.c   | 590 +---------------------------------
>  libavfilter/vf_vpp_qsv.c | 113 ++++++-
>  5 files changed, 799 insertions(+), 594 deletions(-)
>  create mode 100644 libavfilter/lut3d.c
> 

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file
  2024-01-23  1:59 ` [FFmpeg-devel] [PATCH v2 0/1] " Xiang, Haihao
@ 2024-01-23 12:09   ` Chen Yufei
  2024-01-24  7:24     ` Xiang, Haihao
  0 siblings, 1 reply; 20+ messages in thread
From: Chen Yufei @ 2024-01-23 12:09 UTC (permalink / raw)
  To: Xiang, Haihao; +Cc: ffmpeg-devel

On Tue, Jan 23, 2024 at 10:00 AM Xiang, Haihao <haihao.xiang@intel.com> wrote:
>
> On Sa, 2024-01-20 at 23:14 +0800, Chen Yufei wrote:
> > This patch adds support for applying 3D LUT from file using oneVPL VPP.
> >
> > PATCH v1 uses VA-API to create LUT surface. Because oneVPL can't work with VA-
> > API on Windows,
> > this version now creates LUT in system memory (MFX_RESOURCE_SYSTEM_SURFACE)
> > and let oneVPL
> > copy LUT to video memory.
> >
> > Note: requires oneVPL-intel-gpu version >= 24.1.1 because this version
> > contains
> > a fix for creating LUT in video memory.
> > (For details, refer to
> > https://github.com/oneapi-src/oneVPL-intel-gpu/issues/307)
>
> Please bump a new runtime version, then you may check the runtime version for
> this feature.

What does "bump a new runtime version" mean? Could you please provide
more details?

I'm confused about the version number of libvpl and oneVPL-intel-gpu.

I looked at the implementation of `QSV_RUNTIME_VERSION_ATLEAST`, and
tried to print `mfxVersion` stored in `vpp->qsv`.
I can only get 2.10 which is the version of libvpl (2.10.1 actually)
on my system.

I've also looked at the build directory of oneVPL-intel-gpu on my
system, the compile commands defines following

    -DMEDIA_VERSION_STR="24.1.2" -DMFX_API_VERSION="2.10+"

Do you mean I should just use `QSV_RUNTIME_VERSION_ATLEAST(ver, 2,
10)` to check the runtime version?
Does this guarantee the underlying oneVPL-intel-gpu would be >= 24.1.1 then?

>
> Thanks
> Haihao
>
>
> >
> > Chen Yufei (1):
> >   avfilter/vf_vpp_qsv: apply 3D LUT from file.
> >
> >  libavfilter/Makefile     |   8 +-
> >  libavfilter/lut3d.c      | 669 +++++++++++++++++++++++++++++++++++++++
> >  libavfilter/lut3d.h      |  13 +
> >  libavfilter/vf_lut3d.c   | 590 +---------------------------------
> >  libavfilter/vf_vpp_qsv.c | 113 ++++++-
> >  5 files changed, 799 insertions(+), 594 deletions(-)
> >  create mode 100644 libavfilter/lut3d.c
> >
>

-- 
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file
  2024-01-23 12:09   ` Chen Yufei
@ 2024-01-24  7:24     ` Xiang, Haihao
  0 siblings, 0 replies; 20+ messages in thread
From: Xiang, Haihao @ 2024-01-24  7:24 UTC (permalink / raw)
  To: cyfdecyf; +Cc: ffmpeg-devel

On Di, 2024-01-23 at 20:09 +0800, Chen Yufei wrote:
> On Tue, Jan 23, 2024 at 10:00 AM Xiang, Haihao <haihao.xiang@intel.com> wrote:
> > 
> > On Sa, 2024-01-20 at 23:14 +0800, Chen Yufei wrote:
> > > This patch adds support for applying 3D LUT from file using oneVPL VPP.
> > > 
> > > PATCH v1 uses VA-API to create LUT surface. Because oneVPL can't work with
> > > VA-
> > > API on Windows,
> > > this version now creates LUT in system memory
> > > (MFX_RESOURCE_SYSTEM_SURFACE)
> > > and let oneVPL
> > > copy LUT to video memory.
> > > 
> > > Note: requires oneVPL-intel-gpu version >= 24.1.1 because this version
> > > contains
> > > a fix for creating LUT in video memory.
> > > (For details, refer to
> > > https://github.com/oneapi-src/oneVPL-intel-gpu/issues/307)
> > 
> > Please bump a new runtime version, then you may check the runtime version
> > for
> > this feature.
> 
> What does "bump a new runtime version" mean? Could you please provide
> more details?
> 
> I'm confused about the version number of libvpl and oneVPL-intel-gpu.
> 
> I looked at the implementation of `QSV_RUNTIME_VERSION_ATLEAST`, and
> tried to print `mfxVersion` stored in `vpp->qsv`.
> I can only get 2.10 which is the version of libvpl (2.10.1 actually)
> on my system.
> 
> I've also looked at the build directory of oneVPL-intel-gpu on my
> system, the compile commands defines following
> 
>     -DMEDIA_VERSION_STR="24.1.2" -DMFX_API_VERSION="2.10+"
> 
> Do you mean I should just use `QSV_RUNTIME_VERSION_ATLEAST(ver, 2,
> 10)` to check the runtime version?

Yes, I meant using QSV_RUNTIME_VERSION_ATLEAST to check the runtime version. 

> Does this guarantee the underlying oneVPL-intel-gpu would be >= 24.1.1 then?

No, it doesn't. QSV_RUNTIME_VERSION_ATLEAST(ver, 2, 11) should guarantee the
feature works. This is why I said 'bump a new runtime version' 

Thanks
Haihao

> 
> > 
> > Thanks
> > Haihao
> > 
> > 
> > > 
> > > Chen Yufei (1):
> > >   avfilter/vf_vpp_qsv: apply 3D LUT from file.
> > > 
> > >  libavfilter/Makefile     |   8 +-
> > >  libavfilter/lut3d.c      | 669 +++++++++++++++++++++++++++++++++++++++
> > >  libavfilter/lut3d.h      |  13 +
> > >  libavfilter/vf_lut3d.c   | 590 +---------------------------------
> > >  libavfilter/vf_vpp_qsv.c | 113 ++++++-
> > >  5 files changed, 799 insertions(+), 594 deletions(-)
> > >  create mode 100644 libavfilter/lut3d.c
> > > 
> > 
> 

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-20 15:14 ` [FFmpeg-devel] [PATCH v2 1/1] " Chen Yufei
@ 2024-01-24 11:39   ` Anton Khirnov
  2024-01-25 16:16     ` Chen Yufei
  0 siblings, 1 reply; 20+ messages in thread
From: Anton Khirnov @ 2024-01-24 11:39 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: haihao.xiang, Chen Yufei

Quoting Chen Yufei (2024-01-20 16:14:29)
> Usage: "vpp_qsv=lut3d_file=<path to file>"

Passing file paths to a filter and having the filter load the file is
not recommended, it is generally preferable to have an
AV_OPT_TYPE_BINARY option, with IO performed by the caller.

E.g. in ffmpeg CLI you can do
 -filter vpp_qsv=/lut3d=<file>
to load the option value from a file.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-24 11:39   ` Anton Khirnov
@ 2024-01-25 16:16     ` Chen Yufei
  2024-01-28 10:31       ` Anton Khirnov
  0 siblings, 1 reply; 20+ messages in thread
From: Chen Yufei @ 2024-01-25 16:16 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, haihao.xiang, Chen Yufei

On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
>
> Quoting Chen Yufei (2024-01-20 16:14:29)
> > Usage: "vpp_qsv=lut3d_file=<path to file>"
>
> Passing file paths to a filter and having the filter load the file is
> not recommended, it is generally preferable to have an
> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
>
> E.g. in ffmpeg CLI you can do
>  -filter vpp_qsv=/lut3d=<file>
> to load the option value from a file.

I searched for code using `AV_OPT_TYPE_BINARY`.
`vf_libplacebo.c` gives me a good example.

The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
It's mainly text processing which calls functions on `FILE*`.
Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
code, and also need to change the command line option of `vf_lut3d`.
So I'd keep the lut file option as is.

If there are no other review messages. I'll send patch v3 this weekend.

The planed change is to
check runtime version >= 2.11 if `lut3d_file` option is set,
return `AVERROR(ENOTSUP)` and print error message if version is too low.

-- 
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-25 16:16     ` Chen Yufei
@ 2024-01-28 10:31       ` Anton Khirnov
  2024-01-28 12:22         ` Paul B Mahol
  2024-01-28 13:51         ` Zhao Zhili
  0 siblings, 2 replies; 20+ messages in thread
From: Anton Khirnov @ 2024-01-28 10:31 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, haihao.xiang, Chen Yufei

Quoting Chen Yufei (2024-01-25 17:16:46)
> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> >
> > Quoting Chen Yufei (2024-01-20 16:14:29)
> > > Usage: "vpp_qsv=lut3d_file=<path to file>"
> >
> > Passing file paths to a filter and having the filter load the file is
> > not recommended, it is generally preferable to have an
> > AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> >
> > E.g. in ffmpeg CLI you can do
> >  -filter vpp_qsv=/lut3d=<file>
> > to load the option value from a file.
> 
> I searched for code using `AV_OPT_TYPE_BINARY`.
> `vf_libplacebo.c` gives me a good example.
> 
> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> It's mainly text processing which calls functions on `FILE*`.
> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> code, and also need to change the command line option of `vf_lut3d`.
> So I'd keep the lut file option as is.

Your patch is rejected then.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 10:31       ` Anton Khirnov
@ 2024-01-28 12:22         ` Paul B Mahol
  2024-01-28 13:51         ` Zhao Zhili
  1 sibling, 0 replies; 20+ messages in thread
From: Paul B Mahol @ 2024-01-28 12:22 UTC (permalink / raw)
  To: FFmpeg development discussions and patches,
	haihao.xiang-at-intel.com, Chen Yufei
  Cc: haihao.xiang

On Sun, Jan 28, 2024 at 11:31 AM Anton Khirnov <anton@khirnov.net> wrote:

> Quoting Chen Yufei (2024-01-25 17:16:46)
> > On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > >
> > > Quoting Chen Yufei (2024-01-20 16:14:29)
> > > > Usage: "vpp_qsv=lut3d_file=<path to file>"
> > >
> > > Passing file paths to a filter and having the filter load the file is
> > > not recommended, it is generally preferable to have an
> > > AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> > >
> > > E.g. in ffmpeg CLI you can do
> > >  -filter vpp_qsv=/lut3d=<file>
> > > to load the option value from a file.
> >
> > I searched for code using `AV_OPT_TYPE_BINARY`.
> > `vf_libplacebo.c` gives me a good example.
> >
> > The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > It's mainly text processing which calls functions on `FILE*`.
> > Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > code, and also need to change the command line option of `vf_lut3d`.
> > So I'd keep the lut file option as is.
>
> Your patch is rejected then.
>

Thanks for stating that very clearly.

Yours sincerely, obsequious ex-contributor.


>
> --
> Anton Khirnov
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 10:31       ` Anton Khirnov
  2024-01-28 12:22         ` Paul B Mahol
@ 2024-01-28 13:51         ` Zhao Zhili
  2024-01-28 14:10           ` Anton Khirnov
  1 sibling, 1 reply; 20+ messages in thread
From: Zhao Zhili @ 2024-01-28 13:51 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: haihao.xiang, Chen Yufei



> On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> 
> Quoting Chen Yufei (2024-01-25 17:16:46)
>> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
>>> 
>>> Quoting Chen Yufei (2024-01-20 16:14:29)
>>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
>>> 
>>> Passing file paths to a filter and having the filter load the file is
>>> not recommended, it is generally preferable to have an
>>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
>>> 
>>> E.g. in ffmpeg CLI you can do
>>> -filter vpp_qsv=/lut3d=<file>
>>> to load the option value from a file.
>> 
>> I searched for code using `AV_OPT_TYPE_BINARY`.
>> `vf_libplacebo.c` gives me a good example.
>> 
>> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
>> It's mainly text processing which calls functions on `FILE*`.
>> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
>> code, and also need to change the command line option of `vf_lut3d`.
>> So I'd keep the lut file option as is.
> 
> Your patch is rejected then.

Could you be more elaborate?

I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
use AV_OPT_TYPE_BINARY for data which could be a large chunk.

Pass as file path works for me for now since it’s not the first case. We can replace
it if anyone has a better idea.

> 
> -- 
> Anton Khirnov
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 13:51         ` Zhao Zhili
@ 2024-01-28 14:10           ` Anton Khirnov
  2024-01-28 15:46             ` Zhao Zhili
  2024-01-29  3:01             ` Chen Yufei
  0 siblings, 2 replies; 20+ messages in thread
From: Anton Khirnov @ 2024-01-28 14:10 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: haihao.xiang, Chen Yufei

Quoting Zhao Zhili (2024-01-28 14:51:58)
> 
> 
> > On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > 
> > Quoting Chen Yufei (2024-01-25 17:16:46)
> >> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> >>> 
> >>> Quoting Chen Yufei (2024-01-20 16:14:29)
> >>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> >>> 
> >>> Passing file paths to a filter and having the filter load the file is
> >>> not recommended, it is generally preferable to have an
> >>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> >>> 
> >>> E.g. in ffmpeg CLI you can do
> >>> -filter vpp_qsv=/lut3d=<file>
> >>> to load the option value from a file.
> >> 
> >> I searched for code using `AV_OPT_TYPE_BINARY`.
> >> `vf_libplacebo.c` gives me a good example.
> >> 
> >> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> >> It's mainly text processing which calls functions on `FILE*`.
> >> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> >> code, and also need to change the command line option of `vf_lut3d`.
> >> So I'd keep the lut file option as is.
> > 
> > Your patch is rejected then.
> 
> Could you be more elaborate?

I said in my previous email what I believe should be done instead. I'm
open to reasonable arguments about that of course, but "I am going to
ignore your review" is not a good way to get patches in.

> I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
> use AV_OPT_TYPE_BINARY for data which could be a large chunk.

The LUT is loaded into memory in any case, is it not?

> Pass as file path works for me for now since it’s not the first case. We can replace
> it if anyone has a better idea.

Every new patch like this is just more work somebody has to undo in the
future. Given past experience, I'd MUCH prefer to do it properly in the
first place.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 14:10           ` Anton Khirnov
@ 2024-01-28 15:46             ` Zhao Zhili
  2024-01-28 16:52               ` Anton Khirnov
  2024-01-29  3:01             ` Chen Yufei
  1 sibling, 1 reply; 20+ messages in thread
From: Zhao Zhili @ 2024-01-28 15:46 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Haihao Xiang, Chen Yufei



> On Jan 28, 2024, at 22:10, Anton Khirnov <anton@khirnov.net> wrote:
> 
> Quoting Zhao Zhili (2024-01-28 14:51:58)
>> 
>> 
>>> On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
>>> 
>>> Quoting Chen Yufei (2024-01-25 17:16:46)
>>>> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
>>>>> 
>>>>> Quoting Chen Yufei (2024-01-20 16:14:29)
>>>>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
>>>>> 
>>>>> Passing file paths to a filter and having the filter load the file is
>>>>> not recommended, it is generally preferable to have an
>>>>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
>>>>> 
>>>>> E.g. in ffmpeg CLI you can do
>>>>> -filter vpp_qsv=/lut3d=<file>
>>>>> to load the option value from a file.
>>>> 
>>>> I searched for code using `AV_OPT_TYPE_BINARY`.
>>>> `vf_libplacebo.c` gives me a good example.
>>>> 
>>>> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
>>>> It's mainly text processing which calls functions on `FILE*`.
>>>> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
>>>> code, and also need to change the command line option of `vf_lut3d`.
>>>> So I'd keep the lut file option as is.
>>> 
>>> Your patch is rejected then.
>> 
>> Could you be more elaborate?
> 
> I said in my previous email what I believe should be done instead. I'm
> open to reasonable arguments about that of course, but "I am going to
> ignore your review" is not a good way to get patches in.
> 
>> I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
>> use AV_OPT_TYPE_BINARY for data which could be a large chunk.
> 
> The LUT is loaded into memory in any case, is it not?

The binary to string in hex format to binary is like transport image in base64. It doesn’t
sound right to use base64 for video streams.

> 
>> Pass as file path works for me for now since it’s not the first case. We can replace
>> it if anyone has a better idea.
> 
> Every new patch like this is just more work somebody has to undo in the
> future. Given past experience, I'd MUCH prefer to do it properly in the
> first place.
> 
> -- 
> Anton Khirnov
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 15:46             ` Zhao Zhili
@ 2024-01-28 16:52               ` Anton Khirnov
  2024-01-28 17:27                 ` Zhao Zhili
  0 siblings, 1 reply; 20+ messages in thread
From: Anton Khirnov @ 2024-01-28 16:52 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Haihao Xiang, Chen Yufei

Quoting Zhao Zhili (2024-01-28 16:46:55)
> 
> 
> > On Jan 28, 2024, at 22:10, Anton Khirnov <anton@khirnov.net> wrote:
> > 
> > Quoting Zhao Zhili (2024-01-28 14:51:58)
> >> 
> >> 
> >>> On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> >>> 
> >>> Quoting Chen Yufei (2024-01-25 17:16:46)
> >>>> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> >>>>> 
> >>>>> Quoting Chen Yufei (2024-01-20 16:14:29)
> >>>>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> >>>>> 
> >>>>> Passing file paths to a filter and having the filter load the file is
> >>>>> not recommended, it is generally preferable to have an
> >>>>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> >>>>> 
> >>>>> E.g. in ffmpeg CLI you can do
> >>>>> -filter vpp_qsv=/lut3d=<file>
> >>>>> to load the option value from a file.
> >>>> 
> >>>> I searched for code using `AV_OPT_TYPE_BINARY`.
> >>>> `vf_libplacebo.c` gives me a good example.
> >>>> 
> >>>> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> >>>> It's mainly text processing which calls functions on `FILE*`.
> >>>> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> >>>> code, and also need to change the command line option of `vf_lut3d`.
> >>>> So I'd keep the lut file option as is.
> >>> 
> >>> Your patch is rejected then.
> >> 
> >> Could you be more elaborate?
> > 
> > I said in my previous email what I believe should be done instead. I'm
> > open to reasonable arguments about that of course, but "I am going to
> > ignore your review" is not a good way to get patches in.
> > 
> >> I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
> >> use AV_OPT_TYPE_BINARY for data which could be a large chunk.
> > 
> > The LUT is loaded into memory in any case, is it not?
> 
> The binary to string in hex format to binary is like transport image in base64. It doesn’t
> sound right to use base64 for video streams.

I don't quite see the connection. Where is anything converted to a hex
string?

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 16:52               ` Anton Khirnov
@ 2024-01-28 17:27                 ` Zhao Zhili
  0 siblings, 0 replies; 20+ messages in thread
From: Zhao Zhili @ 2024-01-28 17:27 UTC (permalink / raw)
  To: 'FFmpeg development discussions and patches'



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Anton Khirnov
> Sent: 2024年1月29日 0:52
> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
> Cc: Haihao Xiang <haihao.xiang@intel.com>; Chen Yufei <cyfdecyf@gmail.com>
> Subject: Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
> 
> Quoting Zhao Zhili (2024-01-28 16:46:55)
> >
> >
> > > On Jan 28, 2024, at 22:10, Anton Khirnov <anton@khirnov.net> wrote:
> > >
> > > Quoting Zhao Zhili (2024-01-28 14:51:58)
> > >>
> > >>
> > >>> On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > >>>
> > >>> Quoting Chen Yufei (2024-01-25 17:16:46)
> > >>>> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > >>>>>
> > >>>>> Quoting Chen Yufei (2024-01-20 16:14:29)
> > >>>>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> > >>>>>
> > >>>>> Passing file paths to a filter and having the filter load the file is
> > >>>>> not recommended, it is generally preferable to have an
> > >>>>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> > >>>>>
> > >>>>> E.g. in ffmpeg CLI you can do
> > >>>>> -filter vpp_qsv=/lut3d=<file>
> > >>>>> to load the option value from a file.
> > >>>>
> > >>>> I searched for code using `AV_OPT_TYPE_BINARY`.
> > >>>> `vf_libplacebo.c` gives me a good example.
> > >>>>
> > >>>> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > >>>> It's mainly text processing which calls functions on `FILE*`.
> > >>>> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > >>>> code, and also need to change the command line option of `vf_lut3d`.
> > >>>> So I'd keep the lut file option as is.
> > >>>
> > >>> Your patch is rejected then.
> > >>
> > >> Could you be more elaborate?
> > >
> > > I said in my previous email what I believe should be done instead. I'm
> > > open to reasonable arguments about that of course, but "I am going to
> > > ignore your review" is not a good way to get patches in.
> > >
> > >> I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
> > >> use AV_OPT_TYPE_BINARY for data which could be a large chunk.
> > >
> > > The LUT is loaded into memory in any case, is it not?
> >
> > The binary to string in hex format to binary is like transport image in base64. It doesn’t
> > sound right to use base64 for video streams.
> 
> I don't quite see the connection. Where is anything converted to a hex
> string?

When the option value is set via av_opt_set instead of av_opt_set_bin. av_opt_set_bin can
avoid such inefficiency, but it still do memcpy.

> 
> --
> Anton Khirnov
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-28 14:10           ` Anton Khirnov
  2024-01-28 15:46             ` Zhao Zhili
@ 2024-01-29  3:01             ` Chen Yufei
  2024-01-29  3:28               ` Zhao Zhili
  2024-01-29 17:07               ` Anton Khirnov
  1 sibling, 2 replies; 20+ messages in thread
From: Chen Yufei @ 2024-01-29  3:01 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, Chen Yufei, anton
  Cc: haihao.xiang, quinkblack

On Sun, Jan 28, 2024 at 10:10 PM Anton Khirnov <anton@khirnov.net> wrote:
>
> Quoting Zhao Zhili (2024-01-28 14:51:58)
> >
> >
> > > On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > >
> > > Quoting Chen Yufei (2024-01-25 17:16:46)
> > >> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > >>>
> > >>> Quoting Chen Yufei (2024-01-20 16:14:29)
> > >>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> > >>>
> > >>> Passing file paths to a filter and having the filter load the file is
> > >>> not recommended, it is generally preferable to have an
> > >>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.

"is not recommended, it is generally preferable"
I take this as using `AV_OPT_TYPE_BINARY` is not a MUST.

I'm not an English native speaker, correct me If I'm wrong.

> > >>>
> > >>> E.g. in ffmpeg CLI you can do
> > >>> -filter vpp_qsv=/lut3d=<file>
> > >>> to load the option value from a file.
> > >>
> > >> I searched for code using `AV_OPT_TYPE_BINARY`.
> > >> `vf_libplacebo.c` gives me a good example.
> > >>
> > >> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > >> It's mainly text processing which calls functions on `FILE*`.
> > >> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > >> code, and also need to change the command line option of `vf_lut3d`.
> > >> So I'd keep the lut file option as is.
> > >
> > > Your patch is rejected then.

Now I understand using `AV_OPT_TYPE_BINARY` is a must.

> >
> > Could you be more elaborate?
>
> I said in my previous email what I believe should be done instead. I'm
> open to reasonable arguments about that of course, but "I am going to
> ignore your review" is not a good way to get patches in.
>

The review is not ignored.

I've taken time to search for how to use `AV_OPT_TYPE_BINARY` and did
not think it's
appropriate to use in this case.

If someone can show me code in FFmpeg that parses loaded data as text,
I can follow
that and send a new patch. This is to avoid doing things the wrong
way, as I'm a newcomer
and don't know if there's existing code to do this.

> > I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
> > use AV_OPT_TYPE_BINARY for data which could be a large chunk.
>
> The LUT is loaded into memory in any case, is it not?
>
> > Pass as file path works for me for now since it’s not the first case. We can replace
> > it if anyone has a better idea.
>
> Every new patch like this is just more work somebody has to undo in the
> future. Given past experience, I'd MUCH prefer to do it properly in the
> first place.
>
> --
> Anton Khirnov
--
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-29  3:01             ` Chen Yufei
@ 2024-01-29  3:28               ` Zhao Zhili
  2024-01-29 12:09                 ` Chen Yufei
  2024-01-29 17:07               ` Anton Khirnov
  1 sibling, 1 reply; 20+ messages in thread
From: Zhao Zhili @ 2024-01-29  3:28 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On Jan 29, 2024, at 11:01, Chen Yufei <cyfdecyf@gmail.com> wrote:
> 
> On Sun, Jan 28, 2024 at 10:10 PM Anton Khirnov <anton@khirnov.net <mailto:anton@khirnov.net>> wrote:
>> 
>> Quoting Zhao Zhili (2024-01-28 14:51:58)
>>> 
>>> 
>>>> On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
>>>> 
>>>> Quoting Chen Yufei (2024-01-25 17:16:46)
>>>>> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
>>>>>> 
>>>>>> Quoting Chen Yufei (2024-01-20 16:14:29)
>>>>>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
>>>>>> 
>>>>>> Passing file paths to a filter and having the filter load the file is
>>>>>> not recommended, it is generally preferable to have an
>>>>>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> 
> "is not recommended, it is generally preferable"
> I take this as using `AV_OPT_TYPE_BINARY` is not a MUST.
> 
> I'm not an English native speaker, correct me If I'm wrong.
> 
>>>>>> 
>>>>>> E.g. in ffmpeg CLI you can do
>>>>>> -filter vpp_qsv=/lut3d=<file>
>>>>>> to load the option value from a file.
>>>>> 
>>>>> I searched for code using `AV_OPT_TYPE_BINARY`.
>>>>> `vf_libplacebo.c` gives me a good example.
>>>>> 
>>>>> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
>>>>> It's mainly text processing which calls functions on `FILE*`.
>>>>> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
>>>>> code, and also need to change the command line option of `vf_lut3d`.
>>>>> So I'd keep the lut file option as is.
>>>> 
>>>> Your patch is rejected then.
> 
> Now I understand using `AV_OPT_TYPE_BINARY` is a must.
> 
>>> 
>>> Could you be more elaborate?
>> 
>> I said in my previous email what I believe should be done instead. I'm
>> open to reasonable arguments about that of course, but "I am going to
>> ignore your review" is not a good way to get patches in.
>> 
> 
> The review is not ignored.
> 
> I've taken time to search for how to use `AV_OPT_TYPE_BINARY` and did
> not think it's
> appropriate to use in this case.
> 
> If someone can show me code in FFmpeg that parses loaded data as text,
> I can follow
> that and send a new patch. This is to avoid doing things the wrong
> way, as I'm a newcomer
> and don't know if there's existing code to do this.

Check read_binary() in ffmpeg_filter.c for loading data from file and setting AV_OPT_TYPE_BINARY
option value.

Check pix_fmts option in buffersink.c for the consumer side of AV_OPT_TYPE_BINARY.

static const AVOption buffersink_options[] = {
    { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },

> 
>>> I agree pass LUT as file path isn’t flexible and clean, but it’s more questionable to
>>> use AV_OPT_TYPE_BINARY for data which could be a large chunk.
>> 
>> The LUT is loaded into memory in any case, is it not?
>> 
>>> Pass as file path works for me for now since it’s not the first case. We can replace
>>> it if anyone has a better idea.
>> 
>> Every new patch like this is just more work somebody has to undo in the
>> future. Given past experience, I'd MUCH prefer to do it properly in the
>> first place.
>> 
>> --
>> Anton Khirnov
> --
> Best regards,
> Chen Yufei
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-29  3:28               ` Zhao Zhili
@ 2024-01-29 12:09                 ` Chen Yufei
  0 siblings, 0 replies; 20+ messages in thread
From: Chen Yufei @ 2024-01-29 12:09 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Zhao Zhili

On Mon, Jan 29, 2024 at 11:29 AM Zhao Zhili <quinkblack@foxmail.com> wrote:
>
> >
> > If someone can show me code in FFmpeg that parses loaded data as text,
> > I can follow
> > that and send a new patch. This is to avoid doing things the wrong
> > way, as I'm a newcomer
> > and don't know if there's existing code to do this.
>
> Check read_binary() in ffmpeg_filter.c for loading data from file and setting AV_OPT_TYPE_BINARY
> option value.
>
> Check pix_fmts option in buffersink.c for the consumer side of AV_OPT_TYPE_BINARY.
>
> static const AVOption buffersink_options[] = {
>     { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
>

Thanks for giving directions. I find `FFTextReader` in
libavformat/subtitles.h and can follow that to create a
struct `FF3DLUTReader` to do text processing.

But there's one problem I don't know how to solve. When using
`AV_OPT_TYPE_BINARY`, the original file name
is not available in the filter code, only the loaded data and length
is available.

Take a look at `ff_lut3d_init`, it relies on file name extension to
detect LUT file type and call different parse functions.
If we add another option to specify LUT file type, then vf_lut3d's
command line option would require change.

-- 
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-29  3:01             ` Chen Yufei
  2024-01-29  3:28               ` Zhao Zhili
@ 2024-01-29 17:07               ` Anton Khirnov
  2024-01-30  2:59                 ` Chen Yufei
  1 sibling, 1 reply; 20+ messages in thread
From: Anton Khirnov @ 2024-01-29 17:07 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, Chen Yufei
  Cc: haihao.xiang, quinkblack

Quoting Chen Yufei (2024-01-29 04:01:51)
> On Sun, Jan 28, 2024 at 10:10 PM Anton Khirnov <anton@khirnov.net> wrote:
> >
> > Quoting Zhao Zhili (2024-01-28 14:51:58)
> > >
> > >
> > > > On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > > >
> > > > Quoting Chen Yufei (2024-01-25 17:16:46)
> > > >> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > > >>>
> > > >>> Quoting Chen Yufei (2024-01-20 16:14:29)
> > > >>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> > > >>>
> > > >>> Passing file paths to a filter and having the filter load the file is
> > > >>> not recommended, it is generally preferable to have an
> > > >>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> 
> "is not recommended, it is generally preferable"
> I take this as using `AV_OPT_TYPE_BINARY` is not a MUST.
> 
> I'm not an English native speaker, correct me If I'm wrong.
> 
> > > >>>
> > > >>> E.g. in ffmpeg CLI you can do
> > > >>> -filter vpp_qsv=/lut3d=<file>
> > > >>> to load the option value from a file.
> > > >>
> > > >> I searched for code using `AV_OPT_TYPE_BINARY`.
> > > >> `vf_libplacebo.c` gives me a good example.
> > > >>
> > > >> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > > >> It's mainly text processing which calls functions on `FILE*`.
> > > >> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > > >> code, and also need to change the command line option of `vf_lut3d`.
> > > >> So I'd keep the lut file option as is.
> > > >
> > > > Your patch is rejected then.
> 
> Now I understand using `AV_OPT_TYPE_BINARY` is a must.

Okay, sorry for being unclear. When I say 'recommended', it means it
must be done this way unless there is a strong technical reason to do it
otherwise. But then please provide a detailed explanation, not
something vague like "didn't seem appropriate".

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-29 17:07               ` Anton Khirnov
@ 2024-01-30  2:59                 ` Chen Yufei
  2024-02-03 11:09                   ` Chen Yufei
  0 siblings, 1 reply; 20+ messages in thread
From: Chen Yufei @ 2024-01-30  2:59 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, Chen Yufei, anton
  Cc: haihao.xiang, quinkblack

On Tue, Jan 30, 2024 at 1:07 AM Anton Khirnov <anton@khirnov.net> wrote:
>
> Quoting Chen Yufei (2024-01-29 04:01:51)
> > On Sun, Jan 28, 2024 at 10:10 PM Anton Khirnov <anton@khirnov.net> wrote:
> > >
> > > Quoting Zhao Zhili (2024-01-28 14:51:58)
> > > >
> > > >
> > > > > On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > > > >
> > > > > Quoting Chen Yufei (2024-01-25 17:16:46)
> > > > >> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > > > >>>
> > > > >>> Quoting Chen Yufei (2024-01-20 16:14:29)
> > > > >>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> > > > >>>
> > > > >>> Passing file paths to a filter and having the filter load the file is
> > > > >>> not recommended, it is generally preferable to have an
> > > > >>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> >
> > "is not recommended, it is generally preferable"
> > I take this as using `AV_OPT_TYPE_BINARY` is not a MUST.
> >
> > I'm not an English native speaker, correct me If I'm wrong.
> >
> > > > >>>
> > > > >>> E.g. in ffmpeg CLI you can do
> > > > >>> -filter vpp_qsv=/lut3d=<file>
> > > > >>> to load the option value from a file.
> > > > >>
> > > > >> I searched for code using `AV_OPT_TYPE_BINARY`.
> > > > >> `vf_libplacebo.c` gives me a good example.
> > > > >>
> > > > >> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > > > >> It's mainly text processing which calls functions on `FILE*`.
> > > > >> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > > > >> code, and also need to change the command line option of `vf_lut3d`.
> > > > >> So I'd keep the lut file option as is.
> > > > >
> > > > > Your patch is rejected then.
> >
> > Now I understand using `AV_OPT_TYPE_BINARY` is a must.
>
> Okay, sorry for being unclear. When I say 'recommended', it means it
> must be done this way unless there is a strong technical reason to do it
> otherwise. But then please provide a detailed explanation, not
> something vague like "didn't seem appropriate".

After taking more time looking into how to use `AV_OPT_TYPE_BINARY`,
I'll give more details.

1. For LUT file parsing, I'm not writing new code, it's taken from
existing vf_lut3d.c.
    I avoid making unnecessary modifications to avoid breaking things.

2. The original code relies on file name to detect LUT file type, uses
`fgets` and the like.
    From my understanding, `AV_OPT_TYPE_BINARY` does not give the file
name to the calling filter.
    If we use `AV_OPT_TYPE_BINARY`, then how to do file type detection?
    Adding other cmdline option would require changing vf_lut3d's
cmdline option.

3. I tried to find basic text processing utils in FFmpeg to avoid
writing ad-hoc text processing code in lut3d.c
    I've found `FFTextReader` in libavformat/subtitles.h, but I don't
think I should use it in filter code.
    I'm not sure if it's OK to follow the code in `FFTextReader` and
duplicate read line logic in lut3d.c.

Besides, there's `BINARY` in the name of `AV_OPT_TYPE_BINARY`, but
what I'm specifying here is text file.
This is not a big problem, but seem like an option name like
`AV_OPT_TYPE_TEXT` can express the usage of the option more clear in
code.

>
> --
> Anton Khirnov

-- 
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/1] avfilter/vf_vpp_qsv: apply 3D LUT from file.
  2024-01-30  2:59                 ` Chen Yufei
@ 2024-02-03 11:09                   ` Chen Yufei
  0 siblings, 0 replies; 20+ messages in thread
From: Chen Yufei @ 2024-02-03 11:09 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, Chen Yufei, anton
  Cc: haihao.xiang, quinkblack

On Tue, Jan 30, 2024 at 10:59 AM Chen Yufei <cyfdecyf@gmail.com> wrote:
>
> On Tue, Jan 30, 2024 at 1:07 AM Anton Khirnov <anton@khirnov.net> wrote:
> >
> > Quoting Chen Yufei (2024-01-29 04:01:51)
> > > On Sun, Jan 28, 2024 at 10:10 PM Anton Khirnov <anton@khirnov.net> wrote:
> > > >
> > > > Quoting Zhao Zhili (2024-01-28 14:51:58)
> > > > >
> > > > >
> > > > > > On Jan 28, 2024, at 18:31, Anton Khirnov <anton@khirnov.net> wrote:
> > > > > >
> > > > > > Quoting Chen Yufei (2024-01-25 17:16:46)
> > > > > >> On Wed, Jan 24, 2024 at 7:39 PM Anton Khirnov <anton@khirnov.net> wrote:
> > > > > >>>
> > > > > >>> Quoting Chen Yufei (2024-01-20 16:14:29)
> > > > > >>>> Usage: "vpp_qsv=lut3d_file=<path to file>"
> > > > > >>>
> > > > > >>> Passing file paths to a filter and having the filter load the file is
> > > > > >>> not recommended, it is generally preferable to have an
> > > > > >>> AV_OPT_TYPE_BINARY option, with IO performed by the caller.
> > >
> > > "is not recommended, it is generally preferable"
> > > I take this as using `AV_OPT_TYPE_BINARY` is not a MUST.
> > >
> > > I'm not an English native speaker, correct me If I'm wrong.
> > >
> > > > > >>>
> > > > > >>> E.g. in ffmpeg CLI you can do
> > > > > >>> -filter vpp_qsv=/lut3d=<file>
> > > > > >>> to load the option value from a file.
> > > > > >>
> > > > > >> I searched for code using `AV_OPT_TYPE_BINARY`.
> > > > > >> `vf_libplacebo.c` gives me a good example.
> > > > > >>
> > > > > >> The LUT parsing code is took from `libavfilter/vf_lut3d.c`.
> > > > > >> It's mainly text processing which calls functions on `FILE*`.
> > > > > >> Using `AV_OPT_TYPE_BINARY` would require many changes in LUT paring
> > > > > >> code, and also need to change the command line option of `vf_lut3d`.
> > > > > >> So I'd keep the lut file option as is.
> > > > > >
> > > > > > Your patch is rejected then.
> > >
> > > Now I understand using `AV_OPT_TYPE_BINARY` is a must.
> >
> > Okay, sorry for being unclear. When I say 'recommended', it means it
> > must be done this way unless there is a strong technical reason to do it
> > otherwise. But then please provide a detailed explanation, not
> > something vague like "didn't seem appropriate".
>
> After taking more time looking into how to use `AV_OPT_TYPE_BINARY`,
> I'll give more details.
>
> 1. For LUT file parsing, I'm not writing new code, it's taken from
> existing vf_lut3d.c.
>     I avoid making unnecessary modifications to avoid breaking things.
>
> 2. The original code relies on file name to detect LUT file type, uses
> `fgets` and the like.
>     From my understanding, `AV_OPT_TYPE_BINARY` does not give the file
> name to the calling filter.
>     If we use `AV_OPT_TYPE_BINARY`, then how to do file type detection?
>     Adding other cmdline option would require changing vf_lut3d's
> cmdline option.

I've spent some time this weekend trying to use `AV_OPT_TYPE_BINARY`.
Got an idea from vf_libplacebo.c.

It's possible to still use `AV_OPT_TYPE_STRING` in vf_lut3d.c, use
`av_file_map` to load text into a buffer, so that all the LUT parsing
functions can work on buffers instead of `FILE*`. But this is still
reading file in filter code.

It's more work than I expected and I don't know if this change will
meet the standards to be accepted.

I'll stop here.

If someone's interested in this feature, feel free to use my patch
https://github.com/cyfdecyf/FFmpeg/tree/vpp_qsv_lut_sysmem

>
> 3. I tried to find basic text processing utils in FFmpeg to avoid
> writing ad-hoc text processing code in lut3d.c
>     I've found `FFTextReader` in libavformat/subtitles.h, but I don't
> think I should use it in filter code.
>     I'm not sure if it's OK to follow the code in `FFTextReader` and
> duplicate read line logic in lut3d.c.
>
> Besides, there's `BINARY` in the name of `AV_OPT_TYPE_BINARY`, but
> what I'm specifying here is text file.
> This is not a big problem, but seem like an option name like
> `AV_OPT_TYPE_TEXT` can express the usage of the option more clear in
> code.
>

-- 
Best regards,
Chen Yufei
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-02-03 11:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-20 15:14 [FFmpeg-devel] [PATCH v2 0/1] avfilter/vf_vpp_qsv: apply 3D LUT from file Chen Yufei
2024-01-20 15:14 ` [FFmpeg-devel] [PATCH v2 1/1] " Chen Yufei
2024-01-24 11:39   ` Anton Khirnov
2024-01-25 16:16     ` Chen Yufei
2024-01-28 10:31       ` Anton Khirnov
2024-01-28 12:22         ` Paul B Mahol
2024-01-28 13:51         ` Zhao Zhili
2024-01-28 14:10           ` Anton Khirnov
2024-01-28 15:46             ` Zhao Zhili
2024-01-28 16:52               ` Anton Khirnov
2024-01-28 17:27                 ` Zhao Zhili
2024-01-29  3:01             ` Chen Yufei
2024-01-29  3:28               ` Zhao Zhili
2024-01-29 12:09                 ` Chen Yufei
2024-01-29 17:07               ` Anton Khirnov
2024-01-30  2:59                 ` Chen Yufei
2024-02-03 11:09                   ` Chen Yufei
2024-01-23  1:59 ` [FFmpeg-devel] [PATCH v2 0/1] " Xiang, Haihao
2024-01-23 12:09   ` Chen Yufei
2024-01-24  7:24     ` Xiang, Haihao

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git