Mercurial > mplayer.hg
annotate vidix/pm2_vid.c @ 23510:a6c619ee9d30
Teletext support for tv:// (v4l and v4l2 only)
modified patch from Otvos Attila oattila at chello dot hu
Module uses zvbi library for all low-level VBI operations (like I/O with vbi
device, converting vbi pages into usefull vbi_page stuctures, rendering them
into RGB32 images).
All teletext related stuff (except properties, slave commands and rendering
osd in text mode or RGB32 rendered teletext pages in spu mode) is implemented
in tvi_vbi.c
New properties:
teletext_page - switching between pages
teletext_mode - switch between on/off/opaque/transparent modes
teletext_format - (currently read-only) allows to get format info
(black/white,gray,text)
teletext_half_page - trivial zooming (displaying top/bottom half of teletext
page)
New slave commands:
teletext_add_dec - user interface for jumping to any page by editing page number
interactively
teletext_go_link - goes though links, specified on current page
author | voroshil |
---|---|
date | Sun, 10 Jun 2007 00:06:12 +0000 |
parents | 91ad6d4d6a54 |
children | acfe034e5386 |
rev | line source |
---|---|
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
1 /* |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
2 * VIDIX driver for 3DLabs Permedia 2 chipsets. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
3 * Copyright (C) 2002 Måns Rullgård |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
4 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
5 * This file is part of MPlayer. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
6 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
10 * (at your option) any later version. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
11 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
15 * GNU General Public License for more details. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
16 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
17 * You should have received a copy of the GNU General Public License |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
18 * along with MPlayer; if not, write to the Free Software |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
23040
diff
changeset
|
20 */ |
22974 | 21 |
22 #include <errno.h> | |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <string.h> | |
26 #include <inttypes.h> | |
27 #include <sys/types.h> | |
28 #include <unistd.h> | |
29 | |
30 #include "vidix.h" | |
31 #include "vidixlib.h" | |
32 #include "fourcc.h" | |
33 #include "dha.h" | |
34 #include "pci_ids.h" | |
35 #include "pci_names.h" | |
36 #include "config.h" | |
37 | |
38 #include "glint_regs.h" | |
39 | |
40 /* MBytes of video memory to use */ | |
41 #define PM2_VIDMEM 6 | |
42 | |
43 #if 0 | |
44 #define TRACE_ENTER() fprintf(stderr, "%s: enter\n", __FUNCTION__) | |
45 #define TRACE_EXIT() fprintf(stderr, "%s: exit\n", __FUNCTION__) | |
46 #else | |
47 #define TRACE_ENTER() | |
48 #define TRACE_EXIT() | |
49 #endif | |
50 | |
51 #define WRITE_REG(offset,val) \ | |
23040 | 52 *(volatile unsigned long *)(((unsigned char *)(pm2_reg_base)) + offset) = (val) |
22974 | 53 #define READ_REG(offset) \ |
54 *(volatile unsigned long *)(((unsigned char *)(pm2_reg_base)) + offset) | |
55 | |
56 static pciinfo_t pci_info; | |
57 | |
58 static void *pm2_reg_base; | |
59 static void *pm2_mem; | |
60 | |
61 static int pm2_vidmem = PM2_VIDMEM; | |
62 | |
63 static vidix_capability_t pm2_cap = | |
64 { | |
65 "3DLabs Permedia2 driver", | |
66 "Måns Rullgård <mru@users.sf.net>", | |
67 TYPE_OUTPUT, | |
68 { 0, 0, 0, 0 }, | |
69 2048, | |
70 2048, | |
71 4, | |
72 4, | |
73 -1, | |
74 FLAG_UPSCALER|FLAG_DOWNSCALER, | |
75 VENDOR_3DLABS, | |
76 -1, | |
77 { 0, 0, 0, 0 } | |
78 }; | |
79 | |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
80 static unsigned int pm2_card_ids[] = |
22974 | 81 { |
82 (VENDOR_3DLABS << 16) | DEVICE_3DLABS_PERMEDIA2, | |
83 (VENDOR_TEXAS << 16) | DEVICE_TEXAS_TVP4020_PERMEDIA_2 | |
84 }; | |
85 | |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
86 static int find_chip(unsigned int vendor, uint32_t chip_id) |
22974 | 87 { |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
88 unsigned int vci = (vendor << 16) | chip_id; |
22974 | 89 unsigned i; |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
90 for(i = 0; i < sizeof(pm2_card_ids)/sizeof(unsigned int); i++){ |
22974 | 91 if(vci == pm2_card_ids[i]) return i; |
92 } | |
93 return -1; | |
94 } | |
95 | |
96 static int pm2_probe(int verbose, int force __attribute__ ((unused))) | |
97 { | |
98 pciinfo_t lst[MAX_PCI_DEVICES]; | |
99 unsigned i,num_pci; | |
100 int err; | |
101 | |
102 err = pci_scan(lst,&num_pci); | |
103 if(err) | |
104 { | |
105 printf("[pm2] Error occurred during pci scan: %s\n",strerror(err)); | |
106 return err; | |
107 } | |
108 else | |
109 { | |
110 err = ENXIO; | |
111 for(i=0; i < num_pci; i++) | |
112 { | |
113 int idx; | |
114 const char *dname; | |
115 idx = find_chip(lst[i].vendor, lst[i].device); | |
116 if(idx == -1) | |
117 continue; | |
118 dname = pci_device_name(lst[i].vendor, lst[i].device); | |
119 dname = dname ? dname : "Unknown chip"; | |
120 printf("[pm2] Found chip: %s\n", dname); | |
121 pm2_cap.device_id = lst[i].device; | |
122 err = 0; | |
123 memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); | |
124 break; | |
125 } | |
126 } | |
127 if(err && verbose) printf("[pm2] Can't find chip.\n"); | |
128 return err; | |
129 } | |
130 | |
131 #define PRINT_REG(reg) \ | |
132 { \ | |
133 long _foo = READ_REG(reg); \ | |
134 printf("[pm2] " #reg " (%x) = %#lx (%li)\n", reg, _foo, _foo); \ | |
135 } | |
136 | |
22984 | 137 static int pm2_init(void) |
22974 | 138 { |
139 char *vm; | |
140 pm2_reg_base = map_phys_mem(pci_info.base0, 0x10000); | |
141 pm2_mem = map_phys_mem(pci_info.base1, 1 << 23); | |
142 if((vm = getenv("PM2_VIDMEM"))){ | |
143 pm2_vidmem = strtol(vm, NULL, 0); | |
144 } | |
145 return 0; | |
146 } | |
147 | |
148 static void pm2_destroy(void) | |
149 { | |
150 unmap_phys_mem(pm2_reg_base, 0x10000); | |
151 unmap_phys_mem(pm2_mem, 1 << 23); | |
152 } | |
153 | |
154 static int pm2_get_caps(vidix_capability_t *to) | |
155 { | |
156 memcpy(to, &pm2_cap, sizeof(vidix_capability_t)); | |
157 return 0; | |
158 } | |
159 | |
160 static int is_supported_fourcc(uint32_t fourcc) | |
161 { | |
162 switch(fourcc){ | |
163 case IMGFMT_YUY2: | |
164 return 1; | |
165 default: | |
166 return 0; | |
167 } | |
168 } | |
169 | |
170 static int pm2_query_fourcc(vidix_fourcc_t *to) | |
171 { | |
172 if(is_supported_fourcc(to->fourcc)) | |
173 { | |
23060 | 174 to->depth = VID_DEPTH_ALL; |
22974 | 175 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; |
176 return 0; | |
177 } | |
178 else to->depth = to->flags = 0; | |
179 return ENOSYS; | |
180 } | |
181 | |
182 #define FORMAT_YUV422 ((1 << 6) | 3 | (1 << 4)) | |
183 | |
184 #define PPROD(a,b,c) (a | (b << 3) | (c << 6)) | |
185 | |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
186 static unsigned int ppcodes[][2] = { |
22974 | 187 {0, 0}, |
188 {32, PPROD(1, 0, 0)}, | |
189 {64, PPROD(1, 1, 0)}, | |
190 {96, PPROD(1, 1, 1)}, | |
191 {128, PPROD(2, 1, 1)}, | |
192 {160, PPROD(2, 2, 1)}, | |
193 {192, PPROD(2, 2, 2)}, | |
194 {224, PPROD(3, 2, 1)}, | |
195 {256, PPROD(3, 2, 2)}, | |
196 {288, PPROD(3, 3, 1)}, | |
197 {320, PPROD(3, 3, 2)}, | |
198 {384, PPROD(3, 3, 3)}, | |
199 {416, PPROD(4, 3, 1)}, | |
200 {448, PPROD(4, 3, 2)}, | |
201 {512, PPROD(4, 3, 3)}, | |
202 {544, PPROD(4, 4, 1)}, | |
203 {576, PPROD(4, 4, 2)}, | |
204 {640, PPROD(4, 4, 3)}, | |
205 {768, PPROD(4, 4, 4)}, | |
206 {800, PPROD(5, 4, 1)}, | |
207 {832, PPROD(5, 4, 2)}, | |
208 {896, PPROD(5, 4, 3)}, | |
209 {1024, PPROD(5, 4, 4)}, | |
210 {1056, PPROD(5, 5, 1)}, | |
211 {1088, PPROD(5, 5, 2)}, | |
212 {1152, PPROD(5, 5, 3)}, | |
213 {1280, PPROD(5, 5, 4)}, | |
214 {1536, PPROD(5, 5, 5)}, | |
215 {1568, PPROD(6, 5, 1)}, | |
216 {1600, PPROD(6, 5, 2)}, | |
217 {1664, PPROD(6, 5, 3)}, | |
218 {1792, PPROD(6, 5, 4)}, | |
219 {2048, PPROD(6, 5, 5)} | |
220 }; | |
221 | |
222 static int frames[VID_PLAY_MAXFRAMES]; | |
223 | |
224 static int pm2_config_playback(vidix_playback_t *info) | |
225 { | |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
226 unsigned int src_w, drw_w; |
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
227 unsigned int src_h, drw_h; |
22974 | 228 long base0; |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
229 unsigned int stride, sstr; |
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
230 unsigned int format; |
22974 | 231 unsigned int i; |
23037
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
232 unsigned int ppcode = 0, sppc = 0; |
c2c2bc418257
better fix for r23001, u_int becomes unsigned int, dont force it to uin32_t
ben
parents:
22984
diff
changeset
|
233 unsigned int pitch = 0; |
22974 | 234 |
235 TRACE_ENTER(); | |
236 | |
237 switch(info->fourcc){ | |
238 case IMGFMT_YUY2: | |
239 format = FORMAT_YUV422; | |
240 break; | |
241 default: | |
242 return -1; | |
243 } | |
244 | |
245 src_w = info->src.w; | |
246 src_h = info->src.h; | |
247 | |
248 drw_w = info->dest.w; | |
249 drw_h = info->dest.h; | |
250 | |
251 sstr = READ_REG(PMScreenStride) * 2; | |
252 | |
253 stride = 0; | |
254 for(i = 1; i < sizeof(ppcodes) / sizeof(ppcodes[0]); i++){ | |
255 if((!stride) && (ppcodes[i][0] >= src_w)){ | |
256 stride = ppcodes[i][0]; | |
257 ppcode = ppcodes[i][1]; | |
258 pitch = ppcodes[i][0] - ppcodes[i-1][0]; | |
259 } | |
260 if(ppcodes[i][0] == sstr) | |
261 sppc = ppcodes[i][1]; | |
262 } | |
263 | |
264 if(!stride) | |
265 return -1; | |
266 | |
267 info->num_frames = pm2_vidmem*1024*1024 / (stride * src_h * 2); | |
268 if(info->num_frames > VID_PLAY_MAXFRAMES) | |
269 info->num_frames = VID_PLAY_MAXFRAMES; | |
270 | |
271 /* Use end of video memory. Assume the card has 8 MB */ | |
272 base0 = (8 - pm2_vidmem)*1024*1024; | |
273 info->dga_addr = pm2_mem + base0; | |
274 | |
275 info->dest.pitch.y = pitch*2; | |
276 info->dest.pitch.u = 0; | |
277 info->dest.pitch.v = 0; | |
278 info->offset.y = 0; | |
279 info->offset.v = 0; | |
280 info->offset.u = 0; | |
281 info->frame_size = stride * src_h * 2; | |
282 | |
283 for(i = 0; i < info->num_frames; i++){ | |
284 info->offsets[i] = info->frame_size * i; | |
285 frames[i] = (base0 + info->offsets[i]) >> 1; | |
286 } | |
287 | |
288 WRITE_REG(WindowOrigin, 0); | |
289 WRITE_REG(dY, 1 << 16); | |
290 WRITE_REG(RasterizerMode, 0); | |
291 WRITE_REG(ScissorMode, 0); | |
292 WRITE_REG(AreaStippleMode, 0); | |
293 WRITE_REG(StencilMode, 0); | |
294 WRITE_REG(TextureAddressMode, 1); | |
295 | |
296 WRITE_REG(dSdyDom, 0); | |
297 WRITE_REG(dTdx, 0); | |
298 | |
299 WRITE_REG(PMTextureMapFormat, (1 << 19) | ppcode); | |
300 WRITE_REG(PMTextureDataFormat, format); | |
301 WRITE_REG(PMTextureReadMode, (1 << 17) | /* FilterMode */ | |
302 (11 << 13) | (11 << 9) /* TextureSize log2 */ | 1); | |
303 WRITE_REG(ColorDDAMode, 0); | |
304 WRITE_REG(TextureColorMode, (0 << 4) /* RGB */ | (3 << 1) /* Copy */ | 1); | |
305 WRITE_REG(AlphaBlendMode, 0); | |
306 WRITE_REG(DitherMode, (1 << 10) | 1); | |
307 WRITE_REG(LogicalOpMode, 0); | |
308 WRITE_REG(FBReadMode, sppc); | |
309 WRITE_REG(FBHardwareWriteMask, 0xFFFFFFFF); | |
310 WRITE_REG(FBWriteMode, 1); | |
311 WRITE_REG(YUVMode, 1); | |
312 | |
313 WRITE_REG(SStart, 0); | |
314 WRITE_REG(TStart, 0); | |
315 | |
316 WRITE_REG(dSdx, (src_w << 20) / drw_w); | |
317 WRITE_REG(dTdyDom, (src_h << 20) / drw_h); | |
318 WRITE_REG(RectangleOrigin, info->dest.x | (info->dest.y << 16)); | |
319 WRITE_REG(RectangleSize, (drw_h << 16) | drw_w); | |
320 | |
321 TRACE_EXIT(); | |
322 return 0; | |
323 } | |
324 | |
325 static int pm2_playback_on(void) | |
326 { | |
327 TRACE_ENTER(); | |
328 | |
329 TRACE_EXIT(); | |
330 return 0; | |
331 } | |
332 | |
333 static int pm2_playback_off(void) | |
334 { | |
335 WRITE_REG(YUVMode, 0); | |
336 WRITE_REG(TextureColorMode, 0); | |
337 WRITE_REG(TextureAddressMode, 0); | |
338 WRITE_REG(TextureReadMode, 0); | |
339 return 0; | |
340 } | |
341 | |
342 static int pm2_frame_select(unsigned int frame) | |
343 { | |
344 WRITE_REG(PMTextureBaseAddress, frames[frame]); | |
345 WRITE_REG(Render, PrimitiveRectangle | XPositive | YPositive | | |
346 TextureEnable); | |
347 return 0; | |
348 } | |
349 | |
350 VDXDriver pm2_drv = { | |
351 "pm2", | |
352 NULL, | |
353 .probe = pm2_probe, | |
354 .get_caps = pm2_get_caps, | |
355 .query_fourcc = pm2_query_fourcc, | |
356 .init = pm2_init, | |
357 .destroy = pm2_destroy, | |
358 .config_playback = pm2_config_playback, | |
359 .playback_on = pm2_playback_on, | |
360 .playback_off = pm2_playback_off, | |
361 .frame_sel = pm2_frame_select, | |
362 }; |