VO: Don't reset pause status in VO config() functions
[mplayer.git] / libvo / vesa_lvo.c
blob8875c3aa808cfc0e748efb0677ac74b0cf13998c
1 /*
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.
24 #include <inttypes.h>
25 #include <sys/ioctl.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sys/mman.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 #include "config.h"
34 #include "mp_msg.h"
35 #include "help_mp.h"
37 #include "vesa_lvo.h"
38 #include "libmpcodecs/img_format.h"
39 #include "drivers/mga_vid.h" /* <- should be changed to "linux/'something'.h" */
40 #include "fastmemcpy.h"
41 #include "osd.h"
42 #include "video_out.h"
43 #include "sub.h"
44 #include "libmpcodecs/vfcap.h"
46 #define WIDTH_ALIGN 32 /* should be 16 for rage:422 and 32 for rage:420 */
47 #define NUM_FRAMES 10
48 #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */
50 static uint8_t *frames[NUM_FRAMES];
52 static int lvo_handler = -1;
53 static uint8_t *lvo_mem = NULL;
54 static uint8_t next_frame;
55 static mga_vid_config_t mga_vid_config;
56 static unsigned image_bpp,image_height,image_width,src_format;
57 int vlvo_control(uint32_t request, void *data);
59 #define PIXEL_SIZE() ((video_mode_info.BitsPerPixel+7)/8)
60 #define SCREEN_LINE_SIZE(pixel_size) (video_mode_info.XResolution*(pixel_size) )
61 #define IMAGE_LINE_SIZE(pixel_size) (image_width*(pixel_size))
63 extern struct vo_old_functions video_out_vesa;
65 int vlvo_preinit(const char *drvname)
67 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported);
68 return -1;
69 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
70 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_preinit(%s) was called\n",drvname);}
71 lvo_handler = open(drvname,O_RDWR);
72 if(lvo_handler == -1)
74 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_CouldntOpen,drvname);
75 return -1;
77 /* we are able to tune up this stuff depend on fourcc format */
78 video_out_vesa.draw_slice=vlvo_draw_slice;
79 video_out_vesa.draw_frame=vlvo_draw_frame;
80 video_out_vesa.flip_page=vlvo_flip_page;
81 video_out_vesa.draw_osd=vlvo_draw_osd;
82 video_out_vesa.control=vlvo_control;
83 return 0;
86 int vlvo_init(unsigned src_width,unsigned src_height,
87 unsigned x_org,unsigned y_org,unsigned dst_width,
88 unsigned dst_height,unsigned format,unsigned dest_bpp)
90 size_t i,awidth;
91 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported);
92 return -1;
93 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
94 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_init() was called\n");}
95 image_width = src_width;
96 image_height = src_height;
97 mga_vid_config.version=MGA_VID_VERSION;
98 src_format = mga_vid_config.format=format;
99 awidth = (src_width + (WIDTH_ALIGN-1)) & ~(WIDTH_ALIGN-1);
100 switch(format){
101 case IMGFMT_YV12:
102 case IMGFMT_I420:
103 case IMGFMT_IYUV:
104 image_bpp=16;
105 mga_vid_config.frame_size = awidth*src_height+(awidth*src_height)/2;
106 break;
107 case IMGFMT_YUY2:
108 case IMGFMT_UYVY:
109 image_bpp=16;
110 mga_vid_config.frame_size = awidth*src_height*2;
111 break;
112 case IMGFMT_RGB15:
113 case IMGFMT_BGR15:
114 case IMGFMT_RGB16:
115 case IMGFMT_BGR16:
116 image_bpp=16;
117 mga_vid_config.frame_size = awidth*src_height*2;
118 break;
119 case IMGFMT_RGB24:
120 case IMGFMT_BGR24:
121 image_bpp=24;
122 mga_vid_config.frame_size = awidth*src_height*3;
123 break;
124 case IMGFMT_RGB32:
125 case IMGFMT_BGR32:
126 image_bpp=32;
127 mga_vid_config.frame_size = awidth*src_height*4;
128 break;
129 default:
130 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_InvalidOutputFormat,vo_format_name(format),format);
131 return -1;
133 mga_vid_config.colkey_on=0;
134 mga_vid_config.src_width = src_width;
135 mga_vid_config.src_height= src_height;
136 mga_vid_config.dest_width = dst_width;
137 mga_vid_config.dest_height= dst_height;
138 mga_vid_config.x_org=x_org;
139 mga_vid_config.y_org=y_org;
140 mga_vid_config.num_frames=NUM_FRAMES;
141 if (ioctl(lvo_handler,MGA_VID_CONFIG,&mga_vid_config))
143 perror("vesa_lvo: Error in mga_vid_config ioctl()");
144 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_VESA_IncompatibleDriverVersion);
145 return -1;
147 ioctl(lvo_handler,MGA_VID_ON,0);
149 frames[0] = (char*)mmap(0,mga_vid_config.frame_size*mga_vid_config.num_frames,PROT_WRITE,MAP_SHARED,lvo_handler,0);
150 for(i=1;i<NUM_FRAMES;i++)
151 frames[i] = frames[i-1] + mga_vid_config.frame_size;
152 next_frame = 0;
153 lvo_mem = frames[next_frame];
155 /*clear the buffer*/
156 memset(frames[0],0x80,mga_vid_config.frame_size*mga_vid_config.num_frames);
157 return 0;
160 void vlvo_term( void )
162 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
163 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_term() was called\n");}
164 ioctl( lvo_handler,MGA_VID_OFF,0 );
165 munmap(frames[0],mga_vid_config.frame_size*mga_vid_config.num_frames);
166 if(lvo_handler != -1) close(lvo_handler);
169 int vlvo_draw_slice_420(uint8_t *image[], int stride[], int w,int h,int x,int y)
171 uint8_t *src;
172 uint8_t *dest;
173 uint32_t bespitch,bespitch2;
174 int i;
176 bespitch = (mga_vid_config.src_width + (WIDTH_ALIGN-1)) & ~(WIDTH_ALIGN-1);
177 bespitch2 = bespitch/2;
179 dest = lvo_mem + bespitch * y + x;
180 src = image[0];
181 for(i=0;i<h;i++){
182 fast_memcpy(dest,src,w);
183 src+=stride[0];
184 dest += bespitch;
187 w/=2;h/=2;x/=2;y/=2;
189 dest = lvo_mem + bespitch*mga_vid_config.src_height + bespitch2 * y + x;
190 src = image[1];
191 for(i=0;i<h;i++){
192 fast_memcpy(dest,src,w);
193 src+=stride[1];
194 dest += bespitch2;
197 dest = lvo_mem + bespitch*mga_vid_config.src_height
198 + bespitch*mga_vid_config.src_height / 4
199 + bespitch2 * y + x;
200 src = image[2];
201 for(i=0;i<h;i++){
202 fast_memcpy(dest,src,w);
203 src+=stride[2];
204 dest += bespitch2;
206 return 0;
209 int vlvo_draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y)
211 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
212 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_slice() was called\n");}
213 if(src_format == IMGFMT_YV12 || src_format == IMGFMT_I420 || src_format == IMGFMT_IYUV)
214 vlvo_draw_slice_420(image,stride,w,h,x,y);
215 else
217 uint8_t *dst;
218 uint8_t bytpp;
219 bytpp = (image_bpp+7)/8;
220 dst = lvo_mem + (image_width * y + x)*bytpp;
221 /* vlvo_draw_slice_422(image,stride,w,h,x,y); just for speed */
222 fast_memcpy(dst,image[0],mga_vid_config.frame_size);
224 return 0;
227 int vlvo_draw_frame(uint8_t *image[])
229 /* Note it's very strange but sometime for YUY2 draw_frame is called */
230 fast_memcpy(lvo_mem,image[0],mga_vid_config.frame_size);
231 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
232 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_flip_page() was called\n");}
233 return 0;
236 void vlvo_flip_page(void)
238 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
239 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: vlvo_draw_osd() was called\n");}
240 if(vo_doublebuffering)
242 ioctl(lvo_handler,MGA_VID_FSEL,&next_frame);
243 next_frame=(next_frame+1)%mga_vid_config.num_frames;
244 lvo_mem=frames[next_frame];
248 #if 0
249 static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)
251 UNUSED(x0);
252 UNUSED(y0);
253 UNUSED(w);
254 UNUSED(h);
255 UNUSED(src);
256 UNUSED(srca);
257 UNUSED(stride);
260 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)
262 uint32_t bespitch = /*(*/mga_vid_config.src_width;// + 15) & ~15;
263 switch(mga_vid_config.format){
264 case IMGFMT_BGR15:
265 case IMGFMT_RGB15:
266 vo_draw_alpha_rgb15(w,h,src,srca,stride,lvo_mem+2*(y0*bespitch+x0),2*bespitch);
267 break;
268 case IMGFMT_BGR16:
269 case IMGFMT_RGB16:
270 vo_draw_alpha_rgb16(w,h,src,srca,stride,lvo_mem+2*(y0*bespitch+x0),2*bespitch);
271 break;
272 case IMGFMT_BGR24:
273 case IMGFMT_RGB24:
274 vo_draw_alpha_rgb24(w,h,src,srca,stride,lvo_mem+3*(y0*bespitch+x0),3*bespitch);
275 break;
276 case IMGFMT_BGR32:
277 case IMGFMT_RGB32:
278 vo_draw_alpha_rgb32(w,h,src,srca,stride,lvo_mem+4*(y0*bespitch+x0),4*bespitch);
279 break;
280 case IMGFMT_YV12:
281 case IMGFMT_IYUV:
282 case IMGFMT_I420:
283 vo_draw_alpha_yv12(w,h,src,srca,stride,lvo_mem+bespitch*y0+x0,bespitch);
284 break;
285 case IMGFMT_YUY2:
286 vo_draw_alpha_yuy2(w,h,src,srca,stride,lvo_mem+2*(bespitch*y0+x0),bespitch);
287 break;
288 case IMGFMT_UYVY:
289 vo_draw_alpha_yuy2(w,h,src,srca,stride,lvo_mem+2*(bespitch*y0+x0)+1,bespitch);
290 break;
291 default:
292 draw_alpha_null(x0,y0,w,h,src,srca,stride);
295 #endif
297 void vlvo_draw_osd(void)
299 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
300 mp_msg(MSGT_VO,MSGL_DBG2,"vesa_lvo: vlvo_draw_osd() was called\n"); }
301 /* TODO: hw support */
302 #if 0
303 /* disable this stuff until new fbvid.h interface will be implemented
304 because in different fourcc radeon_vid and rage128_vid have different
305 width alignment */
306 vo_draw_text(mga_vid_config.src_width,mga_vid_config.src_height,draw_alpha);
307 #endif
310 uint32_t vlvo_query_info(uint32_t format)
312 if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) {
313 mp_msg(MSGT_VO,MSGL_DBG2, "vesa_lvo: query_format was called: %x (%s)\n",format,vo_format_name(format)); }
314 return VFCAP_CSP_SUPPORTED;
317 int vlvo_control(uint32_t request, void *data)
319 switch (request) {
320 case VOCTRL_QUERY_FORMAT:
321 return vlvo_query_info(*((uint32_t*)data));
323 return VO_NOTIMPL;