FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/format.c
Date: 2025-07-28 20:30:09
Exec Total Coverage
Lines: 156 176 88.6%
Functions: 15 16 93.8%
Branches: 76 115 66.1%

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 #include "libavutil/avassert.h"
22 #include "libavutil/hdr_dynamic_metadata.h"
23 #include "libavutil/mastering_display_metadata.h"
24
25 #include "format.h"
26
27 typedef struct FormatEntry {
28 uint8_t is_supported_in :1;
29 uint8_t is_supported_out :1;
30 uint8_t is_supported_endianness :1;
31 } FormatEntry;
32
33 /* Format support table for legacy swscale */
34 static const FormatEntry format_entries[] = {
35 [AV_PIX_FMT_YUV420P] = { 1, 1 },
36 [AV_PIX_FMT_YUYV422] = { 1, 1 },
37 [AV_PIX_FMT_RGB24] = { 1, 1 },
38 [AV_PIX_FMT_BGR24] = { 1, 1 },
39 [AV_PIX_FMT_YUV422P] = { 1, 1 },
40 [AV_PIX_FMT_YUV444P] = { 1, 1 },
41 [AV_PIX_FMT_YUV410P] = { 1, 1 },
42 [AV_PIX_FMT_YUV411P] = { 1, 1 },
43 [AV_PIX_FMT_GRAY8] = { 1, 1 },
44 [AV_PIX_FMT_MONOWHITE] = { 1, 1 },
45 [AV_PIX_FMT_MONOBLACK] = { 1, 1 },
46 [AV_PIX_FMT_PAL8] = { 1, 0 },
47 [AV_PIX_FMT_YUVJ420P] = { 1, 1 },
48 [AV_PIX_FMT_YUVJ411P] = { 1, 1 },
49 [AV_PIX_FMT_YUVJ422P] = { 1, 1 },
50 [AV_PIX_FMT_YUVJ444P] = { 1, 1 },
51 [AV_PIX_FMT_YVYU422] = { 1, 1 },
52 [AV_PIX_FMT_UYVY422] = { 1, 1 },
53 [AV_PIX_FMT_UYYVYY411] = { 1, 0 },
54 [AV_PIX_FMT_BGR8] = { 1, 1 },
55 [AV_PIX_FMT_BGR4] = { 0, 1 },
56 [AV_PIX_FMT_BGR4_BYTE] = { 1, 1 },
57 [AV_PIX_FMT_RGB8] = { 1, 1 },
58 [AV_PIX_FMT_RGB4] = { 0, 1 },
59 [AV_PIX_FMT_RGB4_BYTE] = { 1, 1 },
60 [AV_PIX_FMT_NV12] = { 1, 1 },
61 [AV_PIX_FMT_NV21] = { 1, 1 },
62 [AV_PIX_FMT_ARGB] = { 1, 1 },
63 [AV_PIX_FMT_RGBA] = { 1, 1 },
64 [AV_PIX_FMT_ABGR] = { 1, 1 },
65 [AV_PIX_FMT_BGRA] = { 1, 1 },
66 [AV_PIX_FMT_0RGB] = { 1, 1 },
67 [AV_PIX_FMT_RGB0] = { 1, 1 },
68 [AV_PIX_FMT_0BGR] = { 1, 1 },
69 [AV_PIX_FMT_BGR0] = { 1, 1 },
70 [AV_PIX_FMT_GRAY9BE] = { 1, 1 },
71 [AV_PIX_FMT_GRAY9LE] = { 1, 1 },
72 [AV_PIX_FMT_GRAY10BE] = { 1, 1 },
73 [AV_PIX_FMT_GRAY10LE] = { 1, 1 },
74 [AV_PIX_FMT_GRAY12BE] = { 1, 1 },
75 [AV_PIX_FMT_GRAY12LE] = { 1, 1 },
76 [AV_PIX_FMT_GRAY14BE] = { 1, 1 },
77 [AV_PIX_FMT_GRAY14LE] = { 1, 1 },
78 [AV_PIX_FMT_GRAY16BE] = { 1, 1 },
79 [AV_PIX_FMT_GRAY16LE] = { 1, 1 },
80 [AV_PIX_FMT_YUV440P] = { 1, 1 },
81 [AV_PIX_FMT_YUVJ440P] = { 1, 1 },
82 [AV_PIX_FMT_YUV440P10LE] = { 1, 1 },
83 [AV_PIX_FMT_YUV440P10BE] = { 1, 1 },
84 [AV_PIX_FMT_YUV440P12LE] = { 1, 1 },
85 [AV_PIX_FMT_YUV440P12BE] = { 1, 1 },
86 [AV_PIX_FMT_YUVA420P] = { 1, 1 },
87 [AV_PIX_FMT_YUVA422P] = { 1, 1 },
88 [AV_PIX_FMT_YUVA444P] = { 1, 1 },
89 [AV_PIX_FMT_YUVA420P9BE] = { 1, 1 },
90 [AV_PIX_FMT_YUVA420P9LE] = { 1, 1 },
91 [AV_PIX_FMT_YUVA422P9BE] = { 1, 1 },
92 [AV_PIX_FMT_YUVA422P9LE] = { 1, 1 },
93 [AV_PIX_FMT_YUVA444P9BE] = { 1, 1 },
94 [AV_PIX_FMT_YUVA444P9LE] = { 1, 1 },
95 [AV_PIX_FMT_YUVA420P10BE] = { 1, 1 },
96 [AV_PIX_FMT_YUVA420P10LE] = { 1, 1 },
97 [AV_PIX_FMT_YUVA422P10BE] = { 1, 1 },
98 [AV_PIX_FMT_YUVA422P10LE] = { 1, 1 },
99 [AV_PIX_FMT_YUVA444P10BE] = { 1, 1 },
100 [AV_PIX_FMT_YUVA444P10LE] = { 1, 1 },
101 [AV_PIX_FMT_YUVA420P16BE] = { 1, 1 },
102 [AV_PIX_FMT_YUVA420P16LE] = { 1, 1 },
103 [AV_PIX_FMT_YUVA422P16BE] = { 1, 1 },
104 [AV_PIX_FMT_YUVA422P16LE] = { 1, 1 },
105 [AV_PIX_FMT_YUVA444P16BE] = { 1, 1 },
106 [AV_PIX_FMT_YUVA444P16LE] = { 1, 1 },
107 [AV_PIX_FMT_RGB48BE] = { 1, 1 },
108 [AV_PIX_FMT_RGB48LE] = { 1, 1 },
109 [AV_PIX_FMT_RGBA64BE] = { 1, 1, 1 },
110 [AV_PIX_FMT_RGBA64LE] = { 1, 1, 1 },
111 [AV_PIX_FMT_RGB565BE] = { 1, 1 },
112 [AV_PIX_FMT_RGB565LE] = { 1, 1 },
113 [AV_PIX_FMT_RGB555BE] = { 1, 1 },
114 [AV_PIX_FMT_RGB555LE] = { 1, 1 },
115 [AV_PIX_FMT_BGR565BE] = { 1, 1 },
116 [AV_PIX_FMT_BGR565LE] = { 1, 1 },
117 [AV_PIX_FMT_BGR555BE] = { 1, 1 },
118 [AV_PIX_FMT_BGR555LE] = { 1, 1 },
119 [AV_PIX_FMT_YUV420P16LE] = { 1, 1 },
120 [AV_PIX_FMT_YUV420P16BE] = { 1, 1 },
121 [AV_PIX_FMT_YUV422P16LE] = { 1, 1 },
122 [AV_PIX_FMT_YUV422P16BE] = { 1, 1 },
123 [AV_PIX_FMT_YUV444P16LE] = { 1, 1 },
124 [AV_PIX_FMT_YUV444P16BE] = { 1, 1 },
125 [AV_PIX_FMT_RGB444LE] = { 1, 1 },
126 [AV_PIX_FMT_RGB444BE] = { 1, 1 },
127 [AV_PIX_FMT_BGR444LE] = { 1, 1 },
128 [AV_PIX_FMT_BGR444BE] = { 1, 1 },
129 [AV_PIX_FMT_YA8] = { 1, 1 },
130 [AV_PIX_FMT_YA16BE] = { 1, 1 },
131 [AV_PIX_FMT_YA16LE] = { 1, 1 },
132 [AV_PIX_FMT_BGR48BE] = { 1, 1 },
133 [AV_PIX_FMT_BGR48LE] = { 1, 1 },
134 [AV_PIX_FMT_BGRA64BE] = { 1, 1, 1 },
135 [AV_PIX_FMT_BGRA64LE] = { 1, 1, 1 },
136 [AV_PIX_FMT_YUV420P9BE] = { 1, 1 },
137 [AV_PIX_FMT_YUV420P9LE] = { 1, 1 },
138 [AV_PIX_FMT_YUV420P10BE] = { 1, 1 },
139 [AV_PIX_FMT_YUV420P10LE] = { 1, 1 },
140 [AV_PIX_FMT_YUV420P12BE] = { 1, 1 },
141 [AV_PIX_FMT_YUV420P12LE] = { 1, 1 },
142 [AV_PIX_FMT_YUV420P14BE] = { 1, 1 },
143 [AV_PIX_FMT_YUV420P14LE] = { 1, 1 },
144 [AV_PIX_FMT_YUV422P9BE] = { 1, 1 },
145 [AV_PIX_FMT_YUV422P9LE] = { 1, 1 },
146 [AV_PIX_FMT_YUV422P10BE] = { 1, 1 },
147 [AV_PIX_FMT_YUV422P10LE] = { 1, 1 },
148 [AV_PIX_FMT_YUV422P12BE] = { 1, 1 },
149 [AV_PIX_FMT_YUV422P12LE] = { 1, 1 },
150 [AV_PIX_FMT_YUV422P14BE] = { 1, 1 },
151 [AV_PIX_FMT_YUV422P14LE] = { 1, 1 },
152 [AV_PIX_FMT_YUV444P9BE] = { 1, 1 },
153 [AV_PIX_FMT_YUV444P9LE] = { 1, 1 },
154 [AV_PIX_FMT_YUV444P10BE] = { 1, 1 },
155 [AV_PIX_FMT_YUV444P10LE] = { 1, 1 },
156 [AV_PIX_FMT_YUV444P12BE] = { 1, 1 },
157 [AV_PIX_FMT_YUV444P12LE] = { 1, 1 },
158 [AV_PIX_FMT_YUV444P14BE] = { 1, 1 },
159 [AV_PIX_FMT_YUV444P14LE] = { 1, 1 },
160 [AV_PIX_FMT_YUV444P10MSBBE] = { 1, 1 },
161 [AV_PIX_FMT_YUV444P10MSBLE] = { 1, 1 },
162 [AV_PIX_FMT_YUV444P12MSBBE] = { 1, 1 },
163 [AV_PIX_FMT_YUV444P12MSBLE] = { 1, 1 },
164 [AV_PIX_FMT_GBRP] = { 1, 1 },
165 [AV_PIX_FMT_GBRP9LE] = { 1, 1 },
166 [AV_PIX_FMT_GBRP9BE] = { 1, 1 },
167 [AV_PIX_FMT_GBRP10LE] = { 1, 1 },
168 [AV_PIX_FMT_GBRP10BE] = { 1, 1 },
169 [AV_PIX_FMT_GBRAP10LE] = { 1, 1 },
170 [AV_PIX_FMT_GBRAP10BE] = { 1, 1 },
171 [AV_PIX_FMT_GBRP10MSBLE] = { 1, 1 },
172 [AV_PIX_FMT_GBRP10MSBBE] = { 1, 1 },
173 [AV_PIX_FMT_GBRP12LE] = { 1, 1 },
174 [AV_PIX_FMT_GBRP12BE] = { 1, 1 },
175 [AV_PIX_FMT_GBRP12MSBLE] = { 1, 1 },
176 [AV_PIX_FMT_GBRP12MSBBE] = { 1, 1 },
177 [AV_PIX_FMT_GBRAP12LE] = { 1, 1 },
178 [AV_PIX_FMT_GBRAP12BE] = { 1, 1 },
179 [AV_PIX_FMT_GBRP14LE] = { 1, 1 },
180 [AV_PIX_FMT_GBRP14BE] = { 1, 1 },
181 [AV_PIX_FMT_GBRAP14LE] = { 1, 1 },
182 [AV_PIX_FMT_GBRAP14BE] = { 1, 1 },
183 [AV_PIX_FMT_GBRP16LE] = { 1, 1 },
184 [AV_PIX_FMT_GBRP16BE] = { 1, 1 },
185 [AV_PIX_FMT_GBRPF32LE] = { 1, 1 },
186 [AV_PIX_FMT_GBRPF32BE] = { 1, 1 },
187 [AV_PIX_FMT_GBRAPF32LE] = { 1, 1 },
188 [AV_PIX_FMT_GBRAPF32BE] = { 1, 1 },
189 [AV_PIX_FMT_GBRPF16LE] = { 1, 0 },
190 [AV_PIX_FMT_GBRPF16BE] = { 1, 0 },
191 [AV_PIX_FMT_GBRAPF16LE] = { 1, 0 },
192 [AV_PIX_FMT_GBRAPF16BE] = { 1, 0 },
193 [AV_PIX_FMT_GBRAP] = { 1, 1 },
194 [AV_PIX_FMT_GBRAP16LE] = { 1, 1 },
195 [AV_PIX_FMT_GBRAP16BE] = { 1, 1 },
196 [AV_PIX_FMT_BAYER_BGGR8] = { 1, 0 },
197 [AV_PIX_FMT_BAYER_RGGB8] = { 1, 0 },
198 [AV_PIX_FMT_BAYER_GBRG8] = { 1, 0 },
199 [AV_PIX_FMT_BAYER_GRBG8] = { 1, 0 },
200 [AV_PIX_FMT_BAYER_BGGR16LE] = { 1, 0 },
201 [AV_PIX_FMT_BAYER_BGGR16BE] = { 1, 0 },
202 [AV_PIX_FMT_BAYER_RGGB16LE] = { 1, 0 },
203 [AV_PIX_FMT_BAYER_RGGB16BE] = { 1, 0 },
204 [AV_PIX_FMT_BAYER_GBRG16LE] = { 1, 0 },
205 [AV_PIX_FMT_BAYER_GBRG16BE] = { 1, 0 },
206 [AV_PIX_FMT_BAYER_GRBG16LE] = { 1, 0 },
207 [AV_PIX_FMT_BAYER_GRBG16BE] = { 1, 0 },
208 [AV_PIX_FMT_XYZ12BE] = { 1, 1, 1 },
209 [AV_PIX_FMT_XYZ12LE] = { 1, 1, 1 },
210 [AV_PIX_FMT_AYUV64LE] = { 1, 1},
211 [AV_PIX_FMT_AYUV64BE] = { 1, 1 },
212 [AV_PIX_FMT_P010LE] = { 1, 1 },
213 [AV_PIX_FMT_P010BE] = { 1, 1 },
214 [AV_PIX_FMT_P012LE] = { 1, 1 },
215 [AV_PIX_FMT_P012BE] = { 1, 1 },
216 [AV_PIX_FMT_P016LE] = { 1, 1 },
217 [AV_PIX_FMT_P016BE] = { 1, 1 },
218 [AV_PIX_FMT_GRAYF32LE] = { 1, 1 },
219 [AV_PIX_FMT_GRAYF32BE] = { 1, 1 },
220 [AV_PIX_FMT_GRAYF16LE] = { 1, 0 },
221 [AV_PIX_FMT_GRAYF16BE] = { 1, 0 },
222 [AV_PIX_FMT_YAF32LE] = { 1, 0 },
223 [AV_PIX_FMT_YAF32BE] = { 1, 0 },
224 [AV_PIX_FMT_YAF16LE] = { 1, 0 },
225 [AV_PIX_FMT_YAF16BE] = { 1, 0 },
226 [AV_PIX_FMT_YUVA422P12BE] = { 1, 1 },
227 [AV_PIX_FMT_YUVA422P12LE] = { 1, 1 },
228 [AV_PIX_FMT_YUVA444P12BE] = { 1, 1 },
229 [AV_PIX_FMT_YUVA444P12LE] = { 1, 1 },
230 [AV_PIX_FMT_NV24] = { 1, 1 },
231 [AV_PIX_FMT_NV42] = { 1, 1 },
232 [AV_PIX_FMT_Y210LE] = { 1, 1 },
233 [AV_PIX_FMT_Y212LE] = { 1, 1 },
234 [AV_PIX_FMT_Y216LE] = { 1, 1 },
235 [AV_PIX_FMT_X2RGB10LE] = { 1, 1 },
236 [AV_PIX_FMT_X2BGR10LE] = { 1, 1 },
237 [AV_PIX_FMT_NV20BE] = { 1, 1 },
238 [AV_PIX_FMT_NV20LE] = { 1, 1 },
239 [AV_PIX_FMT_P210BE] = { 1, 1 },
240 [AV_PIX_FMT_P210LE] = { 1, 1 },
241 [AV_PIX_FMT_P212BE] = { 1, 1 },
242 [AV_PIX_FMT_P212LE] = { 1, 1 },
243 [AV_PIX_FMT_P410BE] = { 1, 1 },
244 [AV_PIX_FMT_P410LE] = { 1, 1 },
245 [AV_PIX_FMT_P412BE] = { 1, 1 },
246 [AV_PIX_FMT_P412LE] = { 1, 1 },
247 [AV_PIX_FMT_P216BE] = { 1, 1 },
248 [AV_PIX_FMT_P216LE] = { 1, 1 },
249 [AV_PIX_FMT_P416BE] = { 1, 1 },
250 [AV_PIX_FMT_P416LE] = { 1, 1 },
251 [AV_PIX_FMT_NV16] = { 1, 1 },
252 [AV_PIX_FMT_VUYA] = { 1, 1 },
253 [AV_PIX_FMT_VUYX] = { 1, 1 },
254 [AV_PIX_FMT_RGBAF16BE] = { 1, 0 },
255 [AV_PIX_FMT_RGBAF16LE] = { 1, 0 },
256 [AV_PIX_FMT_RGBF16BE] = { 1, 0 },
257 [AV_PIX_FMT_RGBF16LE] = { 1, 0 },
258 [AV_PIX_FMT_RGBF32BE] = { 1, 0 },
259 [AV_PIX_FMT_RGBF32LE] = { 1, 0 },
260 [AV_PIX_FMT_XV30LE] = { 1, 1 },
261 [AV_PIX_FMT_XV36LE] = { 1, 1 },
262 [AV_PIX_FMT_XV36BE] = { 1, 1 },
263 [AV_PIX_FMT_XV48LE] = { 1, 1 },
264 [AV_PIX_FMT_XV48BE] = { 1, 1 },
265 [AV_PIX_FMT_AYUV] = { 1, 1 },
266 [AV_PIX_FMT_UYVA] = { 1, 1 },
267 [AV_PIX_FMT_VYU444] = { 1, 1 },
268 [AV_PIX_FMT_V30XLE] = { 1, 1 },
269 };
270
271 1886241 int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
272 {
273 1886241 return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
274
2/2
✓ Branch 0 taken 1879682 times.
✓ Branch 1 taken 6559 times.
1886241 format_entries[pix_fmt].is_supported_in : 0;
275 }
276
277 1886241 int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
278 {
279 1886241 return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
280
2/2
✓ Branch 0 taken 1879682 times.
✓ Branch 1 taken 6559 times.
1886241 format_entries[pix_fmt].is_supported_out : 0;
281 }
282
283 30934 int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
284 {
285 30934 return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
286
1/2
✓ Branch 0 taken 30934 times.
✗ Branch 1 not taken.
30934 format_entries[pix_fmt].is_supported_endianness : 0;
287 }
288
289 /**
290 * This function also sanitizes and strips the input data, removing irrelevant
291 * fields for certain formats.
292 */
293 421936 SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field)
294 {
295 421936 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
296 const AVColorPrimariesDesc *primaries;
297 AVFrameSideData *sd;
298
299 421936 SwsFormat fmt = {
300 421936 .width = frame->width,
301 421936 .height = frame->height,
302 421936 .format = frame->format,
303 421936 .range = frame->color_range,
304 421936 .csp = frame->colorspace,
305 421936 .loc = frame->chroma_location,
306 .desc = desc,
307 .color = {
308 421936 .prim = frame->color_primaries,
309 421936 .trc = frame->color_trc,
310 },
311 };
312
313 av_assert1(fmt.width > 0);
314 av_assert1(fmt.height > 0);
315 av_assert1(fmt.format != AV_PIX_FMT_NONE);
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 421936 times.
421936 av_assert0(desc);
317
2/2
✓ Branch 0 taken 124370 times.
✓ Branch 1 taken 297566 times.
421936 if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER)) {
318 /* RGB-like family */
319 124370 fmt.csp = AVCOL_SPC_RGB;
320 124370 fmt.range = AVCOL_RANGE_JPEG;
321
2/2
✓ Branch 0 taken 1298 times.
✓ Branch 1 taken 296268 times.
297566 } else if (desc->flags & AV_PIX_FMT_FLAG_XYZ) {
322 1298 fmt.csp = AVCOL_SPC_UNSPECIFIED;
323 1298 fmt.color = (SwsColor) {
324 .prim = AVCOL_PRI_BT709, /* swscale currently hard-codes this XYZ matrix */
325 .trc = AVCOL_TRC_SMPTE428,
326 };
327
2/2
✓ Branch 0 taken 15764 times.
✓ Branch 1 taken 280504 times.
296268 } else if (desc->nb_components < 3) {
328 /* Grayscale formats */
329 15764 fmt.color.prim = AVCOL_PRI_UNSPECIFIED;
330 15764 fmt.csp = AVCOL_SPC_UNSPECIFIED;
331
2/2
✓ Branch 0 taken 374 times.
✓ Branch 1 taken 15390 times.
15764 if (desc->flags & AV_PIX_FMT_FLAG_FLOAT)
332 374 fmt.range = AVCOL_RANGE_UNSPECIFIED;
333 else
334 15390 fmt.range = AVCOL_RANGE_JPEG; // FIXME: this restriction should be lifted
335 }
336
337
2/2
✓ Branch 0 taken 11180 times.
✓ Branch 1 taken 410756 times.
421936 switch (frame->format) {
338 11180 case AV_PIX_FMT_YUVJ420P:
339 case AV_PIX_FMT_YUVJ411P:
340 case AV_PIX_FMT_YUVJ422P:
341 case AV_PIX_FMT_YUVJ444P:
342 case AV_PIX_FMT_YUVJ440P:
343 11180 fmt.range = AVCOL_RANGE_JPEG;
344 11180 break;
345 }
346
347
4/4
✓ Branch 0 taken 255534 times.
✓ Branch 1 taken 166402 times.
✓ Branch 2 taken 247902 times.
✓ Branch 3 taken 7632 times.
421936 if (!desc->log2_chroma_w && !desc->log2_chroma_h)
348 247902 fmt.loc = AVCHROMA_LOC_UNSPECIFIED;
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 421936 times.
421936 if (frame->flags & AV_FRAME_FLAG_INTERLACED) {
351 fmt.height = (fmt.height + (field == FIELD_TOP)) >> 1;
352 fmt.interlaced = 1;
353 }
354
355 /* Set luminance and gamut information */
356 421936 fmt.color.min_luma = av_make_q(0, 1);
357
3/3
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 421862 times.
421936 switch (fmt.color.trc) {
358 16 case AVCOL_TRC_SMPTE2084:
359 16 fmt.color.max_luma = av_make_q(10000, 1); break;
360 58 case AVCOL_TRC_ARIB_STD_B67:
361 58 fmt.color.max_luma = av_make_q( 1000, 1); break; /* HLG reference display */
362 421862 default:
363 421862 fmt.color.max_luma = av_make_q( 203, 1); break; /* SDR reference brightness */
364 }
365
366 421936 primaries = av_csp_primaries_desc_from_id(fmt.color.prim);
367
2/2
✓ Branch 0 taken 2054 times.
✓ Branch 1 taken 419882 times.
421936 if (primaries)
368 2054 fmt.color.gamut = primaries->prim;
369
370
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 421932 times.
421936 if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA))) {
371 4 const AVMasteringDisplayMetadata *mdm = (const AVMasteringDisplayMetadata *) sd->data;
372
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (mdm->has_luminance) {
373 4 fmt.color.min_luma = mdm->min_luminance;
374 4 fmt.color.max_luma = mdm->max_luminance;
375 }
376
377
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (mdm->has_primaries) {
378 /* Ignore mastering display white point as it has no bearance on
379 * the underlying content */
380 4 fmt.color.gamut.r.x = mdm->display_primaries[0][0];
381 4 fmt.color.gamut.r.y = mdm->display_primaries[0][1];
382 4 fmt.color.gamut.g.x = mdm->display_primaries[1][0];
383 4 fmt.color.gamut.g.y = mdm->display_primaries[1][1];
384 4 fmt.color.gamut.b.x = mdm->display_primaries[2][0];
385 4 fmt.color.gamut.b.y = mdm->display_primaries[2][1];
386 }
387 }
388
389
2/2
✓ Branch 1 taken 421932 times.
✓ Branch 2 taken 4 times.
421936 if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS))) {
390 4 const AVDynamicHDRPlus *dhp = (const AVDynamicHDRPlus *) sd->data;
391 4 const AVHDRPlusColorTransformParams *pars = &dhp->params[0];
392 4 const AVRational nits = av_make_q(10000, 1);
393 4 AVRational maxrgb = pars->maxscl[0];
394
395
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (!dhp->num_windows || dhp->application_version > 1)
396 goto skip_hdr10;
397
398 /* Maximum of MaxSCL components */
399
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (av_cmp_q(pars->maxscl[1], maxrgb) > 0)
400 maxrgb = pars->maxscl[1];
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (av_cmp_q(pars->maxscl[2], maxrgb) > 0)
402 maxrgb = pars->maxscl[2];
403
404
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (maxrgb.num > 0) {
405 /* Estimate true luminance from MaxSCL */
406 4 const AVLumaCoefficients *luma = av_csp_luma_coeffs_from_avcsp(fmt.csp);
407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!luma)
408 goto skip_hdr10;
409 4 fmt.color.frame_peak = av_add_q(av_mul_q(luma->cr, pars->maxscl[0]),
410 av_add_q(av_mul_q(luma->cg, pars->maxscl[1]),
411 av_mul_q(luma->cb, pars->maxscl[2])));
412 /* Scale the scene average brightness by the ratio between the
413 * maximum luminance and the MaxRGB values */
414 4 fmt.color.frame_avg = av_mul_q(pars->average_maxrgb,
415 av_div_q(fmt.color.frame_peak, maxrgb));
416 } else {
417 /**
418 * Calculate largest value from histogram to use as fallback for
419 * clips with missing MaxSCL information. Note that this may end
420 * up picking the "reserved" value at the 5% percentile, which in
421 * practice appears to track the brightest pixel in the scene.
422 */
423 for (int i = 0; i < pars->num_distribution_maxrgb_percentiles; i++) {
424 const AVRational pct = pars->distribution_maxrgb[i].percentile;
425 if (av_cmp_q(pct, maxrgb) > 0)
426 maxrgb = pct;
427 fmt.color.frame_peak = maxrgb;
428 fmt.color.frame_avg = pars->average_maxrgb;
429 }
430 }
431
432 /* Rescale to nits */
433 4 fmt.color.frame_peak = av_mul_q(nits, fmt.color.frame_peak);
434 4 fmt.color.frame_avg = av_mul_q(nits, fmt.color.frame_avg);
435 }
436 421932 skip_hdr10:
437
438 /* PQ is always scaled down to absolute zero, so ignore mastering metadata */
439
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 421920 times.
421936 if (fmt.color.trc == AVCOL_TRC_SMPTE2084)
440 16 fmt.color.min_luma = av_make_q(0, 1);
441
442 421936 return fmt;
443 }
444
445 12548 static int infer_prim_ref(SwsColor *csp, const SwsColor *ref)
446 {
447
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 12404 times.
12548 if (csp->prim != AVCOL_PRI_UNSPECIFIED)
448 144 return 0;
449
450 /* Re-use the reference gamut only for "safe", similar primaries */
451
2/2
✓ Branch 0 taken 6226 times.
✓ Branch 1 taken 6178 times.
12404 switch (ref->prim) {
452 6226 case AVCOL_PRI_BT709:
453 case AVCOL_PRI_BT470M:
454 case AVCOL_PRI_BT470BG:
455 case AVCOL_PRI_SMPTE170M:
456 case AVCOL_PRI_SMPTE240M:
457 6226 csp->prim = ref->prim;
458 6226 csp->gamut = ref->gamut;
459 6226 break;
460 6178 default:
461 6178 csp->prim = AVCOL_PRI_BT709;
462 6178 csp->gamut = av_csp_primaries_desc_from_id(csp->prim)->prim;
463 6178 break;
464 }
465
466 12404 return 1;
467 }
468
469 12548 static int infer_trc_ref(SwsColor *csp, const SwsColor *ref)
470 {
471
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 12254 times.
12548 if (csp->trc != AVCOL_TRC_UNSPECIFIED)
472 294 return 0;
473
474 /* Pick a suitable SDR transfer function, to try and minimize conversions */
475
2/2
✓ Branch 0 taken 6103 times.
✓ Branch 1 taken 6151 times.
12254 switch (ref->trc) {
476 6103 case AVCOL_TRC_UNSPECIFIED:
477 /* HDR curves, never default to these */
478 case AVCOL_TRC_SMPTE2084:
479 case AVCOL_TRC_ARIB_STD_B67:
480 6103 csp->trc = AVCOL_TRC_BT709;
481 6103 csp->min_luma = av_make_q(0, 1);
482 6103 csp->max_luma = av_make_q(203, 1);
483 6103 break;
484 6151 default:
485 6151 csp->trc = ref->trc;
486 6151 csp->min_luma = ref->min_luma;
487 6151 csp->max_luma = ref->max_luma;
488 6151 break;
489 }
490
491 12254 return 1;
492 }
493
494 6274 bool ff_infer_colors(SwsColor *src, SwsColor *dst)
495 {
496 6274 int incomplete = 0;
497
498 6274 incomplete |= infer_prim_ref(dst, src);
499 6274 incomplete |= infer_prim_ref(src, dst);
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6274 times.
6274 av_assert0(src->prim != AVCOL_PRI_UNSPECIFIED);
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6274 times.
6274 av_assert0(dst->prim != AVCOL_PRI_UNSPECIFIED);
502
503 6274 incomplete |= infer_trc_ref(dst, src);
504 6274 incomplete |= infer_trc_ref(src, dst);
505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6274 times.
6274 av_assert0(src->trc != AVCOL_TRC_UNSPECIFIED);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6274 times.
6274 av_assert0(dst->trc != AVCOL_TRC_UNSPECIFIED);
507
508 6274 return incomplete;
509 }
510
511 3708124 int sws_test_format(enum AVPixelFormat format, int output)
512 {
513
2/2
✓ Branch 0 taken 1854062 times.
✓ Branch 1 taken 1854062 times.
3708124 return output ? sws_isSupportedOutput(format) : sws_isSupportedInput(format);
514 }
515
516 440165 int sws_test_colorspace(enum AVColorSpace csp, int output)
517 {
518
2/2
✓ Branch 0 taken 322139 times.
✓ Branch 1 taken 118026 times.
440165 switch (csp) {
519 322139 case AVCOL_SPC_UNSPECIFIED:
520 case AVCOL_SPC_RGB:
521 case AVCOL_SPC_BT709:
522 case AVCOL_SPC_BT470BG:
523 case AVCOL_SPC_SMPTE170M:
524 case AVCOL_SPC_FCC:
525 case AVCOL_SPC_SMPTE240M:
526 case AVCOL_SPC_BT2020_NCL:
527 322139 return 1;
528 118026 default:
529 118026 return 0;
530 }
531 }
532
533 206152 int sws_test_primaries(enum AVColorPrimaries prim, int output)
534 {
535
3/6
✓ Branch 0 taken 206152 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 206152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 206152 times.
✗ Branch 5 not taken.
206152 return prim > AVCOL_PRI_RESERVED0 && prim < AVCOL_PRI_NB &&
536 prim != AVCOL_PRI_RESERVED;
537 }
538
539 206152 int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output)
540 {
541 103076 av_csp_eotf_function eotf = output ? av_csp_itu_eotf_inv(trc)
542
2/2
✓ Branch 0 taken 103076 times.
✓ Branch 1 taken 103076 times.
206152 : av_csp_itu_eotf(trc);
543
3/4
✓ Branch 0 taken 1219 times.
✓ Branch 1 taken 204933 times.
✓ Branch 2 taken 1219 times.
✗ Branch 3 not taken.
206152 return trc == AVCOL_TRC_UNSPECIFIED || eotf != NULL;
544 }
545
546 206152 static int test_range(enum AVColorRange range)
547 {
548 206152 return (unsigned)range < AVCOL_RANGE_NB;
549 }
550
551 206152 static int test_loc(enum AVChromaLocation loc)
552 {
553 206152 return (unsigned)loc < AVCHROMA_LOC_NB;
554 }
555
556 206152 int ff_test_fmt(const SwsFormat *fmt, int output)
557 {
558
2/4
✓ Branch 0 taken 206152 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 206152 times.
✗ Branch 3 not taken.
412304 return fmt->width > 0 && fmt->height > 0 &&
559
1/2
✓ Branch 1 taken 206152 times.
✗ Branch 2 not taken.
412304 sws_test_format (fmt->format, output) &&
560
1/2
✓ Branch 1 taken 206152 times.
✗ Branch 2 not taken.
412304 sws_test_colorspace(fmt->csp, output) &&
561
1/2
✓ Branch 1 taken 206152 times.
✗ Branch 2 not taken.
412304 sws_test_primaries (fmt->color.prim, output) &&
562
1/2
✓ Branch 1 taken 206152 times.
✗ Branch 2 not taken.
412304 sws_test_transfer (fmt->color.trc, output) &&
563
2/4
✓ Branch 0 taken 206152 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 206152 times.
✗ Branch 4 not taken.
618456 test_range (fmt->range) &&
564 206152 test_loc (fmt->loc);
565 }
566
567 int sws_test_frame(const AVFrame *frame, int output)
568 {
569 for (int field = 0; field < 2; field++) {
570 const SwsFormat fmt = ff_fmt_from_frame(frame, field);
571 if (!ff_test_fmt(&fmt, output))
572 return 0;
573 if (!fmt.interlaced)
574 break;
575 }
576
577 return 1;
578 }
579
580 107892 int sws_is_noop(const AVFrame *dst, const AVFrame *src)
581 {
582
1/2
✓ Branch 0 taken 107892 times.
✗ Branch 1 not taken.
107892 for (int field = 0; field < 2; field++) {
583 107892 SwsFormat dst_fmt = ff_fmt_from_frame(dst, field);
584 107892 SwsFormat src_fmt = ff_fmt_from_frame(src, field);
585
2/2
✓ Branch 1 taken 103076 times.
✓ Branch 2 taken 4816 times.
107892 if (!ff_fmt_equal(&dst_fmt, &src_fmt))
586 103076 return 0;
587
1/2
✓ Branch 0 taken 4816 times.
✗ Branch 1 not taken.
4816 if (!dst_fmt.interlaced)
588 4816 break;
589 }
590
591 4816 return 1;
592 }
593