9 #include "img_format.h"
16 static const struct vf_priv_s
{
24 extern int opt_screen_size_x
;
25 extern int opt_screen_size_y
;
27 //===========================================================================//
29 static int config(struct vf_instance_s
* vf
,
30 int width
, int height
, int d_width
, int d_height
,
31 unsigned int flags
, unsigned int outfmt
){
32 // calculate the missing parameters:
33 if(vf
->priv
->crop_w
<=0 || vf
->priv
->crop_w
>width
) vf
->priv
->crop_w
=width
;
34 if(vf
->priv
->crop_h
<=0 || vf
->priv
->crop_h
>height
) vf
->priv
->crop_h
=height
;
35 if(vf
->priv
->crop_x
<0) vf
->priv
->crop_x
=(width
-vf
->priv
->crop_w
)/2;
36 if(vf
->priv
->crop_y
<0) vf
->priv
->crop_y
=(height
-vf
->priv
->crop_h
)/2;
38 if(!IMGFMT_IS_RGB(outfmt
) && !IMGFMT_IS_BGR(outfmt
)){
59 if(vf
->priv
->crop_w
+vf
->priv
->crop_x
>width
||
60 vf
->priv
->crop_h
+vf
->priv
->crop_y
>height
){
61 mp_msg(MSGT_VFILTER
, MSGL_WARN
, MSGTR_MPCODECS_CropBadPositionWidthHeight
);
64 if(!opt_screen_size_x
&& !opt_screen_size_y
){
65 d_width
=d_width
*vf
->priv
->crop_w
/width
;
66 d_height
=d_height
*vf
->priv
->crop_h
/height
;
68 return vf_next_config(vf
,vf
->priv
->crop_w
,vf
->priv
->crop_h
,d_width
,d_height
,flags
,outfmt
);
71 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
73 if (mpi
->flags
&MP_IMGFLAG_DRAW_CALLBACK
)
74 return vf_next_put_image(vf
,vf
->dmpi
, pts
);
75 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
77 vf
->priv
->crop_w
, vf
->priv
->crop_h
);
78 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
79 dmpi
->planes
[0]=mpi
->planes
[0]+
80 vf
->priv
->crop_y
*mpi
->stride
[0]+vf
->priv
->crop_x
;
81 dmpi
->planes
[1]=mpi
->planes
[1]+
82 (vf
->priv
->crop_y
>>mpi
->chroma_y_shift
)*mpi
->stride
[1]+(vf
->priv
->crop_x
>>mpi
->chroma_x_shift
);
83 dmpi
->planes
[2]=mpi
->planes
[2]+
84 (vf
->priv
->crop_y
>>mpi
->chroma_y_shift
)*mpi
->stride
[2]+(vf
->priv
->crop_x
>>mpi
->chroma_x_shift
);
85 dmpi
->stride
[1]=mpi
->stride
[1];
86 dmpi
->stride
[2]=mpi
->stride
[2];
88 dmpi
->planes
[0]=mpi
->planes
[0]+
89 vf
->priv
->crop_y
*mpi
->stride
[0]+
90 vf
->priv
->crop_x
*(mpi
->bpp
/8);
91 dmpi
->planes
[1]=mpi
->planes
[1]; // passthrough rgb8 palette
93 dmpi
->stride
[0]=mpi
->stride
[0];
94 dmpi
->width
=mpi
->width
;
95 return vf_next_put_image(vf
,dmpi
, pts
);
98 static void start_slice(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
99 vf
->dmpi
= vf_get_image(vf
->next
, mpi
->imgfmt
, mpi
->type
, mpi
->flags
,
100 vf
->priv
->crop_w
, vf
->priv
->crop_h
);
103 static void draw_slice(struct vf_instance_s
* vf
,
104 unsigned char** src
, int* stride
, int w
,int h
, int x
, int y
){
105 unsigned char *src2
[3];
107 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
111 //mp_msg(MSGT_VFILTER, MSGL_V, "crop slice %d %d %d %d ->", w,h,x,y);
112 if ((x
-= vf
->priv
->crop_x
) < 0) {
115 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
116 src2
[1] += x
>>vf
->dmpi
->chroma_x_shift
;
117 src2
[2] += x
>>vf
->dmpi
->chroma_x_shift
;
122 if ((y
-= vf
->priv
->crop_y
) < 0) {
124 src2
[0] += y
*stride
[0];
125 if (vf
->dmpi
->flags
& MP_IMGFLAG_PLANAR
) {
126 src2
[1] += (y
>>vf
->dmpi
->chroma_y_shift
)*stride
[1];
127 src2
[2] += (y
>>vf
->dmpi
->chroma_y_shift
)*stride
[2];
132 if (x
+w
> vf
->priv
->crop_w
) w
= vf
->priv
->crop_w
-x
;
133 if (y
+h
> vf
->priv
->crop_h
) h
= vf
->priv
->crop_h
-y
;
134 //mp_msg(MSGT_VFILTER, MSGL_V, "%d %d %d %d\n", w,h,x,y);
135 if ((w
< 0) || (h
< 0)) return;
136 vf_next_draw_slice(vf
,src2
,stride
,w
,h
,x
,y
);
139 //===========================================================================//
141 static int open(vf_instance_t
*vf
, char* args
){
143 vf
->put_image
=put_image
;
144 vf
->start_slice
=start_slice
;
145 vf
->draw_slice
=draw_slice
;
146 vf
->default_reqs
=VFCAP_ACCEPT_STRIDE
;
148 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
149 // TODO: parse args ->
155 if(args
) sscanf(args
, "%d:%d:%d:%d",
160 mp_msg(MSGT_VFILTER
, MSGL_INFO
, "Crop: %d x %d, %d ; %d\n",
168 #define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
169 static const m_option_t vf_opts_fields
[] = {
170 {"w", ST_OFF(crop_w
), CONF_TYPE_INT
, M_OPT_MIN
,0 ,0, NULL
},
171 {"h", ST_OFF(crop_h
), CONF_TYPE_INT
, M_OPT_MIN
,0 ,0, NULL
},
172 {"x", ST_OFF(crop_x
), CONF_TYPE_INT
, M_OPT_MIN
,-1 ,0, NULL
},
173 {"y", ST_OFF(crop_y
), CONF_TYPE_INT
, M_OPT_MIN
,-1 ,0, NULL
},
174 { NULL
, NULL
, 0, 0, 0, 0, NULL
}
177 static const m_struct_t vf_opts
= {
179 sizeof(struct vf_priv_s
),
184 const vf_info_t vf_info_crop
= {
193 //===========================================================================//