vf_scale.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 705 行 · 第 1/2 页
C
705 行
#include <uclib.h>#include <uclib.h>#include <uclib.h>#include <inttypes.h>#include "config.h"#include "mp_msg.h"#include "cpudetect.h"#include "img_format.h"#include "mp_image.h"#include "vf.h"#include "fmt-conversion.h"#include "bswap.h"#include "libswscale/swscale.h"#include "vf_scale.h"#include "m_option.h"#include "m_struct.h"static struct vf_priv_s { int w,h; int v_chr_drop; double param[2]; unsigned int fmt; struct SwsContext *ctx; struct SwsContext *ctx2; //for interlaced slices only unsigned char* palette; int interlaced; int noup; int accurate_rnd; int query_format_cache[64];} const vf_priv_dflt = { -1,-1, 0, {SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT}, 0, NULL, NULL, NULL};extern int opt_screen_size_x;extern int opt_screen_size_y;extern float screen_size_xy;//===========================================================================//void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam);static unsigned int outfmt_list[]={// YUV: IMGFMT_444P, IMGFMT_422P, IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, IMGFMT_YVU9, IMGFMT_IF09, IMGFMT_411P, IMGFMT_NV12, IMGFMT_NV21, IMGFMT_YUY2, IMGFMT_UYVY,// RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, IMGFMT_BGR24, IMGFMT_RGB24, IMGFMT_BGR16, IMGFMT_RGB16, IMGFMT_BGR15, IMGFMT_RGB15, IMGFMT_Y800, IMGFMT_Y8, IMGFMT_BGR8, IMGFMT_RGB8, IMGFMT_BGR4, IMGFMT_RGB4, IMGFMT_BG4B, IMGFMT_RG4B, IMGFMT_BGR1, IMGFMT_RGB1, 0};static unsigned int find_best_out(vf_instance_t *vf){ unsigned int best=0; int i; // find the best outfmt: for(i=0; i<sizeof(outfmt_list)/sizeof(int)-1; i++){ const int format= outfmt_list[i]; int ret= vf->priv->query_format_cache[i]-1; if(ret == -1){ ret= vf_next_query_format(vf, outfmt_list[i]); vf->priv->query_format_cache[i]= ret+1; } mp_msg(MSGT_VFILTER,MSGL_DBG2,"scale: query(%s) -> %d\n",vo_format_name(format),ret&3); if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=format; // no conversion -> bingo! break; } if(ret&VFCAP_CSP_SUPPORTED && !best) best=format; // best with conversion } return best;}static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ unsigned int best=find_best_out(vf); int vo_flags; int int_sws_flags=0; int round_w=0, round_h=0; SwsFilter *srcFilter, *dstFilter; enum PixelFormat dfmt, sfmt; if(!best){ mp_msg(MSGT_VFILTER,MSGL_WARN,"SwScale: no supported outfmt found :(\n"); return 0; } sfmt = imgfmt2pixfmt(outfmt); if (outfmt == IMGFMT_RGB8 || outfmt == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; dfmt = imgfmt2pixfmt(best); vo_flags=vf->next->query_format(vf->next,best); // scaling to dwidth*d_height, if all these TRUE: // - option -zoom // - no other sw/hw up/down scaling avail. // - we're after postproc // - user didn't set w:h if(!(vo_flags&VFCAP_POSTPROC) && (flags&4) && vf->priv->w<0 && vf->priv->h<0){ // -zoom int x=(vo_flags&VFCAP_SWSCALE) ? 0 : 1; if(d_width<width || d_height<height){ // downscale! if(vo_flags&VFCAP_HWSCALE_DOWN) x=0; } else { // upscale: if(vo_flags&VFCAP_HWSCALE_UP) x=0; } if(x){ // user wants sw scaling! (-zoom) vf->priv->w=d_width; vf->priv->h=d_height; } } if(vf->priv->noup){ if((vf->priv->w > width) + (vf->priv->h > height) >= vf->priv->noup){ vf->priv->w= width; vf->priv->h= height; } } if (vf->priv->w <= -8) { vf->priv->w += 8; round_w = 1; } if (vf->priv->h <= -8) { vf->priv->h += 8; round_h = 1; } if (vf->priv->w < -3 || vf->priv->h < -3 || (vf->priv->w < -1 && vf->priv->h < -1)) { // TODO: establish a direct connection to the user's brain // and find out what the heck he thinks MPlayer should do // with this nonsense. mp_msg(MSGT_VFILTER, MSGL_ERR, "SwScale: EUSERBROKEN Check your parameters, they make no sense!\n"); return 0; } if (vf->priv->w == -1) vf->priv->w = width; if (vf->priv->w == 0) vf->priv->w = d_width; if (vf->priv->h == -1) vf->priv->h = height; if (vf->priv->h == 0) vf->priv->h = d_height; if (vf->priv->w == -3) vf->priv->w = vf->priv->h * width / height; if (vf->priv->w == -2) vf->priv->w = vf->priv->h * d_width / d_height; if (vf->priv->h == -3) vf->priv->h = vf->priv->w * height / width; if (vf->priv->h == -2) vf->priv->h = vf->priv->w * d_height / d_width; if (round_w) vf->priv->w = ((vf->priv->w + 8) / 16) * 16; if (round_h) vf->priv->h = ((vf->priv->h + 8) / 16) * 16; // calculate the missing parameters: switch(best) { case IMGFMT_YV12: /* YV12 needs w & h rounded to 2 */ case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_NV12: case IMGFMT_NV21: vf->priv->h = (vf->priv->h + 1) & ~1; case IMGFMT_YUY2: /* YUY2 needs w rounded to 2 */ case IMGFMT_UYVY: vf->priv->w = (vf->priv->w + 1) & ~1; } mp_msg(MSGT_VFILTER,MSGL_DBG2,"SwScale: scaling %dx%d %s to %dx%d %s \n", width,height,vo_format_name(outfmt), vf->priv->w,vf->priv->h,vo_format_name(best)); // free old ctx: if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); if(vf->priv->ctx2)sws_freeContext(vf->priv->ctx2); // new swscaler: sws_getFlagsAndFilterFromCmdLine(&int_sws_flags, &srcFilter, &dstFilter); int_sws_flags|= vf->priv->v_chr_drop << SWS_SRC_V_CHR_DROP_SHIFT; int_sws_flags|= vf->priv->accurate_rnd * SWS_ACCURATE_RND; vf->priv->ctx=sws_getContext(width, height >> vf->priv->interlaced, sfmt, vf->priv->w, vf->priv->h >> vf->priv->interlaced, dfmt, int_sws_flags | get_sws_cpuflags(), srcFilter, dstFilter, vf->priv->param); if(vf->priv->interlaced){ vf->priv->ctx2=sws_getContext(width, height >> 1, sfmt, vf->priv->w, vf->priv->h >> 1, dfmt, int_sws_flags | get_sws_cpuflags(), srcFilter, dstFilter, vf->priv->param); } if(!vf->priv->ctx){ // error... mp_msg(MSGT_VFILTER,MSGL_WARN,"Couldn't init SwScaler for this setup\n"); return 0; } vf->priv->fmt=best; if(vf->priv->palette){ free(vf->priv->palette); vf->priv->palette=NULL; } switch(best){ case IMGFMT_RGB8: { /* set 332 palette for 8 bpp */ int i; vf->priv->palette=malloc(4*256); for(i=0; i<256; i++){ vf->priv->palette[4*i+0]=4*(i>>6)*21; vf->priv->palette[4*i+1]=4*((i>>3)&7)*9; vf->priv->palette[4*i+2]=4*((i&7)&7)*9; vf->priv->palette[4*i+3]=0; } break; } case IMGFMT_BGR8: { /* set 332 palette for 8 bpp */ int i; vf->priv->palette=malloc(4*256); for(i=0; i<256; i++){ vf->priv->palette[4*i+0]=4*(i&3)*21; vf->priv->palette[4*i+1]=4*((i>>2)&7)*9; vf->priv->palette[4*i+2]=4*((i>>5)&7)*9; vf->priv->palette[4*i+3]=0; } break; } case IMGFMT_BGR4: case IMGFMT_BG4B: { int i; vf->priv->palette=malloc(4*16); for(i=0; i<16; i++){ vf->priv->palette[4*i+0]=4*(i&1)*63; vf->priv->palette[4*i+1]=4*((i>>1)&3)*21; vf->priv->palette[4*i+2]=4*((i>>3)&1)*63; vf->priv->palette[4*i+3]=0; } break; } case IMGFMT_RGB4: case IMGFMT_RG4B: { int i; vf->priv->palette=malloc(4*16); for(i=0; i<16; i++){ vf->priv->palette[4*i+0]=4*(i>>3)*63; vf->priv->palette[4*i+1]=4*((i>>1)&3)*21; vf->priv->palette[4*i+2]=4*((i&1)&1)*63; vf->priv->palette[4*i+3]=0; } break; } } if(!opt_screen_size_x && !opt_screen_size_y && !(screen_size_xy >= 0.001)){ // Compute new d_width and d_height, preserving aspect // while ensuring that both are >= output size in pixels. if (vf->priv->h * d_width > vf->priv->w * d_height) { d_width = vf->priv->h * d_width / d_height; d_height = vf->priv->h; } else { d_height = vf->priv->w * d_height / d_width; d_width = vf->priv->w; } //d_width=d_width*vf->priv->w/width; //d_height=d_height*vf->priv->h/height; } return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,best);}static void start_slice(struct vf_instance_s* vf, mp_image_t *mpi){// printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK); if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) return; // shouldn't happen // they want slices!!! allocate the buffer. mpi->priv=vf->dmpi=vf_get_image(vf->next,vf->priv->fmt,// mpi->type, mpi->flags & (~MP_IMGFLAG_DRAW_CALLBACK), MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, vf->priv->w, vf->priv->h);}static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[3], int src_stride[3], int y, int h, uint8_t *dst[3], int dst_stride[3], int interlaced){ uint8_t *src2[3]={src[0], src[1], src[2]};#ifdef WORDS_BIGENDIAN uint32_t pal2[256]; if (src[1] && !src[2]){ int i; for(i=0; i<256; i++) pal2[i]= bswap_32(((uint32_t*)src[1])[i]); src2[1]= pal2; }#endif if(interlaced){ int i; uint8_t *dst2[3]={dst[0], dst[1], dst[2]}; int src_stride2[3]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2]}; int dst_stride2[3]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2]}; sws_scale_ordered(sws1, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2); for(i=0; i<3; i++){ src2[i] += src_stride[i]; dst2[i] += dst_stride[i]; } sws_scale_ordered(sws2, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2); }else{ sws_scale_ordered(sws1, src2, src_stride, y, h, dst, dst_stride); } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?