FFmpeg
Loading...
Searching...
No Matches
vf_iccdetect.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/csp.h"
28#include "libavutil/opt.h"
29#include "libavutil/pixdesc.h"
30
31#include "avfilter.h"
32#include "fflcms2.h"
33#include "filters.h"
34#include "video.h"
35
36typedef struct IccDetectContext {
37 const AVClass *class;
39 int force;
40 /* (cached) detected ICC profile values */
45
46#define OFFSET(x) offsetof(IccDetectContext, x)
47#define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
48
49static const AVOption iccdetect_options[] = {
50 { "force", "overwrite existing tags", OFFSET(force), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, VF },
51 { NULL }
52};
53
55
57{
58 IccDetectContext *s = avctx->priv;
59 av_buffer_unref(&s->profile);
61}
62
64{
65 IccDetectContext *s = avctx->priv;
66 return ff_icc_context_init(&s->icc, avctx);
67}
68
70{
71 AVFilterContext *avctx = inlink->dst;
72 IccDetectContext *s = avctx->priv;
73 const AVFrameSideData *sd;
75 cmsHPROFILE profile;
76 int ret;
77
79 if (!sd)
80 return ff_filter_frame(inlink->dst->outputs[0], frame);
81
82 if (s->profile && s->profile->data == sd->buf->data) {
83 /* No change from previous ICC profile */
84 goto done;
85 }
86
87 if ((ret = av_buffer_replace(&s->profile, sd->buf)) < 0)
88 return ret;
89 s->profile_prim = AVCOL_PRI_UNSPECIFIED;
90 s->profile_trc = AVCOL_TRC_UNSPECIFIED;
91
92 profile = cmsOpenProfileFromMemTHR(s->icc.ctx, sd->data, sd->size);
93 if (!profile)
95
96 ret = ff_icc_profile_sanitize(&s->icc, profile);
97 if (!ret)
98 ret = ff_icc_profile_read_primaries(&s->icc, profile, &coeffs);
99 if (!ret)
100 ret = ff_icc_profile_detect_transfer(&s->icc, profile, &s->profile_trc);
101 cmsCloseProfile(profile);
102 if (ret < 0)
103 return ret;
104
105 s->profile_prim = av_csp_primaries_id_from_desc(&coeffs);
106
107done:
108 if (s->profile_prim != AVCOL_PRI_UNSPECIFIED) {
109 if (s->force || frame->color_primaries == AVCOL_PRI_UNSPECIFIED)
110 frame->color_primaries = s->profile_prim;
111 }
112
113 if (s->profile_trc != AVCOL_TRC_UNSPECIFIED) {
114 if (s->force || frame->color_trc == AVCOL_TRC_UNSPECIFIED)
115 frame->color_trc = s->profile_trc;
116 }
117
118 return ff_filter_frame(inlink->dst->outputs[0], frame);
119}
120
122 {
123 .name = "default",
124 .type = AVMEDIA_TYPE_VIDEO,
125 .filter_frame = iccdetect_filter_frame,
126 },
127};
128
130 .p.name = "iccdetect",
131 .p.description = NULL_IF_CONFIG_SMALL("Detect and parse ICC profiles."),
132 .p.priv_class = &iccdetect_class,
134 .priv_size = sizeof(IccDetectContext),
139};
const FFFilter ff_vf_iccdetect
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
Colorspace value utility functions for libavutil.
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
@ 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
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition buffer.c:233
#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
@ 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
enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm)
Detects which enum AVColorPrimaries constant corresponds to the given complete gamut description.
Definition csp.c:115
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
static av_cold void uninit(AVBitStreamFilterContext *ctx)
void ff_icc_context_uninit(FFIccContext *s)
Definition fflcms2.c:42
int ff_icc_profile_sanitize(FFIccContext *s, cmsHPROFILE profile)
Sanitize an ICC profile to try and fix badly broken values.
Definition fflcms2.c:211
int ff_icc_profile_read_primaries(FFIccContext *s, cmsHPROFILE profile, AVColorPrimariesDesc *out_primaries)
Read the color primaries and white point coefficients encoded by an ICC profile, and return the raw v...
Definition fflcms2.c:253
int ff_icc_context_init(FFIccContext *s, void *avctx)
Initializes an FFIccContext.
Definition fflcms2.c:30
int ff_icc_profile_detect_transfer(FFIccContext *s, cmsHPROFILE profile, enum AVColorTransferCharacteristic *out_trc)
Attempt detecting the transfer characteristic that best approximates the transfer function encoded by...
Definition fflcms2.c:300
#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
int profile
Definition mxfenc.c:2299
AVOptions.
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition pixfmt.h:672
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition csp.h:78
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
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
AVBufferRef * buf
Definition frame.h:332
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
FFIccContext icc
enum AVColorTransferCharacteristic profile_trc
enum AVColorPrimaries profile_prim
AVBufferRef * profile
static const AVFilterPad iccdetect_inputs[]
static av_cold int iccdetect_init(AVFilterContext *avctx)
static int iccdetect_filter_frame(AVFilterLink *inlink, AVFrame *frame)
#define OFFSET(x)
static const AVOption iccdetect_options[]
static av_cold void iccdetect_uninit(AVFilterContext *avctx)
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