10 #include "img_format.h"
17 static const struct vf_priv_s
{
25 //===========================================================================//
27 static int config(struct vf_instance
* vf
,
28 int width
, int height
, int d_width
, int d_height
,
29 unsigned int flags
, unsigned int outfmt
){
30 struct MPOpts
*opts
= vf
->opts
;
31 // calculate the missing parameters:
32 if(vf
->priv
->crop_w
<=0 || vf
->priv
->crop_w
>width
) vf
->priv
->crop_w
=width
;
33 if(vf
->priv
->crop_h
<=0 || vf
->priv
->crop_h
>height
) vf
->priv
->crop_h
=height
;
34 if(vf
->priv
->crop_x
<0) vf
->priv
->crop_x
=(width
-vf
->priv
->crop_w
)/2;
35 if(vf
->priv
->crop_y
<0) vf
->priv
->crop_y
=(height
-vf
->priv
->crop_h
)/2;
37 if(!IMGFMT_IS_RGB(outfmt
) && !IMGFMT_IS_BGR(outfmt
)){
58 if(vf
->priv
->crop_w
+vf
->priv
->crop_x
>width
||
59 vf
->priv
->crop_h
+vf
->priv
->crop_y
>height
){
60 mp_msg(MSGT_VFILTER
, MSGL_WARN
, MSGTR_MPCODECS_CropBadPositionWidthHeight
);
63 if(!opts
->screen_size_x
&& !opts
->screen_size_y
){
64 d_width
=d_width
*vf
->priv
->crop_w
/width
;
65 d_height
=d_height
*vf
->priv
->crop_h
/height
;
67 return vf_next_config(vf
,vf
->priv
->crop_w
,vf
->priv
->crop_h
,d_width
,d_height
,flags
,outfmt
);
70 static int put_image(struct vf_instance
* vf
, mp_image_t
*mpi
, double pts
){
72 if (mpi
->flags
&MP_IMGFLAG_DRAW_CALLBACK
)
73 return vf_next_put_image(vf
,vf
->dmpi
, pts
);
74 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
76 vf
->priv
->crop_w
, vf
->priv
->crop_h
);
77 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
78 dmpi
->planes
[0]=mpi
->planes
[0]+
79 vf
->priv
->crop_y
*mpi
->stride
[0]+vf
->priv
->crop_x
;
80 dmpi
->planes
[1]=mpi
->planes
[1]+
81 (vf
->priv
->crop_y
>>mpi
->chroma_y_shift
)*mpi
->stride
[1]+(vf
->priv
->crop_x
>>mpi
->chroma_x_shift
);
82 dmpi
->planes
[2]=mpi
->planes
[2]+
83 (vf
->priv
->crop_y
>>mpi
->chroma_y_shift
)*mpi
->stride
[2]+(vf
->priv
->crop_x
>>mpi
->chroma_x_shift
);
84 dmpi
->stride
[1]=mpi
->stride
[1];
85 dmpi
->stride
[2]=mpi
->stride
[2];
87 dmpi
->planes
[0]=mpi
->planes
[0]+
88 vf
->priv
->crop_y
*mpi
->stride
[0]+
89 vf
->priv
->crop_x
*(mpi
->bpp
/8);
90 dmpi
->planes
[1]=mpi
->planes
[1]; // passthrough rgb8 palette
92 dmpi
->stride
[0]=mpi
->stride
[0];
93 dmpi
->width
=mpi
->width
;
94 return vf_next_put_image(vf
,dmpi
, pts
);
97 static void start_slice(struct vf_instance
* vf
, mp_image_t
*mpi
){
98 vf
->dmpi
= vf_get_image(vf
->next
, mpi
->imgfmt
, mpi
->type
, mpi
->flags
,
99 vf
->priv
->crop_w
, vf
->priv
->crop_h
);
102 static void draw_slice(struct vf_instance
* vf
,
103 unsigned char** src
, int* stride
, int w
,int h
, int x
, int y
){
104 unsigned char *src2
[3];
106 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
110 //mp_msg(MSGT_VFILTER, MSGL_V, "crop slice %d %d %d %d ->", w,h,x,y);
111 if ((x
-= vf
->priv
->crop_x
) < 0) {
114 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
115 src2
[1] += x
>>vf
->dmpi
->chroma_x_shift
;
116 src2
[2] += x
>>vf
->dmpi
->chroma_x_shift
;
121 if ((y
-= vf
->priv
->crop_y
) < 0) {
123 src2
[0] += y
*stride
[0];
124 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
125 src2
[1] += (y
>>vf
->dmpi
->chroma_y_shift
)*stride
[1];
126 src2
[2] += (y
>>vf
->dmpi
->chroma_y_shift
)*stride
[2];
131 if (x
+w
> vf
->priv
->crop_w
) w
= vf
->priv
->crop_w
-x
;
132 if (y
+h
> vf
->priv
->crop_h
) h
= vf
->priv
->crop_h
-y
;
133 //mp_msg(MSGT_VFILTER, MSGL_V, "%d %d %d %d\n", w,h,x,y);
134 if ((w
< 0) || (h
< 0)) return;
135 vf_next_draw_slice(vf
,src2
,stride
,w
,h
,x
,y
);
138 //===========================================================================//
140 static int open(vf_instance_t
*vf
, char* args
){
142 vf
->put_image
=put_image
;
143 vf
->start_slice
=start_slice
;
144 vf
->draw_slice
=draw_slice
;
145 vf
->default_reqs
=VFCAP_ACCEPT_STRIDE
;
147 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
148 // TODO: parse args ->
154 if(args
) sscanf(args
, "%d:%d:%d:%d",
159 mp_msg(MSGT_VFILTER
, MSGL_INFO
, "Crop: %d x %d, %d ; %d\n",
167 #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
168 static const m_option_t vf_opts_fields
[] = {
169 {"w", ST_OFF(crop_w
), CONF_TYPE_INT
, M_OPT_MIN
,0 ,0, NULL
},
170 {"h", ST_OFF(crop_h
), CONF_TYPE_INT
, M_OPT_MIN
,0 ,0, NULL
},
171 {"x", ST_OFF(crop_x
), CONF_TYPE_INT
, M_OPT_MIN
,-1 ,0, NULL
},
172 {"y", ST_OFF(crop_y
), CONF_TYPE_INT
, M_OPT_MIN
,-1 ,0, NULL
},
173 { NULL
, NULL
, 0, 0, 0, 0, NULL
}
176 static const m_struct_t vf_opts
= {
178 sizeof(struct vf_priv_s
),
183 const vf_info_t vf_info_crop
= {
192 //===========================================================================//