17 #include "libmpcodecs/img_format.h"
18 #include "libmpcodecs/mp_image.h"
19 #include "libmpcodecs/vf.h"
21 #include "libvo/fastmemcpy.h"
22 #include "libvo/video_out.h"
23 #include "libvo/font_load.h"
24 #include "input/input.h"
27 #include "access_mpcontext.h"
30 static struct vf_priv_s
* st_priv
= NULL
;
32 static mp_image_t
* pause_mpi
= NULL
;
33 static int go2pause
= 0;
34 /// if nonzero display menu at startup
35 int attribute_used menu_startup
= 0;
43 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
);
45 static mp_image_t
* alloc_mpi(int w
, int h
, uint32_t fmt
) {
46 mp_image_t
* mpi
= new_mp_image(w
,h
);
48 mp_image_setfmt(mpi
,fmt
);
49 // IF09 - allocate space for 4. plane delta info - unused
50 if (mpi
->imgfmt
== IMGFMT_IF09
)
52 mpi
->planes
[0]=memalign(64, mpi
->bpp
*mpi
->width
*(mpi
->height
+2)/8+
53 mpi
->chroma_width
*mpi
->chroma_height
);
54 /* delta table, just for fun ;) */
55 mpi
->planes
[3]=mpi
->planes
[0]+2*(mpi
->chroma_width
*mpi
->chroma_height
);
58 mpi
->planes
[0]=memalign(64, mpi
->bpp
*mpi
->width
*(mpi
->height
+2)/8);
59 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
60 // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
61 if(!mpi
->stride
[0]) mpi
->stride
[0]=mpi
->width
;
62 if(!mpi
->stride
[1]) mpi
->stride
[1]=mpi
->stride
[2]=mpi
->chroma_width
;
63 if(mpi
->flags
&MP_IMGFLAG_SWAPPED
){
65 mpi
->planes
[1]=mpi
->planes
[0]+mpi
->width
*mpi
->height
;
66 mpi
->planes
[2]=mpi
->planes
[1]+mpi
->chroma_width
*mpi
->chroma_height
;
68 // YV12,YVU9,IF09 (Y,V,U)
69 mpi
->planes
[2]=mpi
->planes
[0]+mpi
->width
*mpi
->height
;
70 mpi
->planes
[1]=mpi
->planes
[2]+mpi
->chroma_width
*mpi
->chroma_height
;
73 if(!mpi
->stride
[0]) mpi
->stride
[0]=mpi
->width
*mpi
->bpp
/8;
75 mpi
->flags
|=MP_IMGFLAG_ALLOCATED
;
80 void vf_menu_pause_update(struct vf_instance_s
* vf
) {
81 vo_functions_t
*video_out
= mpctx_get_video_out(vf
->priv
->current
->ctx
);
83 put_image(vf
,pause_mpi
, MP_NOPTS_VALUE
);
84 // Don't draw the osd atm
85 //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
86 video_out
->flip_page();
90 static int cmd_filter(mp_cmd_t
* cmd
, int paused
, struct vf_priv_s
* priv
) {
94 #if 0 // http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2003-March/017286.html
95 if(!paused
&& !go2pause
) { // Initial pause cmd -> wait the next put_image
100 if(go2pause
== 2) // Msg resent by put_image after saving the image
103 case MP_CMD_MENU
: { // Convert txt cmd from the users into libmenu stuff
104 char* arg
= cmd
->args
[0].v
.s
;
106 if(!priv
->current
->show
&& !(strcmp(arg
,"hide") == 0) )
107 priv
->current
->show
= 1;
108 else if(strcmp(arg
,"up") == 0)
109 menu_read_cmd(priv
->current
,MENU_CMD_UP
);
110 else if(strcmp(arg
,"down") == 0)
111 menu_read_cmd(priv
->current
,MENU_CMD_DOWN
);
112 else if(strcmp(arg
,"left") == 0)
113 menu_read_cmd(priv
->current
,MENU_CMD_LEFT
);
114 else if(strcmp(arg
,"right") == 0)
115 menu_read_cmd(priv
->current
,MENU_CMD_RIGHT
);
116 else if(strcmp(arg
,"ok") == 0)
117 menu_read_cmd(priv
->current
,MENU_CMD_OK
);
118 else if(strcmp(arg
,"cancel") == 0)
119 menu_read_cmd(priv
->current
,MENU_CMD_CANCEL
);
120 else if(strcmp(arg
,"hide") == 0 || strcmp(arg
,"toggle") == 0)
121 priv
->current
->show
= 0;
123 mp_msg(MSGT_GLOBAL
,MSGL_WARN
,MSGTR_LIBMENU_UnknownMenuCommand
,arg
);
126 case MP_CMD_SET_MENU
: {
127 char* menu
= cmd
->args
[0].v
.s
;
128 menu_t
* l
= priv
->current
;
129 priv
->current
= menu_open(menu
);
131 mp_msg(MSGT_GLOBAL
,MSGL_WARN
,MSGTR_LIBMENU_FailedToOpenMenu
,menu
);
133 priv
->current
->show
= 0;
135 priv
->current
->show
= 1;
136 priv
->current
->parent
= l
;
144 static void get_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
147 if(mpi
->type
== MP_IMGTYPE_TEMP
&& (!(mpi
->flags
&MP_IMGFLAG_PRESERVE
)) ) {
148 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,mpi
->type
, mpi
->flags
, mpi
->w
, mpi
->h
);
149 memcpy(mpi
->planes
,dmpi
->planes
,MP_MAX_PLANES
*sizeof(unsigned char*));
150 memcpy(mpi
->stride
,dmpi
->stride
,MP_MAX_PLANES
*sizeof(unsigned int));
151 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
152 mpi
->priv
=(void*)dmpi
;
157 static void key_cb(int code
) {
158 menu_read_key(st_priv
->current
,code
);
163 inline static void copy_mpi(mp_image_t
*dmpi
, mp_image_t
*mpi
) {
164 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
165 memcpy_pic(dmpi
->planes
[0],mpi
->planes
[0], mpi
->w
, mpi
->h
,
166 dmpi
->stride
[0],mpi
->stride
[0]);
167 memcpy_pic(dmpi
->planes
[1],mpi
->planes
[1], mpi
->chroma_width
, mpi
->chroma_height
,
168 dmpi
->stride
[1],mpi
->stride
[1]);
169 memcpy_pic(dmpi
->planes
[2], mpi
->planes
[2], mpi
->chroma_width
, mpi
->chroma_height
,
170 dmpi
->stride
[2],mpi
->stride
[2]);
172 memcpy_pic(dmpi
->planes
[0],mpi
->planes
[0],
173 mpi
->w
*(dmpi
->bpp
/8), mpi
->h
,
174 dmpi
->stride
[0],mpi
->stride
[0]);
180 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
181 mp_image_t
*dmpi
= NULL
;
183 if (vf
->priv
->passthrough
) {
184 dmpi
=vf_get_image(vf
->next
, IMGFMT_MPEGPES
, MP_IMGTYPE_EXPORT
,
186 dmpi
->planes
[0]=mpi
->planes
[0];
187 return vf_next_put_image(vf
,dmpi
, pts
);
190 if(vf
->priv
->current
->show
191 || (vf
->priv
->current
->parent
&& vf
->priv
->current
->parent
->show
)) {
192 // Close all menu who requested it
193 while(vf
->priv
->current
->cl
&& vf
->priv
->current
!= vf
->priv
->root
) {
194 menu_t
* m
= vf
->priv
->current
;
195 vf
->priv
->current
= m
->parent
? m
->parent
: vf
->priv
->root
;
199 // Step 1 : save the picture
200 while(go2pause
== 1) {
201 static char delay
= 0; // Hack : wait the 2 frame to be sure to show the right picture
202 delay
^= 1; // after a seek
205 if(pause_mpi
&& (mpi
->w
!= pause_mpi
->w
|| mpi
->h
!= pause_mpi
->h
||
206 mpi
->imgfmt
!= pause_mpi
->imgfmt
)) {
207 free_mp_image(pause_mpi
);
211 pause_mpi
= alloc_mpi(mpi
->w
,mpi
->h
,mpi
->imgfmt
);
212 copy_mpi(pause_mpi
,mpi
);
213 mp_input_queue_cmd(mp_input_parse_cmd("pause"));
218 // Grab // Ungrab the keys
219 if(!mp_input_key_cb
&& vf
->priv
->current
->show
)
220 mp_input_key_cb
= key_cb
;
221 if(mp_input_key_cb
&& !vf
->priv
->current
->show
)
222 mp_input_key_cb
= NULL
;
224 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
227 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
228 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
232 menu_draw(vf
->priv
->current
,dmpi
);
236 mp_input_key_cb
= NULL
;
238 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
241 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
242 MP_IMGTYPE_EXPORT
, MP_IMGFLAG_ACCEPT_STRIDE
,
245 dmpi
->stride
[0] = mpi
->stride
[0];
246 dmpi
->stride
[1] = mpi
->stride
[1];
247 dmpi
->stride
[2] = mpi
->stride
[2];
248 dmpi
->planes
[0] = mpi
->planes
[0];
249 dmpi
->planes
[1] = mpi
->planes
[1];
250 dmpi
->planes
[2] = mpi
->planes
[2];
251 dmpi
->priv
= mpi
->priv
;
254 return vf_next_put_image(vf
,dmpi
, pts
);
257 static void uninit(vf_instance_t
*vf
) {
260 free_mp_image(pause_mpi
);
265 static int config(struct vf_instance_s
* vf
, int width
, int height
, int d_width
, int d_height
,
266 unsigned int flags
, unsigned int outfmt
) {
268 // here is the right place to get screen dimensions
269 if (force_load_font
) {
271 load_font_ft(width
,height
,&vo_font
,font_name
);
274 if(outfmt
== IMGFMT_MPEGPES
)
275 vf
->priv
->passthrough
= 1;
276 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
279 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
280 return (vf_next_query_format(vf
,fmt
));
283 static int open_vf(vf_instance_t
*vf
, char* args
){
285 st_priv
= calloc(1,sizeof(struct vf_priv_s
));
286 st_priv
->root
= st_priv
->current
= menu_open(args
);
287 if(!st_priv
->current
) {
292 st_priv
->root
->show
= menu_startup
;
293 mp_input_add_cmd_filter((mp_input_cmd_filter
)cmd_filter
,st_priv
);
297 vf
->query_format
=query_format
;
298 vf
->put_image
= put_image
;
299 vf
->get_image
= get_image
;
308 vf_info_t vf_info_menu
= {
309 "Internal filter for libmenu",