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 {
70  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
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 {
100  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
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;
255  yuv2planarX_fn yuv2planeX = c->yuv2planeX;
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];
284  SwsFilterDescriptor *desc = c->desc;
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[0] =
295  src[1] =
296  src[2] =
297  src[3] = src[0];
298  srcStride[0] =
299  srcStride[1] =
300  srcStride[2] =
301  srcStride[3] = srcStride[0];
302  }
303  srcStride[1] *= 1 << c->vChrDrop;
304  srcStride[2] *= 1 << c->vChrDrop;
305 
306  DEBUG_BUFFERS("swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
307  src[0], srcStride[0], src[1], srcStride[1],
308  src[2], srcStride[2], src[3], srcStride[3],
309  dst[0], dstStride[0], dst[1], dstStride[1],
310  dst[2], dstStride[2], dst[3], dstStride[3]);
311  DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
312  srcSliceY, srcSliceH, dstY, dstH);
313  DEBUG_BUFFERS("vLumFilterSize: %d vChrFilterSize: %d\n",
314  vLumFilterSize, vChrFilterSize);
315 
316  if (dstStride[0]&15 || dstStride[1]&15 ||
317  dstStride[2]&15 || dstStride[3]&15) {
318  static int warnedAlready = 0; // FIXME maybe move this into the context
319  if (flags & SWS_PRINT_INFO && !warnedAlready) {
321  "Warning: dstStride is not aligned!\n"
322  " ->cannot do aligned memory accesses anymore\n");
323  warnedAlready = 1;
324  }
325  }
326 
327  if ( (uintptr_t)dst[0]&15 || (uintptr_t)dst[1]&15 || (uintptr_t)dst[2]&15
328  || (uintptr_t)src[0]&15 || (uintptr_t)src[1]&15 || (uintptr_t)src[2]&15
329  || dstStride[0]&15 || dstStride[1]&15 || dstStride[2]&15 || dstStride[3]&15
330  || srcStride[0]&15 || srcStride[1]&15 || srcStride[2]&15 || srcStride[3]&15
331  ) {
332  static int warnedAlready=0;
333  int cpu_flags = av_get_cpu_flags();
334  if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){
335  av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speed loss\n");
336  warnedAlready=1;
337  }
338  }
339 
340  /* Note the user might start scaling the picture in the middle so this
341  * will not get executed. This is not really intended but works
342  * currently, so people might do it. */
343  if (srcSliceY == 0) {
344  lumBufIndex = -1;
345  chrBufIndex = -1;
346  dstY = 0;
347  lastInLumBuf = -1;
348  lastInChrBuf = -1;
349  }
350 
351  if (!should_dither) {
352  c->chrDither8 = c->lumDither8 = sws_pb_64;
353  }
354  lastDstY = dstY;
355 
356  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
357  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, c->use_mmx_vfilter);
358 
359  ff_init_slice_from_src(src_slice, (uint8_t**)src, srcStride, c->srcW,
360  srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
361 
362  ff_init_slice_from_src(vout_slice, (uint8_t**)dst, dstStride, c->dstW,
363  dstY, dstH, dstY >> c->chrDstVSubSample,
364  AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample), 0);
365  if (srcSliceY == 0) {
366  hout_slice->plane[0].sliceY = lastInLumBuf + 1;
367  hout_slice->plane[1].sliceY = lastInChrBuf + 1;
368  hout_slice->plane[2].sliceY = lastInChrBuf + 1;
369  hout_slice->plane[3].sliceY = lastInLumBuf + 1;
370 
371  hout_slice->plane[0].sliceH =
372  hout_slice->plane[1].sliceH =
373  hout_slice->plane[2].sliceH =
374  hout_slice->plane[3].sliceH = 0;
375  hout_slice->width = dstW;
376  }
377 
378  for (; dstY < dstH; dstY++) {
379  const int chrDstY = dstY >> c->chrDstVSubSample;
380  int use_mmx_vfilter= c->use_mmx_vfilter;
381 
382  // First line needed as input
383  const int firstLumSrcY = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
384  const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), dstH - 1)]);
385  // First line needed as input
386  const int firstChrSrcY = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
387 
388  // Last line needed as input
389  int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
390  int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
391  int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
392  int enough_lines;
393 
394  int i;
395  int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;
396 
397  // handle holes (FAST_BILINEAR & weird filters)
398  if (firstLumSrcY > lastInLumBuf) {
399 
400  hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
401  if (hasLumHoles) {
402  hout_slice->plane[0].sliceY = firstLumSrcY;
403  hout_slice->plane[3].sliceY = firstLumSrcY;
404  hout_slice->plane[0].sliceH =
405  hout_slice->plane[3].sliceH = 0;
406  }
407 
408  lastInLumBuf = firstLumSrcY - 1;
409  }
410  if (firstChrSrcY > lastInChrBuf) {
411 
412  hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
413  if (hasChrHoles) {
414  hout_slice->plane[1].sliceY = firstChrSrcY;
415  hout_slice->plane[2].sliceY = firstChrSrcY;
416  hout_slice->plane[1].sliceH =
417  hout_slice->plane[2].sliceH = 0;
418  }
419 
420  lastInChrBuf = firstChrSrcY - 1;
421  }
422 
423  DEBUG_BUFFERS("dstY: %d\n", dstY);
424  DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
425  firstLumSrcY, lastLumSrcY, lastInLumBuf);
426  DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
427  firstChrSrcY, lastChrSrcY, lastInChrBuf);
428 
429  // Do we have enough lines in this slice to output the dstY line
430  enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
431  lastChrSrcY < AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample);
432 
433  if (!enough_lines) {
434  lastLumSrcY = srcSliceY + srcSliceH - 1;
435  lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
436  DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
437  lastLumSrcY, lastChrSrcY);
438  }
439 
440  av_assert0((lastLumSrcY - firstLumSrcY + 1) <= hout_slice->plane[0].available_lines);
441  av_assert0((lastChrSrcY - firstChrSrcY + 1) <= hout_slice->plane[1].available_lines);
442 
443 
444  posY = hout_slice->plane[0].sliceY + hout_slice->plane[0].sliceH;
445  if (posY <= lastLumSrcY && !hasLumHoles) {
446  firstPosY = FFMAX(firstLumSrcY, posY);
447  lastPosY = FFMIN(firstLumSrcY + hout_slice->plane[0].available_lines - 1, srcSliceY + srcSliceH - 1);
448  } else {
449  firstPosY = posY;
450  lastPosY = lastLumSrcY;
451  }
452 
453  cPosY = hout_slice->plane[1].sliceY + hout_slice->plane[1].sliceH;
454  if (cPosY <= lastChrSrcY && !hasChrHoles) {
455  firstCPosY = FFMAX(firstChrSrcY, cPosY);
456  lastCPosY = FFMIN(firstChrSrcY + hout_slice->plane[1].available_lines - 1, AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample) - 1);
457  } else {
458  firstCPosY = cPosY;
459  lastCPosY = lastChrSrcY;
460  }
461 
462  ff_rotate_slice(hout_slice, lastPosY, lastCPosY);
463 
464  if (posY < lastLumSrcY + 1) {
465  for (i = lumStart; i < lumEnd; ++i)
466  desc[i].process(c, &desc[i], firstPosY, lastPosY - firstPosY + 1);
467  }
468 
469  lumBufIndex += lastLumSrcY - lastInLumBuf;
470  lastInLumBuf = lastLumSrcY;
471 
472  if (cPosY < lastChrSrcY + 1) {
473  for (i = chrStart; i < chrEnd; ++i)
474  desc[i].process(c, &desc[i], firstCPosY, lastCPosY - firstCPosY + 1);
475  }
476 
477  chrBufIndex += lastChrSrcY - lastInChrBuf;
478  lastInChrBuf = lastChrSrcY;
479 
480  // wrap buf index around to stay inside the ring buffer
481  if (lumBufIndex >= vLumFilterSize)
482  lumBufIndex -= vLumFilterSize;
483  if (chrBufIndex >= vChrFilterSize)
484  chrBufIndex -= vChrFilterSize;
485  if (!enough_lines)
486  break; // we can't output a dstY line so let's try with the next slice
487 
488 #if HAVE_MMX_INLINE
489  ff_updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex,
490  lastInLumBuf, lastInChrBuf);
491 #endif
492  if (should_dither) {
493  c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
494  c->lumDither8 = ff_dither_8x8_128[dstY & 7];
495  }
496  if (dstY >= dstH - 2) {
497  /* hmm looks like we can't use MMX here without overwriting
498  * this array's tail */
499  ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
500  &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
501  use_mmx_vfilter= 0;
502  ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
503  yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
504  }
505 
506  {
507  for (i = vStart; i < vEnd; ++i)
508  desc[i].process(c, &desc[i], dstY, 1);
509  }
510  }
511  if (isPlanar(dstFormat) && isALPHA(dstFormat) && !needAlpha) {
512  int length = dstW;
513  int height = dstY - lastDstY;
514 
515  if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
516  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
517  fillPlane16(dst[3], dstStride[3], length, height, lastDstY,
518  1, desc->comp[3].depth,
519  isBE(dstFormat));
520  } else
521  fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255);
522  }
523 
524 #if HAVE_MMXEXT_INLINE
526  __asm__ volatile ("sfence" ::: "memory");
527 #endif
528  emms_c();
529 
530  /* store changed local vars back in the context */
531  c->dstY = dstY;
532  c->lumBufIndex = lumBufIndex;
533  c->chrBufIndex = chrBufIndex;
534  c->lastInLumBuf = lastInLumBuf;
535  c->lastInChrBuf = lastInChrBuf;
536 
537  return dstY - lastDstY;
538 }
539 
541 {
542  c->lumConvertRange = NULL;
543  c->chrConvertRange = NULL;
544  if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
545  if (c->dstBpc <= 14) {
546  if (c->srcRange) {
547  c->lumConvertRange = lumRangeFromJpeg_c;
548  c->chrConvertRange = chrRangeFromJpeg_c;
549  } else {
550  c->lumConvertRange = lumRangeToJpeg_c;
551  c->chrConvertRange = chrRangeToJpeg_c;
552  }
553  } else {
554  if (c->srcRange) {
555  c->lumConvertRange = lumRangeFromJpeg16_c;
556  c->chrConvertRange = chrRangeFromJpeg16_c;
557  } else {
558  c->lumConvertRange = lumRangeToJpeg16_c;
559  c->chrConvertRange = chrRangeToJpeg16_c;
560  }
561  }
562  }
563 }
564 
566 {
567  enum AVPixelFormat srcFormat = c->srcFormat;
568 
569  ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
570  &c->yuv2nv12cX, &c->yuv2packed1,
571  &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
572 
574 
575 
576  if (c->srcBpc == 8) {
577  if (c->dstBpc <= 14) {
578  c->hyScale = c->hcScale = hScale8To15_c;
579  if (c->flags & SWS_FAST_BILINEAR) {
580  c->hyscale_fast = ff_hyscale_fast_c;
581  c->hcscale_fast = ff_hcscale_fast_c;
582  }
583  } else {
584  c->hyScale = c->hcScale = hScale8To19_c;
585  }
586  } else {
587  c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
588  : hScale16To15_c;
589  }
590 
592 
593  if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
594  srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE))
595  c->needs_hcscale = 1;
596 }
597 
599 {
601 
602  if (ARCH_PPC)
604  if (ARCH_X86)
606  if (ARCH_AARCH64)
608  if (ARCH_ARM)
610 
611  return swscale;
612 }
613 
614 static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
615 {
616  if (!isALPHA(format))
617  src[3] = NULL;
618  if (!isPlanar(format)) {
619  src[3] = src[2] = NULL;
620 
621  if (!usePal(format))
622  src[1] = NULL;
623  }
624 }
625 
626 static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
627  const int linesizes[4])
628 {
630  int i;
631 
632  av_assert2(desc);
633 
634  for (i = 0; i < 4; i++) {
635  int plane = desc->comp[i].plane;
636  if (!data[plane] || !linesizes[plane])
637  return 0;
638  }
639 
640  return 1;
641 }
642 
643 static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
644  const uint16_t *src, int stride, int h)
645 {
646  int xp,yp;
647  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
648 
649  for (yp=0; yp<h; yp++) {
650  for (xp=0; xp+2<stride; xp+=3) {
651  int x, y, z, r, g, b;
652 
653  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
654  x = AV_RB16(src + xp + 0);
655  y = AV_RB16(src + xp + 1);
656  z = AV_RB16(src + xp + 2);
657  } else {
658  x = AV_RL16(src + xp + 0);
659  y = AV_RL16(src + xp + 1);
660  z = AV_RL16(src + xp + 2);
661  }
662 
663  x = c->xyzgamma[x>>4];
664  y = c->xyzgamma[y>>4];
665  z = c->xyzgamma[z>>4];
666 
667  // convert from XYZlinear to sRGBlinear
668  r = c->xyz2rgb_matrix[0][0] * x +
669  c->xyz2rgb_matrix[0][1] * y +
670  c->xyz2rgb_matrix[0][2] * z >> 12;
671  g = c->xyz2rgb_matrix[1][0] * x +
672  c->xyz2rgb_matrix[1][1] * y +
673  c->xyz2rgb_matrix[1][2] * z >> 12;
674  b = c->xyz2rgb_matrix[2][0] * x +
675  c->xyz2rgb_matrix[2][1] * y +
676  c->xyz2rgb_matrix[2][2] * z >> 12;
677 
678  // limit values to 12-bit depth
679  r = av_clip_uintp2(r, 12);
680  g = av_clip_uintp2(g, 12);
681  b = av_clip_uintp2(b, 12);
682 
683  // convert from sRGBlinear to RGB and scale from 12bit to 16bit
684  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
685  AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
686  AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
687  AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
688  } else {
689  AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
690  AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
691  AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
692  }
693  }
694  src += stride;
695  dst += stride;
696  }
697 }
698 
699 static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst,
700  const uint16_t *src, int stride, int h)
701 {
702  int xp,yp;
703  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
704 
705  for (yp=0; yp<h; yp++) {
706  for (xp=0; xp+2<stride; xp+=3) {
707  int x, y, z, r, g, b;
708 
709  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
710  r = AV_RB16(src + xp + 0);
711  g = AV_RB16(src + xp + 1);
712  b = AV_RB16(src + xp + 2);
713  } else {
714  r = AV_RL16(src + xp + 0);
715  g = AV_RL16(src + xp + 1);
716  b = AV_RL16(src + xp + 2);
717  }
718 
719  r = c->rgbgammainv[r>>4];
720  g = c->rgbgammainv[g>>4];
721  b = c->rgbgammainv[b>>4];
722 
723  // convert from sRGBlinear to XYZlinear
724  x = c->rgb2xyz_matrix[0][0] * r +
725  c->rgb2xyz_matrix[0][1] * g +
726  c->rgb2xyz_matrix[0][2] * b >> 12;
727  y = c->rgb2xyz_matrix[1][0] * r +
728  c->rgb2xyz_matrix[1][1] * g +
729  c->rgb2xyz_matrix[1][2] * b >> 12;
730  z = c->rgb2xyz_matrix[2][0] * r +
731  c->rgb2xyz_matrix[2][1] * g +
732  c->rgb2xyz_matrix[2][2] * b >> 12;
733 
734  // limit values to 12-bit depth
735  x = av_clip_uintp2(x, 12);
736  y = av_clip_uintp2(y, 12);
737  z = av_clip_uintp2(z, 12);
738 
739  // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
740  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
741  AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4);
742  AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4);
743  AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4);
744  } else {
745  AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4);
746  AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4);
747  AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 4);
748  }
749  }
750  src += stride;
751  dst += stride;
752  }
753 }
754 
755 /**
756  * swscale wrapper, so we don't need to export the SwsContext.
757  * Assumes planar YUV to be in YUV order instead of YVU.
758  */
759 int attribute_align_arg sws_scale(struct SwsContext *c,
760  const uint8_t * const srcSlice[],
761  const int srcStride[], int srcSliceY,
762  int srcSliceH, uint8_t *const dst[],
763  const int dstStride[])
764 {
765  int i, ret;
766  const uint8_t *src2[4];
767  uint8_t *dst2[4];
768  uint8_t *rgb0_tmp = NULL;
769  int macro_height = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
770  // copy strides, so they can safely be modified
771  int srcStride2[4];
772  int dstStride2[4];
773  int srcSliceY_internal = srcSliceY;
774 
775  if (!srcStride || !dstStride || !dst || !srcSlice) {
776  av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
777  return 0;
778  }
779 
780  for (i=0; i<4; i++) {
781  srcStride2[i] = srcStride[i];
782  dstStride2[i] = dstStride[i];
783  }
784 
785  if ((srcSliceY & (macro_height-1)) ||
786  ((srcSliceH& (macro_height-1)) && srcSliceY + srcSliceH != c->srcH) ||
787  srcSliceY + srcSliceH > c->srcH) {
788  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH);
789  return AVERROR(EINVAL);
790  }
791 
792  if (c->gamma_flag && c->cascaded_context[0]) {
793 
794 
795  ret = sws_scale(c->cascaded_context[0],
796  srcSlice, srcStride, srcSliceY, srcSliceH,
797  c->cascaded_tmp, c->cascaded_tmpStride);
798 
799  if (ret < 0)
800  return ret;
801 
802  if (c->cascaded_context[2])
803  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);
804  else
805  ret = sws_scale(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp, c->cascaded_tmpStride, srcSliceY, srcSliceH, dst, dstStride);
806 
807  if (ret < 0)
808  return ret;
809 
810  if (c->cascaded_context[2]) {
811  ret = sws_scale(c->cascaded_context[2],
812  (const uint8_t * const *)c->cascaded1_tmp, c->cascaded1_tmpStride, c->cascaded_context[1]->dstY - ret, c->cascaded_context[1]->dstY,
813  dst, dstStride);
814  }
815  return ret;
816  }
817 
818  if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH) {
819  ret = sws_scale(c->cascaded_context[0],
820  srcSlice, srcStride, srcSliceY, srcSliceH,
821  c->cascaded_tmp, c->cascaded_tmpStride);
822  if (ret < 0)
823  return ret;
824  ret = sws_scale(c->cascaded_context[1],
825  (const uint8_t * const * )c->cascaded_tmp, c->cascaded_tmpStride, 0, c->cascaded_context[0]->dstH,
826  dst, dstStride);
827  return ret;
828  }
829 
830  memcpy(src2, srcSlice, sizeof(src2));
831  memcpy(dst2, dst, sizeof(dst2));
832 
833  // do not mess up sliceDir if we have a "trailing" 0-size slice
834  if (srcSliceH == 0)
835  return 0;
836 
837  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
838  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
839  return 0;
840  }
841  if (!check_image_pointers((const uint8_t* const*)dst, c->dstFormat, dstStride)) {
842  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
843  return 0;
844  }
845 
846  if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
847  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
848  return 0;
849  }
850  if (c->sliceDir == 0) {
851  if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
852  }
853 
854  if (usePal(c->srcFormat)) {
855  for (i = 0; i < 256; i++) {
856  int r, g, b, y, u, v, a = 0xff;
857  if (c->srcFormat == AV_PIX_FMT_PAL8) {
858  uint32_t p = ((const uint32_t *)(srcSlice[1]))[i];
859  a = (p >> 24) & 0xFF;
860  r = (p >> 16) & 0xFF;
861  g = (p >> 8) & 0xFF;
862  b = p & 0xFF;
863  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
864  r = ( i >> 5 ) * 36;
865  g = ((i >> 2) & 7) * 36;
866  b = ( i & 3) * 85;
867  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
868  b = ( i >> 6 ) * 85;
869  g = ((i >> 3) & 7) * 36;
870  r = ( i & 7) * 36;
871  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
872  r = ( i >> 3 ) * 255;
873  g = ((i >> 1) & 3) * 85;
874  b = ( i & 1) * 255;
875  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
876  r = g = b = i;
877  } else {
878  av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
879  b = ( i >> 3 ) * 255;
880  g = ((i >> 1) & 3) * 85;
881  r = ( i & 1) * 255;
882  }
883 #define RGB2YUV_SHIFT 15
884 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
885 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
886 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
887 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
888 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
889 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
890 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
891 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
892 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
893 
894  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
895  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
896  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
897  c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
898 
899  switch (c->dstFormat) {
900  case AV_PIX_FMT_BGR32:
901 #if !HAVE_BIGENDIAN
902  case AV_PIX_FMT_RGB24:
903 #endif
904  c->pal_rgb[i]= r + (g<<8) + (b<<16) + ((unsigned)a<<24);
905  break;
906  case AV_PIX_FMT_BGR32_1:
907 #if HAVE_BIGENDIAN
908  case AV_PIX_FMT_BGR24:
909 #endif
910  c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24);
911  break;
912  case AV_PIX_FMT_RGB32_1:
913 #if HAVE_BIGENDIAN
914  case AV_PIX_FMT_RGB24:
915 #endif
916  c->pal_rgb[i]= a + (b<<8) + (g<<16) + ((unsigned)r<<24);
917  break;
918  case AV_PIX_FMT_RGB32:
919 #if !HAVE_BIGENDIAN
920  case AV_PIX_FMT_BGR24:
921 #endif
922  default:
923  c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24);
924  }
925  }
926  }
927 
928  if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
929  uint8_t *base;
930  int x,y;
931  rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
932  if (!rgb0_tmp)
933  return AVERROR(ENOMEM);
934 
935  base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
936  for (y=0; y<srcSliceH; y++){
937  memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
938  for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
939  base[ srcStride[0]*y + x] = 0xFF;
940  }
941  }
942  src2[0] = base;
943  }
944 
945  if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
946  uint8_t *base;
947  rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
948  if (!rgb0_tmp)
949  return AVERROR(ENOMEM);
950 
951  base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
952 
953  xyz12Torgb48(c, (uint16_t*)base, (const uint16_t*)src2[0], srcStride[0]/2, srcSliceH);
954  src2[0] = base;
955  }
956 
957  if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
958  for (i = 0; i < 4; i++)
959  memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
960 
961  if (c->sliceDir != 1) {
962  // slices go from bottom to top => we flip the image internally
963  for (i=0; i<4; i++) {
964  srcStride2[i] *= -1;
965  dstStride2[i] *= -1;
966  }
967 
968  src2[0] += (srcSliceH - 1) * srcStride[0];
969  if (!usePal(c->srcFormat))
970  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
971  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
972  src2[3] += (srcSliceH - 1) * srcStride[3];
973  dst2[0] += ( c->dstH - 1) * dstStride[0];
974  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
975  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
976  dst2[3] += ( c->dstH - 1) * dstStride[3];
977 
978  srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
979  }
980  reset_ptr(src2, c->srcFormat);
981  reset_ptr((void*)dst2, c->dstFormat);
982 
983  /* reset slice direction at end of frame */
984  if (srcSliceY_internal + srcSliceH == c->srcH)
985  c->sliceDir = 0;
986  ret = c->swscale(c, src2, srcStride2, srcSliceY_internal, srcSliceH, dst2, dstStride2);
987 
988 
989  if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
990  int dstY = c->dstY ? c->dstY : srcSliceY + srcSliceH;
991  uint16_t *dst16 = (uint16_t*)(dst2[0] + (dstY - ret) * dstStride2[0]);
992  av_assert0(dstY >= ret);
993  av_assert0(ret >= 0);
994  av_assert0(c->dstH >= dstY);
995 
996  /* replace on the same data */
997  rgb48Toxyz12(c, dst16, dst16, dstStride2[0]/2, ret);
998  }
999 
1000  av_free(rgb0_tmp);
1001  return ret;
1002 }
isBayer
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:754
yuv2packed2_fn
void(* yuv2packed2_fn)(struct SwsContext *c, const int16_t *lumSrc[2], const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing bilinear scalin...
Definition: swscale_internal.h:202
stride
int stride
Definition: mace.c:144
yuv2planar1_fn
void(* yuv2planar1_fn)(const int16_t *src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output without any additional vertical scaling (...
Definition: swscale_internal.h:98
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
yuv2packed1_fn
void(* yuv2packed1_fn)(struct SwsContext *c, const int16_t *lumSrc, const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc, uint8_t *dest, int dstW, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output without any additional v...
Definition: swscale_internal.h:169
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
SwsPlane::sliceH
int sliceH
number of lines
Definition: swscale_internal.h:933
hScale16To19_c
static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:66
isPacked
static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:785
r
const char * r
Definition: vf_curves.c:114
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
chrRangeFromJpeg16_c
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:203
AV_PIX_FMT_BGR32
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:362
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
ff_hyscale_fast_c
void ff_hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
Definition: hscale_fast_bilinear.c:23
ff_rotate_slice
int ff_rotate_slice(SwsSlice *s, int lum, int chr)
Definition: slice.c:119
AV_PIX_FMT_FLAG_FLOAT
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:188
SwsSlice::plane
SwsPlane plane[MAX_SLICE_PLANES]
color planes
Definition: swscale_internal.h:951
pixdesc.h
hScale8To15_c
static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:125
GV
#define GV
ff_sws_init_input_funcs
void ff_sws_init_input_funcs(SwsContext *c)
b
#define b
Definition: input.c:41
SwsFilterDescriptor
Struct which holds all necessary data for processing a slice.
Definition: swscale_internal.h:958
yuv2planeX
static void FUNC() yuv2planeX(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Definition: swscale_ppc_template.c:81
data
const char data[16]
Definition: mxf.c:91
AV_PIX_FMT_MONOWHITE
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:75
isGray
#define isGray(x)
Definition: swscale.c:40
AV_PIX_FMT_RGB32_1
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:361
base
uint8_t base
Definition: vp3data.h:202
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
mathematics.h
sws_scale
int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition: swscale.c:759
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
RV
#define RV
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:93
DEBUG_BUFFERS
#define DEBUG_BUFFERS(...)
Definition: swscale.c:233
cpu_flags
static atomic_int cpu_flags
Definition: cpu.c:50
xyz12Torgb48
static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:643
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
SWS_FAST_BILINEAR
#define SWS_FAST_BILINEAR
Definition: swscale.h:58
is16BPS
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:646
ff_sws_init_swscale_aarch64
av_cold void ff_sws_init_swscale_aarch64(SwsContext *c)
Definition: swscale.c:32
SWS_BITEXACT
#define SWS_BITEXACT
Definition: swscale.h:84
SwsFunc
int(* SwsFunc)(struct SwsContext *context, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
Definition: swscale_internal.h:82
yuv2anyX_fn
void(* yuv2anyX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t **dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to YUV/RGB output by doing multi-point vertical scaling...
Definition: swscale_internal.h:268
U
#define U(x)
Definition: vp56_arith.h:37
plane
int plane
Definition: avisynth_c.h:384
hScale8To19_c
static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:141
isNBPS
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:653
RY
#define RY
src
#define src
Definition: vp8dsp.c:254
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:84
sws_init_swscale
static av_cold void sws_init_swscale(SwsContext *c)
Definition: swscale.c:565
SWS_DITHER_ED
@ SWS_DITHER_ED
Definition: swscale_internal.h:69
width
#define width
intreadwrite.h
GU
#define GU
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
ff_sws_init_swscale_arm
av_cold void ff_sws_init_swscale_arm(SwsContext *c)
Definition: swscale.c:32
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
g
const char * g
Definition: vf_curves.c:115
SwsSlice::width
int width
Slice line width.
Definition: swscale_internal.h:945
bits
uint8_t bits
Definition: vp3data.h:202
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:90
lumRangeFromJpeg_c
static void lumRangeFromJpeg_c(int16_t *dst, int width)
Definition: swscale.c:185
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
ff_init_vscale_pfn
void ff_init_vscale_pfn(SwsContext *c, yuv2planar1_fn yuv2plane1, yuv2planarX_fn yuv2planeX, yuv2interleavedX_fn yuv2nv12cX, yuv2packed1_fn yuv2packed1, yuv2packed2_fn yuv2packed2, yuv2packedX_fn yuv2packedX, yuv2anyX_fn yuv2anyX, int use_mmx)
setup vertical scaler functions
Definition: vscale.c:250
AV_PIX_FMT_BGR32_1
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:363
int32_t
int32_t
Definition: audio_convert.c:194
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
ff_sws_init_range_convert
av_cold void ff_sws_init_range_convert(SwsContext *c)
Definition: swscale.c:540
AV_PIX_FMT_GRAY8A
@ AV_PIX_FMT_GRAY8A
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:146
fillPlane
static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
Definition: swscale.c:55
NULL
#define NULL
Definition: coverity.c:32
SwsPlane::available_lines
int available_lines
max number of lines that can be hold by this plane
Definition: swscale_internal.h:931
ff_sws_init_swscale_x86
av_cold void ff_sws_init_swscale_x86(SwsContext *c)
Definition: swscale.c:384
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
AV_PIX_FMT_MONOBLACK
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:76
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
process
static int process(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed)
Definition: soxr_resample.c:84
AV_PIX_FMT_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
chrRangeToJpeg_c
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:160
AV_CPU_FLAG_SSE2
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:36
ff_getSwsFunc
SwsFunc ff_getSwsFunc(SwsContext *c)
Return function pointer to fastest main scaler path function depending on architecture and available ...
Definition: swscale.c:598
isBE
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:660
desc
const char * desc
Definition: nvenc.c:68
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
fillPlane16
static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian)
Definition: swscale_internal.h:906
usePal
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:816
BV
#define BV
cpu.h
isAnyRGB
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:761
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
hScale16To15_c
static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Definition: swscale.c:96
chrRangeToJpeg16_c
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
Definition: swscale.c:192
swscale
static int swscale(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
Definition: swscale.c:237
val
const char const char void * val
Definition: avisynth_c.h:863
RGB2YUV_SHIFT
#define RGB2YUV_SHIFT
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
height
#define height
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:360
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
ff_hcscale_fast_c
void ff_hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
Definition: hscale_fast_bilinear.c:38
GY
#define GY
isALPHA
#define isALPHA(x)
Definition: swscale.c:51
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:112
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
check_image_pointers
static int check_image_pointers(const uint8_t *const data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
Definition: swscale.c:626
av_always_inline
#define av_always_inline
Definition: attributes.h:43
swscale_internal.h
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:128
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_PIX_FMT_RGB4_BYTE
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
SwsSlice
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
Definition: swscale_internal.h:943
ff_init_slice_from_src
int ff_init_slice_from_src(SwsSlice *s, uint8_t *src[4], int stride[4], int srcW, int lumY, int lumH, int chrY, int chrH, int relative)
Definition: slice.c:147
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
ff_sws_init_output_funcs
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
ret
ret
Definition: filter_design.txt:187
bswap.h
sws_pb_64
static const uint8_t sws_pb_64[8]
Definition: swscale.c:51
ff_sws_init_swscale_ppc
av_cold void ff_sws_init_swscale_ppc(SwsContext *c)
Definition: swscale_altivec.c:238
yuv2planarX_fn
void(* yuv2planarX_fn)(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output with multi-point vertical scaling between...
Definition: swscale_internal.h:114
yuv2interleavedX_fn
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 ...
Definition: swscale_internal.h:133
reset_ptr
static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
Definition: swscale.c:614
config.h
yuv2packedX_fn
void(* yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing multi-point ver...
Definition: swscale_internal.h:234
ff_dither_8x8_128
const uint8_t ff_dither_8x8_128[9][8]
Definition: swscale.c:39
AV_CPU_FLAG_MMXEXT
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:32
RU
#define RU
lumRangeToJpeg_c
static void lumRangeToJpeg_c(int16_t *dst, int width)
Definition: swscale.c:178
BU
#define BU
lumRangeFromJpeg16_c
static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:223
SWS_PRINT_INFO
#define SWS_PRINT_INFO
Definition: swscale.h:75
avutil.h
lumRangeToJpeg16_c
static void lumRangeToJpeg16_c(int16_t *_dst, int width)
Definition: swscale.c:214
SwsPlane::sliceY
int sliceY
index of first line
Definition: swscale_internal.h:932
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
BY
#define BY
chrRangeFromJpeg_c
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
Definition: swscale.c:169
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
length
const char int length
Definition: avisynth_c.h:860
h
h
Definition: vp9dsp_template.c:2038
isPlanar
static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:794
int
int
Definition: ffmpeg_filter.c:191
SwsContext
Definition: swscale_internal.h:280
rgb48Toxyz12
static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:699
ff_updateMMXDitherTables
void ff_updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, int lastInLumBuf, int lastInChrBuf)
rgb2rgb.h
swscale.h
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:94