FFmpeg
Loading...
Searching...
No Matches
vf_iccgen.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Niklas Haas
3 * This file is part of FFmpeg.
4 *
5 * FFmpeg is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * FFmpeg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with FFmpeg; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/**
21 * @file
22 * filter for generating ICC profiles
23 */
24
25#include <lcms2.h>
26
27#include "libavutil/opt.h"
28#include "libavutil/pixdesc.h"
29
30#include "avfilter.h"
31#include "fflcms2.h"
32#include "filters.h"
33#include "video.h"
34
35typedef struct IccGenContext {
36 const AVClass *class;
38 /* options */
41 int force;
42 /* (cached) generated ICC profile */
43 cmsHPROFILE profile;
47
48#define OFFSET(x) offsetof(IccGenContext, x)
49#define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
50
51static const AVOption iccgen_options[] = {
52 {"color_primaries", "select color primaries", OFFSET(color_prim), AV_OPT_TYPE_INT, {.i64=0}, 0, AVCOL_PRI_NB-1, VF, .unit = "color_primaries"},
53 {"auto", "infer based on frame", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, VF, .unit = "color_primaries"},
54 {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT709}, 0, 0, VF, .unit = "color_primaries"},
55 {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470M}, 0, 0, VF, .unit = "color_primaries"},
56 {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470BG}, 0, 0, VF, .unit = "color_primaries"},
57 {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE170M}, 0, 0, VF, .unit = "color_primaries"},
58 {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE240M}, 0, 0, VF, .unit = "color_primaries"},
59 {"film", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_FILM}, 0, 0, VF, .unit = "color_primaries"},
60 {"bt2020", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT2020}, 0, 0, VF, .unit = "color_primaries"},
61 {"smpte428", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE428}, 0, 0, VF, .unit = "color_primaries"},
62 {"smpte431", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE431}, 0, 0, VF, .unit = "color_primaries"},
63 {"smpte432", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE432}, 0, 0, VF, .unit = "color_primaries"},
64 {"jedec-p22", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_JEDEC_P22}, 0, 0, VF, .unit = "color_primaries"},
65 {"ebu3213", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_EBU3213}, 0, 0, VF, .unit = "color_primaries"},
66 {"color_trc", "select color transfer", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64=0}, 0, AVCOL_TRC_NB-1, VF, .unit = "color_trc"},
67 {"auto", "infer based on frame", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, VF, .unit = "color_trc"},
68 {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT709}, 0, 0, VF, .unit = "color_trc"},
69 {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA22}, 0, 0, VF, .unit = "color_trc"},
70 {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA28}, 0, 0, VF, .unit = "color_trc"},
71 {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE170M}, 0, 0, VF, .unit = "color_trc"},
72 {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE240M}, 0, 0, VF, .unit = "color_trc"},
73 {"linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_LINEAR}, 0, 0, VF, .unit = "color_trc"},
74 {"iec61966-2-4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_4}, 0, 0, VF, .unit = "color_trc"},
75 {"bt1361e", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT1361_ECG}, 0, 0, VF, .unit = "color_trc"},
76 {"iec61966-2-1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_1}, 0, 0, VF, .unit = "color_trc"},
77 {"bt2020-10", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_10}, 0, 0, VF, .unit = "color_trc"},
78 {"bt2020-12", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_12}, 0, 0, VF, .unit = "color_trc"},
79 {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, 0, 0, VF, .unit = "color_trc"},
80 {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, 0, 0, VF, .unit = "color_trc"},
81 { "force", "overwrite existing ICC profile", OFFSET(force), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, VF },
82 { NULL }
83};
84
86
88{
89 IccGenContext *s = avctx->priv;
90 cmsCloseProfile(s->profile);
92}
93
95{
96 IccGenContext *s = avctx->priv;
97 return ff_icc_context_init(&s->icc, avctx);
98}
99
101{
102 AVFilterContext *avctx = inlink->dst;
103 IccGenContext *s = avctx->priv;
105 enum AVColorPrimaries prim;
106 int ret;
107
109 if (s->force) {
111 } else {
112 return ff_filter_frame(inlink->dst->outputs[0], frame);
113 }
114 }
115
116 trc = s->color_trc ? s->color_trc : frame->color_trc;
117 if (trc == AVCOL_TRC_UNSPECIFIED) {
119 if (!desc)
120 return AVERROR_INVALIDDATA;
121
122 if ((desc->flags & AV_PIX_FMT_FLAG_RGB) || frame->color_range == AVCOL_RANGE_JPEG) {
123 /* Default to sRGB for RGB or full-range content */
125 } else {
126 /* Default to an ITU-R transfer depending on the bit-depth */
127 trc = desc->comp[0].depth >= 12 ? AVCOL_TRC_BT2020_12
128 : desc->comp[0].depth >= 10 ? AVCOL_TRC_BT2020_10
130 }
131 }
132
133 prim = s->color_prim ? s->color_prim : frame->color_primaries;
134 if (prim == AVCOL_PRI_UNSPECIFIED) {
135 /* Simply always default to sRGB/BT.709 primaries to avoid surprises */
136 prim = AVCOL_PRI_BT709;
137 }
138
139 if (s->profile && prim != s->profile_prim && trc != s->profile_trc) {
140 cmsCloseProfile(s->profile);
141 s->profile = NULL;
142 }
143
144 if (!s->profile) {
145 if ((ret = ff_icc_profile_generate(&s->icc, prim, trc, &s->profile)) < 0)
146 return ret;
147 s->profile_prim = prim;
148 s->profile_trc = trc;
149 }
150
151 if ((ret = ff_icc_profile_attach(&s->icc, s->profile, frame)) < 0)
152 return ret;
153
154 return ff_filter_frame(inlink->dst->outputs[0], frame);
155}
156
157static const AVFilterPad iccgen_inputs[] = {
158 {
159 .name = "default",
160 .type = AVMEDIA_TYPE_VIDEO,
161 .filter_frame = iccgen_filter_frame,
162 },
163};
164
166 .p.name = "iccgen",
167 .p.description = NULL_IF_CONFIG_SMALL("Generate and attach ICC profiles."),
168 .p.priv_class = &iccgen_class,
170 .priv_size = sizeof(IccGenContext),
171 .init = &iccgen_init,
175};
const FFFilter ff_vf_iccgen
Definition vf_iccgen.c:165
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:182
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
Definition frame.c:725
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
Definition frame.h:144
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
static av_cold void uninit(AVBitStreamFilterContext *ctx)
int ff_icc_profile_attach(FFIccContext *s, cmsHPROFILE profile, AVFrame *frame)
Attach an ICC profile to a frame.
Definition fflcms2.c:170
int ff_icc_profile_generate(FFIccContext *s, enum AVColorPrimaries color_prim, enum AVColorTransferCharacteristic color_trc, cmsHPROFILE *out_profile)
Generate an ICC profile for a given combination of color primaries and transfer function.
Definition fflcms2.c:143
void ff_icc_context_uninit(FFIccContext *s)
Definition fflcms2.c:42
int ff_icc_context_init(FFIccContext *s, void *avctx)
Initializes an FFIccContext.
Definition fflcms2.c:30
#define VF
Definition af_afir.c:731
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
const char * desc
Definition libsvtav1.c:83
AVOptions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition pixdesc.h:136
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition pixfmt.h:649
@ AVCOL_PRI_NB
Not part of ABI.
Definition pixfmt.h:660
@ AVCOL_PRI_FILM
colour filters using Illuminant C
Definition pixfmt.h:652
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition pixfmt.h:657
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition pixfmt.h:644
@ AVCOL_PRI_JEDEC_P22
Definition pixfmt.h:659
@ AVCOL_PRI_SMPTE240M
identical to above, also called "SMPTE C" even though it uses D65
Definition pixfmt.h:651
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_PRI_EBU3213
EBU Tech. 3213-E (nothing there) / one of JEDEC P22 group phosphors.
Definition pixfmt.h:658
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition pixfmt.h:656
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
Definition pixfmt.h:654
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition pixfmt.h:650
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition pixfmt.h:653
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition pixfmt.h:647
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition pixfmt.h:672
@ AVCOL_TRC_SMPTE170M
also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
Definition pixfmt.h:679
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition pixfmt.h:677
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
Definition pixfmt.h:685
@ AVCOL_TRC_SMPTE240M
Definition pixfmt.h:680
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
Definition pixfmt.h:684
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition pixfmt.h:681
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition pixfmt.h:678
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition pixfmt.h:693
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition pixfmt.h:688
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition pixfmt.h:686
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition pixfmt.h:687
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition pixfmt.h:674
@ AVCOL_TRC_NB
Not part of ABI.
Definition pixfmt.h:694
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
FFIccContext icc
Definition vf_iccgen.c:37
cmsHPROFILE profile
Definition vf_iccgen.c:43
static av_cold void iccgen_uninit(AVFilterContext *avctx)
Definition vf_iccgen.c:87
static av_cold int iccgen_init(AVFilterContext *avctx)
Definition vf_iccgen.c:94
static const AVOption iccgen_options[]
Definition vf_iccgen.c:51
static int iccgen_filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition vf_iccgen.c:100
#define OFFSET(x)
Definition vf_iccgen.c:48
static const AVFilterPad iccgen_inputs[]
Definition vf_iccgen.c:157
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37