2 * libvo common functions, variables used by many/all drivers.
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 //#include <sys/mman.h>
33 #include "video_out.h"
36 #include "old_vo_wrapper.h"
40 #include "osdep/shmem.h"
42 #include "x11_common.h"
44 #ifdef CONFIG_GL_WIN32
48 int xinerama_screen
= -1;
52 int vo_nomouse_input
= 0;
53 int vo_grabpointer
= 1;
54 int vo_doublebuffering
= 1;
58 float vo_panscan
= 0.0f
;
60 int vo_refresh_rate
=0;
66 int vo_pts
=0; // for hw decoding
69 char *vo_subdevice
= NULL
;
70 int vo_directrendering
=0;
72 int vo_colorkey
= 0x0000ff00; // default colorkey is green
73 // (0xff000000 means that colorkey has been disabled)
75 // name to be used instead of the vo's default
77 // title to be applied to movie window
81 // Externally visible list of all vo drivers
83 extern struct vo_driver video_out_mga
;
84 extern struct vo_driver video_out_xmga
;
85 extern struct vo_driver video_out_x11
;
86 extern struct vo_driver video_out_xover
;
87 extern struct vo_driver video_out_xvmc
;
88 extern struct vo_driver video_out_vdpau
;
89 extern struct vo_driver video_out_xv
;
90 extern struct vo_driver video_out_gl_nosw
;
91 extern struct vo_driver video_out_gl
;
92 extern struct vo_driver video_out_gl2
;
93 extern struct vo_driver video_out_matrixview
;
94 extern struct vo_driver video_out_dga
;
95 extern struct vo_driver video_out_sdl
;
96 extern struct vo_driver video_out_3dfx
;
97 extern struct vo_driver video_out_tdfxfb
;
98 extern struct vo_driver video_out_s3fb
;
99 extern struct vo_driver video_out_wii
;
100 extern struct vo_driver video_out_null
;
101 extern struct vo_driver video_out_zr
;
102 extern struct vo_driver video_out_zr2
;
103 extern struct vo_driver video_out_bl
;
104 extern struct vo_driver video_out_fbdev
;
105 extern struct vo_driver video_out_fbdev2
;
106 extern struct vo_driver video_out_svga
;
107 extern struct vo_driver video_out_png
;
108 extern struct vo_driver video_out_ggi
;
109 extern struct vo_driver video_out_aa
;
110 extern struct vo_driver video_out_caca
;
111 extern struct vo_driver video_out_mpegpes
;
112 extern struct vo_driver video_out_yuv4mpeg
;
113 extern struct vo_driver video_out_direct3d
;
114 extern struct vo_driver video_out_directx
;
115 extern struct vo_driver video_out_kva
;
116 extern struct vo_driver video_out_dxr2
;
117 extern struct vo_driver video_out_dxr3
;
118 extern struct vo_driver video_out_ivtv
;
119 extern struct vo_driver video_out_v4l2
;
120 extern struct vo_driver video_out_jpeg
;
121 extern struct vo_driver video_out_gif89a
;
122 extern struct vo_driver video_out_vesa
;
123 extern struct vo_driver video_out_directfb
;
124 extern struct vo_driver video_out_dfbmga
;
125 extern struct vo_driver video_out_xvidix
;
126 extern struct vo_driver video_out_winvidix
;
127 extern struct vo_driver video_out_cvidix
;
128 extern struct vo_driver video_out_tdfx_vid
;
129 extern struct vo_driver video_out_xvr100
;
130 extern struct vo_driver video_out_tga
;
131 extern struct vo_driver video_out_corevideo
;
132 extern struct vo_driver video_out_quartz
;
133 extern struct vo_driver video_out_pnm
;
134 extern struct vo_driver video_out_md5sum
;
136 const struct vo_driver
*video_out_drivers
[] =
141 #ifdef CONFIG_TDFX_VID
144 #ifdef CONFIG_DIRECTX
147 #ifdef CONFIG_DIRECT3D
153 #ifdef CONFIG_COREVIDEO
154 &video_out_corevideo
,
207 #ifdef CONFIG_SVGALIB
210 #ifdef CONFIG_MATRIXVIEW
211 &video_out_matrixview
,
228 #ifdef CONFIG_V4L2_DECODER
248 #if defined(__MINGW32__) || defined(__CYGWIN__)
254 // should not be auto-selected
255 #ifdef CONFIG_DIRECTFB
256 // vo directfb can call exit() if initialization fails
263 #ifdef CONFIG_YUV4MPEG
266 #ifdef CONFIG_LIBAVCODEC
288 static int vo_preinit(struct vo
*vo
, const char *arg
)
290 return vo
->driver
->preinit(vo
, arg
);
293 int vo_control(struct vo
*vo
, uint32_t request
, void *data
)
295 return vo
->driver
->control(vo
, request
, data
);
298 // Return -1 if driver appears not to support a draw_image interface,
299 // 0 otherwise (whether the driver actually drew something or not).
300 int vo_draw_image(struct vo
*vo
, struct mp_image
*mpi
, double pts
)
304 if (vo
->driver
->buffer_frames
) {
305 vo
->driver
->draw_image(vo
, mpi
, pts
);
308 vo
->frame_loaded
= true;
310 if (vo_control(vo
, VOCTRL_DRAW_IMAGE
, mpi
) == VO_NOTIMPL
)
315 int vo_get_buffered_frame(struct vo
*vo
, bool eof
)
319 if (vo
->frame_loaded
)
321 if (!vo
->driver
->buffer_frames
)
323 vo
->driver
->get_buffered_frame(vo
, eof
);
324 return vo
->frame_loaded
? 0 : -1;
327 int vo_draw_frame(struct vo
*vo
, uint8_t *src
[])
329 assert(!vo
->driver
->is_new
);
332 return old_vo_draw_frame(vo
, src
);
335 int vo_draw_slice(struct vo
*vo
, uint8_t *src
[], int stride
[], int w
, int h
, int x
, int y
)
337 return vo
->driver
->draw_slice(vo
, src
, stride
, w
, h
, x
, y
);
340 void vo_draw_osd(struct vo
*vo
, struct osd_state
*osd
)
344 vo
->driver
->draw_osd(vo
, osd
);
347 void vo_flip_page(struct vo
*vo
, unsigned int pts_us
, int duration
)
351 vo
->frame_loaded
= false;
352 vo
->next_pts
= MP_NOPTS_VALUE
;
353 if (vo
->driver
->flip_page_timed
)
354 vo
->driver
->flip_page_timed(vo
, pts_us
, duration
);
356 vo
->driver
->flip_page(vo
);
359 void vo_check_events(struct vo
*vo
)
363 vo
->driver
->check_events(vo
);
366 void vo_seek_reset(struct vo
*vo
)
368 vo_control(vo
, VOCTRL_RESET
, NULL
);
369 vo
->frame_loaded
= false;
372 void vo_destroy(struct vo
*vo
)
374 vo
->driver
->uninit(vo
);
378 void list_video_out(void)
381 mp_tmsg(MSGT_CPLAYER
, MSGL_INFO
, "Available video output drivers:\n");
382 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_VIDEO_OUTPUTS\n");
383 while (video_out_drivers
[i
]) {
384 const vo_info_t
*info
= video_out_drivers
[i
++]->info
;
385 mp_msg(MSGT_GLOBAL
, MSGL_INFO
,"\t%s\t%s\n", info
->short_name
, info
->name
);
387 mp_msg(MSGT_GLOBAL
, MSGL_INFO
,"\n");
390 struct vo
*init_best_video_out(struct MPOpts
*opts
, struct vo_x11_state
*x11
,
391 struct mp_fifo
*key_fifo
,
392 struct input_ctx
*input_ctx
)
394 char **vo_list
= opts
->video_driver_list
;
396 struct vo
*vo
= talloc_ptrtype(NULL
, vo
);
397 struct vo initial_values
= {
400 .key_fifo
= key_fifo
,
401 .input_ctx
= input_ctx
,
403 // first try the preferred drivers, with their optional subdevice param:
404 if (vo_list
&& vo_list
[0])
405 while (vo_list
[0][0]) {
406 char *name
= strdup(vo_list
[0]);
408 vo_subdevice
= strchr(name
,':');
409 if (!strcmp(name
, "pgm"))
410 mp_tmsg(MSGT_CPLAYER
, MSGL_ERR
, "The pgm video output driver has been replaced by -vo pnm:pgmyuv.\n");
411 if (!strcmp(name
, "md5"))
412 mp_tmsg(MSGT_CPLAYER
, MSGL_ERR
, "The md5 video output driver has been replaced by -vo md5sum.\n");
417 for (i
= 0; video_out_drivers
[i
]; i
++) {
418 const struct vo_driver
*video_driver
= video_out_drivers
[i
];
419 const vo_info_t
*info
= video_driver
->info
;
420 if (!strcmp(info
->short_name
, name
)) {
421 // name matches, try it
422 *vo
= initial_values
;
423 vo
->driver
= video_driver
;
424 if (!vo_preinit(vo
, vo_subdevice
)) {
426 return vo
; // success!
428 talloc_free_children(vo
);
435 return NULL
; // do NOT fallback to others
438 #ifdef CONFIG_GL_WIN32
439 OSVERSIONINFO winver
;
440 memset(&winver
, 0, sizeof(OSVERSIONINFO
));
441 winver
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
442 GetVersionEx(&winver
);
444 if(winver
.dwMajorVersion
>= 6) { // If Vista+
445 vo_subdevice
= strdup("yuv=2"); // Use -vo gl:yuv=2 by default
446 *vo
= initial_values
; // Since directdraw is deprecated
447 vo
->driver
= &video_out_gl
; // And direct3d is buggy
448 if (!vo_preinit(vo
, vo_subdevice
)) {
450 return vo
; // it works!
452 talloc_free_children(vo
);
456 // now try the rest...
458 for (i
= 0; video_out_drivers
[i
]; i
++) {
459 const struct vo_driver
*video_driver
= video_out_drivers
[i
];
460 *vo
= initial_values
;
461 vo
->driver
= video_driver
;
462 if (!vo_preinit(vo
, vo_subdevice
))
463 return vo
; // success!
464 talloc_free_children(vo
);
470 int vo_config(struct vo
*vo
, uint32_t width
, uint32_t height
,
471 uint32_t d_width
, uint32_t d_height
, uint32_t flags
,
472 char *title
, uint32_t format
)
474 struct MPOpts
*opts
= vo
->opts
;
476 aspect_save_orig(vo
, width
, height
);
477 aspect_save_prescale(vo
, d_width
, d_height
);
479 if (vo_control(vo
, VOCTRL_UPDATE_SCREENINFO
, NULL
) == VO_TRUE
) {
480 aspect(vo
, &d_width
, &d_height
, A_NOZOOM
);
481 vo
->dx
= (int)(opts
->vo_screenwidth
- d_width
) / 2;
482 vo
->dy
= (int)(opts
->vo_screenheight
- d_height
) / 2;
483 geometry(&vo
->dx
, &vo
->dy
, &d_width
, &d_height
,
484 opts
->vo_screenwidth
, opts
->vo_screenheight
);
485 vo
->dx
+= xinerama_x
;
486 vo
->dy
+= xinerama_y
;
487 vo
->dwidth
= d_width
;
488 vo
->dheight
= d_height
;
491 int ret
= vo
->driver
->config(vo
, width
, height
, d_width
, d_height
, flags
,
493 vo
->config_ok
= (ret
== 0);
494 vo
->config_count
+= vo
->config_ok
;
499 * \brief lookup an integer in a table, table must have 0 as the last key
500 * \param key key to search for
501 * \result translation corresponding to key or "to" value of last mapping
504 int lookup_keymap_table(const struct keymap
*map
, int key
) {
505 while (map
->from
&& map
->from
!= key
) map
++;
510 * \brief helper function for the kind of panscan-scaling that needs a source
511 * and destination rectangle like Direct3D and VDPAU
513 static void src_dst_split_scaling(int src_size
, int dst_size
, int scaled_src_size
,
514 int *src_start
, int *src_end
, int *dst_start
, int *dst_end
) {
515 if (scaled_src_size
> dst_size
) {
516 int border
= src_size
* (scaled_src_size
- dst_size
) / scaled_src_size
;
517 // round to a multiple of 2, this is at least needed for vo_direct3d and ATI cards
518 border
= (border
/ 2 + 1) & ~1;
520 *src_end
= src_size
- border
;
526 *dst_start
= (dst_size
- scaled_src_size
) / 2;
527 *dst_end
= *dst_start
+ scaled_src_size
;
532 * Calculate the appropriate source and destination rectangle to
533 * get a correctly scaled picture, including pan-scan.
534 * Can be extended to take future cropping support into account.
536 * \param crop specifies the cropping border size in the left, right, top and bottom members, may be NULL
537 * \param borders the border values as e.g. EOSD (ASS) and properly placed DVD highlight support requires,
538 * may be NULL and only left and top are currently valid.
540 void calc_src_dst_rects(struct vo
*vo
, int src_width
, int src_height
,
541 struct vo_rect
*src
, struct vo_rect
*dst
,
542 struct vo_rect
*borders
, const struct vo_rect
*crop
)
544 static const struct vo_rect no_crop
= {0, 0, 0, 0, 0, 0};
545 int scaled_width
= 0;
546 int scaled_height
= 0;
547 if (!crop
) crop
= &no_crop
;
548 src_width
-= crop
->left
+ crop
->right
;
549 src_height
-= crop
->top
+ crop
->bottom
;
550 if (src_width
< 2) src_width
= 2;
551 if (src_height
< 2) src_height
= 2;
552 dst
->left
= 0; dst
->right
= vo
->dwidth
;
553 dst
->top
= 0; dst
->bottom
= vo
->dheight
;
554 src
->left
= 0; src
->right
= src_width
;
555 src
->top
= 0; src
->bottom
= src_height
;
557 borders
->left
= 0; borders
->top
= 0;
559 if (aspect_scaling()) {
560 aspect(vo
, &scaled_width
, &scaled_height
, A_WINZOOM
);
561 panscan_calc_windowed(vo
);
562 scaled_width
+= vo
->panscan_x
;
563 scaled_height
+= vo
->panscan_y
;
565 borders
->left
= (vo
->dwidth
- scaled_width
) / 2;
566 borders
->top
= (vo
->dheight
- scaled_height
) / 2;
568 src_dst_split_scaling(src_width
, vo
->dwidth
, scaled_width
,
569 &src
->left
, &src
->right
, &dst
->left
, &dst
->right
);
570 src_dst_split_scaling(src_height
, vo
->dheight
, scaled_height
,
571 &src
->top
, &src
->bottom
, &dst
->top
, &dst
->bottom
);
573 src
->left
+= crop
->left
; src
->right
+= crop
->left
;
574 src
->top
+= crop
->top
; src
->bottom
+= crop
->top
;
575 src
->width
= src
->right
- src
->left
;
576 src
->height
= src
->bottom
- src
->top
;
577 dst
->width
= dst
->right
- dst
->left
;
578 dst
->height
= dst
->bottom
- dst
->top
;
581 #if defined(CONFIG_FBDEV) || defined(CONFIG_VESA)
582 /* Borrowed from vo_fbdev.c
583 Monitor ranges related functions*/
585 char *monitor_hfreq_str
= NULL
;
586 char *monitor_vfreq_str
= NULL
;
587 char *monitor_dotclock_str
= NULL
;
589 float range_max(range_t
*r
)
593 for (/* NOTHING */; (r
->min
!= -1 && r
->max
!= -1); r
++)
594 if (max
< r
->max
) max
= r
->max
;
599 int in_range(range_t
*r
, float f
)
601 for (/* NOTHING */; (r
->min
!= -1 && r
->max
!= -1); r
++)
602 if (f
>= r
->min
&& f
<= r
->max
)
607 range_t
*str2range(char *s
)
609 float tmp_min
, tmp_max
;
610 char *endptr
= s
; // to start the loop
616 for (i
= 0; *endptr
; i
++) {
619 if (!(r
= realloc(r
, sizeof(*r
) * (i
+ 2)))) {
620 mp_msg(MSGT_GLOBAL
, MSGL_WARN
,"can't realloc 'r'\n");
623 tmp_min
= strtod(s
, &endptr
);
624 if (*endptr
== 'k' || *endptr
== 'K') {
627 } else if (*endptr
== 'm' || *endptr
== 'M') {
628 tmp_min
*= 1000000.0;
631 if (*endptr
== '-') {
632 tmp_max
= strtod(endptr
+ 1, &endptr
);
633 if (*endptr
== 'k' || *endptr
== 'K') {
636 } else if (*endptr
== 'm' || *endptr
== 'M') {
637 tmp_max
*= 1000000.0;
640 if (*endptr
!= ',' && *endptr
)
642 } else if (*endptr
== ',' || !*endptr
) {
648 if (r
[i
].min
< 0 || r
[i
].max
< 0)
652 r
[i
].min
= r
[i
].max
= -1;
660 /* Borrowed from vo_fbdev.c END */