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 + -
显示快捷键?