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