mirror of https://github.com/mpv-player/mpv
vf_crop: make it work with more image formats
This commit is contained in:
parent
926c6631ff
commit
f282d0b290
|
@ -43,69 +43,50 @@ static const struct vf_priv_s {
|
|||
|
||||
static int config(struct vf_instance *vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt){
|
||||
struct MPOpts *opts = vf->opts;
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
{
|
||||
// calculate the missing parameters:
|
||||
if(vf->priv->crop_w<=0 || vf->priv->crop_w>width) vf->priv->crop_w=width;
|
||||
if(vf->priv->crop_h<=0 || vf->priv->crop_h>height) vf->priv->crop_h=height;
|
||||
if(vf->priv->crop_x<0) vf->priv->crop_x=(width-vf->priv->crop_w)/2;
|
||||
if(vf->priv->crop_y<0) vf->priv->crop_y=(height-vf->priv->crop_h)/2;
|
||||
// rounding:
|
||||
if(!IMGFMT_IS_RGB(outfmt)){
|
||||
switch(outfmt){
|
||||
case IMGFMT_444P:
|
||||
case IMGFMT_Y8:
|
||||
break;
|
||||
case IMGFMT_410P:
|
||||
vf->priv->crop_y&=~3;
|
||||
case IMGFMT_411P:
|
||||
vf->priv->crop_x&=~3;
|
||||
break;
|
||||
case IMGFMT_420P:
|
||||
vf->priv->crop_y&=~1;
|
||||
default:
|
||||
vf->priv->crop_x&=~1;
|
||||
}
|
||||
}
|
||||
|
||||
struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(outfmt);
|
||||
|
||||
vf->priv->crop_x = MP_ALIGN_DOWN(vf->priv->crop_x, fmt.align_x);
|
||||
vf->priv->crop_y = MP_ALIGN_DOWN(vf->priv->crop_y, fmt.align_y);
|
||||
|
||||
// check:
|
||||
if(vf->priv->crop_w+vf->priv->crop_x>width ||
|
||||
vf->priv->crop_h+vf->priv->crop_y>height){
|
||||
mp_tmsg(MSGT_VFILTER, MSGL_WARN, "[CROP] Bad position/width/height - cropped area outside of the original!\n");
|
||||
return 0;
|
||||
}
|
||||
if(!opts->screen_size_x && !opts->screen_size_y){
|
||||
d_width=d_width*vf->priv->crop_w/width;
|
||||
d_height=d_height*vf->priv->crop_h/height;
|
||||
}
|
||||
vf_rescale_dsize(vf, &d_width, &d_height, width, height,
|
||||
vf->priv->crop_w, vf->priv->crop_h);
|
||||
return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
|
||||
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
|
||||
{
|
||||
mp_image_t *dmpi = mpi;
|
||||
if(mpi->flags&MP_IMGFLAG_PLANAR){
|
||||
dmpi->planes[0]=mpi->planes[0]+
|
||||
vf->priv->crop_y*mpi->stride[0]+vf->priv->crop_x;
|
||||
dmpi->planes[1]=mpi->planes[1]+
|
||||
(vf->priv->crop_y>>mpi->chroma_y_shift)*mpi->stride[1]+(vf->priv->crop_x>>mpi->chroma_x_shift);
|
||||
dmpi->planes[2]=mpi->planes[2]+
|
||||
(vf->priv->crop_y>>mpi->chroma_y_shift)*mpi->stride[2]+(vf->priv->crop_x>>mpi->chroma_x_shift);
|
||||
dmpi->stride[1]=mpi->stride[1];
|
||||
dmpi->stride[2]=mpi->stride[2];
|
||||
} else {
|
||||
dmpi->planes[0]=mpi->planes[0]+
|
||||
vf->priv->crop_y*mpi->stride[0]+
|
||||
vf->priv->crop_x*(mpi->bpp/8);
|
||||
}
|
||||
mp_image_set_size(dmpi, vf->priv->crop_w, vf->priv->crop_h);
|
||||
mp_image_crop(mpi, vf->priv->crop_x, vf->priv->crop_y,
|
||||
vf->priv->crop_x + vf->priv->crop_w,
|
||||
vf->priv->crop_y + vf->priv->crop_h);
|
||||
return mpi;
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
static int query_format(struct vf_instance *vf, unsigned int fmt)
|
||||
{
|
||||
if (!IMGFMT_IS_HWACCEL(fmt))
|
||||
return vf_next_query_format(vf, fmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->config=config;
|
||||
vf->filter=filter;
|
||||
vf->query_format=query_format;
|
||||
mp_msg(MSGT_VFILTER, MSGL_INFO, "Crop: %d x %d, %d ; %d\n",
|
||||
vf->priv->crop_w,
|
||||
vf->priv->crop_h,
|
||||
|
|
|
@ -126,4 +126,8 @@ struct mp_csp_details;
|
|||
void mp_image_set_colorspace_details(struct mp_image *image,
|
||||
struct mp_csp_details *csp);
|
||||
|
||||
// align must be a power of two (align >= 1), v >= 0
|
||||
#define MP_ALIGN_UP(v, align) FFALIGN(v, align)
|
||||
#define MP_ALIGN_DOWN(v, align) ((v) & ~((align) - 1))
|
||||
|
||||
#endif /* MPLAYER_MP_IMAGE_H */
|
||||
|
|
Loading…
Reference in New Issue