2 * vo_vesa interface to Linux Video Overlay
3 * (partly based on vo_mga.c)
5 * copyright (C) 2001 Nick Kurshev <nickols_k@mail.ru>
7 * This file is part of MPlayer.
9 * MPlayer is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * MPlayer is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <sys/ioctl.h>
37 #include "libmpcodecs/img_format.h"
38 #include "drivers/mga_vid.h" /* <- should be changed to "linux/'something'.h" */
39 #include "fastmemcpy.h"
41 #include "video_out.h"
43 #include "libmpcodecs/vfcap.h"
45 #define WIDTH_ALIGN 32 /* should be 16 for rage:422 and 32 for rage:420 */
47 #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */
49 static uint8_t *frames
[NUM_FRAMES
];
51 static int lvo_handler
= -1;
52 static uint8_t *lvo_mem
= NULL
;
53 static uint8_t next_frame
;
54 static mga_vid_config_t mga_vid_config
;
55 static unsigned image_bpp
,image_height
,image_width
,src_format
;
56 int vlvo_control(uint32_t request
, void *data
);
58 #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8)
59 #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) )
60 #define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size))
62 int vlvo_init(unsigned src_width
,unsigned src_height
,
63 unsigned x_org
,unsigned y_org
,unsigned dst_width
,
64 unsigned dst_height
,unsigned format
,unsigned dest_bpp
)
67 mp_tmsg(MSGT_VO
,MSGL_WARN
, "[VESA_LVO] This branch is no longer supported.\n[VESA_LVO] Please use -vo vesa:vidix instead.\n");
69 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
70 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_init() was called\n");}
71 image_width
= src_width
;
72 image_height
= src_height
;
73 mga_vid_config
.version
=MGA_VID_VERSION
;
74 src_format
= mga_vid_config
.format
=format
;
75 awidth
= (src_width
+ (WIDTH_ALIGN
-1)) & ~(WIDTH_ALIGN
-1);
81 mga_vid_config
.frame_size
= awidth
*src_height
+(awidth
*src_height
)/2;
86 mga_vid_config
.frame_size
= awidth
*src_height
*2;
93 mga_vid_config
.frame_size
= awidth
*src_height
*2;
98 mga_vid_config
.frame_size
= awidth
*src_height
*3;
103 mga_vid_config
.frame_size
= awidth
*src_height
*4;
106 mp_tmsg(MSGT_VO
,MSGL_WARN
, "[VESA_LVI] Invalid output format: %s(%0X)\n",vo_format_name(format
),format
);
109 mga_vid_config
.colkey_on
=0;
110 mga_vid_config
.src_width
= src_width
;
111 mga_vid_config
.src_height
= src_height
;
112 mga_vid_config
.dest_width
= dst_width
;
113 mga_vid_config
.dest_height
= dst_height
;
114 mga_vid_config
.x_org
=x_org
;
115 mga_vid_config
.y_org
=y_org
;
116 mga_vid_config
.num_frames
=NUM_FRAMES
;
117 if (ioctl(lvo_handler
,MGA_VID_CONFIG
,&mga_vid_config
))
119 perror("vesa_lvo: Error in mga_vid_config ioctl()");
120 mp_tmsg(MSGT_VO
,MSGL_WARN
, "[VESA_LVO] Your fb_vid driver version is incompatible with this MPlayer version!\n");
123 ioctl(lvo_handler
,MGA_VID_ON
,0);
125 frames
[0] = (char*)mmap(0,mga_vid_config
.frame_size
*mga_vid_config
.num_frames
,PROT_WRITE
,MAP_SHARED
,lvo_handler
,0);
126 for(i
=1;i
<NUM_FRAMES
;i
++)
127 frames
[i
] = frames
[i
-1] + mga_vid_config
.frame_size
;
129 lvo_mem
= frames
[next_frame
];
132 memset(frames
[0],0x80,mga_vid_config
.frame_size
*mga_vid_config
.num_frames
);
136 void vlvo_term( void )
138 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
139 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_term() was called\n");}
140 ioctl( lvo_handler
,MGA_VID_OFF
,0 );
141 munmap(frames
[0],mga_vid_config
.frame_size
*mga_vid_config
.num_frames
);
142 if(lvo_handler
!= -1) close(lvo_handler
);
145 static int vlvo_draw_slice_420(uint8_t *image
[], int stride
[],
146 int w
, int h
, int x
, int y
)
150 uint32_t bespitch
,bespitch2
;
153 bespitch
= (mga_vid_config
.src_width
+ (WIDTH_ALIGN
-1)) & ~(WIDTH_ALIGN
-1);
154 bespitch2
= bespitch
/2;
156 dest
= lvo_mem
+ bespitch
* y
+ x
;
159 fast_memcpy(dest
,src
,w
);
166 dest
= lvo_mem
+ bespitch
*mga_vid_config
.src_height
+ bespitch2
* y
+ x
;
169 fast_memcpy(dest
,src
,w
);
174 dest
= lvo_mem
+ bespitch
*mga_vid_config
.src_height
175 + bespitch
*mga_vid_config
.src_height
/ 4
179 fast_memcpy(dest
,src
,w
);
186 static int vlvo_draw_slice(uint8_t *image
[], int stride
[],
187 int w
,int h
,int x
,int y
)
189 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
190 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_draw_slice() was called\n");}
191 if(src_format
== IMGFMT_YV12
|| src_format
== IMGFMT_I420
|| src_format
== IMGFMT_IYUV
)
192 vlvo_draw_slice_420(image
,stride
,w
,h
,x
,y
);
197 bytpp
= (image_bpp
+7)/8;
198 dst
= lvo_mem
+ (image_width
* y
+ x
)*bytpp
;
199 /* vlvo_draw_slice_422(image,stride,w,h,x,y); just for speed */
200 fast_memcpy(dst
,image
[0],mga_vid_config
.frame_size
);
205 static int vlvo_draw_frame(uint8_t *image
[])
207 /* Note it's very strange but sometime for YUY2 draw_frame is called */
208 fast_memcpy(lvo_mem
,image
[0],mga_vid_config
.frame_size
);
209 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
210 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_flip_page() was called\n");}
214 static void vlvo_flip_page(void)
216 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
217 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_draw_osd() was called\n");}
218 if(vo_doublebuffering
)
220 ioctl(lvo_handler
,MGA_VID_FSEL
,&next_frame
);
221 next_frame
=(next_frame
+1)%mga_vid_config
.num_frames
;
222 lvo_mem
=frames
[next_frame
];
227 static void draw_alpha_null(int x0
,int y0
, int w
,int h
, unsigned char* src
, unsigned char *srca
, int stride
)
238 static void draw_alpha(int x0
,int y0
, int w
,int h
, unsigned char* src
, unsigned char *srca
, int stride
)
240 uint32_t bespitch
= /*(*/mga_vid_config
.src_width
;// + 15) & ~15;
241 switch(mga_vid_config
.format
){
244 vo_draw_alpha_rgb15(w
,h
,src
,srca
,stride
,lvo_mem
+2*(y0
*bespitch
+x0
),2*bespitch
);
248 vo_draw_alpha_rgb16(w
,h
,src
,srca
,stride
,lvo_mem
+2*(y0
*bespitch
+x0
),2*bespitch
);
252 vo_draw_alpha_rgb24(w
,h
,src
,srca
,stride
,lvo_mem
+3*(y0
*bespitch
+x0
),3*bespitch
);
256 vo_draw_alpha_rgb32(w
,h
,src
,srca
,stride
,lvo_mem
+4*(y0
*bespitch
+x0
),4*bespitch
);
261 vo_draw_alpha_yv12(w
,h
,src
,srca
,stride
,lvo_mem
+bespitch
*y0
+x0
,bespitch
);
264 vo_draw_alpha_yuy2(w
,h
,src
,srca
,stride
,lvo_mem
+2*(bespitch
*y0
+x0
),bespitch
);
267 vo_draw_alpha_yuy2(w
,h
,src
,srca
,stride
,lvo_mem
+2*(bespitch
*y0
+x0
)+1,bespitch
);
270 draw_alpha_null(x0
,y0
,w
,h
,src
,srca
,stride
);
275 static void vlvo_draw_osd(void)
277 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
278 mp_msg(MSGT_VO
,MSGL_DBG2
,"vesa_lvo: vlvo_draw_osd() was called\n"); }
279 /* TODO: hw support */
281 /* disable this stuff until new fbvid.h interface will be implemented
282 because in different fourcc radeon_vid and rage128_vid have different
284 vo_draw_text(mga_vid_config
.src_width
,mga_vid_config
.src_height
,draw_alpha
);
288 extern struct vo_old_functions video_out_vesa
;
290 int vlvo_preinit(const char *drvname
)
292 mp_tmsg(MSGT_VO
,MSGL_WARN
, "[VESA_LVO] This branch is no longer supported.\n[VESA_LVO] Please use -vo vesa:vidix instead.\n");
294 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
295 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: vlvo_preinit(%s) was called\n",drvname
);}
296 lvo_handler
= open(drvname
,O_RDWR
);
297 if(lvo_handler
== -1)
299 mp_tmsg(MSGT_VO
,MSGL_WARN
, "[VESA_LVO] Couldn't open: '%s'\n",drvname
);
302 /* we are able to tune up this stuff depend on fourcc format */
303 video_out_vesa
.draw_slice
=vlvo_draw_slice
;
304 video_out_vesa
.draw_frame
=vlvo_draw_frame
;
305 video_out_vesa
.flip_page
=vlvo_flip_page
;
306 video_out_vesa
.draw_osd
=vlvo_draw_osd
;
307 video_out_vesa
.control
=vlvo_control
;
311 static uint32_t vlvo_query_info(uint32_t format
)
313 if( mp_msg_test(MSGT_VO
,MSGL_DBG2
) ) {
314 mp_msg(MSGT_VO
,MSGL_DBG2
, "vesa_lvo: query_format was called: %x (%s)\n",format
,vo_format_name(format
)); }
315 return VFCAP_CSP_SUPPORTED
;
318 int vlvo_control(uint32_t request
, void *data
)
321 case VOCTRL_QUERY_FORMAT
:
322 return vlvo_query_info(*((uint32_t*)data
));