FFmpeg
swscale.c
Go to the documentation of this file.
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 #include <stdint.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "libavutil/avassert.h"
26 #include "libavutil/bswap.h"
27 #include "libavutil/common.h"
28 #include "libavutil/cpu.h"
29 #include "libavutil/emms.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/mem_internal.h"
33 #include "libavutil/pixdesc.h"
34 #include "config.h"
35 #include "swscale_internal.h"
36 #include "swscale.h"
37 
38 DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_128)[9][8] = {
39  { 36, 68, 60, 92, 34, 66, 58, 90, },
40  { 100, 4, 124, 28, 98, 2, 122, 26, },
41  { 52, 84, 44, 76, 50, 82, 42, 74, },
42  { 116, 20, 108, 12, 114, 18, 106, 10, },
43  { 32, 64, 56, 88, 38, 70, 62, 94, },
44  { 96, 0, 120, 24, 102, 6, 126, 30, },
45  { 48, 80, 40, 72, 54, 86, 46, 78, },
46  { 112, 16, 104, 8, 118, 22, 110, 14, },
47  { 36, 68, 60, 92, 34, 66, 58, 90, },
48 };
49 
50 DECLARE_ALIGNED(8, static const uint8_t, sws_pb_64)[8] = {
51  64, 64, 64, 64, 64, 64, 64, 64
52 };
53 
54 static av_always_inline void fillPlane(uint8_t *plane, int stride, int width,
55  int height, int y, uint8_t val)
56 {
57  int i;
58  uint8_t *ptr = plane + stride * y;
59  for (i = 0; i < height; i++) {
60  memset(ptr, val, width);
61  ptr += stride;
62  }
63 }
64 
65 static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW,
66  const uint8_t *_src, const int16_t *filter,
67  const int32_t *filterPos, int filterSize)
68 {
69  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
70  int i;
71  int32_t *dst = (int32_t *) _dst;
72  const uint16_t *src = (const uint16_t *) _src;
73  int bits = desc->comp[0].depth - 1;
74  int sh = bits - 4;
75 
76  if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
77  sh = 9;
78  } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
79  sh = 16 - 1 - 4;
80  }
81 
82  for (i = 0; i < dstW; i++) {
83  int j;
84  int srcPos = filterPos[i];
85  int val = 0;
86 
87  for (j = 0; j < filterSize; j++) {
88  val += src[srcPos + j] * filter[filterSize * i + j];
89  }
90  // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit
91  dst[i] = FFMIN(val >> sh, (1 << 19) - 1);
92  }
93 }
94 
95 static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW,
96  const uint8_t *_src, const int16_t *filter,
97  const int32_t *filterPos, int filterSize)
98 {
99  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
100  int i;
101  const uint16_t *src = (const uint16_t *) _src;
102  int sh = desc->comp[0].depth - 1;
103 
104  if (sh<15) {
105  sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
106  } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
107  sh = 16 - 1;
108  }
109 
110  for (i = 0; i < dstW; i++) {
111  int j;
112  int srcPos = filterPos[i];
113  int val = 0;
114 
115  for (j = 0; j < filterSize; j++) {
116  val += src[srcPos + j] * filter[filterSize * i + j];
117  }
118  // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit
119  dst[i] = FFMIN(val >> sh, (1 << 15) - 1);
120  }
121 }
122 
123 // bilinear / bicubic scaling
124 static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW,
125  const uint8_t *src, const int16_t *filter,
126  const int32_t *filterPos, int filterSize)
127 {
128  int i;
129  for (i = 0; i < dstW; i++) {
130  int j;
131  int srcPos = filterPos[i];
132  int val = 0;
133  for (j = 0; j < filterSize; j++) {
134  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
135  }
136  dst[i] = FFMIN(val >> 7, (1 << 15) - 1); // the cubic equation does overflow ...
137  }
138 }
139 
140 static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW,
141  const uint8_t *src, const int16_t *filter,
142  const int32_t *filterPos, int filterSize)
143 {
144  int i;
145  int32_t *dst = (int32_t *) _dst;
146  for (i = 0; i < dstW; i++) {
147  int j;
148  int srcPos = filterPos[i];
149  int val = 0;
150  for (j = 0; j < filterSize; j++) {
151  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
152  }
153  dst[i] = FFMIN(val >> 3, (1 << 19) - 1); // the cubic equation does overflow ...
154  }
155 }
156 
157 // FIXME all pal and rgb srcFormats could do this conversion as well
158 // FIXME all scalers more complex than bilinear could do half of this transform
159 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
160 {
161  int i;
162  for (i = 0; i < width; i++) {
163  dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
164  dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
165  }
166 }
167 
168 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
169 {
170  int i;
171  for (i = 0; i < width; i++) {
172  dstU[i] = (dstU[i] * 1799 + 4081085) >> 11; // 1469
173  dstV[i] = (dstV[i] * 1799 + 4081085) >> 11; // 1469
174  }
175 }
176 
177 static void lumRangeToJpeg_c(int16_t *dst, int width)
178 {
179  int i;
180  for (i = 0; i < width; i++)
181  dst[i] = (FFMIN(dst[i], 30189) * 19077 - 39057361) >> 14;
182 }
183 
184 static void lumRangeFromJpeg_c(int16_t *dst, int width)
185 {
186  int i;
187  for (i = 0; i < width; i++)
188  dst[i] = (dst[i] * 14071 + 33561947) >> 14;
189 }
190 
191 static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
192 {
193  int i;
194  int32_t *dstU = (int32_t *) _dstU;
195  int32_t *dstV = (int32_t *) _dstV;
196  for (i = 0; i < width; i++) {
197  dstU[i] = (FFMIN(dstU[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
198  dstV[i] = (FFMIN(dstV[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
199  }
200 }
201 
202 static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
203 {
204  int i;
205  int32_t *dstU = (int32_t *) _dstU;
206  int32_t *dstV = (int32_t *) _dstV;
207  for (i = 0; i < width; i++) {
208  dstU[i] = (dstU[i] * 1799 + (4081085 << 4)) >> 11; // 1469
209  dstV[i] = (dstV[i] * 1799 + (4081085 << 4)) >> 11; // 1469
210  }
211 }
212 
213 static void lumRangeToJpeg16_c(int16_t *_dst, int width)
214 {
215  int i;
216  int32_t *dst = (int32_t *) _dst;
217  for (i = 0; i < width; i++) {
218  dst[i] = ((int)(FFMIN(dst[i], 30189 << 4) * 4769U - (39057361 << 2))) >> 12;
219  }
220 }
221 
222 static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
223 {
224  int i;
225  int32_t *dst = (int32_t *) _dst;
226  for (i = 0; i < width; i++)
227  dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
228 }
229 
230 
231 #define DEBUG_SWSCALE_BUFFERS 0
232 #define DEBUG_BUFFERS(...) \
233  if (DEBUG_SWSCALE_BUFFERS) \
234  av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
235 
236 static int swscale(SwsContext *c, const uint8_t *src[],
237  int srcStride[], int srcSliceY, int srcSliceH,
238  uint8_t *dst[], int dstStride[],
239  int dstSliceY, int dstSliceH)
240 {
241  const int scale_dst = dstSliceY > 0 || dstSliceH < c->dstH;
242 
243  /* load a few things into local vars to make the code more readable?
244  * and faster */
245  const int dstW = c->dstW;
246  int dstH = c->dstH;
247 
248  const enum AVPixelFormat dstFormat = c->dstFormat;
249  const int flags = c->flags;
250  int32_t *vLumFilterPos = c->vLumFilterPos;
251  int32_t *vChrFilterPos = c->vChrFilterPos;
252 
253  const int vLumFilterSize = c->vLumFilterSize;
254  const int vChrFilterSize = c->vChrFilterSize;
255 
256  yuv2planar1_fn yuv2plane1 = c->yuv2plane1;
257  yuv2planarX_fn yuv2planeX = c->yuv2planeX;
258  yuv2interleavedX_fn yuv2nv12cX = c->yuv2nv12cX;
259  yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
260  yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
261  yuv2packedX_fn yuv2packedX = c->yuv2packedX;
262  yuv2anyX_fn yuv2anyX = c->yuv2anyX;
263  const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample;
264  const int chrSrcSliceH = AV_CEIL_RSHIFT(srcSliceH, c->chrSrcVSubSample);
265  int should_dither = isNBPS(c->srcFormat) ||
266  is16BPS(c->srcFormat);
267  int lastDstY;
268 
269  /* vars which will change and which we need to store back in the context */
270  int dstY = c->dstY;
271  int lastInLumBuf = c->lastInLumBuf;
272  int lastInChrBuf = c->lastInChrBuf;
273 
274  int lumStart = 0;
275  int lumEnd = c->descIndex[0];
276  int chrStart = lumEnd;
277  int chrEnd = c->descIndex[1];
278  int vStart = chrEnd;
279  int vEnd = c->numDesc;
280  SwsSlice *src_slice = &c->slice[lumStart];
281  SwsSlice *hout_slice = &c->slice[c->numSlice-2];
282  SwsSlice *vout_slice = &c->slice[c->numSlice-1];
283  SwsFilterDescriptor *desc = c->desc;
284 
285  int needAlpha = c->needAlpha;
286 
287  int hasLumHoles = 1;
288  int hasChrHoles = 1;
289 
290  if (isPacked(c->srcFormat)) {
291  src[1] =
292  src[2] =
293  src[3] = src[0];
294  srcStride[1] =
295  srcStride[2] =
296  srcStride[3] = srcStride[0];
297  }
298  srcStride[1] *= 1 << c->vChrDrop;
299  srcStride[2] *= 1 << c->vChrDrop;
300 
301  DEBUG_BUFFERS("swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
302  src[0], srcStride[0], src[1], srcStride[1],
303  src[2], srcStride[2], src[3], srcStride[3],
304  dst[0], dstStride[0], dst[1], dstStride[1],
305  dst[2], dstStride[2], dst[3], dstStride[3]);
306  DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
307  srcSliceY, srcSliceH, dstY, dstH);
308  DEBUG_BUFFERS("vLumFilterSize: %d vChrFilterSize: %d\n",
309  vLumFilterSize, vChrFilterSize);
310 
311  if (dstStride[0]&15 || dstStride[1]&15 ||
312  dstStride[2]&15 || dstStride[3]&15) {
313  SwsContext *const ctx = c->parent ? c->parent : c;
314  if (flags & SWS_PRINT_INFO &&
315  !atomic_exchange_explicit(&ctx->stride_unaligned_warned, 1, memory_order_relaxed)) {
317  "Warning: dstStride is not aligned!\n"
318  " ->cannot do aligned memory accesses anymore\n");
319  }
320  }
321 
322 #if ARCH_X86
323  if ( (uintptr_t)dst[0]&15 || (uintptr_t)dst[1]&15 || (uintptr_t)dst[2]&15
324  || (uintptr_t)src[0]&15 || (uintptr_t)src[1]&15 || (uintptr_t)src[2]&15
325  || dstStride[0]&15 || dstStride[1]&15 || dstStride[2]&15 || dstStride[3]&15
326  || srcStride[0]&15 || srcStride[1]&15 || srcStride[2]&15 || srcStride[3]&15
327  ) {
328  SwsContext *const ctx = c->parent ? c->parent : c;
329  int cpu_flags = av_get_cpu_flags();
330  if (flags & SWS_PRINT_INFO && HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) &&
331  !atomic_exchange_explicit(&ctx->stride_unaligned_warned,1, memory_order_relaxed)) {
332  av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speed loss\n");
333  }
334  }
335 #endif
336 
337  if (scale_dst) {
338  dstY = dstSliceY;
339  dstH = dstY + dstSliceH;
340  lastInLumBuf = -1;
341  lastInChrBuf = -1;
342  } else if (srcSliceY == 0) {
343  /* Note the user might start scaling the picture in the middle so this
344  * will not get executed. This is not really intended but works
345  * currently, so people might do it. */
346  dstY = 0;
347  lastInLumBuf = -1;
348  lastInChrBuf = -1;
349  }
350 
351  if (!should_dither) {
352  c->chrDither8 = c->lumDither8 = sws_pb_64;
353  }
354  lastDstY = dstY;
355 
356  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
357  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, c->use_mmx_vfilter);
358 
359  ff_init_slice_from_src(src_slice, (uint8_t**)src, srcStride, c->srcW,
360  srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
361 
362  ff_init_slice_from_src(vout_slice, (uint8_t**)dst, dstStride, c->dstW,
363  dstY, dstSliceH, dstY >> c->chrDstVSubSample,
364  AV_CEIL_RSHIFT(dstSliceH, c->chrDstVSubSample), scale_dst);
365  if (srcSliceY == 0) {
366  hout_slice->plane[0].sliceY = lastInLumBuf + 1;
367  hout_slice->plane[1].sliceY = lastInChrBuf + 1;
368  hout_slice->plane[2].sliceY = lastInChrBuf + 1;
369  hout_slice->plane[3].sliceY = lastInLumBuf + 1;
370 
371  hout_slice->plane[0].sliceH =
372  hout_slice->plane[1].sliceH =
373  hout_slice->plane[2].sliceH =
374  hout_slice->plane[3].sliceH = 0;
375  hout_slice->width = dstW;
376  }
377 
378  for (; dstY < dstH; dstY++) {
379  const int chrDstY = dstY >> c->chrDstVSubSample;
380  int use_mmx_vfilter= c->use_mmx_vfilter;
381 
382  // First line needed as input
383  const int firstLumSrcY = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
384  const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), c->dstH - 1)]);
385  // First line needed as input
386  const int firstChrSrcY = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
387 
388  // Last line needed as input
389  int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
390  int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
391  int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
392  int enough_lines;
393 
394  int i;
395  int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;
396 
397  // handle holes (FAST_BILINEAR & weird filters)
398  if (firstLumSrcY > lastInLumBuf) {
399 
400  hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
401  if (hasLumHoles) {
402  hout_slice->plane[0].sliceY = firstLumSrcY;
403  hout_slice->plane[3].sliceY = firstLumSrcY;
404  hout_slice->plane[0].sliceH =
405  hout_slice->plane[3].sliceH = 0;
406  }
407 
408  lastInLumBuf = firstLumSrcY - 1;
409  }
410  if (firstChrSrcY > lastInChrBuf) {
411 
412  hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
413  if (hasChrHoles) {
414  hout_slice->plane[1].sliceY = firstChrSrcY;
415  hout_slice->plane[2].sliceY = firstChrSrcY;
416  hout_slice->plane[1].sliceH =
417  hout_slice->plane[2].sliceH = 0;
418  }
419 
420  lastInChrBuf = firstChrSrcY - 1;
421  }
422 
423  DEBUG_BUFFERS("dstY: %d\n", dstY);
424  DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
425  firstLumSrcY, lastLumSrcY, lastInLumBuf);
426  DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
427  firstChrSrcY, lastChrSrcY, lastInChrBuf);
428 
429  // Do we have enough lines in this slice to output the dstY line
430  enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
431  lastChrSrcY < AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample);
432 
433  if (!enough_lines) {
434  lastLumSrcY = srcSliceY + srcSliceH - 1;
435  lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
436  DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
437  lastLumSrcY, lastChrSrcY);
438  }
439 
440  av_assert0((lastLumSrcY - firstLumSrcY + 1) <= hout_slice->plane[0].available_lines);
441  av_assert0((lastChrSrcY - firstChrSrcY + 1) <= hout_slice->plane[1].available_lines);
442 
443 
444  posY = hout_slice->plane[0].sliceY + hout_slice->plane[0].sliceH;
445  if (posY <= lastLumSrcY && !hasLumHoles) {
446  firstPosY = FFMAX(firstLumSrcY, posY);
447  lastPosY = FFMIN(firstLumSrcY + hout_slice->plane[0].available_lines - 1, srcSliceY + srcSliceH - 1);
448  } else {
449  firstPosY = posY;
450  lastPosY = lastLumSrcY;
451  }
452 
453  cPosY = hout_slice->plane[1].sliceY + hout_slice->plane[1].sliceH;
454  if (cPosY <= lastChrSrcY && !hasChrHoles) {
455  firstCPosY = FFMAX(firstChrSrcY, cPosY);
456  lastCPosY = FFMIN(firstChrSrcY + hout_slice->plane[1].available_lines - 1, AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample) - 1);
457  } else {
458  firstCPosY = cPosY;
459  lastCPosY = lastChrSrcY;
460  }
461 
462  ff_rotate_slice(hout_slice, lastPosY, lastCPosY);
463 
464  if (posY < lastLumSrcY + 1) {
465  for (i = lumStart; i < lumEnd; ++i)
466  desc[i].process(c, &desc[i], firstPosY, lastPosY - firstPosY + 1);
467  }
468 
469  lastInLumBuf = lastLumSrcY;
470 
471  if (cPosY < lastChrSrcY + 1) {
472  for (i = chrStart; i < chrEnd; ++i)
473  desc[i].process(c, &desc[i], firstCPosY, lastCPosY - firstCPosY + 1);
474  }
475 
476  lastInChrBuf = lastChrSrcY;
477 
478  if (!enough_lines)
479  break; // we can't output a dstY line so let's try with the next slice
480 
481 #if HAVE_MMX_INLINE
483 #endif
484  if (should_dither) {
485  c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
486  c->lumDither8 = ff_dither_8x8_128[dstY & 7];
487  }
488  if (dstY >= c->dstH - 2) {
489  /* hmm looks like we can't use MMX here without overwriting
490  * this array's tail */
491  ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
492  &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
493  use_mmx_vfilter= 0;
494  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
495  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
496  }
497 
498  for (i = vStart; i < vEnd; ++i)
499  desc[i].process(c, &desc[i], dstY, 1);
500  }
501  if (isPlanar(dstFormat) && isALPHA(dstFormat) && !needAlpha) {
502  int offset = lastDstY - dstSliceY;
503  int length = dstW;
504  int height = dstY - lastDstY;
505 
506  if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
507  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
508  fillPlane16(dst[3], dstStride[3], length, height, offset,
509  1, desc->comp[3].depth,
510  isBE(dstFormat));
511  } else if (is32BPS(dstFormat)) {
512  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
513  fillPlane32(dst[3], dstStride[3], length, height, offset,
514  1, desc->comp[3].depth,
515  isBE(dstFormat), desc->flags & AV_PIX_FMT_FLAG_FLOAT);
516  } else
517  fillPlane(dst[3], dstStride[3], length, height, offset, 255);
518  }
519 
520 #if HAVE_MMXEXT_INLINE
522  __asm__ volatile ("sfence" ::: "memory");
523 #endif
524  emms_c();
525 
526  /* store changed local vars back in the context */
527  c->dstY = dstY;
528  c->lastInLumBuf = lastInLumBuf;
529  c->lastInChrBuf = lastInChrBuf;
530 
531  return dstY - lastDstY;
532 }
533 
535 {
536  c->lumConvertRange = NULL;
537  c->chrConvertRange = NULL;
538  if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
539  if (c->dstBpc <= 14) {
540  if (c->srcRange) {
541  c->lumConvertRange = lumRangeFromJpeg_c;
542  c->chrConvertRange = chrRangeFromJpeg_c;
543  } else {
544  c->lumConvertRange = lumRangeToJpeg_c;
545  c->chrConvertRange = chrRangeToJpeg_c;
546  }
547  } else {
548  if (c->srcRange) {
549  c->lumConvertRange = lumRangeFromJpeg16_c;
550  c->chrConvertRange = chrRangeFromJpeg16_c;
551  } else {
552  c->lumConvertRange = lumRangeToJpeg16_c;
553  c->chrConvertRange = chrRangeToJpeg16_c;
554  }
555  }
556  }
557 }
558 
560 {
561  enum AVPixelFormat srcFormat = c->srcFormat;
562 
563  ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
564  &c->yuv2nv12cX, &c->yuv2packed1,
565  &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
566 
568 
569  if (c->srcBpc == 8) {
570  if (c->dstBpc <= 14) {
571  c->hyScale = c->hcScale = hScale8To15_c;
572  if (c->flags & SWS_FAST_BILINEAR) {
573  c->hyscale_fast = ff_hyscale_fast_c;
574  c->hcscale_fast = ff_hcscale_fast_c;
575  }
576  } else {
577  c->hyScale = c->hcScale = hScale8To19_c;
578  }
579  } else {
580  c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
581  : hScale16To15_c;
582  }
583 
585 
586  if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
587  srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE))
588  c->needs_hcscale = 1;
589 }
590 
592 {
594 
595 #if ARCH_PPC
597 #elif ARCH_X86
599 #elif ARCH_AARCH64
601 #elif ARCH_ARM
603 #elif ARCH_LOONGARCH64
605 #endif
606 }
607 
608 static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
609 {
610  if (!isALPHA(format))
611  src[3] = NULL;
612  if (!isPlanar(format)) {
613  src[3] = src[2] = NULL;
614 
615  if (!usePal(format))
616  src[1] = NULL;
617  }
618 }
619 
620 static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
621  const int linesizes[4])
622 {
624  int i;
625 
626  av_assert2(desc);
627 
628  for (i = 0; i < 4; i++) {
629  int plane = desc->comp[i].plane;
630  if (!data[plane] || !linesizes[plane])
631  return 0;
632  }
633 
634  return 1;
635 }
636 
637 static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
638  const uint16_t *src, int stride, int h)
639 {
640  int xp,yp;
641  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
642 
643  for (yp=0; yp<h; yp++) {
644  for (xp=0; xp+2<stride; xp+=3) {
645  int x, y, z, r, g, b;
646 
647  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
648  x = AV_RB16(src + xp + 0);
649  y = AV_RB16(src + xp + 1);
650  z = AV_RB16(src + xp + 2);
651  } else {
652  x = AV_RL16(src + xp + 0);
653  y = AV_RL16(src + xp + 1);
654  z = AV_RL16(src + xp + 2);
655  }
656 
657  x = c->xyzgamma[x>>4];
658  y = c->xyzgamma[y>>4];
659  z = c->xyzgamma[z>>4];
660 
661  // convert from XYZlinear to sRGBlinear
662  r = c->xyz2rgb_matrix[0][0] * x +
663  c->xyz2rgb_matrix[0][1] * y +
664  c->xyz2rgb_matrix[0][2] * z >> 12;
665  g = c->xyz2rgb_matrix[1][0] * x +
666  c->xyz2rgb_matrix[1][1] * y +
667  c->xyz2rgb_matrix[1][2] * z >> 12;
668  b = c->xyz2rgb_matrix[2][0] * x +
669  c->xyz2rgb_matrix[2][1] * y +
670  c->xyz2rgb_matrix[2][2] * z >> 12;
671 
672  // limit values to 12-bit depth
673  r = av_clip_uintp2(r, 12);
674  g = av_clip_uintp2(g, 12);
675  b = av_clip_uintp2(b, 12);
676 
677  // convert from sRGBlinear to RGB and scale from 12bit to 16bit
678  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
679  AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
680  AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
681  AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
682  } else {
683  AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
684  AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
685  AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
686  }
687  }
688  src += stride;
689  dst += stride;
690  }
691 }
692 
693 static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst,
694  const uint16_t *src, int stride, int h)
695 {
696  int xp,yp;
697  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
698 
699  for (yp=0; yp<h; yp++) {
700  for (xp=0; xp+2<stride; xp+=3) {
701  int x, y, z, r, g, b;
702 
703  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
704  r = AV_RB16(src + xp + 0);
705  g = AV_RB16(src + xp + 1);
706  b = AV_RB16(src + xp + 2);
707  } else {
708  r = AV_RL16(src + xp + 0);
709  g = AV_RL16(src + xp + 1);
710  b = AV_RL16(src + xp + 2);
711  }
712 
713  r = c->rgbgammainv[r>>4];
714  g = c->rgbgammainv[g>>4];
715  b = c->rgbgammainv[b>>4];
716 
717  // convert from sRGBlinear to XYZlinear
718  x = c->rgb2xyz_matrix[0][0] * r +
719  c->rgb2xyz_matrix[0][1] * g +
720  c->rgb2xyz_matrix[0][2] * b >> 12;
721  y = c->rgb2xyz_matrix[1][0] * r +
722  c->rgb2xyz_matrix[1][1] * g +
723  c->rgb2xyz_matrix[1][2] * b >> 12;
724  z = c->rgb2xyz_matrix[2][0] * r +
725  c->rgb2xyz_matrix[2][1] * g +
726  c->rgb2xyz_matrix[2][2] * b >> 12;
727 
728  // limit values to 12-bit depth
729  x = av_clip_uintp2(x, 12);
730  y = av_clip_uintp2(y, 12);
731  z = av_clip_uintp2(z, 12);
732 
733  // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
734  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
735  AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4);
736  AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4);
737  AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4);
738  } else {
739  AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4);
740  AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4);
741  AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 4);
742  }
743  }
744  src += stride;
745  dst += stride;
746  }
747 }
748 
749 static void update_palette(SwsContext *c, const uint32_t *pal)
750 {
751  for (int i = 0; i < 256; i++) {
752  int r, g, b, y, u, v, a = 0xff;
753  if (c->srcFormat == AV_PIX_FMT_PAL8) {
754  uint32_t p = pal[i];
755  a = (p >> 24) & 0xFF;
756  r = (p >> 16) & 0xFF;
757  g = (p >> 8) & 0xFF;
758  b = p & 0xFF;
759  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
760  r = ( i >> 5 ) * 36;
761  g = ((i >> 2) & 7) * 36;
762  b = ( i & 3) * 85;
763  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
764  b = ( i >> 6 ) * 85;
765  g = ((i >> 3) & 7) * 36;
766  r = ( i & 7) * 36;
767  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
768  r = ( i >> 3 ) * 255;
769  g = ((i >> 1) & 3) * 85;
770  b = ( i & 1) * 255;
771  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
772  r = g = b = i;
773  } else {
774  av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
775  b = ( i >> 3 ) * 255;
776  g = ((i >> 1) & 3) * 85;
777  r = ( i & 1) * 255;
778  }
779 #define RGB2YUV_SHIFT 15
780 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
781 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
782 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
783 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
784 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
785 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
786 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
787 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
788 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
789 
790  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
791  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
792  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
793  c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
794 
795  switch (c->dstFormat) {
796  case AV_PIX_FMT_BGR32:
797 #if !HAVE_BIGENDIAN
798  case AV_PIX_FMT_RGB24:
799 #endif
800  c->pal_rgb[i]= r + (g<<8) + (b<<16) + ((unsigned)a<<24);
801  break;
802  case AV_PIX_FMT_BGR32_1:
803 #if HAVE_BIGENDIAN
804  case AV_PIX_FMT_BGR24:
805 #endif
806  c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24);
807  break;
808  case AV_PIX_FMT_RGB32_1:
809 #if HAVE_BIGENDIAN
810  case AV_PIX_FMT_RGB24:
811 #endif
812  c->pal_rgb[i]= a + (b<<8) + (g<<16) + ((unsigned)r<<24);
813  break;
814  case AV_PIX_FMT_RGB32:
815 #if !HAVE_BIGENDIAN
816  case AV_PIX_FMT_BGR24:
817 #endif
818  default:
819  c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24);
820  }
821  }
822 }
823 
824 static int scale_internal(SwsContext *c,
825  const uint8_t * const srcSlice[], const int srcStride[],
826  int srcSliceY, int srcSliceH,
827  uint8_t *const dstSlice[], const int dstStride[],
828  int dstSliceY, int dstSliceH);
829 
831  const uint8_t * const srcSlice[], const int srcStride[],
832  int srcSliceY, int srcSliceH,
833  uint8_t * const dstSlice[], const int dstStride[],
834  int dstSliceY, int dstSliceH)
835 {
836  int ret = scale_internal(c->cascaded_context[0],
837  srcSlice, srcStride, srcSliceY, srcSliceH,
838  c->cascaded_tmp, c->cascaded_tmpStride, 0, c->srcH);
839 
840  if (ret < 0)
841  return ret;
842 
843  if (c->cascaded_context[2])
844  ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp,
845  c->cascaded_tmpStride, srcSliceY, srcSliceH,
846  c->cascaded1_tmp, c->cascaded1_tmpStride, 0, c->dstH);
847  else
848  ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp,
849  c->cascaded_tmpStride, srcSliceY, srcSliceH,
850  dstSlice, dstStride, dstSliceY, dstSliceH);
851 
852  if (ret < 0)
853  return ret;
854 
855  if (c->cascaded_context[2]) {
856  ret = scale_internal(c->cascaded_context[2], (const uint8_t * const *)c->cascaded1_tmp,
857  c->cascaded1_tmpStride, c->cascaded_context[1]->dstY - ret,
858  c->cascaded_context[1]->dstY,
859  dstSlice, dstStride, dstSliceY, dstSliceH);
860  }
861  return ret;
862 }
863 
865  const uint8_t * const srcSlice[], const int srcStride[],
866  int srcSliceY, int srcSliceH,
867  uint8_t * const dstSlice[], const int dstStride[],
868  int dstSliceY, int dstSliceH)
869 {
870  int ret = scale_internal(c->cascaded_context[0],
871  srcSlice, srcStride, srcSliceY, srcSliceH,
872  c->cascaded_tmp, c->cascaded_tmpStride,
873  0, c->cascaded_context[0]->dstH);
874  if (ret < 0)
875  return ret;
876  ret = scale_internal(c->cascaded_context[1],
877  (const uint8_t * const * )c->cascaded_tmp, c->cascaded_tmpStride,
878  0, c->cascaded_context[0]->dstH,
879  dstSlice, dstStride, dstSliceY, dstSliceH);
880  return ret;
881 }
882 
884  const uint8_t * const srcSlice[], const int srcStride[],
885  int srcSliceY, int srcSliceH,
886  uint8_t *const dstSlice[], const int dstStride[],
887  int dstSliceY, int dstSliceH)
888 {
889  const int scale_dst = dstSliceY > 0 || dstSliceH < c->dstH;
890  const int frame_start = scale_dst || !c->sliceDir;
891  int i, ret;
892  const uint8_t *src2[4];
893  uint8_t *dst2[4];
894  int macro_height_src = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
895  int macro_height_dst = isBayer(c->dstFormat) ? 2 : (1 << c->chrDstVSubSample);
896  // copy strides, so they can safely be modified
897  int srcStride2[4];
898  int dstStride2[4];
899  int srcSliceY_internal = srcSliceY;
900 
901  if (!srcStride || !dstStride || !dstSlice || !srcSlice) {
902  av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
903  return AVERROR(EINVAL);
904  }
905 
906  if ((srcSliceY & (macro_height_src - 1)) ||
907  ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH != c->srcH) ||
908  srcSliceY + srcSliceH > c->srcH ||
909  (isBayer(c->srcFormat) && srcSliceH <= 1)) {
910  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH);
911  return AVERROR(EINVAL);
912  }
913 
914  if ((dstSliceY & (macro_height_dst - 1)) ||
915  ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH != c->dstH) ||
916  dstSliceY + dstSliceH > c->dstH) {
917  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", dstSliceY, dstSliceH);
918  return AVERROR(EINVAL);
919  }
920 
921  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
922  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
923  return AVERROR(EINVAL);
924  }
925  if (!check_image_pointers((const uint8_t* const*)dstSlice, c->dstFormat, dstStride)) {
926  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
927  return AVERROR(EINVAL);
928  }
929 
930  // do not mess up sliceDir if we have a "trailing" 0-size slice
931  if (srcSliceH == 0)
932  return 0;
933 
934  if (c->gamma_flag && c->cascaded_context[0])
935  return scale_gamma(c, srcSlice, srcStride, srcSliceY, srcSliceH,
936  dstSlice, dstStride, dstSliceY, dstSliceH);
937 
938  if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH)
939  return scale_cascaded(c, srcSlice, srcStride, srcSliceY, srcSliceH,
940  dstSlice, dstStride, dstSliceY, dstSliceH);
941 
942  if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
943  for (i = 0; i < 4; i++)
944  memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
945 
946  if (usePal(c->srcFormat))
947  update_palette(c, (const uint32_t *)srcSlice[1]);
948 
949  memcpy(src2, srcSlice, sizeof(src2));
950  memcpy(dst2, dstSlice, sizeof(dst2));
951  memcpy(srcStride2, srcStride, sizeof(srcStride2));
952  memcpy(dstStride2, dstStride, sizeof(dstStride2));
953 
954  if (frame_start && !scale_dst) {
955  if (srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
956  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
957  return AVERROR(EINVAL);
958  }
959 
960  c->sliceDir = (srcSliceY == 0) ? 1 : -1;
961  } else if (scale_dst)
962  c->sliceDir = 1;
963 
964  if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
965  uint8_t *base;
966  int x,y;
967 
968  av_fast_malloc(&c->rgb0_scratch, &c->rgb0_scratch_allocated,
969  FFABS(srcStride[0]) * srcSliceH + 32);
970  if (!c->rgb0_scratch)
971  return AVERROR(ENOMEM);
972 
973  base = srcStride[0] < 0 ? c->rgb0_scratch - srcStride[0] * (srcSliceH-1) :
974  c->rgb0_scratch;
975  for (y=0; y<srcSliceH; y++){
976  memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
977  for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
978  base[ srcStride[0]*y + x] = 0xFF;
979  }
980  }
981  src2[0] = base;
982  }
983 
984  if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
985  uint8_t *base;
986 
987  av_fast_malloc(&c->xyz_scratch, &c->xyz_scratch_allocated,
988  FFABS(srcStride[0]) * srcSliceH + 32);
989  if (!c->xyz_scratch)
990  return AVERROR(ENOMEM);
991 
992  base = srcStride[0] < 0 ? c->xyz_scratch - srcStride[0] * (srcSliceH-1) :
993  c->xyz_scratch;
994 
995  xyz12Torgb48(c, (uint16_t*)base, (const uint16_t*)src2[0], srcStride[0]/2, srcSliceH);
996  src2[0] = base;
997  }
998 
999  if (c->sliceDir != 1) {
1000  // slices go from bottom to top => we flip the image internally
1001  for (i=0; i<4; i++) {
1002  srcStride2[i] *= -1;
1003  dstStride2[i] *= -1;
1004  }
1005 
1006  src2[0] += (srcSliceH - 1) * srcStride[0];
1007  if (!usePal(c->srcFormat))
1008  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
1009  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
1010  src2[3] += (srcSliceH - 1) * srcStride[3];
1011  dst2[0] += ( c->dstH - 1) * dstStride[0];
1012  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
1013  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
1014  dst2[3] += ( c->dstH - 1) * dstStride[3];
1015 
1016  srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
1017  }
1018  reset_ptr(src2, c->srcFormat);
1019  reset_ptr((void*)dst2, c->dstFormat);
1020 
1021  if (c->convert_unscaled) {
1022  int offset = srcSliceY_internal;
1023  int slice_h = srcSliceH;
1024 
1025  // for dst slice scaling, offset the pointers to match the unscaled API
1026  if (scale_dst) {
1027  av_assert0(offset == 0);
1028  for (i = 0; i < 4 && src2[i]; i++) {
1029  if (!src2[i] || (i > 0 && usePal(c->srcFormat)))
1030  break;
1031  src2[i] += (dstSliceY >> ((i == 1 || i == 2) ? c->chrSrcVSubSample : 0)) * srcStride2[i];
1032  }
1033 
1034  for (i = 0; i < 4 && dst2[i]; i++) {
1035  if (!dst2[i] || (i > 0 && usePal(c->dstFormat)))
1036  break;
1037  dst2[i] -= (dstSliceY >> ((i == 1 || i == 2) ? c->chrDstVSubSample : 0)) * dstStride2[i];
1038  }
1039  offset = dstSliceY;
1040  slice_h = dstSliceH;
1041  }
1042 
1043  ret = c->convert_unscaled(c, src2, srcStride2, offset, slice_h,
1044  dst2, dstStride2);
1045  if (scale_dst)
1046  dst2[0] += dstSliceY * dstStride2[0];
1047  } else {
1048  ret = swscale(c, src2, srcStride2, srcSliceY_internal, srcSliceH,
1049  dst2, dstStride2, dstSliceY, dstSliceH);
1050  }
1051 
1052  if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
1053  uint16_t *dst16;
1054 
1055  if (scale_dst) {
1056  dst16 = (uint16_t *)dst2[0];
1057  } else {
1058  int dstY = c->dstY ? c->dstY : srcSliceY + srcSliceH;
1059 
1060  av_assert0(dstY >= ret);
1061  av_assert0(ret >= 0);
1062  av_assert0(c->dstH >= dstY);
1063  dst16 = (uint16_t*)(dst2[0] + (dstY - ret) * dstStride2[0]);
1064  }
1065 
1066  /* replace on the same data */
1067  rgb48Toxyz12(c, dst16, dst16, dstStride2[0]/2, ret);
1068  }
1069 
1070  /* reset slice direction at end of frame */
1071  if ((srcSliceY_internal + srcSliceH == c->srcH) || scale_dst)
1072  c->sliceDir = 0;
1073 
1074  return ret;
1075 }
1076 
1078 {
1079  av_frame_unref(c->frame_src);
1080  av_frame_unref(c->frame_dst);
1081  c->src_ranges.nb_ranges = 0;
1082 }
1083 
1084 int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
1085 {
1086  int ret, allocated = 0;
1087 
1088  ret = av_frame_ref(c->frame_src, src);
1089  if (ret < 0)
1090  return ret;
1091 
1092  if (!dst->buf[0]) {
1093  dst->width = c->dstW;
1094  dst->height = c->dstH;
1095  dst->format = c->dstFormat;
1096 
1097  ret = av_frame_get_buffer(dst, 0);
1098  if (ret < 0)
1099  return ret;
1100  allocated = 1;
1101  }
1102 
1103  ret = av_frame_ref(c->frame_dst, dst);
1104  if (ret < 0) {
1105  if (allocated)
1106  av_frame_unref(dst);
1107 
1108  return ret;
1109  }
1110 
1111  return 0;
1112 }
1113 
1114 int sws_send_slice(struct SwsContext *c, unsigned int slice_start,
1115  unsigned int slice_height)
1116 {
1117  int ret;
1118 
1119  ret = ff_range_add(&c->src_ranges, slice_start, slice_height);
1120  if (ret < 0)
1121  return ret;
1122 
1123  return 0;
1124 }
1125 
1126 unsigned int sws_receive_slice_alignment(const struct SwsContext *c)
1127 {
1128  if (c->slice_ctx)
1129  return c->slice_ctx[0]->dst_slice_align;
1130 
1131  return c->dst_slice_align;
1132 }
1133 
1134 int sws_receive_slice(struct SwsContext *c, unsigned int slice_start,
1135  unsigned int slice_height)
1136 {
1137  unsigned int align = sws_receive_slice_alignment(c);
1138  uint8_t *dst[4];
1139 
1140  /* wait until complete input has been received */
1141  if (!(c->src_ranges.nb_ranges == 1 &&
1142  c->src_ranges.ranges[0].start == 0 &&
1143  c->src_ranges.ranges[0].len == c->srcH))
1144  return AVERROR(EAGAIN);
1145 
1146  if ((slice_start > 0 || slice_height < c->dstH) &&
1147  (slice_start % align || slice_height % align)) {
1149  "Incorrectly aligned output: %u/%u not multiples of %u\n",
1150  slice_start, slice_height, align);
1151  return AVERROR(EINVAL);
1152  }
1153 
1154  if (c->slicethread) {
1155  int nb_jobs = c->slice_ctx[0]->dither == SWS_DITHER_ED ? 1 : c->nb_slice_ctx;
1156  int ret = 0;
1157 
1158  c->dst_slice_start = slice_start;
1159  c->dst_slice_height = slice_height;
1160 
1161  avpriv_slicethread_execute(c->slicethread, nb_jobs, 0);
1162 
1163  for (int i = 0; i < c->nb_slice_ctx; i++) {
1164  if (c->slice_err[i] < 0) {
1165  ret = c->slice_err[i];
1166  break;
1167  }
1168  }
1169 
1170  memset(c->slice_err, 0, c->nb_slice_ctx * sizeof(*c->slice_err));
1171 
1172  return ret;
1173  }
1174 
1175  for (int i = 0; i < FF_ARRAY_ELEMS(dst); i++) {
1176  ptrdiff_t offset = c->frame_dst->linesize[i] * (slice_start >> c->chrDstVSubSample);
1177  dst[i] = FF_PTR_ADD(c->frame_dst->data[i], offset);
1178  }
1179 
1180  return scale_internal(c, (const uint8_t * const *)c->frame_src->data,
1181  c->frame_src->linesize, 0, c->srcH,
1182  dst, c->frame_dst->linesize, slice_start, slice_height);
1183 }
1184 
1185 int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
1186 {
1187  int ret;
1188 
1189  ret = sws_frame_start(c, dst, src);
1190  if (ret < 0)
1191  return ret;
1192 
1193  ret = sws_send_slice(c, 0, src->height);
1194  if (ret >= 0)
1195  ret = sws_receive_slice(c, 0, dst->height);
1196 
1197  sws_frame_end(c);
1198 
1199  return ret;
1200 }
1201 
1202 /**
1203  * swscale wrapper, so we don't need to export the SwsContext.
1204  * Assumes planar YUV to be in YUV order instead of YVU.
1205  */
1207  const uint8_t * const srcSlice[],
1208  const int srcStride[], int srcSliceY,
1209  int srcSliceH, uint8_t *const dst[],
1210  const int dstStride[])
1211 {
1212  if (c->nb_slice_ctx)
1213  c = c->slice_ctx[0];
1214 
1215  return scale_internal(c, srcSlice, srcStride, srcSliceY, srcSliceH,
1216  dst, dstStride, 0, c->dstH);
1217 }
1218 
1219 void ff_sws_slice_worker(void *priv, int jobnr, int threadnr,
1220  int nb_jobs, int nb_threads)
1221 {
1222  SwsContext *parent = priv;
1223  SwsContext *c = parent->slice_ctx[threadnr];
1224 
1225  const int slice_height = FFALIGN(FFMAX((parent->dst_slice_height + nb_jobs - 1) / nb_jobs, 1),
1226  c->dst_slice_align);
1227  const int slice_start = jobnr * slice_height;
1228  const int slice_end = FFMIN((jobnr + 1) * slice_height, parent->dst_slice_height);
1229  int err = 0;
1230 
1231  if (slice_end > slice_start) {
1232  uint8_t *dst[4] = { NULL };
1233 
1234  for (int i = 0; i < FF_ARRAY_ELEMS(dst) && parent->frame_dst->data[i]; i++) {
1235  const int vshift = (i == 1 || i == 2) ? c->chrDstVSubSample : 0;
1236  const ptrdiff_t offset = parent->frame_dst->linesize[i] *
1237  ((slice_start + parent->dst_slice_start) >> vshift);
1238 
1239  dst[i] = parent->frame_dst->data[i] + offset;
1240  }
1241 
1242  err = scale_internal(c, (const uint8_t * const *)parent->frame_src->data,
1243  parent->frame_src->linesize, 0, c->srcH,
1244  dst, parent->frame_dst->linesize,
1246  }
1247 
1248  parent->slice_err[threadnr] = err;
1249 }
isBayer
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:821
yuv2packed2_fn
void(* yuv2packed2_fn)(struct SwsContext *c, const int16_t *lumSrc[2], const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing bilinear scalin...
Definition: swscale_internal.h:223
yuv2planar1_fn
void(* yuv2planar1_fn)(const int16_t *src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output without any additional vertical scaling (...
Definition: swscale_internal.h:117
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
process
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
Definition: vf_normalize.c:155
yuv2packed1_fn
void(* yuv2packed1_fn)(struct SwsContext *c, const int16_t *lumSrc, const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc, uint8_t *dest, int dstW, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output without any additional v...
Definition: swscale_internal.h:190
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
SwsPlane::sliceH
int sliceH
number of lines
Definition: swscale_internal.h:1053
hScale16To19_c
static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:65
isPacked
static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:866
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
mem_internal.h
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:288
chrRangeFromJpeg16_c
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:202
AV_PIX_FMT_BGR32
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:453
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2965
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:123
ff_hyscale_fast_c
void ff_hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
Definition: hscale_fast_bilinear.c:23
ff_rotate_slice
int ff_rotate_slice(SwsSlice *s, int lum, int chr)
Definition: slice.c:120
AV_PIX_FMT_FLAG_FLOAT
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:158
SwsSlice::plane
SwsPlane plane[MAX_SLICE_PLANES]
color planes
Definition: swscale_internal.h:1071
avpriv_slicethread_execute
void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading.
Definition: slicethread.c:249
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
pixdesc.h
AVFrame::width
int width
Definition: frame.h:446
hScale8To15_c
static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:124
GV
#define GV
ff_sws_init_input_funcs
void ff_sws_init_input_funcs(SwsContext *c)
b
#define b
Definition: input.c:41
SwsFilterDescriptor
Struct which holds all necessary data for processing a slice.
Definition: swscale_internal.h:1078
yuv2planeX
static void FUNC() yuv2planeX(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Definition: swscale_ppc_template.c:84
data
const char data[16]
Definition: mxf.c:148
AV_PIX_FMT_MONOWHITE
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:82
isGray
#define isGray(x)
Definition: swscale.c:42
AV_PIX_FMT_RGB32_1
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:452
base
uint8_t base
Definition: vp3data.h:128
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
sws_scale
int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition: swscale.c:1206
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
RV
#define RV
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:103
DEBUG_BUFFERS
#define DEBUG_BUFFERS(...)
Definition: swscale.c:232
scale_internal
static int scale_internal(SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
Definition: swscale.c:883
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:587
cpu_flags
static atomic_int cpu_flags
Definition: cpu.c:52
sws_send_slice
int sws_send_slice(struct SwsContext *c, unsigned int slice_start, unsigned int slice_height)
Indicate that a horizontal slice of input data is available in the source frame previously provided t...
Definition: swscale.c:1114
scale_cascaded
static int scale_cascaded(SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
Definition: swscale.c:864
xyz12Torgb48
static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:637
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
sws_receive_slice
int sws_receive_slice(struct SwsContext *c, unsigned int slice_start, unsigned int slice_height)
Request a horizontal slice of the output data to be written into the frame previously provided to sws...
Definition: swscale.c:1134
SWS_FAST_BILINEAR
#define SWS_FAST_BILINEAR
Definition: swscale.h:65
is16BPS
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:706
ff_sws_init_swscale_aarch64
av_cold void ff_sws_init_swscale_aarch64(SwsContext *c)
Definition: swscale.c:204
SWS_BITEXACT
#define SWS_BITEXACT
Definition: swscale.h:91
yuv2anyX_fn
void(* yuv2anyX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t **dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to YUV/RGB output by doing multi-point vertical scaling...
Definition: swscale_internal.h:289
hScale8To19_c
static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:140
val
static double val(void *priv, double ch)
Definition: aeval.c:78
isNBPS
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:720
RY
#define RY
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:90
avassert.h
frame_start
static int frame_start(MpegEncContext *s)
Definition: mpegvideo_enc.c:1708
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
SwsContext::dst_slice_height
int dst_slice_height
Definition: swscale_internal.h:316
ff_sws_init_swscale_loongarch
av_cold void ff_sws_init_swscale_loongarch(SwsContext *c)
Definition: swscale_init_loongarch.c:59
sws_init_swscale
static av_cold void sws_init_swscale(SwsContext *c)
Definition: swscale.c:559
SWS_DITHER_ED
@ SWS_DITHER_ED
Definition: swscale_internal.h:75
emms_c
#define emms_c()
Definition: emms.h:63
width
#define width
intreadwrite.h
GU
#define GU
sws_frame_start
int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
Initialize the scaling process for a given pair of source/destination frames.
Definition: swscale.c:1084
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:59
ff_sws_init_swscale_arm
av_cold void ff_sws_init_swscale_arm(SwsContext *c)
Definition: swscale.c:33
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
g
const char * g
Definition: vf_curves.c:128
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
SwsSlice::width
int width
Slice line width.
Definition: swscale_internal.h:1065
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:1730
bits
uint8_t bits
Definition: vp3data.h:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
scale_gamma
static int scale_gamma(SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
Definition: swscale.c:830
lumRangeFromJpeg_c
static void lumRangeFromJpeg_c(int16_t *dst, int width)
Definition: swscale.c:184
ff_init_vscale_pfn
void ff_init_vscale_pfn(SwsContext *c, yuv2planar1_fn yuv2plane1, yuv2planarX_fn yuv2planeX, yuv2interleavedX_fn yuv2nv12cX, yuv2packed1_fn yuv2packed1, yuv2packed2_fn yuv2packed2, yuv2packedX_fn yuv2packedX, yuv2anyX_fn yuv2anyX, int use_mmx)
setup vertical scaler functions
Definition: vscale.c:258
AV_PIX_FMT_BGR32_1
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:454
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:73
SwsContext::dst_slice_start
int dst_slice_start
Definition: swscale_internal.h:315
ff_sws_init_range_convert
av_cold void ff_sws_init_range_convert(SwsContext *c)
Definition: swscale.c:534
SwsContext::slice_err
int * slice_err
Definition: swscale_internal.h:311
AV_PIX_FMT_GRAY8A
@ AV_PIX_FMT_GRAY8A
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:143
fillPlane
static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
Definition: swscale.c:54
NULL
#define NULL
Definition: coverity.c:32
SwsPlane::available_lines
int available_lines
max number of lines that can be hold by this plane
Definition: swscale_internal.h:1051
ff_sws_init_swscale_x86
av_cold void ff_sws_init_swscale_x86(SwsContext *c)
Definition: swscale.c:450
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
AV_PIX_FMT_MONOBLACK
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:83
FF_PTR_ADD
#define FF_PTR_ADD(ptr, off)
Definition: internal.h:80
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
Definition: pixfmt.h:93
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AV_PIX_FMT_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:92
ff_range_add
int ff_range_add(RangeList *r, unsigned int start, unsigned int len)
Definition: utils.c:2569
chrRangeToJpeg_c
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:159
attribute_align_arg
#define attribute_align_arg
Definition: internal.h:50
AV_CPU_FLAG_SSE2
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:34
ff_sws_slice_worker
void ff_sws_slice_worker(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
Definition: swscale.c:1219
isBE
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:727
update_palette
static void update_palette(SwsContext *c, const uint32_t *pal)
Definition: swscale.c:749
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
ff_sws_init_scale
void ff_sws_init_scale(SwsContext *c)
Definition: swscale.c:591
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:384
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem_internal.h:109
fillPlane16
static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian)
Definition: swscale_internal.h:1011
usePal
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:897
BV
#define BV
cpu.h
isAnyRGB
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:835
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
hScale16To15_c
static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:95
SwsContext::slice_ctx
struct SwsContext ** slice_ctx
Definition: swscale_internal.h:310
srcSliceH
return srcSliceH
Definition: yuv2rgb_template.c:87
chrRangeToJpeg16_c
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:191
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:461
RGB2YUV_SHIFT
#define RGB2YUV_SHIFT
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:411
is32BPS
static av_always_inline int is32BPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:713
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:410
height
#define height
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:451
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
ff_hcscale_fast_c
void ff_hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
Definition: hscale_fast_bilinear.c:38
fillPlane32
static void fillPlane32(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian, int is_float)
Definition: swscale_internal.h:1025
GY
#define GY
emms.h
SwsContext::frame_src
AVFrame * frame_src
Definition: swscale_internal.h:346
sws_scale_frame
int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
Definition: swscale.c:1185
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
src2
const pixel * src2
Definition: h264pred_template.c:422
common.h
sws_receive_slice_alignment
unsigned int sws_receive_slice_alignment(const struct SwsContext *c)
Get the alignment required for slices.
Definition: swscale.c:1126
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
check_image_pointers
static int check_image_pointers(const uint8_t *const data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
Definition: swscale.c:620
av_always_inline
#define av_always_inline
Definition: attributes.h:49
swscale_internal.h
yuv2interleavedX_fn
void(* yuv2interleavedX_fn)(enum AVPixelFormat dstFormat, const uint8_t *chrDither, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest, int dstW)
Write one line of horizontally scaled chroma to interleaved output with multi-point vertical scaling ...
Definition: swscale_internal.h:153
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:116
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:606
AV_PIX_FMT_RGB4_BYTE
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:95
SwsSlice
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
Definition: swscale_internal.h:1063
stride
#define stride
Definition: h264pred_template.c:537
ff_init_slice_from_src
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)
Definition: slice.c:148
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ret
ret
Definition: filter_design.txt:187
__asm__
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
bswap.h
sws_pb_64
static const uint8_t sws_pb_64[8]
Definition: swscale.c:50
sws_frame_end
void sws_frame_end(struct SwsContext *c)
Finish the scaling process for a pair of source/destination frames previously submitted with sws_fram...
Definition: swscale.c:1077
ff_sws_init_swscale_ppc
av_cold void ff_sws_init_swscale_ppc(SwsContext *c)
Definition: swscale_altivec.c:232
U
#define U(x)
Definition: vpx_arith.h:37
yuv2planarX_fn
void(* yuv2planarX_fn)(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output with multi-point vertical scaling between...
Definition: swscale_internal.h:133
ff_sws_init_output_funcs
void ff_sws_init_output_funcs(SwsContext *c, yuv2planar1_fn *yuv2plane1, yuv2planarX_fn *yuv2planeX, yuv2interleavedX_fn *yuv2nv12cX, yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2, yuv2packedX_fn *yuv2packedX, yuv2anyX_fn *yuv2anyX)
AVFrame::height
int height
Definition: frame.h:446
isALPHA
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
Definition: swscale.c:54
reset_ptr
static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
Definition: swscale.c:608
yuv2packedX_fn
void(* yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing multi-point ver...
Definition: swscale_internal.h:255
SwsContext::frame_dst
AVFrame * frame_dst
Definition: swscale_internal.h:347
atomic_exchange_explicit
#define atomic_exchange_explicit(object, desired, order)
Definition: stdatomic.h:106
swscale
static int swscale(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[], int dstSliceY, int dstSliceH)
Definition: swscale.c:236
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:699
ff_dither_8x8_128
const uint8_t ff_dither_8x8_128[9][8]
Definition: swscale.c:38
AV_CPU_FLAG_MMXEXT
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:30
av_clip_uint8
#define av_clip_uint8
Definition: common.h:105
RU
#define RU
lumRangeToJpeg_c
static void lumRangeToJpeg_c(int16_t *dst, int width)
Definition: swscale.c:177
BU
#define BU
lumRangeFromJpeg16_c
static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:222
desc
const char * desc
Definition: libsvtav1.c:79
SWS_PRINT_INFO
#define SWS_PRINT_INFO
Definition: swscale.h:82
mem.h
lumRangeToJpeg16_c
static void lumRangeToJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:213
SwsPlane::sliceY
int sliceY
index of first line
Definition: swscale_internal.h:1052
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
BY
#define BY
chrRangeFromJpeg_c
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:168
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_fast_malloc
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:557
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
int32_t
int32_t
Definition: audioconvert.c:56
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:419
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
ff_updateMMXDitherTables
void ff_updateMMXDitherTables(SwsContext *c, int dstY)
isPlanar
static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:875
int
int
Definition: ffmpeg_filter.c:424
SwsContext
Definition: swscale_internal.h:301
rgb48Toxyz12
static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:693
swscale.h
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98