Go to the documentation of this file.
39 { 36, 68, 60, 92, 34, 66, 58, 90, },
40 { 100, 4, 124, 28, 98, 2, 122, 26, },
41 { 52, 84, 44, 76, 50, 82, 42, 74, },
42 { 116, 20, 108, 12, 114, 18, 106, 10, },
43 { 32, 64, 56, 88, 38, 70, 62, 94, },
44 { 96, 0, 120, 24, 102, 6, 126, 30, },
45 { 48, 80, 40, 72, 54, 86, 46, 78, },
46 { 112, 16, 104, 8, 118, 22, 110, 14, },
47 { 36, 68, 60, 92, 34, 66, 58, 90, },
51 64, 64, 64, 64, 64, 64, 64, 64
58 uint8_t *ptr = plane +
stride * y;
67 const int32_t *filterPos,
int filterSize)
72 const uint16_t *
src = (
const uint16_t *)
_src;
82 for (
i = 0;
i < dstW;
i++) {
84 int srcPos = filterPos[
i];
87 for (j = 0; j < filterSize; j++) {
97 const int32_t *filterPos,
int filterSize)
101 const uint16_t *
src = (
const uint16_t *)
_src;
102 int sh =
desc->comp[0].depth - 1;
110 for (
i = 0;
i < dstW;
i++) {
112 int srcPos = filterPos[
i];
115 for (j = 0; j < filterSize; j++) {
125 const uint8_t *
src,
const int16_t *
filter,
126 const int32_t *filterPos,
int filterSize)
129 for (
i = 0;
i < dstW;
i++) {
131 int srcPos = filterPos[
i];
133 for (j = 0; j < filterSize; j++) {
141 const uint8_t *
src,
const int16_t *
filter,
142 const int32_t *filterPos,
int filterSize)
146 for (
i = 0;
i < dstW;
i++) {
148 int srcPos = filterPos[
i];
150 for (j = 0; j < filterSize; j++) {
163 dstU[
i] = (
FFMIN(dstU[
i], 30775) * 4663 - 9289992) >> 12;
164 dstV[
i] = (
FFMIN(dstV[
i], 30775) * 4663 - 9289992) >> 12;
172 dstU[
i] = (dstU[
i] * 1799 + 4081085) >> 11;
173 dstV[
i] = (dstV[
i] * 1799 + 4081085) >> 11;
188 dst[
i] = (
dst[
i] * 14071 + 33561947) >> 14;
197 dstU[
i] = ((int)(
FFMIN(dstU[
i], 30775 << 4) * 4663
U - (9289992 << 4))) >> 12;
198 dstV[
i] = ((int)(
FFMIN(dstV[
i], 30775 << 4) * 4663
U - (9289992 << 4))) >> 12;
208 dstU[
i] = (dstU[
i] * 1799 + (4081085 << 4)) >> 11;
209 dstV[
i] = (dstV[
i] * 1799 + (4081085 << 4)) >> 11;
218 dst[
i] = ((int)(
FFMIN(
dst[
i], 30189 << 4) * 4769
U - (39057361 << 2))) >> 12;
227 dst[
i] = ((
int)(
dst[
i]*(14071
U/4) + (33561947<<4)/4)) >> 12;
231 #define DEBUG_SWSCALE_BUFFERS 0
232 #define DEBUG_BUFFERS(...) \
233 if (DEBUG_SWSCALE_BUFFERS) \
234 av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
237 int srcSliceY,
int srcSliceH, uint8_t *
const dst[],
238 const int dstStride[],
int dstSliceY,
int dstSliceH)
240 const int scale_dst = dstSliceY > 0 || dstSliceH <
c->dstH;
244 const int dstW =
c->dstW;
248 const int flags =
c->flags;
249 int32_t *vLumFilterPos =
c->vLumFilterPos;
250 int32_t *vChrFilterPos =
c->vChrFilterPos;
252 const int vLumFilterSize =
c->vLumFilterSize;
253 const int vChrFilterSize =
c->vChrFilterSize;
262 const int chrSrcSliceY = srcSliceY >>
c->chrSrcVSubSample;
263 const int chrSrcSliceH =
AV_CEIL_RSHIFT(srcSliceH,
c->chrSrcVSubSample);
264 int should_dither =
isNBPS(
c->srcFormat) ||
270 int lastInLumBuf =
c->lastInLumBuf;
271 int lastInChrBuf =
c->lastInChrBuf;
274 int lumEnd =
c->descIndex[0];
275 int chrStart = lumEnd;
276 int chrEnd =
c->descIndex[1];
278 int vEnd =
c->numDesc;
279 SwsSlice *src_slice = &
c->slice[lumStart];
280 SwsSlice *hout_slice = &
c->slice[
c->numSlice-2];
281 SwsSlice *vout_slice = &
c->slice[
c->numSlice-1];
284 int needAlpha =
c->needAlpha;
289 const uint8_t *
src2[4];
300 srcStride2[3] = srcStride[0];
303 memcpy(srcStride2, srcStride,
sizeof(srcStride2));
306 srcStride2[1] *= 1 <<
c->vChrDrop;
307 srcStride2[2] *= 1 <<
c->vChrDrop;
309 DEBUG_BUFFERS(
"swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
310 src2[0], srcStride2[0],
src2[1], srcStride2[1],
311 src2[2], srcStride2[2],
src2[3], srcStride2[3],
312 dst[0], dstStride[0],
dst[1], dstStride[1],
313 dst[2], dstStride[2],
dst[3], dstStride[3]);
314 DEBUG_BUFFERS(
"srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
315 srcSliceY, srcSliceH, dstY, dstH);
317 vLumFilterSize, vChrFilterSize);
319 if (dstStride[0]&15 || dstStride[1]&15 ||
320 dstStride[2]&15 || dstStride[3]&15) {
325 "Warning: dstStride is not aligned!\n"
326 " ->cannot do aligned memory accesses anymore\n");
331 if ( (uintptr_t)
dst[0]&15 || (uintptr_t)
dst[1]&15 || (uintptr_t)
dst[2]&15
332 || (uintptr_t)
src2[0]&15 || (uintptr_t)
src2[1]&15 || (uintptr_t)
src2[2]&15
333 || dstStride[0]&15 || dstStride[1]&15 || dstStride[2]&15 || dstStride[3]&15
334 || srcStride2[0]&15 || srcStride2[1]&15 || srcStride2[2]&15 || srcStride2[3]&15
347 dstH = dstY + dstSliceH;
350 }
else if (srcSliceY == 0) {
359 if (!should_dither) {
365 yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX,
c->use_mmx_vfilter);
368 srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
371 dstY, dstSliceH, dstY >>
c->chrDstVSubSample,
373 if (srcSliceY == 0) {
383 hout_slice->
width = dstW;
386 for (; dstY < dstH; dstY++) {
387 const int chrDstY = dstY >>
c->chrDstVSubSample;
388 int use_mmx_vfilter=
c->use_mmx_vfilter;
391 const int firstLumSrcY =
FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
392 const int firstLumSrcY2 =
FFMAX(1 - vLumFilterSize, vLumFilterPos[
FFMIN(dstY | ((1 <<
c->chrDstVSubSample) - 1),
c->dstH - 1)]);
394 const int firstChrSrcY =
FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
397 int lastLumSrcY =
FFMIN(
c->srcH, firstLumSrcY + vLumFilterSize) - 1;
398 int lastLumSrcY2 =
FFMIN(
c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
399 int lastChrSrcY =
FFMIN(
c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
403 int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;
406 if (firstLumSrcY > lastInLumBuf) {
408 hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
416 lastInLumBuf = firstLumSrcY - 1;
418 if (firstChrSrcY > lastInChrBuf) {
420 hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
428 lastInChrBuf = firstChrSrcY - 1;
432 DEBUG_BUFFERS(
"\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
433 firstLumSrcY, lastLumSrcY, lastInLumBuf);
434 DEBUG_BUFFERS(
"\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
435 firstChrSrcY, lastChrSrcY, lastInChrBuf);
438 enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
439 lastChrSrcY <
AV_CEIL_RSHIFT(srcSliceY + srcSliceH,
c->chrSrcVSubSample);
442 lastLumSrcY = srcSliceY + srcSliceH - 1;
443 lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
444 DEBUG_BUFFERS(
"buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
445 lastLumSrcY, lastChrSrcY);
453 if (posY <= lastLumSrcY && !hasLumHoles) {
454 firstPosY =
FFMAX(firstLumSrcY, posY);
458 lastPosY = lastLumSrcY;
462 if (cPosY <= lastChrSrcY && !hasChrHoles) {
463 firstCPosY =
FFMAX(firstChrSrcY, cPosY);
467 lastCPosY = lastChrSrcY;
472 if (posY < lastLumSrcY + 1) {
473 for (
i = lumStart;
i < lumEnd; ++
i)
477 lastInLumBuf = lastLumSrcY;
479 if (cPosY < lastChrSrcY + 1) {
480 for (
i = chrStart;
i < chrEnd; ++
i)
484 lastInChrBuf = lastChrSrcY;
491 c->dstW_mmx =
c->dstW;
497 if (dstY >=
c->dstH - 2) {
501 &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
504 yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, use_mmx_vfilter);
507 for (
i = vStart;
i < vEnd; ++
i)
511 int offset = lastDstY - dstSliceY;
513 int height = dstY - lastDstY;
518 1,
desc->comp[3].depth,
520 }
else if (
is32BPS(dstFormat)) {
523 1,
desc->comp[3].depth,
529 #if HAVE_MMXEXT_INLINE
531 __asm__ volatile (
"sfence" :::
"memory");
537 c->lastInLumBuf = lastInLumBuf;
538 c->lastInChrBuf = lastInChrBuf;
540 return dstY - lastDstY;
545 c->lumConvertRange =
NULL;
546 c->chrConvertRange =
NULL;
547 if (
c->srcRange !=
c->dstRange && !
isAnyRGB(
c->dstFormat)) {
548 if (
c->dstBpc <= 14) {
568 #elif ARCH_LOONGARCH64
583 &
c->yuv2nv12cX, &
c->yuv2packed1,
584 &
c->yuv2packed2, &
c->yuv2packedX, &
c->yuv2anyX);
587 &
c->readLumPlanar, &
c->readAlpPlanar, &
c->readChrPlanar);
589 if (
c->srcBpc == 8) {
590 if (
c->dstBpc <= 14) {
608 c->needs_hcscale = 1;
623 #elif ARCH_LOONGARCH64
643 const int linesizes[4])
650 for (
i = 0;
i < 4;
i++) {
651 int plane =
desc->comp[
i].plane;
652 if (!
data[plane] || !linesizes[plane])
660 const uint8_t *
src,
int src_stride,
int w,
int h)
664 for (
int yp = 0; yp <
h; yp++) {
665 const uint16_t *src16 = (
const uint16_t *)
src;
666 uint16_t *dst16 = (uint16_t *)
dst;
668 for (
int xp = 0; xp < 3 *
w; xp += 3) {
669 int x, y, z,
r,
g,
b;
681 x =
c->xyzgamma[x >> 4];
682 y =
c->xyzgamma[y >> 4];
683 z =
c->xyzgamma[z >> 4];
686 r =
c->xyz2rgb_matrix[0][0] * x +
687 c->xyz2rgb_matrix[0][1] * y +
688 c->xyz2rgb_matrix[0][2] * z >> 12;
689 g =
c->xyz2rgb_matrix[1][0] * x +
690 c->xyz2rgb_matrix[1][1] * y +
691 c->xyz2rgb_matrix[1][2] * z >> 12;
692 b =
c->xyz2rgb_matrix[2][0] * x +
693 c->xyz2rgb_matrix[2][1] * y +
694 c->xyz2rgb_matrix[2][2] * z >> 12;
703 AV_WB16(dst16 + xp + 0,
c->rgbgamma[
r] << 4);
704 AV_WB16(dst16 + xp + 1,
c->rgbgamma[
g] << 4);
705 AV_WB16(dst16 + xp + 2,
c->rgbgamma[
b] << 4);
707 AV_WL16(dst16 + xp + 0,
c->rgbgamma[
r] << 4);
708 AV_WL16(dst16 + xp + 1,
c->rgbgamma[
g] << 4);
709 AV_WL16(dst16 + xp + 2,
c->rgbgamma[
b] << 4);
719 const uint8_t *
src,
int src_stride,
int w,
int h)
723 for (
int yp = 0; yp <
h; yp++) {
724 uint16_t *src16 = (uint16_t *)
src;
725 uint16_t *dst16 = (uint16_t *)
dst;
727 for (
int xp = 0; xp < 3 *
w; xp += 3) {
728 int x, y, z,
r,
g,
b;
740 r =
c->rgbgammainv[
r>>4];
741 g =
c->rgbgammainv[
g>>4];
742 b =
c->rgbgammainv[
b>>4];
745 x =
c->rgb2xyz_matrix[0][0] *
r +
746 c->rgb2xyz_matrix[0][1] *
g +
747 c->rgb2xyz_matrix[0][2] *
b >> 12;
748 y =
c->rgb2xyz_matrix[1][0] *
r +
749 c->rgb2xyz_matrix[1][1] *
g +
750 c->rgb2xyz_matrix[1][2] *
b >> 12;
751 z =
c->rgb2xyz_matrix[2][0] *
r +
752 c->rgb2xyz_matrix[2][1] *
g +
753 c->rgb2xyz_matrix[2][2] *
b >> 12;
762 AV_WB16(dst16 + xp + 0,
c->xyzgammainv[x] << 4);
763 AV_WB16(dst16 + xp + 1,
c->xyzgammainv[y] << 4);
764 AV_WB16(dst16 + xp + 2,
c->xyzgammainv[z] << 4);
766 AV_WL16(dst16 + xp + 0,
c->xyzgammainv[x] << 4);
767 AV_WL16(dst16 + xp + 1,
c->xyzgammainv[y] << 4);
768 AV_WL16(dst16 + xp + 2,
c->xyzgammainv[z] << 4);
779 for (
int i = 0;
i < 256;
i++) {
780 int r,
g,
b, y,
u, v,
a = 0xff;
783 a = (p >> 24) & 0xFF;
784 r = (p >> 16) & 0xFF;
789 g = ((
i >> 2) & 7) * 36;
793 g = ((
i >> 3) & 7) * 36;
796 r = (
i >> 3 ) * 255;
797 g = ((
i >> 1) & 3) * 85;
803 b = (
i >> 3 ) * 255;
804 g = ((
i >> 1) & 3) * 85;
807 #define RGB2YUV_SHIFT 15
808 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
809 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
810 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
811 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
812 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
813 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
814 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
815 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
816 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
821 c->pal_yuv[
i]= y + (
u<<8) + (v<<16) + ((unsigned)
a<<24);
823 switch (
c->dstFormat) {
828 c->pal_rgb[
i]=
r + (
g<<8) + (
b<<16) + ((unsigned)
a<<24);
834 c->pal_rgb[
i]=
a + (
r<<8) + (
g<<16) + ((unsigned)
b<<24);
840 c->pal_rgb[
i]=
a + (
b<<8) + (
g<<16) + ((unsigned)
r<<24);
847 c->pal_rgb[
i]=
b + (
g<<8) + (
r<<16) + ((unsigned)
a<<24);
853 const uint8_t *
const srcSlice[],
const int srcStride[],
854 int srcSliceY,
int srcSliceH,
855 uint8_t *
const dstSlice[],
const int dstStride[],
856 int dstSliceY,
int dstSliceH);
859 const uint8_t *
const srcSlice[],
const int srcStride[],
860 int srcSliceY,
int srcSliceH,
861 uint8_t *
const dstSlice[],
const int dstStride[],
862 int dstSliceY,
int dstSliceH)
865 srcSlice, srcStride, srcSliceY, srcSliceH,
866 c->cascaded_tmp[0],
c->cascaded_tmpStride[0], 0,
c->srcH);
871 if (
c->cascaded_context[2])
873 c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
874 c->cascaded_tmp[1],
c->cascaded_tmpStride[1], 0,
c->dstH);
877 c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
878 dstSlice, dstStride, dstSliceY, dstSliceH);
883 if (
c->cascaded_context[2]) {
886 c->cascaded_tmpStride[1], dstY1 -
ret, dstY1,
887 dstSlice, dstStride, dstSliceY, dstSliceH);
893 const uint8_t *
const srcSlice[],
const int srcStride[],
894 int srcSliceY,
int srcSliceH,
895 uint8_t *
const dstSlice[],
const int dstStride[],
896 int dstSliceY,
int dstSliceH)
900 srcSlice, srcStride, srcSliceY, srcSliceH,
901 c->cascaded_tmp[0],
c->cascaded_tmpStride[0],
906 (
const uint8_t *
const * )
c->cascaded_tmp[0],
c->cascaded_tmpStride[0],
907 0, dstH0, dstSlice, dstStride, dstSliceY, dstSliceH);
912 const uint8_t *
const srcSlice[],
const int srcStride[],
913 int srcSliceY,
int srcSliceH,
914 uint8_t *
const dstSlice[],
const int dstStride[],
915 int dstSliceY,
int dstSliceH)
918 const int scale_dst = dstSliceY > 0 || dstSliceH <
c->dstH;
921 const uint8_t *
src2[4];
923 int macro_height_src =
isBayer(
c->srcFormat) ? 2 : (1 <<
c->chrSrcVSubSample);
924 int macro_height_dst =
isBayer(
c->dstFormat) ? 2 : (1 <<
c->chrDstVSubSample);
928 int srcSliceY_internal = srcSliceY;
930 if (!srcStride || !dstStride || !dstSlice || !srcSlice) {
931 av_log(
c,
AV_LOG_ERROR,
"One of the input parameters to sws_scale() is NULL, please check the calling code\n");
935 if ((srcSliceY & (macro_height_src - 1)) ||
936 ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH !=
c->srcH) ||
937 srcSliceY + srcSliceH >
c->srcH ||
938 (
isBayer(
c->srcFormat) && srcSliceH <= 1)) {
943 if ((dstSliceY & (macro_height_dst - 1)) ||
944 ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH !=
c->dstH) ||
945 dstSliceY + dstSliceH >
c->dstH) {
963 if (
c->gamma_flag &&
c->cascaded_context[0])
964 return scale_gamma(
c, srcSlice, srcStride, srcSliceY, srcSliceH,
965 dstSlice, dstStride, dstSliceY, dstSliceH);
967 if (
c->cascaded_context[0] && srcSliceY == 0 &&
971 dstSlice, dstStride, dstSliceY, dstSliceH);
975 for (
i = 0;
i < 4;
i++)
976 memset(
c->dither_error[
i], 0,
sizeof(
c->dither_error[0][0]) * (
c->dstW+2));
981 memcpy(
src2, srcSlice,
sizeof(
src2));
982 memcpy(dst2, dstSlice,
sizeof(dst2));
983 memcpy(srcStride2, srcStride,
sizeof(srcStride2));
984 memcpy(dstStride2, dstStride,
sizeof(dstStride2));
987 if (srcSliceY != 0 && srcSliceY + srcSliceH !=
c->srcH) {
992 c->sliceDir = (srcSliceY == 0) ? 1 : -1;
993 }
else if (scale_dst)
996 if (
c->src0Alpha && !
c->dst0Alpha &&
isALPHA(
c->dstFormat)) {
1001 FFABS(srcStride[0]) * srcSliceH + 32);
1002 if (!
c->rgb0_scratch)
1005 base = srcStride[0] < 0 ?
c->rgb0_scratch - srcStride[0] * (srcSliceH-1) :
1007 for (y=0; y<srcSliceH; y++){
1008 memcpy(
base + srcStride[0]*y,
src2[0] + srcStride[0]*y, 4*
c->srcW);
1009 for (x=
c->src0Alpha-1; x<4*c->srcW; x+=4) {
1010 base[ srcStride[0]*y + x] = 0xFF;
1016 if (
c->srcXYZ && !(
c->dstXYZ &&
c->srcW==
c->dstW &&
c->srcH==
c->dstH)) {
1020 FFABS(srcStride[0]) * srcSliceH + 32);
1021 if (!
c->xyz_scratch)
1024 base = srcStride[0] < 0 ?
c->xyz_scratch - srcStride[0] * (srcSliceH-1) :
1031 if (
c->sliceDir != 1) {
1033 for (
i=0;
i<4;
i++) {
1034 srcStride2[
i] *= -1;
1035 dstStride2[
i] *= -1;
1038 src2[0] += (srcSliceH - 1) * srcStride[0];
1040 src2[1] += ((srcSliceH >>
c->chrSrcVSubSample) - 1) * srcStride[1];
1041 src2[2] += ((srcSliceH >>
c->chrSrcVSubSample) - 1) * srcStride[2];
1042 src2[3] += (srcSliceH - 1) * srcStride[3];
1043 dst2[0] += (
c->dstH - 1) * dstStride[0];
1044 dst2[1] += ((
c->dstH >>
c->chrDstVSubSample) - 1) * dstStride[1];
1045 dst2[2] += ((
c->dstH >>
c->chrDstVSubSample) - 1) * dstStride[2];
1046 dst2[3] += (
c->dstH - 1) * dstStride[3];
1048 srcSliceY_internal =
c->srcH-srcSliceY-srcSliceH;
1053 if (
c->convert_unscaled) {
1054 int offset = srcSliceY_internal;
1055 int slice_h = srcSliceH;
1060 for (
i = 0;
i < 4 &&
src2[
i];
i++) {
1063 src2[
i] += (dstSliceY >> ((
i == 1 ||
i == 2) ?
c->chrSrcVSubSample : 0)) * srcStride2[
i];
1066 for (
i = 0;
i < 4 && dst2[
i];
i++) {
1067 if (!dst2[
i] || (
i > 0 &&
usePal(
c->dstFormat)))
1069 dst2[
i] -= (dstSliceY >> ((
i == 1 ||
i == 2) ?
c->chrDstVSubSample : 0)) * dstStride2[
i];
1072 slice_h = dstSliceH;
1078 dst2[0] += dstSliceY * dstStride2[0];
1081 dst2, dstStride2, dstSliceY, dstSliceH);
1084 if (
c->dstXYZ && !(
c->srcXYZ &&
c->srcW==
c->dstW &&
c->srcH==
c->dstH)) {
1090 int dstY =
c->dstY ?
c->dstY : srcSliceY + srcSliceH;
1095 dst = dst2[0] + (dstY -
ret) * dstStride2[0];
1103 if ((srcSliceY_internal + srcSliceH ==
c->srcH) || scale_dst)
1114 c->src_ranges.nb_ranges = 0;
1120 int ret, allocated = 0;
1127 dst->width =
c->dstW;
1128 dst->height =
c->dstH;
1129 dst->format =
c->dstFormat;
1149 unsigned int slice_height)
1167 return c->dst_slice_align;
1171 unsigned int slice_height)
1178 if (!(
c->src_ranges.nb_ranges == 1 &&
1179 c->src_ranges.ranges[0].start == 0 &&
1180 c->src_ranges.ranges[0].len ==
c->srcH))
1183 if ((
slice_start > 0 || slice_height < c->dstH) &&
1186 "Incorrectly aligned output: %u/%u not multiples of %u\n",
1191 if (
c->slicethread) {
1192 int nb_jobs =
c->nb_slice_ctx;
1199 c->dst_slice_height = slice_height;
1203 for (
int i = 0;
i <
c->nb_slice_ctx;
i++) {
1204 if (
c->slice_err[
i] < 0) {
1205 ret =
c->slice_err[
i];
1210 memset(
c->slice_err, 0,
c->nb_slice_ctx *
sizeof(*
c->slice_err));
1216 ptrdiff_t
offset =
c->frame_dst->linesize[
i] * (ptrdiff_t)(
slice_start >>
c->chrDstVSubSample);
1220 return scale_internal(sws, (
const uint8_t *
const *)
c->frame_src->data,
1221 c->frame_src->linesize, 0,
c->srcH,
1247 const uint8_t *
const srcSlice[],
1248 const int srcStride[],
int srcSliceY,
1249 int srcSliceH, uint8_t *
const dst[],
1250 const int dstStride[])
1253 if (
c->nb_slice_ctx) {
1254 sws =
c->slice_ctx[0];
1258 return scale_internal(sws, srcSlice, srcStride, srcSliceY, srcSliceH,
1259 dst, dstStride, 0,
c->dstH);
1263 int nb_jobs,
int nb_threads)
1270 c->dst_slice_align);
1279 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
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
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
#define u(width, name, range_min, range_max)
void ff_rgb48Toxyz12(const SwsInternal *c, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int w, int h)
av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
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.
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.
#define AV_PIX_FMT_RGB32_1
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)
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
#define DEBUG_BUFFERS(...)
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.
#define SWS_FAST_BILINEAR
static av_always_inline int is16BPS(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 slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
static void frame_start(MpegEncContext *s)
static double val(void *priv, double ch)
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
@ 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)
struct SwsContext SwsContext
#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...
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)
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
static enum AVPixelFormat pix_fmt
int width
Slice line width.
int srcH
Height of source luma/alpha planes.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
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 void lumRangeFromJpeg_c(int16_t *dst, int width)
void ff_xyz12Torgb48(const SwsInternal *c, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int w, int h)
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)
int available_lines
max number of lines that can be hold by this plane
@ 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)
@ 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_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)
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
#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_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)
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
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
av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
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...
#define i(width, name, range_min, range_max)
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.
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.
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)
@ 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")
int sws_frame_start(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Initialize the scaling process for a given pair of source/destination frames.
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 av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
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.
#define atomic_exchange_explicit(object, desired, order)
const uint8_t ff_dither_8x8_128[9][8]
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
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)
static void lumRangeToJpeg_c(int16_t *dst, int width)
static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
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)
static void lumRangeToJpeg16_c(int16_t *_dst, int width)
int sliceY
index of first line
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)
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
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)
#define flags(name, subs,...)
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 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 av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
int dstH
Height of destination luma/alpha planes.
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