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