vf_scale.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 705 行 · 第 1/2 页
C
705 行
static void draw_slice(struct vf_instance_s* vf, unsigned char** src, int* stride, int w,int h, int x, int y){ mp_image_t *dmpi=vf->dmpi; if(!dmpi){ mp_msg(MSGT_VFILTER,MSGL_FATAL,"vf_scale: draw_slice() called with dmpi=NULL (no get_image?)\n"); return; }// printf("vf_scale::draw_slice() y=%d h=%d\n",y,h); scale(vf->priv->ctx, vf->priv->ctx2, src, stride, y, h, dmpi->planes, dmpi->stride, vf->priv->interlaced);}static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ mp_image_t *dmpi=mpi->priv;// printf("vf_scale::put_image(): processing whole frame! dmpi=%p flag=%d\n",// dmpi, (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)); if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK && dmpi)){ // hope we'll get DR buffer: dmpi=vf_get_image(vf->next,vf->priv->fmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, vf->priv->w, vf->priv->h); scale(vf->priv->ctx, vf->priv->ctx, mpi->planes,mpi->stride,0,mpi->h,dmpi->planes,dmpi->stride, vf->priv->interlaced); } if(vf->priv->w==mpi->w && vf->priv->h==mpi->h){ // just conversion, no scaling -> keep postprocessing data // this way we can apply pp filter to non-yv12 source using scaler vf_clone_mpi_attributes(dmpi, mpi); } if(vf->priv->palette) dmpi->planes[1]=vf->priv->palette; // export palette! return vf_next_put_image(vf,dmpi, pts);}static int control(struct vf_instance_s* vf, int request, void* data){ int *table; int *inv_table; int r; int brightness, contrast, saturation, srcRange, dstRange; vf_equalizer_t *eq; if(vf->priv->ctx) switch(request){ case VFCTRL_GET_EQUALIZER: r= sws_getColorspaceDetails(vf->priv->ctx, &inv_table, &srcRange, &table, &dstRange, &brightness, &contrast, &saturation); if(r<0) break; eq = data; if (!strcmp(eq->item,"brightness")) { eq->value = ((brightness*100) + (1<<15))>>16; } else if (!strcmp(eq->item,"contrast")) { eq->value = (((contrast *100) + (1<<15))>>16) - 100; } else if (!strcmp(eq->item,"saturation")) { eq->value = (((saturation*100) + (1<<15))>>16) - 100; } else break; return CONTROL_TRUE; case VFCTRL_SET_EQUALIZER: r= sws_getColorspaceDetails(vf->priv->ctx, &inv_table, &srcRange, &table, &dstRange, &brightness, &contrast, &saturation); if(r<0) break;//printf("set %f %f %f\n", brightness/(float)(1<<16), contrast/(float)(1<<16), saturation/(float)(1<<16)); eq = data; if (!strcmp(eq->item,"brightness")) { brightness = (( eq->value <<16) + 50)/100; } else if (!strcmp(eq->item,"contrast")) { contrast = (((eq->value+100)<<16) + 50)/100; } else if (!strcmp(eq->item,"saturation")) { saturation = (((eq->value+100)<<16) + 50)/100; } else break; r= sws_setColorspaceDetails(vf->priv->ctx, inv_table, srcRange, table, dstRange, brightness, contrast, saturation); if(r<0) break; if(vf->priv->ctx2){ r= sws_setColorspaceDetails(vf->priv->ctx2, inv_table, srcRange, table, dstRange, brightness, contrast, saturation); if(r<0) break; } return CONTROL_TRUE; default: break; } return vf_next_control(vf,request,data);}//===========================================================================//// supported Input formats: YV12, I420, IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800static int query_format(struct vf_instance_s* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_UYVY: case IMGFMT_YUY2: case IMGFMT_BGR32: case IMGFMT_BGR24: case IMGFMT_BGR16: case IMGFMT_BGR15: case IMGFMT_RGB32: case IMGFMT_RGB24: case IMGFMT_Y800: case IMGFMT_Y8: case IMGFMT_YVU9: case IMGFMT_IF09: case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: case IMGFMT_BGR8: case IMGFMT_RGB8: case IMGFMT_BG4B: case IMGFMT_RG4B: { unsigned int best=find_best_out(vf); int flags; if(!best) return 0; // no matching out-fmt flags=vf_next_query_format(vf,best); if(!(flags&(VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW))) return 0; // huh? if(fmt!=best) flags&=~VFCAP_CSP_SUPPORTED_BY_HW; // do not allow scaling, if we are before the PP fliter! if(!(flags&VFCAP_POSTPROC)) flags|=VFCAP_SWSCALE; return flags; } } return 0; // nomatching in-fmt}//global sws_flags from the command lineint sws_flags=2;//global srcFilterstatic SwsFilter *src_filter= NULL;float sws_lum_gblur= 0.0;float sws_chr_gblur= 0.0;int sws_chr_vshift= 0;int sws_chr_hshift= 0;float sws_chr_sharpen= 0.0;float sws_lum_sharpen= 0.0;static void uninit(struct vf_instance_s *vf){ if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); if(vf->priv->ctx2) sws_freeContext(vf->priv->ctx2); if(vf->priv->palette) free(vf->priv->palette); free(vf->priv); if(src_filter) sws_freeFilter(src_filter); src_filter = NULL; sws_flags=2; sws_lum_gblur= 0.0; sws_chr_gblur= 0.0; sws_chr_vshift= 0; sws_chr_hshift= 0; sws_chr_sharpen= 0.0; sws_lum_sharpen= 0.0;}static int open(vf_instance_t *vf, char* args){ vf->config=config; vf->start_slice=start_slice;#ifdef JZ4740_IPU vf->draw_slice=NULL; vf->put_image=jz47_put_image;#else vf->draw_slice=draw_slice; vf->put_image=put_image;#endif vf->query_format=query_format; vf->control= control; vf->uninit=uninit; if(!vf->priv) { vf->priv=malloc(sizeof(struct vf_priv_s)); // TODO: parse args -> vf->priv->ctx=NULL; vf->priv->ctx2=NULL; vf->priv->w= vf->priv->h=-1; vf->priv->v_chr_drop=0; vf->priv->accurate_rnd=0; vf->priv->param[0]= vf->priv->param[1]=SWS_PARAM_DEFAULT; vf->priv->palette=NULL; } // if(!vf->priv) if(args) sscanf(args, "%d:%d:%d:%lf:%lf", &vf->priv->w, &vf->priv->h, &vf->priv->v_chr_drop, &vf->priv->param[0], &vf->priv->param[1]); mp_msg(MSGT_VFILTER,MSGL_V,"SwScale params: %d x %d (-1=no scaling)\n", vf->priv->w, vf->priv->h); return 1;}int get_sws_cpuflags(void){#ifdef USE_16M_SDRAM 1 return 0;#else return (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0) | (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0) | (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0) | (gCpuCaps.hasAltiVec ? SWS_CPU_CAPS_ALTIVEC : 0);#endif}void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam){ static int firstTime=1; *flags=0;#ifdef ARCH_X86 if(gCpuCaps.hasMMX) asm volatile("emms\n\t"::: "memory"); //FIXME this shouldnt be required but it IS (even for non mmx versions)#endif if(firstTime) { firstTime=0; *flags= SWS_PRINT_INFO; } else if( mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO; if(src_filter) sws_freeFilter(src_filter); src_filter= sws_getDefaultFilter( sws_lum_gblur, sws_chr_gblur, sws_lum_sharpen, sws_chr_sharpen, sws_chr_hshift, sws_chr_vshift, verbose>1); switch(sws_flags) { case 0: *flags|= SWS_FAST_BILINEAR; break; case 1: *flags|= SWS_BILINEAR; break; case 2: *flags|= SWS_BICUBIC; break; case 3: *flags|= SWS_X; break; case 4: *flags|= SWS_POINT; break; case 5: *flags|= SWS_AREA; break; case 6: *flags|= SWS_BICUBLIN; break; case 7: *flags|= SWS_GAUSS; break; case 8: *flags|= SWS_SINC; break; case 9: *flags|= SWS_LANCZOS; break; case 10:*flags|= SWS_SPLINE; break; default:*flags|= SWS_BILINEAR; break; } *srcFilterParam= src_filter; *dstFilterParam= NULL;}// will use sws_flags & src_filter (from cmd line)struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat){ int flags; SwsFilter *dstFilterParam, *srcFilterParam; enum PixelFormat dfmt, sfmt; dfmt = imgfmt2pixfmt(dstFormat); sfmt = imgfmt2pixfmt(srcFormat); if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | get_sws_cpuflags(), srcFilterParam, dstFilterParam, NULL);}/// An example of presets usagestatic struct size_preset { char* name; int w, h;} vf_size_presets_defs[] = { // TODO add more 'standard' resolutions { "qntsc", 352, 240 }, { "qpal", 352, 288 }, { "ntsc", 720, 480 }, { "pal", 720, 576 }, { "sntsc", 640, 480 }, { "spal", 768, 576 }, { NULL, 0, 0}};#define ST_OFF(f) M_ST_OFF(struct size_preset,f)static m_option_t vf_size_preset_fields[] = { {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL}, {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,1 ,0, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL }};static m_struct_t vf_size_preset = { "scale_size_preset", sizeof(struct size_preset), NULL, vf_size_preset_fields};static m_struct_t vf_opts;static m_obj_presets_t size_preset = { &vf_size_preset, // Input struct desc &vf_opts, // Output struct desc vf_size_presets_defs, // The list of presets ST_OFF(name) // At wich offset is the name field in the preset struct};/// Now the options#undef ST_OFF#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)static m_option_t vf_opts_fields[] = { {"w", ST_OFF(w), CONF_TYPE_INT, M_OPT_MIN,-11,0, NULL}, {"h", ST_OFF(h), CONF_TYPE_INT, M_OPT_MIN,-11,0, NULL}, {"interlaced", ST_OFF(interlaced), CONF_TYPE_INT, M_OPT_RANGE, 0, 1, NULL}, {"chr-drop", ST_OFF(v_chr_drop), CONF_TYPE_INT, M_OPT_RANGE, 0, 3, NULL}, {"param" , ST_OFF(param[0]), CONF_TYPE_DOUBLE, M_OPT_RANGE, 0.0, 100.0, NULL}, {"param2", ST_OFF(param[1]), CONF_TYPE_DOUBLE, M_OPT_RANGE, 0.0, 100.0, NULL}, // Note that here the 2 field is NULL (ie 0) // As we want this option to act on the option struct itself {"presize", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0, &size_preset}, {"noup", ST_OFF(noup), CONF_TYPE_INT, M_OPT_RANGE, 0, 2, NULL}, {"arnd", ST_OFF(accurate_rnd), CONF_TYPE_FLAG, 0, 0, 1, NULL}, { NULL, NULL, 0, 0, 0, 0, NULL }};static m_struct_t vf_opts = { "scale", sizeof(struct vf_priv_s), &vf_priv_dflt, vf_opts_fields};vf_info_t vf_info_scale = { "software scaling", "scale", "A'rpi", "", open, &vf_opts};//===========================================================================//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?