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 <assert.h>
22 #include <inttypes.h>
23 #include <math.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "libavutil/avassert.h"
28 #include "libavutil/avutil.h"
29 #include "libavutil/bswap.h"
30 #include "libavutil/cpu.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 
39 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
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 };
49 
50 DECLARE_ALIGNED(8, const uint8_t, ff_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 {
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_minus1;
74  int sh = bits - 4;
75 
76  if((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth_minus1<15)
77  sh= 9;
78 
79  for (i = 0; i < dstW; i++) {
80  int j;
81  int srcPos = filterPos[i];
82  int val = 0;
83 
84  for (j = 0; j < filterSize; j++) {
85  val += src[srcPos + j] * filter[filterSize * i + j];
86  }
87  // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit
88  dst[i] = FFMIN(val >> sh, (1 << 19) - 1);
89  }
90 }
91 
92 static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW,
93  const uint8_t *_src, const int16_t *filter,
94  const int32_t *filterPos, int filterSize)
95 {
97  int i;
98  const uint16_t *src = (const uint16_t *) _src;
99  int sh = desc->comp[0].depth_minus1;
100 
101  if(sh<15)
102  sh= isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : desc->comp[0].depth_minus1;
103 
104  for (i = 0; i < dstW; i++) {
105  int j;
106  int srcPos = filterPos[i];
107  int val = 0;
108 
109  for (j = 0; j < filterSize; j++) {
110  val += src[srcPos + j] * filter[filterSize * i + j];
111  }
112  // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit
113  dst[i] = FFMIN(val >> sh, (1 << 15) - 1);
114  }
115 }
116 
117 // bilinear / bicubic scaling
118 static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW,
119  const uint8_t *src, const int16_t *filter,
120  const int32_t *filterPos, int filterSize)
121 {
122  int i;
123  for (i = 0; i < dstW; i++) {
124  int j;
125  int srcPos = filterPos[i];
126  int val = 0;
127  for (j = 0; j < filterSize; j++) {
128  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
129  }
130  dst[i] = FFMIN(val >> 7, (1 << 15) - 1); // the cubic equation does overflow ...
131  }
132 }
133 
134 static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW,
135  const uint8_t *src, const int16_t *filter,
136  const int32_t *filterPos, int filterSize)
137 {
138  int i;
139  int32_t *dst = (int32_t *) _dst;
140  for (i = 0; i < dstW; i++) {
141  int j;
142  int srcPos = filterPos[i];
143  int val = 0;
144  for (j = 0; j < filterSize; j++) {
145  val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
146  }
147  dst[i] = FFMIN(val >> 3, (1 << 19) - 1); // the cubic equation does overflow ...
148  }
149 }
150 
151 // FIXME all pal and rgb srcFormats could do this conversion as well
152 // FIXME all scalers more complex than bilinear could do half of this transform
153 static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
154 {
155  int i;
156  for (i = 0; i < width; i++) {
157  dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
158  dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
159  }
160 }
161 
162 static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
163 {
164  int i;
165  for (i = 0; i < width; i++) {
166  dstU[i] = (dstU[i] * 1799 + 4081085) >> 11; // 1469
167  dstV[i] = (dstV[i] * 1799 + 4081085) >> 11; // 1469
168  }
169 }
170 
171 static void lumRangeToJpeg_c(int16_t *dst, int width)
172 {
173  int i;
174  for (i = 0; i < width; i++)
175  dst[i] = (FFMIN(dst[i], 30189) * 19077 - 39057361) >> 14;
176 }
177 
178 static void lumRangeFromJpeg_c(int16_t *dst, int width)
179 {
180  int i;
181  for (i = 0; i < width; i++)
182  dst[i] = (dst[i] * 14071 + 33561947) >> 14;
183 }
184 
185 static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
186 {
187  int i;
188  int32_t *dstU = (int32_t *) _dstU;
189  int32_t *dstV = (int32_t *) _dstV;
190  for (i = 0; i < width; i++) {
191  dstU[i] = (FFMIN(dstU[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
192  dstV[i] = (FFMIN(dstV[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
193  }
194 }
195 
196 static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
197 {
198  int i;
199  int32_t *dstU = (int32_t *) _dstU;
200  int32_t *dstV = (int32_t *) _dstV;
201  for (i = 0; i < width; i++) {
202  dstU[i] = (dstU[i] * 1799 + (4081085 << 4)) >> 11; // 1469
203  dstV[i] = (dstV[i] * 1799 + (4081085 << 4)) >> 11; // 1469
204  }
205 }
206 
207 static void lumRangeToJpeg16_c(int16_t *_dst, int width)
208 {
209  int i;
210  int32_t *dst = (int32_t *) _dst;
211  for (i = 0; i < width; i++)
212  dst[i] = (FFMIN(dst[i], 30189 << 4) * 4769 - (39057361 << 2)) >> 12;
213 }
214 
215 static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
216 {
217  int i;
218  int32_t *dst = (int32_t *) _dst;
219  for (i = 0; i < width; i++)
220  dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
221 }
222 
223 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
224  const uint8_t *src, int srcW, int xInc)
225 {
226  int i;
227  unsigned int xpos = 0;
228  for (i = 0; i < dstWidth; i++) {
229  register unsigned int xx = xpos >> 16;
230  register unsigned int xalpha = (xpos & 0xFFFF) >> 9;
231  dst[i] = (src[xx] << 7) + (src[xx + 1] - src[xx]) * xalpha;
232  xpos += xInc;
233  }
234  for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
235  dst[i] = src[srcW-1]*128;
236 }
237 
238 // *** horizontal scale Y line to temp buffer
239 static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth,
240  const uint8_t *src_in[4],
241  int srcW, int xInc,
242  const int16_t *hLumFilter,
243  const int32_t *hLumFilterPos,
244  int hLumFilterSize,
246  uint32_t *pal, int isAlpha)
247 {
248  void (*toYV12)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, int, uint32_t *) =
249  isAlpha ? c->alpToYV12 : c->lumToYV12;
250  void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
251  const uint8_t *src = src_in[isAlpha ? 3 : 0];
252 
253  if (toYV12) {
254  toYV12(formatConvBuffer, src, src_in[1], src_in[2], srcW, pal);
256  } else if (c->readLumPlanar && !isAlpha) {
257  c->readLumPlanar(formatConvBuffer, src_in, srcW, c->input_rgb2yuv_table);
259  }
260 
261  if (!c->hyscale_fast) {
262  c->hyScale(c, dst, dstWidth, src, hLumFilter,
263  hLumFilterPos, hLumFilterSize);
264  } else { // fast bilinear upscale / crap downscale
265  c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
266  }
267 
268  if (convertRange)
269  convertRange(dst, dstWidth);
270 }
271 
272 static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
273  int dstWidth, const uint8_t *src1,
274  const uint8_t *src2, int srcW, int xInc)
275 {
276  int i;
277  unsigned int xpos = 0;
278  for (i = 0; i < dstWidth; i++) {
279  register unsigned int xx = xpos >> 16;
280  register unsigned int xalpha = (xpos & 0xFFFF) >> 9;
281  dst1[i] = (src1[xx] * (xalpha ^ 127) + src1[xx + 1] * xalpha);
282  dst2[i] = (src2[xx] * (xalpha ^ 127) + src2[xx + 1] * xalpha);
283  xpos += xInc;
284  }
285  for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
286  dst1[i] = src1[srcW-1]*128;
287  dst2[i] = src2[srcW-1]*128;
288  }
289 }
290 
291 static av_always_inline void hcscale(SwsContext *c, int16_t *dst1,
292  int16_t *dst2, int dstWidth,
293  const uint8_t *src_in[4],
294  int srcW, int xInc,
295  const int16_t *hChrFilter,
296  const int32_t *hChrFilterPos,
297  int hChrFilterSize,
298  uint8_t *formatConvBuffer, uint32_t *pal)
299 {
300  const uint8_t *src1 = src_in[1], *src2 = src_in[2];
301  if (c->chrToYV12) {
302  uint8_t *buf2 = formatConvBuffer +
303  FFALIGN(srcW*2+78, 16);
304  c->chrToYV12(formatConvBuffer, buf2, src_in[0], src1, src2, srcW, pal);
305  src1= formatConvBuffer;
306  src2= buf2;
307  } else if (c->readChrPlanar) {
308  uint8_t *buf2 = formatConvBuffer +
309  FFALIGN(srcW*2+78, 16);
310  c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW, c->input_rgb2yuv_table);
311  src1 = formatConvBuffer;
312  src2 = buf2;
313  }
314 
315  if (!c->hcscale_fast) {
316  c->hcScale(c, dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
317  c->hcScale(c, dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
318  } else { // fast bilinear upscale / crap downscale
319  c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
320  }
321 
322  if (c->chrConvertRange)
323  c->chrConvertRange(dst1, dst2, dstWidth);
324 }
325 
326 #define DEBUG_SWSCALE_BUFFERS 0
327 #define DEBUG_BUFFERS(...) \
328  if (DEBUG_SWSCALE_BUFFERS) \
329  av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
330 
331 static int swScale(SwsContext *c, const uint8_t *src[],
332  int srcStride[], int srcSliceY,
333  int srcSliceH, uint8_t *dst[], int dstStride[])
334 {
335  /* load a few things into local vars to make the code more readable?
336  * and faster */
337  const int srcW = c->srcW;
338  const int dstW = c->dstW;
339  const int dstH = c->dstH;
340  const int chrDstW = c->chrDstW;
341  const int chrSrcW = c->chrSrcW;
342  const int lumXInc = c->lumXInc;
343  const int chrXInc = c->chrXInc;
344  const enum AVPixelFormat dstFormat = c->dstFormat;
345  const int flags = c->flags;
350  int16_t *hLumFilter = c->hLumFilter;
351  int16_t *hChrFilter = c->hChrFilter;
354  const int vLumFilterSize = c->vLumFilterSize;
355  const int vChrFilterSize = c->vChrFilterSize;
356  const int hLumFilterSize = c->hLumFilterSize;
357  const int hChrFilterSize = c->hChrFilterSize;
358  int16_t **lumPixBuf = c->lumPixBuf;
359  int16_t **chrUPixBuf = c->chrUPixBuf;
360  int16_t **chrVPixBuf = c->chrVPixBuf;
361  int16_t **alpPixBuf = c->alpPixBuf;
362  const int vLumBufSize = c->vLumBufSize;
363  const int vChrBufSize = c->vChrBufSize;
365  uint32_t *pal = c->pal_yuv;
373  const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample;
374  const int chrSrcSliceH = -((-srcSliceH) >> c->chrSrcVSubSample);
375  int should_dither = is9_OR_10BPS(c->srcFormat) ||
376  is16BPS(c->srcFormat);
377  int lastDstY;
378 
379  /* vars which will change and which we need to store back in the context */
380  int dstY = c->dstY;
381  int lumBufIndex = c->lumBufIndex;
382  int chrBufIndex = c->chrBufIndex;
383  int lastInLumBuf = c->lastInLumBuf;
384  int lastInChrBuf = c->lastInChrBuf;
385 
386  if (!usePal(c->srcFormat)) {
387  pal = c->input_rgb2yuv_table;
388  }
389 
390  if (isPacked(c->srcFormat)) {
391  src[0] =
392  src[1] =
393  src[2] =
394  src[3] = src[0];
395  srcStride[0] =
396  srcStride[1] =
397  srcStride[2] =
398  srcStride[3] = srcStride[0];
399  }
400  srcStride[1] <<= c->vChrDrop;
401  srcStride[2] <<= c->vChrDrop;
402 
403  DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
404  src[0], srcStride[0], src[1], srcStride[1],
405  src[2], srcStride[2], src[3], srcStride[3],
406  dst[0], dstStride[0], dst[1], dstStride[1],
407  dst[2], dstStride[2], dst[3], dstStride[3]);
408  DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
409  srcSliceY, srcSliceH, dstY, dstH);
410  DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
411  vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
412 
413  if (dstStride[0]%16 !=0 || dstStride[1]%16 !=0 ||
414  dstStride[2]%16 !=0 || dstStride[3]%16 != 0) {
415  static int warnedAlready = 0; // FIXME maybe move this into the context
416  if (flags & SWS_PRINT_INFO && !warnedAlready) {
418  "Warning: dstStride is not aligned!\n"
419  " ->cannot do aligned memory accesses anymore\n");
420  warnedAlready = 1;
421  }
422  }
423 
424  if ( (uintptr_t)dst[0]%16 || (uintptr_t)dst[1]%16 || (uintptr_t)dst[2]%16
425  || (uintptr_t)src[0]%16 || (uintptr_t)src[1]%16 || (uintptr_t)src[2]%16
426  || dstStride[0]%16 || dstStride[1]%16 || dstStride[2]%16 || dstStride[3]%16
427  || srcStride[0]%16 || srcStride[1]%16 || srcStride[2]%16 || srcStride[3]%16
428  ) {
429  static int warnedAlready=0;
430  int cpu_flags = av_get_cpu_flags();
431  if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){
432  av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speedloss\n");
433  warnedAlready=1;
434  }
435  }
436 
437  /* Note the user might start scaling the picture in the middle so this
438  * will not get executed. This is not really intended but works
439  * currently, so people might do it. */
440  if (srcSliceY == 0) {
441  lumBufIndex = -1;
442  chrBufIndex = -1;
443  dstY = 0;
444  lastInLumBuf = -1;
445  lastInChrBuf = -1;
446  }
447 
448  if (!should_dither) {
449  c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
450  }
451  lastDstY = dstY;
452 
453  for (; dstY < dstH; dstY++) {
454  const int chrDstY = dstY >> c->chrDstVSubSample;
455  uint8_t *dest[4] = {
456  dst[0] + dstStride[0] * dstY,
457  dst[1] + dstStride[1] * chrDstY,
458  dst[2] + dstStride[2] * chrDstY,
459  (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
460  };
462 
463  // First line needed as input
464  const int firstLumSrcY = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
465  const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), dstH - 1)]);
466  // First line needed as input
467  const int firstChrSrcY = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
468 
469  // Last line needed as input
470  int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
471  int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
472  int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
473  int enough_lines;
474 
475  // handle holes (FAST_BILINEAR & weird filters)
476  if (firstLumSrcY > lastInLumBuf)
477  lastInLumBuf = firstLumSrcY - 1;
478  if (firstChrSrcY > lastInChrBuf)
479  lastInChrBuf = firstChrSrcY - 1;
480  av_assert0(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
481  av_assert0(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
482 
483  DEBUG_BUFFERS("dstY: %d\n", dstY);
484  DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
485  firstLumSrcY, lastLumSrcY, lastInLumBuf);
486  DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
487  firstChrSrcY, lastChrSrcY, lastInChrBuf);
488 
489  // Do we have enough lines in this slice to output the dstY line
490  enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
491  lastChrSrcY < -((-srcSliceY - srcSliceH) >> c->chrSrcVSubSample);
492 
493  if (!enough_lines) {
494  lastLumSrcY = srcSliceY + srcSliceH - 1;
495  lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
496  DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
497  lastLumSrcY, lastChrSrcY);
498  }
499 
500  // Do horizontal scaling
501  while (lastInLumBuf < lastLumSrcY) {
502  const uint8_t *src1[4] = {
503  src[0] + (lastInLumBuf + 1 - srcSliceY) * srcStride[0],
504  src[1] + (lastInLumBuf + 1 - srcSliceY) * srcStride[1],
505  src[2] + (lastInLumBuf + 1 - srcSliceY) * srcStride[2],
506  src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3],
507  };
508  lumBufIndex++;
509  av_assert0(lumBufIndex < 2 * vLumBufSize);
510  av_assert0(lastInLumBuf + 1 - srcSliceY < srcSliceH);
511  av_assert0(lastInLumBuf + 1 - srcSliceY >= 0);
512  hyscale(c, lumPixBuf[lumBufIndex], dstW, src1, srcW, lumXInc,
513  hLumFilter, hLumFilterPos, hLumFilterSize,
514  formatConvBuffer, pal, 0);
515  if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
516  hyscale(c, alpPixBuf[lumBufIndex], dstW, src1, srcW,
517  lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
518  formatConvBuffer, pal, 1);
519  lastInLumBuf++;
520  DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
521  lumBufIndex, lastInLumBuf);
522  }
523  while (lastInChrBuf < lastChrSrcY) {
524  const uint8_t *src1[4] = {
525  src[0] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[0],
526  src[1] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[1],
527  src[2] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[2],
528  src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3],
529  };
530  chrBufIndex++;
531  av_assert0(chrBufIndex < 2 * vChrBufSize);
532  av_assert0(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
533  av_assert0(lastInChrBuf + 1 - chrSrcSliceY >= 0);
534  // FIXME replace parameters through context struct (some at least)
535 
536  if (c->needs_hcscale)
537  hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
538  chrDstW, src1, chrSrcW, chrXInc,
539  hChrFilter, hChrFilterPos, hChrFilterSize,
540  formatConvBuffer, pal);
541  lastInChrBuf++;
542  DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
543  chrBufIndex, lastInChrBuf);
544  }
545  // wrap buf index around to stay inside the ring buffer
546  if (lumBufIndex >= vLumBufSize)
547  lumBufIndex -= vLumBufSize;
548  if (chrBufIndex >= vChrBufSize)
549  chrBufIndex -= vChrBufSize;
550  if (!enough_lines)
551  break; // we can't output a dstY line so let's try with the next slice
552 
553 #if HAVE_MMX_INLINE
554  updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex,
555  lastInLumBuf, lastInChrBuf);
556 #endif
557  if (should_dither) {
558  c->chrDither8 = dither_8x8_128[chrDstY & 7];
559  c->lumDither8 = dither_8x8_128[dstY & 7];
560  }
561  if (dstY >= dstH - 2) {
562  /* hmm looks like we can't use MMX here without overwriting
563  * this array's tail */
564  ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
565  &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
566  use_mmx_vfilter= 0;
567  }
568 
569  {
570  const int16_t **lumSrcPtr = (const int16_t **)(void*) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
571  const int16_t **chrUSrcPtr = (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
572  const int16_t **chrVSrcPtr = (const int16_t **)(void*) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
573  const int16_t **alpSrcPtr = (CONFIG_SWSCALE_ALPHA && alpPixBuf) ?
574  (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
575  int16_t *vLumFilter = c->vLumFilter;
576  int16_t *vChrFilter = c->vChrFilter;
577 
578  if (isPlanarYUV(dstFormat) ||
579  (isGray(dstFormat) && !isALPHA(dstFormat))) { // YV12 like
580  const int chrSkipMask = (1 << c->chrDstVSubSample) - 1;
581 
582  vLumFilter += dstY * vLumFilterSize;
583  vChrFilter += chrDstY * vChrFilterSize;
584 
585 // av_assert0(use_mmx_vfilter != (
586 // yuv2planeX == yuv2planeX_10BE_c
587 // || yuv2planeX == yuv2planeX_10LE_c
588 // || yuv2planeX == yuv2planeX_9BE_c
589 // || yuv2planeX == yuv2planeX_9LE_c
590 // || yuv2planeX == yuv2planeX_16BE_c
591 // || yuv2planeX == yuv2planeX_16LE_c
592 // || yuv2planeX == yuv2planeX_8_c) || !ARCH_X86);
593 
594  if(use_mmx_vfilter){
595  vLumFilter= (int16_t *)c->lumMmxFilter;
596  vChrFilter= (int16_t *)c->chrMmxFilter;
597  }
598 
599  if (vLumFilterSize == 1) {
600  yuv2plane1(lumSrcPtr[0], dest[0], dstW, c->lumDither8, 0);
601  } else {
602  yuv2planeX(vLumFilter, vLumFilterSize,
603  lumSrcPtr, dest[0],
604  dstW, c->lumDither8, 0);
605  }
606 
607  if (!((dstY & chrSkipMask) || isGray(dstFormat))) {
608  if (yuv2nv12cX) {
609  yuv2nv12cX(c, vChrFilter,
610  vChrFilterSize, chrUSrcPtr, chrVSrcPtr,
611  dest[1], chrDstW);
612  } else if (vChrFilterSize == 1) {
613  yuv2plane1(chrUSrcPtr[0], dest[1], chrDstW, c->chrDither8, 0);
614  yuv2plane1(chrVSrcPtr[0], dest[2], chrDstW, c->chrDither8, 3);
615  } else {
616  yuv2planeX(vChrFilter,
617  vChrFilterSize, chrUSrcPtr, dest[1],
618  chrDstW, c->chrDither8, 0);
619  yuv2planeX(vChrFilter,
620  vChrFilterSize, chrVSrcPtr, dest[2],
621  chrDstW, c->chrDither8, use_mmx_vfilter ? (c->uv_offx2 >> 1) : 3);
622  }
623  }
624 
625  if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
626  if(use_mmx_vfilter){
627  vLumFilter= (int16_t *)c->alpMmxFilter;
628  }
629  if (vLumFilterSize == 1) {
630  yuv2plane1(alpSrcPtr[0], dest[3], dstW,
631  c->lumDither8, 0);
632  } else {
633  yuv2planeX(vLumFilter,
634  vLumFilterSize, alpSrcPtr, dest[3],
635  dstW, c->lumDither8, 0);
636  }
637  }
638  } else if (yuv2packedX) {
639  av_assert1(lumSrcPtr + vLumFilterSize - 1 < (const int16_t **)lumPixBuf + vLumBufSize * 2);
640  av_assert1(chrUSrcPtr + vChrFilterSize - 1 < (const int16_t **)chrUPixBuf + vChrBufSize * 2);
641  if (c->yuv2packed1 && vLumFilterSize == 1 &&
642  vChrFilterSize <= 2) { // unscaled RGB
643  int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1];
644  yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
645  alpPixBuf ? *alpSrcPtr : NULL,
646  dest[0], dstW, chrAlpha, dstY);
647  } else if (c->yuv2packed2 && vLumFilterSize == 2 &&
648  vChrFilterSize == 2) { // bilinear upscale RGB
649  int lumAlpha = vLumFilter[2 * dstY + 1];
650  int chrAlpha = vChrFilter[2 * dstY + 1];
651  lumMmxFilter[2] =
652  lumMmxFilter[3] = vLumFilter[2 * dstY] * 0x10001;
653  chrMmxFilter[2] =
654  chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
655  yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
656  alpPixBuf ? alpSrcPtr : NULL,
657  dest[0], dstW, lumAlpha, chrAlpha, dstY);
658  } else { // general RGB
659  yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
660  lumSrcPtr, vLumFilterSize,
661  vChrFilter + dstY * vChrFilterSize,
662  chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
663  alpSrcPtr, dest[0], dstW, dstY);
664  }
665  } else {
666  av_assert1(!yuv2packed1 && !yuv2packed2);
667  yuv2anyX(c, vLumFilter + dstY * vLumFilterSize,
668  lumSrcPtr, vLumFilterSize,
669  vChrFilter + dstY * vChrFilterSize,
670  chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
671  alpSrcPtr, dest, dstW, dstY);
672  }
673  }
674  }
675  if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) {
676  int length = dstW;
677  int height = dstY - lastDstY;
678 
679  if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
680  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
681  fillPlane16(dst[3], dstStride[3], length, height, lastDstY,
682  1, desc->comp[3].depth_minus1,
683  isBE(dstFormat));
684  } else
685  fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255);
686  }
687 
688 #if HAVE_MMXEXT_INLINE
690  __asm__ volatile ("sfence" ::: "memory");
691 #endif
692  emms_c();
693 
694  /* store changed local vars back in the context */
695  c->dstY = dstY;
700 
701  return dstY - lastDstY;
702 }
703 
705 {
707 
709  &c->yuv2nv12cX, &c->yuv2packed1,
710  &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
711 
713 
714 
715  if (c->srcBpc == 8) {
716  if (c->dstBpc <= 14) {
717  c->hyScale = c->hcScale = hScale8To15_c;
718  if (c->flags & SWS_FAST_BILINEAR) {
721  }
722  } else {
723  c->hyScale = c->hcScale = hScale8To19_c;
724  }
725  } else {
726  c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
727  : hScale16To15_c;
728  }
729 
730  if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
731  if (c->dstBpc <= 14) {
732  if (c->srcRange) {
735  } else {
738  }
739  } else {
740  if (c->srcRange) {
743  } else {
746  }
747  }
748  }
749 
750  if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
751  srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE))
752  c->needs_hcscale = 1;
753 }
754 
756 {
758 
759  if (HAVE_MMX)
761  if (HAVE_ALTIVEC)
763 
764  return swScale;
765 }
766 
767 static void reset_ptr(const uint8_t *src[], int format)
768 {
769  if (!isALPHA(format))
770  src[3] = NULL;
771  if (!isPlanar(format)) {
772  src[3] = src[2] = NULL;
773 
774  if (!usePal(format))
775  src[1] = NULL;
776  }
777 }
778 
779 static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
780  const int linesizes[4])
781 {
782  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
783  int i;
784 
785  for (i = 0; i < 4; i++) {
786  int plane = desc->comp[i].plane;
787  if (!data[plane] || !linesizes[plane])
788  return 0;
789  }
790 
791  return 1;
792 }
793 
794 /**
795  * swscale wrapper, so we don't need to export the SwsContext.
796  * Assumes planar YUV to be in YUV order instead of YVU.
797  */
799  const uint8_t * const srcSlice[],
800  const int srcStride[], int srcSliceY,
801  int srcSliceH, uint8_t *const dst[],
802  const int dstStride[])
803 {
804  int i, ret;
805  const uint8_t *src2[4];
806  uint8_t *dst2[4];
807  uint8_t *rgb0_tmp = NULL;
808 
809  if (!srcSlice || !dstStride || !dst || !srcSlice) {
810  av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
811  return 0;
812  }
813  memcpy(src2, srcSlice, sizeof(src2));
814  memcpy(dst2, dst, sizeof(dst2));
815 
816  // do not mess up sliceDir if we have a "trailing" 0-size slice
817  if (srcSliceH == 0)
818  return 0;
819 
820  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
821  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
822  return 0;
823  }
824  if (!check_image_pointers((const uint8_t* const*)dst, c->dstFormat, dstStride)) {
825  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
826  return 0;
827  }
828 
829  if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
830  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
831  return 0;
832  }
833  if (c->sliceDir == 0) {
834  if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
835  }
836 
837  if (usePal(c->srcFormat)) {
838  for (i = 0; i < 256; i++) {
839  int p, r, g, b, y, u, v, a = 0xff;
840  if (c->srcFormat == AV_PIX_FMT_PAL8) {
841  p = ((const uint32_t *)(srcSlice[1]))[i];
842  a = (p >> 24) & 0xFF;
843  r = (p >> 16) & 0xFF;
844  g = (p >> 8) & 0xFF;
845  b = p & 0xFF;
846  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
847  r = ( i >> 5 ) * 36;
848  g = ((i >> 2) & 7) * 36;
849  b = ( i & 3) * 85;
850  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
851  b = ( i >> 6 ) * 85;
852  g = ((i >> 3) & 7) * 36;
853  r = ( i & 7) * 36;
854  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
855  r = ( i >> 3 ) * 255;
856  g = ((i >> 1) & 3) * 85;
857  b = ( i & 1) * 255;
858  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
859  r = g = b = i;
860  } else {
862  b = ( i >> 3 ) * 255;
863  g = ((i >> 1) & 3) * 85;
864  r = ( i & 1) * 255;
865  }
866 #define RGB2YUV_SHIFT 15
867 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
868 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
869 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
870 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
871 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
872 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
873 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
874 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
875 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
876 
877  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
878  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
879  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
880  c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
881 
882  switch (c->dstFormat) {
883  case AV_PIX_FMT_BGR32:
884 #if !HAVE_BIGENDIAN
885  case AV_PIX_FMT_RGB24:
886 #endif
887  c->pal_rgb[i]= r + (g<<8) + (b<<16) + ((unsigned)a<<24);
888  break;
889  case AV_PIX_FMT_BGR32_1:
890 #if HAVE_BIGENDIAN
891  case AV_PIX_FMT_BGR24:
892 #endif
893  c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24);
894  break;
895  case AV_PIX_FMT_RGB32_1:
896 #if HAVE_BIGENDIAN
897  case AV_PIX_FMT_RGB24:
898 #endif
899  c->pal_rgb[i]= a + (b<<8) + (g<<16) + ((unsigned)r<<24);
900  break;
901  case AV_PIX_FMT_RGB32:
902 #if !HAVE_BIGENDIAN
903  case AV_PIX_FMT_BGR24:
904 #endif
905  default:
906  c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24);
907  }
908  }
909  }
910 
911  if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
912  uint8_t *base;
913  int x,y;
914  rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
915  base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
916  for (y=0; y<srcSliceH; y++){
917  memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
918  for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
919  base[ srcStride[0]*y + x] = 0xFF;
920  }
921  }
922  src2[0] = base;
923  }
924 
925  if (!srcSliceY && (c->flags & SWS_BITEXACT) && (c->flags & SWS_ERROR_DIFFUSION) && c->dither_error[0])
926  for (i = 0; i < 4; i++)
927  memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
928 
929 
930  // copy strides, so they can safely be modified
931  if (c->sliceDir == 1) {
932  // slices go from top to bottom
933  int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
934  srcStride[3] };
935  int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
936  dstStride[3] };
937 
938  reset_ptr(src2, c->srcFormat);
939  reset_ptr((void*)dst2, c->dstFormat);
940 
941  /* reset slice direction at end of frame */
942  if (srcSliceY + srcSliceH == c->srcH)
943  c->sliceDir = 0;
944 
945  ret = c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
946  dstStride2);
947  } else {
948  // slices go from bottom to top => we flip the image internally
949  int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
950  -srcStride[3] };
951  int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
952  -dstStride[3] };
953 
954  src2[0] += (srcSliceH - 1) * srcStride[0];
955  if (!usePal(c->srcFormat))
956  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
957  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
958  src2[3] += (srcSliceH - 1) * srcStride[3];
959  dst2[0] += ( c->dstH - 1) * dstStride[0];
960  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
961  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
962  dst2[3] += ( c->dstH - 1) * dstStride[3];
963 
964  reset_ptr(src2, c->srcFormat);
965  reset_ptr((void*)dst2, c->dstFormat);
966 
967  /* reset slice direction at end of frame */
968  if (!srcSliceY)
969  c->sliceDir = 0;
970 
971  ret = c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
972  srcSliceH, dst2, dstStride2);
973  }
974 
975  av_free(rgb0_tmp);
976  return ret;
977 }
978 
#define BU
int16_t ** alpPixBuf
Ring buffer for scaled horizontal alpha plane lines to be fed to the vertical scaler.
void(* hcScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
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:171
float v
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:1565
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:162
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
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.
uint32_t pal_rgb[256]
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
#define GU
void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, int lastInLumBuf, int lastInChrBuf)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
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:207
#define SWS_FAST_BILINEAR
Definition: swscale.h:58
void(* chrToYV12)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of chroma planes to YV12 for horizontal scaler.
#define HAVE_ALTIVEC
Definition: config.h:56
void(* alpToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of alpha plane to YV12 for horizontal scaler.
#define RU
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
external API header
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...
int srcRange
0 = MPG YUV range, 1 = JPG YUV range (source image).
const uint8_t * lumDither8
#define BY
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...
int dstY
Last destination vertical line output from last slice.
SwsFunc swScale
Note that src, dst, srcStride, dstStride will be copied in the sws_scale() wrapper so they can be fre...
int stride
Definition: mace.c:144
#define FFALIGN(x, a)
Definition: common.h:63
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
int srcH
Height of source luma/alpha planes.
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:89
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
#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...
uint8_t bits
Definition: crc.c:216
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
static void lumRangeFromJpeg_c(int16_t *dst, int width)
Definition: swscale.c:178
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
int vChrFilterSize
Vertical filter size for chroma pixels.
#define b
Definition: input.c:42
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:798
int16_t ** lumPixBuf
Ring buffer for scaled horizontal luma plane lines to be fed to the vertical scaler.
#define emms_c()
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:30
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common 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
#define SWS_BITEXACT
Definition: swscale.h:84
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 (...
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
#define isAnyRGB(x)
external API header
enum AVPixelFormat dstFormat
Destination pixel format.
#define BV
#define isALPHA(x)
Definition: swscale-test.c:47
av_cold void ff_sws_init_input_funcs(SwsContext *c)
Definition: input.c:889
yuv2packedX_fn yuv2packedX
int32_t * vChrFilterPos
Array of vertical filter starting positions for each dst[i] for chroma planes.
#define DEBUG_BUFFERS(...)
Definition: swscale.c:327
int dstH
Height of destination luma/alpha planes.
int * dither_error[4]
Discrete Time axis x
yuv2anyX_fn yuv2anyX
uint16_t depth_minus1
number of bits in the component minus 1
Definition: pixdesc.h:43
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8]
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:262
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static void 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: swscale.c:272
int16_t ** chrVPixBuf
Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int32_t * hChrFilterPos
Array of horizontal filter starting positions for each dst[i] for chroma planes.
int hLumFilterSize
Horizontal filter size for luma/alpha pixels.
SwsFunc ff_getSwsFunc(SwsContext *c)
Return function pointer to fastest main scaler path function depending on architecture and available ...
Definition: swscale.c:755
#define RV
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:153
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
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:92
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int vChrBufSize
Number of vertical chroma lines allocated in the ring buffer.
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:56
static int check_image_pointers(const uint8_t *const data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
Definition: swscale.c:779
int chrDstW
Width of destination chroma planes.
#define isNBPS(x)
static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
Definition: swscale.c:223
int32_t alpMmxFilter[4 *MAX_FILTER_SIZE]
int32_t * hLumFilterPos
Array of horizontal filter starting positions for each dst[i] for luma/alpha planes.
int hChrFilterSize
Horizontal filter size for chroma pixels.
int dstRange
0 = MPG YUV range, 1 = JPG YUV range (destination image).
#define RGB2YUV_SHIFT
#define SWS_ERROR_DIFFUSION
Definition: swscale.h:85
FFT buffer for g
Definition: stft_peak.m:17
8bit gray, 8bit alpha
Definition: pixfmt.h:141
#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:58
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:92
#define RY
uint8_t * formatConvBuffer
static av_always_inline int is9_OR_10BPS(enum AVPixelFormat pix_fmt)
yuv2planar1_fn yuv2plane1
int vLumBufSize
Number of vertical luma/alpha lines allocated in the ring buffer.
ret
Definition: avfilter.c:821
void(* readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width, int32_t *rgb2yuv)
int16_t ** chrUPixBuf
Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
yuv2interleavedX_fn yuv2nv12cX
static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hLumFilter, const int32_t *hLumFilterPos, int hLumFilterSize, uint8_t *formatConvBuffer, uint32_t *pal, int isAlpha)
Definition: swscale.c:239
int32_t
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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
#define FFABS(a)
Definition: common.h:53
float u
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
void(* lumConvertRange)(int16_t *dst, int width)
Color range conversion function for luma plane if needed.
static int cpu_flags
Definition: dct-test.c:77
int dstW
Width of destination luma/alpha planes.
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 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 AV_PIX_FMT_BGR32
Definition: pixfmt.h:261
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
#define attribute_align_arg
int32_t lumMmxFilter[4 *MAX_FILTER_SIZE]
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:87
static int width
Definition: tests/utils.c:158
dest
Definition: start.py:60
AVS_Value src
Definition: avisynth_c.h:523
static int swScale(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
Definition: swscale.c:331
typedef void(RENAME(mix_any_func_type))
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...
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:55
yuv2planarX_fn yuv2planeX
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:259
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...
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static void reset_ptr(const uint8_t *src[], int format)
Definition: swscale.c:767
static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
Definition: swscale.c:54
static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:215
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
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
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
int16_t * vChrFilter
Array of vertical filter coefficients for chroma planes.
#define isGray(x)
Definition: swscale-test.c:38
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:30
int16_t * hLumFilter
Array of horizontal filter coefficients for luma/alpha planes.
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:185
static int flags
Definition: cpu.c:23
int lumBufIndex
Index in ring buffer of the last scaled horizontal luma/alpha line from source.
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:29
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:78
int lastInChrBuf
Last scaled horizontal chroma line from source in the ring buffer.
yuv2packed2_fn yuv2packed2
#define CONFIG_SWSCALE_ALPHA
Definition: config.h:394
Y , 8bpp.
Definition: pixfmt.h:76
#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:77
static double c[64]
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.
int32_t chrMmxFilter[4 *MAX_FILTER_SIZE]
#define HAVE_MMXEXT
Definition: config.h:49
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:90
function y
Definition: D.m:1
void(* readLumPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv)
Functions to read planar input, such as planar RGB, and convert internally to Y/UV.
#define GV
av_cold void ff_sws_init_swScale_altivec(SwsContext *c)
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:260
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 ...
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
void(* lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of luma plane to YV12 for horizontal scaler.
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:196
int16_t * vLumFilter
Array of vertical filter coefficients for luma/alpha planes.
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:34
#define av_always_inline
Definition: attributes.h:41
void ff_sws_init_swScale_mmx(SwsContext *c)
Definition: x86/swscale.c:380
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hChrFilter, const int32_t *hChrFilterPos, int hChrFilterSize, uint8_t *formatConvBuffer, uint32_t *pal)
Definition: swscale.c:291
int16_t * hChrFilter
Array of horizontal filter coefficients for chroma planes.
const char int length
Definition: avisynth_c.h:668
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:118
int chrSrcW
Width of source chroma planes.
#define isPacked(x)
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:66
uint32_t pal_yuv[256]
static av_cold void sws_init_swScale_c(SwsContext *c)
Definition: swscale.c:704
#define SWS_PRINT_INFO
Definition: swscale.h:75
#define HAVE_MMX
Definition: config.h:48
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:134