12 #include "../mp_msg.h"
14 #include "../libmpcodecs/img_format.h"
15 #include "../libmpcodecs/mp_image.h"
16 #include "../libmpcodecs/vf.h"
18 #include "../libvo/fastmemcpy.h"
19 #include "../libvo/video_out.h"
20 #include "../libvo/font_load.h"
21 #include "../input/input.h"
22 #include "../m_struct.h"
25 extern vo_functions_t
* video_out
;
28 static struct vf_priv_s
* st_priv
= NULL
;
30 static mp_image_t
* pause_mpi
= NULL
;
31 static int go2pause
= 0;
38 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
);
40 static mp_image_t
* alloc_mpi(int w
, int h
, uint32_t fmt
) {
41 mp_image_t
* mpi
= new_mp_image(w
,h
);
43 mp_image_setfmt(mpi
,fmt
);
44 // IF09 - allocate space for 4. plane delta info - unused
45 if (mpi
->imgfmt
== IMGFMT_IF09
)
47 mpi
->planes
[0]=memalign(64, mpi
->bpp
*mpi
->width
*(mpi
->height
+2)/8+
48 mpi
->chroma_width
*mpi
->chroma_height
);
49 /* delta table, just for fun ;) */
50 mpi
->planes
[3]=mpi
->planes
[0]+2*(mpi
->chroma_width
*mpi
->chroma_height
);
53 mpi
->planes
[0]=memalign(64, mpi
->bpp
*mpi
->width
*(mpi
->height
+2)/8);
54 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
55 // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
56 if(!mpi
->stride
[0]) mpi
->stride
[0]=mpi
->width
;
57 if(!mpi
->stride
[1]) mpi
->stride
[1]=mpi
->stride
[2]=mpi
->chroma_width
;
58 if(mpi
->flags
&MP_IMGFLAG_SWAPPED
){
60 mpi
->planes
[1]=mpi
->planes
[0]+mpi
->width
*mpi
->height
;
61 mpi
->planes
[2]=mpi
->planes
[1]+mpi
->chroma_width
*mpi
->chroma_height
;
63 // YV12,YVU9,IF09 (Y,V,U)
64 mpi
->planes
[2]=mpi
->planes
[0]+mpi
->width
*mpi
->height
;
65 mpi
->planes
[1]=mpi
->planes
[2]+mpi
->chroma_width
*mpi
->chroma_height
;
68 if(!mpi
->stride
[0]) mpi
->stride
[0]=mpi
->width
*mpi
->bpp
/8;
70 mpi
->flags
|=MP_IMGFLAG_ALLOCATED
;
75 void vf_menu_pause_update(struct vf_instance_s
* vf
) {
77 put_image(vf
,pause_mpi
);
78 // Don't draw the osd atm
79 //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
80 video_out
->flip_page();
84 static int cmd_filter(mp_cmd_t
* cmd
, int paused
, struct vf_priv_s
* priv
) {
88 #if 0 // http://mplayerhq.hu/pipermail/mplayer-dev-eng/2003-March/017331.html
89 if(!paused
&& !go2pause
) { // Initial pause cmd -> wait the next put_image
94 if(go2pause
== 2) // Msg resent by put_image after saving the image
97 case MP_CMD_MENU
: { // Convert txt cmd from the users into libmenu stuff
98 char* arg
= cmd
->args
[0].v
.s
;
100 if(!priv
->current
->show
)
101 priv
->current
->show
= 1;
102 else if(strcmp(arg
,"up") == 0)
103 menu_read_cmd(priv
->current
,MENU_CMD_UP
);
104 else if(strcmp(arg
,"down") == 0)
105 menu_read_cmd(priv
->current
,MENU_CMD_DOWN
);
106 else if(strcmp(arg
,"ok") == 0)
107 menu_read_cmd(priv
->current
,MENU_CMD_OK
);
108 else if(strcmp(arg
,"cancel") == 0)
109 menu_read_cmd(priv
->current
,MENU_CMD_CANCEL
);
110 else if(strcmp(arg
,"hide") == 0)
111 priv
->current
->show
= 0;
113 printf("Unknown menu command: '%s'\n",arg
);
116 case MP_CMD_SET_MENU
: {
117 char* menu
= cmd
->args
[0].v
.s
;
118 menu_t
* l
= priv
->current
;
119 priv
->current
= menu_open(menu
);
121 printf("Failed to open menu '%s'\n",menu
);
123 priv
->current
->show
= 0;
125 priv
->current
->show
= 1;
126 priv
->current
->parent
= l
;
134 static void get_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
137 if(mpi
->type
== MP_IMGTYPE_TEMP
&& (!(mpi
->flags
&MP_IMGFLAG_PRESERVE
)) ) {
138 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,mpi
->type
, mpi
->flags
, mpi
->w
, mpi
->h
);
139 memcpy(mpi
->planes
,dmpi
->planes
,MP_MAX_PLANES
*sizeof(unsigned char*));
140 memcpy(mpi
->stride
,dmpi
->stride
,MP_MAX_PLANES
*sizeof(unsigned int));
141 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
142 mpi
->priv
=(void*)dmpi
;
147 static void key_cb(int code
) {
148 menu_read_key(st_priv
->current
,code
);
153 inline static void copy_mpi(mp_image_t
*dmpi
, mp_image_t
*mpi
) {
154 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
155 memcpy_pic(dmpi
->planes
[0],mpi
->planes
[0], mpi
->w
, mpi
->h
,
156 dmpi
->stride
[0],mpi
->stride
[0]);
157 memcpy_pic(dmpi
->planes
[1],mpi
->planes
[1], mpi
->chroma_width
, mpi
->chroma_height
,
158 dmpi
->stride
[1],mpi
->stride
[1]);
159 memcpy_pic(dmpi
->planes
[2], mpi
->planes
[2], mpi
->chroma_width
, mpi
->chroma_height
,
160 dmpi
->stride
[2],mpi
->stride
[2]);
162 memcpy_pic(dmpi
->planes
[0],mpi
->planes
[0],
163 mpi
->w
*(dmpi
->bpp
/8), mpi
->h
,
164 dmpi
->stride
[0],mpi
->stride
[0]);
170 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
171 mp_image_t
*dmpi
= NULL
;
173 if(vf
->priv
->current
->show
174 || (vf
->priv
->current
->parent
&& vf
->priv
->current
->parent
->show
)) {
175 // Close all menu who requested it
176 while(vf
->priv
->current
->cl
&& vf
->priv
->current
!= vf
->priv
->root
) {
177 menu_t
* m
= vf
->priv
->current
;
178 vf
->priv
->current
= m
->parent
? m
->parent
: vf
->priv
->root
;
182 // Step 1 : save the picture
183 while(go2pause
== 1) {
184 static char delay
= 0; // Hack : wait the 2 frame to be sure to show the right picture
185 delay
^= 1; // after a seek
188 if(pause_mpi
&& (mpi
->w
!= pause_mpi
->w
|| mpi
->h
!= pause_mpi
->h
||
189 mpi
->imgfmt
!= pause_mpi
->imgfmt
)) {
190 free_mp_image(pause_mpi
);
194 pause_mpi
= alloc_mpi(mpi
->w
,mpi
->h
,mpi
->imgfmt
);
195 copy_mpi(pause_mpi
,mpi
);
196 mp_input_queue_cmd(mp_input_parse_cmd("pause"));
201 // Grab // Ungrab the keys
202 if(!mp_input_key_cb
&& vf
->priv
->current
->show
)
203 mp_input_key_cb
= key_cb
;
204 if(mp_input_key_cb
&& !vf
->priv
->current
->show
)
205 mp_input_key_cb
= NULL
;
207 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
210 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
211 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
215 menu_draw(vf
->priv
->current
,dmpi
);
219 mp_input_key_cb
= NULL
;
220 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
221 MP_IMGTYPE_EXPORT
, MP_IMGFLAG_ACCEPT_STRIDE
,
224 dmpi
->stride
[0] = mpi
->stride
[0];
225 dmpi
->stride
[1] = mpi
->stride
[1];
226 dmpi
->stride
[2] = mpi
->stride
[2];
227 dmpi
->planes
[0] = mpi
->planes
[0];
228 dmpi
->planes
[1] = mpi
->planes
[1];
229 dmpi
->planes
[2] = mpi
->planes
[2];
230 dmpi
->priv
= mpi
->priv
;
232 return vf_next_put_image(vf
,dmpi
);
235 static void uninit(vf_instance_t
*vf
) {
238 free_mp_image(pause_mpi
);
243 static int config(struct vf_instance_s
* vf
, int width
, int height
, int d_width
, int d_height
,
244 unsigned int flags
, unsigned int outfmt
) {
246 // here is the right place to get screen dimensions
247 if (force_load_font
) {
249 load_font_ft(width
,height
);
252 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
254 static int open(vf_instance_t
*vf
, char* args
){
256 st_priv
= calloc(1,sizeof(struct vf_priv_s
));
257 st_priv
->root
= st_priv
->current
= menu_open(args
);
258 if(!st_priv
->current
) {
263 mp_input_add_cmd_filter((mp_input_cmd_filter
)cmd_filter
,st_priv
);
267 vf
->put_image
= put_image
;
268 vf
->get_image
= get_image
;
277 vf_info_t vf_info_menu
= {
278 "Internal filter for libmenu",