⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swscale.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	srcFormat = remove_dup_fourcc(origSrcFormat);	dstFormat = remove_dup_fourcc(origDstFormat);	unscaled = (srcW == dstW && srcH == dstH);	needsDither= (isBGR(dstFormat) || isRGB(dstFormat)) 		     && (dstFormat&0xFF)<24		     && ((dstFormat&0xFF)<(srcFormat&0xFF) || (!(isRGB(srcFormat) || isBGR(srcFormat))));	if(!isSupportedIn(srcFormat)) 	{		MSG_ERR("swScaler: %s is not supported as input format\n", vo_format_name(srcFormat));		return NULL;	}	if(!isSupportedOut(dstFormat))	{		MSG_ERR("swScaler: %s is not supported as output format\n", vo_format_name(dstFormat));		return NULL;	}	/* sanity check */	if(srcW<4 || srcH<1 || dstW<8 || dstH<1) //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code	{		 MSG_ERR("swScaler: %dx%d -> %dx%d is invalid scaling dimension\n", 			srcW, srcH, dstW, dstH);		return NULL;	}	if(!dstFilter) dstFilter= &dummyFilter;	if(!srcFilter) srcFilter= &dummyFilter;	c= memalign(64, sizeof(SwsContext));	memset(c, 0, sizeof(SwsContext));	c->srcW= srcW;	c->srcH= srcH;	c->dstW= dstW;	c->dstH= dstH;	c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;	c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;	c->flags= flags;	c->dstFormat= dstFormat;	c->srcFormat= srcFormat;	c->origDstFormat= origDstFormat;	c->origSrcFormat= origSrcFormat;        c->vRounder= 4* 0x0001000100010001ULL;	usesHFilter= usesVFilter= 0;	if(dstFilter->lumV!=NULL && dstFilter->lumV->length>1) usesVFilter=1;	if(dstFilter->lumH!=NULL && dstFilter->lumH->length>1) usesHFilter=1;	if(dstFilter->chrV!=NULL && dstFilter->chrV->length>1) usesVFilter=1;	if(dstFilter->chrH!=NULL && dstFilter->chrH->length>1) usesHFilter=1;	if(srcFilter->lumV!=NULL && srcFilter->lumV->length>1) usesVFilter=1;	if(srcFilter->lumH!=NULL && srcFilter->lumH->length>1) usesHFilter=1;	if(srcFilter->chrV!=NULL && srcFilter->chrV->length>1) usesVFilter=1;	if(srcFilter->chrH!=NULL && srcFilter->chrH->length>1) usesHFilter=1;	getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);	getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);	// reuse chroma for 2 pixles rgb/bgr unless user wants full chroma interpolation	if((isBGR(dstFormat) || isRGB(dstFormat)) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1;	// drop some chroma lines if the user wants it	c->vChrDrop= (flags&SWS_SRC_V_CHR_DROP_MASK)>>SWS_SRC_V_CHR_DROP_SHIFT;	c->chrSrcVSubSample+= c->vChrDrop;	// drop every 2. pixel for chroma calculation unless user wants full chroma	if((isBGR(srcFormat) || isRGB(srcFormat)) && !(flags&SWS_FULL_CHR_H_INP)) 		c->chrSrcHSubSample=1;	c->chrIntHSubSample= c->chrDstHSubSample;	c->chrIntVSubSample= c->chrSrcVSubSample;	// note the -((-x)>>y) is so that we allways round toward +inf	c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);	c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);	c->chrDstW= -((-dstW) >> c->chrDstHSubSample);	c->chrDstH= -((-dstH) >> c->chrDstVSubSample);	sws_setColorspaceDetails(c, Inverse_Table_6_9[SWS_CS_DEFAULT], 0, Inverse_Table_6_9[SWS_CS_DEFAULT] /* FIXME*/, 0, 0, 1<<16, 1<<16); 	/* unscaled special Cases */	if(unscaled && !usesHFilter && !usesVFilter)	{		/* yv12_to_nv12 */		if(srcFormat == IMGFMT_YV12 && dstFormat == IMGFMT_NV12)		{			c->swScale= PlanarToNV12Wrapper;		}		/* yuv2bgr */		if((srcFormat==IMGFMT_YV12 || srcFormat==IMGFMT_422P) && (isBGR(dstFormat) || isRGB(dstFormat)))		{			c->swScale= yuv2rgb_get_func_ptr(c);		}				if( srcFormat==IMGFMT_YVU9 && dstFormat==IMGFMT_YV12 )		{			c->swScale= yvu9toyv12Wrapper;		}		/* bgr24toYV12 */		if(srcFormat==IMGFMT_BGR24 && dstFormat==IMGFMT_YV12)			c->swScale= bgr24toyv12Wrapper;				/* rgb/bgr -> rgb/bgr (no dither needed forms) */		if(   (isBGR(srcFormat) || isRGB(srcFormat))		   && (isBGR(dstFormat) || isRGB(dstFormat)) 		   && !needsDither)			c->swScale= rgb2rgbWrapper;		/* LQ converters if -sws 0 or -sws 4*/		if(c->flags&(SWS_FAST_BILINEAR|SWS_POINT)){			/* rgb/bgr -> rgb/bgr (dither needed forms) */			if(  (isBGR(srcFormat) || isRGB(srcFormat))			  && (isBGR(dstFormat) || isRGB(dstFormat)) 			  && needsDither)				c->swScale= rgb2rgbWrapper;			/* yv12_to_yuy2 */			if(srcFormat == IMGFMT_YV12 && 			    (dstFormat == IMGFMT_YUY2 || dstFormat == IMGFMT_UYVY))			{				if (dstFormat == IMGFMT_YUY2)				    c->swScale= PlanarToYuy2Wrapper;				else				    c->swScale= PlanarToUyvyWrapper;			}		}#ifdef HAVE_ALTIVEC		if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&		    ((srcFormat == IMGFMT_YV12 && 		      (dstFormat == IMGFMT_YUY2 || dstFormat == IMGFMT_UYVY)))) {		  // unscaled YV12 -> packed YUV, we want speed		  if (dstFormat == IMGFMT_YUY2)		    c->swScale= yv12toyuy2_unscaled_altivec;		  else		    c->swScale= yv12touyvy_unscaled_altivec;		}#endif		/* simple copy */		if(   srcFormat == dstFormat		   || (isPlanarYUV(srcFormat) && isGray(dstFormat))		   || (isPlanarYUV(dstFormat) && isGray(srcFormat))		  )		{			c->swScale= simpleCopy;		}		if(c->swScale){			if(flags&SWS_PRINT_INFO)				MSG_INFO("SwScaler: using unscaled %s -> %s special converter\n", 					vo_format_name(srcFormat), vo_format_name(dstFormat));			return c;		}	}	if(flags & SWS_CPU_CAPS_MMX2)	{		c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;		if(!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR))		{			if(flags&SWS_PRINT_INFO)				MSG_INFO("SwScaler: output Width is not a multiple of 32 -> no MMX2 scaler\n");		}		if(usesHFilter) c->canMMX2BeUsed=0;	}	else		c->canMMX2BeUsed=0;	c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;	c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;	// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst	// but only for the FAST_BILINEAR mode otherwise do correct scaling	// n-2 is the last chrominance sample available	// this is not perfect, but noone shuld notice the difference, the more correct variant	// would be like the vertical one, but that would require some special code for the	// first and last pixel	if(flags&SWS_FAST_BILINEAR)	{		if(c->canMMX2BeUsed)		{			c->lumXInc+= 20;			c->chrXInc+= 20;		}		//we don't use the x86asm scaler if mmx is available		else if(flags & SWS_CPU_CAPS_MMX)		{			c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;			c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;		}	}	/* precalculate horizontal scaler filter coefficients */	{		const int filterAlign=		  (flags & SWS_CPU_CAPS_MMX) ? 4 :		  (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :		  1;		initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,				 srcW      ,       dstW, filterAlign, 1<<14,				 (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC)  : flags,				 srcFilter->lumH, dstFilter->lumH);		initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,				 c->chrSrcW, c->chrDstW, filterAlign, 1<<14,				 (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,				 srcFilter->chrH, dstFilter->chrH);#ifdef ARCH_X86// can't downscale !!!		if(c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))		{			c->lumMmx2Filter   = (int16_t*)memalign(8, (dstW        /8+8)*sizeof(int16_t));			c->chrMmx2Filter   = (int16_t*)memalign(8, (c->chrDstW  /4+8)*sizeof(int16_t));			c->lumMmx2FilterPos= (int32_t*)memalign(8, (dstW      /2/8+8)*sizeof(int32_t));			c->chrMmx2FilterPos= (int32_t*)memalign(8, (c->chrDstW/2/4+8)*sizeof(int32_t));			initMMX2HScaler(      dstW, c->lumXInc, c->funnyYCode , c->lumMmx2Filter, c->lumMmx2FilterPos, 8);			initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode, c->chrMmx2Filter, c->chrMmx2FilterPos, 4);		}#endif	} // Init Horizontal stuff	/* precalculate vertical scaler filter coefficients */	{		const int filterAlign=		  (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :		  1;		initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,				srcH      ,        dstH, filterAlign, (1<<12)-4,				(flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC)  : flags,				srcFilter->lumV, dstFilter->lumV);		initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,				c->chrSrcH, c->chrDstH, filterAlign, (1<<12)-4,				(flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,				srcFilter->chrV, dstFilter->chrV);	}	// Calculate Buffer Sizes so that they won't run out while handling these damn slices	c->vLumBufSize= c->vLumFilterSize;	c->vChrBufSize= c->vChrFilterSize;	for(i=0; i<dstH; i++)	{		int chrI= i*c->chrDstH / dstH;		int nextSlice= MAX(c->vLumFilterPos[i   ] + c->vLumFilterSize - 1,				 ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<c->chrSrcVSubSample));		nextSlice>>= c->chrSrcVSubSample;		nextSlice<<= c->chrSrcVSubSample;		if(c->vLumFilterPos[i   ] + c->vLumBufSize < nextSlice)			c->vLumBufSize= nextSlice - c->vLumFilterPos[i   ];		if(c->vChrFilterPos[chrI] + c->vChrBufSize < (nextSlice>>c->chrSrcVSubSample))			c->vChrBufSize= (nextSlice>>c->chrSrcVSubSample) - c->vChrFilterPos[chrI];	}	// allocate pixbufs (we use dynamic allocation because otherwise we would need to	c->lumPixBuf= (int16_t**)memalign(4, c->vLumBufSize*2*sizeof(int16_t*));	c->chrPixBuf= (int16_t**)memalign(4, c->vChrBufSize*2*sizeof(int16_t*));	//Note we need at least one pixel more at the end because of the mmx code (just in case someone wanna replace the 4000/8000)	for(i=0; i<c->vLumBufSize; i++)		c->lumPixBuf[i]= c->lumPixBuf[i+c->vLumBufSize]= (uint16_t*)memalign(8, 4000);	for(i=0; i<c->vChrBufSize; i++)		c->chrPixBuf[i]= c->chrPixBuf[i+c->vChrBufSize]= (uint16_t*)memalign(8, 8000);	//try to avoid drawing green stuff between the right end and the stride end	for(i=0; i<c->vLumBufSize; i++) memset(c->lumPixBuf[i], 0, 4000);	for(i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, 8000);	ASSERT(c->chrDstH <= dstH)	if(flags&SWS_PRINT_INFO)	{#ifdef DITHER1XBPP		char *dither= " dithered";#else		char *dither= "";#endif		if(flags&SWS_FAST_BILINEAR)			MSG_INFO("\nSwScaler: FAST_BILINEAR scaler, ");		else if(flags&SWS_BILINEAR)			MSG_INFO("\nSwScaler: BILINEAR scaler, ");		else if(flags&SWS_BICUBIC)			MSG_INFO("\nSwScaler: BICUBIC scaler, ");		else if(flags&SWS_X)			MSG_INFO("\nSwScaler: Experimental scaler, ");		else if(flags&SWS_POINT)			MSG_INFO("\nSwScaler: Nearest Neighbor / POINT scaler, ");		else if(flags&SWS_AREA)			MSG_INFO("\nSwScaler: Area Averageing scaler, ");		else if(flags&SWS_BICUBLIN)			MSG_INFO("\nSwScaler: luma BICUBIC / chroma BILINEAR scaler, ");		else if(flags&SWS_GAUSS)			MSG_INFO("\nSwScaler: Gaussian scaler, ");		else if(flags&SWS_SINC)			MSG_INFO("\nSwScaler: Sinc scaler, ");		else if(flags&SWS_LANCZOS)			MSG_INFO("\nSwScaler: Lanczos scaler, ");		else if(flags&SWS_SPLINE)			MSG_INFO("\nSwScaler: Bicubic spline scaler, ");		else			MSG_INFO("\nSwScaler: ehh flags invalid?! ");		if(dstFormat==IMGFMT_BGR15 || dstFormat==IMGFMT_BGR16)			MSG_INFO("from %s to%s %s ", 				vo_format_name(srcFormat), dither, vo_format_name(dstFormat));		else			MSG_INFO("from %s to %s ", 				vo_format_name(srcFormat), vo_format_name(dstFormat));		if(flags & SWS_CPU_CAPS_MMX2)			MSG_INFO("using MMX2\n");		else if(flags & SWS_CPU_CAPS_3DNOW)			MSG_INFO("using 3DNOW\n");		else if(flags & SWS_CPU_CAPS_MMX)			MSG_INFO("using MMX\n");		else if(flags & SWS_CPU_CAPS_ALTIVEC)			MSG_INFO("using AltiVec\n");		else 			MSG_INFO("using C\n");	}	if(flags & SWS_PRINT_INFO)	{		if(flags & SWS_CPU_CAPS_MMX)		{			if(c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))				MSG_V("SwScaler: using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");			else			{				if(c->hLumFilterSize==4)					MSG_V("SwScaler: using 4-tap MMX scaler for horizontal luminance scaling\n");				else if(c->hLumFilterSize==8)					MSG_V("SwScaler: using 8-tap MMX scaler for horizontal luminance scaling\n");				else					MSG_V("SwScaler: using n-tap MMX scaler for horizontal luminance scaling\n");				if(c->hChrFilterSize==4)					MSG_V("SwScaler: using 4-tap MMX scaler for horizontal chrominance scaling\n");				else if(c->hChrFilterSize==8)					MSG_V("SwScaler: using 8-tap MMX scaler for horizontal chrominance scaling\n");				else					MSG_V("SwScaler: using n-tap MMX scaler for horizontal chrominance scaling\n");			}		}		else		{#ifdef ARCH_X86			MSG_V("SwScaler: using X86-Asm scaler for horizontal scaling\n");#else			if(flags & SWS_FAST_BILINEAR)				MSG_V("SwScaler: using FAST_BILINEAR C scaler for horizontal scaling\n");			else				MSG_V("SwScaler: using C scaler for horizontal scaling\n");#endif		}		if(isPlanarYUV(dstFormat))		{			if(c->vLumFilterSize==1)				MSG_V("SwScaler: using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");			else				MSG_V("SwScaler: using n-tap %s scaler for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");		}		else		{			if(c->vLumFilterSize==1 && c->vChrFilterSize==2)				MSG_V("SwScaler: using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"				       "SwScaler:       2-tap scaler for vertical chrominance scaling (BGR)\n",(flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");			else if(c->vLumFilterSize==2 && c->vChrFilterSize==2)				MSG_V("SwScaler: using 2-tap linear %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");			else				MSG_V("SwScaler: using n-tap %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");		}		if(dstFormat==IMGFMT_BGR24)			MSG_V("SwScaler: using %s YV12->BGR24 Converter\n",				(flags & SWS_CPU_CAPS_MMX2) ? "MMX2" : ((flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"));		else if(dstFormat==IMGFMT_BGR32)			MSG_V("SwScaler: using %s YV12->BGR32 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");		else if(dstFormat==IMGFMT_BGR16)			MSG_V("SwScaler: using %s YV12->BGR16 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");		else if(dstFormat==IMGFMT_BGR15)			MSG_V("SwScaler: using %s YV12->BGR15 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");		MSG_V("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);	}	if(flags & SWS_PRINT_INFO)	{		MSG_DBG2("SwScaler:Lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",			c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);		MSG_DBG2("SwScaler:Chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",			c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);	}	c->swScale= getSwsFunc(flags);	return c;}/** * swscale warper, so we don't need to export the SwsContext. * assumes planar YUV to be in YUV order instead of YVU */int sws_scale_ordered(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,                           int srcSliceH, uint8_t* dst[], int dstStride[]){	//copy strides, so they can safely be modified	int srcStride2[3]= {srcStride[0], srcStride[1], srcStride[2]};	int dstStride2[3]= {dstStride[0], dstStride[1], dstStride[2]};	return c->swScale(c, src, srcStride2, srcSliceY, srcSliceH, dst, dstStride2);}/** * swscale warper, so we don't need to export the SwsContext */int sws_scale(SwsContext *c, uint8_t* srcParam[], int srcStrideParam[], int srcSliceY,                           int srcSliceH, uint8_t* dstParam[], int dstStrideParam[]){	int srcStride[3];	int dstStride[3];	uint8_t *src[3];	uint8_t *dst[3];	sws_orderYUV(c->origSrcFormat, src, srcStride, srcParam, srcStrideParam);	sws_orderYUV(c->origDstFormat, dst, dstStride, dstParam, dstStrideParam);//printf("sws: slice %d %d\n", srcSliceY, srcSliceH);	return c->swScale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride);}SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, 				float lumaSharpen, float chromaSharpen,				float chromaHShift, float chromaVShift,				int verbose){	SwsFilter *filter= malloc(sizeof(SwsFilter));	if(lumaGBlur!=0.0){		filter->lumH= sws_getGaussianVec(lumaGBlur, 3.0);		filter->lumV= sws_getGaussianVec(lumaGBlur, 3.0);	}else{		filter->lumH= sws_getIden

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -