Go to the documentation of this file.
43 { 36, 68, 60, 92, 34, 66, 58, 90, },
44 { 100, 4, 124, 28, 98, 2, 122, 26, },
45 { 52, 84, 44, 76, 50, 82, 42, 74, },
46 { 116, 20, 108, 12, 114, 18, 106, 10, },
47 { 32, 64, 56, 88, 38, 70, 62, 94, },
48 { 96, 0, 120, 24, 102, 6, 126, 30, },
49 { 48, 80, 40, 72, 54, 86, 46, 78, },
50 { 112, 16, 104, 8, 118, 22, 110, 14, },
51 { 36, 68, 60, 92, 34, 66, 58, 90, },
55 64, 64, 64, 64, 64, 64, 64, 64
62 uint8_t *ptr = plane +
stride * y;
71 const int32_t *filterPos,
int filterSize)
76 const uint16_t *
src = (
const uint16_t *)
_src;
86 for (
i = 0;
i < dstW;
i++) {
88 int srcPos = filterPos[
i];
91 for (j = 0; j < filterSize; j++) {
101 const int32_t *filterPos,
int filterSize)
105 const uint16_t *
src = (
const uint16_t *)
_src;
106 int sh =
desc->comp[0].depth - 1;
114 for (
i = 0;
i < dstW;
i++) {
116 int srcPos = filterPos[
i];
119 for (j = 0; j < filterSize; j++) {
129 const uint8_t *
src,
const int16_t *
filter,
130 const int32_t *filterPos,
int filterSize)
133 for (
i = 0;
i < dstW;
i++) {
135 int srcPos = filterPos[
i];
137 for (j = 0; j < filterSize; j++) {
145 const uint8_t *
src,
const int16_t *
filter,
146 const int32_t *filterPos,
int filterSize)
150 for (
i = 0;
i < dstW;
i++) {
152 int srcPos = filterPos[
i];
154 for (j = 0; j < filterSize; j++) {
164 uint32_t _coeff,
int64_t _offset)
166 uint16_t
coeff = _coeff;
172 dstU[
i] =
FFMIN(
U, (1 << 15) - 1);
173 dstV[
i] =
FFMIN(
V, (1 << 15) - 1);
178 uint32_t _coeff,
int64_t _offset)
180 uint16_t
coeff = _coeff;
190 uint32_t _coeff,
int64_t _offset)
192 uint16_t
coeff = _coeff;
202 uint32_t _coeff,
int64_t _offset)
204 uint16_t
coeff = _coeff;
220 dstU[
i] =
FFMIN(
U, (1 << 19) - 1);
221 dstV[
i] =
FFMIN(
V, (1 << 19) - 1);
258 #define DEBUG_SWSCALE_BUFFERS 0
259 #define DEBUG_BUFFERS(...) \
260 if (DEBUG_SWSCALE_BUFFERS) \
261 av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
264 int srcSliceY,
int srcSliceH, uint8_t *
const dst[],
265 const int dstStride[],
int dstSliceY,
int dstSliceH)
267 const int scale_dst = dstSliceY > 0 || dstSliceH <
c->opts.dst_h;
271 const int dstW =
c->opts.dst_w;
272 int dstH =
c->opts.dst_h;
275 const int flags =
c->opts.flags;
276 int32_t *vLumFilterPos =
c->vLumFilterPos;
277 int32_t *vChrFilterPos =
c->vChrFilterPos;
279 const int vLumFilterSize =
c->vLumFilterSize;
280 const int vChrFilterSize =
c->vChrFilterSize;
289 const int chrSrcSliceY = srcSliceY >>
c->chrSrcVSubSample;
290 const int chrSrcSliceH =
AV_CEIL_RSHIFT(srcSliceH,
c->chrSrcVSubSample);
291 int should_dither =
isNBPS(
c->opts.src_format) ||
297 int lastInLumBuf =
c->lastInLumBuf;
298 int lastInChrBuf =
c->lastInChrBuf;
301 int lumEnd =
c->descIndex[0];
302 int chrStart = lumEnd;
303 int chrEnd =
c->descIndex[1];
305 int vEnd =
c->numDesc;
306 SwsSlice *src_slice = &
c->slice[lumStart];
307 SwsSlice *hout_slice = &
c->slice[
c->numSlice-2];
308 SwsSlice *vout_slice = &
c->slice[
c->numSlice-1];
311 int needAlpha =
c->needAlpha;
316 const uint8_t *
src2[4];
327 srcStride2[3] = srcStride[0];
330 memcpy(srcStride2, srcStride,
sizeof(srcStride2));
333 srcStride2[1] *= 1 <<
c->vChrDrop;
334 srcStride2[2] *= 1 <<
c->vChrDrop;
336 DEBUG_BUFFERS(
"swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
337 src2[0], srcStride2[0],
src2[1], srcStride2[1],
338 src2[2], srcStride2[2],
src2[3], srcStride2[3],
339 dst[0], dstStride[0],
dst[1], dstStride[1],
340 dst[2], dstStride[2],
dst[3], dstStride[3]);
341 DEBUG_BUFFERS(
"srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
342 srcSliceY, srcSliceH, dstY, dstH);
344 vLumFilterSize, vChrFilterSize);
346 if (dstStride[0]&15 || dstStride[1]&15 ||
347 dstStride[2]&15 || dstStride[3]&15) {
352 "Warning: dstStride is not aligned!\n"
353 " ->cannot do aligned memory accesses anymore\n");
358 if ( (uintptr_t)
dst[0]&15 || (uintptr_t)
dst[1]&15 || (uintptr_t)
dst[2]&15
359 || (uintptr_t)
src2[0]&15 || (uintptr_t)
src2[1]&15 || (uintptr_t)
src2[2]&15
360 || srcStride2[0]&15 || srcStride2[1]&15 || srcStride2[2]&15 || srcStride2[3]&15
373 dstH = dstY + dstSliceH;
376 }
else if (srcSliceY == 0) {
385 if (!should_dither) {
391 yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX,
c->use_mmx_vfilter);
394 srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
397 dstY, dstSliceH, dstY >>
c->chrDstVSubSample,
399 if (srcSliceY == 0) {
409 hout_slice->
width = dstW;
412 for (; dstY < dstH; dstY++) {
413 const int chrDstY = dstY >>
c->chrDstVSubSample;
414 int use_mmx_vfilter=
c->use_mmx_vfilter;
417 const int firstLumSrcY =
FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
418 const int firstLumSrcY2 =
FFMAX(1 - vLumFilterSize, vLumFilterPos[
FFMIN(dstY | ((1 <<
c->chrDstVSubSample) - 1),
c->opts.dst_h - 1)]);
420 const int firstChrSrcY =
FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
423 int lastLumSrcY =
FFMIN(
c->opts.src_h, firstLumSrcY + vLumFilterSize) - 1;
424 int lastLumSrcY2 =
FFMIN(
c->opts.src_h, firstLumSrcY2 + vLumFilterSize) - 1;
425 int lastChrSrcY =
FFMIN(
c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
429 int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;
432 if (firstLumSrcY > lastInLumBuf) {
434 hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
442 lastInLumBuf = firstLumSrcY - 1;
444 if (firstChrSrcY > lastInChrBuf) {
446 hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
454 lastInChrBuf = firstChrSrcY - 1;
458 DEBUG_BUFFERS(
"\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
459 firstLumSrcY, lastLumSrcY, lastInLumBuf);
460 DEBUG_BUFFERS(
"\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
461 firstChrSrcY, lastChrSrcY, lastInChrBuf);
464 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
465 lastChrSrcY <
AV_CEIL_RSHIFT(srcSliceY + srcSliceH,
c->chrSrcVSubSample);
468 lastLumSrcY = srcSliceY + srcSliceH - 1;
469 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
470 DEBUG_BUFFERS(
"buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
471 lastLumSrcY, lastChrSrcY);
479 if (posY <= lastLumSrcY && !hasLumHoles) {
480 firstPosY =
FFMAX(firstLumSrcY, posY);
484 lastPosY = lastLumSrcY;
488 if (cPosY <= lastChrSrcY && !hasChrHoles) {
489 firstCPosY =
FFMAX(firstChrSrcY, cPosY);
493 lastCPosY = lastChrSrcY;
498 if (posY < lastLumSrcY + 1) {
499 for (
i = lumStart;
i < lumEnd; ++
i)
503 lastInLumBuf = lastLumSrcY;
505 if (cPosY < lastChrSrcY + 1) {
506 for (
i = chrStart;
i < chrEnd; ++
i)
510 lastInChrBuf = lastChrSrcY;
517 c->dstW_mmx =
c->opts.dst_w;
523 if (dstY >=
c->opts.dst_h - 2) {
527 &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
530 yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
533 for (
i = vStart;
i < vEnd; ++
i)
537 int offset = lastDstY - dstSliceY;
539 int height = dstY - lastDstY;
544 1,
desc->comp[3].depth,
546 }
else if (
is32BPS(dstFormat)) {
549 1,
desc->comp[3].depth,
555 #if HAVE_MMXEXT_INLINE
557 __asm__ volatile (
"sfence" :::
"memory");
563 c->lastInLumBuf = lastInLumBuf;
564 c->lastInChrBuf = lastInChrBuf;
566 return dstY - lastDstY;
578 uint16_t dst_min, uint16_t dst_max,
579 int src_bits,
int src_shift,
int mult_shift,
582 uint16_t src_range = src_max - src_min;
583 uint16_t dst_range = dst_max - dst_min;
584 int total_shift = mult_shift + src_shift;
588 (1
U << (mult_shift - 1));
594 const int src_bits =
bit_depth <= 14 ? 15 : 19;
595 const int src_shift = src_bits -
bit_depth;
596 const int mult_shift =
bit_depth <= 14 ? 14 : 18;
597 const uint16_t mpeg_min = 16
U << (
bit_depth - 8);
598 const uint16_t mpeg_max_lum = 235
U << (
bit_depth - 8);
599 const uint16_t mpeg_max_chr = 240
U << (
bit_depth - 8);
600 const uint16_t jpeg_max = (1
U <<
bit_depth) - 1;
601 uint16_t src_min, src_max_lum, src_max_chr;
602 uint16_t dst_min, dst_max_lum, dst_max_chr;
603 if (
c->opts.src_range) {
605 src_max_lum = jpeg_max;
606 src_max_chr = jpeg_max;
608 dst_max_lum = mpeg_max_lum;
609 dst_max_chr = mpeg_max_chr;
612 src_max_lum = mpeg_max_lum;
613 src_max_chr = mpeg_max_chr;
615 dst_max_lum = jpeg_max;
616 dst_max_chr = jpeg_max;
619 src_bits, src_shift, mult_shift,
620 &
c->lumConvertRange_coeff, &
c->lumConvertRange_offset);
622 src_bits, src_shift, mult_shift,
623 &
c->chrConvertRange_coeff, &
c->chrConvertRange_offset);
628 c->lumConvertRange =
NULL;
629 c->chrConvertRange =
NULL;
630 if (
c->opts.src_range !=
c->opts.dst_range && !
isAnyRGB(
c->opts.dst_format) &&
c->dstBpc < 32) {
632 if (
c->dstBpc <= 14) {
633 if (
c->opts.src_range) {
641 if (
c->opts.src_range) {
652 #elif ARCH_LOONGARCH64
669 &
c->yuv2nv12cX, &
c->yuv2packed1,
670 &
c->yuv2packed2, &
c->yuv2packedX, &
c->yuv2anyX);
673 &
c->readLumPlanar, &
c->readAlpPlanar, &
c->readChrPlanar);
675 if (
c->srcBpc == 8) {
676 if (
c->dstBpc <= 14) {
694 c->needs_hcscale = 1;
709 #elif ARCH_LOONGARCH64
729 const int linesizes[4])
736 for (
i = 0;
i < 4;
i++) {
737 int plane =
desc->comp[
i].plane;
738 if (!
data[plane] || !linesizes[plane])
746 const uint8_t *
src,
int src_stride,
int w,
int h)
750 for (
int yp = 0; yp <
h; yp++) {
751 const uint16_t *src16 = (
const uint16_t *)
src;
752 uint16_t *dst16 = (uint16_t *)
dst;
754 for (
int xp = 0; xp < 3 *
w; xp += 3) {
755 int x, y, z,
r,
g,
b;
767 x =
c->xyz2rgb.gamma.in[x >> 4];
768 y =
c->xyz2rgb.gamma.in[y >> 4];
769 z =
c->xyz2rgb.gamma.in[z >> 4];
772 r =
c->xyz2rgb.mat[0][0] * x +
773 c->xyz2rgb.mat[0][1] * y +
774 c->xyz2rgb.mat[0][2] * z >> 12;
775 g =
c->xyz2rgb.mat[1][0] * x +
776 c->xyz2rgb.mat[1][1] * y +
777 c->xyz2rgb.mat[1][2] * z >> 12;
778 b =
c->xyz2rgb.mat[2][0] * x +
779 c->xyz2rgb.mat[2][1] * y +
780 c->xyz2rgb.mat[2][2] * z >> 12;
789 AV_WB16(dst16 + xp + 0,
c->xyz2rgb.gamma.out[
r] << 4);
790 AV_WB16(dst16 + xp + 1,
c->xyz2rgb.gamma.out[
g] << 4);
791 AV_WB16(dst16 + xp + 2,
c->xyz2rgb.gamma.out[
b] << 4);
793 AV_WL16(dst16 + xp + 0,
c->xyz2rgb.gamma.out[
r] << 4);
794 AV_WL16(dst16 + xp + 1,
c->xyz2rgb.gamma.out[
g] << 4);
795 AV_WL16(dst16 + xp + 2,
c->xyz2rgb.gamma.out[
b] << 4);
805 const uint8_t *
src,
int src_stride,
int w,
int h)
809 for (
int yp = 0; yp <
h; yp++) {
810 uint16_t *src16 = (uint16_t *)
src;
811 uint16_t *dst16 = (uint16_t *)
dst;
813 for (
int xp = 0; xp < 3 *
w; xp += 3) {
814 int x, y, z,
r,
g,
b;
826 r =
c->rgb2xyz.gamma.in[
r >> 4];
827 g =
c->rgb2xyz.gamma.in[
g >> 4];
828 b =
c->rgb2xyz.gamma.in[
b >> 4];
831 x =
c->rgb2xyz.mat[0][0] *
r +
832 c->rgb2xyz.mat[0][1] *
g +
833 c->rgb2xyz.mat[0][2] *
b >> 12;
834 y =
c->rgb2xyz.mat[1][0] *
r +
835 c->rgb2xyz.mat[1][1] *
g +
836 c->rgb2xyz.mat[1][2] *
b >> 12;
837 z =
c->rgb2xyz.mat[2][0] *
r +
838 c->rgb2xyz.mat[2][1] *
g +
839 c->rgb2xyz.mat[2][2] *
b >> 12;
848 AV_WB16(dst16 + xp + 0,
c->rgb2xyz.gamma.out[x] << 4);
849 AV_WB16(dst16 + xp + 1,
c->rgb2xyz.gamma.out[y] << 4);
850 AV_WB16(dst16 + xp + 2,
c->rgb2xyz.gamma.out[z] << 4);
852 AV_WL16(dst16 + xp + 0,
c->rgb2xyz.gamma.out[x] << 4);
853 AV_WL16(dst16 + xp + 1,
c->rgb2xyz.gamma.out[y] << 4);
854 AV_WL16(dst16 + xp + 2,
c->rgb2xyz.gamma.out[z] << 4);
875 uint32_t *
rgb2yuv =
c->input_rgb2yuv_table;
881 for (
int i = 0;
i < 256;
i++) {
882 int r,
g,
b, y,
u, v,
a = 0xff;
885 a = (
p >> 24) & 0xFF;
886 r = (
p >> 16) & 0xFF;
891 g = ((
i >> 2) & 7) * 36;
895 g = ((
i >> 3) & 7) * 36;
898 r = (
i >> 3 ) * 255;
899 g = ((
i >> 1) & 3) * 85;
905 b = (
i >> 3 ) * 255;
906 g = ((
i >> 1) & 3) * 85;
914 c->pal_yuv[
i]= y + (
u<<8) + (v<<16) + ((unsigned)
a<<24);
916 switch (
c->opts.dst_format) {
921 c->pal_rgb[
i]=
r + (
g<<8) + (
b<<16) + ((unsigned)
a<<24);
927 c->pal_rgb[
i]=
a + (
r<<8) + (
g<<16) + ((unsigned)
b<<24);
933 c->pal_rgb[
i]=
a + (
b<<8) + (
g<<16) + ((unsigned)
r<<24);
938 c->pal_rgb[
i]=
a + (
r<<8) + (
b<<16) + ((unsigned)
g<<24);
940 c->pal_rgb[
i]=
g + (
b<<8) + (
r<<16) + ((unsigned)
a<<24);
948 c->pal_rgb[
i]=
b + (
g<<8) + (
r<<16) + ((unsigned)
a<<24);
954 const uint8_t *
const srcSlice[],
const int srcStride[],
955 int srcSliceY,
int srcSliceH,
956 uint8_t *
const dstSlice[],
const int dstStride[],
957 int dstSliceY,
int dstSliceH);
960 const uint8_t *
const srcSlice[],
const int srcStride[],
961 int srcSliceY,
int srcSliceH,
962 uint8_t *
const dstSlice[],
const int dstStride[],
963 int dstSliceY,
int dstSliceH)
966 srcSlice, srcStride, srcSliceY, srcSliceH,
967 c->cascaded_tmp[0],
c->cascaded_tmpStride[0], 0,
c->opts.src_h);
972 if (
c->cascaded_context[2])
974 c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
975 c->cascaded_tmp[1],
c->cascaded_tmpStride[1], 0,
c->opts.dst_h);
978 c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
979 dstSlice, dstStride, dstSliceY, dstSliceH);
984 if (
c->cascaded_context[2]) {
987 c->cascaded_tmpStride[1], dstY1 -
ret, dstY1,
988 dstSlice, dstStride, dstSliceY, dstSliceH);
994 const uint8_t *
const srcSlice[],
const int srcStride[],
995 int srcSliceY,
int srcSliceH,
996 uint8_t *
const dstSlice[],
const int dstStride[],
997 int dstSliceY,
int dstSliceH)
999 const int dstH0 =
c->cascaded_context[0]->dst_h;
1001 srcSlice, srcStride, srcSliceY, srcSliceH,
1002 c->cascaded_tmp[0],
c->cascaded_tmpStride[0],
1007 (
const uint8_t *
const * )
c->cascaded_tmp[0],
c->cascaded_tmpStride[0],
1008 0, dstH0, dstSlice, dstStride, dstSliceY, dstSliceH);
1013 const uint8_t *
const srcSlice[],
const int srcStride[],
1014 int srcSliceY,
int srcSliceH,
1015 uint8_t *
const dstSlice[],
const int dstStride[],
1016 int dstSliceY,
int dstSliceH)
1019 const int scale_dst = dstSliceY > 0 || dstSliceH < sws->
dst_h;
1022 const uint8_t *
src2[4];
1029 int srcSliceY_internal = srcSliceY;
1031 if (!srcStride || !dstStride || !dstSlice || !srcSlice) {
1032 av_log(
c,
AV_LOG_ERROR,
"One of the input parameters to sws_scale() is NULL, please check the calling code\n");
1036 if ((srcSliceY & (macro_height_src - 1)) ||
1037 ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH != sws->
src_h) ||
1038 srcSliceY + srcSliceH > sws->
src_h ||
1044 if ((dstSliceY & (macro_height_dst - 1)) ||
1045 ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH != sws->
dst_h) ||
1046 dstSliceY + dstSliceH > sws->
dst_h) {
1065 return scale_gamma(
c, srcSlice, srcStride, srcSliceY, srcSliceH,
1066 dstSlice, dstStride, dstSliceY, dstSliceH);
1068 if (
c->cascaded_context[0] && srcSliceY == 0 && srcSliceH ==
c->cascaded_context[0]->src_h)
1070 dstSlice, dstStride, dstSliceY, dstSliceH);
1073 for (
i = 0;
i < 4;
i++)
1074 memset(
c->dither_error[
i], 0,
sizeof(
c->dither_error[0][0]) * (sws->
dst_w+2));
1079 memcpy(
src2, srcSlice,
sizeof(
src2));
1080 memcpy(dst2, dstSlice,
sizeof(dst2));
1081 memcpy(srcStride2, srcStride,
sizeof(srcStride2));
1082 memcpy(dstStride2, dstStride,
sizeof(dstStride2));
1085 if (srcSliceY != 0 && srcSliceY + srcSliceH != sws->
src_h) {
1090 c->sliceDir = (srcSliceY == 0) ? 1 : -1;
1091 }
else if (scale_dst)
1099 FFABS(srcStride[0]) * srcSliceH + 32);
1100 if (!
c->rgb0_scratch)
1103 base = srcStride[0] < 0 ?
c->rgb0_scratch - srcStride[0] * (srcSliceH-1) :
1105 for (y=0; y<srcSliceH; y++){
1106 memcpy(
base + srcStride[0]*y,
src2[0] + srcStride[0]*y, 4*sws->
src_w);
1107 for (x=
c->src0Alpha-1; x<4*sws->src_w; x+=4) {
1108 base[ srcStride[0]*y + x] = 0xFF;
1118 FFABS(srcStride[0]) * srcSliceH + 32);
1119 if (!
c->xyz_scratch)
1122 base = srcStride[0] < 0 ?
c->xyz_scratch - srcStride[0] * (srcSliceH-1) :
1125 c->xyz12Torgb48(
c,
base, srcStride[0],
src2[0], srcStride[0], sws->
src_w, srcSliceH);
1129 if (
c->sliceDir != 1) {
1131 for (
i=0;
i<4;
i++) {
1132 srcStride2[
i] *= -1;
1133 dstStride2[
i] *= -1;
1136 src2[0] += (srcSliceH - 1) * srcStride[0];
1138 src2[1] += ((srcSliceH >>
c->chrSrcVSubSample) - 1) * srcStride[1];
1139 src2[2] += ((srcSliceH >>
c->chrSrcVSubSample) - 1) * srcStride[2];
1140 src2[3] += (srcSliceH - 1) * srcStride[3];
1141 dst2[0] += ( sws->
dst_h - 1) * dstStride[0];
1142 dst2[1] += ((sws->
dst_h >>
c->chrDstVSubSample) - 1) * dstStride[1];
1143 dst2[2] += ((sws->
dst_h >>
c->chrDstVSubSample) - 1) * dstStride[2];
1144 dst2[3] += ( sws->
dst_h - 1) * dstStride[3];
1146 srcSliceY_internal = sws->
src_h-srcSliceY-srcSliceH;
1151 if (
c->convert_unscaled) {
1152 int offset = srcSliceY_internal;
1153 int slice_h = srcSliceH;
1158 for (
i = 0;
i < 4 &&
src2[
i];
i++) {
1161 src2[
i] += (dstSliceY >> ((
i == 1 ||
i == 2) ?
c->chrSrcVSubSample : 0)) * srcStride2[
i];
1164 for (
i = 0;
i < 4 && dst2[
i];
i++) {
1167 dst2[
i] -= (dstSliceY >> ((
i == 1 ||
i == 2) ?
c->chrDstVSubSample : 0)) * dstStride2[
i];
1170 slice_h = dstSliceH;
1176 dst2[0] += dstSliceY * dstStride2[0];
1179 dst2, dstStride2, dstSliceY, dstSliceH);
1188 int dstY =
c->dstY ?
c->dstY : srcSliceY + srcSliceH;
1193 dst = dst2[0] + (dstY -
ret) * dstStride2[0];
1197 c->rgb48Toxyz12(
c,
dst, dstStride2[0],
dst, dstStride2[0], sws->
dst_w,
ret);
1201 if ((srcSliceY_internal + srcSliceH == sws->
src_h) || scale_dst)
1210 if (!
c->is_legacy_init)
1214 c->src_ranges.nb_ranges = 0;
1224 for (
int i = 0;
i < nb_planes;
i++) {
1238 int ret, allocated = 0;
1239 if (!
c->is_legacy_init)
1269 unsigned int slice_height)
1273 if (!
c->is_legacy_init)
1289 return c->dst_slice_align;
1293 unsigned int slice_height)
1298 if (!
c->is_legacy_init)
1302 if (!(
c->src_ranges.nb_ranges == 1 &&
1303 c->src_ranges.ranges[0].start == 0 &&
1304 c->src_ranges.ranges[0].len == sws->
src_h))
1307 if ((
slice_start > 0 || slice_height < sws->dst_h) &&
1310 "Incorrectly aligned output: %u/%u not multiples of %u\n",
1315 if (
c->slicethread) {
1316 int nb_jobs =
c->nb_slice_ctx;
1323 c->dst_slice_height = slice_height;
1327 for (
int i = 0;
i <
c->nb_slice_ctx;
i++) {
1328 if (
c->slice_err[
i] < 0) {
1329 ret =
c->slice_err[
i];
1334 memset(
c->slice_err, 0,
c->nb_slice_ctx *
sizeof(*
c->slice_err));
1340 ptrdiff_t
offset =
c->frame_dst->linesize[
i] * (ptrdiff_t)(
slice_start >>
c->chrDstVSubSample);
1344 return scale_internal(sws, (
const uint8_t *
const *)
c->frame_src->data,
1345 c->frame_src->linesize, 0, sws->
src_h,
1361 memcpy(
dst->data,
src->data,
sizeof(
src->data));
1362 memcpy(
dst->linesize,
src->linesize,
sizeof(
src->linesize));
1368 int ret, allocated = 0;
1373 if (
c->is_legacy_init) {
1402 memset(
dst->buf, 0,
sizeof(
dst->buf));
1403 memset(
dst->data, 0,
sizeof(
dst->data));
1404 memset(
dst->linesize, 0,
sizeof(
dst->linesize));
1405 dst->extended_data =
dst->data;
1407 if (
src->buf[0] && top->
noop && (!bot || bot->
noop))
1430 #define VALIDATE(field, min, max) \
1431 if (ctx->field < min || ctx->field > max) { \
1432 av_log(ctx, AV_LOG_ERROR, "'%s' (%d) out of range [%d, %d]\n", \
1433 #field, (int) ctx->field, min, max); \
1434 return AVERROR(EINVAL); \
1446 const char *err_msg;
1455 if (!!
src->hw_frames_ctx != !!
dst->hw_frames_ctx) {
1457 }
else if (!!
src->hw_frames_ctx) {
1459 if (!
src->data[0] || !
dst->data[0])
1476 #if CONFIG_UNSTABLE && CONFIG_VULKAN
1483 int dst_width =
dst->width;
1490 err_msg =
"Cannot convert interlaced to progressive frames or vice versa.\n";
1497 if ((!src_ok || !dst_ok) && !
ff_props_equal(&src_fmt, &dst_fmt)) {
1498 err_msg = src_ok ?
"Unsupported output" :
"Unsupported input";
1505 err_msg =
"Failed initializing scaling graph";
1511 err_msg =
"Incomplete scaling graph";
1520 dst_width =
FFMAX(dst_width, aligned_w);
1532 " fmt:%s csp:%s prim:%s trc:%s\n",
1545 if (!
dst->hw_frames_ctx) {
1560 const uint8_t *
const srcSlice[],
1561 const int srcStride[],
int srcSliceY,
1562 int srcSliceH, uint8_t *
const dst[],
1563 const int dstStride[])
1566 if (!
c->is_legacy_init)
1569 if (
c->nb_slice_ctx) {
1570 sws =
c->slice_ctx[0];
1574 return scale_internal(sws, srcSlice, srcStride, srcSliceY, srcSliceH,
1579 int nb_jobs,
int nb_threads)
1586 c->dst_slice_align);
1595 const int vshift = (
i == 1 ||
i == 2) ?
c->chrDstVSubSample : 0;
static av_cold void sws_init_swscale(SwsInternal *c)
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
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 (...
#define AV_LOG_WARNING
Something somehow does not look correct.
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
AVPixelFormat
Pixel format.
int sliceH
number of lines
Represents a single filter pass in the scaling graph.
static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
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
SwsPass ** passes
Sorted sequence of filter passes to apply.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
static void lumRangeToJpeg16_c(int16_t *_dst, int width, uint32_t coeff, int64_t offset)
static void lumRangeToJpeg_c(int16_t *dst, int width, uint32_t _coeff, int64_t _offset)
av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c)
static void frame_start(MPVMainEncContext *const m)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
int src_w
Deprecated frame property overrides, for the legacy API only.
uint8_t * data
The data buffer.
static av_always_inline int process_frame(AVTextFormatContext *tfc, InputFile *ifile, AVFrame *frame, const AVPacket *pkt, int *packet_new)
int ff_sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src, int field, SwsGraph **out_graph)
Wrapper around ff_sws_graph_create() that reuses the existing graph if the format is compatible.
int ff_rotate_slice(SwsSlice *s, int lum, int chr)
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
SwsPlane plane[MAX_SLICE_PLANES]
color planes
void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading.
av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c)
This structure describes decoded (raw) audio or video data.
#define u(width, name, range_min, range_max)
static av_always_inline int isGray(enum AVPixelFormat pix_fmt)
Struct which holds all necessary data for processing a slice.
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)
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
static const char rgb2yuv[]
#define AV_PIX_FMT_RGB32_1
unsigned flags
Bitmask of SWS_*.
void(* filter)(uint8_t *src, int stride, int qscale)
int sws_receive_slice(SwsContext *sws, 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...
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
av_cold void ff_sws_init_swscale_riscv(SwsInternal *c)
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
#define DEBUG_BUFFERS(...)
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
static atomic_int cpu_flags
static void hScale16To15_c(SwsInternal *c, int16_t *dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
uint8_t ptrdiff_t const uint8_t * _src
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
@ AV_HWDEVICE_TYPE_VULKAN
@ SWS_FAST_BILINEAR
Scaler selection options.
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
void ff_sws_init_input_funcs(SwsInternal *c, planar1_YV12_fn *lumToYV12, planar1_YV12_fn *alpToYV12, planar2_YV12_fn *chrToYV12, planarX_YV12_fn *readLumPlanar, planarX_YV12_fn *readAlpPlanar, planarX2_YV12_fn *readChrPlanar)
static int validate_params(SwsContext *ctx)
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width, uint32_t coeff, int64_t offset)
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
const char * av_color_space_name(enum AVColorSpace space)
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width, uint32_t _coeff, int64_t _offset)
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width, uint32_t coeff, int64_t offset)
int sws_frame_setup(SwsContext *ctx, const AVFrame *dst, const AVFrame *src)
Like sws_scale_frame, but without actually scaling.
av_cold void ff_sws_init_xyzdsp_aarch64(SwsInternal *c)
static double val(void *priv, double ch)
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
static void init_range_convert_constants(SwsInternal *c)
enum AVColorTransferCharacteristic trc
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
static void hScale8To19_c(SwsInternal *c, int16_t *_dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
void(* yuv2packed2_fn)(SwsInternal *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...
SwsDither dither
Dither mode.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref)
static const uint16_t dither[8][8]
void ff_update_palette(SwsInternal *c, const uint32_t *pal)
#define AV_CEIL_RSHIFT(a, b)
av_cold void ff_sws_init_swscale_arm(SwsInternal *c)
int flags
Flags modifying the (de)muxer behaviour.
static enum AVPixelFormat pix_fmt
int width
Slice line width.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define VALIDATE(field, min, max)
static AVFormatContext * ctx
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width, uint32_t _coeff, int64_t _offset)
void ff_hcscale_fast_c(SwsInternal *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
static int frame_alloc_buffers(SwsContext *sws, AVFrame *frame)
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 field
av_cold void ff_sws_init_range_convert_riscv(SwsInternal *c)
#define AV_PIX_FMT_BGR32_1
void sws_frame_end(SwsContext *sws)
Finish the scaling process for a pair of source/destination frames previously submitted with sws_fram...
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
av_cold void ff_sws_init_range_convert_x86(SwsInternal *c)
@ AV_PIX_FMT_GRAY8A
alias for AV_PIX_FMT_YA8
static int scale_internal(SwsContext *sws, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
static void rgb48Toxyz12_c(const SwsInternal *c, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int w, int h)
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
int available_lines
max number of lines that can be hold by this plane
int gamma_flag
Use gamma correct scaling.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
#define FF_PTR_ADD(ptr, off)
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
static void hScale8To15_c(SwsInternal *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
av_cold void ff_sws_init_range_convert(SwsInternal *c)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
static void hScale16To19_c(SwsInternal *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize)
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
int dstY
Last destination vertical line output from last slice.
av_cold void ff_sws_init_xyzdsp(SwsInternal *c)
int ff_sws_pass_aligned_width(const SwsPass *pass, int width)
Align width to the optimal size for pass.
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
int ff_range_add(RangeList *r, unsigned int start, unsigned int len)
#define attribute_align_arg
void(* yuv2packedX_fn)(SwsInternal *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...
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
void ff_sws_graph_free(SwsGraph **pgraph)
Uninitialize any state associate with this filter graph and free it.
void ff_sws_slice_worker(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
av_cold void ff_sws_init_swscale_loongarch(SwsInternal *c)
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
#define DECLARE_ALIGNED(n, t, v)
static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
#define i(width, name, range_min, range_max)
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
int src_h
Width and height of the source frame.
static void xyz12Torgb48_c(const SwsInternal *c, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int w, int h)
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
static av_always_inline int is32BPS(enum AVPixelFormat pix_fmt)
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
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
static void lumRangeFromJpeg_c(int16_t *dst, int width, uint32_t _coeff, int64_t _offset)
av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
int dst_format
Destination pixel format.
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)
void(* yuv2anyX_fn)(SwsInternal *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...
av_cold void ff_sws_init_swscale_x86(SwsInternal *c)
static int scale_cascaded(SwsInternal *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
unsigned int dst_slice_align
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
int sws_send_slice(SwsContext *sws, 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...
void ff_sws_init_scale(SwsInternal *c)
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int check_image_pointers(const uint8_t *const data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
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 ...
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int dst_h
Width and height of the destination frame.
void ff_updateMMXDitherTables(SwsInternal *c, int dstY)
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
int ff_init_slice_from_src(SwsSlice *s, uint8_t *const src[4], const int stride[4], int srcW, int lumY, int lumH, int chrY, int chrH, int relative)
This struct describes a set or pool of "hardware" frames (i.e.
static int frame_ref(AVFrame *dst, const AVFrame *src)
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
void(* yuv2packed1_fn)(SwsInternal *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...
unsigned int sws_receive_slice_alignment(const SwsContext *sws)
Get the alignment required for slices.
__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")
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
int sws_frame_start(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Initialize the scaling process for a given pair of source/destination frames.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
static const uint8_t sws_pb_64[8]
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...
static void reset_ptr(const uint8_t *src[], enum AVPixelFormat format)
void ff_init_vscale_pfn(SwsInternal *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
int attribute_align_arg sws_scale(SwsContext *sws, 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.
@ SWS_PRINT_INFO
Emit verbose log of scaling parameters.
static void lumRangeFromJpeg16_c(int16_t *_dst, int width, uint32_t coeff, int64_t offset)
#define atomic_exchange_explicit(object, desired, order)
@ SWS_STRICT
Return an error on underspecified conversions.
const uint8_t ff_dither_8x8_128[9][8]
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[], int dstSliceY, int dstSliceH)
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
static int scale_gamma(SwsInternal *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dstSlice[], const int dstStride[], int dstSliceY, int dstSliceH)
int sliceY
index of first line
Filter graph, which represents a 'baked' pixel format conversion.
int src_format
Source pixel format.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
void ff_hyscale_fast_c(SwsInternal *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
av_cold void ff_sws_init_output_funcs(SwsInternal *c, yuv2planar1_fn *yuv2plane1, yuv2planarX_fn *yuv2planeX, yuv2interleavedX_fn *yuv2nv12cX, yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2, yuv2packedX_fn *yuv2packedX, yuv2anyX_fn *yuv2anyX)
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
av_cold void ff_sws_init_swscale_aarch64(SwsInternal *c)
int ff_frame_pool_video_reinit(FFFramePool *pool, int width, int height, enum AVPixelFormat format, int align)
Recreate the video frame pool if its current configuration differs from the provided configuration.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static const double coeff[2][5]
static SwsInternal * sws_internal(const SwsContext *sws)
int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
static void solve_range_convert(uint16_t src_min, uint16_t src_max, uint16_t dst_min, uint16_t dst_max, int src_bits, int src_shift, int mult_shift, uint32_t *coeff, int64_t *offset)
static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
Main external API structure.
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image dimensions or settings change in any way splits interlaced images into separate and calls ff_sws_graph_run() on each. From the point of view of SwsGraph itself
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
enum AVColorPrimaries prim
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
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
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)