FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/swscale_internal.h
Date: 2024-11-21 09:21:34
Exec Total Coverage
Lines: 168 174 96.6%
Functions: 26 27 96.3%
Branches: 179 208 86.1%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
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_SWSCALE_INTERNAL_H
22 #define SWSCALE_SWSCALE_INTERNAL_H
23
24 #include <stdatomic.h>
25
26 #include "config.h"
27 #include "swscale.h"
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/common.h"
31 #include "libavutil/frame.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/log.h"
34 #include "libavutil/mem_internal.h"
35 #include "libavutil/pixfmt.h"
36 #include "libavutil/pixdesc.h"
37 #include "libavutil/slicethread.h"
38 #if HAVE_ALTIVEC
39 #include "libavutil/ppc/util_altivec.h"
40 #endif
41 #include "libavutil/half2float.h"
42
43 #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long
44
45 #define YUVRGB_TABLE_HEADROOM 512
46 #define YUVRGB_TABLE_LUMA_HEADROOM 512
47
48 #define MAX_FILTER_SIZE SWS_MAX_FILTER_SIZE
49
50 #if HAVE_BIGENDIAN
51 #define ALT32_CORR (-1)
52 #else
53 #define ALT32_CORR 1
54 #endif
55
56 #if ARCH_X86_64
57 # define APCK_PTR2 8
58 # define APCK_COEF 16
59 # define APCK_SIZE 24
60 #else
61 # define APCK_PTR2 4
62 # define APCK_COEF 8
63 # define APCK_SIZE 16
64 #endif
65
66 #define RETCODE_USE_CASCADE -12345
67
68 typedef struct SwsInternal SwsInternal;
69
70 1755445 static inline SwsInternal *sws_internal(const SwsContext *sws)
71 {
72 1755445 return (SwsInternal *) sws;
73 }
74
75 typedef enum SwsDither {
76 SWS_DITHER_NONE = 0,
77 SWS_DITHER_AUTO,
78 SWS_DITHER_BAYER,
79 SWS_DITHER_ED,
80 SWS_DITHER_A_DITHER,
81 SWS_DITHER_X_DITHER,
82 SWS_DITHER_NB,
83 } SwsDither;
84
85 typedef enum SwsAlphaBlend {
86 SWS_ALPHA_BLEND_NONE = 0,
87 SWS_ALPHA_BLEND_UNIFORM,
88 SWS_ALPHA_BLEND_CHECKERBOARD,
89 SWS_ALPHA_BLEND_NB,
90 } SwsAlphaBlend;
91
92 typedef struct Range {
93 unsigned int start;
94 unsigned int len;
95 } Range;
96
97 typedef struct RangeList {
98 Range *ranges;
99 unsigned int nb_ranges;
100 int ranges_allocated;
101 } RangeList;
102
103 int ff_range_add(RangeList *r, unsigned int start, unsigned int len);
104
105 typedef int (*SwsFunc)(SwsInternal *c, const uint8_t *const src[],
106 const int srcStride[], int srcSliceY, int srcSliceH,
107 uint8_t *const dst[], const int dstStride[]);
108
109 /**
110 * Write one line of horizontally scaled data to planar output
111 * without any additional vertical scaling (or point-scaling).
112 *
113 * @param src scaled source data, 15 bits for 8-10-bit output,
114 * 19 bits for 16-bit output (in int32_t)
115 * @param dest pointer to the output plane. For >8-bit
116 * output, this is in uint16_t
117 * @param dstW width of destination in pixels
118 * @param dither ordered dither array of type int16_t and size 8
119 * @param offset Dither offset
120 */
121 typedef void (*yuv2planar1_fn)(const int16_t *src, uint8_t *dest, int dstW,
122 const uint8_t *dither, int offset);
123
124 /**
125 * Write one line of horizontally scaled data to planar output
126 * with multi-point vertical scaling between input pixels.
127 *
128 * @param filter vertical luma/alpha scaling coefficients, 12 bits [0,4096]
129 * @param src scaled luma (Y) or alpha (A) source data, 15 bits for
130 * 8-10-bit output, 19 bits for 16-bit output (in int32_t)
131 * @param filterSize number of vertical input lines to scale
132 * @param dest pointer to output plane. For >8-bit
133 * output, this is in uint16_t
134 * @param dstW width of destination pixels
135 * @param offset Dither offset
136 */
137 typedef void (*yuv2planarX_fn)(const int16_t *filter, int filterSize,
138 const int16_t **src, uint8_t *dest, int dstW,
139 const uint8_t *dither, int offset);
140
141 /**
142 * Write one line of horizontally scaled chroma to interleaved output
143 * with multi-point vertical scaling between input pixels.
144 *
145 * @param dstFormat destination pixel format
146 * @param chrDither ordered dither array of type uint8_t and size 8
147 * @param chrFilter vertical chroma scaling coefficients, 12 bits [0,4096]
148 * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit
149 * output, 19 bits for 16-bit output (in int32_t)
150 * @param chrVSrc scaled chroma (V) source data, 15 bits for 8-10-bit
151 * output, 19 bits for 16-bit output (in int32_t)
152 * @param chrFilterSize number of vertical chroma input lines to scale
153 * @param dest pointer to the output plane. For >8-bit
154 * output, this is in uint16_t
155 * @param dstW width of chroma planes
156 */
157 typedef void (*yuv2interleavedX_fn)(enum AVPixelFormat dstFormat,
158 const uint8_t *chrDither,
159 const int16_t *chrFilter,
160 int chrFilterSize,
161 const int16_t **chrUSrc,
162 const int16_t **chrVSrc,
163 uint8_t *dest, int dstW);
164
165 /**
166 * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
167 * output without any additional vertical scaling (or point-scaling). Note
168 * that this function may do chroma scaling, see the "uvalpha" argument.
169 *
170 * @param c SWS scaling context
171 * @param lumSrc scaled luma (Y) source data, 15 bits for 8-10-bit output,
172 * 19 bits for 16-bit output (in int32_t)
173 * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit output,
174 * 19 bits for 16-bit output (in int32_t)
175 * @param chrVSrc scaled chroma (V) source data, 15 bits for 8-10-bit output,
176 * 19 bits for 16-bit output (in int32_t)
177 * @param alpSrc scaled alpha (A) source data, 15 bits for 8-10-bit output,
178 * 19 bits for 16-bit output (in int32_t)
179 * @param dest pointer to the output plane. For 16-bit output, this is
180 * uint16_t
181 * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
182 * to write into dest[]
183 * @param uvalpha chroma scaling coefficient for the second line of chroma
184 * pixels, either 2048 or 0. If 0, one chroma input is used
185 * for 2 output pixels (or if the SWS_FLAG_FULL_CHR_INT flag
186 * is set, it generates 1 output pixel). If 2048, two chroma
187 * input pixels should be averaged for 2 output pixels (this
188 * only happens if SWS_FLAG_FULL_CHR_INT is not set)
189 * @param y vertical line number for this output. This does not need
190 * to be used to calculate the offset in the destination,
191 * but can be used to generate comfort noise using dithering
192 * for some output formats.
193 */
194 typedef void (*yuv2packed1_fn)(SwsInternal *c, const int16_t *lumSrc,
195 const int16_t *chrUSrc[2],
196 const int16_t *chrVSrc[2],
197 const int16_t *alpSrc, uint8_t *dest,
198 int dstW, int uvalpha, int y);
199 /**
200 * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
201 * output by doing bilinear scaling between two input lines.
202 *
203 * @param c SWS scaling context
204 * @param lumSrc scaled luma (Y) source data, 15 bits for 8-10-bit output,
205 * 19 bits for 16-bit output (in int32_t)
206 * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit output,
207 * 19 bits for 16-bit output (in int32_t)
208 * @param chrVSrc scaled chroma (V) source data, 15 bits for 8-10-bit output,
209 * 19 bits for 16-bit output (in int32_t)
210 * @param alpSrc scaled alpha (A) source data, 15 bits for 8-10-bit output,
211 * 19 bits for 16-bit output (in int32_t)
212 * @param dest pointer to the output plane. For 16-bit output, this is
213 * uint16_t
214 * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
215 * to write into dest[]
216 * @param yalpha luma/alpha scaling coefficients for the second input line.
217 * The first line's coefficients can be calculated by using
218 * 4096 - yalpha
219 * @param uvalpha chroma scaling coefficient for the second input line. The
220 * first line's coefficients can be calculated by using
221 * 4096 - uvalpha
222 * @param y vertical line number for this output. This does not need
223 * to be used to calculate the offset in the destination,
224 * but can be used to generate comfort noise using dithering
225 * for some output formats.
226 */
227 typedef void (*yuv2packed2_fn)(SwsInternal *c, const int16_t *lumSrc[2],
228 const int16_t *chrUSrc[2],
229 const int16_t *chrVSrc[2],
230 const int16_t *alpSrc[2],
231 uint8_t *dest,
232 int dstW, int yalpha, int uvalpha, int y);
233 /**
234 * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
235 * output by doing multi-point vertical scaling between input pixels.
236 *
237 * @param c SWS scaling context
238 * @param lumFilter vertical luma/alpha scaling coefficients, 12 bits [0,4096]
239 * @param lumSrc scaled luma (Y) source data, 15 bits for 8-10-bit output,
240 * 19 bits for 16-bit output (in int32_t)
241 * @param lumFilterSize number of vertical luma/alpha input lines to scale
242 * @param chrFilter vertical chroma scaling coefficients, 12 bits [0,4096]
243 * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit output,
244 * 19 bits for 16-bit output (in int32_t)
245 * @param chrVSrc scaled chroma (V) source data, 15 bits for 8-10-bit output,
246 * 19 bits for 16-bit output (in int32_t)
247 * @param chrFilterSize number of vertical chroma input lines to scale
248 * @param alpSrc scaled alpha (A) source data, 15 bits for 8-10-bit output,
249 * 19 bits for 16-bit output (in int32_t)
250 * @param dest pointer to the output plane. For 16-bit output, this is
251 * uint16_t
252 * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
253 * to write into dest[]
254 * @param y vertical line number for this output. This does not need
255 * to be used to calculate the offset in the destination,
256 * but can be used to generate comfort noise using dithering
257 * or some output formats.
258 */
259 typedef void (*yuv2packedX_fn)(SwsInternal *c, const int16_t *lumFilter,
260 const int16_t **lumSrc, int lumFilterSize,
261 const int16_t *chrFilter,
262 const int16_t **chrUSrc,
263 const int16_t **chrVSrc, int chrFilterSize,
264 const int16_t **alpSrc, uint8_t *dest,
265 int dstW, int y);
266
267 /**
268 * Write one line of horizontally scaled Y/U/V/A to YUV/RGB
269 * output by doing multi-point vertical scaling between input pixels.
270 *
271 * @param c SWS scaling context
272 * @param lumFilter vertical luma/alpha scaling coefficients, 12 bits [0,4096]
273 * @param lumSrc scaled luma (Y) source data, 15 bits for 8-10-bit output,
274 * 19 bits for 16-bit output (in int32_t)
275 * @param lumFilterSize number of vertical luma/alpha input lines to scale
276 * @param chrFilter vertical chroma scaling coefficients, 12 bits [0,4096]
277 * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit output,
278 * 19 bits for 16-bit output (in int32_t)
279 * @param chrVSrc scaled chroma (V) source data, 15 bits for 8-10-bit output,
280 * 19 bits for 16-bit output (in int32_t)
281 * @param chrFilterSize number of vertical chroma input lines to scale
282 * @param alpSrc scaled alpha (A) source data, 15 bits for 8-10-bit output,
283 * 19 bits for 16-bit output (in int32_t)
284 * @param dest pointer to the output planes. For 16-bit output, this is
285 * uint16_t
286 * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
287 * to write into dest[]
288 * @param y vertical line number for this output. This does not need
289 * to be used to calculate the offset in the destination,
290 * but can be used to generate comfort noise using dithering
291 * or some output formats.
292 */
293 typedef void (*yuv2anyX_fn)(SwsInternal *c, const int16_t *lumFilter,
294 const int16_t **lumSrc, int lumFilterSize,
295 const int16_t *chrFilter,
296 const int16_t **chrUSrc,
297 const int16_t **chrVSrc, int chrFilterSize,
298 const int16_t **alpSrc, uint8_t **dest,
299 int dstW, int y);
300
301 /**
302 * Unscaled conversion of luma/alpha plane to YV12 for horizontal scaler.
303 */
304 typedef void (*planar1_YV12_fn)(uint8_t *dst, const uint8_t *src, const uint8_t *src2,
305 const uint8_t *src3, int width, uint32_t *pal,
306 void *opaque);
307
308 /**
309 * Unscaled conversion of chroma plane to YV12 for horizontal scaler.
310 */
311 typedef void (*planar2_YV12_fn)(uint8_t *dst, uint8_t *dst2, const uint8_t *src,
312 const uint8_t *src2, const uint8_t *src3,
313 int width, uint32_t *pal, void *opaque);
314
315 /**
316 * Unscaled conversion of arbitrary planar data (e.g. RGBA) to YV12, through
317 * conversion using the given color matrix.
318 */
319 typedef void (*planarX_YV12_fn)(uint8_t *dst, const uint8_t *src[4], int width,
320 int32_t *rgb2yuv, void *opaque);
321
322 typedef void (*planarX2_YV12_fn)(uint8_t *dst, uint8_t *dst2,
323 const uint8_t *src[4], int width,
324 int32_t *rgb2yuv, void *opaque);
325
326 struct SwsSlice;
327 struct SwsFilterDescriptor;
328
329 /* This struct should be aligned on at least a 32-byte boundary. */
330 struct SwsInternal {
331 /**
332 * info on struct for av_log
333 */
334 const AVClass *av_class;
335
336 SwsContext *parent;
337
338 AVSliceThread *slicethread;
339 SwsContext **slice_ctx;
340 int *slice_err;
341 int nb_slice_ctx;
342
343 // values passed to current sws_receive_slice() call
344 int dst_slice_start;
345 int dst_slice_height;
346
347 /**
348 * Note that src, dst, srcStride, dstStride will be copied in the
349 * sws_scale() wrapper so they can be freely modified here.
350 */
351 SwsFunc convert_unscaled;
352 int srcW; ///< Width of source luma/alpha planes.
353 int srcH; ///< Height of source luma/alpha planes.
354 int dstW; ///< Width of destination luma/alpha planes.
355 int dstH; ///< Height of destination luma/alpha planes.
356 int chrSrcW; ///< Width of source chroma planes.
357 int chrSrcH; ///< Height of source chroma planes.
358 int chrDstW; ///< Width of destination chroma planes.
359 int chrDstH; ///< Height of destination chroma planes.
360 int lumXInc, chrXInc;
361 int lumYInc, chrYInc;
362 enum AVPixelFormat dstFormat; ///< Destination pixel format.
363 enum AVPixelFormat srcFormat; ///< Source pixel format.
364 int dstFormatBpp; ///< Number of bits per pixel of the destination pixel format.
365 int srcFormatBpp; ///< Number of bits per pixel of the source pixel format.
366 int dstBpc, srcBpc;
367 int chrSrcHSubSample; ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in source image.
368 int chrSrcVSubSample; ///< Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in source image.
369 int chrDstHSubSample; ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in destination image.
370 int chrDstVSubSample; ///< Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in destination image.
371 int vChrDrop; ///< Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user.
372 int sliceDir; ///< Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).
373 int nb_threads; ///< Number of threads used for scaling
374 double param[2]; ///< Input parameters for scaling algorithms that need them.
375
376 AVFrame *frame_src;
377 AVFrame *frame_dst;
378
379 RangeList src_ranges;
380
381 /* The cascaded_* fields allow spliting a scaler task into multiple
382 * sequential steps, this is for example used to limit the maximum
383 * downscaling factor that needs to be supported in one scaler.
384 */
385 SwsContext *cascaded_context[3];
386 int cascaded_tmpStride[2][4];
387 uint8_t *cascaded_tmp[2][4];
388 int cascaded_mainindex;
389
390 double gamma_value;
391 int gamma_flag;
392 int is_internal_gamma;
393 uint16_t *gamma;
394 uint16_t *inv_gamma;
395
396 int numDesc;
397 int descIndex[2];
398 int numSlice;
399 struct SwsSlice *slice;
400 struct SwsFilterDescriptor *desc;
401
402 uint32_t pal_yuv[256];
403 uint32_t pal_rgb[256];
404
405 float uint2float_lut[256];
406
407 /**
408 * @name Scaled horizontal lines ring buffer.
409 * The horizontal scaler keeps just enough scaled lines in a ring buffer
410 * so they may be passed to the vertical scaler. The pointers to the
411 * allocated buffers for each line are duplicated in sequence in the ring
412 * buffer to simplify indexing and avoid wrapping around between lines
413 * inside the vertical scaler code. The wrapping is done before the
414 * vertical scaler is called.
415 */
416 //@{
417 int lastInLumBuf; ///< Last scaled horizontal luma/alpha line from source in the ring buffer.
418 int lastInChrBuf; ///< Last scaled horizontal chroma line from source in the ring buffer.
419 //@}
420
421 uint8_t *formatConvBuffer;
422 int needAlpha;
423
424 /**
425 * @name Horizontal and vertical filters.
426 * To better understand the following fields, here is a pseudo-code of
427 * their usage in filtering a horizontal line:
428 * @code
429 * for (i = 0; i < width; i++) {
430 * dst[i] = 0;
431 * for (j = 0; j < filterSize; j++)
432 * dst[i] += src[ filterPos[i] + j ] * filter[ filterSize * i + j ];
433 * dst[i] >>= FRAC_BITS; // The actual implementation is fixed-point.
434 * }
435 * @endcode
436 */
437 //@{
438 int16_t *hLumFilter; ///< Array of horizontal filter coefficients for luma/alpha planes.
439 int16_t *hChrFilter; ///< Array of horizontal filter coefficients for chroma planes.
440 int16_t *vLumFilter; ///< Array of vertical filter coefficients for luma/alpha planes.
441 int16_t *vChrFilter; ///< Array of vertical filter coefficients for chroma planes.
442 int32_t *hLumFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for luma/alpha planes.
443 int32_t *hChrFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for chroma planes.
444 int32_t *vLumFilterPos; ///< Array of vertical filter starting positions for each dst[i] for luma/alpha planes.
445 int32_t *vChrFilterPos; ///< Array of vertical filter starting positions for each dst[i] for chroma planes.
446 int hLumFilterSize; ///< Horizontal filter size for luma/alpha pixels.
447 int hChrFilterSize; ///< Horizontal filter size for chroma pixels.
448 int vLumFilterSize; ///< Vertical filter size for luma/alpha pixels.
449 int vChrFilterSize; ///< Vertical filter size for chroma pixels.
450 //@}
451
452 int lumMmxextFilterCodeSize; ///< Runtime-generated MMXEXT horizontal fast bilinear scaler code size for luma/alpha planes.
453 int chrMmxextFilterCodeSize; ///< Runtime-generated MMXEXT horizontal fast bilinear scaler code size for chroma planes.
454 uint8_t *lumMmxextFilterCode; ///< Runtime-generated MMXEXT horizontal fast bilinear scaler code for luma/alpha planes.
455 uint8_t *chrMmxextFilterCode; ///< Runtime-generated MMXEXT horizontal fast bilinear scaler code for chroma planes.
456
457 int canMMXEXTBeUsed;
458 int warned_unuseable_bilinear;
459
460 int dstY; ///< Last destination vertical line output from last slice.
461 int flags; ///< Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
462 void *yuvTable; // pointer to the yuv->rgb table start so it can be freed()
463 // alignment ensures the offset can be added in a single
464 // instruction on e.g. ARM
465 DECLARE_ALIGNED(16, int, table_gV)[256 + 2*YUVRGB_TABLE_HEADROOM];
466 uint8_t *table_rV[256 + 2*YUVRGB_TABLE_HEADROOM];
467 uint8_t *table_gU[256 + 2*YUVRGB_TABLE_HEADROOM];
468 uint8_t *table_bU[256 + 2*YUVRGB_TABLE_HEADROOM];
469 DECLARE_ALIGNED(16, int32_t, input_rgb2yuv_table)[16+40*4]; // This table can contain both C and SIMD formatted values, the C vales are always at the XY_IDX points
470 #define RY_IDX 0
471 #define GY_IDX 1
472 #define BY_IDX 2
473 #define RU_IDX 3
474 #define GU_IDX 4
475 #define BU_IDX 5
476 #define RV_IDX 6
477 #define GV_IDX 7
478 #define BV_IDX 8
479 #define RGB2YUV_SHIFT 15
480
481 int *dither_error[4];
482
483 //Colorspace stuff
484 int contrast, brightness, saturation; // for sws_getColorspaceDetails
485 int srcColorspaceTable[4];
486 int dstColorspaceTable[4];
487 int srcRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (source image).
488 int dstRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image).
489 int src0Alpha;
490 int dst0Alpha;
491 int srcXYZ;
492 int dstXYZ;
493 int src_h_chr_pos;
494 int dst_h_chr_pos;
495 int src_v_chr_pos;
496 int dst_v_chr_pos;
497 int yuv2rgb_y_offset;
498 int yuv2rgb_y_coeff;
499 int yuv2rgb_v2r_coeff;
500 int yuv2rgb_v2g_coeff;
501 int yuv2rgb_u2g_coeff;
502 int yuv2rgb_u2b_coeff;
503
504 #define RED_DITHER "0*8"
505 #define GREEN_DITHER "1*8"
506 #define BLUE_DITHER "2*8"
507 #define Y_COEFF "3*8"
508 #define VR_COEFF "4*8"
509 #define UB_COEFF "5*8"
510 #define VG_COEFF "6*8"
511 #define UG_COEFF "7*8"
512 #define Y_OFFSET "8*8"
513 #define U_OFFSET "9*8"
514 #define V_OFFSET "10*8"
515 #define LUM_MMX_FILTER_OFFSET "11*8"
516 #define CHR_MMX_FILTER_OFFSET "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)
517 #define DSTW_OFFSET "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2"
518 #define ESP_OFFSET "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+8"
519 #define VROUNDER_OFFSET "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+16"
520 #define U_TEMP "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+24"
521 #define V_TEMP "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+32"
522 #define Y_TEMP "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+40"
523 #define ALP_MMX_FILTER_OFFSET "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*2+48"
524 #define UV_OFF_PX "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*3+48"
525 #define UV_OFF_BYTE "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*3+56"
526 #define DITHER16 "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*3+64"
527 #define DITHER32 "11*8+4*4*"AV_STRINGIFY(MAX_FILTER_SIZE)"*3+80"
528 #define DITHER32_INT (11*8+4*4*MAX_FILTER_SIZE*3+80) // value equal to above, used for checking that the struct hasn't been changed by mistake
529
530 DECLARE_ALIGNED(8, uint64_t, redDither);
531 DECLARE_ALIGNED(8, uint64_t, greenDither);
532 DECLARE_ALIGNED(8, uint64_t, blueDither);
533
534 DECLARE_ALIGNED(8, uint64_t, yCoeff);
535 DECLARE_ALIGNED(8, uint64_t, vrCoeff);
536 DECLARE_ALIGNED(8, uint64_t, ubCoeff);
537 DECLARE_ALIGNED(8, uint64_t, vgCoeff);
538 DECLARE_ALIGNED(8, uint64_t, ugCoeff);
539 DECLARE_ALIGNED(8, uint64_t, yOffset);
540 DECLARE_ALIGNED(8, uint64_t, uOffset);
541 DECLARE_ALIGNED(8, uint64_t, vOffset);
542 int32_t lumMmxFilter[4 * MAX_FILTER_SIZE];
543 int32_t chrMmxFilter[4 * MAX_FILTER_SIZE];
544 int dstW_mmx;
545 DECLARE_ALIGNED(8, uint64_t, esp);
546 DECLARE_ALIGNED(8, uint64_t, vRounder);
547 DECLARE_ALIGNED(8, uint64_t, u_temp);
548 DECLARE_ALIGNED(8, uint64_t, v_temp);
549 DECLARE_ALIGNED(8, uint64_t, y_temp);
550 int32_t alpMmxFilter[4 * MAX_FILTER_SIZE];
551 // alignment of these values is not necessary, but merely here
552 // to maintain the same offset across x8632 and x86-64. Once we
553 // use proper offset macros in the asm, they can be removed.
554 DECLARE_ALIGNED(8, ptrdiff_t, uv_off); ///< offset (in pixels) between u and v planes
555 DECLARE_ALIGNED(8, ptrdiff_t, uv_offx2); ///< offset (in bytes) between u and v planes
556 DECLARE_ALIGNED(8, uint16_t, dither16)[8];
557 DECLARE_ALIGNED(8, uint32_t, dither32)[8];
558
559 const uint8_t *chrDither8, *lumDither8;
560
561 #if HAVE_ALTIVEC
562 vector signed short CY;
563 vector signed short CRV;
564 vector signed short CBU;
565 vector signed short CGU;
566 vector signed short CGV;
567 vector signed short OY;
568 vector unsigned short CSHIFT;
569 vector signed short *vYCoeffsBank, *vCCoeffsBank;
570 #endif
571
572 int use_mmx_vfilter;
573
574 /* pre defined color-spaces gamma */
575 #define XYZ_GAMMA (2.6f)
576 #define RGB_GAMMA (2.2f)
577 int16_t *xyzgamma;
578 int16_t *rgbgamma;
579 int16_t *xyzgammainv;
580 int16_t *rgbgammainv;
581 int16_t xyz2rgb_matrix[3][4];
582 int16_t rgb2xyz_matrix[3][4];
583
584 /* function pointers for swscale() */
585 yuv2planar1_fn yuv2plane1;
586 yuv2planarX_fn yuv2planeX;
587 yuv2interleavedX_fn yuv2nv12cX;
588 yuv2packed1_fn yuv2packed1;
589 yuv2packed2_fn yuv2packed2;
590 yuv2packedX_fn yuv2packedX;
591 yuv2anyX_fn yuv2anyX;
592
593 /// Opaque data pointer passed to all input functions.
594 void *input_opaque;
595
596 planar1_YV12_fn lumToYV12;
597 planar1_YV12_fn alpToYV12;
598 planar2_YV12_fn chrToYV12;
599
600 /**
601 * Functions to read planar input, such as planar RGB, and convert
602 * internally to Y/UV/A.
603 */
604 /** @{ */
605 planarX_YV12_fn readLumPlanar;
606 planarX_YV12_fn readAlpPlanar;
607 planarX2_YV12_fn readChrPlanar;
608 /** @} */
609
610 /**
611 * Scale one horizontal line of input data using a bilinear filter
612 * to produce one line of output data. Compared to SwsInternal->hScale(),
613 * please take note of the following caveats when using these:
614 * - Scaling is done using only 7 bits instead of 14-bit coefficients.
615 * - You can use no more than 5 input pixels to produce 4 output
616 * pixels. Therefore, this filter should not be used for downscaling
617 * by more than ~20% in width (because that equals more than 5/4th
618 * downscaling and thus more than 5 pixels input per 4 pixels output).
619 * - In general, bilinear filters create artifacts during downscaling
620 * (even when <20%), because one output pixel will span more than one
621 * input pixel, and thus some pixels will need edges of both neighbor
622 * pixels to interpolate the output pixel. Since you can use at most
623 * two input pixels per output pixel in bilinear scaling, this is
624 * impossible and thus downscaling by any size will create artifacts.
625 * To enable this type of scaling, set SWS_FLAG_FAST_BILINEAR
626 * in SwsInternal->flags.
627 */
628 /** @{ */
629 void (*hyscale_fast)(SwsInternal *c,
630 int16_t *dst, int dstWidth,
631 const uint8_t *src, int srcW, int xInc);
632 void (*hcscale_fast)(SwsInternal *c,
633 int16_t *dst1, int16_t *dst2, int dstWidth,
634 const uint8_t *src1, const uint8_t *src2,
635 int srcW, int xInc);
636 /** @} */
637
638 /**
639 * Scale one horizontal line of input data using a filter over the input
640 * lines, to produce one (differently sized) line of output data.
641 *
642 * @param dst pointer to destination buffer for horizontally scaled
643 * data. If the number of bits per component of one
644 * destination pixel (SwsInternal->dstBpc) is <= 10, data
645 * will be 15 bpc in 16 bits (int16_t) width. Else (i.e.
646 * SwsInternal->dstBpc == 16), data will be 19bpc in
647 * 32 bits (int32_t) width.
648 * @param dstW width of destination image
649 * @param src pointer to source data to be scaled. If the number of
650 * bits per component of a source pixel (SwsInternal->srcBpc)
651 * is 8, this is 8bpc in 8 bits (uint8_t) width. Else
652 * (i.e. SwsInternal->dstBpc > 8), this is native depth
653 * in 16 bits (uint16_t) width. In other words, for 9-bit
654 * YUV input, this is 9bpc, for 10-bit YUV input, this is
655 * 10bpc, and for 16-bit RGB or YUV, this is 16bpc.
656 * @param filter filter coefficients to be used per output pixel for
657 * scaling. This contains 14bpp filtering coefficients.
658 * Guaranteed to contain dstW * filterSize entries.
659 * @param filterPos position of the first input pixel to be used for
660 * each output pixel during scaling. Guaranteed to
661 * contain dstW entries.
662 * @param filterSize the number of input coefficients to be used (and
663 * thus the number of input pixels to be used) for
664 * creating a single output pixel. Is aligned to 4
665 * (and input coefficients thus padded with zeroes)
666 * to simplify creating SIMD code.
667 */
668 /** @{ */
669 void (*hyScale)(SwsInternal *c, int16_t *dst, int dstW,
670 const uint8_t *src, const int16_t *filter,
671 const int32_t *filterPos, int filterSize);
672 void (*hcScale)(SwsInternal *c, int16_t *dst, int dstW,
673 const uint8_t *src, const int16_t *filter,
674 const int32_t *filterPos, int filterSize);
675 /** @} */
676
677 /// Color range conversion function for luma plane if needed.
678 void (*lumConvertRange)(int16_t *dst, int width);
679 /// Color range conversion function for chroma planes if needed.
680 void (*chrConvertRange)(int16_t *dst1, int16_t *dst2, int width);
681
682 int needs_hcscale; ///< Set if there are chroma planes to be converted.
683
684 SwsDither dither;
685
686 SwsAlphaBlend alphablend;
687
688 // scratch buffer for converting packed rgb0 sources
689 // filled with a copy of the input frame + fully opaque alpha,
690 // then passed as input to further conversion
691 uint8_t *rgb0_scratch;
692 unsigned int rgb0_scratch_allocated;
693
694 // scratch buffer for converting XYZ sources
695 // filled with the input converted to rgb48
696 // then passed as input to further conversion
697 uint8_t *xyz_scratch;
698 unsigned int xyz_scratch_allocated;
699
700 unsigned int dst_slice_align;
701 atomic_int stride_unaligned_warned;
702 atomic_int data_unaligned_warned;
703
704 Half2FloatTables *h2f_tables;
705 };
706 //FIXME check init (where 0)
707
708 SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c);
709 int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
710 int fullRange, int brightness,
711 int contrast, int saturation);
712 void ff_yuv2rgb_init_tables_ppc(SwsInternal *c, const int inv_table[4],
713 int brightness, int contrast, int saturation);
714
715 void ff_updateMMXDitherTables(SwsInternal *c, int dstY);
716
717 void ff_update_palette(SwsInternal *c, const uint32_t *pal);
718
719 av_cold void ff_sws_init_range_convert(SwsInternal *c);
720 av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c);
721 av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c);
722 av_cold void ff_sws_init_range_convert_riscv(SwsInternal *c);
723 av_cold void ff_sws_init_range_convert_x86(SwsInternal *c);
724
725 SwsFunc ff_yuv2rgb_init_x86(SwsInternal *c);
726 SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c);
727 SwsFunc ff_yuv2rgb_init_loongarch(SwsInternal *c);
728
729 461096 static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
730 {
731 461096 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 461096 times.
461096 av_assert0(desc);
733 461096 return desc->comp[0].depth == 16;
734 }
735
736 5658 static av_always_inline int is32BPS(enum AVPixelFormat pix_fmt)
737 {
738 5658 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5658 times.
5658 av_assert0(desc);
740 5658 return desc->comp[0].depth == 32;
741 }
742
743 623297 static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
744 {
745 623297 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 623297 times.
623297 av_assert0(desc);
747
4/4
✓ Branch 0 taken 335497 times.
✓ Branch 1 taken 287800 times.
✓ Branch 2 taken 248013 times.
✓ Branch 3 taken 87484 times.
623297 return desc->comp[0].depth >= 9 && desc->comp[0].depth <= 14;
748 }
749
750 4013479 static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
751 {
752 4013479 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4013479 times.
4013479 av_assert0(desc);
754 4013479 return desc->flags & AV_PIX_FMT_FLAG_BE;
755 }
756
757 1334466 static av_always_inline int isYUV(enum AVPixelFormat pix_fmt)
758 {
759 1334466 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1334466 times.
1334466 av_assert0(desc);
761
4/4
✓ Branch 0 taken 1111920 times.
✓ Branch 1 taken 222546 times.
✓ Branch 2 taken 1104009 times.
✓ Branch 3 taken 7911 times.
1334466 return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components >= 2;
762 }
763
764 1312610 static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
765 {
766 1312610 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1312610 times.
1312610 av_assert0(desc);
768
4/4
✓ Branch 0 taken 1024654 times.
✓ Branch 1 taken 287956 times.
✓ Branch 3 taken 861943 times.
✓ Branch 4 taken 162711 times.
1312610 return ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) && isYUV(pix_fmt));
769 }
770
771 /*
772 * Identity semi-planar YUV formats. Specifically, those are YUV formats
773 * where the second and third components (U & V) are on the same plane.
774 */
775 470464 static av_always_inline int isSemiPlanarYUV(enum AVPixelFormat pix_fmt)
776 {
777 470464 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 470464 times.
470464 av_assert0(desc);
779
4/4
✓ Branch 1 taken 338259 times.
✓ Branch 2 taken 132205 times.
✓ Branch 3 taken 179796 times.
✓ Branch 4 taken 158463 times.
470464 return (isPlanarYUV(pix_fmt) && desc->comp[1].plane == desc->comp[2].plane);
780 }
781
782 243 static av_always_inline int isRGB(enum AVPixelFormat pix_fmt)
783 {
784 243 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243 times.
243 av_assert0(desc);
786 243 return (desc->flags & AV_PIX_FMT_FLAG_RGB);
787 }
788
789 791924 static av_always_inline int isGray(enum AVPixelFormat pix_fmt)
790 {
791 791924 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 791924 times.
791924 av_assert0(desc);
793 1581949 return !(desc->flags & AV_PIX_FMT_FLAG_PAL) &&
794
2/2
✓ Branch 0 taken 790011 times.
✓ Branch 1 taken 14 times.
790025 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
795
4/4
✓ Branch 0 taken 63542 times.
✓ Branch 1 taken 726469 times.
✓ Branch 2 taken 60101 times.
✓ Branch 3 taken 3441 times.
790011 desc->nb_components <= 2 &&
796
4/4
✓ Branch 0 taken 790025 times.
✓ Branch 1 taken 1899 times.
✓ Branch 2 taken 55192 times.
✓ Branch 3 taken 4909 times.
1581949 pix_fmt != AV_PIX_FMT_MONOBLACK &&
797 pix_fmt != AV_PIX_FMT_MONOWHITE;
798 }
799
800 40650 static av_always_inline int isRGBinInt(enum AVPixelFormat pix_fmt)
801 {
802
2/2
✓ Branch 0 taken 40194 times.
✓ Branch 1 taken 444 times.
40638 return pix_fmt == AV_PIX_FMT_RGB48BE ||
803
2/2
✓ Branch 0 taken 35369 times.
✓ Branch 1 taken 4825 times.
40194 pix_fmt == AV_PIX_FMT_RGB48LE ||
804
2/2
✓ Branch 0 taken 35364 times.
✓ Branch 1 taken 5 times.
35369 pix_fmt == AV_PIX_FMT_RGB32 ||
805
2/2
✓ Branch 0 taken 16643 times.
✓ Branch 1 taken 18721 times.
35364 pix_fmt == AV_PIX_FMT_RGB32_1 ||
806
2/2
✓ Branch 0 taken 16642 times.
✓ Branch 1 taken 1 times.
16643 pix_fmt == AV_PIX_FMT_RGB24 ||
807
2/2
✓ Branch 0 taken 14580 times.
✓ Branch 1 taken 2062 times.
16642 pix_fmt == AV_PIX_FMT_RGB565BE ||
808
2/2
✓ Branch 0 taken 14579 times.
✓ Branch 1 taken 1 times.
14580 pix_fmt == AV_PIX_FMT_RGB565LE ||
809
2/2
✓ Branch 0 taken 5614 times.
✓ Branch 1 taken 8965 times.
14579 pix_fmt == AV_PIX_FMT_RGB555BE ||
810
2/2
✓ Branch 0 taken 5613 times.
✓ Branch 1 taken 1 times.
5614 pix_fmt == AV_PIX_FMT_RGB555LE ||
811
2/2
✓ Branch 0 taken 5612 times.
✓ Branch 1 taken 1 times.
5613 pix_fmt == AV_PIX_FMT_RGB444BE ||
812
2/2
✓ Branch 0 taken 5609 times.
✓ Branch 1 taken 3 times.
5612 pix_fmt == AV_PIX_FMT_RGB444LE ||
813
2/2
✓ Branch 0 taken 5608 times.
✓ Branch 1 taken 1 times.
5609 pix_fmt == AV_PIX_FMT_RGB8 ||
814
2/2
✓ Branch 0 taken 5606 times.
✓ Branch 1 taken 2 times.
5608 pix_fmt == AV_PIX_FMT_RGB4 ||
815
2/2
✓ Branch 0 taken 5594 times.
✓ Branch 1 taken 12 times.
5606 pix_fmt == AV_PIX_FMT_RGB4_BYTE ||
816
2/2
✓ Branch 0 taken 5591 times.
✓ Branch 1 taken 3 times.
5594 pix_fmt == AV_PIX_FMT_RGBA64BE ||
817
2/2
✓ Branch 0 taken 5500 times.
✓ Branch 1 taken 91 times.
5591 pix_fmt == AV_PIX_FMT_RGBA64LE ||
818
4/4
✓ Branch 0 taken 40638 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 5409 times.
81288 pix_fmt == AV_PIX_FMT_MONOBLACK ||
819 pix_fmt == AV_PIX_FMT_MONOWHITE;
820 }
821
822 27170 static av_always_inline int isBGRinInt(enum AVPixelFormat pix_fmt)
823 {
824
2/2
✓ Branch 0 taken 27166 times.
✓ Branch 1 taken 3 times.
27169 return pix_fmt == AV_PIX_FMT_BGR48BE ||
825
2/2
✓ Branch 0 taken 26981 times.
✓ Branch 1 taken 185 times.
27166 pix_fmt == AV_PIX_FMT_BGR48LE ||
826
2/2
✓ Branch 0 taken 26922 times.
✓ Branch 1 taken 59 times.
26981 pix_fmt == AV_PIX_FMT_BGR32 ||
827
2/2
✓ Branch 0 taken 25399 times.
✓ Branch 1 taken 1523 times.
26922 pix_fmt == AV_PIX_FMT_BGR32_1 ||
828
2/2
✓ Branch 0 taken 25398 times.
✓ Branch 1 taken 1 times.
25399 pix_fmt == AV_PIX_FMT_BGR24 ||
829
2/2
✓ Branch 0 taken 25397 times.
✓ Branch 1 taken 1 times.
25398 pix_fmt == AV_PIX_FMT_BGR565BE ||
830
2/2
✓ Branch 0 taken 25396 times.
✓ Branch 1 taken 1 times.
25397 pix_fmt == AV_PIX_FMT_BGR565LE ||
831
2/2
✓ Branch 0 taken 22209 times.
✓ Branch 1 taken 3187 times.
25396 pix_fmt == AV_PIX_FMT_BGR555BE ||
832
2/2
✓ Branch 0 taken 22208 times.
✓ Branch 1 taken 1 times.
22209 pix_fmt == AV_PIX_FMT_BGR555LE ||
833
2/2
✓ Branch 0 taken 22207 times.
✓ Branch 1 taken 1 times.
22208 pix_fmt == AV_PIX_FMT_BGR444BE ||
834
2/2
✓ Branch 0 taken 22204 times.
✓ Branch 1 taken 3 times.
22207 pix_fmt == AV_PIX_FMT_BGR444LE ||
835
2/2
✓ Branch 0 taken 22203 times.
✓ Branch 1 taken 1 times.
22204 pix_fmt == AV_PIX_FMT_BGR8 ||
836
2/2
✓ Branch 0 taken 22201 times.
✓ Branch 1 taken 2 times.
22203 pix_fmt == AV_PIX_FMT_BGR4 ||
837
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 1 times.
22201 pix_fmt == AV_PIX_FMT_BGR4_BYTE ||
838
2/2
✓ Branch 0 taken 22197 times.
✓ Branch 1 taken 3 times.
22200 pix_fmt == AV_PIX_FMT_BGRA64BE ||
839
2/2
✓ Branch 0 taken 22124 times.
✓ Branch 1 taken 73 times.
22197 pix_fmt == AV_PIX_FMT_BGRA64LE ||
840
4/4
✓ Branch 0 taken 27169 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 73 times.
✓ Branch 3 taken 22051 times.
54339 pix_fmt == AV_PIX_FMT_MONOBLACK ||
841 pix_fmt == AV_PIX_FMT_MONOWHITE;
842 }
843
844 1503364 static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
845 {
846 1503364 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1503364 times.
1503364 av_assert0(desc);
848 1503364 return !!(desc->flags & AV_PIX_FMT_FLAG_BAYER);
849 }
850
851 static av_always_inline int isBayer16BPS(enum AVPixelFormat pix_fmt)
852 {
853 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
854 av_assert0(desc);
855 return desc->comp[1].depth == 8;
856 }
857
858 28927046 static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
859 {
860 28927046 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28927046 times.
28927046 av_assert0(desc);
862
2/2
✓ Branch 0 taken 14288986 times.
✓ Branch 1 taken 67530 times.
14356516 return (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
863
4/4
✓ Branch 0 taken 14356516 times.
✓ Branch 1 taken 14570530 times.
✓ Branch 2 taken 78920 times.
✓ Branch 3 taken 14210066 times.
43283562 pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt == AV_PIX_FMT_MONOWHITE;
864 }
865
866 50491 static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
867 {
868 50491 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50491 times.
50491 av_assert0(desc);
870 50491 return desc->flags & AV_PIX_FMT_FLAG_FLOAT;
871 }
872
873 17771 static av_always_inline int isFloat16(enum AVPixelFormat pix_fmt)
874 {
875 17771 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17771 times.
17771 av_assert0(desc);
877
3/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 17735 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
17771 return (desc->flags & AV_PIX_FMT_FLAG_FLOAT) && desc->comp[0].depth == 16;
878 }
879
880 1382222 static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
881 {
882 1382222 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1382222 times.
1382222 av_assert0(desc);
884
2/2
✓ Branch 0 taken 34485 times.
✓ Branch 1 taken 1347737 times.
1382222 if (pix_fmt == AV_PIX_FMT_PAL8)
885 34485 return 1;
886 1347737 return desc->flags & AV_PIX_FMT_FLAG_ALPHA;
887 }
888
889 407965 static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
890 {
891 407965 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407965 times.
407965 av_assert0(desc);
893
4/4
✓ Branch 0 taken 297794 times.
✓ Branch 1 taken 90835 times.
✓ Branch 2 taken 316198 times.
✓ Branch 3 taken 932 times.
407965 return (desc->nb_components >= 2 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) ||
894
2/2
✓ Branch 0 taken 314323 times.
✓ Branch 1 taken 1875 times.
316198 pix_fmt == AV_PIX_FMT_PAL8 ||
895
4/4
✓ Branch 0 taken 388629 times.
✓ Branch 1 taken 19336 times.
✓ Branch 2 taken 2075 times.
✓ Branch 3 taken 312248 times.
815930 pix_fmt == AV_PIX_FMT_MONOBLACK || pix_fmt == AV_PIX_FMT_MONOWHITE;
896 }
897
898 1381306 static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
899 {
900 1381306 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1381306 times.
1381306 av_assert0(desc);
902
4/4
✓ Branch 0 taken 1285718 times.
✓ Branch 1 taken 95588 times.
✓ Branch 2 taken 919193 times.
✓ Branch 3 taken 366525 times.
1381306 return (desc->nb_components >= 2 && (desc->flags & AV_PIX_FMT_FLAG_PLANAR));
903 }
904
905 21409 static av_always_inline int isPackedRGB(enum AVPixelFormat pix_fmt)
906 {
907 21409 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21409 times.
21409 av_assert0(desc);
909 21409 return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) == AV_PIX_FMT_FLAG_RGB);
910 }
911
912 49839 static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt)
913 {
914 49839 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49839 times.
49839 av_assert0(desc);
916 49839 return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) ==
917 (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB));
918 }
919
920 1011779 static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
921 {
922
2/2
✓ Branch 0 taken 142648 times.
✓ Branch 1 taken 869131 times.
1011779 switch (pix_fmt) {
923 142648 case AV_PIX_FMT_PAL8:
924 case AV_PIX_FMT_BGR4_BYTE:
925 case AV_PIX_FMT_BGR8:
926 case AV_PIX_FMT_GRAY8:
927 case AV_PIX_FMT_RGB4_BYTE:
928 case AV_PIX_FMT_RGB8:
929 142648 return 1;
930 869131 default:
931 869131 return 0;
932 }
933 }
934
935 /*
936 * Identity formats where the data is in the high bits, and the low bits are shifted away.
937 */
938 12231 static av_always_inline int isDataInHighBits(enum AVPixelFormat pix_fmt)
939 {
940 int i;
941 12231 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12231 times.
12231 av_assert0(desc);
943
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12211 times.
12231 if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL))
944 20 return 0;
945
2/2
✓ Branch 0 taken 25170 times.
✓ Branch 1 taken 6478 times.
31648 for (i = 0; i < desc->nb_components; i++) {
946
2/2
✓ Branch 0 taken 5723 times.
✓ Branch 1 taken 19447 times.
25170 if (!desc->comp[i].shift)
947 5723 return 0;
948
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 19437 times.
19447 if ((desc->comp[i].shift + desc->comp[i].depth) & 0x7)
949 10 return 0;
950 }
951 6478 return 1;
952 }
953
954 /*
955 * Identity formats where the chroma planes are swapped (CrCb order).
956 */
957 161925 static av_always_inline int isSwappedChroma(enum AVPixelFormat pix_fmt)
958 {
959 161925 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 161925 times.
161925 av_assert0(desc);
961
2/2
✓ Branch 1 taken 118 times.
✓ Branch 2 taken 161807 times.
161925 if (!isYUV(pix_fmt))
962 118 return 0;
963
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 161774 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 30 times.
161807 if ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) && desc->nb_components < 4)
964 3 return 0;
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 161804 times.
161804 if (desc->nb_components < 3)
966 return 0;
967
4/4
✓ Branch 1 taken 161777 times.
✓ Branch 2 taken 27 times.
✓ Branch 4 taken 161707 times.
✓ Branch 5 taken 70 times.
161804 if (!isPlanarYUV(pix_fmt) || isSemiPlanarYUV(pix_fmt))
968 161734 return desc->comp[1].offset > desc->comp[2].offset;
969 else
970 70 return desc->comp[1].plane > desc->comp[2].plane;
971 }
972
973 extern const uint64_t ff_dither4[2];
974 extern const uint64_t ff_dither8[2];
975
976 extern const uint8_t ff_dither_2x2_4[3][8];
977 extern const uint8_t ff_dither_2x2_8[3][8];
978 extern const uint8_t ff_dither_4x4_16[5][8];
979 extern const uint8_t ff_dither_8x8_32[9][8];
980 extern const uint8_t ff_dither_8x8_73[9][8];
981 extern const uint8_t ff_dither_8x8_128[9][8];
982 extern const uint8_t ff_dither_8x8_220[9][8];
983
984 extern const int32_t ff_yuv2rgb_coeffs[11][4];
985
986 extern const AVClass ff_sws_context_class;
987
988 /**
989 * Set c->convert_unscaled to an unscaled converter if one exists for the
990 * specific source and destination formats, bit depths, flags, etc.
991 */
992 void ff_get_unscaled_swscale(SwsInternal *c);
993 void ff_get_unscaled_swscale_ppc(SwsInternal *c);
994 void ff_get_unscaled_swscale_arm(SwsInternal *c);
995 void ff_get_unscaled_swscale_aarch64(SwsInternal *c);
996
997 void ff_sws_init_scale(SwsInternal *c);
998
999 void ff_sws_init_input_funcs(SwsInternal *c,
1000 planar1_YV12_fn *lumToYV12,
1001 planar1_YV12_fn *alpToYV12,
1002 planar2_YV12_fn *chrToYV12,
1003 planarX_YV12_fn *readLumPlanar,
1004 planarX_YV12_fn *readAlpPlanar,
1005 planarX2_YV12_fn *readChrPlanar);
1006 void ff_sws_init_output_funcs(SwsInternal *c,
1007 yuv2planar1_fn *yuv2plane1,
1008 yuv2planarX_fn *yuv2planeX,
1009 yuv2interleavedX_fn *yuv2nv12cX,
1010 yuv2packed1_fn *yuv2packed1,
1011 yuv2packed2_fn *yuv2packed2,
1012 yuv2packedX_fn *yuv2packedX,
1013 yuv2anyX_fn *yuv2anyX);
1014 void ff_sws_init_swscale_ppc(SwsInternal *c);
1015 void ff_sws_init_swscale_vsx(SwsInternal *c);
1016 void ff_sws_init_swscale_x86(SwsInternal *c);
1017 void ff_sws_init_swscale_aarch64(SwsInternal *c);
1018 void ff_sws_init_swscale_arm(SwsInternal *c);
1019 void ff_sws_init_swscale_loongarch(SwsInternal *c);
1020 void ff_sws_init_swscale_riscv(SwsInternal *c);
1021
1022 void ff_hyscale_fast_c(SwsInternal *c, int16_t *dst, int dstWidth,
1023 const uint8_t *src, int srcW, int xInc);
1024 void ff_hcscale_fast_c(SwsInternal *c, int16_t *dst1, int16_t *dst2,
1025 int dstWidth, const uint8_t *src1,
1026 const uint8_t *src2, int srcW, int xInc);
1027 int ff_init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
1028 int16_t *filter, int32_t *filterPos,
1029 int numSplits);
1030 void ff_hyscale_fast_mmxext(SwsInternal *c, int16_t *dst,
1031 int dstWidth, const uint8_t *src,
1032 int srcW, int xInc);
1033 void ff_hcscale_fast_mmxext(SwsInternal *c, int16_t *dst1, int16_t *dst2,
1034 int dstWidth, const uint8_t *src1,
1035 const uint8_t *src2, int srcW, int xInc);
1036
1037 int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
1038 const int srcStride[], int srcSliceY, int srcSliceH,
1039 uint8_t *const dst[], const int dstStride[]);
1040
1041 void ff_copyPlane(const uint8_t *src, int srcStride,
1042 int srcSliceY, int srcSliceH, int width,
1043 uint8_t *dst, int dstStride);
1044
1045 void ff_xyz12Torgb48(const SwsInternal *c, uint8_t *dst, int dst_stride,
1046 const uint8_t *src, int src_stride, int w, int h);
1047
1048 void ff_rgb48Toxyz12(const SwsInternal *c, uint8_t *dst, int dst_stride,
1049 const uint8_t *src, int src_stride, int w, int h);
1050
1051 966 static inline void fillPlane16(uint8_t *plane, int stride, int width, int height, int y,
1052 int alpha, int bits, const int big_endian)
1053 {
1054 966 uint8_t *ptr = plane + stride * y;
1055
1/2
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
966 int v = alpha ? 0xFFFF>>(16-bits) : (1<<(bits-1));
1056
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 636 times.
966 if (big_endian != HAVE_BIGENDIAN)
1057 330 v = av_bswap16(v);
1058
2/2
✓ Branch 0 taken 243188 times.
✓ Branch 1 taken 966 times.
244154 for (int i = 0; i < height; i++) {
1059
2/2
✓ Branch 0 taken 84803528 times.
✓ Branch 1 taken 243188 times.
85046716 for (int j = 0; j < width; j++)
1060 84803528 AV_WN16(ptr + 2 * j, v);
1061 243188 ptr += stride;
1062 }
1063 966 }
1064
1065 92 static inline void fillPlane32(uint8_t *plane, int stride, int width, int height, int y,
1066 int alpha, int bits, const int big_endian, int is_float)
1067 {
1068 92 uint8_t *ptr = plane + stride * y;
1069 uint32_t v;
1070 92 uint32_t onef32 = 0x3f800000;
1071
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 if (is_float)
1072
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 v = alpha ? onef32 : 0;
1073 else
1074 v = alpha ? 0xFFFFFFFF>>(32-bits) : (1<<(bits-1));
1075
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 72 times.
92 if (big_endian != HAVE_BIGENDIAN)
1076 20 v = av_bswap32(v);
1077
1078
2/2
✓ Branch 0 taken 26496 times.
✓ Branch 1 taken 92 times.
26588 for (int i = 0; i < height; i++) {
1079
2/2
✓ Branch 0 taken 9326592 times.
✓ Branch 1 taken 26496 times.
9353088 for (int j = 0; j < width; j++)
1080 9326592 AV_WN32(ptr + 4 * j, v);
1081 26496 ptr += stride;
1082 }
1083 92 }
1084
1085
1086 #define MAX_SLICE_PLANES 4
1087
1088 /// Slice plane
1089 typedef struct SwsPlane
1090 {
1091 int available_lines; ///< max number of lines that can be hold by this plane
1092 int sliceY; ///< index of first line
1093 int sliceH; ///< number of lines
1094 uint8_t **line; ///< line buffer
1095 uint8_t **tmp; ///< Tmp line buffer used by mmx code
1096 } SwsPlane;
1097
1098 /**
1099 * Struct which defines a slice of an image to be scaled or an output for
1100 * a scaled slice.
1101 * A slice can also be used as intermediate ring buffer for scaling steps.
1102 */
1103 typedef struct SwsSlice
1104 {
1105 int width; ///< Slice line width
1106 int h_chr_sub_sample; ///< horizontal chroma subsampling factor
1107 int v_chr_sub_sample; ///< vertical chroma subsampling factor
1108 int is_ring; ///< flag to identify if this slice is a ring buffer
1109 int should_free_lines; ///< flag to identify if there are dynamic allocated lines
1110 enum AVPixelFormat fmt; ///< planes pixel format
1111 SwsPlane plane[MAX_SLICE_PLANES]; ///< color planes
1112 } SwsSlice;
1113
1114 /**
1115 * Struct which holds all necessary data for processing a slice.
1116 * A processing step can be a color conversion or horizontal/vertical scaling.
1117 */
1118 typedef struct SwsFilterDescriptor
1119 {
1120 SwsSlice *src; ///< Source slice
1121 SwsSlice *dst; ///< Output slice
1122
1123 int alpha; ///< Flag for processing alpha channel
1124 void *instance; ///< Filter instance data
1125
1126 /// Function for processing input slice sliceH lines starting from line sliceY
1127 int (*process)(SwsInternal *c, struct SwsFilterDescriptor *desc, int sliceY, int sliceH);
1128 } SwsFilterDescriptor;
1129
1130 // warp input lines in the form (src + width*i + j) to slice format (line[i][j])
1131 // relative=true means first line src[x][0] otherwise first line is src[x][lum/crh Y]
1132 int ff_init_slice_from_src(SwsSlice * s, uint8_t *const src[4], const int stride[4],
1133 int srcW, int lumY, int lumH, int chrY, int chrH, int relative);
1134
1135 // Initialize scaler filter descriptor chain
1136 int ff_init_filters(SwsInternal *c);
1137
1138 // Free all filter data
1139 int ff_free_filters(SwsInternal *c);
1140
1141 /*
1142 function for applying ring buffer logic into slice s
1143 It checks if the slice can hold more @lum lines, if yes
1144 do nothing otherwise remove @lum least used lines.
1145 It applies the same procedure for @chr lines.
1146 */
1147 int ff_rotate_slice(SwsSlice *s, int lum, int chr);
1148
1149 /// initializes gamma conversion descriptor
1150 int ff_init_gamma_convert(SwsFilterDescriptor *desc, SwsSlice * src, uint16_t *table);
1151
1152 /// initializes lum pixel format conversion descriptor
1153 int ff_init_desc_fmt_convert(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst, uint32_t *pal);
1154
1155 /// initializes lum horizontal scaling descriptor
1156 int ff_init_desc_hscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int * filter_pos, int filter_size, int xInc);
1157
1158 /// initializes chr pixel format conversion descriptor
1159 int ff_init_desc_cfmt_convert(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst, uint32_t *pal);
1160
1161 /// initializes chr horizontal scaling descriptor
1162 int ff_init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int * filter_pos, int filter_size, int xInc);
1163
1164 int ff_init_desc_no_chr(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst);
1165
1166 /// initializes vertical scaling descriptors
1167 int ff_init_vscale(SwsInternal *c, SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst);
1168
1169 /// setup vertical scaler functions
1170 void ff_init_vscale_pfn(SwsInternal *c, yuv2planar1_fn yuv2plane1, yuv2planarX_fn yuv2planeX,
1171 yuv2interleavedX_fn yuv2nv12cX, yuv2packed1_fn yuv2packed1, yuv2packed2_fn yuv2packed2,
1172 yuv2packedX_fn yuv2packedX, yuv2anyX_fn yuv2anyX, int use_mmx);
1173
1174 void ff_sws_slice_worker(void *priv, int jobnr, int threadnr,
1175 int nb_jobs, int nb_threads);
1176
1177 int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
1178 int srcSliceY, int srcSliceH, uint8_t *const dst[],
1179 const int dstStride[], int dstSliceY, int dstSliceH);
1180
1181
1182 //number of extra lines to process
1183 #define MAX_LINES_AHEAD 4
1184
1185 //shuffle filter and filterPos for hyScale and hcScale filters in avx2
1186 int ff_shuffle_filter_coefficients(SwsInternal *c, int* filterPos, int filterSize, int16_t *filter, int dstW);
1187 #endif /* SWSCALE_SWSCALE_INTERNAL_H */
1188