Mercurial > mplayer.hg
changeset 5565:0b301fec999a
capabilities support -> automatic insertion of scale, expand, pp
author | arpi |
---|---|
date | Thu, 11 Apr 2002 20:56:17 +0000 |
parents | efe856039f8f |
children | e01c664def74 |
files | libmpcodecs/vd.c libmpcodecs/ve_lavc.c libmpcodecs/ve_rawrgb.c libmpcodecs/ve_vfw.c libmpcodecs/vf.c libmpcodecs/vf.h libmpcodecs/vf_crop.c libmpcodecs/vf_fame.c libmpcodecs/vf_flip.c libmpcodecs/vf_format.c libmpcodecs/vf_pp.c libmpcodecs/vf_scale.c libmpcodecs/vf_vo.c libmpcodecs/vf_yuy2.c |
diffstat | 14 files changed, 179 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpcodecs/vd.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vd.c Thu Apr 11 20:56:17 2002 +0000 @@ -112,6 +112,7 @@ int vd_use_slices=1; extern vd_functions_t* mpvdec; // FIXME! +extern int divx_quality; int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int preferred_outfmt){ int i,j; @@ -120,6 +121,7 @@ int screen_size_y=0;//SCREEN_SIZE_Y; // vo_functions_t* video_out=sh->video_out; vf_instance_t* vf=sh->vfilter; + unsigned int fmtlist[CODECS_MAX_OUTFMT+1]; #if 1 if(!(sh->disp_w && sh->disp_h)) @@ -137,28 +139,40 @@ w,h,vo_format_name(preferred_outfmt)); if(!vf) return 1; // temp hack + + if(get_video_quality_max(sh)<=0 && divx_quality){ + // user wants postprocess but no pp filter yet: + sh->vfilter=vf=vf_open_filter(vf,"pp",NULL); + } // check if libvo and codec has common outfmt (no conversion): +csp_again: j=-1; for(i=0;i<CODECS_MAX_OUTFMT;i++){ + int flags; out_fmt=sh->codec->outfmt[i]; if(out_fmt==(signed int)0xFFFFFFFF) continue; - vo_flags=vf->query_format(vf,out_fmt); - mp_msg(MSGT_CPLAYER,MSGL_V,"vo_debug: query(%s) returned 0x%X (i=%d) \n",vo_format_name(out_fmt),vo_flags,i); - if((vo_flags&2) || (vo_flags && j<0)){ + flags=vf->query_format(vf,out_fmt); + mp_msg(MSGT_CPLAYER,MSGL_V,"vo_debug: query(%s) returned 0x%X (i=%d) \n",vo_format_name(out_fmt),flags,i); + if((flags&2) || (flags && j<0)){ // check (query) if codec really support this outfmt... if(mpvdec->control(sh,VDCTRL_QUERY_FORMAT,&out_fmt)==CONTROL_FALSE) continue; - j=i; if(vo_flags&2) break; + j=i; vo_flags=flags; if(flags&2) break; } } if(j<0){ // TODO: no match - we should use conversion... + if(strcmp(vf->info->name,"scale")){ + vf=vf_open_filter(vf,"scale",NULL); + goto csp_again; + } mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_VOincompCodec); return 0; // failed } out_fmt=sh->codec->outfmt[j]; sh->outfmtidx=j; + sh->vfilter=vf; // autodetect flipping if(flip==-1){ @@ -167,6 +181,11 @@ if(!(sh->codec->outflags[j]&CODECS_FLAG_NOFLIP)) flip=1; } + if(vo_flags&VFCAP_FLIPPED) flip^=1; + if(flip && !(vo_flags&VFCAP_FLIP)){ + // we need to flip, but no flipping filter avail. + sh->vfilter=vf=vf_open_filter(vf,"flip",NULL); + } // time to do aspect ratio corrections...
--- a/libmpcodecs/ve_lavc.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/ve_lavc.c Thu Apr 11 20:56:17 2002 +0000 @@ -178,7 +178,7 @@ case IMGFMT_YV12: case IMGFMT_IYUV: case IMGFMT_I420: - return 1; + return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE; } return 0; }
--- a/libmpcodecs/ve_rawrgb.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/ve_rawrgb.c Thu Apr 11 20:56:17 2002 +0000 @@ -40,7 +40,7 @@ } static int query_format(struct vf_instance_s* vf, unsigned int fmt){ - if(fmt==IMGFMT_BGR24) return 1; + if(fmt==IMGFMT_BGR24) return 3; return 0; }
--- a/libmpcodecs/ve_vfw.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/ve_vfw.c Thu Apr 11 20:56:17 2002 +0000 @@ -53,7 +53,7 @@ } static int query_format(struct vf_instance_s* vf, unsigned int fmt){ - if(fmt==IMGFMT_BGR24) return 1; + if(fmt==IMGFMT_BGR24) return 3 | VFCAP_FLIPPED; return 0; }
--- a/libmpcodecs/vf.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf.c Thu Apr 11 20:56:17 2002 +0000 @@ -162,6 +162,8 @@ vf->control=vf_next_control; vf->query_format=vf_next_query_format; vf->put_image=vf_next_put_image; + vf->default_caps=VFCAP_ACCEPT_STRIDE; + vf->default_reqs=0; if(vf->info->open(vf,args)>0) return vf; // Success! free(vf); mp_msg(MSGT_VFILTER,MSGL_ERR,"Couldn't open video filter '%s'\n",name); @@ -174,10 +176,66 @@ //============================================================================ +unsigned int vf_match_csp(vf_instance_t** vfp,unsigned int* list,unsigned int preferred){ + vf_instance_t* vf=*vfp; + unsigned int* p; + unsigned int best=0; + int ret; + if((p=list)) while(*p){ + ret=vf->query_format(vf,*p); + mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3); + if(ret&2){ best=*p; break;} // no conversion -> bingo! + if(ret&1 && !best) best=*p; // best with conversion + ++p; + } + if(best) return best; // bingo, they have common csp! + // ok, then try with scale: + if(vf->info == &vf_info_scale) return 0; // avoid infinite recursion! + vf=vf_open_filter(vf,"scale",NULL); + if(!vf) return 0; // failed to init "scale" + // try the preferred csp first: + if(preferred && vf->query_format(vf,preferred)) best=preferred; else + // try the list again, now with "scaler" : + if((p=list)) while(*p){ + ret=vf->query_format(vf,*p); + mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3); + if(ret&2){ best=*p; break;} // no conversion -> bingo! + if(ret&1 && !best) best=*p; // best with conversion + ++p; + } + if(best) *vfp=vf; // else uninit vf !FIXME! + return best; +} + int vf_next_config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - return vf->next->config(vf->next,width,height,d_width,d_height,flags,outfmt); + unsigned int voflags, unsigned int outfmt){ + int miss; + int flags=vf->next->query_format(vf->next,outfmt); + if(!flags){ + // hmm. colorspace mismatch!!! + // let's insert the 'scale' filter, it does the job for us: + vf_instance_t* vf2; + if(vf->next->info==&vf_info_scale) return 0; // scale->scale + vf2=vf_open_filter(vf->next,"scale",NULL); + if(!vf2) return 0; // shouldn't happen! + vf->next=vf2; + flags=vf->next->query_format(vf->next,outfmt); + if(!flags){ + mp_msg(MSGT_VFILTER,MSGL_ERR,"Cannot find common colorspace, even by inserting 'scale' :(\n"); + return 0; // FAIL + } + } + printf("REQ: flags=0x%X req=0x%X \n",flags,vf->default_reqs); + miss=vf->default_reqs - (flags&vf->default_reqs); + if(miss&VFCAP_ACCEPT_STRIDE){ + // vf requires stride support but vf->next doesn't support it! + // let's insert the 'expand' filter, it does the job for us: + vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL); + if(!vf2) return 0; // shouldn't happen! + vf->next=vf2; + } + return vf->next->config(vf->next,width,height,d_width,d_height,voflags,outfmt); } int vf_next_control(struct vf_instance_s* vf, int request, void* data){ @@ -185,7 +243,9 @@ } int vf_next_query_format(struct vf_instance_s* vf, unsigned int fmt){ - return vf->next->query_format(vf->next,fmt); + int flags=vf->next->query_format(vf->next,fmt); + if(flags) flags|=vf->default_caps; + return flags; } void vf_next_put_image(struct vf_instance_s* vf,mp_image_t *mpi){
--- a/libmpcodecs/vf.h Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf.h Thu Apr 11 20:56:17 2002 +0000 @@ -34,6 +34,9 @@ void (*draw_slice)(struct vf_instance_s* vf, unsigned char* src, int* stride, int w,int h, int x, int y); void (*uninit)(struct vf_instance_s* vf); + // caps: + unsigned int default_caps; // used by default query_format() + unsigned int default_reqs; // used by default config() // data: vf_image_context_t imgctx; struct vf_instance_s* next; @@ -47,29 +50,7 @@ #define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */ #define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */ -// VFCAP_* values: they are flags, returned by query_format(): - -// set, if the given colorspace is supported (with or without conversion) -#define VFCAP_CSP_SUPPORTED 0x1 -// set, if the given colorspace is supported _without_ conversion -#define VFCAP_CSP_SUPPORTED_BY_HW 0x2 -// set if the driver/filter can draw OSD -#define VFCAP_OSD 0x4 -// set if the driver/filter can handle compressed SPU stream -#define VFCAP_SPU 0x8 -// scaling up/down by hardware, or software: -#define VFCAP_HWSCALE_UP 0x10 -#define VFCAP_HWSCALE_DOWN 0x20 -#define VFCAP_SWSCALE 0x40 -// driver/filter can do vertical flip (upside-down) -#define VFCAP_FLIP 0x80 - -// driver/hardware handles timing (blocking) -#define VFCAP_TIMER 0x100 -// driver _always_ flip image upside-down (for ve_vfw) -#define VFCAP_FLIPPED 0x200 -// driver accept stride: (put_image/draw_frame) -#define VFCAP_ACCEPT_STRIDE 0x400 +#include "vfcap.h" // functions: mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h); @@ -78,6 +59,8 @@ vf_instance_t* vf_open_filter(vf_instance_t* next, char *name, char *args); vf_instance_t* vf_open_encoder(vf_instance_t* next, char *name, char *args); +unsigned int vf_match_csp(vf_instance_t** vfp,unsigned int* list,unsigned int preferred); + // default wrappers: int vf_next_config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height,
--- a/libmpcodecs/vf_crop.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_crop.c Thu Apr 11 20:56:17 2002 +0000 @@ -61,6 +61,7 @@ static int open(vf_instance_t *vf, char* args){ vf->config=config; vf->put_image=put_image; + vf->default_reqs=VFCAP_ACCEPT_STRIDE; vf->priv=malloc(sizeof(struct vf_priv_s)); // TODO: parse args -> vf->priv->crop_x=
--- a/libmpcodecs/vf_fame.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_fame.c Thu Apr 11 20:56:17 2002 +0000 @@ -81,7 +81,7 @@ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: - return 3; //vf_next_query_format(vf,fmt); + return (vf_next_query_format(vf,fmt) & (~VFCAP_CSP_SUPPORTED_BY_HW)); } return 0; }
--- a/libmpcodecs/vf_flip.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_flip.c Thu Apr 11 20:56:17 2002 +0000 @@ -69,6 +69,7 @@ static int open(vf_instance_t *vf, char* args){ vf->get_image=get_image; vf->put_image=put_image; + vf->default_reqs=VFCAP_ACCEPT_STRIDE; vf->priv=malloc(sizeof(struct vf_priv_s)); return 1; }
--- a/libmpcodecs/vf_format.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_format.c Thu Apr 11 20:56:17 2002 +0000 @@ -35,6 +35,7 @@ if(!strcasecmp(args,"bgr24")) vf->priv->fmt=IMGFMT_BGR24; else if(!strcasecmp(args,"bgr32")) vf->priv->fmt=IMGFMT_BGR32; else if(!strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else + if(!strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else { printf("Unknown format name: '%s'\n",args);return 0;} } else vf->priv->fmt=IMGFMT_YUY2; @@ -46,7 +47,7 @@ "force output format", "format", "A'rpi", - "", + "FIXME! get_image()/put_image()", open };
--- a/libmpcodecs/vf_pp.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_pp.c Thu Apr 11 20:56:17 2002 +0000 @@ -14,16 +14,23 @@ struct vf_priv_s { unsigned int pp; mp_image_t *dmpi; + unsigned int outfmt; }; //===========================================================================// +static int config(struct vf_instance_s* vf, + int width, int height, int d_width, int d_height, + unsigned int voflags, unsigned int outfmt){ + return vf_next_config(vf,width,height,d_width,d_height,voflags,vf->priv->outfmt); +} + static int query_format(struct vf_instance_s* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: - return vf_next_query_format(vf,fmt); + return vf_next_query_format(vf,vf->priv->outfmt); } return 0; } @@ -43,6 +50,8 @@ if(vf->priv->pp&0xFFFF) return; // non-local filters enabled if((mpi->type==MP_IMGTYPE_IPB || vf->priv->pp) && mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change + if(!(mpi->flags&MP_IMGFLAG_ACCEPT_STRIDE) && mpi->imgfmt!=vf->priv->outfmt) + return; // colorspace differ // ok, we can do pp in-place (or pp disabled): vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt, mpi->type, mpi->flags, mpi->w, mpi->h); @@ -61,7 +70,7 @@ static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){ if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ // no DR, so get a new image! hope we'll get DR buffer: - vf->priv->dmpi=vf_get_image(vf->next,mpi->imgfmt, + vf->priv->dmpi=vf_get_image(vf->next,vf->priv->outfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ALIGNED_STRIDE, mpi->w,mpi->h); } @@ -82,13 +91,27 @@ extern int divx_quality; +static unsigned int fmt_list[]={ + IMGFMT_YV12, + IMGFMT_I420, + IMGFMT_IYUV, + NULL +}; + static int open(vf_instance_t *vf, char* args){ char *endptr; vf->query_format=query_format; vf->control=control; + vf->config=config; vf->get_image=get_image; vf->put_image=put_image; + vf->default_caps=VFCAP_ACCEPT_STRIDE|VFCAP_POSTPROC; vf->priv=malloc(sizeof(struct vf_priv_s)); + + // check csp: + vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12); + if(!vf->priv->outfmt) return 0; // no csp match :( + if(args){ vf->priv->pp=strtol(args, &endptr, 0); if(!(*endptr)) return 1;
--- a/libmpcodecs/vf_scale.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_scale.c Thu Apr 11 20:56:17 2002 +0000 @@ -32,12 +32,9 @@ NULL }; -static int config(struct vf_instance_s* vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ +static unsigned int find_best_out(vf_instance_t *vf){ + unsigned int best=0; unsigned int* p=outfmt_list; - unsigned int best=0; - // find the best outfmt: while(*p){ int ret=vf_next_query_format(vf,*p); @@ -46,10 +43,43 @@ if(ret&1 && !best) best=*p; // best with conversion ++p; } + 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; + if(!best){ printf("SwScale: no supported outfmt found :(\n"); return 0; } + + 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; + } + } // calculate the missing parameters: if(vf->priv->w<=0) vf->priv->w=width; @@ -110,10 +140,19 @@ case IMGFMT_BGR15: case IMGFMT_RGB32: case IMGFMT_RGB24: - case IMGFMT_Y800: - return 3; //vf_next_query_format(vf,fmt); + case IMGFMT_Y800: { + 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&3)) 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; + return 0; // nomatching in-fmt } static int open(vf_instance_t *vf, char* args){
--- a/libmpcodecs/vf_vo.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_vo.c Thu Apr 11 20:56:17 2002 +0000 @@ -47,7 +47,12 @@ } static int query_format(struct vf_instance_s* vf, unsigned int fmt){ - return video_out->control(VOCTRL_QUERY_FORMAT,&fmt); + int flags=video_out->control(VOCTRL_QUERY_FORMAT,&fmt); + // draw_slice() accepts stride, draw_frame() doesn't: + if(flags) + if(fmt==IMGFMT_YV12 || fmt==IMGFMT_I420 || fmt==IMGFMT_IYUV) + flags|=VFCAP_ACCEPT_STRIDE; + return flags; } static void get_image(struct vf_instance_s* vf,
--- a/libmpcodecs/vf_yuy2.c Thu Apr 11 20:55:10 2002 +0000 +++ b/libmpcodecs/vf_yuy2.c Thu Apr 11 20:56:17 2002 +0000 @@ -51,7 +51,7 @@ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: - return 3; //vf_next_query_format(vf,fmt); + return vf_next_query_format(vf,IMGFMT_YUY2) & (~VFCAP_CSP_SUPPORTED_BY_HW); } return 0; }