2 * MatrixView video output driver for MPlayer
4 * by Pigeon <pigeon at pigeond.net>
6 * Based on MatrixView the screensaver from http://rss-glx.sf.net/
16 #include "subopt-helper.h"
17 #include "video_out.h"
18 #include "video_out_internal.h"
19 #include "gl_common.h"
21 #include "libswscale/swscale.h"
22 #include "libmpcodecs/vf_scale.h"
23 #include "osdep/timer.h"
25 #include "matrixview.h"
27 static vo_info_t info
=
29 "MatrixView (OpenGL)",
31 "Pigeon <pigeon@pigeond.net>",
32 "Based on MatrixView from rss-glx.sf.net"
35 LIBVO_EXTERN(matrixview
)
38 static int gl_vinfo
= 0;
39 static HGLRC gl_context
= 0;
40 #define update_xinerama_info w32_update_xinerama_info
41 #define vo_init vo_w32_init
42 #define vo_window vo_w32_window
44 static XVisualInfo
*gl_vinfo
= NULL
;
45 static GLXContext gl_context
= 0;
46 static int wsGLXAttrib
[] = {
57 static int int_pause
= 0;
58 static int eq_contrast
= 0.0;
59 static int eq_brightness
= 0.0;
60 static uint32_t image_width
;
61 static uint32_t image_height
;
62 static uint32_t image_format
;
63 static struct SwsContext
*sws
= NULL
;
65 static uint8_t *map_image
[3] = { NULL
, NULL
, NULL
};
66 static int map_stride
[3] = { 0, 0, 0 };
68 #define MATRIX_ROWS 90
69 #define MATRIX_COLS 120
70 static int matrix_rows
= MATRIX_ROWS
;
71 static int matrix_cols
= MATRIX_COLS
;
73 #define DEFAULT_CONTRAST 0.90f
74 #define CONTRAST_MULTIPLIER 0.02f
76 #define DEFAULT_BRIGHTNESS 1.0f
77 #define BRIGHTNESS_MULTIPLIER 0.02f
81 contrast_set(int value
)
85 contrast
= value
* CONTRAST_MULTIPLIER
+ DEFAULT_CONTRAST
;
87 matrixview_contrast_set(contrast
);
93 brightness_set(int value
)
96 eq_brightness
= value
;
97 brightness
= value
* BRIGHTNESS_MULTIPLIER
+ DEFAULT_BRIGHTNESS
;
98 if (brightness
>= 0) {
99 matrixview_brightness_set(brightness
);
105 config(uint32_t width
, uint32_t height
,
106 uint32_t d_width
, uint32_t d_height
,
107 uint32_t flags
, char *title
, uint32_t format
)
109 image_height
= height
;
111 image_format
= format
;
116 aspect_save_orig(width
,height
);
117 aspect_save_prescale(d_width
,d_height
);
118 update_xinerama_info();
120 aspect((int *) &d_width
, (int *) &d_height
,A_NOZOOM
);
121 vo_dx
= (int)(vo_screenwidth
- d_width
) / 2;
122 vo_dy
= (int)(vo_screenheight
- d_height
) / 2;
123 geometry((int *) &vo_dx
, (int *) &vo_dy
,
124 (int *) &d_width
, (int *) &d_height
,
125 vo_screenwidth
, vo_screenheight
);
130 vo_dheight
= d_height
;
132 if (!vo_w32_config(d_width
, d_height
, flags
))
136 vo_window
= WinID
? (Window
) WinID
: mRootWin
;
137 vo_x11_selectinput_witherr(mDisplay
, vo_window
,
138 StructureNotifyMask
| KeyPressMask
| PointerMotionMask
|
139 ButtonPressMask
| ButtonReleaseMask
| ExposureMask
);
143 if (vo_window
== None
) {
153 hint
.width
= d_width
;
154 hint
.height
= d_height
;
155 hint
.flags
= PPosition
| PSize
;
157 /* Get some colors */
158 bg
= WhitePixel(mDisplay
, mScreen
);
159 fg
= BlackPixel(mDisplay
, mScreen
);
161 /* Make the window */
163 vinfo
=glXChooseVisual( mDisplay
,mScreen
,wsGLXAttrib
);
166 mp_msg(MSGT_VO
, MSGL_ERR
, "[matrixview] no GLX support present\n");
171 vo_window
= vo_x11_create_smooth_window(mDisplay
, mRootWin
, vinfo
->visual
, hint
.x
, hint
.y
, hint
.width
, hint
.height
, vinfo
->depth
, XCreateColormap(mDisplay
, mRootWin
, vinfo
->visual
, AllocNone
));
173 vo_x11_classhint(mDisplay
,vo_window
,"matrixview");
174 vo_hidecursor(mDisplay
,vo_window
);
176 XSelectInput(mDisplay
, vo_window
, StructureNotifyMask
);
177 /* Tell other applications about this window */
178 XSetStandardProperties(mDisplay
, vo_window
, title
, title
, None
, NULL
, 0, &hint
);
180 XMapWindow(mDisplay
, vo_window
);
185 XNextEvent(mDisplay
, &xev
);
187 while (xev
.type
!= MapNotify
|| xev
.xmap
.event
!= vo_window
);
189 XSelectInput(mDisplay
, vo_window
, NoEventMask
);
191 XSync(mDisplay
, False
);
193 vo_x11_selectinput_witherr(mDisplay
, vo_window
, StructureNotifyMask
| KeyPressMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
| ExposureMask
);
196 if (vo_ontop
) vo_x11_setlayer(mDisplay
, vo_window
, vo_ontop
);
198 if (vo_config_count
== 0) {
199 vo_x11_nofs_sizepos(vo_dx
, vo_dy
, d_width
, d_height
);
200 if (vo_fs
^ (flags
& VOFLAG_FULLSCREEN
))
203 #endif /* GL_WIN32 */
205 setGlWindow(&gl_vinfo
, &gl_context
, vo_window
);
208 sws_freeContext(sws
);
211 sws
= sws_getContextFromCmdLine(image_width
, image_height
, image_format
, matrix_cols
, matrix_rows
, IMGFMT_Y8
);
213 mp_msg(MSGT_VO
, MSGL_ERR
, "[matrixview] Cannot create SwsContext context\n");
218 map_image
[0] = malloc(matrix_cols
* matrix_rows
);
221 map_stride
[0] = matrix_cols
;
223 matrixview_init(vo_dwidth
, vo_dheight
);
224 matrixview_matrix_resize(matrix_cols
, matrix_rows
);
226 contrast_set(eq_contrast
);
227 brightness_set(eq_brightness
);
229 /* On win32 starts with black screen */
230 matrixview_reshape(vo_dwidth
, vo_dheight
);
236 static void check_events(void)
238 int e
=vo_check_events();
239 if(e
& VO_EVENT_RESIZE
) {
240 matrixview_reshape(vo_dwidth
, vo_dheight
);
242 if(e
& VO_EVENT_EXPOSE
&& int_pause
) flip_page();
246 static void draw_osd(void)
252 static void do_matrixview()
254 matrixview_draw(vo_dwidth
, vo_dheight
, GetTimer(), 0.0, map_image
[0]);
267 static int draw_slice(uint8_t *src
[], int stride
[],
268 int w
, int h
, int x
, int y
)
270 sws_scale_ordered(sws
, src
, stride
, y
, h
, map_image
, map_stride
);
276 draw_frame(uint8_t *src
[])
281 int stride
[3] = { 0, 0, 0 };
283 switch(image_format
) {
285 stride
[0] = image_width
* 12 / 8;
289 stride
[0] = image_width
* 4;
293 stride
[0] = image_width
* 3;
297 stride
[0] = image_width
* 2;
301 sws_scale_ordered(sws
, src
, stride
, 0, image_height
,
302 map_image
, map_stride
);
310 query_format(uint32_t format
)
312 int caps
= VFCAP_CSP_SUPPORTED
| VFCAP_HWSCALE_UP
| VFCAP_HWSCALE_DOWN
|
336 if (!vo_config_count
) return;
337 releaseGlContext(&gl_vinfo
, &gl_context
);
341 sws_freeContext(sws
);
346 static opt_t subopts
[] =
348 { "rows", OPT_ARG_INT
, &matrix_rows
, (opt_test_f
) int_non_neg
, 0 },
349 { "cols", OPT_ARG_INT
, &matrix_cols
, (opt_test_f
) int_non_neg
, 0 },
350 { NULL
, 0, NULL
, NULL
, 0 },
354 static int preinit(const char *arg
)
356 if(!vo_init()) return -1;
358 matrix_rows
= MATRIX_ROWS
;
359 matrix_cols
= MATRIX_COLS
;
361 if(subopt_parse(arg
, subopts
) != 0) {
362 mp_msg(MSGT_VO
, MSGL_FATAL
,
363 "\n-vo matrixview command line help:\n"
364 "Example: mplayer -vo matrixview:cols=320:rows=240\n"
369 " Specify the number of columns of the matrix view, default %d\n"
372 " Specify the number of rows of the matrix view, default %d\n"
375 MATRIX_COLS
, MATRIX_ROWS
380 if(matrix_cols
> 320)
384 else if(matrix_cols
< 12)
389 if(matrix_rows
> 240)
393 else if(matrix_rows
< 12)
402 static int control(uint32_t request
, void *data
)
405 case VOCTRL_PAUSE
: return (int_pause
=1);
406 case VOCTRL_RESUME
: return (int_pause
=0);
407 case VOCTRL_QUERY_FORMAT
:
408 return query_format(*((uint32_t*)data
));
412 case VOCTRL_FULLSCREEN
:
414 matrixview_reshape(vo_dwidth
, vo_dheight
);
421 case VOCTRL_GET_EQUALIZER
:
423 struct voctrl_get_equalizer_args
*args
= data
;
424 if (strcasecmp(args
->name
, "contrast") == 0)
426 *(args
->valueptr
) = eq_contrast
;
428 else if (strcasecmp(args
->name
, "brightness") == 0)
430 *(args
->valueptr
) = eq_brightness
;
434 case VOCTRL_SET_EQUALIZER
:
436 struct voctrl_set_equalizer_args
*args
= data
;
437 if (strcasecmp(args
->name
, "contrast") == 0)
439 contrast_set(args
->value
);
441 else if (strcasecmp(data
, "brightness") == 0)
443 brightness_set(args
->value
);