]> git.vomp.tv Git - vompclient.git/blob - wwss.cc
Demuxer::scanForVideo()
[vompclient.git] / wwss.cc
1 /*\r
2     Copyright 2006 Chris Tallon\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 */\r
20 \r
21 #include "wwss.h"\r
22 \r
23 Wwss::Wwss()\r
24 {\r
25   format = Video::NTSC;\r
26 }\r
27 \r
28 Wwss::~Wwss()\r
29 {\r
30 }\r
31 \r
32 void Wwss::setFormat(UCHAR tformat)\r
33 {\r
34   format = tformat;\r
35 }\r
36 \r
37 UINT Wwss::gcd(UINT a, UINT b)\r
38 {\r
39   UINT t;\r
40   while (b != 0)\r
41   {\r
42     t = b;\r
43     b = a % b;\r
44     a = t;\r
45   }\r
46   return a;\r
47 }\r
48 \r
49 UINT Wwss::lcm(UINT a, UINT b)\r
50 {\r
51   return (a / gcd(a, b)) * b;\r
52 }\r
53 \r
54 void Wwss::setWide(bool twide)\r
55 {\r
56   wide = twide;\r
57 }\r
58 \r
59 void Wwss::draw()\r
60 {\r
61   if (format == Video::PAL) drawPAL();\r
62 //  else if (format == Video::NTSC) drawNTSC();\r
63 }\r
64 \r
65 void Wwss::drawPAL()\r
66 {\r
67   // The aspect43 and aspect169 codes are not what they should be according to the docs, but these are what work...\r
68   // (1 = 111000, = 0 000111)\r
69   static UCHAR runIn[]     = {1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1};                       // 29 pos 0\r
70   static UCHAR startCode[] = {0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1};                                 // 24 pos 29\r
71   static UCHAR aspect43[]  = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0}; // = 0001   4:3 full frame      // 24 pos 53\r
72   static UCHAR aspect169[] = {1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1}; // = 1110   16:9 anamorphic     // 24 pos 53\r
73   static UCHAR theRest[]   = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,                                  // 60 pos 77\r
74                               0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,\r
75                               0,0,0,1,1,1,0,0,0,1,1,1};\r
76   /*\r
77   Real PAL pixel frequency: 13.5 MHz\r
78   WSS element frequency: 5 MHz\r
79   = 2.7 pal pixels per wss element\r
80   * 137 wss elements = 369.9 pal pixels (total code width) (round to 370..)\r
81 \r
82   There is also a 11us gap at the start of the pal raster, but since I don't really have any\r
83   idea where our 720 pixels start in the raster I can't calculate an offset.\r
84 \r
85   PAL line 23 seems to be MVP line 6.\r
86   */\r
87 \r
88   const UINT   Ns = 137;           // Num pix src\r
89   const UINT   Nd = 370;           // Num pix dst         359->395 does something. not the right thing, but something.\r
90   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm\r
91   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)\r
92   UINT         Sd = Nl / Nd;       // Dst split\r
93   UCHAR src[Ns];\r
94 \r
95   memcpy(&src[0], runIn, 29);\r
96   memcpy(&src[29], startCode, 24);\r
97   if (wide) memcpy(&src[53], aspect169, 24);\r
98   else      memcpy(&src[53], aspect43, 24);\r
99   memcpy(&src[77], theRest, 60);\r
100 \r
101   float dst[Nd];\r
102   UINT lcmpxbase = 0;\r
103 \r
104   for(UINT t = 0; t < Nd; t++) // for every destination pixel\r
105   {\r
106     dst[t] = 0;\r
107     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)\r
108     {\r
109       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;\r
110     }\r
111     lcmpxbase += Sd;\r
112   }\r
113 \r
114   Colour c;\r
115   UINT value;\r
116   for(UINT q = 0; q < Nd; q++)\r
117   {\r
118     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value\r
119     c.set(value, value, value);\r
120     drawPixel(q, 6, c);\r
121   }\r
122 }\r
123 \r
124 void Wwss::drawNTSC()\r
125 {\r
126   static UCHAR startCode[] = {1,0};\r
127   static UCHAR aspect43[]  = {0,0};\r
128   static UCHAR aspect169[] = {1,0};\r
129   static UCHAR theRest[]   = {0,0,0,0,0,0,0,0,0,0,0,0};\r
130   static UCHAR crc43[]     = {0,0,0,0,0,0};\r
131   static UCHAR crc169[]    = {1,0,0,1,0,1};\r
132 \r
133   /*\r
134   Real NTSC pixel frequency: 13.5 MHz\r
135   WSS bit frequency: 447.443125 kHz\r
136   = 30.1714 NTSC pixels per wss bit\r
137   * 22 wss bits = 663.7715 NTSC pixels (total code width) (round to 664..)\r
138 \r
139   There is also a 11.2us gap at the start of the pal raster, but since I don't really have any\r
140   idea where our 720 pixels start in the raster I can't calculate an offset.\r
141 \r
142   PAL line 23 seems to be MVP line 6.\r
143   */\r
144 \r
145   const UINT   Ns = 22;            // Num pix src\r
146   const UINT   Nd = 664;           // Num pix dst\r
147   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm\r
148   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)\r
149   UINT         Sd = Nl / Nd;       // Dst split\r
150   UCHAR src[Ns];\r
151 \r
152   memcpy(&src[0], startCode, 2);\r
153   if (wide) memcpy(&src[2], aspect169, 2);\r
154   else      memcpy(&src[2], aspect43, 2);\r
155   memcpy(&src[4], theRest, 12);\r
156   if (wide) memcpy(&src[16], crc169, 6);\r
157   else      memcpy(&src[16], crc43, 6);\r
158 \r
159   float dst[Nd];\r
160   UINT lcmpxbase = 0;\r
161 \r
162   for(UINT t = 0; t < Nd; t++) // for every destination pixel\r
163   {\r
164     dst[t] = 0;\r
165     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)\r
166     {\r
167       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;\r
168     }\r
169     lcmpxbase += Sd;\r
170   }\r
171 \r
172   Colour c;\r
173   UINT value;\r
174 \r
175 /*\r
176   for(UINT q = 0; q < Nd; q++)\r
177   {\r
178     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value\r
179     c.set(value, value, value);\r
180     drawPixel(q, 6, c);\r
181   }\r
182 */\r
183 \r
184 for(int yy = 0; yy < 100; yy++)\r
185 {\r
186   for(UINT q = 0; q < Nd; q++)\r
187   {\r
188     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value\r
189     c.set(value, value, value);\r
190     drawPixel(q+20, yy, c);\r
191   }\r
192 }\r
193 \r
194 \r
195 \r
196 }\r
197 \r
198 /*\r
199 x6 + x + 1\r
200 \r
201 1x6 + 0x5 + 0x4 + 0x3 + 0x2 + 1x1 + 1x0\r
202 =\r
203 1      0     0     0     0     1     1\r
204 =\r
205 1000011\r
206 key width = 6\r
207 \r
208 static UCHAR startCode[] = {1,0};\r
209 static UCHAR aspect43[]  = {0,0};\r
210 static UCHAR aspect169[] = {1,0};\r
211 static UCHAR theRest[]   = {0,0,0,0,0,0,0,0,0,0,0,0};\r
212 static UCHAR crc43[]     = {0,0,0,0,0,0};\r
213 static UCHAR crc169[]    = {1,0,0,1,0,1};\r
214 \r
215 Message 4:3\r
216 \r
217 1000000000000000\r
218 \r
219 Message 4:3 augmented\r
220 \r
221 1000000000000000000000\r
222 \r
223 Key\r
224 \r
225 1000011\r
226 \r
227 \r
228 Ho ho, polynomial long division. Yeeeeaaahhh I remember\r
229 doing *that*. Of course I do. If you know of a faster,\r
230 easier, more reliable way of doing this, please let me know.\r
231 \r
232 \r
233                  100\r
234          ________________________\r
235 1000011  ) 1000000000000000000000\r
236            1000011\r
237            -------\r
238             0000110\r
239             0000000\r
240             -------\r
241              0001100\r
242 \r
243 \r
244 \r
245 \r
246 \r
247 \r
248 Message 16:9\r
249 \r
250 1010000000000000\r
251 \r
252 Message 4:3 augmented\r
253 \r
254 1010000000000000000000\r
255 \r
256 Key\r
257 \r
258 1000011\r
259 \r
260                  1010011110100011\r
261          ________________________\r
262 1000011  ) 1010000000000000000000\r
263            1000011\r
264             -------\r
265             0100110\r
266             0000000\r
267              -------\r
268              1001100\r
269              1000011\r
270               -------\r
271               0011110\r
272               0000000\r
273                -------\r
274                0111100\r
275                0000000\r
276                 -------\r
277                 1111000\r
278                 1000011\r
279                  -------\r
280                  1110110\r
281                  1000011\r
282                   -------\r
283                   1101010\r
284                   1000011\r
285                    -------\r
286                    1010010\r
287                    1000011\r
288                     -------\r
289                     0100010\r
290                     0000000\r
291                      -------\r
292                      1000100\r
293                      1000011\r
294                       -------\r
295                       0001110\r
296                       0000000\r
297                        -------\r
298                        0011100\r
299                        0000000\r
300                         -------\r
301                         0111000\r
302                         0000000\r
303                          -------\r
304                          1110000\r
305                          1000011\r
306                           -------\r
307                           1100110\r
308                           1000011\r
309                           -------\r
310                            100101\r
311 */\r