FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/format.h
Date: 2026-11-04 10:59:43
Exec Total Coverage
Lines: 33 33 100.0%
Functions: 8 8 100.0%
Branches: 32 48 66.7%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2024 Niklas Haas
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef SWSCALE_FORMAT_H
22 #define SWSCALE_FORMAT_H
23
24 #include <stdbool.h>
25
26 #include "libavutil/csp.h"
27 #include "libavutil/pixdesc.h"
28
29 #include "swscale.h"
30
31 8460888 static inline int ff_q_isnan(const AVRational a)
32 {
33
4/4
✓ Branch 0 taken 7843611 times.
✓ Branch 1 taken 617277 times.
✓ Branch 2 taken 7238400 times.
✓ Branch 3 taken 605211 times.
8460888 return !a.num && !a.den;
34 }
35
36 /* Like av_cmp_q but considers NaN == NaN */
37 4841688 static inline int ff_q_equal(const AVRational a, const AVRational b)
38 {
39
4/6
✓ Branch 1 taken 3619200 times.
✓ Branch 2 taken 1222488 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3619200 times.
✓ Branch 7 taken 1222488 times.
✗ Branch 8 not taken.
4841688 return (ff_q_isnan(a) && ff_q_isnan(b)) || !av_cmp_q(a, b);
40 }
41
42 1815633 static inline int ff_cie_xy_equal(const AVCIExy a, const AVCIExy b)
43 {
44
2/4
✓ Branch 1 taken 1815633 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1815633 times.
✗ Branch 5 not taken.
1815633 return ff_q_equal(a.x, b.x) && ff_q_equal(a.y, b.y);
45 }
46
47 605211 static inline int ff_prim_equal(const AVPrimaryCoefficients *a,
48 const AVPrimaryCoefficients *b)
49 {
50
1/2
✓ Branch 1 taken 605211 times.
✗ Branch 2 not taken.
1210422 return ff_cie_xy_equal(a->r, b->r) &&
51
2/4
✓ Branch 0 taken 605211 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 605211 times.
✗ Branch 4 not taken.
1210422 ff_cie_xy_equal(a->g, b->g) &&
52 605211 ff_cie_xy_equal(a->b, b->b);
53 }
54
55 enum {
56 FIELD_TOP, /* top/even rows, or progressive */
57 FIELD_BOTTOM, /* bottom/odd rows */
58 };
59
60 /* The X'Y'Z' conversion: ST 428-1 codes to and from gamma 2.2 RGB */
61 #define XYZ_TRC AVCOL_TRC_SMPTE428
62 #define XYZ_RGB_TRC AVCOL_TRC_GAMMA22
63
64 typedef struct SwsColor {
65 enum AVColorPrimaries prim;
66 enum AVColorTransferCharacteristic trc;
67 AVPrimaryCoefficients gamut; /* mastering display gamut */
68 AVRational min_luma; /* minimum luminance in nits */
69 AVRational max_luma; /* maximum luminance in nits */
70 AVRational frame_peak; /* per-frame/scene peak luminance, or 0 */
71 AVRational frame_avg; /* per-frame/scene average luminance, or 0 */
72 } SwsColor;
73
74 234962 static inline void ff_color_update_dynamic(SwsColor *dst, const SwsColor *src)
75 {
76 234962 dst->frame_peak = src->frame_peak;
77 234962 dst->frame_avg = src->frame_avg;
78 234962 }
79
80 /* Subset of AVFrame parameters that uniquely determine pixel representation */
81 typedef struct SwsFormat {
82 int width, height;
83 int interlaced;
84 int field;
85 enum AVPixelFormat format;
86 enum AVPixelFormat hw_format;
87 enum AVColorRange range;
88 enum AVColorSpace csp;
89 enum AVChromaLocation loc;
90 const AVPixFmtDescriptor *desc; /* convenience */
91 SwsColor color;
92 } SwsFormat;
93
94 5990614 static inline void ff_fmt_clear(SwsFormat *fmt)
95 {
96 5990614 *fmt = (SwsFormat) {
97 .format = AV_PIX_FMT_NONE,
98 .range = AVCOL_RANGE_UNSPECIFIED,
99 .csp = AVCOL_SPC_UNSPECIFIED,
100 .loc = AVCHROMA_LOC_UNSPECIFIED,
101 .color = {
102 .prim = AVCOL_PRI_UNSPECIFIED,
103 .trc = AVCOL_TRC_UNSPECIFIED,
104 },
105 };
106 5990614 }
107
108 /**
109 * This function also sanitizes and strips the input data, removing irrelevant
110 * fields for certain formats.
111 */
112 SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field);
113
114 /**
115 * Subset of ff_fmt_from_frame() that sets default metadata for the format.
116 */
117 void ff_fmt_from_pixfmt(enum AVPixelFormat pixfmt, SwsFormat *fmt);
118
119 605211 static inline int ff_color_equal(const SwsColor *c1, const SwsColor *c2)
120 {
121 1210422 return c1->prim == c2->prim &&
122
2/4
✓ Branch 0 taken 605211 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 605211 times.
✗ Branch 3 not taken.
1210422 c1->trc == c2->trc &&
123
1/2
✓ Branch 1 taken 605211 times.
✗ Branch 2 not taken.
1210422 ff_q_equal(c1->min_luma, c2->min_luma) &&
124
2/4
✓ Branch 0 taken 605211 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 605211 times.
✗ Branch 4 not taken.
1815633 ff_q_equal(c1->max_luma, c2->max_luma) &&
125 605211 ff_prim_equal(&c1->gamut, &c2->gamut);
126 }
127
128 /* Tests only the static components of a colorspace, ignoring per-frame data */
129 1376855 static inline int ff_fmt_equal(const SwsFormat *fmt1, const SwsFormat *fmt2)
130 {
131 2377479 return fmt1->width == fmt2->width &&
132
2/2
✓ Branch 0 taken 907174 times.
✓ Branch 1 taken 93450 times.
1000624 fmt1->height == fmt2->height &&
133
1/2
✓ Branch 0 taken 907174 times.
✗ Branch 1 not taken.
907174 fmt1->interlaced == fmt2->interlaced &&
134
1/2
✓ Branch 0 taken 907174 times.
✗ Branch 1 not taken.
907174 fmt1->field == fmt2->field &&
135
2/2
✓ Branch 0 taken 612097 times.
✓ Branch 1 taken 295077 times.
907174 fmt1->format == fmt2->format &&
136
2/2
✓ Branch 0 taken 609752 times.
✓ Branch 1 taken 2345 times.
612097 fmt1->range == fmt2->range &&
137
1/2
✓ Branch 0 taken 609752 times.
✗ Branch 1 not taken.
609752 fmt1->csp == fmt2->csp &&
138
5/6
✓ Branch 0 taken 1000624 times.
✓ Branch 1 taken 376231 times.
✓ Branch 2 taken 605211 times.
✓ Branch 3 taken 4541 times.
✓ Branch 4 taken 605211 times.
✗ Branch 5 not taken.
2982690 fmt1->loc == fmt2->loc &&
139 605211 ff_color_equal(&fmt1->color, &fmt2->color);
140 }
141
142 static inline int ff_fmt_align(enum AVPixelFormat fmt)
143 {
144 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
145 if (desc->flags & AV_PIX_FMT_FLAG_BAYER) {
146 return 2;
147 } else {
148 return 1 << desc->log2_chroma_h;
149 }
150 }
151
152 /* Internal helper to test a format for either the legacy backend or the
153 * ops-based backends, depending on `backends` (must be nonzero). */
154 int ff_sws_test_pixfmt_backend(const SwsBackend backends,
155 enum AVPixelFormat format, int output);
156
157 /**
158 * Statically test if a given format is supported by the given set of
159 * backends. This is a heuristic, which may have false positives if a
160 * specific backend does not actually implement all operations that would be
161 * required to support the format.
162 */
163 int ff_test_fmt(SwsBackend backends, const SwsFormat *fmt, int output);
164
165 /* Returns true if the formats are incomplete, false otherwise */
166 bool ff_infer_colors(SwsColor *src, SwsColor *dst);
167
168 /**
169 * Infers an unspecified chroma location of a subsampled format from the
170 * other format. Returns true if a location was inferred, false otherwise.
171 */
172 bool ff_infer_chroma_loc(SwsFormat *src, SwsFormat *dst);
173
174 /**
175 * Wrapper around av_chroma_location_enum_to_pos() that accounts for
176 * the per-field offset introduced by interlacing.
177 */
178 void ff_sws_chroma_pos(const SwsFormat *fmt, bool *incomplete,
179 int *out_xpos, int *out_ypos);
180
181 typedef struct SwsOpList SwsOpList;
182 typedef struct SwsLut3D SwsLut3D;
183
184 /**
185 * Generate an SwsOpList defining a conversion from `src` to `dst`, with an
186 * optional 3DLUT for converting between gamuts.
187 *
188 * Returns 0 on success, or a negative error code on failure.
189 */
190 int ff_sws_op_list_generate(SwsContext *ctx, const SwsFormat *src,
191 const SwsFormat *dst, const SwsLut3D *lut3d,
192 SwsOpList **out_ops, bool *incomplete);
193
194 /**
195 * Represents a view into a single field of frame data.
196 *
197 * Ostensibly, this is a (non-compatible) subset of AVFrame, however, the
198 * semantics are VERY different.
199 *
200 * Unlike AVFrame, this struct does NOT own any data references. All buffers
201 * referenced by a SwsFrame are managed externally. This merely represents
202 * a view into data.
203 *
204 * This struct is not refcounted, and may be freely copied onto the stack.
205 */
206 typedef struct SwsFrame {
207 /* Data buffers and line stride */
208 uint8_t *data[4];
209 int linesize[4];
210
211 /**
212 * Dimensions and format
213 */
214 int width, height;
215 enum AVPixelFormat format;
216
217 /**
218 * Pointer to the original AVFrame, if there is a 1:1 correspondence.
219 **/
220 const AVFrame *avframe;
221 } SwsFrame;
222
223 /**
224 * Initialize a SwsFrame from an AVFrame.
225 */
226 void ff_sws_frame_from_avframe(SwsFrame *dst, const AVFrame *src);
227
228 #endif /* SWSCALE_FORMAT_H */
229