Mercurial > mplayer.hg
comparison postproc/swscale_template.c @ 3215:3083616ba4d6
sliced scaleing bugfix
author | michael |
---|---|
date | Thu, 29 Nov 2001 22:19:21 +0000 |
parents | 0b172eb639f1 |
children | 7e4399d1eb65 |
comparison
equal
deleted
inserted
replaced
3214:6d3c84c8b2f6 | 3215:3083616ba4d6 |
---|---|
1153 } | 1153 } |
1154 #endif | 1154 #endif |
1155 } | 1155 } |
1156 | 1156 |
1157 | 1157 |
1158 static inline void RENAME(hyscale)(uint16_t *dst, int dstWidth, uint8_t *src, int srcWidth, int xInc) | 1158 static inline void RENAME(hyscale)(uint16_t *dst, int dstWidth, uint8_t *src, int srcW, int xInc) |
1159 { | 1159 { |
1160 // *** horizontal scale Y line to temp buffer | 1160 // *** horizontal scale Y line to temp buffer |
1161 #ifdef ARCH_X86 | 1161 #ifdef ARCH_X86 |
1162 #ifdef HAVE_MMX2 | 1162 #ifdef HAVE_MMX2 |
1163 int i; | 1163 int i; |
1206 | 1206 |
1207 :: "m" (src), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), | 1207 :: "m" (src), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), |
1208 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF) | 1208 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF) |
1209 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" | 1209 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" |
1210 ); | 1210 ); |
1211 for(i=dstWidth-1; (i*xInc)>>16 >=srcWidth-1; i--) dst[i] = src[srcWidth-1]*128; | 1211 for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128; |
1212 } | 1212 } |
1213 else | 1213 else |
1214 { | 1214 { |
1215 #endif | 1215 #endif |
1216 //NO MMX just normal asm ... | 1216 //NO MMX just normal asm ... |
1268 } | 1268 } |
1269 #endif | 1269 #endif |
1270 } | 1270 } |
1271 | 1271 |
1272 inline static void RENAME(hcscale)(uint16_t *dst, int dstWidth, | 1272 inline static void RENAME(hcscale)(uint16_t *dst, int dstWidth, |
1273 uint8_t *src1, uint8_t *src2, int srcWidth, int xInc) | 1273 uint8_t *src1, uint8_t *src2, int srcW, int xInc) |
1274 { | 1274 { |
1275 #ifdef ARCH_X86 | 1275 #ifdef ARCH_X86 |
1276 #ifdef HAVE_MMX2 | 1276 #ifdef HAVE_MMX2 |
1277 int i; | 1277 int i; |
1278 if(canMMX2BeUsed) | 1278 if(canMMX2BeUsed) |
1335 | 1335 |
1336 :: "m" (src1), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), | 1336 :: "m" (src1), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), |
1337 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF), "m" (src2) | 1337 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF), "m" (src2) |
1338 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" | 1338 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" |
1339 ); | 1339 ); |
1340 for(i=dstWidth-1; (i*xInc)>>16 >=srcWidth/2-1; i--) | 1340 for(i=dstWidth-1; (i*xInc)>>16 >=srcW/2-1; i--) |
1341 { | 1341 { |
1342 dst[i] = src1[srcWidth/2-1]*128; | 1342 dst[i] = src1[srcW/2-1]*128; |
1343 dst[i+2048] = src2[srcWidth/2-1]*128; | 1343 dst[i+2048] = src2[srcW/2-1]*128; |
1344 } | 1344 } |
1345 } | 1345 } |
1346 else | 1346 else |
1347 { | 1347 { |
1348 #endif | 1348 #endif |
1411 | 1411 |
1412 unsigned int s_xinc2; | 1412 unsigned int s_xinc2; |
1413 //FIXME do we need th +-2 stuff? | 1413 //FIXME do we need th +-2 stuff? |
1414 unsigned int s_xinc= (srcW << 16) / dstW - 2; | 1414 unsigned int s_xinc= (srcW << 16) / dstW - 2; |
1415 unsigned int s_yinc= (srcH << 16) / dstH + 2; | 1415 unsigned int s_yinc= (srcH << 16) / dstH + 2; |
1416 | 1416 |
1417 static int lumDstYInSrc; // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) | 1417 static int lumDstYInSrc; // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) |
1418 static int dstY; | 1418 static int dstY; |
1419 | 1419 |
1420 // last horzontally interpolated lines, used to avoid unnecessary calculations | 1420 // last horzontally interpolated lines, used to avoid unnecessary calculations |
1421 static int lastLumSrcY; | 1421 static int lastLumSrcY; |
1425 // used to detect a horizontal size change | 1425 // used to detect a horizontal size change |
1426 static int old_dstW= -1; | 1426 static int old_dstW= -1; |
1427 static int old_s_xinc= -1; | 1427 static int old_s_xinc= -1; |
1428 #endif | 1428 #endif |
1429 | 1429 |
1430 int srcWidth; | |
1431 int dstUVw; | 1430 int dstUVw; |
1432 int i; | 1431 int i; |
1433 | 1432 |
1434 if(((dstW + 7)&(~7)) >= dststride) dstW&= ~7; | 1433 if(((dstW + 7)&(~7)) >= dststride) dstW&= ~7; |
1435 | 1434 |
1436 srcWidth= (dstW*s_xinc + 0x8000)>>16; | |
1437 dstUVw= fullUVIpol ? dstW : dstW/2; | 1435 dstUVw= fullUVIpol ? dstW : dstW/2; |
1438 | 1436 |
1437 //printf("%d %d %d %d\n", srcW, srcH, dstW, dstH); | |
1438 //printf("%d %d %d %d\n", s_xinc, s_yinc, srcSliceY, srcSliceH); | |
1439 | |
1439 #ifdef HAVE_MMX2 | 1440 #ifdef HAVE_MMX2 |
1440 canMMX2BeUsed= (s_xinc <= 0x10000 && (dstW&31)==0 && (srcWidth&15)==0) ? 1 : 0; | 1441 canMMX2BeUsed= (s_xinc <= 0x10000 && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0; |
1441 #endif | 1442 #endif |
1442 | 1443 |
1443 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst | 1444 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst |
1444 // n-2 is the last chrominance sample available | 1445 // n-2 is the last chrominance sample available |
1445 // FIXME this is not perfect, but noone shuld notice the difference, the more correct variant | 1446 // FIXME this is not perfect, but noone shuld notice the difference, the more correct variant |
1446 // would be like the vertical one, but that would require some special code for the | 1447 // would be like the vertical one, but that would require some special code for the |
1447 // first and last pixel | 1448 // first and last pixel |
1448 if(canMMX2BeUsed) s_xinc+= 20; | 1449 if(canMMX2BeUsed) s_xinc+= 20; |
1449 else s_xinc = ((srcWidth-2)<<16)/(dstW-2) - 20; | 1450 else s_xinc = ((srcW-2)<<16)/(dstW-2) - 20; |
1450 | 1451 |
1451 if(fullUVIpol && !(dstbpp==12)) s_xinc2= s_xinc>>1; | 1452 if(fullUVIpol && !(dstbpp==12)) s_xinc2= s_xinc>>1; |
1452 else s_xinc2= s_xinc; | 1453 else s_xinc2= s_xinc; |
1453 // force calculation of the horizontal interpolation of the first line | 1454 // force calculation of the horizontal interpolation of the first line |
1454 | 1455 |
1455 if(srcSliceY ==0){ | 1456 if(srcSliceY ==0){ |
1456 // printf("dstW %d, srcw %d, mmx2 %d\n", dstW, srcWidth, canMMX2BeUsed); | 1457 // printf("dstW %d, srcw %d, mmx2 %d\n", dstW, srcW, canMMX2BeUsed); |
1457 lastLumSrcY=-99; | 1458 lastLumSrcY=-99; |
1458 lastChrSrcY=-99; | 1459 lastChrSrcY=-99; |
1459 lumDstYInSrc= s_yinc/2 - 0x8000; | 1460 lumDstYInSrc= s_yinc/2 - 0x8000; |
1460 dstY=0; | 1461 dstY=0; |
1461 | 1462 |
1618 uint16_t *buf0=pix_buf_y[ lumSrcY &1]; // top line of the interpolated slice | 1619 uint16_t *buf0=pix_buf_y[ lumSrcY &1]; // top line of the interpolated slice |
1619 uint16_t *buf1=pix_buf_y[(lumSrcY+1)&1]; // bottom line of the interpolated slice | 1620 uint16_t *buf1=pix_buf_y[(lumSrcY+1)&1]; // bottom line of the interpolated slice |
1620 uint16_t *uvbuf0=pix_buf_uv[ chrSrcY &1]; // top line of the interpolated slice | 1621 uint16_t *uvbuf0=pix_buf_uv[ chrSrcY &1]; // top line of the interpolated slice |
1621 uint16_t *uvbuf1=pix_buf_uv[(chrSrcY+1)&1]; // bottom line of the interpolated slice | 1622 uint16_t *uvbuf1=pix_buf_uv[(chrSrcY+1)&1]; // bottom line of the interpolated slice |
1622 | 1623 |
1623 // if(lumSrcY>=srcSliceY + srcSliceH) break; // wrong, skips last lines, but they are dupliactes anyway | 1624 if(lumSrcY>=srcSliceY + srcSliceH && srcSliceY + srcSliceH < srcH) break; |
1624 if(dstY >= dstH) break; | 1625 if(dstY >= dstH) break; |
1625 | 1626 |
1626 // printf("lumSrcY:%d, dstY:%d, yalpha:%d\n", lumSrcY, dstY, yalpha*100/0x1000); | 1627 // printf("lumSrcY:%d, dstY:%d, yalpha:%d\n", lumSrcY, dstY, yalpha*100/0x1000); |
1627 | 1628 |
1628 if((dstY&1) && dstbpp==12) uvalpha=-1; | 1629 if((dstY&1) && dstbpp==12) uvalpha=-1; |
1629 | 1630 |
1630 dstY++; lumDstYInSrc+=s_yinc; | 1631 dstY++; lumDstYInSrc+=s_yinc; |
1631 | 1632 |
1632 //only interpolate the src line horizontally if we didnt do it allready | 1633 //only interpolate the src line horizontally if we didnt do it allready |
1633 if(lastLumSrcY!=lumSrcY) | 1634 if(lastLumSrcY!=lumSrcY) |
1634 { | 1635 { |
1635 unsigned char *src; | 1636 unsigned char *src; |
1637 | |
1636 // skip if first line has been horiz scaled alleady | 1638 // skip if first line has been horiz scaled alleady |
1637 if(lastLumSrcY != lumSrcY-1) | 1639 if(lastLumSrcY != lumSrcY-1) |
1638 { | 1640 { |
1639 // check if first line is before any available src lines | 1641 // check if first line is before any available src lines |
1640 if(lumSrcY-1 < srcSliceY ) src=srcptr[0]+(0 )*stride[0]; | 1642 if(lumSrcY-1 < srcSliceY ) src=srcptr[0]+(0 )*stride[0]; |
1641 else src=srcptr[0]+(lumSrcY-srcSliceY -1)*stride[0]; | 1643 else src=srcptr[0]+(lumSrcY-srcSliceY -1)*stride[0]; |
1642 | 1644 |
1643 RENAME(hyscale)(buf0, dstW, src, srcWidth, s_xinc); | 1645 RENAME(hyscale)(buf0, dstW, src, srcW, s_xinc); |
1644 } | 1646 } |
1645 // check if second line is after any available src lines | 1647 // check if second line is after any available src lines |
1646 if(lumSrcY-srcSliceY >= srcSliceH) src=srcptr[0]+(srcSliceH-1 )*stride[0]; | 1648 if(lumSrcY-srcSliceY >= srcSliceH) src=srcptr[0]+(srcSliceH-1 )*stride[0]; |
1647 else src=srcptr[0]+(lumSrcY-srcSliceY )*stride[0]; | 1649 else src=srcptr[0]+(lumSrcY-srcSliceY )*stride[0]; |
1648 | 1650 |
1649 // the min() is required to avoid reuseing lines which where not available | 1651 // the min() is required to avoid reuseing lines which where not available |
1650 lastLumSrcY= MIN(lumSrcY, srcSliceY +srcSliceH-1); | 1652 lastLumSrcY= MIN(lumSrcY, srcSliceY +srcSliceH-1); |
1651 RENAME(hyscale)(buf1, dstW, src, srcWidth, s_xinc); | 1653 RENAME(hyscale)(buf1, dstW, src, srcW, s_xinc); |
1652 } | 1654 } |
1653 // printf("%d %d %d %d\n", y, chrSrcY, lastChrSrcY, h); | 1655 // printf("%d %d %d %d\n", y, chrSrcY, lastChrSrcY, h); |
1654 // *** horizontal scale U and V lines to temp buffer | 1656 // *** horizontal scale U and V lines to temp buffer |
1655 if(lastChrSrcY!=chrSrcY) | 1657 if(lastChrSrcY!=chrSrcY) |
1656 { | 1658 { |
1665 src2= srcptr[2]+(0)*stride[2]; | 1667 src2= srcptr[2]+(0)*stride[2]; |
1666 }else{ | 1668 }else{ |
1667 src1= srcptr[1]+(chrSrcY-srcSliceY /2-1)*stride[1]; | 1669 src1= srcptr[1]+(chrSrcY-srcSliceY /2-1)*stride[1]; |
1668 src2= srcptr[2]+(chrSrcY-srcSliceY /2-1)*stride[2]; | 1670 src2= srcptr[2]+(chrSrcY-srcSliceY /2-1)*stride[2]; |
1669 } | 1671 } |
1670 RENAME(hcscale)(uvbuf0, dstUVw, src1, src2, srcWidth, s_xinc2); | 1672 RENAME(hcscale)(uvbuf0, dstUVw, src1, src2, srcW, s_xinc2); |
1671 } | 1673 } |
1672 | 1674 |
1673 // check if second line is after any available src lines | 1675 // check if second line is after any available src lines |
1674 if(chrSrcY - srcSliceY /2 >= srcSliceH/2) | 1676 if(chrSrcY - srcSliceY /2 >= srcSliceH/2) |
1675 { | 1677 { |
1677 src2= srcptr[2]+(srcSliceH/2-1)*stride[2]; | 1679 src2= srcptr[2]+(srcSliceH/2-1)*stride[2]; |
1678 }else{ | 1680 }else{ |
1679 src1= srcptr[1]+(chrSrcY-srcSliceY /2)*stride[1]; | 1681 src1= srcptr[1]+(chrSrcY-srcSliceY /2)*stride[1]; |
1680 src2= srcptr[2]+(chrSrcY-srcSliceY /2)*stride[2]; | 1682 src2= srcptr[2]+(chrSrcY-srcSliceY /2)*stride[2]; |
1681 } | 1683 } |
1682 RENAME(hcscale)(uvbuf1, dstUVw, src1, src2, srcWidth, s_xinc2); | 1684 RENAME(hcscale)(uvbuf1, dstUVw, src1, src2, srcW, s_xinc2); |
1683 | 1685 |
1684 // the min() is required to avoid reuseing lines which where not available | 1686 // the min() is required to avoid reuseing lines which where not available |
1685 lastChrSrcY= MIN(chrSrcY, srcSliceY /2+srcSliceH/2-1); | 1687 lastChrSrcY= MIN(chrSrcY, srcSliceY /2+srcSliceH/2-1); |
1686 } | 1688 } |
1687 #ifdef HAVE_MMX | 1689 #ifdef HAVE_MMX |