Mercurial > mplayer.hg
annotate stream/tvi_vbi.c @ 25194:e816d546c4fe
ao_null: Make duration of "buffered" audio constant
Choose the "buffer size" for the amount of audio the driver accepts so
that it corresponds to about 0.2 seconds of playback based on the
number of channels, sample size and samplerate.
author | uau |
---|---|
date | Sat, 01 Dec 2007 01:39:39 +0000 |
parents | c0672ecc6bca |
children | 157aafb33efe |
rev | line source |
---|---|
23899 | 1 /* |
2 * Teletext support | |
3 * Copyright (C) 2007 Vladimir Voroshilov <voroshil@gmail.com> | |
4 * | |
5 * This file is part of MPlayer. | |
6 * | |
7 * MPlayer is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * MPlayer is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with MPlayer; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 * | |
21 * | |
22 * Based on Attila Otvos' teletext patch, Michael Niedermayer's | |
23 * proof-of-concept teletext capture utility and some parts | |
24 * (decode_raw_line_runin,pll_add,pll_reset) of MythTV project. | |
24099 | 25 * Code for calculating [soc:eoc] is based on aletv of Edgar Toernig. |
23899 | 26 * |
24186 | 27 * Teletext system is described in |
28 * ETS 300 706 "Enhanced Teletext specification" : May 1997 | |
29 * http://www.themm.net/~mihu/linux/saa7146/specs/ets_300706e01p.pdf | |
23899 | 30 * |
31 * Some implementation details: | |
32 * How to port teletext to another tvi_* driver (see tvi_v4l2.c for example): | |
33 * | |
34 * 1. Implement TVI_CONTROL_VBI_INIT (initialize driver-related vbi subsystem, | |
35 * start grabbing thread) | |
36 * input data: vbi device name. | |
37 * (driver should also call TV_VBI_CONTROL_START for common vbi subsystem initialization | |
38 * with pointer to initialized tt_stream_properties structure. | |
39 * After ioctl call variable will contain pointer to initialized priv_vbi_t structure. | |
40 * | |
41 * 2. After receiving next chunk of raw vbi data call TV_VBI_CONTROL_DECODE_PAGE | |
42 * ioctl with pointer to data buffer | |
43 * 3. pass all other VBI related ioctl cmds to teletext_control routine | |
44 * | |
45 * Page displaying process consist of following stages: | |
46 * | |
47 * ---grabbing stage--- | |
48 * 0. stream/tvi_*.c: vbi_grabber(...) | |
49 * getting vbi data from video device | |
50 * ---decoding stage--- | |
51 * 1. stream/tvi_vbi.c: decode_raw_line_runin(...) or decode_raw_line_sine(...) | |
52 * decode raw vbi data into sliced 45(?) bytes long packets | |
53 * 2. stream/tvi_vbi.c: decode_pkt0(...), decode_pkt_page(...) | |
54 * packets processing (header analyzing, storing complete page in cache, | |
55 * only raw member of tt_char is filled at this stage) | |
56 * 3. stream/tvi_vbi.c: decode_page(...) | |
57 * page decoding. filling unicode,gfx,ctl,etc members of tt_char structure | |
58 * with appropriate values according to teletext control chars, converting | |
59 * text to utf8. | |
60 * ---rendering stage--- | |
61 * 4. stream/tvi_vbi.c: prepare_visible_page(...) | |
62 * processing page. adding number of just received by background process | |
63 * teletext page, adding current time,etc. | |
64 * 5. libvo/sub.c: vo_update_text_teletext(...) | |
65 * rendering displayable osd with text and graphics | |
66 * | |
67 * TODO: | |
68 * v4lv1,bktr support | |
69 * spu rendering | |
70 * is better quality on poor signal possible ? | |
71 * link support | |
72 * font autoscale | |
73 * greyscale osd | |
74 * slave command for dumping pages | |
75 * fix bcd<->dec as suggested my Michael | |
76 * | |
77 * BUGS: | |
78 * wrong colors in debug dump | |
79 * blinking when visible page was just updated | |
80 */ | |
81 | |
82 #include "config.h" | |
83 | |
84 #include <stdlib.h> | |
85 #include <string.h> | |
86 #include <unistd.h> | |
87 #include <errno.h> | |
88 #include <math.h> | |
89 #include <stdio.h> | |
90 | |
91 #include <pthread.h> | |
92 | |
93 #include "tv.h" | |
94 #include "mp_msg.h" | |
95 #include "help_mp.h" | |
96 #include "libmpcodecs/img_format.h" | |
97 #include "libavutil/common.h" | |
98 #include "input/input.h" | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
99 #include "osdep/timer.h" |
23899 | 100 |
101 //#define DEBUG_DUMP 1 | |
102 | |
103 /// page magazine entry structure | |
104 typedef struct mag_s{ | |
105 tt_page* pt; | |
106 int order; | |
107 } mag_t; | |
108 | |
109 typedef struct { | |
110 int on; ///< teletext on/off | |
111 int pagenum; ///< seek page number | |
112 int subpagenum; ///< seek subpage | |
113 int curr_pagenum; ///< current page number | |
114 int pagenumdec; ///< set page num with dec | |
115 | |
116 teletext_format tformat; ///< see teletext_format enum | |
117 teletext_zoom zoom; ///< see teletext_zoom enum | |
118 mag_t* mag; ///< pages magazine (has 8 entities) | |
24290 | 119 int primary_language; ///< primary character set |
120 int secondary_language; ///< secondary character set | |
23899 | 121 /// Currently displayed page (with additional info, e.g current time) |
122 tt_char display_page[VBI_ROWS*VBI_COLUMNS]; | |
123 /// number of raw bytes between two subsequent encoded bits | |
124 int bpb; | |
125 /// clock run-in sequence will be searched in buffer in [soc:eoc] bytes range | |
126 int soc; | |
127 int eoc; | |
128 /// minimum number of raw vbi bytes wich can be decoded into 8 data bits | |
129 int bp8bl; | |
130 /// maximum number of raw vbi bytes wich can be decoded into 8 data bits | |
131 int bp8bh; | |
132 | |
133 int pll_adj; | |
134 int pll_dir; | |
135 int pll_cnt; | |
136 int pll_err; | |
137 int pll_lerr; | |
138 int pll_fixed; | |
139 /// vbi stream properties (buffer size,bytes per line, etc) | |
140 tt_stream_props* ptsp; | |
141 pthread_mutex_t buffer_mutex; | |
142 | |
143 tt_page** ptt_cache; | |
144 unsigned char* ptt_cache_first_subpage; | |
24232
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
145 /// network info |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
146 unsigned char initialpage; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
147 unsigned int initialsubpage; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
148 unsigned int networkid; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
149 int timeoffset; // timeoffset=realoffset*2 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
150 unsigned int juliandate; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
151 unsigned int universaltime; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
152 unsigned char networkname[21]; |
24301
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
153 int cache_reset; |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
154 /// "page changed" flag: 0-unchanged, 1-entire page, 3-only header |
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
155 int page_changed; |
24345 | 156 int last_rendered; |
23899 | 157 } priv_vbi_t; |
158 | |
159 static unsigned char fixParity[256]; | |
160 | |
24344 | 161 static tt_char tt_space={0x20,7,0,0,0,0,0,0,0x20}; |
162 static tt_char tt_error={'?',1,0,0,0,0,0,0,'?'}; // Red '?' on black background | |
23899 | 163 static double si[12]; |
164 static double co[12]; | |
165 | |
166 #define VBI_FORMAT(priv) (*(priv->ptsp)) | |
167 | |
168 #define FIXP_SH 16 | |
169 #define ONE_FIXP (1<<FIXP_SH) | |
170 #define FIXP2INT(a) ((a)>>FIXP_SH) | |
171 #define ANY2FIXP(a) ((int)((a)*ONE_FIXP)) | |
172 | |
173 static const unsigned char corrHamm48[256]={ | |
174 0x01, 0xff, 0x01, 0x01, 0xff, 0x00, 0x01, 0xff, | |
175 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, | |
176 0xff, 0x00, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00, | |
177 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff, | |
178 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07, | |
179 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x07, | |
180 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff, | |
181 0x06, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, | |
182 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09, | |
183 0x02, 0x02, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, | |
184 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff, | |
185 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03, | |
186 0x04, 0xff, 0xff, 0x05, 0x04, 0x04, 0x04, 0xff, | |
187 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, | |
188 0xff, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, 0x05, | |
189 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, | |
190 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09, | |
191 0x0a, 0xff, 0xff, 0x0b, 0x0a, 0x0a, 0x0a, 0xff, | |
192 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff, | |
193 0xff, 0x0b, 0x0b, 0x0b, 0x0a, 0xff, 0xff, 0x0b, | |
194 0x0c, 0x0c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff, | |
195 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, | |
196 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x0d, 0x0d, | |
197 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, | |
198 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x09, | |
199 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, | |
200 0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09, | |
201 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff, | |
202 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09, | |
203 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, | |
204 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff, | |
205 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e }; | |
206 | |
207 | |
208 enum { | |
24271 | 209 LATIN=0, |
24256 | 210 CYRILLIC1, |
24271 | 211 CYRILLIC2, |
24255
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
212 CYRILLIC3, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
213 GREEK, |
23899 | 214 LANGS |
215 }; | |
216 | |
217 // conversion table for chars 0x20-0x7F (UTF8) | |
218 // TODO: add another languages | |
219 static unsigned int lang_chars[LANGS][0x60]={ | |
220 { | |
221 //Latin | |
222 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, | |
223 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, | |
224 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, | |
225 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, | |
226 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, | |
227 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, | |
228 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, | |
229 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, | |
230 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, | |
231 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, | |
232 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, | |
233 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f | |
234 }, | |
235 { | |
24255
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
236 //Cyrillic-1 (Serbian/Croatian) |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
237 0x20,0x21,0x22,0x23,0x24,0x25,0x044b,0x27, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
238 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
239 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
240 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
241 0x0427,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
242 0x0425,0x0418,0x0408,0x041a,0x041b,0x041c,0x041d,0x041e, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
243 0x041f,0x040c,0x0420,0x0421,0x0422,0x0423,0x0412,0x0403, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
244 0x0409,0x040a,0x0417,0x040b,0x0416,0x0402,0x0428,0x040f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
245 0x0447,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
246 0x0445,0x0438,0x0428,0x043a,0x043b,0x043c,0x043d,0x043e, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
247 0x043f,0x042c,0x0440,0x0441,0x0442,0x0443,0x0432,0x0423, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
248 0x0429,0x042a,0x0437,0x042b,0x0436,0x0422,0x0448,0x042f |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
249 }, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
250 { |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
251 //Cyrillic-2 (Russian/Bulgarian) |
23899 | 252 0x20,0x21,0x22,0x23,0x24,0x25,0x044b,0x27, |
253 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, | |
254 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, | |
255 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, | |
256 0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413, | |
257 0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e, | |
258 0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412, | |
259 0x042c,0x042a,0x0417,0x0428,0x042d,0x0429,0x0427,0x042b, | |
260 0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433, | |
261 0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e, | |
262 0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432, | |
263 0x044c,0x044a,0x0437,0x0448,0x044d,0x0449,0x0447,0x044b | |
24255
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
264 }, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
265 { |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
266 //Cyrillic-3 (Ukrainian) |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
267 0x20,0x21,0x22,0x23,0x24,0x25,0xef,0x27, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
268 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
269 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
270 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
271 0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
272 0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
273 0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
274 0x042c,0x49,0x0417,0x0428,0x042d,0x0429,0x0427,0xcf, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
275 0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
276 0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
277 0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
278 0x044c,0x69,0x0437,0x0448,0x044d,0x0449,0x0447,0xFF |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
279 }, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
280 { |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
281 //Greek |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
282 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
283 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
284 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
285 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
286 0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
287 0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
288 0x03a0,0x03a1,0x03a2,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
289 0x03a8,0x03a9,0x03aa,0x03ab,0x03ac,0x03ad,0x03ae,0x03af, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
290 0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
291 0x03b8,0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
292 0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7, |
d6b310ab40c8
Conversion tables for Serbian/Croatian, Ukrainian and Greek charsets.
voroshil
parents:
24244
diff
changeset
|
293 0x03c8,0x03c9,0x03ca,0x03cb,0x03cc,0x03cd,0x03ce,0x03cf |
23899 | 294 } |
295 }; | |
296 | |
24184 | 297 /** |
298 * Latin National Option Sub-Sets | |
299 * see Table 36 of ETS specification for details. | |
300 * | |
301 * 00: £ $ @ « ½ » ¬ # ¼ ¦ ¾ ÷ English | |
302 * 01: é ï à ë ê ù î # è â ô û ç French | |
303 * 02: # ¤ É Ä Ö Å Ü _ é ä ö å ü Swedish/Finnish/Hungarian | |
24788 | 304 * 03: # ů č ť ž ý í ř é á ě ú š Czech/Slovak |
24184 | 305 * 04: # $ § Ä Ö Ü ^ _ ° ä ö ü ß German |
306 * 05: ç $ ¡ á é í ó ú ¿ ü ñ è à Portuguese/Spanish | |
307 * 06: £ $ é ° ç » ¬ # ù à ò è ì Italian | |
308 * | |
309 */ | |
310 static unsigned int latin_subchars[8][13]={ | |
311 // English | |
312 {0xa3,0x24,0x40,0xab,0xbd,0xbb,0xac,0x23,0xad,0xbc,0xa6,0xbe,0xf7}, | |
313 // French | |
314 {0xe9,0xef,0xe0,0xeb,0xea,0xf9,0xee,0x23,0xe8,0xe2,0xf4,0xfb,0xe7}, | |
315 // Swedish/Finnish/Hungarian | |
316 {0x23,0xa4,0xc9,0xc4,0xd6,0xc5,0xdc,0x5f,0xe9,0xe4,0xf6,0xe5,0xfc}, | |
317 // Czech/Slovak | |
24788 | 318 {0x23,0x16f,0x10d,0x165,0x17e,0xfd,0xed,0x159,0xe9,0xe1,0x11b,0xfa,0x161}, |
24184 | 319 // German |
320 {0x23,0x24,0xa7,0xc4,0xd6,0xdc,0x5e,0x5f,0xb0,0xe4,0xf6,0xfc,0xdf}, | |
321 // Portuguese/Spanish | |
322 {0xe7,0x24,0xa1,0xe1,0xe9,0xed,0xf3,0xfa,0xbf,0xfc,0xf1,0xe8,0xe0}, | |
323 // Italian | |
324 {0xa3,0x24,0xe9,0xb0,0xe7,0xbb,0xac,0x23,0xf9,0xe0,0xf2,0xe8,0xec}, | |
325 // Reserved | |
326 {0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x7b,0x7c,0x7d,0x7e} | |
327 }; | |
328 | |
24290 | 329 /** |
330 * List of supported languages. | |
331 * | |
332 * lang_code bits for primary Language: | |
333 * bits 7-4 corresponds to bits 14-11 of 28 packet's first triplet | |
334 * bits 3-1 corresponds to bits C12-C14 of packet 0 (lang) | |
335 * | |
336 * lang_code bits for secondary Language: | |
337 * bits 7-5 corresponds to bits 3-1 of 28 packet's second triplet | |
338 * bits 4,2 corresponds to bits 18,16 of 28 packet's first triplet | |
339 * bits 3,1 corresponds to bits 15,17 of 28 packet's first triplet | |
340 * | |
341 * For details see Tables 32 and 33 of specification (subclause 15.2) | |
342 */ | |
343 struct { | |
344 unsigned char lang_code; | |
345 unsigned char charset; | |
346 char* lang_name; | |
347 } tt_languages[]= | |
348 { | |
349 { 0x01, LATIN, "French"}, | |
350 { 0x02, LATIN, "Swedish/Finnish/Hungarian"}, | |
351 { 0x03, LATIN, "Czech/Slovak"}, | |
352 { 0x04, LATIN, "German"}, | |
353 { 0x05, LATIN, "Portuguese/Spanish"}, | |
354 { 0x06, LATIN, "Italian"}, | |
355 | |
356 { 0x08, LATIN, "Polish"}, | |
357 { 0x09, LATIN, "French"}, | |
358 { 0x0a, LATIN, "Swedish/Finnish/Hungarian"}, | |
359 { 0x0b, LATIN, "Czech/Slovak"}, | |
360 { 0x0c, LATIN, "German"}, | |
361 { 0x0e, LATIN, "Italian"}, | |
362 | |
363 { 0x10, LATIN, "English"}, | |
364 { 0x11, LATIN, "French"}, | |
365 { 0x12, LATIN, "Swedish/Finnish/Hungarian"}, | |
366 { 0x13, LATIN, "Turkish"}, | |
367 { 0x14, LATIN, "German"}, | |
368 { 0x15, LATIN, "Portuguese/Spanish"}, | |
369 { 0x16, LATIN, "Italian"}, | |
370 | |
371 { 0x1d, LATIN, "Serbian/Croatian/Slovenian (Latin)"}, | |
372 | |
373 { 0x20, CYRILLIC1, "Serbian/Croatian (Cyrillic)"}, | |
374 { 0x21, CYRILLIC2, "Russian, Bulgarian"}, | |
375 { 0x22, LATIN, "Estonian"}, | |
376 { 0x23, LATIN, "Czech/Slovak"}, | |
377 { 0x24, LATIN, "German"}, | |
378 { 0x25, CYRILLIC3, "Ukrainian"}, | |
379 { 0x26, LATIN, "Lettish/Lithuanian"}, | |
380 | |
381 { 0x33, LATIN, "Turkish"}, | |
382 { 0x37, GREEK, "Greek"}, | |
383 | |
384 { 0x40, LATIN, "English"}, | |
385 { 0x41, LATIN, "French"}, | |
386 // { 0x47, ARABIC, "Arabic"}, | |
387 | |
388 // { 0x55, HEBREW, "Hebrew"}, | |
389 // { 0x57, ARABIC, "Arabic"}, | |
390 | |
391 { 0x00, LATIN, "English"}, | |
392 }; | |
393 | |
394 /** | |
395 * \brief 24/18 Hamming code decoding | |
396 * \param data bytes with hamming code (array must be at least 3 bytes long) | |
397 * \return -1 if multiple bit error occured, D1-DI data bits - otherwise | |
398 * | |
399 * \note Bits must be correctly ordered, that is for 24/18 (lowest bit first) | |
400 * P1 P2 D1 P3 D2 D3 D4 P4 D5 D6 D7 D8 D9 DA DB P5 DC DD DE DF DG DH DI P6 | |
401 */ | |
402 int corrHamm24(unsigned char *data){ | |
403 unsigned char syndrom=0; | |
404 int cw=data[0] | (data[1]<<8) | (data[2]<<16); | |
405 int i; | |
406 | |
407 for(i=0;i<23;i++) | |
408 syndrom^=((cw>>i)&1)*(i+33); | |
409 | |
410 syndrom^=(cw>>11)&32; | |
411 | |
412 if(syndrom&31){ | |
413 if(syndrom < 32 || syndrom > 55) | |
414 return -1; | |
415 cw ^= 1<<((syndrom&31)-1); | |
416 } | |
417 | |
418 return (cw&4)>>2 | | |
419 (cw&0x70)>>3 | | |
420 (cw&0x3f00)>>4 | | |
421 (cw&0x3f0000)>>5; | |
422 } | |
423 | |
424 /** | |
425 * \brief converts language bits to charset index | |
426 * \param lang language bits | |
427 * \return charset index in lang_chars array | |
428 */ | |
429 static int lang2charset (int lang){ | |
430 int i; | |
431 for(i=0;tt_languages[i].lang_code;i++) | |
432 if(tt_languages[i].lang_code==lang) | |
433 break; | |
434 | |
435 return tt_languages[i].charset; | |
23899 | 436 } |
437 | |
438 /** | |
439 * \brief convert chars from curent teletext codepage into MPlayer charset | |
440 * \param p raw teletext char to decode | |
24290 | 441 * \param charset index on lang_chars |
442 * \param lang index in substitution array (latin charset only) | |
23899 | 443 * \return UTF8 char |
444 * | |
445 * \remarks | |
446 * routine will analyze raw member of given tt_char structure and | |
447 * fill unicode member of the same struct with appropriate utf8 code. | |
448 */ | |
24290 | 449 static unsigned int conv2uni(unsigned int p,int charset,int lang) |
23899 | 450 { |
24290 | 451 |
23899 | 452 if(p<0x80 && p>=0x20){ |
24271 | 453 if(charset==LATIN){ |
24290 | 454 lang&=7; |
24184 | 455 if (p>=0x23 && p<=0x24){ |
456 return latin_subchars[lang][p-0x23]; | |
457 }else if (p==0x40){ | |
458 return latin_subchars[lang][2]; | |
459 }else if (p>=0x5b && p<=0x60){ | |
24190 | 460 return latin_subchars[lang][p-0x5b+3]; |
24184 | 461 }else if (p>=0x7b && p<=0x7e){ |
462 return latin_subchars[lang][p-0x7b+9]; | |
24278 | 463 } |
464 } | |
24184 | 465 return lang_chars[charset][p-0x20]; |
23899 | 466 }else |
467 return 0x20; | |
468 } | |
469 | |
470 static void init_vbi_consts(priv_vbi_t* priv){ | |
471 int i,j; | |
472 double ang; | |
473 for(i=0; i<256; i++){ | |
474 j=i&0x7F; | |
475 j^= j+j; | |
476 j^= j<<2; | |
477 j^= j<<4; | |
478 fixParity[i]= i ^ (j&0x80) ^ 0x80; | |
479 } | |
480 | |
481 for(i=0,ang=0; i<12; i++,ang+=M_PI/priv->bpb){ | |
482 si[i]= sin(ang); | |
483 co[i]= cos(ang); | |
484 } | |
485 | |
486 priv->bpb=(priv->ptsp->sampling_rate/6937500.0)*ONE_FIXP+0.5; | |
24099 | 487 priv->soc=FFMAX(9.2e-6*priv->ptsp->sampling_rate-priv->ptsp->offset, 0); |
488 priv->eoc=FFMIN(12.9e-6*priv->ptsp->sampling_rate-priv->ptsp->offset, | |
489 priv->ptsp->samples_per_line-43*8*priv->bpb/ONE_FIXP); | |
490 if (priv->eoc - priv->soc<16*priv->bpb/ONE_FIXP){ // invalid [soc:eoc] | |
491 priv->soc=0; | |
492 priv->eoc=92; | |
24197 | 493 } |
23899 | 494 priv->bp8bl=0.97*8*priv->bpb/ONE_FIXP; // -3% tolerance |
495 priv->bp8bh=1.03*8*priv->bpb/ONE_FIXP; // +3% tolerance | |
496 } | |
497 /** | |
498 * \brief calculate increased/decreased by given value page number | |
499 * \param curr current page number in hexadecimal for | |
500 * \param direction decimal value (can be negative) to add to value | |
501 * of curr parameter | |
502 * \return new page number in hexadecimal form | |
503 * | |
504 * VBI page numbers are represented in special hexadecimal form, e.g. | |
505 * page with number 123 (as seen by user) internally has number 0x123. | |
506 * and equation 0x123+8 should be equal to 0x131 instead of regular 0x12b. | |
507 * | |
508 * | |
509 * Page numbers 0xYYY (where Y is not belongs to (0..9). | |
510 * Page number belongs to [0x000,0x799] or [0x100:0x899] (first 0 can be | |
511 * treated as '8') | |
512 */ | |
513 static int steppage(int p, int direction, int skip_hidden) | |
514 { | |
515 if(skip_hidden) | |
516 p=(p&15)+((p>>4)&15)*10+(p>>8)*100; | |
517 p+=direction; | |
518 if(skip_hidden){ | |
519 p=(p+800)%800; | |
520 p=(p%10)+((p/10)%10)*16+(p/100)*256; | |
521 } | |
522 | |
523 return p&0x7ff; | |
524 } | |
525 | |
526 /* | |
527 ------------------------------------------------------------------ | |
528 Cache stuff | |
529 ------------------------------------------------------------------ | |
530 */ | |
531 | |
532 /** | |
533 * \brief add/update entry in cache | |
534 * \param priv private data structure | |
535 * \param pg page to store in cache | |
536 * \param line line to update (value below 0 means update entire page) | |
537 */ | |
538 static void put_to_cache(priv_vbi_t* priv,tt_page* pg,int line){ | |
539 tt_page* pgc; //page in cache | |
24244 | 540 int i,j,count; |
23899 | 541 |
542 if(line<0){ | |
543 i=0; | |
24278 | 544 count=VBI_ROWS*VBI_COLUMNS; |
23899 | 545 }else if(line<VBI_ROWS){ |
546 i=line*VBI_COLUMNS; | |
547 count=(line+1)*VBI_COLUMNS; | |
548 }else | |
549 return; | |
550 | |
551 pthread_mutex_lock(&(priv->buffer_mutex)); | |
552 | |
553 if(!priv->ptt_cache[pg->pagenum]){ | |
554 priv->ptt_cache[pg->pagenum]=calloc(1,sizeof(tt_page)); | |
555 pgc=priv->ptt_cache[pg->pagenum]; | |
556 }else{ | |
557 pgc=priv->ptt_cache[pg->pagenum]; | |
558 while(pgc->next_subpage && pgc->subpagenum!=pg->subpagenum) | |
559 pgc=pgc->next_subpage; | |
560 | |
561 if(pgc->subpagenum!=pg->subpagenum){ | |
562 pgc->next_subpage=calloc(1,sizeof(tt_page)); | |
563 pgc=pgc->next_subpage; | |
564 } | |
565 } | |
566 pgc->pagenum=pg->pagenum; | |
567 pgc->subpagenum=pg->subpagenum; | |
24290 | 568 pgc->primary_lang=pg->primary_lang; |
569 pgc->secondary_lang=pg->secondary_lang; | |
23899 | 570 pgc->flags=pg->flags; |
24244 | 571 for(j=0;j<6;++j) |
572 pgc->links[j]=pg->links[j]; | |
23899 | 573 //instead of copying entire page into cache, copy only undamaged |
574 //symbols into cache | |
575 for(;i<count;i++){ | |
576 if(!(pg->raw[i]&0x80)) | |
577 pgc->raw[i]=pg->raw[i]; | |
578 else | |
579 mp_msg(MSGT_TV,MSGL_DBG3,"char error. pg:%x, c[%d]=0x%x\n", | |
580 pg->pagenum,i,pg->raw[i]); | |
581 } | |
582 pgc->active=1; | |
583 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
584 } | |
585 | |
586 /** | |
587 * \brief get any subpage number of given page | |
588 * \param priv private data structure | |
589 * \param pagenum page number to search subpages in | |
590 * | |
591 * \return subpage number of first found subpage which belongs to | |
592 * given page number | |
593 * | |
594 * \note page itself is subpage too (and usually has subpage number 0) | |
595 */ | |
596 static inline int get_subpagenum_from_cache(priv_vbi_t* priv, int pagenum){ | |
597 if (!priv->ptt_cache[pagenum]) | |
24294
68b413a3ce51
Fix missed -1 -> 0x3f7f changes for subpage number.
voroshil
parents:
24293
diff
changeset
|
598 return 0x3f7f; |
23899 | 599 else |
600 return priv->ptt_cache[pagenum]->subpagenum; | |
601 } | |
602 | |
603 /** | |
604 * \brief get page from cache by it page and subpage number | |
605 * \param priv private data structure | |
606 * \param pagenum page number | |
607 * \param subpagenum subpage number | |
608 * | |
609 * \return pointer to tt_page structure if requested page is found | |
610 * and NULL otherwise | |
611 */ | |
612 static inline tt_page* get_from_cache(priv_vbi_t* priv, int pagenum,int subpagenum){ | |
613 tt_page* tp=priv->ptt_cache[pagenum]; | |
614 | |
615 while(tp && tp->subpagenum!=subpagenum) | |
616 tp=tp->next_subpage; | |
617 return tp; | |
618 } | |
619 | |
620 /** | |
621 * \brief clears cache | |
622 * \param priv private data structure | |
623 * | |
624 * Deletes all tt_page structures from cache and frees allocated memory. | |
625 * Only zero-filled array of pointers remains in memory | |
626 */ | |
627 static void clear_cache(priv_vbi_t* priv){ | |
628 int i; | |
629 tt_page* tp; | |
24301
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
630 |
24305
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
631 /* |
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
632 Skip next 5 buffers to avoid mixing teletext pages from different |
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
633 channels during channel switch |
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
634 */ |
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
635 priv->cache_reset=5; |
23899 | 636 for(i=0;i<VBI_MAX_PAGES;i++){ |
637 while(priv->ptt_cache[i]){ | |
638 tp=priv->ptt_cache[i]; | |
639 priv->ptt_cache[i]=tp->next_subpage; | |
640 free(tp); | |
641 } | |
642 } | |
24232
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
643 priv->initialsubpage=priv->networkid=0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
644 priv->timeoffset=0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
645 priv->juliandate=priv->universaltime=0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
646 memset(priv->networkname,0,21); |
23899 | 647 } |
648 | |
649 /** | |
650 * \brief cache initialization | |
651 * \param priv private data structure | |
652 * | |
653 * \note Has to be called before any cache operations! | |
654 */ | |
655 static void init_cache(priv_vbi_t* priv){ | |
656 priv->ptt_cache=calloc(VBI_MAX_PAGES,sizeof(tt_page*)); | |
657 } | |
658 | |
659 /** | |
660 * \brief destroys cache | |
661 * \param priv private data structure | |
662 * | |
663 * Frees all memory allocated for cache (including array of pointers). | |
664 * It is safe to call this routine multiple times | |
665 */ | |
666 static void destroy_cache(priv_vbi_t* priv){ | |
667 if(priv->ptt_cache){ | |
668 clear_cache(priv); | |
669 free(priv->ptt_cache); | |
670 priv->ptt_cache=NULL; | |
671 } | |
672 } | |
673 | |
674 /* | |
675 ------------------------------------------------------------------ | |
676 Decoder stuff | |
677 ------------------------------------------------------------------ | |
678 */ | |
679 /** | |
680 * \brief converts raw teletext page into useful format (1st rendering stage) | |
681 * \param pg page to decode | |
24290 | 682 * \param raw raw data to decode page from |
683 * \param primary_lang primary language code | |
684 * \param secondary_lang secondary language code | |
685 * | |
23899 | 686 * Routine fills tt_char structure of each teletext_page character with proper |
687 * info about foreground and background colors, character | |
688 * type (graphics/control/text). | |
689 */ | |
24344 | 690 static void decode_page(tt_char* p,unsigned char* raw,int primary_lang,int secondary_lang,int flags) |
23899 | 691 { |
692 int row,col; | |
24290 | 693 int prim_charset=lang2charset(primary_lang); |
694 int sec_charset=lang2charset(secondary_lang); | |
23899 | 695 |
696 for(row=0;row<VBI_ROWS;row++) { | |
24290 | 697 int prim_lang=1; |
24280
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
698 int gfx=0; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
699 int fg_color=7; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
700 int bg_color=0; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
701 int separated=0; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
702 int conceal=0; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
703 int hold=0; |
24292
ca146808e926
Proper support for flashing chars in teletext pages.
voroshil
parents:
24290
diff
changeset
|
704 int flash=0; |
24344 | 705 int box=0; |
706 | |
24280
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
707 tt_char tt_held=tt_space; |
23899 | 708 for(col=0;col<VBI_COLUMNS;col++){ |
24280
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
709 int i=row*VBI_COLUMNS+col; |
c1d941c2d9a0
Small code simplification as suggested by Reimar:
voroshil
parents:
24279
diff
changeset
|
710 int c=raw[i]; |
23899 | 711 p[i].raw=c; |
712 if(c&0x80){ //damaged char | |
713 p[i]=tt_error; | |
714 continue; | |
715 } | |
24344 | 716 if((flags&TT_PGFL_SUBTITLE) || (flags&TT_PGFL_NEWFLASH)) |
717 p[i].hidden=!box; | |
718 else | |
719 p[i].hidden=0; | |
23899 | 720 p[i].gfx=gfx?(separated?2:1):0; |
24290 | 721 p[i].lng=prim_lang; |
23899 | 722 p[i].ctl=(c&0x60)==0?1:0; |
723 p[i].fg=fg_color; | |
724 p[i].bg=bg_color; | |
24292
ca146808e926
Proper support for flashing chars in teletext pages.
voroshil
parents:
24290
diff
changeset
|
725 p[i].flh=flash; |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
726 |
23899 | 727 if ((c&0x60)==0){ //control chars |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
728 if(c>=0x08 && c<=0x09){//Flash/Steady |
24292
ca146808e926
Proper support for flashing chars in teletext pages.
voroshil
parents:
24290
diff
changeset
|
729 flash=c==0x08; |
ca146808e926
Proper support for flashing chars in teletext pages.
voroshil
parents:
24290
diff
changeset
|
730 p[i].flh=flash; |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
731 if(c==0x09){ |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
732 p[i].fg=fg_color; |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
733 p[i].bg=bg_color; |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
734 } |
24344 | 735 }else if(c>=0x0a && c<=0x0b){ |
736 box=c&1; | |
737 }else if(c>=0x0c && c<=0x0f){ | |
23899 | 738 }else if (c<=0x17){ //colors |
739 fg_color=c&0x0f; | |
740 gfx=c>>4; | |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
741 conceal=0; |
24276
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
742 if(!gfx) hold=0; |
23899 | 743 }else if (c<=0x18){ |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
744 conceal=1; |
23899 | 745 }else if (c<=0x1a){ //Contiguous/Separated gfx |
746 separated=!(c&1); | |
747 }else if (c<=0x1b){ | |
24290 | 748 prim_lang=!prim_lang; |
23899 | 749 }else if (c<=0x1d){ |
750 bg_color=(c&1)?fg_color:0; | |
751 p[i].bg=bg_color; | |
24276
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
752 }else{ //Hold/Release Graphics |
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
753 hold=!(c&1); |
23899 | 754 } |
755 p[i].ctl=1; | |
24276
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
756 if(hold || c==0x1f){ |
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
757 p[i]=tt_held; |
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
758 p[i].fg=fg_color; |
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
759 p[i].bg=bg_color; |
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
760 }else |
24277 | 761 p[i].unicode=p[i].gfx?0:' '; |
23899 | 762 continue; |
763 } | |
764 | |
24275
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
765 if(conceal){ |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
766 p[i].gfx=0; |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
767 p[i].unicode=' '; |
a12f357e8bd0
Implement Flash/Steady (swapping foreground/background colors)
voroshil
parents:
24271
diff
changeset
|
768 }else if(gfx){ |
23899 | 769 p[i].unicode=c-0x20; |
770 if (p[i].unicode>0x3f) p[i].unicode-=0x20; | |
24276
e8b635a55781
Implement Hold/Release graphics (showing control chars as
voroshil
parents:
24275
diff
changeset
|
771 tt_held=p[i]; |
24290 | 772 }else{ |
773 if(p[i].lng){ | |
774 p[i].unicode=conv2uni(c,prim_charset,primary_lang&7); | |
775 }else{ | |
776 p[i].unicode=conv2uni(c,sec_charset,secondary_lang&7); | |
777 } | |
778 } | |
23899 | 779 p[i].fg=fg_color; |
780 p[i].bg=bg_color; | |
781 } | |
782 } | |
783 } | |
784 | |
785 /** | |
786 * \brief prepares current page for displaying | |
787 * \param priv_vbi private data structure | |
788 * | |
789 * Routine adds some useful info (time and page number of page, grabbed by | |
790 * background thread to top line of current page). Displays "No teletext" | |
791 * string if no vbi data available. | |
792 */ | |
23908 | 793 #define PRINT_HEX(dp,i,h) dp[i].unicode=((h)&0xf)>9?'A'+((h)&0xf)-10:'0'+((h)&0xf) |
23899 | 794 static void prepare_visible_page(priv_vbi_t* priv){ |
795 tt_page *pg,*curr_pg; | |
796 unsigned char *p; | |
797 int i; | |
798 | |
799 pthread_mutex_lock(&(priv->buffer_mutex)); | |
800 mp_msg(MSGT_TV,MSGL_DBG3,"tvi_vbi: prepare_visible_page pg:0x%x, sub:0x%x\n", | |
801 priv->pagenum,priv->subpagenum); | |
24293 | 802 if(priv->subpagenum==0x3f7f) //no page yet |
23899 | 803 priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum); |
804 | |
805 pg=get_from_cache(priv,priv->pagenum,priv->subpagenum); | |
806 mp_dbg(MSGT_TV,MSGL_DBG3,"tvi_vbi: prepare_vibible_page2 pg:0x%x, sub:0x%x\n", | |
807 priv->pagenum,priv->subpagenum); | |
808 | |
809 curr_pg=get_from_cache(priv,priv->curr_pagenum, | |
810 get_subpagenum_from_cache(priv,priv->curr_pagenum)); | |
811 if (!pg && !curr_pg){ | |
812 p=MSGTR_TV_NoTeletext; | |
813 for(i=0;i<VBI_COLUMNS && *p;i++){ | |
814 GET_UTF8(priv->display_page[i].unicode,*p++,break;); | |
815 } | |
816 for(;i<VBI_ROWS*VBI_COLUMNS;i++) | |
817 priv->display_page[i]=tt_space; | |
818 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
819 return; | |
820 } | |
821 | |
822 if (!pg || !pg->active){ | |
823 for(i=0;i<VBI_ROWS*VBI_COLUMNS;i++){ | |
824 priv->display_page[i]=tt_space; | |
825 } | |
826 }else{ | |
24344 | 827 decode_page(priv->display_page,pg->raw,pg->primary_lang,pg->secondary_lang,pg->flags); |
23899 | 828 mp_msg(MSGT_TV,MSGL_DBG3,"page #%x was decoded!\n",pg->pagenum); |
829 } | |
830 | |
831 PRINT_HEX(priv->display_page,0,(priv->curr_pagenum&0x700)?priv->curr_pagenum>>8:8); | |
832 PRINT_HEX(priv->display_page,1,priv->curr_pagenum>>4); | |
833 PRINT_HEX(priv->display_page,2,priv->curr_pagenum); | |
834 priv->display_page[3].unicode=' '; | |
835 priv->display_page[4].unicode=' '; | |
836 switch(priv->pagenumdec>>12){ | |
837 case 1: | |
838 priv->display_page[5].unicode='_'; | |
839 priv->display_page[6].unicode='_'; | |
840 PRINT_HEX(priv->display_page,7,priv->pagenumdec); | |
841 break; | |
842 case 2: | |
843 priv->display_page[5].unicode='_'; | |
844 PRINT_HEX(priv->display_page,6,priv->pagenumdec>>4); | |
845 PRINT_HEX(priv->display_page,7,priv->pagenumdec); | |
846 break; | |
847 default: | |
848 PRINT_HEX(priv->display_page,5,(priv->pagenum&0x700)?priv->pagenum>>8:8); | |
849 PRINT_HEX(priv->display_page,6,priv->pagenum>>4); | |
850 PRINT_HEX(priv->display_page,7,priv->pagenum); | |
851 } | |
24294
68b413a3ce51
Fix missed -1 -> 0x3f7f changes for subpage number.
voroshil
parents:
24293
diff
changeset
|
852 if(priv->subpagenum!=0x3f7f){ |
23899 | 853 priv->display_page[8].unicode='.'; |
854 PRINT_HEX(priv->display_page,9,priv->subpagenum>>4); | |
855 PRINT_HEX(priv->display_page,10,priv->subpagenum); | |
856 }else{ | |
857 priv->display_page[8].unicode=' '; | |
858 priv->display_page[9].unicode=' '; | |
859 priv->display_page[10].unicode=' '; | |
860 } | |
861 priv->display_page[11].unicode=' '; | |
24296
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
862 for(i=VBI_COLUMNS;i>VBI_TIME_LINEPOS || |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
863 ((curr_pg->raw[i]&0x60) && curr_pg->raw[i]!=0x20 && i>11); |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
864 --i) |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
865 if(curr_pg->raw[i]&0x60) |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
866 priv->display_page[i].unicode=curr_pg->raw[i]; |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
867 else |
1980e76f4482
Drop out control chars from page header in time position.
voroshil
parents:
24294
diff
changeset
|
868 priv->display_page[i].unicode=' '; |
23899 | 869 pthread_mutex_unlock(&(priv->buffer_mutex)); |
870 } | |
871 /* | |
872 ------------------------------------------------------------------ | |
873 Renderer stuff | |
874 ------------------------------------------------------------------ | |
875 */ | |
876 #ifdef DEBUG_DUMP | |
877 /** | |
878 * \brief renders teletext page into given file | |
879 * \param pt page to render | |
880 * \param f opened file descriptor | |
881 * \param pagenum which page to render | |
882 * \param colored use colors not implementede yet) | |
883 * | |
884 * Text will be UTF8 encoded | |
885 */ | |
886 static void render2text(tt_page* pt,FILE* f,int colored){ | |
887 int i,j; | |
888 unsigned int u; | |
889 unsigned char buf[8]; | |
890 unsigned char tmp; | |
891 int pos; | |
892 tt_char dp[VBI_ROWS*VBI_COLUMNS]; | |
893 int color=0; | |
894 int bkg=0; | |
895 int c1,b1; | |
896 if(!pt) | |
897 return; | |
898 fprintf(f,"+========================================+\n"); | |
899 fprintf(f,"| lang:%d pagenum:0x%x subpagenum:%d flags:0x%x|\n", | |
900 pt->lang, | |
901 pt->pagenum, | |
902 pt->subpagenum, | |
903 0); | |
904 fprintf(f,"+----------------------------------------+\n"); | |
905 | |
24344 | 906 decode_page(dp,pt->raw,pt->primary_lang,pt->secondary_lang,pt->flags); |
23899 | 907 for(i=0;i<VBI_ROWS;i++){ |
908 fprintf(f,"|"); | |
909 if(colored) fprintf(f,"\033[40m"); | |
910 for(j=0;j<VBI_COLUMNS;j++) | |
911 { | |
912 u=dp[i*VBI_COLUMNS+j].unicode; | |
23928 | 913 if(dp[i*VBI_COLUMNS+j].fg <= 7) |
23899 | 914 c1=30+dp[i*VBI_COLUMNS+j].fg; |
23928 | 915 else |
23899 | 916 c1=38; |
23928 | 917 if(dp[i*VBI_COLUMNS+j].bg <= 7) |
23899 | 918 b1=40+dp[i*VBI_COLUMNS+j].bg; |
23928 | 919 else |
23899 | 920 b1=40; |
921 if (b1!=bkg && colored){ | |
922 fprintf(f,"\033[%dm",b1); | |
923 bkg=b1; | |
924 } | |
925 if(c1!=color && colored){ | |
926 fprintf(f,"\033[%dm",c1); | |
927 color=c1; | |
928 } | |
929 if(dp[i*VBI_COLUMNS+j].gfx){ | |
930 fprintf(f,"*"); | |
931 }else{ | |
932 pos=0; | |
933 PUT_UTF8(u,tmp,if(pos<7) buf[pos++]=tmp;); | |
934 buf[pos]='\0'; | |
935 fprintf(f,"%s",buf); | |
936 } | |
937 } | |
938 | |
939 if (colored) fprintf(f,"\033[0m"); | |
940 color=-1;bkg=-1; | |
941 fprintf(f,"|\n"); | |
942 } | |
943 #if 1 | |
944 //for debug | |
945 fprintf(f,"+====================raw=================+\n"); | |
946 for(i=0;i<VBI_ROWS;i++){ | |
947 for(j=0;j<VBI_COLUMNS;j++) | |
948 fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].raw); | |
949 fprintf(f,"\n"); | |
950 } | |
951 fprintf(f,"+====================lng=================+\n"); | |
952 for(i=0;i<VBI_ROWS;i++){ | |
953 for(j=0;j<VBI_COLUMNS;j++) | |
954 fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].lng); | |
955 fprintf(f,"\n"); | |
956 } | |
957 #endif | |
958 fprintf(f,"+========================================+\n"); | |
959 } | |
960 | |
961 /** | |
962 * \brief dump page into pgXXX.txt file in vurrent directory | |
963 * \param pt page to dump | |
964 * | |
965 * \note XXX in filename is page number | |
966 * \note use only for debug purposes | |
967 */ | |
968 static void dump_page(tt_page* pt) | |
969 { | |
970 FILE*f; | |
971 char name[100]; | |
972 snprintf(name,99,"pg%x.txt",pt->pagenum); | |
973 f=fopen(name,"wb"); | |
974 render2text(pt,f,1); | |
975 fclose(f); | |
976 } | |
977 #endif //DEBUG_DUMP | |
978 | |
979 | |
980 /** | |
981 * \brief checks whether page is ready and copies it into cache array if so | |
982 * \param priv private data structure | |
983 * \param magAddr page's magazine address (0-7) | |
984 * | |
985 * Routine also calls decode_page to perform 1st stage of rendering | |
986 */ | |
987 static void store_in_cache(priv_vbi_t* priv, int magAddr, int line){ | |
988 mp_msg(MSGT_TV,MSGL_DBG2,"store_in_cache(%d): pagenum:%x\n", | |
989 priv->mag[magAddr].order, | |
990 priv->mag[magAddr].pt->pagenum); | |
991 | |
992 put_to_cache(priv,priv->mag[magAddr].pt,line); | |
993 priv->curr_pagenum=priv->mag[magAddr].pt->pagenum; | |
994 | |
995 #ifdef DEBUG_DUMP | |
996 dump_page(get_from_cache(priv, | |
997 priv->mag[magAddr].pt->pagenum, | |
998 priv->mag[magAddr].pt->subpagenum)); | |
999 #endif | |
1000 } | |
1001 | |
1002 | |
1003 /* | |
1004 ------------------------------------------------------------------ | |
1005 Grabber stuff | |
1006 ------------------------------------------------------------------ | |
1007 */ | |
1008 #define PLL_SAMPLES 4 | |
1009 #define PLL_ERROR 4 | |
1010 #define PLL_ADJUST 4 | |
1011 | |
1012 /** | |
1013 * \brief adjust current phase for better signal decoding | |
1014 * \param n count of bytes processed (?) | |
1015 * \param err count of error bytes (?) | |
1016 * | |
1017 * \remarks code was got from MythTV project | |
1018 */ | |
1019 static void pll_add(priv_vbi_t* priv,int n,int err){ | |
1020 if(priv->pll_fixed) | |
1021 return; | |
1022 if(err>PLL_ERROR*2/3) | |
1023 err=PLL_ERROR*2/3; | |
1024 priv->pll_err+=err; | |
1025 priv->pll_cnt+=n; | |
1026 if(priv->pll_cnt<PLL_SAMPLES) | |
1027 return; | |
1028 if(priv->pll_err>PLL_ERROR) | |
1029 { | |
1030 if(priv->pll_err>priv->pll_lerr) | |
1031 priv->pll_dir= -priv->pll_dir; | |
1032 priv->pll_lerr=priv->pll_err; | |
1033 priv->pll_adj+=priv->pll_dir; | |
1034 if (priv->pll_adj<-PLL_ADJUST || priv->pll_adj>PLL_ADJUST) | |
1035 { | |
1036 priv->pll_adj=0; | |
1037 priv->pll_dir=-1; | |
1038 priv->pll_lerr=0; | |
1039 } | |
1040 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: pll_adj=%2d\n",priv->pll_adj); | |
1041 } | |
1042 priv->pll_cnt=0; | |
1043 priv->pll_err=0; | |
1044 } | |
1045 | |
1046 /** | |
1047 * \brief reset error correction | |
1048 * \param priv private data structure | |
1049 * \param fine_tune shift value for adjusting | |
1050 * | |
1051 * \remarks code was got from MythTV project | |
1052 */ | |
1053 static void pll_reset(priv_vbi_t* priv,int fine_tune){ | |
1054 priv->pll_fixed=fine_tune >= -PLL_ADJUST && fine_tune <= PLL_ADJUST; | |
1055 | |
1056 priv->pll_err=0; | |
1057 priv->pll_lerr=0; | |
1058 priv->pll_cnt=0; | |
1059 priv->pll_dir=-1; | |
1060 priv->pll_adj=0; | |
1061 if(priv->pll_fixed) | |
1062 priv->pll_adj=fine_tune; | |
1063 if(priv->pll_fixed) | |
1064 mp_msg(MSGT_TV,MSGL_DBG3,"pll_reset (fixed@%2d)\n",priv->pll_adj); | |
1065 else | |
1066 mp_msg(MSGT_TV,MSGL_DBG3,"pll_reset (auto)\n"); | |
1067 | |
1068 } | |
1069 /** | |
1070 * \brief decode packet 0 (teletext page header) | |
1071 * \param priv private data structure | |
1072 * \param data raw teletext data (with not applied hamm correction yet) | |
1073 * \param magAddr teletext page's magazine address | |
1074 * | |
1075 * \remarks | |
1076 * data buffer was shifted by 6 and now contains: | |
1077 * 0..1 page number | |
1078 * 2..5 sub-code | |
1079 * 6..7 control codes | |
1080 * 8..39 display data | |
1081 * | |
1082 * only first 8 bytes protected by Hamm 8/4 code | |
1083 */ | |
1084 static int decode_pkt0(priv_vbi_t* priv,unsigned char* data,int magAddr) | |
1085 { | |
1086 int d[8]; | |
1087 int i,err; | |
1088 | |
1089 if (magAddr<0 || magAddr>7) | |
1090 return 0; | |
1091 for(i=0;i<8;i++){ | |
1092 d[i]= corrHamm48[ data[i] ]; | |
1093 if(d[i]&0x80){ | |
1094 pll_add(priv,2,4); | |
1095 | |
1096 if(priv->mag[magAddr].pt) | |
1097 free(priv->mag[magAddr].pt); | |
1098 priv->mag[magAddr].pt=NULL; | |
1099 priv->mag[magAddr].order=0; | |
1100 return 0; | |
1101 } | |
1102 } | |
1103 if (!priv->mag[magAddr].pt) | |
1104 priv->mag[magAddr].pt= malloc(sizeof(tt_page)); | |
1105 | |
24290 | 1106 if(priv->primary_language) |
1107 priv->mag[magAddr].pt->primary_lang=priv->primary_language; | |
1108 else | |
1109 priv->mag[magAddr].pt->primary_lang= (d[7]&7)>>1; | |
1110 priv->mag[magAddr].pt->secondary_lang=priv->secondary_language; | |
23899 | 1111 priv->mag[magAddr].pt->subpagenum=(d[2]|(d[3]<<4)|(d[4]<<8)|(d[5]<<12))&0x3f7f; |
1112 priv->mag[magAddr].pt->pagenum=(magAddr<<8) | d[0] | (d[1]<<4); | |
24344 | 1113 priv->mag[magAddr].pt->flags=((d[7]&1)<<7) | ((d[3]&8)<<3) | ((d[5]&12)<<2) | d[6]; |
23899 | 1114 |
1115 memset(priv->mag[magAddr].pt->raw, 0x00, VBI_COLUMNS*VBI_ROWS); | |
1116 priv->mag[magAddr].order=0; | |
1117 | |
1118 for(i=0;i<8;i++){ | |
1119 priv->mag[magAddr].pt->raw[i]=0x20; | |
1120 } | |
1121 err=0; | |
1122 for(i=8; i<VBI_COLUMNS; i++){ | |
1123 data[i]= fixParity[data[i]]; | |
1124 priv->mag[magAddr].pt->raw[i]=data[i]; | |
1125 if(data[i]&0x80) //Error | |
1126 err++; | |
1127 pll_add(priv,1,err); | |
1128 } | |
1129 | |
1130 store_in_cache(priv,magAddr,0); | |
1131 | |
1132 return 1; | |
1133 } | |
1134 | |
1135 /** | |
24232
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1136 * \brief decode teletext 8/30 Format 1 packet |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1137 * \param priv private data structure |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1138 * \param data raw teletext data (with not applied hamm correction yet) |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1139 * \param magAddr teletext page's magazine address |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1140 * |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1141 * \remarks |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1142 * packet contains: |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1143 * 0 designation code |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1144 * 1..2 initial page |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1145 * 3..6 initial subpage & magazine address |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1146 * 7..8 network id |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1147 * 9 time offset |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1148 * 10..12 julian date |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1149 * 13..15 universal time |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1150 * 20..40 network name |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1151 * |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1152 * First 7 bytes are protected by Hamm 8/4 code. |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1153 * Bytes 20-40 has odd parity check. |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1154 * |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1155 * See subcaluse 9.8.1 of specification for details |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1156 */ |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1157 static int decode_pkt30(priv_vbi_t* priv,unsigned char* data,int magAddr) |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1158 { |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1159 int d[8]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1160 int i,err; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1161 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1162 for(i=0;i<7;i++){ |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1163 d[i]= corrHamm48[ data[i] ]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1164 if(d[i]&0x80){ |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1165 pll_add(priv,2,4); |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1166 return 0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1167 } |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1168 d[i]&=0xf; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1169 } |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1170 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1171 err=0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1172 for(i=20; i<40; i++){ |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1173 data[i]= fixParity[data[i]]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1174 if(data[i]&0x80)//Unrecoverable error |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1175 err++; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1176 pll_add(priv,1,err); |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1177 } |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1178 if (err) return 0; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1179 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1180 if (d[0]&0xe) //This is not 8/30 Format 1 packet |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1181 return 1; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1182 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1183 priv->initialpage=d[1] | d[2]<<4 | (d[6]&0xc)<<7 | (d[4]&1)<<8; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1184 priv->initialsubpage=d[3] | d[4]<<4 | d[5]<<8 | d[6]<<12; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1185 priv->networkid=data[7]<<8 | data[8]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1186 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1187 priv->timeoffset=(data[9]>>1)&0xf; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1188 if(data[9]&0x40) |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1189 priv->timeoffset=-priv->timeoffset; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1190 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1191 priv->juliandate=(data[10]&0xf)<<16 | data[11]<<8 | data[12]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1192 priv->juliandate-=0x11111; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1193 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1194 priv->universaltime=data[13]<<16 | data[14]<<8 | data[15]; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1195 priv->universaltime-=0x111111; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1196 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1197 snprintf(priv->networkname,21,"%s",data+20); |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1198 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1199 return 1; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1200 } |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1201 |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1202 /** |
23899 | 1203 * \brief decode packets 1..24 (teletext page header) |
1204 * \param priv private data structure | |
1205 * \param data raw teletext data | |
1206 * \param magAddr teletext page's magazine address | |
1207 * \param rowAddr teletext page's row number | |
1208 * | |
1209 * \remarks | |
1210 * data buffer was shifted by 6 and now contains 40 bytes of display data: | |
1211 * this type of packet is not proptected by Hamm 8/4 code | |
1212 */ | |
1213 static void decode_pkt_page(priv_vbi_t* priv,unsigned char*data,int magAddr,int rowAddr){ | |
1214 int i,err; | |
1215 if (!priv->mag[magAddr].pt) | |
1216 return; | |
1217 | |
1218 priv->mag[magAddr].order=rowAddr; | |
1219 | |
1220 err=0; | |
1221 for(i=0; i<VBI_COLUMNS; i++){ | |
1222 data[i]= fixParity[ data[i] ]; | |
1223 priv->mag[magAddr].pt->raw[i+rowAddr*VBI_COLUMNS]=data[i]; | |
1224 if( data[i]&0x80) //HammError | |
1225 err++; | |
1226 } | |
1227 pll_add(priv,1,err); | |
1228 | |
1229 store_in_cache(priv,magAddr,rowAddr); | |
1230 } | |
1231 | |
1232 /** | |
24244 | 1233 * \brief decode packets 27 (teletext links) |
1234 * \param priv private data structure | |
1235 * \param data raw teletext data | |
1236 * \param magAddr teletext page's magazine address | |
1237 */ | |
1238 static int decode_pkt27(priv_vbi_t* priv,unsigned char* data,int magAddr){ | |
1239 int i,hpg; | |
1240 | |
1241 if (!priv->mag[magAddr].pt) | |
1242 return 0; | |
1243 for(i=0;i<38;++i) | |
1244 if ((data[i] = corrHamm48[ data[i] ]) & 0x80){ | |
1245 pll_add(priv,2,4); | |
1246 return 0; | |
1247 } | |
1248 | |
1249 /* | |
1250 Not a X/27/0 Format 1 packet or | |
1251 flag "show links on row 24" is not set. | |
1252 */ | |
1253 if (data[0] || !(data[37] & 8)) | |
1254 return 1; | |
1255 for(i=0;i<6;++i) { | |
1256 hpg = (magAddr<<8) ^ ((data[4+i*6]&0x8)<<5 | (data[6+i*6]&0xc)<<7); | |
1257 if (!hpg) hpg=0x800; | |
1258 priv->mag[magAddr].pt->links[i].pagenum = (data[1+i*6] & 0xf) | | |
1259 ((data[2+i*6] & 0xf) << 4) | hpg; | |
1260 priv->mag[magAddr].pt->links[i].subpagenum = ((data[3+i*6] & 0xf) | | |
1261 (data[4+i*6] & 0xf) << 4 | (data[5+i*6] & 0xf) << 8 | | |
1262 (data[6+i*6] & 0xf) << 12) & 0x3f7f; | |
1263 } | |
1264 put_to_cache(priv,priv->mag[magAddr].pt,-1); | |
1265 return 1; | |
1266 } | |
1267 | |
1268 /** | |
24290 | 1269 * \brief Decode teletext X/28/0 Format 1 packet |
1270 * \param priv private data structure | |
1271 * \param data raw teletext data | |
1272 * | |
1273 * Primary G0 charset is transmitted in bits 14-8 of Triplet 1 | |
1274 * See Table 32 of specification for details. | |
1275 * | |
1276 * Secondary G0 charset is transmitted in bits 3-1 of Triplet 2 and | |
1277 * bits 18-15 of Triplet 1 | |
1278 * See Table 33 of specification for details. | |
1279 * | |
1280 */ | |
1281 static void decode_pkt28(priv_vbi_t* priv,unsigned char*data){ | |
1282 int d; | |
1283 int t1,t2; | |
1284 d=corrHamm48[ data[0] ]; | |
1285 if(d) return; //this is not X/28/0 Format 1 packet or error occured | |
1286 | |
1287 t1=corrHamm24(data+1); | |
1288 t2=corrHamm24(data+4); | |
1289 if (t1<0 || t2<0){ | |
1290 pll_add(priv,1,4); | |
1291 return; | |
1292 } | |
1293 | |
1294 priv->primary_language=(t1>>7)&0x7f; | |
1295 priv->secondary_language=((t2<<4) | (t1>>14))&0x7f; | |
1296 if (priv->secondary_language==0x7f) | |
1297 //No secondary language required | |
1298 priv->secondary_language=priv->primary_language; | |
1299 else // Swapping bits 1 and 3 | |
1300 priv->secondary_language=(priv->secondary_language&0x7a) | | |
1301 (priv->secondary_language&4)>>2 | | |
1302 (priv->secondary_language&1)<<2; | |
1303 | |
1304 mp_msg(MSGT_TV,MSGL_DBG2,"pkt28: language: primary=%02x secondary=0x%02x\n", | |
1305 priv->primary_language,priv->secondary_language); | |
1306 } | |
1307 | |
1308 /** | |
23899 | 1309 * \brief decodes raw vbi data (signal amplitudes) into sequence of bytes |
1310 * \param priv private data structure | |
1311 * \param buf raw vbi data (one line of frame) | |
1312 * \param data output buffer for decoded bytes (at least 45 bytes long) | |
1313 * | |
1314 * Used XawTV's algorithm. Signal phase is calculated with help of starting clock | |
1315 * run-in sequence (min/max values and bit distance values are calculated) | |
1316 */ | |
1317 static int decode_raw_line_runin(priv_vbi_t* priv,unsigned char* buf,unsigned char* data){ | |
1318 const int magic= 0x27; // reversed 1110010 | |
1319 int dt[256],hi[6],lo[6]; | |
1320 int i,x,r; | |
1321 int decoded; | |
1322 int sync; | |
1323 unsigned char min,max; | |
1324 int thr=0; //threshold | |
1325 | |
1326 //stubs | |
24099 | 1327 int soc=priv->soc; |
1328 int eoc=priv->eoc; | |
23899 | 1329 |
1330 for(i=soc;i<eoc;i++) | |
1331 dt[i]=buf[i+priv->bpb/ONE_FIXP]-buf[i]; // amplifies the edges best. | |
1332 /* set barrier */ | |
1333 for (i=eoc; i<eoc+16; i+=2) | |
1334 dt[i]=100, dt[i+1]=-100; | |
1335 | |
1336 /* find 6 rising and falling edges */ | |
1337 for (i=soc, x=0; x<6; ++x) | |
1338 { | |
1339 while (dt[i]<32) | |
1340 i++; | |
1341 hi[x]=i; | |
1342 while (dt[i]>-32) | |
1343 i++; | |
1344 lo[x]=i; | |
1345 } | |
1346 if (i>=eoc) | |
1347 { | |
1348 return 0; // not enough periods found | |
1349 } | |
1350 i=hi[5]-hi[1]; // length of 4 periods (8 bits) | |
1351 if (i<priv->bp8bl || i>priv->bp8bh) | |
1352 { | |
1353 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: wrong freq %d (%d,%d)\n", | |
1354 i,priv->bp8bl,priv->bp8bh); | |
1355 return 0; // bad frequency | |
1356 } | |
1357 /* AGC and sync-reference */ | |
1358 min=255, max=0, sync=0; | |
1359 for (i=hi[4]; i<hi[5]; ++i) | |
1360 if (buf[i]>max) | |
1361 max=buf[i], sync=i; | |
1362 for (i=lo[4]; i<lo[5]; ++i) | |
1363 if (buf[i]<min) | |
1364 min=buf[i]; | |
1365 thr=(min+max)/2; | |
1366 | |
1367 buf+=sync; | |
1368 // searching for '11' | |
1369 for(i=priv->pll_adj*priv->bpb/10;i<16*priv->bpb;i+=priv->bpb) | |
1370 if(buf[FIXP2INT(i)]>thr && buf[FIXP2INT(i+priv->bpb)]>thr) | |
1371 break; | |
1372 r=0; | |
1373 for(decoded=1; decoded<= (VBI_COLUMNS+3)<<3;decoded++){ | |
1374 r>>=1; | |
1375 if(buf[FIXP2INT(i)]>thr) r|=0x80; | |
1376 if(!(decoded & 0x07)){ | |
1377 data[(decoded>>3) - 1]=r; | |
1378 r=0; | |
1379 } | |
1380 i+=priv->bpb; | |
1381 } | |
1382 if(data[0]!=magic) | |
1383 return 0; //magic not found | |
1384 | |
1385 //stub | |
1386 for(i=0;i<43;i++){ | |
1387 data[i]=data[i+1]; | |
1388 } | |
1389 mp_msg(MSGT_TV,MSGL_DBG3,"thr:%d sync:%d ",thr,sync); | |
1390 | |
1391 return 1; | |
1392 } | |
1393 | |
24316 | 1394 #if 0 |
1395 //See comment in vbi_decode for a reason of commenting out this routine. | |
1396 | |
23899 | 1397 /** |
1398 * \brief decodes raw vbi data (signal amplitudes) into sequence of bytes | |
1399 * \param priv private data structure | |
1400 * \param buf raw vbi data (one line of frame) | |
1401 * \param data output buffer for decoded bytes (at least 45 bytes long) | |
1402 * | |
1403 * Used Michael Niedermayer's algorithm. | |
1404 * Signal phase is calculated using correlation between given samples data and | |
1405 * pure sine | |
1406 */ | |
1407 static int decode_raw_line_sine(priv_vbi_t* priv,unsigned char* buf,unsigned char* data){ | |
1408 int i,x,r,amp,xFixp; | |
1409 int avg=0; | |
1410 double sin_sum=0, cos_sum=0; | |
1411 | |
1412 for(x=0; x< FIXP2INT(10*priv->bpb); x++) | |
1413 avg+=buf[x]; | |
1414 | |
1415 avg/=FIXP2INT(10*priv->bpb); | |
1416 | |
1417 for(x=0; x<12; x++){ | |
1418 amp= buf[x<<1]; | |
1419 sin_sum+= si[x]*(amp-avg); | |
1420 cos_sum+= co[x]*(amp-avg); | |
1421 } | |
1422 //this is always zero. Why ? | |
1423 xFixp= atan(sin_sum/cos_sum)*priv->bpb/M_PI; | |
1424 | |
1425 //Without this line the result is full of errors | |
1426 //and routine is unable to find magic sequence | |
1427 buf+=FIXP2INT(10*priv->bpb); | |
1428 | |
1429 r=0; | |
1430 for(x=FIXP2INT(xFixp);x<70;x=FIXP2INT(xFixp)){ | |
1431 r=(r<<1) & 0xFFFF; | |
1432 if(buf[x]>avg) r|=1; | |
1433 xFixp+=priv->bpb; | |
1434 if(r==0xAAE4) break; | |
1435 } | |
1436 | |
1437 //this is not teletext | |
1438 if (r!=0xaae4) return 0; | |
1439 | |
1440 //Decode remaining 45-2(clock run-in)-1(framing code)=42 bytes | |
1441 for(i=1; i<=(42<<3); i++){ | |
1442 r>>=1; | |
1443 x=FIXP2INT(xFixp); | |
1444 if(buf[x]> avg) | |
1445 r|=0x80; | |
1446 | |
1447 if(!(i & 0x07)){ | |
1448 data[(i>>3)-1]=r; | |
1449 r=0; | |
1450 } | |
1451 xFixp+=priv->bpb; | |
1452 } | |
1453 | |
1454 return 1; | |
1455 } | |
24316 | 1456 #endif |
23899 | 1457 |
1458 /** | |
1459 * \brief decodes all vbi lines from one video frame | |
1460 * \param priv private data structure | |
1461 * \param buf buffer with raw vbi data in it | |
1462 * | |
1463 * \note buffer size have to be at least priv->ptsp->bufsize bytes | |
1464 */ | |
1465 static void vbi_decode(priv_vbi_t* priv,unsigned char*buf){ | |
1466 int magAddr; | |
1467 int pkt; | |
1468 unsigned char data[64]; | |
1469 unsigned char* linep; | |
1470 int d0,d1; | |
1471 int i=0; | |
1472 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: vbi_decode\n"); | |
24301
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
1473 for(linep=buf; !priv->cache_reset && linep<buf+priv->ptsp->bufsize; linep+=priv->ptsp->samples_per_line,i++){ |
23899 | 1474 #if 0 |
1475 /* | |
1476 This routine is alternative implementation of raw VBI data decoding. | |
24278 | 1477 Unfortunately, it detects only about 20% of incoming data, |
23899 | 1478 but Michael says that this algorithm is better, and he wants to fix it. |
1479 */ | |
1480 if(decode_raw_line_sine(priv,linep,data)<=0){ | |
1481 #endif | |
1482 if(decode_raw_line_runin(priv,linep,data)<=0){ | |
1483 continue; //this is not valid teletext line | |
1484 } | |
1485 d0= corrHamm48[ data[0] ]; | |
1486 d1= corrHamm48[ data[1] ]; | |
1487 | |
1488 if(d0&0x80 || d1&0x80){ | |
1489 pll_add(priv,2,4); | |
1490 mp_msg(MSGT_TV,MSGL_V,"vbi_decode(%d):HammErr after decode_raw_line\n",i); | |
1491 | |
1492 continue; //hamError | |
1493 } | |
1494 magAddr=d0 & 0x7; | |
1495 pkt=(d0>>3)|(d1<<1); | |
1496 mp_msg(MSGT_TV,MSGL_DBG3,"vbi_decode(%d):%x %x (mag:%x, pkt:%d)\n", | |
1497 i,d0,d1,magAddr,pkt); | |
1498 if(!pkt){ | |
1499 decode_pkt0(priv,data+2,magAddr); //skip MRGA | |
1500 }else if(pkt>0 && pkt<VBI_ROWS){ | |
1501 if(!priv->mag[magAddr].pt) continue; | |
1502 decode_pkt_page(priv,data+2,magAddr,pkt);//skip MRGA | |
24244 | 1503 }else if(pkt==27) { |
1504 decode_pkt27(priv,data+2,magAddr); | |
24290 | 1505 }else if(pkt==28){ |
1506 decode_pkt28(priv,data+2); | |
24232
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1507 }else if(pkt==30){ |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1508 decode_pkt30(priv,data+2,magAddr); |
23899 | 1509 } else { |
1510 mp_msg(MSGT_TV,MSGL_DBG3,"unsupported packet:%d\n",pkt); | |
1511 } | |
1512 } | |
24301
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
1513 if (priv->cache_reset){ |
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
1514 pthread_mutex_lock(&(priv->buffer_mutex)); |
24305
414b72437fe3
Increase number of skipped buffers to 5 to avoid mixing teletext pages from
voroshil
parents:
24301
diff
changeset
|
1515 priv->cache_reset--; |
24301
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
1516 pthread_mutex_unlock(&(priv->buffer_mutex)); |
15d547dfa66b
Make sure that no pages will left in cache during
voroshil
parents:
24296
diff
changeset
|
1517 } |
23899 | 1518 |
1519 } | |
1520 | |
1521 /* | |
1522 --------------------------------------------------------------------------------- | |
1523 Public routines | |
1524 --------------------------------------------------------------------------------- | |
1525 */ | |
1526 | |
1527 /** | |
1528 * \brief toggles teletext page displaying format | |
1529 * \param priv_vbi private data structure | |
1530 * \param flag new format | |
1531 * \return | |
1532 * TVI_CONTROL_TRUE is success, | |
1533 * TVI_CONTROL_FALSE otherwise | |
1534 * | |
1535 * flag: | |
1536 * 0 - opaque | |
1537 * 1 - transparent | |
1538 * 2 - opaque with black foreground color (only in bw mode) | |
1539 * 3 - transparent with black foreground color (only in bw mode) | |
1540 */ | |
1541 static int teletext_set_format(priv_vbi_t * priv, teletext_format flag) | |
1542 { | |
1543 flag&=3; | |
1544 | |
1545 mp_msg(MSGT_TV,MSGL_DBG3,"teletext_set_format_is called. mode:%d\n",flag); | |
1546 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1547 | |
1548 priv->tformat=flag; | |
1549 | |
1550 priv->pagenumdec=0; | |
1551 | |
1552 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
1553 return TVI_CONTROL_TRUE; | |
1554 } | |
1555 | |
1556 /** | |
1557 * \brief append just entered digit to editing page number | |
1558 * \param priv_vbi private data structure | |
1559 * \param dec decimal digit to append | |
1560 * | |
1561 * dec: | |
1562 * '0'..'9' append digit | |
1563 * '-' remove last digit (backspace emulation) | |
1564 * | |
1565 * This routine allows user to jump to arbitrary page. | |
1566 * It implements simple page number editing algorithm. | |
1567 * | |
1568 * Subsystem can be on one of two modes: normal and page number edit mode. | |
1569 * Zero value of priv->pagenumdec means normal mode | |
1570 * Non-zero value means page number edit mode and equals to packed | |
1571 * decimal number of already entered part of page number. | |
1572 * | |
1573 * How this works. | |
1574 * Let's assume that current mode is normal (pagenumdec is zero), teletext page | |
1575 * 100 are displayed as usual. topmost left corner of page contains page number. | |
1576 * Then vbi_add_dec is sequentially called (through slave | |
1577 * command of course) with 1,4,-,2,3 * values of dec parameter. | |
1578 * | |
1579 * +-----+------------+------------------+ | |
1580 * | dec | pagenumdec | displayed number | | |
1581 * +-----+------------+------------------+ | |
1582 * | | 0x000 | 100 | | |
1583 * +-----+------------+------------------+ | |
1584 * | 1 | 0x001 | __1 | | |
1585 * +-----+------------+------------------+ | |
1586 * | 4 | 0x014 | _14 | | |
1587 * +-----+------------+------------------+ | |
1588 * | - | 0x001 | __1 | | |
1589 * +-----+------------+------------------+ | |
1590 * | 2 | 0x012 | _12 | | |
1591 * +-----+------------+------------------+ | |
1592 * | 3 | 0x123 | 123 | | |
1593 * +-----+------------+------------------+ | |
1594 * | | 0x000 | 123 | | |
1595 * +-----+------------+------------------+ | |
1596 * | |
1597 * pagenumdec will automatically receive zero value after third digit of page | |
1598 * number is entered and current page will be switched to another one with | |
1599 * entered page number. | |
1600 */ | |
1601 static void vbi_add_dec(priv_vbi_t * priv, char *dec) | |
1602 { | |
1603 int count, shift; | |
1604 if (!dec) | |
1605 return; | |
1606 if (!priv->on) | |
1607 return; | |
1608 if ((*dec<'0' || *dec>'9') && *dec!='-') | |
1609 return; | |
1610 if (!priv->pagenumdec) //first digit cannot be '0','9' or '-' | |
1611 if(*dec=='-' || *dec=='0' || *dec=='9') | |
1612 return; | |
1613 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1614 count=(priv->pagenumdec>>12)&0xf; | |
1615 if (*dec=='-') { | |
1616 count--; | |
1617 if (count) | |
1618 priv->pagenumdec=((priv->pagenumdec>>4)&0xfff)|(count<<12); | |
1619 else | |
1620 priv->pagenumdec=0; | |
1621 } else { | |
1622 shift = count * 4; | |
1623 count++; | |
1624 priv->pagenumdec= | |
1625 (((priv->pagenumdec)<<4|(*dec-'0'))&0xfff)|(count<<12); | |
1626 if (count==3) { | |
1627 priv->pagenum=priv->pagenumdec&0x7ff; | |
1628 priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum); | |
1629 priv->pagenumdec=0; | |
1630 } | |
1631 } | |
1632 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
1633 } | |
1634 | |
1635 | |
1636 /** | |
1637 * \brief Teletext control routine | |
1638 * \param priv_vbi private data structure | |
1639 * \param cmd command | |
1640 * \param arg command parameter (has to be not null) | |
1641 */ | |
1642 int teletext_control(void* p, int cmd, void *arg) | |
1643 { | |
1644 int fine_tune=99; | |
1645 priv_vbi_t* priv=(priv_vbi_t*)p; | |
24244 | 1646 tt_page* pgc; |
23899 | 1647 |
1648 if (!priv && cmd!=TV_VBI_CONTROL_START) | |
1649 return TVI_CONTROL_FALSE; | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1650 if (!arg && cmd!=TV_VBI_CONTROL_STOP && cmd!=TV_VBI_CONTROL_MARK_UNCHANGED) |
23899 | 1651 return TVI_CONTROL_FALSE; |
1652 | |
1653 switch (cmd) { | |
1654 case TV_VBI_CONTROL_RESET: | |
1655 { | |
24290 | 1656 int i; |
23899 | 1657 tv_param_t* tv_param=arg; |
1658 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1659 priv->pagenumdec=0; | |
1660 clear_cache(priv); | |
1661 priv->pagenum=steppage(0,tv_param->tpage&0x7ff,1); | |
1662 priv->tformat=tv_param->tformat; | |
24293 | 1663 priv->subpagenum=0x3f7f; |
23899 | 1664 pll_reset(priv,fine_tune); |
24290 | 1665 if(tv_param->tlang==-1){ |
1666 mp_msg(MSGT_TV,MSGL_INFO,MSGTR_TV_TTSupportedLanguages); | |
1667 for(i=0; tt_languages[i].lang_code; i++){ | |
1668 mp_msg(MSGT_TV,MSGL_INFO," %3d %s\n", | |
1669 tt_languages[i].lang_code, tt_languages[i].lang_name); | |
1670 } | |
1671 mp_msg(MSGT_TV,MSGL_INFO," %3d %s\n", | |
1672 tt_languages[i].lang_code, tt_languages[i].lang_name); | |
1673 }else{ | |
1674 for(i=0; tt_languages[i].lang_code; i++){ | |
1675 if(tt_languages[i].lang_code==tv_param->tlang) | |
1676 break; | |
1677 } | |
1678 if (priv->primary_language!=tt_languages[i].lang_code){ | |
1679 mp_msg(MSGT_TV,MSGL_INFO,MSGTR_TV_TTSelectedLanguage, | |
1680 tt_languages[i].lang_name); | |
1681 priv->primary_language=tt_languages[i].lang_code; | |
1682 } | |
1683 } | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1684 priv->page_changed=1; |
23899 | 1685 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1686 return TVI_CONTROL_TRUE; | |
1687 } | |
1688 case TV_VBI_CONTROL_START: | |
1689 { | |
1690 int i; | |
1691 tt_stream_props* ptsp=*(tt_stream_props**)arg; | |
1692 | |
1693 if(!ptsp) | |
1694 return TVI_CONTROL_FALSE; | |
1695 | |
1696 priv=calloc(1,sizeof(priv_vbi_t)); | |
1697 | |
1698 priv->ptsp=malloc(sizeof(tt_stream_props)); | |
1699 memcpy(priv->ptsp,ptsp,sizeof(tt_stream_props)); | |
1700 *(priv_vbi_t**)arg=priv; | |
1701 | |
24293 | 1702 priv->subpagenum=0x3f7f; |
23899 | 1703 pthread_mutex_init(&priv->buffer_mutex, NULL); |
1704 priv->pagenumdec=0; | |
1705 for(i=0;i<VBI_ROWS*VBI_COLUMNS;i++) | |
1706 priv->display_page[i]=tt_space; | |
1707 | |
1708 priv->mag=calloc(8,sizeof(mag_t)); | |
1709 init_cache(priv); | |
1710 init_vbi_consts(priv); | |
1711 pll_reset(priv,fine_tune); | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1712 priv->page_changed=1; |
23899 | 1713 return TVI_CONTROL_TRUE; |
1714 } | |
1715 case TV_VBI_CONTROL_STOP: | |
1716 { | |
1717 if(priv->mag) | |
1718 free(priv->mag); | |
1719 if(priv->ptsp) | |
1720 free(priv->ptsp); | |
1721 destroy_cache(priv); | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1722 priv->page_changed=1; |
23899 | 1723 free(priv); |
1724 return TVI_CONTROL_TRUE; | |
1725 } | |
1726 case TV_VBI_CONTROL_SET_MODE: | |
1727 priv->on=(*(int*)arg%2); | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1728 priv->page_changed=1; |
23899 | 1729 return TVI_CONTROL_TRUE; |
1730 case TV_VBI_CONTROL_GET_MODE: | |
1731 *(int*)arg=priv->on; | |
1732 return TVI_CONTROL_TRUE; | |
1733 case TV_VBI_CONTROL_SET_FORMAT: | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1734 priv->page_changed=1; |
23899 | 1735 return teletext_set_format(priv, *(int *) arg); |
1736 case TV_VBI_CONTROL_GET_FORMAT: | |
1737 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1738 *(int*)arg=priv->tformat; | |
1739 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
1740 return TVI_CONTROL_TRUE; | |
1741 case TV_VBI_CONTROL_GET_HALF_PAGE: | |
1742 if(!priv->on) | |
1743 return TVI_CONTROL_FALSE; | |
1744 *(int *)arg=priv->zoom; | |
1745 return TVI_CONTROL_TRUE; | |
1746 case TV_VBI_CONTROL_SET_HALF_PAGE: | |
1747 { | |
1748 int val=*(int*)arg; | |
1749 val%=3; | |
1750 if(val<0) | |
1751 val+=3; | |
1752 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1753 priv->zoom=val; | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1754 priv->page_changed=1; |
23899 | 1755 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1756 return TVI_CONTROL_TRUE; | |
1757 } | |
24244 | 1758 case TV_VBI_CONTROL_GO_LINK: |
1759 { | |
1760 int val=*(int *) arg; | |
1761 if(val<1 || val>6) | |
1762 return TVI_CONTROL_FALSE; | |
1763 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1764 if (!(pgc = priv->ptt_cache[priv->pagenum])) { | |
1765 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
1766 return TVI_CONTROL_FALSE; | |
1767 } | |
1768 if (!pgc->links[val-1].pagenum || pgc->links[val-1].pagenum>0x7ff) { | |
1769 pthread_mutex_unlock(&(priv->buffer_mutex)); | |
1770 return TVI_CONTROL_FALSE; | |
1771 } | |
1772 priv->pagenum=pgc->links[val-1].pagenum; | |
1773 if(pgc->links[val-1].subpagenum!=0x3f7f) | |
1774 priv->subpagenum=pgc->links[val-1].subpagenum; | |
1775 else | |
1776 priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum); | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1777 priv->page_changed=1; |
24244 | 1778 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1779 return TVI_CONTROL_TRUE; | |
1780 } | |
23899 | 1781 case TV_VBI_CONTROL_SET_PAGE: |
1782 { | |
1783 int val=*(int *) arg; | |
1784 if(val<100 || val>0x899) | |
1785 return TVI_CONTROL_FALSE; | |
1786 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1787 priv->pagenum=val&0x7ff; | |
1788 priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum); | |
1789 priv->pagenumdec=0; | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1790 priv->page_changed=1; |
23899 | 1791 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1792 return TVI_CONTROL_TRUE; | |
1793 } | |
1794 case TV_VBI_CONTROL_STEP_PAGE: | |
1795 { | |
1796 int direction=*(int *) arg; | |
1797 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1798 priv->pagenum=steppage(priv->pagenum, direction,1); | |
1799 priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum); | |
1800 priv->pagenumdec=0; | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1801 priv->page_changed=1; |
23899 | 1802 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1803 return TVI_CONTROL_TRUE; | |
1804 } | |
1805 case TV_VBI_CONTROL_GET_PAGE: | |
1806 *(int*)arg=((priv->pagenum+0x700)&0x7ff)+0x100; | |
1807 return TVI_CONTROL_TRUE; | |
1808 case TV_VBI_CONTROL_SET_SUBPAGE: | |
1809 pthread_mutex_lock(&(priv->buffer_mutex)); | |
1810 priv->pagenumdec=0; | |
1811 priv->subpagenum=*(int*)arg; | |
1812 if(priv->subpagenum<0) | |
24293 | 1813 priv->subpagenum=0x3f7f; |
23899 | 1814 if(priv->subpagenum>=VBI_MAX_SUBPAGES) |
1815 priv->subpagenum=VBI_MAX_SUBPAGES-1; | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1816 priv->page_changed=1; |
23899 | 1817 pthread_mutex_unlock(&(priv->buffer_mutex)); |
1818 return TVI_CONTROL_TRUE; | |
1819 case TV_VBI_CONTROL_GET_SUBPAGE: | |
1820 *(int*)arg=priv->subpagenum; | |
1821 return TVI_CONTROL_TRUE; | |
1822 case TV_VBI_CONTROL_ADD_DEC: | |
1823 vbi_add_dec(priv, *(char **) arg); | |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1824 priv->page_changed=1; |
23899 | 1825 return TVI_CONTROL_TRUE; |
1826 case TV_VBI_CONTROL_DECODE_PAGE: | |
1827 vbi_decode(priv,*(unsigned char**)arg); | |
1828 return TVI_CONTROL_TRUE; | |
1829 case TV_VBI_CONTROL_GET_VBIPAGE: | |
1830 if(!priv->on) | |
1831 return TVI_CONTROL_FALSE; | |
1832 prepare_visible_page(priv); | |
1833 *(void **)arg=priv->display_page; | |
1834 return TVI_CONTROL_TRUE; | |
24232
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1835 case TV_VBI_CONTROL_GET_NETWORKNAME: |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1836 *(void **)arg=priv->networkname; |
d0290b80e612
Implement 8/30 format 1 teletext packet decoding
voroshil
parents:
24197
diff
changeset
|
1837 return TVI_CONTROL_TRUE; |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1838 case TV_VBI_CONTROL_MARK_UNCHANGED: |
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1839 priv->page_changed=0; |
24345 | 1840 priv->last_rendered=GetTimerMS(); |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1841 return TVI_CONTROL_TRUE; |
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1842 case TV_VBI_CONTROL_IS_CHANGED: |
24345 | 1843 if(GetTimerMS()-priv->last_rendered> 250) //forcing page update every 1/4 sec |
24342
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1844 priv->page_changed=3; //mark that header update is enough |
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1845 *(int*)arg=priv->page_changed; |
8873c972c6aa
Decrease teletext page rendering frequency from 1/frame to about 4/sec.
voroshil
parents:
24316
diff
changeset
|
1846 return TVI_CONTROL_TRUE; |
23899 | 1847 } |
1848 return TVI_CONTROL_UNKNOWN; | |
1849 } |