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 <inttypes.h>
22 #include <math.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/avutil.h"
28 #include "libavutil/bswap.h"
29 #include "libavutil/cpu.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/pixdesc.h"
34 #include "config.h"
35 #include "rgb2rgb.h"
36 #include "swscale_internal.h"
37 #include "swscale.h"
38 
40  { 36, 68, 60, 92, 34, 66, 58, 90, },
41  { 100, 4, 124, 28, 98, 2, 122, 26, },
42  { 52, 84, 44, 76, 50, 82, 42, 74, },
43  { 116, 20, 108, 12, 114, 18, 106, 10, },
44  { 32, 64, 56, 88, 38, 70, 62, 94, },
45  { 96, 0, 120, 24, 102, 6, 126, 30, },
46  { 48, 80, 40, 72, 54, 86, 46, 78, },
47  { 112, 16, 104, 8, 118, 22, 110, 14, },
48  { 36, 68, 60, 92, 34, 66, 58, 90, },
49 };
50 
51 DECLARE_ALIGNED(8, static const uint8_t, sws_pb_64)[8] = {
52  64, 64, 64, 64, 64, 64, 64, 64
53 };
54 
56  int height, int y, uint8_t val)
57 {
58  int i;
59  uint8_t *ptr = plane + stride * y;
60  for (i = 0; i < height; i++) {
61  memset(ptr, val, width);
62  ptr += stride;
63  }
64 }
65 
66 static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW,
67  const uint8_t *_src, const int16_t *filter,
68  const int32_t *filterPos, int filterSize)
69 {
71  int i;
72  int32_t *dst = (int32_t *) _dst;
73  const uint16_t *src = (const uint16_t *) _src;
74  int bits = desc->comp[0].depth - 1;
75  int sh = bits - 4;
76 
77  if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
78  sh = 9;
79  } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
80  sh = 16 - 1 - 4;
81  }
82 
83  for (i = 0; i < dstW; i++) {
84  int j;
85  int srcPos = filterPos[i];
86  int val = 0;
87 
88  for (j = 0; j < filterSize; j++) {
89  val += src[srcPos + j] * filter[filterSize * i + j];
90  }
91  // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit
92  dst[i] = FFMIN(val >> sh, (1 << 19) - 1);
93  }
94 }
95 
96 static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW,
97  const uint8_t *_src, const int16_t *filter,
98  const int32_t *filterPos, int filterSize)
99 {
101  int i;
102  const uint16_t *src = (const uint16_t *) _src;
103  int sh = desc->comp[0].depth - 1;
104 
105  if (sh<15) {
106  sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
107  } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
108  sh = 16 - 1;
109  }
110 
111  for (i = 0; i < dstW; i++) {
112  int j;
113  int srcPos = filterPos[i];
114  int val = 0;
115 
116  for (j = 0; j < filterSize; j++) {
117  val += src[srcPos + j] * filter[filterSize * i + j];
118  }
119  // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit
120  dst[i] = FFMIN(val >> sh, (1 << 15) - 1);
121  }
122 }
123 
124 // bilinear / bicubic scaling
125 static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW,
126  const uint8_t *src, const int16_t *filter,
127  const int32_t *filterPos, int filterSize)
128 {
129  int i;
130  for (i = 0; i < dstW; i++) {
131  int j;
132  int srcPos = filterPos[i];
133  int val = 0;
134  for (j = 0; j < filterSize; j++) {
135  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
136  }
137  dst[i] = FFMIN(val >> 7, (1 << 15) - 1); // the cubic equation does overflow ...
138  }
139 }
140 
141 static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW,
142  const uint8_t *src, const int16_t *filter,
143  const int32_t *filterPos, int filterSize)
144 {
145  int i;
146  int32_t *dst = (int32_t *) _dst;
147  for (i = 0; i < dstW; i++) {
148  int j;
149  int srcPos = filterPos[i];
150  int val = 0;
151  for (j = 0; j < filterSize; j++) {
152  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
153  }
154  dst[i] = FFMIN(val >> 3, (1 << 19) - 1); // the cubic equation does overflow ...
155  }
156 }
157 
158 // FIXME all pal and rgb srcFormats could do this conversion as well
159 // FIXME all scalers more complex than bilinear could do half of this transform
160 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
161 {
162  int i;
163  for (i = 0; i < width; i++) {
164  dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
165  dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
166  }
167 }
168 
169 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
170 {
171  int i;
172  for (i = 0; i < width; i++) {
173  dstU[i] = (dstU[i] * 1799 + 4081085) >> 11; // 1469
174  dstV[i] = (dstV[i] * 1799 + 4081085) >> 11; // 1469
175  }
176 }
177 
178 static void lumRangeToJpeg_c(int16_t *dst, int width)
179 {
180  int i;
181  for (i = 0; i < width; i++)
182  dst[i] = (FFMIN(dst[i], 30189) * 19077 - 39057361) >> 14;
183 }
184 
185 static void lumRangeFromJpeg_c(int16_t *dst, int width)
186 {
187  int i;
188  for (i = 0; i < width; i++)
189  dst[i] = (dst[i] * 14071 + 33561947) >> 14;
190 }
191 
192 static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
193 {
194  int i;
195  int32_t *dstU = (int32_t *) _dstU;
196  int32_t *dstV = (int32_t *) _dstV;
197  for (i = 0; i < width; i++) {
198  dstU[i] = (FFMIN(dstU[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
199  dstV[i] = (FFMIN(dstV[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
200  }
201 }
202 
203 static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
204 {
205  int i;
206  int32_t *dstU = (int32_t *) _dstU;
207  int32_t *dstV = (int32_t *) _dstV;
208  for (i = 0; i < width; i++) {
209  dstU[i] = (dstU[i] * 1799 + (4081085 << 4)) >> 11; // 1469
210  dstV[i] = (dstV[i] * 1799 + (4081085 << 4)) >> 11; // 1469
211  }
212 }
213 
214 static void lumRangeToJpeg16_c(int16_t *_dst, int width)
215 {
216  int i;
217  int32_t *dst = (int32_t *) _dst;
218  for (i = 0; i < width; i++) {
219  dst[i] = ((int)(FFMIN(dst[i], 30189 << 4) * 4769U - (39057361 << 2))) >> 12;
220  }
221 }
222 
223 static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
224 {
225  int i;
226  int32_t *dst = (int32_t *) _dst;
227  for (i = 0; i < width; i++)
228  dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
229 }
230 
231 
232 #define DEBUG_SWSCALE_BUFFERS 0
233 #define DEBUG_BUFFERS(...) \
234  if (DEBUG_SWSCALE_BUFFERS) \
235  av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
236 
237 static int swscale(SwsContext *c, const uint8_t *src[],
238  int srcStride[], int srcSliceY,
239  int srcSliceH, uint8_t *dst[], int dstStride[])
240 {
241  /* load a few things into local vars to make the code more readable?
242  * and faster */
243  const int dstW = c->dstW;
244  const int dstH = c->dstH;
245 
246  const enum AVPixelFormat dstFormat = c->dstFormat;
247  const int flags = c->flags;
248  int32_t *vLumFilterPos = c->vLumFilterPos;
249  int32_t *vChrFilterPos = c->vChrFilterPos;
250 
251  const int vLumFilterSize = c->vLumFilterSize;
252  const int vChrFilterSize = c->vChrFilterSize;
253 
254  yuv2planar1_fn yuv2plane1 = c->yuv2plane1;
256  yuv2interleavedX_fn yuv2nv12cX = c->yuv2nv12cX;
257  yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
258  yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
259  yuv2packedX_fn yuv2packedX = c->yuv2packedX;
260  yuv2anyX_fn yuv2anyX = c->yuv2anyX;
261  const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample;
262  const int chrSrcSliceH = AV_CEIL_RSHIFT(srcSliceH, c->chrSrcVSubSample);
263  int should_dither = isNBPS(c->srcFormat) ||
264  is16BPS(c->srcFormat);
265  int lastDstY;
266 
267  /* vars which will change and which we need to store back in the context */
268  int dstY = c->dstY;
269  int lumBufIndex = c->lumBufIndex;
270  int chrBufIndex = c->chrBufIndex;
271  int lastInLumBuf = c->lastInLumBuf;
272  int lastInChrBuf = c->lastInChrBuf;
273 
274 
275  int lumStart = 0;
276  int lumEnd = c->descIndex[0];
277  int chrStart = lumEnd;
278  int chrEnd = c->descIndex[1];
279  int vStart = chrEnd;
280  int vEnd = c->numDesc;
281  SwsSlice *src_slice = &c->slice[lumStart];
282  SwsSlice *hout_slice = &c->slice[c->numSlice-2];
283  SwsSlice *vout_slice = &c->slice[c->numSlice-1];
285 
286 
287  int needAlpha = c->needAlpha;
288 
289  int hasLumHoles = 1;
290  int hasChrHoles = 1;
291 
292 
293  if (isPacked(c->srcFormat)) {
294  src[1] =
295  src[2] =
296  src[3] = src[0];
297  srcStride[1] =
298  srcStride[2] =
299  srcStride[3] = srcStride[0];
300  }
301  srcStride[1] <<= c->vChrDrop;
302  srcStride[2] <<= c->vChrDrop;
303 
304  DEBUG_BUFFERS("swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
305  src[0], srcStride[0], src[1], srcStride[1],
306  src[2], srcStride[2], src[3], srcStride[3],
307  dst[0], dstStride[0], dst[1], dstStride[1],
308  dst[2], dstStride[2], dst[3], dstStride[3]);
309  DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
310  srcSliceY, srcSliceH, dstY, dstH);
311  DEBUG_BUFFERS("vLumFilterSize: %d vChrFilterSize: %d\n",
312  vLumFilterSize, vChrFilterSize);
313 
314  if (dstStride[0]&15 || dstStride[1]&15 ||
315  dstStride[2]&15 || dstStride[3]&15) {
316  static int warnedAlready = 0; // FIXME maybe move this into the context
317  if (flags & SWS_PRINT_INFO && !warnedAlready) {
319  "Warning: dstStride is not aligned!\n"
320  " ->cannot do aligned memory accesses anymore\n");
321  warnedAlready = 1;
322  }
323  }
324 
325  if ( (uintptr_t)dst[0]&15 || (uintptr_t)dst[1]&15 || (uintptr_t)dst[2]&15
326  || (uintptr_t)src[0]&15 || (uintptr_t)src[1]&15 || (uintptr_t)src[2]&15
327  || dstStride[0]&15 || dstStride[1]&15 || dstStride[2]&15 || dstStride[3]&15
328  || srcStride[0]&15 || srcStride[1]&15 || srcStride[2]&15 || srcStride[3]&15
329  ) {
330  static int warnedAlready=0;
331  int cpu_flags = av_get_cpu_flags();
332  if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){
333  av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speed loss\n");
334  warnedAlready=1;
335  }
336  }
337 
338  /* Note the user might start scaling the picture in the middle so this
339  * will not get executed. This is not really intended but works
340  * currently, so people might do it. */
341  if (srcSliceY == 0) {
342  lumBufIndex = -1;
343  chrBufIndex = -1;
344  dstY = 0;
345  lastInLumBuf = -1;
346  lastInChrBuf = -1;
347  }
348 
349  if (!should_dither) {
350  c->chrDither8 = c->lumDither8 = sws_pb_64;
351  }
352  lastDstY = dstY;
353 
354  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
355  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, c->use_mmx_vfilter);
356 
357  ff_init_slice_from_src(src_slice, (uint8_t**)src, srcStride, c->srcW,
358  srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
359 
360  ff_init_slice_from_src(vout_slice, (uint8_t**)dst, dstStride, c->dstW,
361  dstY, dstH, dstY >> c->chrDstVSubSample,
362  AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample), 0);
363  if (srcSliceY == 0) {
364  hout_slice->plane[0].sliceY = lastInLumBuf + 1;
365  hout_slice->plane[1].sliceY = lastInChrBuf + 1;
366  hout_slice->plane[2].sliceY = lastInChrBuf + 1;
367  hout_slice->plane[3].sliceY = lastInLumBuf + 1;
368 
369  hout_slice->plane[0].sliceH =
370  hout_slice->plane[1].sliceH =
371  hout_slice->plane[2].sliceH =
372  hout_slice->plane[3].sliceH = 0;
373  hout_slice->width = dstW;
374  }
375 
376  for (; dstY < dstH; dstY++) {
377  const int chrDstY = dstY >> c->chrDstVSubSample;
378  int use_mmx_vfilter= c->use_mmx_vfilter;
379 
380  // First line needed as input
381  const int firstLumSrcY = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
382  const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), dstH - 1)]);
383  // First line needed as input
384  const int firstChrSrcY = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
385 
386  // Last line needed as input
387  int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
388  int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
389  int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
390  int enough_lines;
391 
392  int i;
393  int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;
394 
395  // handle holes (FAST_BILINEAR & weird filters)
396  if (firstLumSrcY > lastInLumBuf) {
397 
398  hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
399  if (hasLumHoles) {
400  hout_slice->plane[0].sliceY = firstLumSrcY;
401  hout_slice->plane[3].sliceY = firstLumSrcY;
402  hout_slice->plane[0].sliceH =
403  hout_slice->plane[3].sliceH = 0;
404  }
405 
406  lastInLumBuf = firstLumSrcY - 1;
407  }
408  if (firstChrSrcY > lastInChrBuf) {
409 
410  hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
411  if (hasChrHoles) {
412  hout_slice->plane[1].sliceY = firstChrSrcY;
413  hout_slice->plane[2].sliceY = firstChrSrcY;
414  hout_slice->plane[1].sliceH =
415  hout_slice->plane[2].sliceH = 0;
416  }
417 
418  lastInChrBuf = firstChrSrcY - 1;
419  }
420 
421  DEBUG_BUFFERS("dstY: %d\n", dstY);
422  DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
423  firstLumSrcY, lastLumSrcY, lastInLumBuf);
424  DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
425  firstChrSrcY, lastChrSrcY, lastInChrBuf);
426 
427  // Do we have enough lines in this slice to output the dstY line
428  enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
429  lastChrSrcY < AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample);
430 
431  if (!enough_lines) {
432  lastLumSrcY = srcSliceY + srcSliceH - 1;
433  lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
434  DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
435  lastLumSrcY, lastChrSrcY);
436  }
437 
438  av_assert0((lastLumSrcY - firstLumSrcY + 1) <= hout_slice->plane[0].available_lines);
439  av_assert0((lastChrSrcY - firstChrSrcY + 1) <= hout_slice->plane[1].available_lines);
440 
441 
442  posY = hout_slice->plane[0].sliceY + hout_slice->plane[0].sliceH;
443  if (posY <= lastLumSrcY && !hasLumHoles) {
444  firstPosY = FFMAX(firstLumSrcY, posY);
445  lastPosY = FFMIN(firstLumSrcY + hout_slice->plane[0].available_lines - 1, srcSliceY + srcSliceH - 1);
446  } else {
447  firstPosY = posY;
448  lastPosY = lastLumSrcY;
449  }
450 
451  cPosY = hout_slice->plane[1].sliceY + hout_slice->plane[1].sliceH;
452  if (cPosY <= lastChrSrcY && !hasChrHoles) {
453  firstCPosY = FFMAX(firstChrSrcY, cPosY);
454  lastCPosY = FFMIN(firstChrSrcY + hout_slice->plane[1].available_lines - 1, AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample) - 1);
455  } else {
456  firstCPosY = cPosY;
457  lastCPosY = lastChrSrcY;
458  }
459 
460  ff_rotate_slice(hout_slice, lastPosY, lastCPosY);
461 
462  if (posY < lastLumSrcY + 1) {
463  for (i = lumStart; i < lumEnd; ++i)
464  desc[i].process(c, &desc[i], firstPosY, lastPosY - firstPosY + 1);
465  }
466 
467  lumBufIndex += lastLumSrcY - lastInLumBuf;
468  lastInLumBuf = lastLumSrcY;
469 
470  if (cPosY < lastChrSrcY + 1) {
471  for (i = chrStart; i < chrEnd; ++i)
472  desc[i].process(c, &desc[i], firstCPosY, lastCPosY - firstCPosY + 1);
473  }
474 
475  chrBufIndex += lastChrSrcY - lastInChrBuf;
476  lastInChrBuf = lastChrSrcY;
477 
478  // wrap buf index around to stay inside the ring buffer
479  if (lumBufIndex >= vLumFilterSize)
480  lumBufIndex -= vLumFilterSize;
481  if (chrBufIndex >= vChrFilterSize)
482  chrBufIndex -= vChrFilterSize;
483  if (!enough_lines)
484  break; // we can't output a dstY line so let's try with the next slice
485 
486 #if HAVE_MMX_INLINE
487  ff_updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex,
488  lastInLumBuf, lastInChrBuf);
489 #endif
490  if (should_dither) {
491  c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
492  c->lumDither8 = ff_dither_8x8_128[dstY & 7];
493  }
494  if (dstY >= dstH - 2) {
495  /* hmm looks like we can't use MMX here without overwriting
496  * this array's tail */
497  ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
498  &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
499  use_mmx_vfilter= 0;
500  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
501  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
502  }
503 
504  {
505  for (i = vStart; i < vEnd; ++i)
506  desc[i].process(c, &desc[i], dstY, 1);
507  }
508  }
509  if (isPlanar(dstFormat) && isALPHA(dstFormat) && !needAlpha) {
510  int length = dstW;
511  int height = dstY - lastDstY;
512 
513  if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
514  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
515  fillPlane16(dst[3], dstStride[3], length, height, lastDstY,
516  1, desc->comp[3].depth,
517  isBE(dstFormat));
518  } else
519  fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255);
520  }
521 
522 #if HAVE_MMXEXT_INLINE
524  __asm__ volatile ("sfence" ::: "memory");
525 #endif
526  emms_c();
527 
528  /* store changed local vars back in the context */
529  c->dstY = dstY;
530  c->lumBufIndex = lumBufIndex;
531  c->chrBufIndex = chrBufIndex;
532  c->lastInLumBuf = lastInLumBuf;
533  c->lastInChrBuf = lastInChrBuf;
534 
535  return dstY - lastDstY;
536 }
537 
539 {
540  c->lumConvertRange = NULL;
541  c->chrConvertRange = NULL;
542  if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
543  if (c->dstBpc <= 14) {
544  if (c->srcRange) {
547  } else {
550  }
551  } else {
552  if (c->srcRange) {
555  } else {
558  }
559  }
560  }
561 }
562 
564 {
565  enum AVPixelFormat srcFormat = c->srcFormat;
566 
568  &c->yuv2nv12cX, &c->yuv2packed1,
569  &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
570 
572 
573 
574  if (c->srcBpc == 8) {
575  if (c->dstBpc <= 14) {
576  c->hyScale = c->hcScale = hScale8To15_c;
577  if (c->flags & SWS_FAST_BILINEAR) {
580  }
581  } else {
582  c->hyScale = c->hcScale = hScale8To19_c;
583  }
584  } else {
585  c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
586  : hScale16To15_c;
587  }
588 
590 
591  if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
592  srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE))
593  c->needs_hcscale = 1;
594 }
595 
597 {
598  sws_init_swscale(c);
599 
600  if (ARCH_PPC)
602  if (ARCH_X86)
604  if (ARCH_AARCH64)
606  if (ARCH_ARM)
608 
609  return swscale;
610 }
611 
612 static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
613 {
614  if (!isALPHA(format))
615  src[3] = NULL;
616  if (!isPlanar(format)) {
617  src[3] = src[2] = NULL;
618 
619  if (!usePal(format))
620  src[1] = NULL;
621  }
622 }
623 
624 static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
625  const int linesizes[4])
626 {
627  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
628  int i;
629 
630  av_assert2(desc);
631 
632  for (i = 0; i < 4; i++) {
633  int plane = desc->comp[i].plane;
634  if (!data[plane] || !linesizes[plane])
635  return 0;
636  }
637 
638  return 1;
639 }
640 
641 static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
642  const uint16_t *src, int stride, int h)
643 {
644  int xp,yp;
646 
647  for (yp=0; yp<h; yp++) {
648  for (xp=0; xp+2<stride; xp+=3) {
649  int x, y, z, r, g, b;
650 
651  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
652  x = AV_RB16(src + xp + 0);
653  y = AV_RB16(src + xp + 1);
654  z = AV_RB16(src + xp + 2);
655  } else {
656  x = AV_RL16(src + xp + 0);
657  y = AV_RL16(src + xp + 1);
658  z = AV_RL16(src + xp + 2);
659  }
660 
661  x = c->xyzgamma[x>>4];
662  y = c->xyzgamma[y>>4];
663  z = c->xyzgamma[z>>4];
664 
665  // convert from XYZlinear to sRGBlinear
666  r = c->xyz2rgb_matrix[0][0] * x +
667  c->xyz2rgb_matrix[0][1] * y +
668  c->xyz2rgb_matrix[0][2] * z >> 12;
669  g = c->xyz2rgb_matrix[1][0] * x +
670  c->xyz2rgb_matrix[1][1] * y +
671  c->xyz2rgb_matrix[1][2] * z >> 12;
672  b = c->xyz2rgb_matrix[2][0] * x +
673  c->xyz2rgb_matrix[2][1] * y +
674  c->xyz2rgb_matrix[2][2] * z >> 12;
675 
676  // limit values to 12-bit depth
677  r = av_clip_uintp2(r, 12);
678  g = av_clip_uintp2(g, 12);
679  b = av_clip_uintp2(b, 12);
680 
681  // convert from sRGBlinear to RGB and scale from 12bit to 16bit
682  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
683  AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
684  AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
685  AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
686  } else {
687  AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
688  AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
689  AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
690  }
691  }
692  src += stride;
693  dst += stride;
694  }
695 }
696 
697 static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst,
698  const uint16_t *src, int stride, int h)
699 {
700  int xp,yp;
702 
703  for (yp=0; yp<h; yp++) {
704  for (xp=0; xp+2<stride; xp+=3) {
705  int x, y, z, r, g, b;
706 
707  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
708  r = AV_RB16(src + xp + 0);
709  g = AV_RB16(src + xp + 1);
710  b = AV_RB16(src + xp + 2);
711  } else {
712  r = AV_RL16(src + xp + 0);
713  g = AV_RL16(src + xp + 1);
714  b = AV_RL16(src + xp + 2);
715  }
716 
717  r = c->rgbgammainv[r>>4];
718  g = c->rgbgammainv[g>>4];
719  b = c->rgbgammainv[b>>4];
720 
721  // convert from sRGBlinear to XYZlinear
722  x = c->rgb2xyz_matrix[0][0] * r +
723  c->rgb2xyz_matrix[0][1] * g +
724  c->rgb2xyz_matrix[0][2] * b >> 12;
725  y = c->rgb2xyz_matrix[1][0] * r +
726  c->rgb2xyz_matrix[1][1] * g +
727  c->rgb2xyz_matrix[1][2] * b >> 12;
728  z = c->rgb2xyz_matrix[2][0] * r +
729  c->rgb2xyz_matrix[2][1] * g +
730  c->rgb2xyz_matrix[2][2] * b >> 12;
731 
732  // limit values to 12-bit depth
733  x = av_clip_uintp2(x, 12);
734  y = av_clip_uintp2(y, 12);
735  z = av_clip_uintp2(z, 12);
736 
737  // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
738  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
739  AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4);
740  AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4);
741  AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4);
742  } else {
743  AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4);
744  AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4);
745  AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 4);
746  }
747  }
748  src += stride;
749  dst += stride;
750  }
751 }
752 
753 /**
754  * swscale wrapper, so we don't need to export the SwsContext.
755  * Assumes planar YUV to be in YUV order instead of YVU.
756  */
757 int attribute_align_arg sws_scale(struct SwsContext *c,
758  const uint8_t * const srcSlice[],
759  const int srcStride[], int srcSliceY,
760  int srcSliceH, uint8_t *const dst[],
761  const int dstStride[])
762 {
763  int i, ret;
764  const uint8_t *src2[4];
765  uint8_t *dst2[4];
766  uint8_t *rgb0_tmp = NULL;
767  int macro_height = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
768  // copy strides, so they can safely be modified
769  int srcStride2[4];
770  int dstStride2[4];
771  int srcSliceY_internal = srcSliceY;
772 
773  if (!srcStride || !dstStride || !dst || !srcSlice) {
774  av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
775  return 0;
776  }
777 
778  for (i=0; i<4; i++) {
779  srcStride2[i] = srcStride[i];
780  dstStride2[i] = dstStride[i];
781  }
782 
783  if ((srcSliceY & (macro_height-1)) ||
784  ((srcSliceH& (macro_height-1)) && srcSliceY + srcSliceH != c->srcH) ||
785  srcSliceY + srcSliceH > c->srcH) {
786  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH);
787  return AVERROR(EINVAL);
788  }
789 
790  if (c->gamma_flag && c->cascaded_context[0]) {
791 
792 
793  ret = sws_scale(c->cascaded_context[0],
794  srcSlice, srcStride, srcSliceY, srcSliceH,
796 
797  if (ret < 0)
798  return ret;
799 
800  if (c->cascaded_context[2])
801  ret = sws_scale(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp, c->cascaded_tmpStride, srcSliceY, srcSliceH, c->cascaded1_tmp, c->cascaded1_tmpStride);
802  else
803  ret = sws_scale(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp, c->cascaded_tmpStride, srcSliceY, srcSliceH, dst, dstStride);
804 
805  if (ret < 0)
806  return ret;
807 
808  if (c->cascaded_context[2]) {
809  ret = sws_scale(c->cascaded_context[2],
810  (const uint8_t * const *)c->cascaded1_tmp, c->cascaded1_tmpStride, c->cascaded_context[1]->dstY - ret, c->cascaded_context[1]->dstY,
811  dst, dstStride);
812  }
813  return ret;
814  }
815 
816  if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH) {
817  ret = sws_scale(c->cascaded_context[0],
818  srcSlice, srcStride, srcSliceY, srcSliceH,
820  if (ret < 0)
821  return ret;
822  ret = sws_scale(c->cascaded_context[1],
823  (const uint8_t * const * )c->cascaded_tmp, c->cascaded_tmpStride, 0, c->cascaded_context[0]->dstH,
824  dst, dstStride);
825  return ret;
826  }
827 
828  memcpy(src2, srcSlice, sizeof(src2));
829  memcpy(dst2, dst, sizeof(dst2));
830 
831  // do not mess up sliceDir if we have a "trailing" 0-size slice
832  if (srcSliceH == 0)
833  return 0;
834 
835  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
836  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
837  return 0;
838  }
839  if (!check_image_pointers((const uint8_t* const*)dst, c->dstFormat, dstStride)) {
840  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
841  return 0;
842  }
843 
844  if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
845  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
846  return 0;
847  }
848  if (c->sliceDir == 0) {
849  if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
850  }
851 
852  if (usePal(c->srcFormat)) {
853  for (i = 0; i < 256; i++) {
854  int r, g, b, y, u, v, a = 0xff;
855  if (c->srcFormat == AV_PIX_FMT_PAL8) {
856  uint32_t p = ((const uint32_t *)(srcSlice[1]))[i];
857  a = (p >> 24) & 0xFF;
858  r = (p >> 16) & 0xFF;
859  g = (p >> 8) & 0xFF;
860  b = p & 0xFF;
861  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
862  r = ( i >> 5 ) * 36;
863  g = ((i >> 2) & 7) * 36;
864  b = ( i & 3) * 85;
865  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
866  b = ( i >> 6 ) * 85;
867  g = ((i >> 3) & 7) * 36;
868  r = ( i & 7) * 36;
869  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
870  r = ( i >> 3 ) * 255;
871  g = ((i >> 1) & 3) * 85;
872  b = ( i & 1) * 255;
873  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
874  r = g = b = i;
875  } else {
877  b = ( i >> 3 ) * 255;
878  g = ((i >> 1) & 3) * 85;
879  r = ( i & 1) * 255;
880  }
881 #define RGB2YUV_SHIFT 15
882 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
883 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
884 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
885 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
886 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
887 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
888 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
889 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
890 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
891 
892  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
893  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
894  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
895  c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
896 
897  switch (c->dstFormat) {
898  case AV_PIX_FMT_BGR32:
899 #if !HAVE_BIGENDIAN
900  case AV_PIX_FMT_RGB24:
901 #endif
902  c->pal_rgb[i]= r + (g<<8) + (b<<16) + ((unsigned)a<<24);
903  break;
904  case AV_PIX_FMT_BGR32_1:
905 #if HAVE_BIGENDIAN
906  case AV_PIX_FMT_BGR24:
907 #endif
908  c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24);
909  break;
910  case AV_PIX_FMT_RGB32_1:
911 #if HAVE_BIGENDIAN
912  case AV_PIX_FMT_RGB24:
913 #endif
914  c->pal_rgb[i]= a + (b<<8) + (g<<16) + ((unsigned)r<<24);
915  break;
916  case AV_PIX_FMT_RGB32:
917 #if !HAVE_BIGENDIAN
918  case AV_PIX_FMT_BGR24:
919 #endif
920  default:
921  c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24);
922  }
923  }
924  }
925 
926  if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
927  uint8_t *base;
928  int x,y;
929  rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
930  if (!rgb0_tmp)
931  return AVERROR(ENOMEM);
932 
933  base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
934  for (y=0; y<srcSliceH; y++){
935  memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
936  for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
937  base[ srcStride[0]*y + x] = 0xFF;
938  }
939  }
940  src2[0] = base;
941  }
942 
943  if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
944  uint8_t *base;
945  rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
946  if (!rgb0_tmp)
947  return AVERROR(ENOMEM);
948 
949  base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
950 
951  xyz12Torgb48(c, (uint16_t*)base, (const uint16_t*)src2[0], srcStride[0]/2, srcSliceH);
952  src2[0] = base;
953  }
954 
955  if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
956  for (i = 0; i < 4; i++)
957  memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
958 
959  if (c->sliceDir != 1) {
960  // slices go from bottom to top => we flip the image internally
961  for (i=0; i<4; i++) {
962  srcStride2[i] *= -1;
963  dstStride2[i] *= -1;
964  }
965 
966  src2[0] += (srcSliceH - 1) * srcStride[0];
967  if (!usePal(c->srcFormat))
968  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
969  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
970  src2[3] += (srcSliceH - 1) * srcStride[3];
971  dst2[0] += ( c->dstH - 1) * dstStride[0];
972  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
973  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
974  dst2[3] += ( c->dstH - 1) * dstStride[3];
975 
976  srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
977  }
978  reset_ptr(src2, c->srcFormat);
979  reset_ptr((void*)dst2, c->dstFormat);
980 
981  /* reset slice direction at end of frame */
982  if (srcSliceY_internal + srcSliceH == c->srcH)
983  c->sliceDir = 0;
984  ret = c->swscale(c, src2, srcStride2, srcSliceY_internal, srcSliceH, dst2, dstStride2);
985 
986 
987  if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
988  int dstY = c->dstY ? c->dstY : srcSliceY + srcSliceH;
989  uint16_t *dst16 = (uint16_t*)(dst2[0] + (dstY - ret) * dstStride2[0]);
990  av_assert0(dstY >= ret);
991  av_assert0(ret >= 0);
992  av_assert0(c->dstH >= dstY);
993 
994  /* replace on the same data */
995  rgb48Toxyz12(c, dst16, dst16, dstStride2[0]/2, ret);
996  }
997 
998  av_free(rgb0_tmp);
999  return ret;
1000 }
int plane
Definition: avisynth_c.h:384
#define BU
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:35
#define NULL
Definition: coverity.c:32
void(* hcScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
const char const char void * val
Definition: avisynth_c.h:863
int chrBufIndex
Index in ring buffer of the last scaled horizontal chroma line from source.
static void lumRangeToJpeg_c(int16_t *dst, int width)
Definition: swscale.c:178
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
av_cold 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)
Definition: output.c:2454
static enum AVPixelFormat pix_fmt
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:169
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
int chrSrcH
Height of source chroma planes.
void(* chrConvertRange)(int16_t *dst1, int16_t *dst2, int width)
Color range conversion function for chroma planes if needed.
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
Definition: swscale.c:612
uint32_t pal_rgb[256]
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int16_t * rgbgamma
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
#define GU
const char * g
Definition: vf_curves.c:115
const char * desc
Definition: nvenc.c:68
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:147
int vChrDrop
Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user...
static void lumRangeToJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:214
Struct which holds all necessary data for processing a slice.
int16_t * rgbgammainv
#define RU
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
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:36
Convenience header that includes libavutil&#39;s core.
int16_t * xyzgammainv
void(* hyScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Scale one horizontal line of input data using a filter over the input lines, to produce one (differen...
static atomic_int cpu_flags
Definition: cpu.c:50
int srcRange
0 = MPG YUV range, 1 = JPG YUV range (source image).
const uint8_t * lumDither8
#define BY
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:87
void(* hyscale_fast)(struct SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
Scale one horizontal line of input data using a bilinear filter to produce one line of output data...
#define src
Definition: vp8dsp.c:254
#define SWS_PRINT_INFO
Definition: swscale.h:75
int dstY
Last destination vertical line output from last slice.
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
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
void ff_sws_init_input_funcs(SwsContext *c)
uint8_t base
Definition: vp3data.h:202
int srcH
Height of source luma/alpha planes.
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
static int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
Definition: soxr_resample.c:84
static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:697
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:66
int ff_rotate_slice(SwsSlice *s, int lum, int chr)
Definition: slice.c:119
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int chrDstVSubSample
Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in destination i...
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
static void lumRangeFromJpeg_c(int16_t *dst, int width)
Definition: swscale.c:185
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
int vChrFilterSize
Vertical filter size for chroma pixels.
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:188
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
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:32
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
int cascaded_tmpStride[4]
av_cold void ff_sws_init_swscale_x86(SwsContext *c)
Definition: swscale.c:384
#define SWS_FAST_BILINEAR
Definition: swscale.h:58
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Definition: mem.h:112
#define height
int lastInLumBuf
Last scaled horizontal luma/alpha line from source in the ring buffer.
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 (...
int16_t rgb2xyz_matrix[3][4]
external API header
enum AVPixelFormat dstFormat
Destination pixel format.
#define BV
#define isALPHA(x)
Definition: swscale.c:51
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
#define av_log(a,...)
yuv2packedX_fn yuv2packedX
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:250
av_cold void ff_sws_init_swscale_aarch64(SwsContext *c)
Definition: swscale.c:32
int32_t * vChrFilterPos
Array of vertical filter starting positions for each dst[i] for chroma planes.
#define DEBUG_BUFFERS(...)
Definition: swscale.c:233
int dstH
Height of destination luma/alpha planes.
int * dither_error[4]
#define U(x)
Definition: vp56_arith.h:37
yuv2anyX_fn yuv2anyX
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:363
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
SwsFunc ff_getSwsFunc(SwsContext *c)
Return function pointer to fastest main scaler path function depending on architecture and available ...
Definition: swscale.c:596
#define RV
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:160
const char * r
Definition: vf_curves.c:114
yuv2packed1_fn yuv2packed1
simple assert() macros that are a bit more flexible than ISO C assert().
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:96
GLsizei GLsizei * length
Definition: opengl_enc.c:114
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)
uint8_t bits
Definition: vp3data.h:202
void(* hcscale_fast)(struct SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
#define FFMAX(a, b)
Definition: common.h:94
static int check_image_pointers(const uint8_t *const data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
Definition: swscale.c:624
uint8_t * cascaded1_tmp[4]
static av_cold void sws_init_swscale(SwsContext *c)
Definition: swscale.c:563
SwsPlane plane[MAX_SLICE_PLANES]
color planes
int sliceH
number of lines
int16_t * xyzgamma
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:641
av_cold void ff_sws_init_swscale_ppc(SwsContext *c)
int dstRange
0 = MPG YUV range, 1 = JPG YUV range (destination image).
#define RGB2YUV_SHIFT
#define b
Definition: input.c:41
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:146
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
#define FFMIN(a, b)
Definition: common.h:96
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
#define RY
#define width
yuv2planar1_fn yuv2plane1
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
yuv2interleavedX_fn yuv2nv12cX
int32_t
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
int available_lines
max number of lines that can be hold by this plane
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
av_cold void ff_sws_init_range_convert(SwsContext *c)
Definition: swscale.c:538
struct SwsFilterDescriptor * desc
void(* lumConvertRange)(int16_t *dst, int width)
Color range conversion function for luma plane if needed.
int dstW
Width of destination luma/alpha planes.
uint8_t * cascaded_tmp[4]
int sliceDir
Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).
int(* SwsFunc)(struct SwsContext *context, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
int cascaded1_tmpStride[4]
int needs_hcscale
Set if there are chroma planes to be converted.
int32_t * vLumFilterPos
Array of vertical filter starting positions for each dst[i] for luma/alpha planes.
#define isGray(x)
Definition: swscale.c:40
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:362
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
int width
Slice line width.
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...
int16_t xyz2rgb_matrix[3][4]
static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
yuv2planarX_fn yuv2planeX
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:360
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...
const uint8_t ff_dither_8x8_128[9][8]
Definition: swscale.c:39
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
struct SwsSlice * slice
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&#39;t need to export the SwsContext.
Definition: swscale.c:757
static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
Definition: swscale.c:55
static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:223
void ff_hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
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...
int vLumFilterSize
Vertical filter size for luma/alpha pixels.
byte swapping routines
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:93
static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian)
const uint8_t * chrDither8
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:192
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define SWS_BITEXACT
Definition: swscale.h:84
int lumBufIndex
Index in ring buffer of the last scaled horizontal luma/alpha line from source.
static int swscale(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
Definition: swscale.c:237
SwsDither dither
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:76
int lastInChrBuf
Last scaled horizontal chroma line from source in the ring buffer.
int
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
yuv2packed2_fn yuv2packed2
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)
Y , 8bpp.
Definition: pixfmt.h:74
#define GY
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:75
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
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...
enum AVPixelFormat srcFormat
Source pixel format.
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
struct SwsContext * cascaded_context[3]
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:128
SwsFunc swscale
Note that src, dst, srcStride, dstStride will be copied in the sws_scale() wrapper so they can be fre...
#define GV
#define av_free(p)
void ff_updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, int lastInLumBuf, int lastInChrBuf)
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:361
void(* yuv2interleavedX_fn)(struct SwsContext *c, 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 ...
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...
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:203
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:36
static const uint8_t sws_pb_64[8]
Definition: swscale.c:51
#define av_always_inline
Definition: attributes.h:39
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
#define stride
static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
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:125
int sliceY
index of first line
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
int srcW
Width of source luma/alpha planes.
int chrSrcVSubSample
Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in source image...
int flags
Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
uint32_t pal_yuv[256]
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
av_cold void ff_sws_init_swscale_arm(SwsContext *c)
Definition: swscale.c:32
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
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:141