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