📄 swscale.c
字号:
return swScale_3DNow; else if(flags & SWS_CPU_CAPS_MMX) return swScale_MMX; else return swScale_C;#else#ifdef ARCH_POWERPC if(flags & SWS_CPU_CAPS_ALTIVEC) return swScale_altivec; else return swScale_C;#endif return swScale_C;#endif#else //RUNTIME_CPUDETECT#ifdef HAVE_MMX2 return swScale_MMX2;#elif defined (HAVE_3DNOW) return swScale_3DNow;#elif defined (HAVE_MMX) return swScale_MMX;#elif defined (HAVE_ALTIVEC) return swScale_altivec;#else return swScale_C;#endif#endif //!RUNTIME_CPUDETECT}static int PlanarToNV12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride[]){ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; /* Copy Y plane */ if(dstStride[0]==srcStride[0]) memcpy(dst, src[0], srcSliceH*dstStride[0]); else { int i; uint8_t *srcPtr= src[0]; uint8_t *dstPtr= dst; for(i=0; i<srcSliceH; i++) { memcpy(dstPtr, srcPtr, srcStride[0]); srcPtr+= srcStride[0]; dstPtr+= dstStride[0]; } } dst = dstParam[1] + dstStride[1]*srcSliceY; interleaveBytes( src[1],src[2],dst,c->srcW,srcSliceH,srcStride[1],srcStride[2],dstStride[0] ); return srcSliceH;}static int PlanarToYuy2Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride[]){ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; yv12toyuy2( src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0] ); return srcSliceH;}static int PlanarToUyvyWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride[]){ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; yv12touyvy( src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0] ); return srcSliceH;}/* {RGB,BGR}{15,16,24,32} -> {RGB,BGR}{15,16,24,32} */static int rgb2rgbWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ const int srcFormat= c->srcFormat; const int dstFormat= c->dstFormat; const int srcBpp= ((srcFormat&0xFF) + 7)>>3; const int dstBpp= ((dstFormat&0xFF) + 7)>>3; const int srcId= (srcFormat&0xFF)>>2; // 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 const int dstId= (dstFormat&0xFF)>>2; void (*conv)(const uint8_t *src, uint8_t *dst, unsigned src_size)=NULL; /* BGR -> BGR */ if( (isBGR(srcFormat) && isBGR(dstFormat)) || (isRGB(srcFormat) && isRGB(dstFormat))){ switch(srcId | (dstId<<4)){ case 0x34: conv= rgb16to15; break; case 0x36: conv= rgb24to15; break; case 0x38: conv= rgb32to15; break; case 0x43: conv= rgb15to16; break; case 0x46: conv= rgb24to16; break; case 0x48: conv= rgb32to16; break; case 0x63: conv= rgb15to24; break; case 0x64: conv= rgb16to24; break; case 0x68: conv= rgb32to24; break; case 0x83: conv= rgb15to32; break; case 0x84: conv= rgb16to32; break; case 0x86: conv= rgb24to32; break; default: MSG_ERR("swScaler: internal error %s -> %s converter\n", vo_format_name(srcFormat), vo_format_name(dstFormat)); break; } }else if( (isBGR(srcFormat) && isRGB(dstFormat)) || (isRGB(srcFormat) && isBGR(dstFormat))){ switch(srcId | (dstId<<4)){ case 0x33: conv= rgb15tobgr15; break; case 0x34: conv= rgb16tobgr15; break; case 0x36: conv= rgb24tobgr15; break; case 0x38: conv= rgb32tobgr15; break; case 0x43: conv= rgb15tobgr16; break; case 0x44: conv= rgb16tobgr16; break; case 0x46: conv= rgb24tobgr16; break; case 0x48: conv= rgb32tobgr16; break; case 0x63: conv= rgb15tobgr24; break; case 0x64: conv= rgb16tobgr24; break; case 0x66: conv= rgb24tobgr24; break; case 0x68: conv= rgb32tobgr24; break; case 0x83: conv= rgb15tobgr32; break; case 0x84: conv= rgb16tobgr32; break; case 0x86: conv= rgb24tobgr32; break; case 0x88: conv= rgb32tobgr32; break; default: MSG_ERR("swScaler: internal error %s -> %s converter\n", vo_format_name(srcFormat), vo_format_name(dstFormat)); break; } }else{ MSG_ERR("swScaler: internal error %s -> %s converter\n", vo_format_name(srcFormat), vo_format_name(dstFormat)); } if(dstStride[0]*srcBpp == srcStride[0]*dstBpp) conv(src[0], dst[0] + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]); else { int i; uint8_t *srcPtr= src[0]; uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; for(i=0; i<srcSliceH; i++) { conv(srcPtr, dstPtr, c->srcW*srcBpp); srcPtr+= srcStride[0]; dstPtr+= dstStride[0]; } } return srcSliceH;}static int bgr24toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ rgb24toyv12( src[0], dst[0]+ srcSliceY *dstStride[0], dst[1]+(srcSliceY>>1)*dstStride[1], dst[2]+(srcSliceY>>1)*dstStride[2], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); return srcSliceH;}static int yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ int i; /* copy Y */ if(srcStride[0]==dstStride[0]) memcpy(dst[0]+ srcSliceY*dstStride[0], src[0], srcStride[0]*srcSliceH); else{ uint8_t *srcPtr= src[0]; uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; for(i=0; i<srcSliceH; i++) { memcpy(dstPtr, srcPtr, c->srcW); srcPtr+= srcStride[0]; dstPtr+= dstStride[0]; } } if(c->dstFormat==IMGFMT_YV12){ planar2x(src[1], dst[1], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[1]); planar2x(src[2], dst[2], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[2]); }else{ planar2x(src[1], dst[2], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[2]); planar2x(src[2], dst[1], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[1]); } return srcSliceH;}/** * bring pointers in YUV order instead of YVU */static inline void sws_orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]){ if(format == IMGFMT_YV12 || format == IMGFMT_YVU9 || format == IMGFMT_444P || format == IMGFMT_422P || format == IMGFMT_411P){ sortedP[0]= p[0]; sortedP[1]= p[2]; sortedP[2]= p[1]; sortedStride[0]= stride[0]; sortedStride[1]= stride[2]; sortedStride[2]= stride[1]; } else if(isPacked(format) || isGray(format) || format == IMGFMT_Y8) { sortedP[0]= p[0]; sortedP[1]= sortedP[2]= NULL; sortedStride[0]= stride[0]; sortedStride[1]= sortedStride[2]= 0; } else if(format == IMGFMT_I420 || format == IMGFMT_IYUV) { sortedP[0]= p[0]; sortedP[1]= p[1]; sortedP[2]= p[2]; sortedStride[0]= stride[0]; sortedStride[1]= stride[1]; sortedStride[2]= stride[2]; }else{ MSG_ERR("internal error in orderYUV\n"); }}/* unscaled copy like stuff (assumes nearly identical formats) */static int simpleCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){ if(isPacked(c->srcFormat)) { if(dstStride[0]==srcStride[0]) memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); else { int i; uint8_t *srcPtr= src[0]; uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; int length=0; /* universal length finder */ while(length+c->srcW <= ABS(dstStride[0]) && length+c->srcW <= ABS(srcStride[0])) length+= c->srcW; ASSERT(length!=0); for(i=0; i<srcSliceH; i++) { memcpy(dstPtr, srcPtr, length); srcPtr+= srcStride[0]; dstPtr+= dstStride[0]; } } } else { /* Planar YUV or gray */ int plane; for(plane=0; plane<3; plane++) { int length= plane==0 ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); int y= plane==0 ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); int height= plane==0 ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); if((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0) { if(!isGray(c->dstFormat)) memset(dst[plane], 128, dstStride[plane]*height); } else { if(dstStride[plane]==srcStride[plane]) memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]); else { int i; uint8_t *srcPtr= src[plane]; uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; for(i=0; i<height; i++) { memcpy(dstPtr, srcPtr, length); srcPtr+= srcStride[plane]; dstPtr+= dstStride[plane]; } } } } } return srcSliceH;}static int remove_dup_fourcc(int fourcc){ switch(fourcc) { case IMGFMT_I420: case IMGFMT_IYUV: return IMGFMT_YV12; case IMGFMT_Y8 : return IMGFMT_Y800; case IMGFMT_IF09: return IMGFMT_YVU9; default: return fourcc; }}static void getSubSampleFactors(int *h, int *v, int format){ switch(format){ case IMGFMT_UYVY: case IMGFMT_YUY2: *h=1; *v=0; break; case IMGFMT_YV12: case IMGFMT_Y800: //FIXME remove after different subsamplings are fully implemented *h=1; *v=1; break; case IMGFMT_YVU9: *h=2; *v=2; break; case IMGFMT_444P: *h=0; *v=0; break; case IMGFMT_422P: *h=1; *v=0; break; case IMGFMT_411P: *h=2; *v=0; break; default: *h=0; *v=0; break; }}static uint16_t roundToInt16(int64_t f){ int r= (f + (1<<15))>>16; if(r<-0x7FFF) return 0x8000; else if(r> 0x7FFF) return 0x7FFF; else return r;}/** * @param inv_table the yuv2rgb coeffs, normally Inverse_Table_6_9[x] * @param fullRange if 1 then the luma range is 0..255 if 0 its 16..235 * @return -1 if not supported */int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation){ int64_t crv = inv_table[0]; int64_t cbu = inv_table[1]; int64_t cgu = -inv_table[2]; int64_t cgv = -inv_table[3]; int64_t cy = 1<<16; int64_t oy = 0; if(isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1; memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4); memcpy(c->dstColorspaceTable, table, sizeof(int)*4); c->brightness= brightness; c->contrast = contrast; c->saturation= saturation; c->srcRange = srcRange; c->dstRange = dstRange; c->uOffset= 0x0400040004000400LL; c->vOffset= 0x0400040004000400LL; if(!srcRange){ cy= (cy*255) / 219; oy= 16<<16; } cy = (cy *contrast )>>16; crv= (crv*contrast * saturation)>>32; cbu= (cbu*contrast * saturation)>>32; cgu= (cgu*contrast * saturation)>>32; cgv= (cgv*contrast * saturation)>>32; oy -= 256*brightness; c->yCoeff= roundToInt16(cy *8192) * 0x0001000100010001ULL; c->vrCoeff= roundToInt16(crv*8192) * 0x0001000100010001ULL; c->ubCoeff= roundToInt16(cbu*8192) * 0x0001000100010001ULL; c->vgCoeff= roundToInt16(cgv*8192) * 0x0001000100010001ULL; c->ugCoeff= roundToInt16(cgu*8192) * 0x0001000100010001ULL; c->yOffset= roundToInt16(oy * 8) * 0x0001000100010001ULL; yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); //FIXME factorize#ifdef HAVE_ALTIVEC yuv2rgb_altivec_init_tables (c, inv_table);#endif return 0;}/** * @return -1 if not supported */int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation){ if(isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1; *inv_table = c->srcColorspaceTable; *table = c->dstColorspaceTable; *srcRange = c->srcRange; *dstRange = c->dstRange; *brightness= c->brightness; *contrast = c->contrast; *saturation= c->saturation; return 0; }SwsContext *sws_getContext(int srcW, int srcH, int origSrcFormat, int dstW, int dstH, int origDstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter){ SwsContext *c; int i; int usesVFilter, usesHFilter; int unscaled, needsDither; int srcFormat, dstFormat; SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};#ifdef ARCH_X86 if(flags & SWS_CPU_CAPS_MMX) asm volatile("emms\n\t"::: "memory");#endif#ifndef RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off flags &= ~(SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2|SWS_CPU_CAPS_3DNOW|SWS_CPU_CAPS_ALTIVEC);#ifdef HAVE_MMX2 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2;#elif defined (HAVE_3DNOW) flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW;#elif defined (HAVE_MMX) flags |= SWS_CPU_CAPS_MMX;#elif defined (HAVE_ALTIVEC) flags |= SWS_CPU_CAPS_ALTIVEC;#endif#endif if(clip_table[512] != 255) globalInit(); if(rgb15to16 == NULL) sws_rgb2rgb_init(flags); /* avoid duplicate Formats, so we don't need to check to much */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -