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 "libvo/sub.h"
25 #include "input/input.h"
28 #include "access_mpcontext.h"
31 static struct vf_priv_s
* st_priv
= NULL
;
33 static mp_image_t
* pause_mpi
= NULL
;
34 static int go2pause
= 0;
35 /// if nonzero display menu at startup
36 int attribute_used menu_startup
= 0;
44 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
);
46 void vf_menu_pause_update(struct vf_instance_s
* vf
) {
47 vo_functions_t
*video_out
= mpctx_get_video_out(vf
->priv
->current
->ctx
);
49 put_image(vf
,pause_mpi
, MP_NOPTS_VALUE
);
50 // Don't draw the osd atm
51 //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
52 video_out
->flip_page();
56 static int cmd_filter(mp_cmd_t
* cmd
, int paused
, struct vf_priv_s
* priv
) {
59 case MP_CMD_MENU
: { // Convert txt cmd from the users into libmenu stuff
60 char* arg
= cmd
->args
[0].v
.s
;
62 if(!priv
->current
->show
&& !(strcmp(arg
,"hide") == 0) )
63 priv
->current
->show
= 1;
64 else if(strcmp(arg
,"up") == 0)
65 menu_read_cmd(priv
->current
,MENU_CMD_UP
);
66 else if(strcmp(arg
,"down") == 0)
67 menu_read_cmd(priv
->current
,MENU_CMD_DOWN
);
68 else if(strcmp(arg
,"left") == 0)
69 menu_read_cmd(priv
->current
,MENU_CMD_LEFT
);
70 else if(strcmp(arg
,"right") == 0)
71 menu_read_cmd(priv
->current
,MENU_CMD_RIGHT
);
72 else if(strcmp(arg
,"ok") == 0)
73 menu_read_cmd(priv
->current
,MENU_CMD_OK
);
74 else if(strcmp(arg
,"cancel") == 0)
75 menu_read_cmd(priv
->current
,MENU_CMD_CANCEL
);
76 else if(strcmp(arg
,"hide") == 0 || strcmp(arg
,"toggle") == 0)
77 priv
->current
->show
= 0;
79 mp_msg(MSGT_GLOBAL
,MSGL_WARN
,MSGTR_LIBMENU_UnknownMenuCommand
,arg
);
82 case MP_CMD_SET_MENU
: {
83 char* menu
= cmd
->args
[0].v
.s
;
84 menu_t
* l
= priv
->current
;
85 priv
->current
= menu_open(menu
);
87 mp_msg(MSGT_GLOBAL
,MSGL_WARN
,MSGTR_LIBMENU_FailedToOpenMenu
,menu
);
89 priv
->current
->show
= 0;
91 priv
->current
->show
= 1;
92 priv
->current
->parent
= l
;
100 static void get_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
103 if(mpi
->type
== MP_IMGTYPE_TEMP
&& (!(mpi
->flags
&MP_IMGFLAG_PRESERVE
)) ) {
104 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,mpi
->type
, mpi
->flags
, mpi
->w
, mpi
->h
);
105 memcpy(mpi
->planes
,dmpi
->planes
,MP_MAX_PLANES
*sizeof(unsigned char*));
106 memcpy(mpi
->stride
,dmpi
->stride
,MP_MAX_PLANES
*sizeof(unsigned int));
107 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
108 mpi
->priv
=(void*)dmpi
;
113 static void key_cb(int code
) {
114 menu_read_key(st_priv
->current
,code
);
117 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
118 mp_image_t
*dmpi
= NULL
;
120 if (vf
->priv
->passthrough
) {
121 dmpi
=vf_get_image(vf
->next
, IMGFMT_MPEGPES
, MP_IMGTYPE_EXPORT
,
123 dmpi
->planes
[0]=mpi
->planes
[0];
124 return vf_next_put_image(vf
,dmpi
, pts
);
127 // Close all menu who requested it
128 while(vf
->priv
->current
->cl
&& vf
->priv
->current
!= vf
->priv
->root
) {
129 menu_t
* m
= vf
->priv
->current
;
130 vf
->priv
->current
= m
->parent
? m
->parent
: vf
->priv
->root
;
134 // Try to capture the last frame before pause, or fallback to use
135 // last captured frame.
136 if(pause_mpi
&& (mpi
->w
!= pause_mpi
->w
|| mpi
->h
!= pause_mpi
->h
||
137 mpi
->imgfmt
!= pause_mpi
->imgfmt
)) {
138 free_mp_image(pause_mpi
);
142 pause_mpi
= alloc_mpi(mpi
->w
,mpi
->h
,mpi
->imgfmt
);
143 copy_mpi(pause_mpi
,mpi
);
145 else if (mpctx_get_osd_function(vf
->priv
->root
->ctx
) == OSD_PAUSE
)
146 copy_mpi(pause_mpi
,mpi
);
148 if (vf
->priv
->current
->show
) {
149 if (!mp_input_key_cb
)
150 mp_input_key_cb
= key_cb
;
152 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
155 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
156 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
160 menu_draw(vf
->priv
->current
,dmpi
);
164 mp_input_key_cb
= NULL
;
166 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
169 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
170 MP_IMGTYPE_EXPORT
, MP_IMGFLAG_ACCEPT_STRIDE
,
173 dmpi
->stride
[0] = mpi
->stride
[0];
174 dmpi
->stride
[1] = mpi
->stride
[1];
175 dmpi
->stride
[2] = mpi
->stride
[2];
176 dmpi
->planes
[0] = mpi
->planes
[0];
177 dmpi
->planes
[1] = mpi
->planes
[1];
178 dmpi
->planes
[2] = mpi
->planes
[2];
179 dmpi
->priv
= mpi
->priv
;
182 return vf_next_put_image(vf
,dmpi
, pts
);
185 static void uninit(vf_instance_t
*vf
) {
188 free_mp_image(pause_mpi
);
193 static int config(struct vf_instance_s
* vf
, int width
, int height
, int d_width
, int d_height
,
194 unsigned int flags
, unsigned int outfmt
) {
196 // here is the right place to get screen dimensions
197 if (force_load_font
) {
199 load_font_ft(width
,height
,&vo_font
,font_name
);
202 if(outfmt
== IMGFMT_MPEGPES
)
203 vf
->priv
->passthrough
= 1;
204 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
207 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
208 return (vf_next_query_format(vf
,fmt
));
211 static int open_vf(vf_instance_t
*vf
, char* args
){
213 st_priv
= calloc(1,sizeof(struct vf_priv_s
));
214 st_priv
->root
= st_priv
->current
= menu_open(args
);
215 if(!st_priv
->current
) {
220 st_priv
->root
->show
= menu_startup
;
221 mp_input_add_cmd_filter((mp_input_cmd_filter
)cmd_filter
,st_priv
);
225 vf
->query_format
=query_format
;
226 vf
->put_image
= put_image
;
227 vf
->get_image
= get_image
;
236 vf_info_t vf_info_menu
= {
237 "Internal filter for libmenu",