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