Mercurial > mplayer.hg
comparison postproc/swscale_template.c @ 2519:6f3fa9bc3b27
yv12 to yv12 scaler
someone who knows a bit about vo_odivx could add support for it ...
author | michael |
---|---|
date | Sun, 28 Oct 2001 18:30:59 +0000 |
parents | d21d8d5f2e23 |
children | b58c43aab619 |
comparison
equal
deleted
inserted
replaced
2518:a3f658d3c98c | 2519:6f3fa9bc3b27 |
---|---|
438 "addl $8, %%eax \n\t"\ | 438 "addl $8, %%eax \n\t"\ |
439 "cmpl %5, %%eax \n\t"\ | 439 "cmpl %5, %%eax \n\t"\ |
440 " jb 1b \n\t" | 440 " jb 1b \n\t" |
441 | 441 |
442 | 442 |
443 static inline void yuv2yuv(uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1, | |
444 uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstw, int yalpha, int uvalpha) | |
445 { | |
446 int yalpha1=yalpha^4095; | |
447 int uvalpha1=uvalpha^4095; | |
448 int i; | |
449 | |
450 for(i=0;i<dstw;i++) | |
451 { | |
452 ((uint8_t*)dest)[0] = (buf0[i]*yalpha1+buf1[i]*yalpha)>>19; | |
453 dest++; | |
454 } | |
455 | |
456 if(uvalpha != -1) | |
457 { | |
458 for(i=0; i<dstw/2; i++) | |
459 { | |
460 ((uint8_t*)uDest)[0] = (uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19; | |
461 ((uint8_t*)vDest)[0] = (uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19; | |
462 uDest++; | |
463 vDest++; | |
464 } | |
465 } | |
466 } | |
467 | |
443 /** | 468 /** |
444 * vertical scale YV12 to RGB | 469 * vertical scale YV12 to RGB |
445 */ | 470 */ |
446 static inline void yuv2rgbX(uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1, | 471 static inline void yuv2rgbX(uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1, |
447 uint8_t *dest, int dstw, int yalpha, int uvalpha, int dstbpp) | 472 uint8_t *dest, int dstw, int yalpha, int uvalpha, int dstbpp) |
1124 } | 1149 } |
1125 #endif | 1150 #endif |
1126 } | 1151 } |
1127 | 1152 |
1128 | 1153 |
1129 // *** bilinear scaling and yuv->rgb conversion of yv12 slices: | 1154 // *** bilinear scaling and yuv->rgb or yuv->yuv conversion of yv12 slices: |
1130 // *** Note: it's called multiple times while decoding a frame, first time y==0 | 1155 // *** Note: it's called multiple times while decoding a frame, first time y==0 |
1131 // *** Designed to upscale, but may work for downscale too. | 1156 // *** Designed to upscale, but may work for downscale too. |
1132 // s_xinc = (src_width << 16) / dst_width | 1157 // s_xinc = (src_width << 16) / dst_width |
1133 // s_yinc = (src_height << 16) / dst_height | 1158 // s_yinc = (src_height << 16) / dst_height |
1134 void SwScale_YV12slice_brg24(unsigned char* srcptr[],int stride[], int y, int h, | 1159 void SwScale_YV12slice(unsigned char* srcptr[],int stride[], int y, int h, |
1135 unsigned char* dstptr, int dststride, int dstw, int dstbpp, | 1160 uint8_t* dstptr[], int dststride, int dstw, int dstbpp, |
1136 unsigned int s_xinc,unsigned int s_yinc){ | 1161 unsigned int s_xinc,unsigned int s_yinc){ |
1137 | 1162 |
1138 // scaling factors: | 1163 // scaling factors: |
1139 //static int s_yinc=(vo_dga_src_height<<16)/vo_dga_vp_height; | 1164 //static int s_yinc=(vo_dga_src_height<<16)/vo_dga_vp_height; |
1140 //static int s_xinc=(vo_dga_src_width<<8)/vo_dga_vp_width; | 1165 //static int s_xinc=(vo_dga_src_width<<8)/vo_dga_vp_width; |
1170 // would be like the vertical one, but that would require some special code for the | 1195 // would be like the vertical one, but that would require some special code for the |
1171 // first and last pixel | 1196 // first and last pixel |
1172 if(canMMX2BeUsed) s_xinc+= 20; | 1197 if(canMMX2BeUsed) s_xinc+= 20; |
1173 else s_xinc = ((srcWidth-2)<<16)/(dstw-2) - 20; | 1198 else s_xinc = ((srcWidth-2)<<16)/(dstw-2) - 20; |
1174 | 1199 |
1175 if(fullUVIpol) s_xinc2= s_xinc>>1; | 1200 if(fullUVIpol && !dstbpp==12) s_xinc2= s_xinc>>1; |
1176 else s_xinc2= s_xinc; | 1201 else s_xinc2= s_xinc; |
1177 // force calculation of the horizontal interpolation of the first line | 1202 // force calculation of the horizontal interpolation of the first line |
1178 | 1203 |
1179 if(y==0){ | 1204 if(y==0){ |
1180 s_last_ypos=-99; | 1205 s_last_ypos=-99; |
1181 s_last_y1pos=-99; | 1206 s_last_y1pos=-99; |
1316 | 1341 |
1317 #endif // HAVE_MMX2 | 1342 #endif // HAVE_MMX2 |
1318 } // reset counters | 1343 } // reset counters |
1319 | 1344 |
1320 while(1){ | 1345 while(1){ |
1321 unsigned char *dest=dstptr+dststride*s_ypos; | 1346 unsigned char *dest =dstptr[0]+dststride*s_ypos; |
1347 unsigned char *uDest=dstptr[1]+(dststride>>1)*(s_ypos>>1); | |
1348 unsigned char *vDest=dstptr[2]+(dststride>>1)*(s_ypos>>1); | |
1349 | |
1322 int y0=(s_srcypos + 0xFFFF)>>16; // first luminance source line number below the dst line | 1350 int y0=(s_srcypos + 0xFFFF)>>16; // first luminance source line number below the dst line |
1323 // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) | 1351 // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) |
1324 int srcuvpos= s_srcypos + s_yinc/2 - 0x8000; | 1352 int srcuvpos= dstbpp==12 ? s_srcypos + s_yinc/2 - 0x8000 : |
1353 s_srcypos - 0x8000; | |
1325 int y1=(srcuvpos + 0x1FFFF)>>17; // first chrominance source line number below the dst line | 1354 int y1=(srcuvpos + 0x1FFFF)>>17; // first chrominance source line number below the dst line |
1326 int yalpha=((s_srcypos-1)&0xFFFF)>>4; | 1355 int yalpha=((s_srcypos-1)&0xFFFF)>>4; |
1327 int uvalpha=((srcuvpos-1)&0x1FFFF)>>5; | 1356 int uvalpha=((srcuvpos-1)&0x1FFFF)>>5; |
1328 uint16_t *buf0=pix_buf_y[y0&1]; // top line of the interpolated slice | 1357 uint16_t *buf0=pix_buf_y[y0&1]; // top line of the interpolated slice |
1329 uint16_t *buf1=pix_buf_y[((y0+1)&1)]; // bottom line of the interpolated slice | 1358 uint16_t *buf1=pix_buf_y[((y0+1)&1)]; // bottom line of the interpolated slice |
1331 uint16_t *uvbuf1=pix_buf_uv[(y1+1)&1]; // bottom line of the interpolated slice | 1360 uint16_t *uvbuf1=pix_buf_uv[(y1+1)&1]; // bottom line of the interpolated slice |
1332 int i; | 1361 int i; |
1333 | 1362 |
1334 if(y0>=y+h) break; // FIXME wrong, skips last lines, but they are dupliactes anyway | 1363 if(y0>=y+h) break; // FIXME wrong, skips last lines, but they are dupliactes anyway |
1335 | 1364 |
1336 // if this is after the last line than use only the last src line | 1365 if((y0&1) && dstbpp==12) uvalpha=-1; // there is no alpha if there is no line |
1337 /* if(y0>=y+h) | |
1338 { | |
1339 buf1= buf0; | |
1340 s_last_ypos=y0; | |
1341 } | |
1342 if(y1>=(y+h)/2) | |
1343 { | |
1344 uvbuf1= uvbuf0; | |
1345 s_last_y1pos=y1; | |
1346 } | |
1347 */ | |
1348 | 1366 |
1349 s_ypos++; s_srcypos+=s_yinc; | 1367 s_ypos++; s_srcypos+=s_yinc; |
1350 | 1368 |
1351 //only interpolate the src line horizontally if we didnt do it allready | 1369 //only interpolate the src line horizontally if we didnt do it allready |
1352 if(s_last_ypos!=y0) | 1370 if(s_last_ypos!=y0) |
1402 | 1420 |
1403 // the min() is required to avoid reuseing lines which where not available | 1421 // the min() is required to avoid reuseing lines which where not available |
1404 s_last_y1pos= MIN(y1, y/2+h/2-1); | 1422 s_last_y1pos= MIN(y1, y/2+h/2-1); |
1405 } | 1423 } |
1406 | 1424 |
1407 | 1425 if(dstbpp==12) //YV12 |
1408 if(ABS(s_yinc - 0x10000) < 10) | 1426 yuv2yuv(buf0, buf1, uvbuf0, uvbuf1, dest, uDest, vDest, dstw, yalpha, uvalpha); |
1427 else if(ABS(s_yinc - 0x10000) < 10) | |
1409 yuv2rgb1(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); | 1428 yuv2rgb1(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); |
1410 else | 1429 else |
1411 yuv2rgbX(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); | 1430 yuv2rgbX(buf0, buf1, uvbuf0, uvbuf1, dest, dstw, yalpha, uvalpha, dstbpp); |
1412 | 1431 |
1413 #ifdef HAVE_MMX | 1432 #ifdef HAVE_MMX |