vf_spp.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 625 行 · 第 1/2 页

C
625
字号
			int temp;			STORE(0);			STORE(1);			STORE(2);			STORE(3);			STORE(4);			STORE(5);			STORE(6);			STORE(7);		}	}}#ifdef HAVE_MMXstatic void store_slice_mmx(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){	int y;	for(y=0; y<height; y++){		uint8_t *dst1= dst;		int16_t *src1= src;		asm volatile(			"movq (%3), %%mm3	\n\t"			"movq (%3), %%mm4	\n\t"			"movd %4, %%mm2		\n\t"			"pxor %%mm0, %%mm0	\n\t"			"punpcklbw %%mm0, %%mm3	\n\t"			"punpckhbw %%mm0, %%mm4	\n\t"			"psraw %%mm2, %%mm3	\n\t"			"psraw %%mm2, %%mm4	\n\t"			"movd %5, %%mm2		\n\t"			"1:			\n\t"			"movq (%0), %%mm0	\n\t"			"movq 8(%0), %%mm1	\n\t"			"paddw %%mm3, %%mm0	\n\t"			"paddw %%mm4, %%mm1	\n\t"			"psraw %%mm2, %%mm0	\n\t"			"psraw %%mm2, %%mm1	\n\t"			"packuswb %%mm1, %%mm0	\n\t"			"movq %%mm0, (%1) 	\n\t"			"add $16, %0		\n\t"			"add $8, %1		\n\t"			"cmp %2, %1		\n\t"			" jb 1b			\n\t"			: "+r" (src1), "+r"(dst1)			: "r"(dst + width), "r"(dither[y]), "g"(log2_scale), "g"(6-log2_scale)		);		src += src_stride;		dst += dst_stride;	}//	if(width != mmxw)//		store_slice_c(dst + mmxw, src + mmxw, dst_stride, src_stride, width - mmxw, log2_scale);}#endifstatic void (*store_slice)(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)= store_slice_c;static void (*requantize)(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation)= hardthresh_c;static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma){	int x, y, i;	const int count= 1<<p->log2_count;	const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15));	uint64_t __attribute__((aligned(16))) block_align[32];	DCTELEM *block = (DCTELEM *)block_align;	DCTELEM *block2= (DCTELEM *)(block_align+16);	if (!src || !dst) return; // HACK avoid crash for Y8 colourspace	for(y=0; y<height; y++){		int index= 8 + 8*stride + y*stride;		fast_memcpy(p->src + index, src + y*src_stride, width);		for(x=0; x<8; x++){ 			p->src[index         - x - 1]= p->src[index +         x    ];			p->src[index + width + x    ]= p->src[index + width - x - 1];		}	}	for(y=0; y<8; y++){		fast_memcpy(p->src + (      7-y)*stride, p->src + (      y+8)*stride, stride);		fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride);	}	//FIXME (try edge emu)	for(y=0; y<height+8; y+=8){		memset(p->temp + (8+y)*stride, 0, 8*stride*sizeof(int16_t));		for(x=0; x<width+8; x+=8){			const int qps= 3 + is_luma;			int qp;                        			if(p->qp)				qp= p->qp;			else{				qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride];				if(p->mpeg2) qp = FFMAX(1, qp>>1);			}			for(i=0; i<count; i++){				const int x1= x + offset[i+count-1][0];				const int y1= y + offset[i+count-1][1];				const int index= x1 + y1*stride;				p->dsp.get_pixels(block, p->src + index, stride);				p->dsp.fdct(block);				requantize(block2, block, qp, p->dsp.idct_permutation);				p->dsp.idct(block2);				add_block(p->temp + index, stride, block2);			}		}		if(y)			store_slice(dst + (y-8)*dst_stride, p->temp + 8 + y*stride, dst_stride, stride, width, XMIN(8, height+8-y), 6-p->log2_count);	}#if 0	for(y=0; y<height; y++){		for(x=0; x<width; x++){			if((((x>>6) ^ (y>>6)) & 1) == 0)				dst[x + y*dst_stride]= p->src[8 + 8*stride  + x + y*stride];			if((x&63) == 0 || (y&63)==0)				dst[x + y*dst_stride] += 128;                }	}#endif	//FIXME reorder for better caching}static int config(struct vf_instance_s* vf,        int width, int height, int d_width, int d_height,	unsigned int flags, unsigned int outfmt){	int h= (height+16+15)&(~15);	vf->priv->temp_stride= (width+16+15)&(~15);        vf->priv->temp= malloc(vf->priv->temp_stride*h*sizeof(int16_t));        vf->priv->src = malloc(vf->priv->temp_stride*h*sizeof(uint8_t));        	return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);}static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){    if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change    // ok, we can do pp in-place (or pp disabled):    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);    mpi->planes[0]=vf->dmpi->planes[0];    mpi->stride[0]=vf->dmpi->stride[0];    mpi->width=vf->dmpi->width;    if(mpi->flags&MP_IMGFLAG_PLANAR){        mpi->planes[1]=vf->dmpi->planes[1];        mpi->planes[2]=vf->dmpi->planes[2];	mpi->stride[1]=vf->dmpi->stride[1];	mpi->stride[2]=vf->dmpi->stride[2];    }    mpi->flags|=MP_IMGFLAG_DIRECT;}static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){	mp_image_t *dmpi;	if(!(mpi->flags&MP_IMGFLAG_DIRECT)){		// no DR, so get a new image! hope we'll get DR buffer:                dmpi=vf_get_image(vf->next,mpi->imgfmt,                    MP_IMGTYPE_TEMP,                    MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,                    mpi->width,mpi->height);                vf_clone_mpi_attributes(dmpi, mpi);        }else{           dmpi=vf->dmpi;        }        vf->priv->mpeg2= mpi->qscale_type;        if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){            if(!vf->priv->non_b_qp)                vf->priv->non_b_qp= malloc(mpi->qstride * ((mpi->h + 15) >> 4));            fast_memcpy(vf->priv->non_b_qp, mpi->qscale, mpi->qstride * ((mpi->h + 15) >> 4));        }	if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){            char *qp_tab= vf->priv->non_b_qp;            if((vf->priv->mode&4) || !qp_tab)                qp_tab= mpi->qscale;	    if(qp_tab || vf->priv->qp){		filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, qp_tab, mpi->qstride, 1);		filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);		filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);	    }else{		memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);		memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);		memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);	    }	}#ifdef HAVE_MMX	if(gCpuCaps.hasMMX) asm volatile ("emms\n\t");#endif#ifdef HAVE_MMX2	if(gCpuCaps.hasMMX2) asm volatile ("sfence\n\t");#endif	return vf_next_put_image(vf,dmpi, pts);}static void uninit(struct vf_instance_s* vf){	if(!vf->priv) return;	if(vf->priv->temp) free(vf->priv->temp);	vf->priv->temp= NULL;	if(vf->priv->src) free(vf->priv->src);	vf->priv->src= NULL;        if(vf->priv->avctx) free(vf->priv->avctx);        vf->priv->avctx= NULL;        if(vf->priv->non_b_qp) free(vf->priv->non_b_qp);        vf->priv->non_b_qp= NULL;		free(vf->priv);	vf->priv=NULL;}//===========================================================================//static int query_format(struct vf_instance_s* vf, unsigned int fmt){    switch(fmt){	case IMGFMT_YVU9:	case IMGFMT_IF09:	case IMGFMT_YV12:	case IMGFMT_I420:	case IMGFMT_IYUV:	case IMGFMT_CLPL:	case IMGFMT_Y800:	case IMGFMT_Y8:	case IMGFMT_444P:	case IMGFMT_422P:	case IMGFMT_411P:	    return vf_next_query_format(vf,fmt);    }    return 0;}static unsigned int fmt_list[]={	IMGFMT_YVU9,	IMGFMT_IF09,	IMGFMT_YV12,	IMGFMT_I420,	IMGFMT_IYUV,	IMGFMT_CLPL,	IMGFMT_Y800,	IMGFMT_Y8,	IMGFMT_444P,	IMGFMT_422P,	IMGFMT_411P,	0};static int control(struct vf_instance_s* vf, int request, void* data){    switch(request){    case VFCTRL_QUERY_MAX_PP_LEVEL:	return 6;    case VFCTRL_SET_PP_LEVEL:	vf->priv->log2_count= *((unsigned int*)data);	return CONTROL_TRUE;    }    return vf_next_control(vf,request,data);}static int open(vf_instance_t *vf, char* args){    int log2c=-1;        vf->config=config;    vf->put_image=put_image;    vf->get_image=get_image;    vf->query_format=query_format;    vf->uninit=uninit;    vf->control= control;    vf->priv=malloc(sizeof(struct vf_priv_s));    memset(vf->priv, 0, sizeof(struct vf_priv_s));        avcodec_init();    vf->priv->avctx= avcodec_alloc_context();    dsputil_init(&vf->priv->dsp, vf->priv->avctx);        vf->priv->log2_count= 3;        if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode);    if( log2c >=0 && log2c <=6 )        vf->priv->log2_count = log2c;    if(vf->priv->qp < 0)        vf->priv->qp = 0;    switch(vf->priv->mode&3){        default:	case 0: requantize= hardthresh_c; break;	case 1: requantize= softthresh_c; break;    }#ifdef HAVE_MMX    if(gCpuCaps.hasMMX){	store_slice= store_slice_mmx;	switch(vf->priv->mode&3){	    case 0: requantize= hardthresh_mmx; break;	    case 1: requantize= softthresh_mmx; break;	}    }#endif        return 1;}vf_info_t vf_info_spp = {    "simple postprocess",    "spp",    "Michael Niedermayer",    "",    open,    NULL};

⌨️ 快捷键说明

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