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  if (ARCH_X86)
597  if (ARCH_AARCH64)
599  if (ARCH_ARM)
601 }
602 
603 static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
604 {
605  if (!isALPHA(format))
606  src[3] = NULL;
607  if (!isPlanar(format)) {
608  src[3] = src[2] = NULL;
609 
610  if (!usePal(format))
611  src[1] = NULL;
612  }
613 }
614 
615 static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
616  const int linesizes[4])
617 {
619  int i;
620 
621  av_assert2(desc);
622 
623  for (i = 0; i < 4; i++) {
624  int plane = desc->comp[i].plane;
625  if (!data[plane] || !linesizes[plane])
626  return 0;
627  }
628 
629  return 1;
630 }
631 
632 static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
633  const uint16_t *src, int stride, int h)
634 {
635  int xp,yp;
636  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
637 
638  for (yp=0; yp<h; yp++) {
639  for (xp=0; xp+2<stride; xp+=3) {
640  int x, y, z, r, g, b;
641 
642  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
643  x = AV_RB16(src + xp + 0);
644  y = AV_RB16(src + xp + 1);
645  z = AV_RB16(src + xp + 2);
646  } else {
647  x = AV_RL16(src + xp + 0);
648  y = AV_RL16(src + xp + 1);
649  z = AV_RL16(src + xp + 2);
650  }
651 
652  x = c->xyzgamma[x>>4];
653  y = c->xyzgamma[y>>4];
654  z = c->xyzgamma[z>>4];
655 
656  // convert from XYZlinear to sRGBlinear
657  r = c->xyz2rgb_matrix[0][0] * x +
658  c->xyz2rgb_matrix[0][1] * y +
659  c->xyz2rgb_matrix[0][2] * z >> 12;
660  g = c->xyz2rgb_matrix[1][0] * x +
661  c->xyz2rgb_matrix[1][1] * y +
662  c->xyz2rgb_matrix[1][2] * z >> 12;
663  b = c->xyz2rgb_matrix[2][0] * x +
664  c->xyz2rgb_matrix[2][1] * y +
665  c->xyz2rgb_matrix[2][2] * z >> 12;
666 
667  // limit values to 12-bit depth
668  r = av_clip_uintp2(r, 12);
669  g = av_clip_uintp2(g, 12);
670  b = av_clip_uintp2(b, 12);
671 
672  // convert from sRGBlinear to RGB and scale from 12bit to 16bit
673  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
674  AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
675  AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
676  AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
677  } else {
678  AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
679  AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
680  AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
681  }
682  }
683  src += stride;
684  dst += stride;
685  }
686 }
687 
688 static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst,
689  const uint16_t *src, int stride, int h)
690 {
691  int xp,yp;
692  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
693 
694  for (yp=0; yp<h; yp++) {
695  for (xp=0; xp+2<stride; xp+=3) {
696  int x, y, z, r, g, b;
697 
698  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
699  r = AV_RB16(src + xp + 0);
700  g = AV_RB16(src + xp + 1);
701  b = AV_RB16(src + xp + 2);
702  } else {
703  r = AV_RL16(src + xp + 0);
704  g = AV_RL16(src + xp + 1);
705  b = AV_RL16(src + xp + 2);
706  }
707 
708  r = c->rgbgammainv[r>>4];
709  g = c->rgbgammainv[g>>4];
710  b = c->rgbgammainv[b>>4];
711 
712  // convert from sRGBlinear to XYZlinear
713  x = c->rgb2xyz_matrix[0][0] * r +
714  c->rgb2xyz_matrix[0][1] * g +
715  c->rgb2xyz_matrix[0][2] * b >> 12;
716  y = c->rgb2xyz_matrix[1][0] * r +
717  c->rgb2xyz_matrix[1][1] * g +
718  c->rgb2xyz_matrix[1][2] * b >> 12;
719  z = c->rgb2xyz_matrix[2][0] * r +
720  c->rgb2xyz_matrix[2][1] * g +
721  c->rgb2xyz_matrix[2][2] * b >> 12;
722 
723  // limit values to 12-bit depth
724  x = av_clip_uintp2(x, 12);
725  y = av_clip_uintp2(y, 12);
726  z = av_clip_uintp2(z, 12);
727 
728  // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
729  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
730  AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4);
731  AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4);
732  AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4);
733  } else {
734  AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4);
735  AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4);
736  AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 4);
737  }
738  }
739  src += stride;
740  dst += stride;
741  }
742 }
743 
744 static void update_palette(SwsContext *c, const uint32_t *pal)
745 {
746  for (int i = 0; i < 256; i++) {
747  int r, g, b, y, u, v, a = 0xff;
748  if (c->srcFormat == AV_PIX_FMT_PAL8) {
749  uint32_t p = pal[i];
750  a = (p >> 24) & 0xFF;
751  r = (p >> 16) & 0xFF;
752  g = (p >> 8) & 0xFF;
753  b = p & 0xFF;
754  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
755  r = ( i >> 5 ) * 36;
756  g = ((i >> 2) & 7) * 36;
757  b = ( i & 3) * 85;
758  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
759  b = ( i >> 6 ) * 85;
760  g = ((i >> 3) & 7) * 36;
761  r = ( i & 7) * 36;
762  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
763  r = ( i >> 3 ) * 255;
764  g = ((i >> 1) & 3) * 85;
765  b = ( i & 1) * 255;
766  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
767  r = g = b = i;
768  } else {
769  av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
770  b = ( i >> 3 ) * 255;
771  g = ((i >> 1) & 3) * 85;
772  r = ( i & 1) * 255;
773  }
774 #define RGB2YUV_SHIFT 15
775 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
776 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
777 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
778 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
779 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
780 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
781 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
782 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
783 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
784 
785  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
786  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
787  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
788  c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
789 
790  switch (c->dstFormat) {
791  case AV_PIX_FMT_BGR32:
792 #if !HAVE_BIGENDIAN
793  case AV_PIX_FMT_RGB24:
794 #endif
795  c->pal_rgb[i]= r + (g<<8) + (b<<16) + ((unsigned)a<<24);
796  break;
797  case AV_PIX_FMT_BGR32_1:
798 #if HAVE_BIGENDIAN
799  case AV_PIX_FMT_BGR24:
800 #endif
801  c->pal_rgb[i]= a + (r<<8) + (g<<16) + ((unsigned)b<<24);
802  break;
803  case AV_PIX_FMT_RGB32_1:
804 #if HAVE_BIGENDIAN
805  case AV_PIX_FMT_RGB24:
806 #endif
807  c->pal_rgb[i]= a + (b<<8) + (g<<16) + ((unsigned)r<<24);
808  break;
809  case AV_PIX_FMT_RGB32:
810 #if !HAVE_BIGENDIAN
811  case AV_PIX_FMT_BGR24:
812 #endif
813  default:
814  c->pal_rgb[i]= b + (g<<8) + (r<<16) + ((unsigned)a<<24);
815  }
816  }
817 }
818 
819 static int scale_internal(SwsContext *c,
820  const uint8_t * const srcSlice[], const int srcStride[],
821  int srcSliceY, int srcSliceH,
822  uint8_t *const dstSlice[], const int dstStride[],
823  int dstSliceY, int dstSliceH);
824 
826  const uint8_t * const srcSlice[], const int srcStride[],
827  int srcSliceY, int srcSliceH,
828  uint8_t * const dstSlice[], const int dstStride[],
829  int dstSliceY, int dstSliceH)
830 {
831  int ret = scale_internal(c->cascaded_context[0],
832  srcSlice, srcStride, srcSliceY, srcSliceH,
833  c->cascaded_tmp, c->cascaded_tmpStride, 0, c->srcH);
834 
835  if (ret < 0)
836  return ret;
837 
838  if (c->cascaded_context[2])
839  ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp,
840  c->cascaded_tmpStride, srcSliceY, srcSliceH,
841  c->cascaded1_tmp, c->cascaded1_tmpStride, 0, c->dstH);
842  else
843  ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp,
844  c->cascaded_tmpStride, srcSliceY, srcSliceH,
845  dstSlice, dstStride, dstSliceY, dstSliceH);
846 
847  if (ret < 0)
848  return ret;
849 
850  if (c->cascaded_context[2]) {
851  ret = scale_internal(c->cascaded_context[2], (const uint8_t * const *)c->cascaded1_tmp,
852  c->cascaded1_tmpStride, c->cascaded_context[1]->dstY - ret,
853  c->cascaded_context[1]->dstY,
854  dstSlice, dstStride, dstSliceY, dstSliceH);
855  }
856  return ret;
857 }
858 
860  const uint8_t * const srcSlice[], const int srcStride[],
861  int srcSliceY, int srcSliceH,
862  uint8_t * const dstSlice[], const int dstStride[],
863  int dstSliceY, int dstSliceH)
864 {
865  int ret = scale_internal(c->cascaded_context[0],
866  srcSlice, srcStride, srcSliceY, srcSliceH,
867  c->cascaded_tmp, c->cascaded_tmpStride,
868  0, c->cascaded_context[0]->dstH);
869  if (ret < 0)
870  return ret;
871  ret = scale_internal(c->cascaded_context[1],
872  (const uint8_t * const * )c->cascaded_tmp, c->cascaded_tmpStride,
873  0, c->cascaded_context[0]->dstH,
874  dstSlice, dstStride, dstSliceY, dstSliceH);
875  return ret;
876 }
877 
879  const uint8_t * const srcSlice[], const int srcStride[],
880  int srcSliceY, int srcSliceH,
881  uint8_t *const dstSlice[], const int dstStride[],
882  int dstSliceY, int dstSliceH)
883 {
884  const int scale_dst = dstSliceY > 0 || dstSliceH < c->dstH;
885  const int frame_start = scale_dst || !c->sliceDir;
886  int i, ret;
887  const uint8_t *src2[4];
888  uint8_t *dst2[4];
889  int macro_height_src = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
890  int macro_height_dst = isBayer(c->dstFormat) ? 2 : (1 << c->chrDstVSubSample);
891  // copy strides, so they can safely be modified
892  int srcStride2[4];
893  int dstStride2[4];
894  int srcSliceY_internal = srcSliceY;
895 
896  if (!srcStride || !dstStride || !dstSlice || !srcSlice) {
897  av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
898  return AVERROR(EINVAL);
899  }
900 
901  if ((srcSliceY & (macro_height_src - 1)) ||
902  ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH != c->srcH) ||
903  srcSliceY + srcSliceH > c->srcH) {
904  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH);
905  return AVERROR(EINVAL);
906  }
907 
908  if ((dstSliceY & (macro_height_dst - 1)) ||
909  ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH != c->dstH) ||
910  dstSliceY + dstSliceH > c->dstH) {
911  av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", dstSliceY, dstSliceH);
912  return AVERROR(EINVAL);
913  }
914 
915  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
916  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
917  return AVERROR(EINVAL);
918  }
919  if (!check_image_pointers((const uint8_t* const*)dstSlice, c->dstFormat, dstStride)) {
920  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
921  return AVERROR(EINVAL);
922  }
923 
924  // do not mess up sliceDir if we have a "trailing" 0-size slice
925  if (srcSliceH == 0)
926  return 0;
927 
928  if (c->gamma_flag && c->cascaded_context[0])
929  return scale_gamma(c, srcSlice, srcStride, srcSliceY, srcSliceH,
930  dstSlice, dstStride, dstSliceY, dstSliceH);
931 
932  if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH)
933  return scale_cascaded(c, srcSlice, srcStride, srcSliceY, srcSliceH,
934  dstSlice, dstStride, dstSliceY, dstSliceH);
935 
936  if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
937  for (i = 0; i < 4; i++)
938  memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
939 
940  if (usePal(c->srcFormat))
941  update_palette(c, (const uint32_t *)srcSlice[1]);
942 
943  memcpy(src2, srcSlice, sizeof(src2));
944  memcpy(dst2, dstSlice, sizeof(dst2));
945  memcpy(srcStride2, srcStride, sizeof(srcStride2));
946  memcpy(dstStride2, dstStride, sizeof(dstStride2));
947 
948  if (frame_start && !scale_dst) {
949  if (srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
950  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
951  return AVERROR(EINVAL);
952  }
953 
954  c->sliceDir = (srcSliceY == 0) ? 1 : -1;
955  } else if (scale_dst)
956  c->sliceDir = 1;
957 
958  if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
959  uint8_t *base;
960  int x,y;
961 
962  av_fast_malloc(&c->rgb0_scratch, &c->rgb0_scratch_allocated,
963  FFABS(srcStride[0]) * srcSliceH + 32);
964  if (!c->rgb0_scratch)
965  return AVERROR(ENOMEM);
966 
967  base = srcStride[0] < 0 ? c->rgb0_scratch - srcStride[0] * (srcSliceH-1) :
968  c->rgb0_scratch;
969  for (y=0; y<srcSliceH; y++){
970  memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
971  for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
972  base[ srcStride[0]*y + x] = 0xFF;
973  }
974  }
975  src2[0] = base;
976  }
977 
978  if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
979  uint8_t *base;
980 
981  av_fast_malloc(&c->xyz_scratch, &c->xyz_scratch_allocated,
982  FFABS(srcStride[0]) * srcSliceH + 32);
983  if (!c->xyz_scratch)
984  return AVERROR(ENOMEM);
985 
986  base = srcStride[0] < 0 ? c->xyz_scratch - srcStride[0] * (srcSliceH-1) :
987  c->xyz_scratch;
988 
989  xyz12Torgb48(c, (uint16_t*)base, (const uint16_t*)src2[0], srcStride[0]/2, srcSliceH);
990  src2[0] = base;
991  }
992 
993  if (c->sliceDir != 1) {
994  // slices go from bottom to top => we flip the image internally
995  for (i=0; i<4; i++) {
996  srcStride2[i] *= -1;
997  dstStride2[i] *= -1;
998  }
999 
1000  src2[0] += (srcSliceH - 1) * srcStride[0];
1001  if (!usePal(c->srcFormat))
1002  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
1003  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
1004  src2[3] += (srcSliceH - 1) * srcStride[3];
1005  dst2[0] += ( c->dstH - 1) * dstStride[0];
1006  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
1007  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
1008  dst2[3] += ( c->dstH - 1) * dstStride[3];
1009 
1010  srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
1011  }
1012  reset_ptr(src2, c->srcFormat);
1013  reset_ptr((void*)dst2, c->dstFormat);
1014 
1015  if (c->convert_unscaled) {
1016  int offset = srcSliceY_internal;
1017  int slice_h = srcSliceH;
1018 
1019  // for dst slice scaling, offset the pointers to match the unscaled API
1020  if (scale_dst) {
1021  av_assert0(offset == 0);
1022  for (i = 0; i < 4 && src2[i]; i++) {
1023  if (!src2[i] || (i > 0 && usePal(c->srcFormat)))
1024  break;
1025  src2[i] += (dstSliceY >> ((i == 1 || i == 2) ? c->chrSrcVSubSample : 0)) * srcStride2[i];
1026  }
1027 
1028  for (i = 0; i < 4 && dst2[i]; i++) {
1029  if (!dst2[i] || (i > 0 && usePal(c->dstFormat)))
1030  break;
1031  dst2[i] -= (dstSliceY >> ((i == 1 || i == 2) ? c->chrDstVSubSample : 0)) * dstStride2[i];
1032  }
1033  offset = dstSliceY;
1034  slice_h = dstSliceH;
1035  }
1036 
1037  ret = c->convert_unscaled(c, src2, srcStride2, offset, slice_h,
1038  dst2, dstStride2);
1039  if (scale_dst)
1040  dst2[0] += dstSliceY * dstStride2[0];
1041  } else {
1042  ret = swscale(c, src2, srcStride2, srcSliceY_internal, srcSliceH,
1043  dst2, dstStride2, dstSliceY, dstSliceH);
1044  }
1045 
1046  if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
1047  uint16_t *dst16;
1048 
1049  if (scale_dst) {
1050  dst16 = (uint16_t *)dst2[0];
1051  } else {
1052  int dstY = c->dstY ? c->dstY : srcSliceY + srcSliceH;
1053 
1054  av_assert0(dstY >= ret);
1055  av_assert0(ret >= 0);
1056  av_assert0(c->dstH >= dstY);
1057  dst16 = (uint16_t*)(dst2[0] + (dstY - ret) * dstStride2[0]);
1058  }
1059 
1060  /* replace on the same data */
1061  rgb48Toxyz12(c, dst16, dst16, dstStride2[0]/2, ret);
1062  }
1063 
1064  /* reset slice direction at end of frame */
1065  if ((srcSliceY_internal + srcSliceH == c->srcH) || scale_dst)
1066  c->sliceDir = 0;
1067 
1068  return ret;
1069 }
1070 
1072 {
1073  av_frame_unref(c->frame_src);
1074  av_frame_unref(c->frame_dst);
1075  c->src_ranges.nb_ranges = 0;
1076 }
1077 
1078 int sws_frame_start(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
1079 {
1080  int ret, allocated = 0;
1081 
1082  ret = av_frame_ref(c->frame_src, src);
1083  if (ret < 0)
1084  return ret;
1085 
1086  if (!dst->buf[0]) {
1087  dst->width = c->dstW;
1088  dst->height = c->dstH;
1089  dst->format = c->dstFormat;
1090 
1091  ret = av_frame_get_buffer(dst, 0);
1092  if (ret < 0)
1093  return ret;
1094  allocated = 1;
1095  }
1096 
1097  ret = av_frame_ref(c->frame_dst, dst);
1098  if (ret < 0) {
1099  if (allocated)
1100  av_frame_unref(dst);
1101 
1102  return ret;
1103  }
1104 
1105  return 0;
1106 }
1107 
1108 int sws_send_slice(struct SwsContext *c, unsigned int slice_start,
1109  unsigned int slice_height)
1110 {
1111  int ret;
1112 
1113  ret = ff_range_add(&c->src_ranges, slice_start, slice_height);
1114  if (ret < 0)
1115  return ret;
1116 
1117  return 0;
1118 }
1119 
1120 unsigned int sws_receive_slice_alignment(const struct SwsContext *c)
1121 {
1122  if (c->slice_ctx)
1123  return c->slice_ctx[0]->dst_slice_align;
1124 
1125  return c->dst_slice_align;
1126 }
1127 
1128 int sws_receive_slice(struct SwsContext *c, unsigned int slice_start,
1129  unsigned int slice_height)
1130 {
1131  unsigned int align = sws_receive_slice_alignment(c);
1132  uint8_t *dst[4];
1133 
1134  /* wait until complete input has been received */
1135  if (!(c->src_ranges.nb_ranges == 1 &&
1136  c->src_ranges.ranges[0].start == 0 &&
1137  c->src_ranges.ranges[0].len == c->srcH))
1138  return AVERROR(EAGAIN);
1139 
1140  if ((slice_start > 0 || slice_height < c->dstH) &&
1141  (slice_start % align || slice_height % align)) {
1143  "Incorrectly aligned output: %u/%u not multiples of %u\n",
1144  slice_start, slice_height, align);
1145  return AVERROR(EINVAL);
1146  }
1147 
1148  if (c->slicethread) {
1149  int nb_jobs = c->slice_ctx[0]->dither == SWS_DITHER_ED ? 1 : c->nb_slice_ctx;
1150  int ret = 0;
1151 
1152  c->dst_slice_start = slice_start;
1153  c->dst_slice_height = slice_height;
1154 
1155  avpriv_slicethread_execute(c->slicethread, nb_jobs, 0);
1156 
1157  for (int i = 0; i < c->nb_slice_ctx; i++) {
1158  if (c->slice_err[i] < 0) {
1159  ret = c->slice_err[i];
1160  break;
1161  }
1162  }
1163 
1164  memset(c->slice_err, 0, c->nb_slice_ctx * sizeof(*c->slice_err));
1165 
1166  return ret;
1167  }
1168 
1169  for (int i = 0; i < FF_ARRAY_ELEMS(dst); i++) {
1170  ptrdiff_t offset = c->frame_dst->linesize[i] * (slice_start >> c->chrDstVSubSample);
1171  dst[i] = FF_PTR_ADD(c->frame_dst->data[i], offset);
1172  }
1173 
1174  return scale_internal(c, (const uint8_t * const *)c->frame_src->data,
1175  c->frame_src->linesize, 0, c->srcH,
1176  dst, c->frame_dst->linesize, slice_start, slice_height);
1177 }
1178 
1179 int sws_scale_frame(struct SwsContext *c, AVFrame *dst, const AVFrame *src)
1180 {
1181  int ret;
1182 
1183  ret = sws_frame_start(c, dst, src);
1184  if (ret < 0)
1185  return ret;
1186 
1187  ret = sws_send_slice(c, 0, src->height);
1188  if (ret >= 0)
1189  ret = sws_receive_slice(c, 0, dst->height);
1190 
1191  sws_frame_end(c);
1192 
1193  return ret;
1194 }
1195 
1196 /**
1197  * swscale wrapper, so we don't need to export the SwsContext.
1198  * Assumes planar YUV to be in YUV order instead of YVU.
1199  */
1200 int attribute_align_arg sws_scale(struct SwsContext *c,
1201  const uint8_t * const srcSlice[],
1202  const int srcStride[], int srcSliceY,
1203  int srcSliceH, uint8_t *const dst[],
1204  const int dstStride[])
1205 {
1206  if (c->nb_slice_ctx)
1207  c = c->slice_ctx[0];
1208 
1209  return scale_internal(c, srcSlice, srcStride, srcSliceY, srcSliceH,
1210  dst, dstStride, 0, c->dstH);
1211 }
1212 
1213 void ff_sws_slice_worker(void *priv, int jobnr, int threadnr,
1214  int nb_jobs, int nb_threads)
1215 {
1216  SwsContext *parent = priv;
1217  SwsContext *c = parent->slice_ctx[threadnr];
1218 
1219  const int slice_height = FFALIGN(FFMAX((parent->dst_slice_height + nb_jobs - 1) / nb_jobs, 1),
1220  c->dst_slice_align);
1221  const int slice_start = jobnr * slice_height;
1222  const int slice_end = FFMIN((jobnr + 1) * slice_height, parent->dst_slice_height);
1223  int err = 0;
1224 
1225  if (slice_end > slice_start) {
1226  uint8_t *dst[4] = { NULL };
1227 
1228  for (int i = 0; i < FF_ARRAY_ELEMS(dst) && parent->frame_dst->data[i]; i++) {
1229  const int vshift = (i == 1 || i == 2) ? c->chrDstVSubSample : 0;
1230  const ptrdiff_t offset = parent->frame_dst->linesize[i] *
1231  ((slice_start + parent->dst_slice_start) >> vshift);
1232 
1233  dst[i] = parent->frame_dst->data[i] + offset;
1234  }
1235 
1236  err = scale_internal(c, (const uint8_t * const *)parent->frame_src->data,
1237  parent->frame_src->linesize, 0, c->srcH,
1238  dst, parent->frame_dst->linesize,
1239  parent->dst_slice_start + slice_start, slice_end - slice_start);
1240  }
1241 
1242  parent->slice_err[threadnr] = err;
1243 }
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:254
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:381
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:2662
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: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:380
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:1200
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:100
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:878
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:1108
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:859
xyz12Torgb48
static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, const uint16_t *src, int stride, int h)
Definition: swscale.c:632
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:1128
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:33
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
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: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:1595
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:1078
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:825
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:382
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:469
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:99
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:2516
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:1213
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:744
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:343
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:379
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:1179
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:271
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:1120
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:615
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:477
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:2587
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:1071
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: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:603
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:561
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:153
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:688
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