├── .gitignore ├── CMakeLists.txt ├── ChangeLog ├── README ├── README.md ├── chanidents ├── crc32.c ├── doc ├── concept.md └── references.md ├── dvb_info_tables.c ├── dvb_text.c ├── dvb_text_iconv.c ├── etc └── dvb_channel.conf ├── iso_639.awk ├── iso_639.tab ├── iso_639.xsl ├── lookup.c ├── patches ├── README ├── subtitle-char.patch └── subtitle-pct.patch ├── samples ├── channels.conf ├── cts.xml ├── ctv.xml ├── ftv.xml ├── pts.xml ├── ptshd.xml └── ttv.xml ├── si_tables.h ├── tv_grab_dvb.1 ├── tv_grab_dvb.c ├── tv_grab_dvb.h └── tv_grab_dvb.spec /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | 19 | tags 20 | CMakeCache.txt 21 | CMakeFiles/ 22 | cmake_install.cmake 23 | langidents.c 24 | Makefile 25 | 26 | epgrab 27 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(EPGrab) 3 | add_definitions("-Wall -O2 -g") 4 | 5 | execute_process(COMMAND awk -f iso_639.awk iso_639.tab 6 | OUTPUT_VARIABLE langidents.c) 7 | 8 | file(WRITE langidents.c "${langidents.c}") 9 | 10 | add_executable(epgrab crc32.c lookup.c dvb_info_tables.c dvb_text_iconv.c langidents.c tv_grab_dvb.c) 11 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | ========================================================================== 2 | tv_grab_dvb 0.10 Released ??/??/2007 3 | ========================================================================== 4 | 02/04/2007 Philipp Hahn 0.10 5 | * Add -i option for reading from file or custom demultiplex devices 6 | * Add -f option for writing to file instead of stdout 7 | * Support different character encodings 8 | * Translate 3 letter languages to 2 letter language IDs 9 | * Improved efficiency: Cache files in memory. 10 | 11 | 10/03/2008 Tero Pelander 12 | * Add -s option to make program silent 13 | * make the output obey xmltv.dtd 14 | 15 | ========================================================================== 16 | tv_grab_dvb 0.9 Released 07/09/2004 17 | ========================================================================== 18 | 26/08/2004 Jon Dye 0.9 19 | * Fixed Stupid 20 vs 0x20 typo - I'm sure that was there before.. 20 | * Updated chanids with a load more. 21 | * Supplied a UK subtitle info patch, char based see patches/ 22 | 23 | 20/08/2004 John Pullan 24 | * Supplied a UK subtitle info patch, % based see patches/ 25 | 26 | 27 | ========================================================================== 28 | tv_grab_dvb 0.8 Released 15/07/2004 29 | ========================================================================== 30 | 15/07/2004 Mark Bryars 0.8 31 | * Added -m -n -p options for various now next selections 32 | * Added -s for no status output 33 | * Added time offset function to manipulate the output dates 34 | Thanks to Andreas Witte for the 35 | pestering emails and the german date patch which i modified. 36 | 37 | 06/06/2005 Nick Craig-Wood 38 | * XMLIFY patch to output correct xml for all symbols 39 | (dont die on <'s or >'s) 40 | 41 | ========================================================================== 42 | tv_grab_dvb 0.6 Released 23/05/2004 43 | ========================================================================== 44 | 23/05/2004 Mark Bryars 0.6 45 | * Added -O2 -Wall to compilation, fixed warnings. 46 | * Reformatted ChangeLog to try and make it the standard format 47 | 48 | 21/05/2004 Nick Craig-Wood 49 | * Identify XML as ISO-8859-1 (latin1) rather than UTF8. Pound signs 50 | etc blow up the XML parser if you identify as UTF8 51 | * Aspect ratios should have colons not slashes according to XMLTV 52 | * Don't ever output control characters (some of these creep in the 53 | descriptions - CTRL-R in particular - don't know why! - and they 54 | confuse the XML parser) 55 | * Don't output empty descriptions (saves a warning from XMLTV) 56 | * Only output the first video or audio tag (XMLTV can't cope 57 | with more than one) 58 | * Make sure all tags are output in the right order 59 | 60 | 11/05/2004 Mark Bryars 61 | * xmlify the channel name too, cheers Chris Birkinshaw for 62 | pointing out the DiscoveryH&L breakage. 63 | * Added 'Drama' code for UK Freeview EPG content description. 64 | 65 | ========================================================================== 66 | tv_grab_dvb 0.5 Released 08/05/2004 67 | ========================================================================== 68 | 69 | 08/05/2004 Mark Bryars 0.5 70 | * Fixed time output to be in local time. 71 | * Fixed decoding of UK 7/8 day epg 72 | * Bad date redefined to be before 24hrs ago and after 2 weeks from now 73 | * Documented option -d to parse bad date packets 74 | * Disabled default output of updates to stop duplicates 75 | ( option -u to reenable output) 76 | 77 | 07/05/2004 Steve Davies 78 | * Improved memory management patch for xmlify routine 79 | 80 | ========================================================================== 81 | tv_grab_dvb 0.3 Released 30/04/2004 82 | ========================================================================== 83 | 84 | 30/04/2004 Mark Bryars 0.3 85 | * Ignore bad dates in the output (if end time was before now, discard) 86 | * Added comprehensive event decoding info 87 | * Added aspect information 88 | * Added audio information 89 | * Still havent fixed the timezone thing. 90 | 91 | ========================================================================== 92 | tv_grab_dvb 0.2 Released 20/04/2004 93 | ========================================================================== 94 | 95 | 20/04/2004 Mark Bryars 0.2 96 | * tv_grab_dvb: Initial Public Release 97 | 98 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | tv_grab_dvb - dump dvb epg info in xmltv 3 | 4 | 5 | 6 | Please Email me with [DVBEPG] in subject to filter out spam 7 | - Copyright (C) 2004 Mark Bryars 8 | 9 | DVB code Mercilessly ripped off from dvbdate 10 | 11 | NEWS 12 | ---- 13 | 15/07/2004 - Ver 0.8 Released 14 | 15 | Restrict to now next options added for current/other multiplexes. 16 | Status info is disablablable for more silent operation 17 | Time Offset chan be changed by an option now 18 | A Patch by Nick again for channel ident rewriting for interoperation 19 | with other xmltv sources.. 20 | 21 | 22 | 23/05/2004 - Ver 0.6 Released 23 | 24 | This consists mostly of a patch from Nick Craig-Wood to make output 25 | more compliant with XML and the XMLTV dtd, with the correct tag 26 | ordering, etc. Cheers! 27 | 28 | View [1]ChangeLog For Detail 29 | 30 | 31 | 08/05/2004 - Ver 0.5 Released 32 | 33 | First fairly usable release, with correct time information! 34 | I've only had UK testers report back so far with this release 35 | Thanks to Steve Davies and Mark Kendall for their helpful suggestions 36 | and testing with the London 8 day EPG broadcast test. 37 | 38 | If you are getting any Unknown ID:?? in your output, let me know 39 | if you know what this should be. In the UK we seem to be getting 40 | a lot of 'f0' which I can't find out what they are meant to be. 41 | Eastenders seems to be categorised with it, but so does a range 42 | of murder mystery things. Update: It appears to be Drama 43 | Let me know anything else please. 44 | 45 | 46 | 47 | CHANGES 48 | ------- 49 | 50 | [2]View ChangeLog 51 | 52 | 53 | DOWNLOAD 54 | -------- 55 | 56 | [3]http://www.darkskiez.co.uk/tv_grab_dvb-0.6.tgz 57 | 58 | 59 | REQUIREMENTS 60 | ------------ 61 | 62 | * DVB Card Working in linux already, and tuned to a multiplex. 63 | 64 | USAGE 65 | ----- 66 | 67 | It reads a channels.conf file [cst]zap format in the current directory to 68 | decode the channel names (at the moment) 69 | May not always need this. 70 | 71 | Tested with: 72 | UK Freeview Now/Next 73 | UK London 8 Day EPG test 74 | Germany/Berlin DVB-T Now/Next 75 | Sweden DVB-S 76 | Let Me Know! 77 | 78 | Tune into a multiplex with whatever you like, dvbtune, mplayer, mythtv and run: 79 | 80 | tv_grab_dvb [-t timeout] > whatson.xml 81 | 82 | HINTS 83 | ----- 84 | 85 | Mythtv: 86 | 87 | tv_grab_dvb|mythfilldatabase --no-delete --file 1 0 - 88 | 89 | Works well for me to stop it messing about all the channels. 90 | 91 | DEBUGGING 92 | --------- 93 | dvbsnoop -s sec 18 -b -n 200 > EIT.bin 94 | tv_garb_dvb -i EIT.bin -f EIT.xmltv 95 | 96 | TODO 97 | ---- 98 | 99 | * Allow specifying path to channels.conf 100 | * Decode Subtitle info in XMLTV Style - 0.6 DTD? 101 | * Decode Channel names from broadcast 102 | 103 | DONE 104 | ---- 105 | 106 | * Do proper XML encoding of text. - nearly 107 | * Allow mapping to existing xmltv id. - thanks nick 108 | * use iconv to correctly output descriptions 109 | * Allow specifying the DVB card 110 | + more 111 | 112 | LICENSE 113 | ------- 114 | This program is free software; you can redistribute it and/or 115 | modify it under the terms of the GNU General Public License 116 | as published by the Free Software Foundation; either version 2 117 | of the License, or (at your option) any later version. 118 | 119 | This program is distributed in the hope that it will be useful, 120 | but WITHOUT ANY WARRANTY; without even the implied warranty of 121 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 122 | GNU General Public License for more details. 123 | 124 | You should have received a copy of the GNU General Public License 125 | along with this program; if not, write to the Free Software 126 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 127 | Or, point your browser to http://www.gnu.org/copyleft/gpl.html 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EPGrab 2 | 3 | Grab DVB EPG data, output to XMLTV format. 4 | 5 | EPGrab is a fork of `tv_grab_dvb` from http://bryars.eu/projects/tv_grab_dvb/ 6 | 7 | ## Minimum Requirements 8 | 9 | * A Linux supported DVB receiver device, see: http://www.linuxtv.org/wiki/index.php/Hardware_Device_Information 10 | * Have `v4l-utils` (https://git.linuxtv.org/v4l-utils.git/) installed on your system. 11 | 12 | ## Build 13 | 14 | I do use CMake build system: 15 | 16 | * cmake . 17 | * make 18 | 19 | ## Run 20 | 21 | You have to use `dvbv5-zap` in `v4l-utils` to set up your DVB receiver. Before that, use `dvbv5-scan` to generate a channels list file. 22 | 23 | For instance: 24 | 25 | dvbv5-zap -c ./etc/dvb_channel.conf "客家電視" 26 | 27 | Then you can run EPGrab's executable file `epgrab` to grab DVB EPG data. 28 | 29 | ## License 30 | 31 | This program is free software: you can redistribute it and/or modify 32 | it under the terms of the GNU General Public License as published by 33 | the Free Software Foundation, either version 3 of the License, or 34 | (at your option) any later version. 35 | 36 | This program is distributed in the hope that it will be useful, 37 | but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39 | GNU General Public License for more details. 40 | 41 | You should have received a copy of the GNU General Public License 42 | along with this program. If not, see . 43 | -------------------------------------------------------------------------------- /chanidents: -------------------------------------------------------------------------------- 1 | 8 start.premiere.de 2 | 9 4.premiere.de 3 | 10 1.premiere.de 4 | 11 2.premiere.de 5 | 12 animalplanet.discoveryeurope.com 6 | 13 history.discovery.com 7 | 14 discoveryeurope.com 8 | 16 serie.premiere.de 9 | 17 premspo.premiere.de 10 | 18 direkt.premiere.de 11 | 19 junior.tv 12 | 20 filmfest.premiere.de 13 | 21 beate-uhse.tv 14 | 22 heimatkanal.de 15 | 23 krimi.premiere.de 16 | 24 classica.de 17 | 28 jetixtv.de 18 | 34 disney.com 19 | 36 scifi.premiere.de 20 | 41 classics.premiere.de 21 | 42 13thstreet.nbc.com 22 | 43 3.premiere.de 23 | 129 premiere.de#hd 24 | 130 discovery.com#hd 25 | 515 mgm.tv 26 | 516 nostalgie.premiere.de 27 | 900 dsf.com 28 | 616 sailingchannel.skytv.it 29 | 617 espnclassicsport.com 30 | 618 extreme.com 31 | 1300 www.raiuno.rai.it 32 | 1350 www.raiduo.rai.it 33 | 1400 www.raitre.rai.it 34 | 1550 trt.net.tr 35 | 2600 euronews.net#Italy 36 | 2650 euronews.net#Spain 37 | 2700 euronews.net#Russia 38 | 2710 euronews.net#Portugese 39 | 2720 euronews.net#French 40 | 2730 euronews.net#English 41 | 4173 east.bbc1.bbc.co.uk 42 | 4175 midlands.bbc1.bbc.co.uk 43 | 4237 east.bbc2.bbc.co.uk 44 | 4239 midlands.bbc2.bbc.co.uk 45 | 4415 news-24.bbc.co.uk 46 | 4671 cbbc.bbc.co.uk 47 | 8258 anglia.tv.co.uk 48 | 8283 yorkshire.granadatv.co.uk 49 | 8322 itv2.itv.co.uk 50 | 8347 itv2.itv.co.uk 51 | 8384 channel4.com 52 | 8454 uk-food.flextech.telewest.co.uk 53 | 8578 itn.co.uk 54 | 8604 itn.co.uk 55 | 8800 price-drop.tv 56 | 12003 rtl.de 57 | 12020 rtl2.de 58 | 12040 superrtl.de 59 | 12060 vox.de 60 | 12080 rtl-shop.de 61 | 12090 n-tv.de 62 | 17500 sat1.de 63 | 17501 prosieben.de 64 | 17502 kabel1.de 65 | 17503 n24.de 66 | 17504 neunlive.de 67 | 12866 channel5.co.uk 68 | 12886 channel5.co.uk 69 | 13120 qvcuk.com 70 | 14272 bid-up.tv 71 | 14336 radio-1.bbc.co.uk 72 | 14400 radio-2.bbc.co.uk 73 | 14464 radio-3.bbc.co.uk 74 | 14528 fm.radio-4.bbc.co.uk 75 | 15040 uk.cartoonnetwork.com 76 | 15168 discoveryeurope.com 77 | 15552 uk-gold.flextech.telewest.co.uk 78 | 16832 knowledge.bbc.co.uk 79 | 16960 cbeebies.bbc.co.uk 80 | 17920 radio-5.bbc.co.uk 81 | 17984 sportsextra.radio-5.bbc.co.uk 82 | 18048 6music.bbc.co.uk 83 | 18112 bbc7.bbc.co.uk 84 | 18176 1xtra.bbc.co.uk 85 | 18240 asian-network.bbc.co.uk 86 | 22080 sky-news.sky.com 87 | 22144 news.sports.sky.com 88 | 22208 travel.sky.co.uk 89 | 22272 ukhistory.tv 90 | 25664 the-hits.emap.com 91 | 25728 tmf.nl 92 | 25792 ukbrightideas.tv 93 | 26176 kiss-tv.kiss100.com 94 | 26240 smashhits.net 95 | 26304 kerrang.com 96 | 26368 jazzfm.com 97 | 26496 world-svc.bbc.com 98 | 26624 magictv.co.uk 99 | 26688 q4music.com 100 | 28006 zdf.de 101 | 28007 3sat.de 102 | 28008 kika.de 103 | 28011 infokanal.zdf.de 104 | 28012 dkultur.zdf.de 105 | 28013 dlf.zdf.de 106 | 28014 dokukanal.zdf.de 107 | 28016 theater.zdf.de 108 | 28017 dok_deb.zdf.de 109 | 28106 ard.de 110 | 28107 3.br-online.de 111 | 28108 hr-online.de 112 | 28109 arte-tv.de 113 | 28111 wdr.de 114 | 28112 alpha.br-online.de 115 | 28113 swr.de 116 | 28114 phoenix.de 117 | 28130 test-r.ard.de 118 | 28201 einsextra.ard.de 119 | 28202 einsfestival.ard.de 120 | 28203 einsplus.ard.de 121 | 28204 mdr.de 122 | 28205 rbb-online.de#brandenburg 123 | 28206 rbb-online.de#berlin 124 | 28207 kultur.ndr.de 125 | 28208 figaro.mdr.de 126 | 28210 2.hr-online.de 127 | 28211 info.mdr.de 128 | 28212 sputnik 129 | 28213 bayern 4 klassik 130 | 28214 2.swr.de 131 | 28215 3.wdr.de 132 | 28216 5.wdr.de 133 | 28218 ard-online-kanal 134 | 28221 test1.ard.de 135 | 28222 test2.ard.de 136 | 28224 ndr.de#mv 137 | 28225 ndr.de#hh 138 | 28226 ndr.de#nds 139 | 28227 ndr.de#sh 140 | 28228 mdr.de#sachsen 141 | 28229 mdr.de#s-anhalt 142 | 28230 mdr.de#thueringen 143 | 28231 swr.de#rp 144 | 28485 radio-bremen-tv.de 145 | 28486 sr.de 146 | 28250 mhp-data.ard.de 147 | -------------------------------------------------------------------------------- /crc32.c: -------------------------------------------------------------------------------- 1 | /* crc32.c: CRC32 routine 2 | */ 3 | #include 4 | #include 5 | 6 | static const uint32_t crc_table[256] = { 7 | 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 8 | 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 9 | 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 10 | 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 11 | 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 12 | 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 13 | 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 14 | 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 15 | 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 16 | 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 17 | 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 18 | 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 19 | 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 20 | 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 21 | 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 22 | 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 23 | 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 24 | 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 25 | 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 26 | 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 27 | 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 28 | 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 29 | 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 30 | 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 31 | 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 32 | 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 33 | 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 34 | 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 35 | 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 36 | 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 37 | 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 38 | 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 39 | 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 40 | 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 41 | 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 42 | 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 43 | 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 44 | 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 45 | 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 46 | 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 47 | 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 48 | 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 49 | 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 50 | }; 51 | 52 | uint32_t _dvb_crc32(const uint8_t *data, size_t len) 53 | { 54 | int i; 55 | uint32_t crc = 0xffffffff; 56 | 57 | for (i = 0; i < len; i++) 58 | crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff]; 59 | 60 | return crc; 61 | } 62 | -------------------------------------------------------------------------------- /doc/concept.md: -------------------------------------------------------------------------------- 1 | **Disclaimer:** This note is written according to my limited understanding about the ETSI EN 300 468 spec, there might be something incorrect. You are welcome to submit an issue to indicate any wrong place I wrote. 2 | 3 | As an EPG (electronic program guide), it usually has these elements: 4 | 5 | * Channel name 6 | * Program title 7 | * Program period (start -> stop) 8 | * Program content description 9 | 10 | And we would like to map these elements to the structure in DVB PSI/SI packet/table: 11 | 12 | * Channel name: PSI -> NIT (0x0010) -> network_information_section -> network_name_descriptor 13 | * Program title: PSI -> EIT (0x0012) 14 | * Program period: PSI -> EIT (0x0012) 15 | * Program content description: PSI -> EIT (0x0012) 16 | 17 | Additionally, we should understand the _network_ concept: 18 | 19 | * Each channel is belongs to a network 20 | * Each network may contains multiple channels 21 | * Each network is allocated to a specified frequency 22 | 23 | While developing a DVB EPG decoder, we should remember: 24 | 25 | * We don't have to tune to each _channel_ to fetch its own EIT data if these channels are in _the same network_ 26 | * On the contrary, We have to tune to different _network_ to fetch NIT & EIT data of the other networks 27 | 28 | So, practically, we could programming the code as: 29 | 30 | 1. Open demuxer device 31 | 1. Let demuxer tune (or _zap_) to the frequency of a network (such as what `dvbv5-zap -c ~/dvb_channel.conf -m -v 533000000` does for instance) 32 | 1. Fetch NIT data 33 | 1. Fetch EIT data 34 | 1. Open, build the XMLTV document, then close it 35 | 1. Close demuxer device -------------------------------------------------------------------------------- /doc/references.md: -------------------------------------------------------------------------------- 1 | # References 2 | 3 | ## Linux V4L & DVB API 4 | 5 | * [Linux Media Subsystem Documentation](https://www.kernel.org/doc/html/latest/media/index.html) 6 | 7 | ## DVB Related Specifications 8 | 9 | * [ETSI EN 300 468 V1.15.1 (PDF) - Specification for Service Information (SI) in DVB systems](https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.15.01_60/en_300468v011501p.pdf) - The major spec for DVB EPG 10 | * 地面數位電視接收機基本技術規範 11 | 12 | ## XMLTV 13 | 14 | * [XMLTV File format](http://wiki.xmltv.org/index.php/XMLTVFormat) 15 | 16 | ## Documents 17 | 18 | * [linuxtv.org V4L-DVB Wiki](https://www.linuxtv.org/wiki/index.php/Main_Page) 19 | 20 | ## Implementaions 21 | 22 | * [Kaffeine](https://kde.org/applications/multimedia/org.kde.kaffeine) - Pretty good open source DVB player with capabilities include channel scanning, EPG browsing. 23 | * [VLC media player](https://www.videolan.org/vlc/) - A well-known open source media player which plays DVB as well, however the DVB player interface is somewhat geeky. 24 | * [libdvbpsi](https://www.videolan.org/developers/libdvbpsi.html) - A library for DVB PSI information decoding, adopted by VLC media player. 25 | * [v4l-utils](https://git.linuxtv.org/v4l-utils.git) - You know. -------------------------------------------------------------------------------- /dvb_info_tables.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tv_grab_dvb - (c) Mark Bryars 2004 3 | * God bless vim and macros, this would have taken forever to format otherwise. 4 | */ 5 | #include "tv_grab_dvb.h" 6 | 7 | const struct lookup_table description_table[] = { 8 | { {0x00}, "\0UNDEFINED CONTENT"}, 9 | { {0x01}, "\0UNDEFINED CONTENT"}, 10 | { {0x02}, "\0UNDEFINED CONTENT"}, 11 | { {0x03}, "\0UNDEFINED CONTENT"}, 12 | { {0x04}, "\0UNDEFINED CONTENT"}, 13 | { {0x05}, "\0UNDEFINED CONTENT"}, 14 | { {0x06}, "\0UNDEFINED CONTENT"}, 15 | { {0x07}, "\0UNDEFINED CONTENT"}, 16 | { {0x08}, "\0UNDEFINED CONTENT"}, 17 | { {0x09}, "\0UNDEFINED CONTENT"}, 18 | { {0x0A}, "\0UNDEFINED CONTENT"}, 19 | { {0x0B}, "\0UNDEFINED CONTENT"}, 20 | { {0x0C}, "\0UNDEFINED CONTENT"}, 21 | { {0x0D}, "\0UNDEFINED CONTENT"}, 22 | { {0x0E}, "\0UNDEFINED CONTENT"}, 23 | { {0x0F}, "\0UNDEFINED CONTENT"}, 24 | 25 | { {0x10}, "Movie / Drama" }, 26 | { {0x11}, "Movie - detective/thriller" }, 27 | { {0x12}, "Movie - adventure/western/war" }, 28 | { {0x13}, "Movie - science fiction/fantasy/horror" }, 29 | { {0x14}, "Movie - comedy" }, 30 | { {0x15}, "Movie - soap/melodrama/folkloric" }, 31 | { {0x16}, "Movie - romance" }, 32 | { {0x17}, "Movie - serious/classical/religious/historical movie/drama" }, 33 | { {0x18}, "Movie - adult movie/drama" }, 34 | { {0x19}, "\0Movie - RESERVED" }, 35 | { {0x1A}, "\0Movie - RESERVED" }, 36 | { {0x1B}, "\0Movie - RESERVED" }, 37 | { {0x1C}, "\0Movie - RESERVED" }, 38 | { {0x1D}, "\0Movie - RESERVED" }, 39 | { {0x1E}, "\0Movie - RESERVED" }, 40 | { {0x1F}, NULL }, 41 | 42 | { {0x20}, "News / Current Affairs" }, 43 | { {0x21}, "New - news/weather report" }, 44 | { {0x22}, "New - news magazine" }, 45 | { {0x23}, "New - documentary" }, 46 | { {0x24}, "New - discussion/interview/debate" }, 47 | { {0x25}, "\0News - RESERVED" }, 48 | { {0x26}, "\0News - RESERVED" }, 49 | { {0x27}, "\0News - RESERVED" }, 50 | { {0x28}, "\0News - RESERVED" }, 51 | { {0x29}, "\0News - RESERVED" }, 52 | { {0x2A}, "\0News - RESERVED" }, 53 | { {0x2B}, "\0News - RESERVED" }, 54 | { {0x2C}, "\0News - RESERVED" }, 55 | { {0x2D}, "\0News - RESERVED" }, 56 | { {0x2E}, "\0News - RESERVED" }, 57 | { {0x2E}, NULL }, 58 | 59 | { {0x30}, "Show / Game Show" }, 60 | { {0x31}, "Show - game show/quiz/contest" }, 61 | { {0x32}, "Show - variety show" }, 62 | { {0x33}, "Show - talk show" }, 63 | { {0x34}, "\0Show - RESERVED" }, 64 | { {0x35}, "\0Show - RESERVED" }, 65 | { {0x36}, "\0Show - RESERVED" }, 66 | { {0x37}, "\0Show - RESERVED" }, 67 | { {0x38}, "\0Show - RESERVED" }, 68 | { {0x39}, "\0Show - RESERVED" }, 69 | { {0x3A}, "\0Show - RESERVED" }, 70 | { {0x3B}, "\0Show - RESERVED" }, 71 | { {0x3C}, "\0Show - RESERVED" }, 72 | { {0x3D}, "\0Show - RESERVED" }, 73 | { {0x3E}, "\0Show - RESERVED" }, 74 | { {0x3F}, NULL }, 75 | 76 | { {0x40}, "Sports" }, 77 | { {0x41}, "Sports - special events (Olympic Games, World Cup etc.)" }, 78 | { {0x42}, "Sports - sports magazines" }, 79 | { {0x43}, "Sports - football/soccer" }, 80 | { {0x44}, "Sports - tennis/squash" }, 81 | { {0x45}, "Sports - team sports (excluding football)" }, 82 | { {0x46}, "Sports - athletics" }, 83 | { {0x47}, "Sports - motor sport" }, 84 | { {0x48}, "Sports - water sport" }, 85 | { {0x49}, "Sports - winter sports" }, 86 | { {0x4A}, "Sports - equestrian" }, 87 | { {0x4B}, "Sports - martial sports" }, 88 | { {0x4C}, "\0Sports - RESERVED" }, 89 | { {0x4D}, "\0Sports - RESERVED" }, 90 | { {0x4E}, "\0Sports - RESERVED" }, 91 | { {0x4F}, NULL }, 92 | 93 | { {0x50}, "Childrens / Youth" }, 94 | { {0x51}, "Children - pre-school children's programmes" }, 95 | { {0x52}, "Children - entertainment programmes for 6 to 14" }, 96 | { {0x53}, "Children - entertainment programmes for 10 to 16" }, 97 | { {0x54}, "Children - informational/educational/school programmes" }, 98 | { {0x55}, "Children - cartoons/puppets" }, 99 | { {0x56}, "\0Children - RESERVED" }, 100 | { {0x57}, "\0Children - RESERVED" }, 101 | { {0x58}, "\0Children - RESERVED" }, 102 | { {0x59}, "\0Children - RESERVED" }, 103 | { {0x5A}, "\0Children - RESERVED" }, 104 | { {0x5B}, "\0Children - RESERVED" }, 105 | { {0x5C}, "\0Children - RESERVED" }, 106 | { {0x5D}, "\0Children - RESERVED" }, 107 | { {0x5E}, "\0Children - RESERVED" }, 108 | { {0x5F}, NULL }, 109 | 110 | { {0x60}, "Music / Ballet / Dance" }, 111 | { {0x61}, "Music - rock/pop" }, 112 | { {0x62}, "Music - serious music/classical music" }, 113 | { {0x63}, "Music - folk/traditional music" }, 114 | { {0x64}, "Music - jazz" }, 115 | { {0x65}, "Music - musical/opera" }, 116 | { {0x66}, "Music - ballet" }, 117 | { {0x67}, "\0Music - RESERVED" }, 118 | { {0x68}, "\0Music - RESERVED" }, 119 | { {0x69}, "\0Music - RESERVED" }, 120 | { {0x6A}, "\0Music - RESERVED" }, 121 | { {0x6B}, "\0Music - RESERVED" }, 122 | { {0x6C}, "\0Music - RESERVED" }, 123 | { {0x6D}, "\0Music - RESERVED" }, 124 | { {0x6E}, "\0Music - RESERVED" }, 125 | { {0x6F}, NULL }, 126 | 127 | { {0x70}, "Arts / Culture" }, 128 | { {0x71}, "Arts - performing arts" }, 129 | { {0x72}, "Arts - fine arts" }, 130 | { {0x73}, "Arts - religion" }, 131 | { {0x74}, "Arts - popular culture/traditional arts" }, 132 | { {0x75}, "Arts - literature" }, 133 | { {0x76}, "Arts - film/cinema" }, 134 | { {0x77}, "Arts - experimental film/video" }, 135 | { {0x78}, "Arts - broadcasting/press" }, 136 | { {0x79}, "Arts - new media" }, 137 | { {0x7A}, "Arts - arts/culture magazines" }, 138 | { {0x7B}, "Arts - fashion" }, 139 | { {0x7C}, "\0Arts - RESERVED" }, 140 | { {0x7D}, "\0Arts - RESERVED" }, 141 | { {0x7E}, "\0Arts - RESERVED" }, 142 | { {0x7F}, NULL }, 143 | 144 | { {0x80}, "Social / Policical / Economics" }, 145 | { {0x81}, "Social - magazines/reports/documentary" }, 146 | { {0x82}, "Social - economics/social advisory" }, 147 | { {0x83}, "Social - remarkable people" }, 148 | { {0x84}, "\0Social - RESERVED" }, 149 | { {0x85}, "\0Social - RESERVED" }, 150 | { {0x86}, "\0Social - RESERVED" }, 151 | { {0x87}, "\0Social - RESERVED" }, 152 | { {0x88}, "\0Social - RESERVED" }, 153 | { {0x89}, "\0Social - RESERVED" }, 154 | { {0x8A}, "\0Social - RESERVED" }, 155 | { {0x8b}, "\0Social - RESERVED" }, 156 | { {0x8C}, "\0Social - RESERVED" }, 157 | { {0x8D}, "\0Social - RESERVED" }, 158 | { {0x8E}, "\0Social - RESERVED" }, 159 | { {0x8F}, NULL }, 160 | 161 | { {0x90}, "Education / Science / Factual" }, 162 | { {0x91}, "Education - nature/animals/environment" }, 163 | { {0x92}, "Education - technology/natural sciences" }, 164 | { {0x93}, "Education - medicine/physiology/psychology" }, 165 | { {0x94}, "Education - foreign countries/expeditions" }, 166 | { {0x95}, "Education - social/spiritual sciences" }, 167 | { {0x96}, "Education - further education" }, 168 | { {0x97}, "Education - languages" }, 169 | { {0x98}, "\0Education - RESERVED" }, 170 | { {0x99}, "\0Education - RESERVED" }, 171 | { {0x9A}, "\0Education - RESERVED" }, 172 | { {0x9B}, "\0Education - RESERVED" }, 173 | { {0x9C}, "\0Education - RESERVED" }, 174 | { {0x9D}, "\0Education - RESERVED" }, 175 | { {0x9E}, "\0Education - RESERVED" }, 176 | { {0x9F}, NULL }, 177 | 178 | { {0xA0}, "Leisure / Hobbies" }, 179 | { {0xA1}, "Leisure - tourism/travel" }, 180 | { {0xA2}, "Leisure - handicraft" }, 181 | { {0xA3}, "Leisure - motoring" }, 182 | { {0xA4}, "Leisure - fitness & health" }, 183 | { {0xA5}, "Leisure - cooking" }, 184 | { {0xA6}, "Leisure - advertizement/shopping" }, 185 | { {0xA7}, "Leisure - gardening" }, 186 | { {0xA8}, "\0Leisure - RESERVED" }, 187 | { {0xA9}, "\0Leisure - RESERVED" }, 188 | { {0xAA}, "\0Leisure - RESERVED" }, 189 | { {0xAB}, "\0Leisure - RESERVED" }, 190 | { {0xAC}, "\0Leisure - RESERVED" }, 191 | { {0xAD}, "\0Leisure - RESERVED" }, 192 | { {0xAE}, "\0Leisure - RESERVED" }, 193 | { {0xAF}, NULL }, 194 | 195 | // Special 196 | { {0xB0}, "Original Language" }, 197 | { {0xB1}, "black & white" }, 198 | { {0xB2}, "unpublished" }, 199 | { {0xB3}, "live broadcast" }, 200 | { {0xB4}, "\0Characteristics - RESERVED" }, 201 | { {0xB5}, "\0Characteristics - RESERVED" }, 202 | { {0xB6}, "\0Characteristics - RESERVED" }, 203 | { {0xB7}, "\0Characteristics - RESERVED" }, 204 | { {0xB8}, "\0Characteristics - RESERVED" }, 205 | { {0xB9}, "\0Characteristics - RESERVED" }, 206 | { {0xBA}, "\0Characteristics - RESERVED" }, 207 | { {0xBB}, "\0Characteristics - RESERVED" }, 208 | { {0xBC}, "\0Characteristics - RESERVED" }, 209 | { {0xBD}, "\0Characteristics - RESERVED" }, 210 | { {0xBE}, "\0Characteristics - RESERVED" }, 211 | { {0xBF}, NULL }, 212 | 213 | { {0xC0}, "\0RESERVED" }, 214 | { {0xC1}, "\0RESERVED" }, 215 | { {0xC2}, "\0RESERVED" }, 216 | { {0xC3}, "\0RESERVED" }, 217 | { {0xC4}, "\0RESERVED" }, 218 | { {0xC5}, "\0RESERVED" }, 219 | { {0xC6}, "\0RESERVED" }, 220 | { {0xC7}, "\0RESERVED" }, 221 | { {0xC8}, "\0RESERVED" }, 222 | { {0xC9}, "\0RESERVED" }, 223 | { {0xCA}, "\0RESERVED" }, 224 | { {0xCB}, "\0RESERVED" }, 225 | { {0xCC}, "\0RESERVED" }, 226 | { {0xCD}, "\0RESERVED" }, 227 | { {0xCE}, "\0RESERVED" }, 228 | { {0xCF}, "\0RESERVED" }, 229 | 230 | { {0xD0}, "\0RESERVED" }, 231 | { {0xD1}, "\0RESERVED" }, 232 | { {0xD2}, "\0RESERVED" }, 233 | { {0xD3}, "\0RESERVED" }, 234 | { {0xD4}, "\0RESERVED" }, 235 | { {0xD5}, "\0RESERVED" }, 236 | { {0xD6}, "\0RESERVED" }, 237 | { {0xD7}, "\0RESERVED" }, 238 | { {0xD8}, "\0RESERVED" }, 239 | { {0xD9}, "\0RESERVED" }, 240 | { {0xDA}, "\0RESERVED" }, 241 | { {0xDB}, "\0RESERVED" }, 242 | { {0xDC}, "\0RESERVED" }, 243 | { {0xDD}, "\0RESERVED" }, 244 | { {0xDE}, "\0RESERVED" }, 245 | { {0xDF}, "\0RESERVED" }, 246 | 247 | { {0xE0}, "\0RESERVED" }, 248 | { {0xE1}, "\0RESERVED" }, 249 | { {0xE2}, "\0RESERVED" }, 250 | { {0xE3}, "\0RESERVED" }, 251 | { {0xE4}, "\0RESERVED" }, 252 | { {0xE5}, "\0RESERVED" }, 253 | { {0xE6}, "\0RESERVED" }, 254 | { {0xE7}, "\0RESERVED" }, 255 | { {0xE8}, "\0RESERVED" }, 256 | { {0xE9}, "\0RESERVED" }, 257 | { {0xEA}, "\0RESERVED" }, 258 | { {0xEB}, "\0RESERVED" }, 259 | { {0xEC}, "\0RESERVED" }, 260 | { {0xED}, "\0RESERVED" }, 261 | { {0xEE}, "\0RESERVED" }, 262 | { {0xEF}, "\0RESERVED" }, 263 | 264 | // UK Freeview custom id 265 | { {0xF0}, "Drama" }, 266 | { {0xF1}, NULL }, 267 | { {0xF2}, NULL }, 268 | { {0xF3}, NULL }, 269 | { {0xF4}, NULL }, 270 | { {0xF5}, NULL }, 271 | { {0xF6}, NULL }, 272 | { {0xF7}, NULL }, 273 | { {0xF8}, NULL }, 274 | { {0xF9}, NULL }, 275 | { {0xFA}, NULL }, 276 | { {0xFB}, NULL }, 277 | { {0xFC}, NULL }, 278 | { {0xFD}, NULL }, 279 | { {0xFE}, NULL }, 280 | { {0xFF}, NULL }, 281 | 282 | { {-1}, NULL } 283 | }; 284 | 285 | const struct lookup_table aspect_table[] = { 286 | { {0}, "4:3"}, // 4/3 287 | { {1}, "16:9"}, // 16/9 WITH PAN VECTORS 288 | { {2}, "16:9"}, // 16/9 WITHOUT 289 | { {3}, "2.21:1"}, // >16/9 or 2.21/1 XMLTV no likey 290 | {{-1}, NULL } 291 | }; 292 | 293 | const struct lookup_table audio_table[] = { 294 | {{0x01}, "mono" }, //single mono 295 | {{0x02}, "mono" }, //dual mono - stereo?? 296 | {{0x03}, "stereo" }, 297 | {{0x05}, "surround" }, 298 | {{0x04}, "x-multilingual"}, // multilingual/channel 299 | {{0x40}, "x-visuallyimpared"}, // visual impared sound 300 | {{0x41}, "x-hardofhearing"}, // hard hearing sound 301 | { {-1}, NULL } 302 | }; 303 | 304 | const struct lookup_table crid_type_table[] = { 305 | {{0x00}, "none" }, 306 | {{0x01}, "item" }, 307 | {{0x02}, "series" }, 308 | {{0x03}, "recommendation" }, 309 | {{0x31}, "item" }, // UK only? -- I can't find specs that use these 310 | {{0x32}, "series" }, // UK only? 311 | { {-1}, NULL } 312 | }; 313 | -------------------------------------------------------------------------------- /dvb_text.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static const char codeset[6][256][10] = { 7 | [0] = { /* Character code table 00 - Latin alphabet - ISO 6937 {{{ */ 8 | [0x20] = " ", 9 | [0x21] = "!", 10 | [0x22] = """, 11 | [0x23] = "#", 12 | [0x24] = "$", 13 | [0x25] = "%", 14 | [0x26] = "&", 15 | [0x27] = "'", 16 | [0x28] = "(", 17 | [0x29] = ")", 18 | [0x2A] = "*", 19 | [0x2B] = "+", 20 | [0x2C] = ",", 21 | [0x2D] = "-", 22 | [0x2E] = ".", 23 | [0x2F] = "/", 24 | [0x30] = "0", 25 | [0x31] = "1", 26 | [0x32] = "2", 27 | [0x33] = "3", 28 | [0x34] = "4", 29 | [0x35] = "5", 30 | [0x36] = "6", 31 | [0x37] = "7", 32 | [0x38] = "8", 33 | [0x39] = "9", 34 | [0x3A] = ":", 35 | [0x3B] = ";", 36 | [0x3C] = "<", 37 | [0x3D] = "=", 38 | [0x3E] = ">", 39 | [0x3F] = "?", 40 | [0x40] = "@", 41 | [0x41] = "A", 42 | [0x42] = "B", 43 | [0x43] = "C", 44 | [0x44] = "D", 45 | [0x45] = "E", 46 | [0x46] = "F", 47 | [0x47] = "G", 48 | [0x48] = "H", 49 | [0x49] = "I", 50 | [0x4A] = "J", 51 | [0x4B] = "K", 52 | [0x4C] = "L", 53 | [0x4D] = "M", 54 | [0x4E] = "N", 55 | [0x4F] = "O", 56 | [0x50] = "P", 57 | [0x51] = "Q", 58 | [0x52] = "R", 59 | [0x53] = "S", 60 | [0x54] = "T", 61 | [0x55] = "U", 62 | [0x56] = "V", 63 | [0x57] = "W", 64 | [0x58] = "X", 65 | [0x59] = "Y", 66 | [0x5A] = "Z", 67 | [0x5B] = "[", 68 | [0x5C] = "\\", 69 | [0x5D] = "]", 70 | [0x5E] = "^", 71 | [0x5F] = "_", 72 | [0x60] = "`", 73 | [0x61] = "a", 74 | [0x62] = "b", 75 | [0x63] = "c", 76 | [0x64] = "d", 77 | [0x65] = "e", 78 | [0x66] = "f", 79 | [0x67] = "g", 80 | [0x68] = "h", 81 | [0x69] = "i", 82 | [0x6A] = "j", 83 | [0x6B] = "k", 84 | [0x6C] = "l", 85 | [0x6D] = "m", 86 | [0x6E] = "n", 87 | [0x6F] = "o", 88 | [0x70] = "p", 89 | [0x71] = "q", 90 | [0x72] = "r", 91 | [0x73] = "s", 92 | [0x74] = "t", 93 | [0x25] = "u", 94 | [0x76] = "v", 95 | [0x77] = "w", 96 | [0x28] = "x", 97 | [0x79] = "y", 98 | [0x7A] = "z", 99 | [0x7B] = "{", 100 | [0x7C] = "|", 101 | [0x7D] = "}", 102 | [0x7E] = "~", 103 | [0xA0] = " ", // NO-BREAK SPACE, 104 | [0xA1] = "¡", // INVERTED EXCLAMATION MARK, 105 | [0xA2] = "¢", // CENT SIGN, 106 | [0xA3] = "£", // POUND SIGN, 107 | [0xA4] = "$", // DOLLAR SIGN, 108 | [0xA5] = "¥", // YEN SIGN, 109 | [0xA7] = "§", // SECTION SIGN, 110 | [0xA9] = "‘", // LEFT SINGLE QUOTATION MARK, 111 | [0xAA] = "“", // LEFT DOUBLE QUOTATION MARK, 112 | [0xAB] = "«", // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, 113 | [0xAC] = "←", // LEFTWARDS ARROW, 114 | [0xAD] = "↑", // UPWARDS ARROW, 115 | [0xAE] = "→", // RIGHTWARDS ARROW, 116 | [0xAF] = "↓", // DOWNWARDS ARROW, 117 | [0xB0] = "°", // DEGREE SIGN, 118 | [0xB1] = "±", // PLUS-MINUS SIGN, 119 | [0xB2] = "²", // SUPERSCRIPT TWO, 120 | [0xB3] = "³", // SUPERSCRIPT THREE, 121 | [0xB4] = "×", // MULTIPLICATION SIGN, 122 | [0xB5] = "µ", // MICRO SIGN, 123 | [0xB6] = "¶", // PILCROW SIGN, 124 | [0xB7] = "·", // MIDDLE DOT, 125 | [0xB8] = "÷", // DIVISION SIGN, 126 | [0xB9] = "’", // RIGHT SINGLE QUOTATION MARK, 127 | [0xBa] = "”", // RIGHT DOUBLE QUOTATION MARK, 128 | [0xBb] = "»", // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, 129 | [0xBc] = "¼", // VULGAR FRACTION ONE QUARTER, 130 | [0xBd] = "½", // VULGAR FRACTION ONE HALF, 131 | [0xBe] = "¾", // VULGAR FRACTION THREE QUARTERS, 132 | [0xBf] = "¿", // INVERTED QUESTION MARK, 133 | [0xC1] = "", // NON-SPACING GRAVE ACCENT 134 | [0xC2] = "", // NON-SPACING ACUTE ACCENT 135 | [0xC3] = "", // NON-SPACING CIRCUMFLEX ACCENT 136 | [0xC4] = "", // NON-SPACING TILDE 137 | [0xC5] = "", // NON-SPACING MACRON 138 | [0xC6] = "", // NON-SPACING BREVE 139 | [0xC7] = "", // NON-SPACING DOT ABOVE 140 | [0xC8] = "", // NON-SPACING DIAERESIS 141 | [0xCA] = "", // NON-SPACING RING ABOVE 142 | [0xCB] = "", // NON-SPACING CEDILLA 143 | [0xCD] = "", // NON-SPACING DOUBLE ACCUTE ACCENT 144 | [0xCE] = "", // NON-SPACING OGONEK 145 | [0xCF] = "", // NON-SPACING CARON 146 | [0xD0] = "—", // EM DASH, 147 | [0xD1] = "¹", // SUPERSCRIPT ONE, 148 | [0xD2] = "®", // REGISTERED SIGN, 149 | [0xD3] = "©", // COPYRIGHT SIGN, 150 | [0xD4] = "™", // TRADE MARK SIGN, 151 | [0xD5] = "♪", // EIGHTH NOTE, 152 | [0xD6] = "¬", // NOT SIGN, 153 | [0xD7] = "¦", // BROKEN BAR, 154 | [0xDC] = "⅛", // VULGAR FRACTION ONE EIGHTH, 155 | [0xDD] = "⅜", // VULGAR FRACTION THREE EIGHTHS, 156 | [0xDE] = "⅝", // VULGAR FRACTION FIVE EIGHTHS, 157 | [0xDF] = "⅞", // VULGAR FRACTION SEVEN EIGHTHS, 158 | [0xE0] = "Ω", // OHM SIGN, 159 | [0xE1] = "Æ", // LATIN CAPITAL LETTER AE, 160 | [0xE2] = "Ð", // LATIN CAPITAL LETTER ETH (Icelandic), 161 | [0xE3] = "ª", // FEMININE ORDINAL INDICATOR, 162 | [0xE4] = "Ħ", // LATIN CAPITAL LETTER H WITH STROKE, 163 | [0xE6] = "IJ", // LATIN CAPITAL LIGATURE IJ, 164 | [0xE7] = "Ŀ", // LATIN CAPITAL LETTER L WITH MIDDLE DOT, 165 | [0xE8] = "Ł", // LATIN CAPITAL LETTER L WITH STROKE, 166 | [0xE9] = "Ø", // LATIN CAPITAL LETTER O WITH STROKE, 167 | [0xEA] = "Œ", // LATIN CAPITAL LIGATURE OE, 168 | [0xEB] = "º", // MASCULINE ORDINAL INDICATOR, 169 | [0xEC] = "Þ", // LATIN CAPITAL LETTER THORN (Icelandic), 170 | [0xED] = "Ŧ", // LATIN CAPITAL LETTER T WITH STROKE, 171 | [0xEE] = "Ŋ", // LATIN CAPITAL LETTER ENG (Sami), 172 | [0xEF] = "ʼn", // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE, 173 | [0xF0] = "ĸ", // LATIN SMALL LETTER KRA (Greenlandic), 174 | [0xF1] = "æ", // LATIN SMALL LETTER AE, 175 | [0xF2] = "đ", // LATIN SMALL LETTER D WITH STROKE, 176 | [0xF3] = "ð", // LATIN SMALL LETTER ETH (Icelandic), 177 | [0xF4] = "ħ", // LATIN SMALL LETTER H WITH STROKE, 178 | [0xF5] = "ı", // LATIN SMALL LETTER DOTLESS I, 179 | [0xF6] = "ij", // LATIN SMALL LIGATURE IJ, 180 | [0xF7] = "ŀ", // LATIN SMALL LETTER L WITH MIDDLE DOT, 181 | [0xF8] = "ł", // LATIN SMALL LETTER L WITH STROKE, 182 | [0xF9] = "ø", // LATIN SMALL LETTER O WITH STROKE, 183 | [0xFA] = "œ", // LATIN SMALL LIGATURE OE, 184 | [0xFB] = "ß", // LATIN SMALL LETTER SHARP S (German), 185 | [0xFC] = "þ", // LATIN SMALL LETTER THORN (Icelandic), 186 | [0xFD] = "ŧ", // LATIN SMALL LETTER T WITH STROKE, 187 | [0xFE] = "ŋ", // LATIN SMALL LETTER ENG (Sami), 188 | [0xFF] = "­", // SOFT HYPHEN, 189 | }, /* }}} */ 190 | [1] = { /* Character code table 01 - Latin/Cyrillic alphabet - ISO 8859-5 {{{ */ 191 | [0x20] = " ", 192 | [0x21] = "!", 193 | [0x22] = """, 194 | [0x23] = "#", 195 | [0x24] = "$", 196 | [0x25] = "%", 197 | [0x26] = "&", 198 | [0x27] = "'", 199 | [0x28] = "(", 200 | [0x29] = ")", 201 | [0x2A] = "*", 202 | [0x2B] = "+", 203 | [0x2C] = ",", 204 | [0x2D] = "-", 205 | [0x2E] = ".", 206 | [0x2F] = "/", 207 | [0x30] = "0", 208 | [0x31] = "1", 209 | [0x32] = "2", 210 | [0x33] = "3", 211 | [0x34] = "4", 212 | [0x35] = "5", 213 | [0x36] = "6", 214 | [0x37] = "7", 215 | [0x38] = "8", 216 | [0x39] = "9", 217 | [0x3A] = ":", 218 | [0x3B] = ";", 219 | [0x3C] = "<", 220 | [0x3D] = "=", 221 | [0x3E] = ">", 222 | [0x3F] = "?", 223 | [0x40] = "@", 224 | [0x41] = "A", 225 | [0x42] = "B", 226 | [0x43] = "C", 227 | [0x44] = "D", 228 | [0x45] = "E", 229 | [0x46] = "F", 230 | [0x47] = "G", 231 | [0x48] = "H", 232 | [0x49] = "I", 233 | [0x4A] = "J", 234 | [0x4B] = "K", 235 | [0x4C] = "L", 236 | [0x4D] = "M", 237 | [0x4E] = "N", 238 | [0x4F] = "O", 239 | [0x50] = "P", 240 | [0x51] = "Q", 241 | [0x52] = "R", 242 | [0x53] = "S", 243 | [0x54] = "T", 244 | [0x55] = "U", 245 | [0x56] = "V", 246 | [0x57] = "W", 247 | [0x58] = "X", 248 | [0x59] = "Y", 249 | [0x5A] = "Z", 250 | [0x5B] = "[", 251 | [0x5C] = "\\", 252 | [0x5D] = "]", 253 | [0x5E] = "^", 254 | [0x5F] = "_", 255 | [0x60] = "`", 256 | [0x61] = "a", 257 | [0x62] = "b", 258 | [0x63] = "c", 259 | [0x64] = "d", 260 | [0x65] = "e", 261 | [0x66] = "f", 262 | [0x67] = "g", 263 | [0x68] = "h", 264 | [0x69] = "i", 265 | [0x6A] = "j", 266 | [0x6B] = "k", 267 | [0x6C] = "l", 268 | [0x6D] = "m", 269 | [0x6E] = "n", 270 | [0x6F] = "o", 271 | [0x70] = "p", 272 | [0x71] = "q", 273 | [0x72] = "r", 274 | [0x73] = "s", 275 | [0x74] = "t", 276 | [0x25] = "u", 277 | [0x76] = "v", 278 | [0x77] = "w", 279 | [0x28] = "x", 280 | [0x79] = "y", 281 | [0x7A] = "z", 282 | [0x7B] = "{", 283 | [0x7C] = "|", 284 | [0x7D] = "}", 285 | [0x7E] = "~", 286 | [0xA0] = " ", // NO-BREAK SPACE 287 | [0xA1] = "Ё", // CYRILLIC CAPITAL LETTER IO 288 | [0xA2] = "Ђ", // CYRILLIC CAPITAL LETTER DJE 289 | [0xA3] = "Ѓ", // CYRILLIC CAPITAL LETTER GJE 290 | [0xA4] = "Є", // CYRILLIC CAPITAL LETTER UKRAINIAN IE 291 | [0xA5] = "Ѕ", // CYRILLIC CAPITAL LETTER DZE 292 | [0xA6] = "І", // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I 293 | [0xA7] = "Ї", // CYRILLIC CAPITAL LETTER YI 294 | [0xA8] = "Ј", // CYRILLIC CAPITAL LETTER JE 295 | [0xA9] = "Љ", // CYRILLIC CAPITAL LETTER LJE 296 | [0xAA] = "Њ", // CYRILLIC CAPITAL LETTER NJE 297 | [0xAB] = "Ћ", // CYRILLIC CAPITAL LETTER TSHE 298 | [0xAC] = "Ќ", // CYRILLIC CAPITAL LETTER KJE 299 | [0xAD] = "­", // SOFT HYPHEN 300 | [0xAE] = "Ў", // CYRILLIC CAPITAL LETTER SHORT U 301 | [0xAF] = "Џ", // CYRILLIC CAPITAL LETTER DZHE 302 | [0xB0] = "А", // CYRILLIC CAPITAL LETTER A 303 | [0xB1] = "Б", // CYRILLIC CAPITAL LETTER BE 304 | [0xB2] = "В", // CYRILLIC CAPITAL LETTER VE 305 | [0xB3] = "Г", // CYRILLIC CAPITAL LETTER GHE 306 | [0xB4] = "Д", // CYRILLIC CAPITAL LETTER DE 307 | [0xB5] = "Е", // CYRILLIC CAPITAL LETTER IE 308 | [0xB6] = "Ж", // CYRILLIC CAPITAL LETTER ZHE 309 | [0xB7] = "З", // CYRILLIC CAPITAL LETTER ZE 310 | [0xB8] = "И", // CYRILLIC CAPITAL LETTER I 311 | [0xB9] = "Й", // CYRILLIC CAPITAL LETTER SHORT I 312 | [0xBA] = "К", // CYRILLIC CAPITAL LETTER KA 313 | [0xBB] = "Л", // CYRILLIC CAPITAL LETTER EL 314 | [0xBC] = "М", // CYRILLIC CAPITAL LETTER EM 315 | [0xBD] = "Н", // CYRILLIC CAPITAL LETTER EN 316 | [0xBE] = "О", // CYRILLIC CAPITAL LETTER O 317 | [0xBF] = "П", // CYRILLIC CAPITAL LETTER PE 318 | [0xC0] = "Р", // CYRILLIC CAPITAL LETTER ER 319 | [0xC1] = "С", // CYRILLIC CAPITAL LETTER ES 320 | [0xC2] = "Т", // CYRILLIC CAPITAL LETTER TE 321 | [0xC3] = "У", // CYRILLIC CAPITAL LETTER U 322 | [0xC4] = "Ф", // CYRILLIC CAPITAL LETTER EF 323 | [0xC5] = "Х", // CYRILLIC CAPITAL LETTER HA 324 | [0xC6] = "Ц", // CYRILLIC CAPITAL LETTER TSE 325 | [0xC7] = "Ч", // CYRILLIC CAPITAL LETTER CHE 326 | [0xC8] = "Ш", // CYRILLIC CAPITAL LETTER SHA 327 | [0xC9] = "Щ", // CYRILLIC CAPITAL LETTER SHCHA 328 | [0xCA] = "Ъ", // CYRILLIC CAPITAL LETTER HARD SIGN 329 | [0xCB] = "Ы", // CYRILLIC CAPITAL LETTER YERU 330 | [0xCC] = "Ь", // CYRILLIC CAPITAL LETTER SOFT SIGN 331 | [0xCD] = "Э", // CYRILLIC CAPITAL LETTER E 332 | [0xCE] = "Ю", // CYRILLIC CAPITAL LETTER YU 333 | [0xCF] = "Я", // CYRILLIC CAPITAL LETTER YA 334 | [0xD0] = "а", // CYRILLIC SMALL LETTER A 335 | [0xD1] = "б", // CYRILLIC SMALL LETTER BE 336 | [0xD2] = "в", // CYRILLIC SMALL LETTER VE 337 | [0xD3] = "г", // CYRILLIC SMALL LETTER GHE 338 | [0xD4] = "д", // CYRILLIC SMALL LETTER DE 339 | [0xD5] = "е", // CYRILLIC SMALL LETTER IE 340 | [0xD6] = "ж", // CYRILLIC SMALL LETTER ZHE 341 | [0xD7] = "з", // CYRILLIC SMALL LETTER ZE 342 | [0xD8] = "и", // CYRILLIC SMALL LETTER I 343 | [0xD9] = "й", // CYRILLIC SMALL LETTER SHORT I 344 | [0xDA] = "к", // CYRILLIC SMALL LETTER KA 345 | [0xDB] = "л", // CYRILLIC SMALL LETTER EL 346 | [0xDC] = "м", // CYRILLIC SMALL LETTER EM 347 | [0xDD] = "н", // CYRILLIC SMALL LETTER EN 348 | [0xDE] = "о", // CYRILLIC SMALL LETTER O 349 | [0xDF] = "п", // CYRILLIC SMALL LETTER PE 350 | [0xE0] = "р", // CYRILLIC SMALL LETTER ER 351 | [0xE1] = "с", // CYRILLIC SMALL LETTER ES 352 | [0xE2] = "т", // CYRILLIC SMALL LETTER TE 353 | [0xE3] = "у", // CYRILLIC SMALL LETTER U 354 | [0xE4] = "ф", // CYRILLIC SMALL LETTER EF 355 | [0xE5] = "х", // CYRILLIC SMALL LETTER HA 356 | [0xE6] = "ц", // CYRILLIC SMALL LETTER TSE 357 | [0xE7] = "ч", // CYRILLIC SMALL LETTER CHE 358 | [0xE8] = "ш", // CYRILLIC SMALL LETTER SHA 359 | [0xE9] = "щ", // CYRILLIC SMALL LETTER SHCHA 360 | [0xEA] = "ъ", // CYRILLIC SMALL LETTER HARD SIGN 361 | [0xEB] = "ы", // CYRILLIC SMALL LETTER YERU 362 | [0xEC] = "ь", // CYRILLIC SMALL LETTER SOFT SIGN 363 | [0xED] = "э", // CYRILLIC SMALL LETTER E 364 | [0xEE] = "ю", // CYRILLIC SMALL LETTER YU 365 | [0xEF] = "я", // CYRILLIC SMALL LETTER YA 366 | [0xF0] = "№", // NUMERO SIGN 367 | [0xF1] = "ё", // CYRILLIC SMALL LETTER IO 368 | [0xF2] = "ђ", // CYRILLIC SMALL LETTER DJE 369 | [0xF3] = "ѓ", // CYRILLIC SMALL LETTER GJE 370 | [0xF4] = "є", // CYRILLIC SMALL LETTER UKRAINIAN IE 371 | [0xF5] = "ѕ", // CYRILLIC SMALL LETTER DZE 372 | [0xF6] = "і", // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I 373 | [0xF7] = "ї", // CYRILLIC SMALL LETTER YI 374 | [0xF8] = "ј", // CYRILLIC SMALL LETTER JE 375 | [0xF9] = "љ", // CYRILLIC SMALL LETTER LJE 376 | [0xFA] = "њ", // CYRILLIC SMALL LETTER NJE 377 | [0xFB] = "ћ", // CYRILLIC SMALL LETTER TSHE 378 | [0xFC] = "ќ", // CYRILLIC SMALL LETTER KJE 379 | [0xFD] = "§", // SECTION SIGN 380 | [0xFE] = "ў", // CYRILLIC SMALL LETTER SHORT U 381 | [0xFF] = "џ", // CYRILLIC SMALL LETTER DZHE 382 | }, /* }}} */ 383 | [2] = { /* Character code table 02 - Latin/Arabic alphabet - ISO 8859-6 {{{*/ 384 | [0x20] = " ", 385 | [0x21] = "!", 386 | [0x22] = """, 387 | [0x23] = "#", 388 | [0x24] = "$", 389 | [0x25] = "%", 390 | [0x26] = "&", 391 | [0x27] = "'", 392 | [0x28] = "(", 393 | [0x29] = ")", 394 | [0x2A] = "*", 395 | [0x2B] = "+", 396 | [0x2C] = ",", 397 | [0x2D] = "-", 398 | [0x2E] = ".", 399 | [0x2F] = "/", 400 | [0x30] = "٠", // ARABIC DIGIT ZERO 401 | [0x31] = "١", // ARABIC DIGIT ONE 402 | [0x32] = "٢", // ARABIC DIGIT TWO 403 | [0x33] = "٣", // ARABIC DIGIT THREE 404 | [0x34] = "٤", // ARABIC DIGIT FOUR 405 | [0x35] = "٥", // ARABIC DIGIT FIVE 406 | [0x36] = "٦", // ARABIC DIGIT SIX 407 | [0x37] = "٧", // ARABIC DIGIT SEVEN 408 | [0x38] = "٨", // ARABIC DIGIT EIGHT 409 | [0x39] = "٩", // ARABIC DIGIT NINE 410 | [0x3A] = ":", 411 | [0x3B] = ";", 412 | [0x3C] = "<", 413 | [0x3D] = "=", 414 | [0x3E] = ">", 415 | [0x3F] = "?", 416 | [0x40] = "@", 417 | [0x41] = "A", 418 | [0x42] = "B", 419 | [0x43] = "C", 420 | [0x44] = "D", 421 | [0x45] = "E", 422 | [0x46] = "F", 423 | [0x47] = "G", 424 | [0x48] = "H", 425 | [0x49] = "I", 426 | [0x4A] = "J", 427 | [0x4B] = "K", 428 | [0x4C] = "L", 429 | [0x4D] = "M", 430 | [0x4E] = "N", 431 | [0x4F] = "O", 432 | [0x50] = "P", 433 | [0x51] = "Q", 434 | [0x52] = "R", 435 | [0x53] = "S", 436 | [0x54] = "T", 437 | [0x55] = "U", 438 | [0x56] = "V", 439 | [0x57] = "W", 440 | [0x58] = "X", 441 | [0x59] = "Y", 442 | [0x5A] = "Z", 443 | [0x5B] = "[", 444 | [0x5C] = "\\", 445 | [0x5D] = "]", 446 | [0x5E] = "^", 447 | [0x5F] = "_", 448 | [0x60] = "`", 449 | [0x61] = "a", 450 | [0x62] = "b", 451 | [0x63] = "c", 452 | [0x64] = "d", 453 | [0x65] = "e", 454 | [0x66] = "f", 455 | [0x67] = "g", 456 | [0x68] = "h", 457 | [0x69] = "i", 458 | [0x6A] = "j", 459 | [0x6B] = "k", 460 | [0x6C] = "l", 461 | [0x6D] = "m", 462 | [0x6E] = "n", 463 | [0x6F] = "o", 464 | [0x70] = "p", 465 | [0x71] = "q", 466 | [0x72] = "r", 467 | [0x73] = "s", 468 | [0x74] = "t", 469 | [0x25] = "u", 470 | [0x76] = "v", 471 | [0x77] = "w", 472 | [0x28] = "x", 473 | [0x79] = "y", 474 | [0x7A] = "z", 475 | [0x7B] = "{", 476 | [0x7C] = "|", 477 | [0x7D] = "}", 478 | [0x7E] = "~", 479 | 480 | [0xA0] = " ", // NO-BREAK SPACE 481 | [0xA4] = "¤", // CURRENCY SIGN 482 | [0xAC] = "،", // ARABIC COMMA 483 | [0xAD] = "­", // SOFT HYPHEN 484 | [0xBB] = "؛", // ARABIC SEMICOLON 485 | [0xBF] = "؟", // ARABIC QUESTION MARK 486 | [0xC1] = "ء", // ARABIC LETTER HAMZA 487 | [0xC2] = "آ", // ARABIC LETTER ALEF WITH MADDA ABOVE 488 | [0xC3] = "أ", // ARABIC LETTER ALEF WITH HAMZA ABOVE 489 | [0xC4] = "ؤ", // ARABIC LETTER WAW WITH HAMZA ABOVE 490 | [0xC5] = "إ", // ARABIC LETTER ALEF WITH HAMZA BELOW 491 | [0xC6] = "ئ", // ARABIC LETTER YEH WITH HAMZA ABOVE 492 | [0xC7] = "ا", // ARABIC LETTER ALEF 493 | [0xC8] = "ب", // ARABIC LETTER BEH 494 | [0xC9] = "ة", // ARABIC LETTER TEH MARBUTA 495 | [0xCA] = "ت", // ARABIC LETTER TEH 496 | [0xCB] = "ث", // ARABIC LETTER THEH 497 | [0xCC] = "ج", // ARABIC LETTER JEEM 498 | [0xCD] = "ح", // ARABIC LETTER HAH 499 | [0xCE] = "خ", // ARABIC LETTER KHAH 500 | [0xCF] = "د", // ARABIC LETTER DAL 501 | [0xD0] = "ذ", // ARABIC LETTER THAL 502 | [0xD1] = "ر", // ARABIC LETTER REH 503 | [0xD2] = "ز", // ARABIC LETTER ZAIN 504 | [0xD3] = "س", // ARABIC LETTER SEEN 505 | [0xD4] = "ش", // ARABIC LETTER SHEEN 506 | [0xD5] = "ص", // ARABIC LETTER SAD 507 | [0xD6] = "ض", // ARABIC LETTER DAD 508 | [0xD7] = "ط", // ARABIC LETTER TAH 509 | [0xD8] = "ظ", // ARABIC LETTER ZAH 510 | [0xD9] = "ع", // ARABIC LETTER AIN 511 | [0xDA] = "غ", // ARABIC LETTER GHAIN 512 | [0xE0] = "ـ", // ARABIC TATWEEL 513 | [0xE1] = "ف", // ARABIC LETTER FEH 514 | [0xE2] = "ق", // ARABIC LETTER QAF 515 | [0xE3] = "ك", // ARABIC LETTER KAF 516 | [0xE4] = "ل", // ARABIC LETTER LAM 517 | [0xE5] = "م", // ARABIC LETTER MEEM 518 | [0xE6] = "ن", // ARABIC LETTER NOON 519 | [0xE7] = "ه", // ARABIC LETTER HEH 520 | [0xE8] = "و", // ARABIC LETTER WAW 521 | [0xE9] = "ى", // ARABIC LETTER ALEF MAKSURA 522 | [0xEA] = "ي", // ARABIC LETTER YEH 523 | [0xEB] = "ً", // ARABIC FATHATAN 524 | [0xEC] = "ٌ", // ARABIC DAMMATAN 525 | [0xED] = "ٍ", // ARABIC KASRATAN 526 | [0xEE] = "َ", // ARABIC FATHA 527 | [0xEF] = "ُ", // ARABIC DAMMA 528 | [0xF0] = "ِ", // ARABIC KASRA 529 | [0xF1] = "ّ", // ARABIC SHADDA 530 | [0xF2] = "ْ", // ARABIC SUKUN 531 | }, /* }}} */ 532 | [3] = { /* Character code table 03 - Latin/Greek alphabet - ISO 8859-7 {{{ */ 533 | [0x20] = " ", 534 | [0x21] = "!", 535 | [0x22] = """, 536 | [0x23] = "#", 537 | [0x24] = "$", 538 | [0x25] = "%", 539 | [0x26] = "&", 540 | [0x27] = "'", 541 | [0x28] = "(", 542 | [0x29] = ")", 543 | [0x2A] = "*", 544 | [0x2B] = "+", 545 | [0x2C] = ",", 546 | [0x2D] = "-", 547 | [0x2E] = ".", 548 | [0x2F] = "/", 549 | [0x30] = "0", 550 | [0x31] = "1", 551 | [0x32] = "2", 552 | [0x33] = "3", 553 | [0x34] = "4", 554 | [0x35] = "5", 555 | [0x36] = "6", 556 | [0x37] = "7", 557 | [0x38] = "8", 558 | [0x39] = "9", 559 | [0x3A] = ":", 560 | [0x3B] = ";", 561 | [0x3C] = "<", 562 | [0x3D] = "=", 563 | [0x3E] = ">", 564 | [0x3F] = "?", 565 | [0x40] = "@", 566 | [0x41] = "A", 567 | [0x42] = "B", 568 | [0x43] = "C", 569 | [0x44] = "D", 570 | [0x45] = "E", 571 | [0x46] = "F", 572 | [0x47] = "G", 573 | [0x48] = "H", 574 | [0x49] = "I", 575 | [0x4A] = "J", 576 | [0x4B] = "K", 577 | [0x4C] = "L", 578 | [0x4D] = "M", 579 | [0x4E] = "N", 580 | [0x4F] = "O", 581 | [0x50] = "P", 582 | [0x51] = "Q", 583 | [0x52] = "R", 584 | [0x53] = "S", 585 | [0x54] = "T", 586 | [0x55] = "U", 587 | [0x56] = "V", 588 | [0x57] = "W", 589 | [0x58] = "X", 590 | [0x59] = "Y", 591 | [0x5A] = "Z", 592 | [0x5B] = "[", 593 | [0x5C] = "\\", 594 | [0x5D] = "]", 595 | [0x5E] = "^", 596 | [0x5F] = "_", 597 | [0x60] = "`", 598 | [0x61] = "a", 599 | [0x62] = "b", 600 | [0x63] = "c", 601 | [0x64] = "d", 602 | [0x65] = "e", 603 | [0x66] = "f", 604 | [0x67] = "g", 605 | [0x68] = "h", 606 | [0x69] = "i", 607 | [0x6A] = "j", 608 | [0x6B] = "k", 609 | [0x6C] = "l", 610 | [0x6D] = "m", 611 | [0x6E] = "n", 612 | [0x6F] = "o", 613 | [0x70] = "p", 614 | [0x71] = "q", 615 | [0x72] = "r", 616 | [0x73] = "s", 617 | [0x74] = "t", 618 | [0x25] = "u", 619 | [0x76] = "v", 620 | [0x77] = "w", 621 | [0x28] = "x", 622 | [0x79] = "y", 623 | [0x7A] = "z", 624 | [0x7B] = "{", 625 | [0x7C] = "|", 626 | [0x7D] = "}", 627 | [0x7E] = "~", 628 | [0xA0] = " ", // NO-BREAK SPACE 629 | [0xA1] = "‘", // LEFT SINGLE QUOTATION MARK 630 | [0xA2] = "’", // RIGHT SINGLE QUOTATION MARK 631 | [0xA3] = "£", // POUND SIGN 632 | [0xA6] = "¦", // BROKEN BAR 633 | [0xA7] = "§", // SECTION SIGN 634 | [0xA8] = "¨", // DIAERESIS 635 | [0xA9] = "©", // COPYRIGHT SIGN 636 | [0xAB] = "«", // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 637 | [0xAC] = "¬", // NOT SIGN 638 | [0xAD] = "­", // SOFT HYPHEN 639 | [0xAF] = "―", // HORIZONTAL BAR 640 | [0xB0] = "°", // DEGREE SIGN 641 | [0xB1] = "±", // PLUS-MINUS SIGN 642 | [0xB2] = "²", // SUPERSCRIPT TWO 643 | [0xB3] = "³", // SUPERSCRIPT THREE 644 | [0xB4] = "΄", // GREEK TONOS 645 | [0xB5] = "΅", // GREEK DIALYTIKA TONOS 646 | [0xB6] = "Ά", // GREEK CAPITAL LETTER ALPHA WITH TONOS 647 | [0xB7] = "·", // MIDDLE DOT 648 | [0xB8] = "Έ", // GREEK CAPITAL LETTER EPSILON WITH TONOS 649 | [0xB9] = "Ή", // GREEK CAPITAL LETTER ETA WITH TONOS 650 | [0xBA] = "Ί", // GREEK CAPITAL LETTER IOTA WITH TONOS 651 | [0xBB] = "»", // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 652 | [0xBC] = "Ό", // GREEK CAPITAL LETTER OMICRON WITH TONOS 653 | [0xBD] = "½", // VULGAR FRACTION ONE HALF 654 | [0xBE] = "Ύ", // GREEK CAPITAL LETTER UPSILON WITH TONOS 655 | [0xBF] = "Ώ", // GREEK CAPITAL LETTER OMEGA WITH TONOS 656 | [0xC0] = "ΐ", // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS 657 | [0xC1] = "Α", // GREEK CAPITAL LETTER ALPHA 658 | [0xC2] = "Β", // GREEK CAPITAL LETTER BETA 659 | [0xC3] = "Γ", // GREEK CAPITAL LETTER GAMMA 660 | [0xC4] = "Δ", // GREEK CAPITAL LETTER DELTA 661 | [0xC5] = "Ε", // GREEK CAPITAL LETTER EPSILON 662 | [0xC6] = "Ζ", // GREEK CAPITAL LETTER ZETA 663 | [0xC7] = "Η", // GREEK CAPITAL LETTER ETA 664 | [0xC8] = "Θ", // GREEK CAPITAL LETTER THETA 665 | [0xC9] = "Ι", // GREEK CAPITAL LETTER IOTA 666 | [0xCA] = "Κ", // GREEK CAPITAL LETTER KAPPA 667 | [0xCB] = "Λ", // GREEK CAPITAL LETTER LAMDA 668 | [0xCC] = "Μ", // GREEK CAPITAL LETTER MU 669 | [0xCD] = "Ν", // GREEK CAPITAL LETTER NU 670 | [0xCE] = "Ξ", // GREEK CAPITAL LETTER XI 671 | [0xCF] = "Ο", // GREEK CAPITAL LETTER OMICRON 672 | [0xD0] = "Π", // GREEK CAPITAL LETTER PI 673 | [0xD1] = "Ρ", // GREEK CAPITAL LETTER RHO 674 | [0xD3] = "Σ", // GREEK CAPITAL LETTER SIGMA 675 | [0xD4] = "Τ", // GREEK CAPITAL LETTER TAU 676 | [0xD5] = "Υ", // GREEK CAPITAL LETTER UPSILON 677 | [0xD6] = "Φ", // GREEK CAPITAL LETTER PHI 678 | [0xD7] = "Χ", // GREEK CAPITAL LETTER CHI 679 | [0xD8] = "Ψ", // GREEK CAPITAL LETTER PSI 680 | [0xD9] = "Ω", // GREEK CAPITAL LETTER OMEGA 681 | [0xDA] = "Ϊ", // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA 682 | [0xDB] = "Ϋ", // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA 683 | [0xDC] = "ά", // GREEK SMALL LETTER ALPHA WITH TONOS 684 | [0xDD] = "έ", // GREEK SMALL LETTER EPSILON WITH TONOS 685 | [0xDE] = "ή", // GREEK SMALL LETTER ETA WITH TONOS 686 | [0xDF] = "ί", // GREEK SMALL LETTER IOTA WITH TONOS 687 | [0xE0] = "ΰ", // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS 688 | [0xE1] = "α", // GREEK SMALL LETTER ALPHA 689 | [0xE2] = "β", // GREEK SMALL LETTER BETA 690 | [0xE3] = "γ", // GREEK SMALL LETTER GAMMA 691 | [0xE4] = "δ", // GREEK SMALL LETTER DELTA 692 | [0xE5] = "ε", // GREEK SMALL LETTER EPSILON 693 | [0xE6] = "ζ", // GREEK SMALL LETTER ZETA 694 | [0xE7] = "η", // GREEK SMALL LETTER ETA 695 | [0xE8] = "θ", // GREEK SMALL LETTER THETA 696 | [0xE9] = "ι", // GREEK SMALL LETTER IOTA 697 | [0xEA] = "κ", // GREEK SMALL LETTER KAPPA 698 | [0xEB] = "λ", // GREEK SMALL LETTER LAMDA 699 | [0xEC] = "μ", // GREEK SMALL LETTER MU 700 | [0xED] = "ν", // GREEK SMALL LETTER NU 701 | [0xEE] = "ξ", // GREEK SMALL LETTER XI 702 | [0xEF] = "ο", // GREEK SMALL LETTER OMICRON 703 | [0xF0] = "π", // GREEK SMALL LETTER PI 704 | [0xF1] = "ρ", // GREEK SMALL LETTER RHO 705 | [0xF2] = "ς", // GREEK SMALL LETTER FINAL SIGMA 706 | [0xF3] = "σ", // GREEK SMALL LETTER SIGMA 707 | [0xF4] = "τ", // GREEK SMALL LETTER TAU 708 | [0xF5] = "υ", // GREEK SMALL LETTER UPSILON 709 | [0xF6] = "φ", // GREEK SMALL LETTER PHI 710 | [0xF7] = "χ", // GREEK SMALL LETTER CHI 711 | [0xF8] = "ψ", // GREEK SMALL LETTER PSI 712 | [0xF9] = "ω", // GREEK SMALL LETTER OMEGA 713 | [0xFA] = "ϊ", // GREEK SMALL LETTER IOTA WITH DIALYTIKA 714 | [0xFB] = "ϋ", // GREEK SMALL LETTER UPSILON WITH DIALYTIKA 715 | [0xFC] = "ό", // GREEK SMALL LETTER OMICRON WITH TONOS 716 | [0xFD] = "ύ", // GREEK SMALL LETTER UPSILON WITH TONOS 717 | [0xFE] = "ώ", // GREEK SMALL LETTER OMEGA WITH TONOS 718 | }, /* }}} */ 719 | [4] = { /* Character code table 04 - Latin/Hebrew alphabet - ISO 8859-8 {{{ */ 720 | [0x20] = " ", 721 | [0x21] = "!", 722 | [0x22] = """, 723 | [0x23] = "#", 724 | [0x24] = "$", 725 | [0x25] = "%", 726 | [0x26] = "&", 727 | [0x27] = "'", 728 | [0x28] = "(", 729 | [0x29] = ")", 730 | [0x2A] = "*", 731 | [0x2B] = "+", 732 | [0x2C] = ",", 733 | [0x2D] = "-", 734 | [0x2E] = ".", 735 | [0x2F] = "/", 736 | [0x30] = "0", 737 | [0x31] = "1", 738 | [0x32] = "2", 739 | [0x33] = "3", 740 | [0x34] = "4", 741 | [0x35] = "5", 742 | [0x36] = "6", 743 | [0x37] = "7", 744 | [0x38] = "8", 745 | [0x39] = "9", 746 | [0x3A] = ":", 747 | [0x3B] = ";", 748 | [0x3C] = "<", 749 | [0x3D] = "=", 750 | [0x3E] = ">", 751 | [0x3F] = "?", 752 | [0x40] = "@", 753 | [0x41] = "A", 754 | [0x42] = "B", 755 | [0x43] = "C", 756 | [0x44] = "D", 757 | [0x45] = "E", 758 | [0x46] = "F", 759 | [0x47] = "G", 760 | [0x48] = "H", 761 | [0x49] = "I", 762 | [0x4A] = "J", 763 | [0x4B] = "K", 764 | [0x4C] = "L", 765 | [0x4D] = "M", 766 | [0x4E] = "N", 767 | [0x4F] = "O", 768 | [0x50] = "P", 769 | [0x51] = "Q", 770 | [0x52] = "R", 771 | [0x53] = "S", 772 | [0x54] = "T", 773 | [0x55] = "U", 774 | [0x56] = "V", 775 | [0x57] = "W", 776 | [0x58] = "X", 777 | [0x59] = "Y", 778 | [0x5A] = "Z", 779 | [0x5B] = "[", 780 | [0x5C] = "\\", 781 | [0x5D] = "]", 782 | [0x5E] = "^", 783 | [0x5F] = "_", 784 | [0x60] = "`", 785 | [0x61] = "a", 786 | [0x62] = "b", 787 | [0x63] = "c", 788 | [0x64] = "d", 789 | [0x65] = "e", 790 | [0x66] = "f", 791 | [0x67] = "g", 792 | [0x68] = "h", 793 | [0x69] = "i", 794 | [0x6A] = "j", 795 | [0x6B] = "k", 796 | [0x6C] = "l", 797 | [0x6D] = "m", 798 | [0x6E] = "n", 799 | [0x6F] = "o", 800 | [0x70] = "p", 801 | [0x71] = "q", 802 | [0x72] = "r", 803 | [0x73] = "s", 804 | [0x74] = "t", 805 | [0x25] = "u", 806 | [0x76] = "v", 807 | [0x77] = "w", 808 | [0x28] = "x", 809 | [0x79] = "y", 810 | [0x7A] = "z", 811 | [0x7B] = "{", 812 | [0x7C] = "|", 813 | [0x7D] = "}", 814 | [0x7E] = "~", 815 | [0xA0] = " ", // NO-BREAK SPACE 816 | [0xA2] = "¢", // CENT SIGN 817 | [0xA3] = "£", // POUND SIGN 818 | [0xA4] = "¤", // CURRENCY SIGN 819 | [0xA5] = "¥", // YEN SIGN 820 | [0xA6] = "¦", // BROKEN BAR 821 | [0xA7] = "§", // SECTION SIGN 822 | [0xA8] = "¨", // DIAERESIS 823 | [0xA9] = "©", // COPYRIGHT SIGN 824 | [0xAA] = "×", // MULTIPLICATION SIGN 825 | [0xAB] = "«", // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 826 | [0xAC] = "¬", // NOT SIGN 827 | [0xAD] = "­", // SOFT HYPHEN 828 | [0xAE] = "®", // REGISTERED SIGN 829 | [0xAF] = "¯", // MACRON 830 | [0xB0] = "°", // DEGREE SIGN 831 | [0xB1] = "±", // PLUS-MINUS SIGN 832 | [0xB2] = "²", // SUPERSCRIPT TWO 833 | [0xB3] = "³", // SUPERSCRIPT THREE 834 | [0xB4] = "´", // ACUTE ACCENT 835 | [0xB5] = "µ", // MICRO SIGN 836 | [0xB6] = "¶", // PILCROW SIGN 837 | [0xB7] = "·", // MIDDLE DOT 838 | [0xB8] = "¸", // CEDILLA 839 | [0xB9] = "¹", // SUPERSCRIPT ONE 840 | [0xBA] = "÷", // DIVISION SIGN 841 | [0xBB] = "»", // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 842 | [0xBC] = "¼", // VULGAR FRACTION ONE QUARTER 843 | [0xBD] = "½", // VULGAR FRACTION ONE HALF 844 | [0xBE] = "¾", // VULGAR FRACTION THREE QUARTERS 845 | [0xDF] = "‗", // DOUBLE LOW LINE 846 | [0xE0] = "א", // HEBREW LETTER ALEF 847 | [0xE1] = "ב", // HEBREW LETTER BET 848 | [0xE2] = "ג", // HEBREW LETTER GIMEL 849 | [0xE3] = "ד", // HEBREW LETTER DALET 850 | [0xE4] = "ה", // HEBREW LETTER HE 851 | [0xE5] = "ו", // HEBREW LETTER VAV 852 | [0xE6] = "ז", // HEBREW LETTER ZAYIN 853 | [0xE7] = "ח", // HEBREW LETTER HET 854 | [0xE8] = "ט", // HEBREW LETTER TET 855 | [0xE9] = "י", // HEBREW LETTER YOD 856 | [0xEA] = "ך", // HEBREW LETTER FINAL KAF 857 | [0xEB] = "כ", // HEBREW LETTER KAF 858 | [0xEC] = "ל", // HEBREW LETTER LAMED 859 | [0xED] = "ם", // HEBREW LETTER FINAL MEM 860 | [0xEE] = "מ", // HEBREW LETTER MEM 861 | [0xEF] = "ן", // HEBREW LETTER FINAL NUN 862 | [0xF0] = "נ", // HEBREW LETTER NUN 863 | [0xF1] = "ס", // HEBREW LETTER SAMEKH 864 | [0xF2] = "ע", // HEBREW LETTER AYIN 865 | [0xF3] = "ף", // HEBREW LETTER FINAL PE 866 | [0xF4] = "פ", // HEBREW LETTER PE 867 | [0xF5] = "ץ", // HEBREW LETTER FINAL TSADI 868 | [0xF6] = "צ", // HEBREW LETTER TSADI 869 | [0xF7] = "ק", // HEBREW LETTER QOF 870 | [0xF8] = "ר", // HEBREW LETTER RESH 871 | [0xF9] = "ש", // HEBREW LETTER SHIN 872 | [0xFA] = "ת", // HEBREW LETTER TAV 873 | [0xFD] = "‎", // LEFT-TO-RIGHT MARK 874 | [0xFE] = "‏", // RIGHT-TO-LEFT MARK 875 | }, /* }}} */ 876 | [5] = { /* Character code table 05 - Latin alphabet number 5 - ISO 8859-9 {{{ */ 877 | [0x20] = " ", 878 | [0x21] = "!", 879 | [0x22] = """, 880 | [0x23] = "#", 881 | [0x24] = "$", 882 | [0x25] = "%", 883 | [0x26] = "&", 884 | [0x27] = "'", 885 | [0x28] = "(", 886 | [0x29] = ")", 887 | [0x2A] = "*", 888 | [0x2B] = "+", 889 | [0x2C] = ",", 890 | [0x2D] = "-", 891 | [0x2E] = ".", 892 | [0x2F] = "/", 893 | [0x30] = "0", 894 | [0x31] = "1", 895 | [0x32] = "2", 896 | [0x33] = "3", 897 | [0x34] = "4", 898 | [0x35] = "5", 899 | [0x36] = "6", 900 | [0x37] = "7", 901 | [0x38] = "8", 902 | [0x39] = "9", 903 | [0x3A] = ":", 904 | [0x3B] = ";", 905 | [0x3C] = "<", 906 | [0x3D] = "=", 907 | [0x3E] = ">", 908 | [0x3F] = "?", 909 | [0x40] = "@", 910 | [0x41] = "A", 911 | [0x42] = "B", 912 | [0x43] = "C", 913 | [0x44] = "D", 914 | [0x45] = "E", 915 | [0x46] = "F", 916 | [0x47] = "G", 917 | [0x48] = "H", 918 | [0x49] = "I", 919 | [0x4A] = "J", 920 | [0x4B] = "K", 921 | [0x4C] = "L", 922 | [0x4D] = "M", 923 | [0x4E] = "N", 924 | [0x4F] = "O", 925 | [0x50] = "P", 926 | [0x51] = "Q", 927 | [0x52] = "R", 928 | [0x53] = "S", 929 | [0x54] = "T", 930 | [0x55] = "U", 931 | [0x56] = "V", 932 | [0x57] = "W", 933 | [0x58] = "X", 934 | [0x59] = "Y", 935 | [0x5A] = "Z", 936 | [0x5B] = "[", 937 | [0x5C] = "\\", 938 | [0x5D] = "]", 939 | [0x5E] = "^", 940 | [0x5F] = "_", 941 | [0x60] = "`", 942 | [0x61] = "a", 943 | [0x62] = "b", 944 | [0x63] = "c", 945 | [0x64] = "d", 946 | [0x65] = "e", 947 | [0x66] = "f", 948 | [0x67] = "g", 949 | [0x68] = "h", 950 | [0x69] = "i", 951 | [0x6A] = "j", 952 | [0x6B] = "k", 953 | [0x6C] = "l", 954 | [0x6D] = "m", 955 | [0x6E] = "n", 956 | [0x6F] = "o", 957 | [0x70] = "p", 958 | [0x71] = "q", 959 | [0x72] = "r", 960 | [0x73] = "s", 961 | [0x74] = "t", 962 | [0x25] = "u", 963 | [0x76] = "v", 964 | [0x77] = "w", 965 | [0x28] = "x", 966 | [0x79] = "y", 967 | [0x7A] = "z", 968 | [0x7B] = "{", 969 | [0x7C] = "|", 970 | [0x7D] = "}", 971 | [0x7E] = "~", 972 | [0xA0] = " ", // NO-BREAK SPACE 973 | [0xA1] = "¡", // INVERTED EXCLAMATION MARK 974 | [0xA2] = "¢", // CENT SIGN 975 | [0xA3] = "£", // POUND SIGN 976 | [0xA4] = "¤", // CURRENCY SIGN 977 | [0xA5] = "¥", // YEN SIGN 978 | [0xA6] = "¦", // BROKEN BAR 979 | [0xA7] = "§", // SECTION SIGN 980 | [0xA8] = "¨", // DIAERESIS 981 | [0xA9] = "©", // COPYRIGHT SIGN 982 | [0xAA] = "ª", // FEMININE ORDINAL INDICATOR 983 | [0xAB] = "«", // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 984 | [0xAC] = "¬", // NOT SIGN 985 | [0xAD] = "­", // SOFT HYPHEN 986 | [0xAE] = "®", // REGISTERED SIGN 987 | [0xAF] = "¯", // MACRON 988 | [0xB0] = "°", // DEGREE SIGN 989 | [0xB1] = "±", // PLUS-MINUS SIGN 990 | [0xB2] = "²", // SUPERSCRIPT TWO 991 | [0xB3] = "³", // SUPERSCRIPT THREE 992 | [0xB4] = "´", // ACUTE ACCENT 993 | [0xB5] = "µ", // MICRO SIGN 994 | [0xB6] = "¶", // PILCROW SIGN 995 | [0xB7] = "·", // MIDDLE DOT 996 | [0xB8] = "¸", // CEDILLA 997 | [0xB9] = "¹", // SUPERSCRIPT ONE 998 | [0xBA] = "º", // MASCULINE ORDINAL INDICATOR 999 | [0xBB] = "»", // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 1000 | [0xBC] = "¼", // VULGAR FRACTION ONE QUARTER 1001 | [0xBD] = "½", // VULGAR FRACTION ONE HALF 1002 | [0xBE] = "¾", // VULGAR FRACTION THREE QUARTERS 1003 | [0xBF] = "¿", // INVERTED QUESTION MARK 1004 | [0xC0] = "À", // LATIN CAPITAL LETTER A WITH GRAVE 1005 | [0xC1] = "Á", // LATIN CAPITAL LETTER A WITH ACUTE 1006 | [0xC2] = "Â", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX 1007 | [0xC3] = "Ã", // LATIN CAPITAL LETTER A WITH TILDE 1008 | [0xC4] = "Ä", // LATIN CAPITAL LETTER A WITH DIAERESIS 1009 | [0xC5] = "Å", // LATIN CAPITAL LETTER A WITH RING ABOVE 1010 | [0xC6] = "Æ", // LATIN CAPITAL LETTER AE 1011 | [0xC7] = "Ç", // LATIN CAPITAL LETTER C WITH CEDILLA 1012 | [0xC8] = "È", // LATIN CAPITAL LETTER E WITH GRAVE 1013 | [0xC9] = "É", // LATIN CAPITAL LETTER E WITH ACUTE 1014 | [0xCA] = "Ê", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX 1015 | [0xCB] = "Ë", // LATIN CAPITAL LETTER E WITH DIAERESIS 1016 | [0xCC] = "Ì", // LATIN CAPITAL LETTER I WITH GRAVE 1017 | [0xCD] = "Í", // LATIN CAPITAL LETTER I WITH ACUTE 1018 | [0xCE] = "Î", // LATIN CAPITAL LETTER I WITH CIRCUMFLEX 1019 | [0xCF] = "Ï", // LATIN CAPITAL LETTER I WITH DIAERESIS 1020 | [0xD0] = "Ğ", // LATIN CAPITAL LETTER G WITH BREVE 1021 | [0xD1] = "Ñ", // LATIN CAPITAL LETTER N WITH TILDE 1022 | [0xD2] = "Ò", // LATIN CAPITAL LETTER O WITH GRAVE 1023 | [0xD3] = "Ó", // LATIN CAPITAL LETTER O WITH ACUTE 1024 | [0xD4] = "Ô", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX 1025 | [0xD5] = "Õ", // LATIN CAPITAL LETTER O WITH TILDE 1026 | [0xD6] = "Ö", // LATIN CAPITAL LETTER O WITH DIAERESIS 1027 | [0xD7] = "×", // MULTIPLICATION SIGN 1028 | [0xD8] = "Ø", // LATIN CAPITAL LETTER O WITH STROKE 1029 | [0xD9] = "Ù", // LATIN CAPITAL LETTER U WITH GRAVE 1030 | [0xDA] = "Ú", // LATIN CAPITAL LETTER U WITH ACUTE 1031 | [0xDB] = "Û", // LATIN CAPITAL LETTER U WITH CIRCUMFLEX 1032 | [0xDC] = "Ü", // LATIN CAPITAL LETTER U WITH DIAERESIS 1033 | [0xDD] = "İ", // LATIN CAPITAL LETTER I WITH DOT ABOVE 1034 | [0xDE] = "Ş", // LATIN CAPITAL LETTER S WITH CEDILLA 1035 | [0xDF] = "ß", // LATIN SMALL LETTER SHARP S 1036 | [0xE0] = "à", // LATIN SMALL LETTER A WITH GRAVE 1037 | [0xE1] = "á", // LATIN SMALL LETTER A WITH ACUTE 1038 | [0xE2] = "â", // LATIN SMALL LETTER A WITH CIRCUMFLEX 1039 | [0xE3] = "ã", // LATIN SMALL LETTER A WITH TILDE 1040 | [0xE4] = "ä", // LATIN SMALL LETTER A WITH DIAERESIS 1041 | [0xE5] = "å", // LATIN SMALL LETTER A WITH RING ABOVE 1042 | [0xE6] = "æ", // LATIN SMALL LETTER AE 1043 | [0xE7] = "ç", // LATIN SMALL LETTER C WITH CEDILLA 1044 | [0xE8] = "è", // LATIN SMALL LETTER E WITH GRAVE 1045 | [0xE9] = "é", // LATIN SMALL LETTER E WITH ACUTE 1046 | [0xEA] = "ê", // LATIN SMALL LETTER E WITH CIRCUMFLEX 1047 | [0xEB] = "ë", // LATIN SMALL LETTER E WITH DIAERESIS 1048 | [0xEC] = "ì", // LATIN SMALL LETTER I WITH GRAVE 1049 | [0xED] = "í", // LATIN SMALL LETTER I WITH ACUTE 1050 | [0xEE] = "î", // LATIN SMALL LETTER I WITH CIRCUMFLEX 1051 | [0xEF] = "ï", // LATIN SMALL LETTER I WITH DIAERESIS 1052 | [0xF0] = "ğ", // LATIN SMALL LETTER G WITH BREVE 1053 | [0xF1] = "ñ", // LATIN SMALL LETTER N WITH TILDE 1054 | [0xF2] = "ò", // LATIN SMALL LETTER O WITH GRAVE 1055 | [0xF3] = "ó", // LATIN SMALL LETTER O WITH ACUTE 1056 | [0xF4] = "ô", // LATIN SMALL LETTER O WITH CIRCUMFLEX 1057 | [0xF5] = "õ", // LATIN SMALL LETTER O WITH TILDE 1058 | [0xF6] = "ö", // LATIN SMALL LETTER O WITH DIAERESIS 1059 | [0xF7] = "÷", // DIVISION SIGN 1060 | [0xF8] = "ø", // LATIN SMALL LETTER O WITH STROKE 1061 | [0xF9] = "ù", // LATIN SMALL LETTER U WITH GRAVE 1062 | [0xFA] = "ú", // LATIN SMALL LETTER U WITH ACUTE 1063 | [0xFB] = "û", // LATIN SMALL LETTER U WITH CIRCUMFLEX 1064 | [0xFC] = "ü", // LATIN SMALL LETTER U WITH DIAERESIS 1065 | [0xFD] = "ı", // LATIN SMALL LETTER DOTLESS I 1066 | [0xFE] = "ş", // LATIN SMALL LETTER S WITH CEDILLA 1067 | [0xFF] = "ÿ", // LATIN SMALL LETTER Y WITH DIAERESIS 1068 | } /* }}} */ 1069 | }; 1070 | 1071 | /* Quote the xml entities in the string passed in. 1072 | * NB this is returned as a pointer to a string on the heap which will 1073 | * be re-used on the next call to xmlify() 1074 | * Patched by Nick Craig-Wood - nick craig-wood com for more chars with 1075 | * strcat func for tidyness 1076 | */ 1077 | char *xmlify(const char *s, int len) { 1078 | static char *xml = NULL; 1079 | static unsigned bufsz = 0; 1080 | char *r; 1081 | unsigned int table = 0; 1082 | int max_len = strlen(s) * 10 + 1; /* Max possible expansion of string n * " + NULL */ 1083 | /* A little untidy but fast! */ 1084 | 1085 | /* Patch by Steve Davies for better memory management */ 1086 | if (bufsz < max_len || xml == NULL) { 1087 | xml = realloc(xml, max_len); 1088 | bufsz = max_len; 1089 | } 1090 | 1091 | switch ((unsigned char)*s) { 1092 | case 0x20 ... 0xFF: // if the first byte of the text field has a value in the range of "0x20" to "0xFF" then this and all subsequent bytes in the text item are coded using the default coding table (table 00 - Latin alphabet) of figure A.1 1093 | table = 0; 1094 | break; 1095 | case 0x01 ... 0x05: // if the first byte of the text field is in the range "0x01" to "0x05" then the remaining bytes in the text item are coded in accordance with character coding table 01 to 05 respectively, which are given in figures A.2 to A.6 respectively 1096 | table = *s++; 1097 | break; 1098 | case 0x10: // if the first byte of the text field has a value "0x10" then the following two bytes carry a 16-bit value (uimsbf) N to indicate that the remaining data of the text field is coded using the character code table specified by ISO Standard 8859, Parts 1 to 9. 1099 | fprintf(stderr, "Unhandled encoding ISO 8859-%02x%02x\n", s[1], s[2]); 1100 | s += 3; 1101 | return NULL; 1102 | case 0x11: // if the first byte of the text field has a value "0x11" then the ramaining bytes in the text item are coded in pairs in accordance with the Basic Multilingual Plane of ISO/IEC 10646-1 1103 | fprintf(stderr, "Unhandled encoding ISO 10646-1\n"); 1104 | return NULL; 1105 | case 0x06 ... 0x0F: case 0x12 ... 0x1F: // Values for the first byte of "0x00", "0x06" to "0x0F", and "0x12" to "0x1F" are reserved for future use. 1106 | fprintf(stderr, "Reserved encoding: %02x\n", s[0]); 1107 | return NULL; 1108 | case 0x00: // empty string 1109 | return ""; 1110 | } 1111 | 1112 | for (r = xml; *s != '\0'; s++) { 1113 | unsigned int i = (unsigned char)*s; 1114 | const char *entity = codeset[table][i]; 1115 | if (!entity[0]) { 1116 | static char buf[10]; 1117 | snprintf(buf, 10, "", i); 1118 | entity = buf; 1119 | } 1120 | while (*entity) 1121 | *r++ = *entity++; 1122 | } 1123 | *r = '\0'; 1124 | return xml; 1125 | } 1126 | 1127 | #ifdef MAIN 1128 | int main(int argc, char **argv) { 1129 | if (argc > 1) 1130 | printf("%s\n%s\n", argv[1], xmlify(argv[1])); 1131 | return 0; 1132 | } 1133 | #endif 1134 | // vim: foldmethod=marker 1135 | -------------------------------------------------------------------------------- /dvb_text_iconv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define MAX 1024 9 | static char buf[MAX * 6]; /* UTF-8 needs up to 6 bytes */ 10 | static char result[MAX * 6]; /* xml-ification needs up to 6 bytes */ 11 | 12 | /* The spec says ISO-6937, but many stations get it wrong and use ISO-8859-1. */ 13 | char *iso6937_encoding = "ISO6937"; 14 | 15 | static int encoding_default(char *t, const char **s, const char *d) { 16 | strncpy(t, iso6937_encoding, 16); 17 | return 0; 18 | } 19 | 20 | static int encoding_fixed(char *t, const char **s, const char *d) { 21 | strncpy(t, d, 16); 22 | *s += 1; 23 | return 0; 24 | } 25 | 26 | static int encoding_variable(char *t, const char **s, const char *d) { 27 | int i = ((unsigned char)(*s)[1] << 8) + (unsigned char)(*s)[2]; 28 | snprintf(t, 16, d, i); 29 | *s += 3; 30 | 31 | return 0; 32 | } 33 | 34 | static int encoding_reserved(char *t, const char **s, const char *d) { 35 | fprintf(stderr, "Reserved encoding: %02x\n", *s[0]); 36 | return 1; 37 | } 38 | 39 | static const struct encoding { 40 | int (*handler)(char *t, const char **s, const char *d); 41 | const char *data; 42 | } encoding[256] = { 43 | [0x00] = {encoding_reserved, NULL}, 44 | [0x01] = {encoding_fixed, "ISO-8859-5"}, 45 | [0x02] = {encoding_fixed, "ISO-8859-6"}, 46 | [0x03] = {encoding_fixed, "ISO-8859-7"}, 47 | [0x04] = {encoding_fixed, "ISO-8859-8"}, 48 | [0x05] = {encoding_fixed, "ISO-8859-9"}, 49 | [0x06] = {encoding_fixed, "ISO-8859-10"}, 50 | [0x07] = {encoding_fixed, "ISO-8859-11"}, 51 | [0x08] = {encoding_fixed, "ISO-8859-12"}, 52 | [0x09] = {encoding_fixed, "ISO-8859-13"}, 53 | [0x0A] = {encoding_fixed, "ISO-8859-14"}, 54 | [0x0B] = {encoding_fixed, "ISO-8859-15"}, 55 | [0x0C] = {encoding_reserved, NULL}, 56 | [0x0D] = {encoding_reserved, NULL}, 57 | [0x0E] = {encoding_reserved, NULL}, 58 | [0x0F] = {encoding_reserved, NULL}, 59 | [0x10] = {encoding_variable, "ISO-8859-%d"}, 60 | [0x11] = {encoding_fixed, "ISO-10646/UCS2"}, // FIXME: UCS-2 LE/BE ??? 61 | [0x12] = {encoding_fixed, "KSC_5601"}, // TODO needs newer iconv 62 | [0x13] = {encoding_fixed, "GB_2312-80"}, 63 | [0x14] = {encoding_fixed, "UTF-16BE"}, 64 | [0x15] = {encoding_fixed, "ISO-10646/UTF8"}, 65 | [0x16] = {encoding_reserved, NULL}, 66 | [0x17] = {encoding_reserved, NULL}, 67 | [0x18] = {encoding_reserved, NULL}, 68 | [0x19] = {encoding_reserved, NULL}, 69 | [0x1A] = {encoding_reserved, NULL}, 70 | [0x1B] = {encoding_reserved, NULL}, 71 | [0x1C] = {encoding_reserved, NULL}, 72 | [0x1D] = {encoding_reserved, NULL}, 73 | [0x1E] = {encoding_reserved, NULL}, 74 | [0x1F] = {encoding_reserved, NULL}, 75 | [0x20 ... 0xFF] = {encoding_default, NULL}, 76 | }; 77 | 78 | static char cs_old[16]; 79 | static iconv_t cd; 80 | 81 | /* Quote the xml entities in the string passed in. 82 | */ 83 | char *xmlify(const char *s, int *len) { 84 | char cs_new[16]; 85 | 86 | int i = (int)(unsigned char)s[0]; 87 | /* get the string encoding, then remove the first byte(s) */ 88 | if (encoding[i].handler(cs_new, &s, encoding[i].data)) 89 | return ""; 90 | if (strncmp(cs_old, cs_new, 16)) { 91 | if (cd) { 92 | iconv_close(cd); 93 | cd = NULL; 94 | } // if 95 | cd = iconv_open("UTF-8", cs_new); 96 | if (cd == (iconv_t)-1) { 97 | fprintf(stderr, "iconv_open() failed: %s\n", strerror(errno)); 98 | exit(1); 99 | } // if 100 | strncpy(cs_old, cs_new, 16); 101 | } // if 102 | 103 | char *inbuf = (char *)s; 104 | size_t inbytesleft = (size_t)len; 105 | char *outbuf = (char *)buf; 106 | size_t outbytesleft = sizeof(buf); 107 | size_t ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); 108 | if (ret == (size_t)-1) { 109 | fprintf(stderr, "iconv() failed: %s\n", strerror(errno)); 110 | /*exit(1); // FIXME: handle errors*/ 111 | } // if 112 | 113 | // Luckily '&<> are single byte character sequences in UTF-8 and no 114 | // other character will have a UTF-8 sequence containing these 115 | // patterns. Because the MSB is set in all multi-byte sequences, we can 116 | // simply scan for '&<> and don't have to parse UTF-8 sequences. 117 | 118 | char *b = buf, *r = result; 119 | for ( ; b < outbuf; b++) 120 | switch (*b) { 121 | #if 0 // only needed for attributes 122 | case '"': 123 | *r++ = '&'; 124 | *r++ = 'q'; 125 | *r++ = 'u'; 126 | *r++ = 'o'; 127 | *r++ = 't'; 128 | *r++ = ';'; 129 | break; 130 | #endif 131 | case '&': 132 | *r++ = '&'; 133 | *r++ = 'a'; 134 | *r++ = 'm'; 135 | *r++ = 'p'; 136 | *r++ = ';'; 137 | break; 138 | case '<': 139 | *r++ = '&'; 140 | *r++ = 'l'; 141 | *r++ = 't'; 142 | *r++ = ';'; 143 | break; 144 | case '>': 145 | *r++ = '&'; 146 | *r++ = 'g'; 147 | *r++ = 't'; 148 | *r++ = ';'; 149 | break; 150 | case 0x0000 ... 0x0008: 151 | case 0x000B ... 0x001F: 152 | case 0x007F: 153 | fprintf(stderr, "Forbidden char %02x\n", *b); 154 | default: 155 | *r++ = *b; 156 | break; 157 | } // switch 158 | 159 | *r = '\0'; 160 | return result; 161 | } // xmlify 162 | 163 | #ifdef MAIN 164 | int main(int argc, char **argv) { 165 | if (argc > 1) 166 | printf("%s\n%s\n", argv[1], xmlify(argv[1])); 167 | return 0; 168 | } // main 169 | #endif 170 | -------------------------------------------------------------------------------- /etc/dvb_channel.conf: -------------------------------------------------------------------------------- 1 | [中視] 2 | SERVICE_ID = 100 3 | NETWORK_ID = 8350 4 | TRANSPORT_ID = 24 5 | VIDEO_PID = 1001 6 | AUDIO_PID = 1002 1003 7 | FREQUENCY = 533000000 8 | MODULATION = QAM/64 9 | BANDWIDTH_HZ = 6000000 10 | INVERSION = AUTO 11 | CODE_RATE_HP = 2/3 12 | CODE_RATE_LP = 1/2 13 | GUARD_INTERVAL = 1/4 14 | TRANSMISSION_MODE = 8K 15 | HIERARCHY = NONE 16 | DELIVERY_SYSTEM = DVBT 17 | 18 | [中視新聞台] 19 | SERVICE_ID = 101 20 | NETWORK_ID = 8350 21 | TRANSPORT_ID = 24 22 | VIDEO_PID = 1011 23 | AUDIO_PID = 1012 24 | FREQUENCY = 533000000 25 | MODULATION = QAM/64 26 | BANDWIDTH_HZ = 6000000 27 | INVERSION = AUTO 28 | CODE_RATE_HP = 2/3 29 | CODE_RATE_LP = 1/2 30 | GUARD_INTERVAL = 1/4 31 | TRANSMISSION_MODE = 8K 32 | HIERARCHY = NONE 33 | DELIVERY_SYSTEM = DVBT 34 | 35 | [中視經典台] 36 | SERVICE_ID = 102 37 | NETWORK_ID = 8350 38 | TRANSPORT_ID = 24 39 | VIDEO_PID = 1021 40 | AUDIO_PID = 1022 1023 41 | FREQUENCY = 533000000 42 | MODULATION = QAM/64 43 | BANDWIDTH_HZ = 6000000 44 | INVERSION = AUTO 45 | CODE_RATE_HP = 2/3 46 | CODE_RATE_LP = 1/2 47 | GUARD_INTERVAL = 1/4 48 | TRANSMISSION_MODE = 8K 49 | HIERARCHY = NONE 50 | DELIVERY_SYSTEM = DVBT 51 | 52 | [中視菁采台] 53 | SERVICE_ID = 103 54 | NETWORK_ID = 8350 55 | TRANSPORT_ID = 24 56 | VIDEO_PID = 1031 57 | AUDIO_PID = 1032 1033 58 | FREQUENCY = 533000000 59 | MODULATION = QAM/64 60 | BANDWIDTH_HZ = 6000000 61 | INVERSION = AUTO 62 | CODE_RATE_HP = 2/3 63 | CODE_RATE_LP = 1/2 64 | GUARD_INTERVAL = 1/4 65 | TRANSMISSION_MODE = 8K 66 | HIERARCHY = NONE 67 | DELIVERY_SYSTEM = DVBT 68 | 69 | [公視 PTS] 70 | SERVICE_ID = 201 71 | NETWORK_ID = 8350 72 | TRANSPORT_ID = 26 73 | VIDEO_PID = 2011 74 | AUDIO_PID = 2012 2013 75 | FREQUENCY = 545000000 76 | MODULATION = QAM/64 77 | BANDWIDTH_HZ = 6000000 78 | INVERSION = AUTO 79 | CODE_RATE_HP = 2/3 80 | CODE_RATE_LP = 1/2 81 | GUARD_INTERVAL = 1/4 82 | TRANSMISSION_MODE = 8K 83 | HIERARCHY = NONE 84 | DELIVERY_SYSTEM = DVBT 85 | 86 | [公視台語台] 87 | SERVICE_ID = 202 88 | NETWORK_ID = 8350 89 | TRANSPORT_ID = 26 90 | VIDEO_PID = 2021 91 | AUDIO_PID = 2022 2023 92 | FREQUENCY = 545000000 93 | MODULATION = QAM/64 94 | BANDWIDTH_HZ = 6000000 95 | INVERSION = AUTO 96 | CODE_RATE_HP = 2/3 97 | CODE_RATE_LP = 1/2 98 | GUARD_INTERVAL = 1/4 99 | TRANSMISSION_MODE = 8K 100 | HIERARCHY = NONE 101 | DELIVERY_SYSTEM = DVBT 102 | 103 | [民視] 104 | SERVICE_ID = 300 105 | NETWORK_ID = 8350 106 | TRANSPORT_ID = 28 107 | VIDEO_PID = 3001 108 | AUDIO_PID = 3002 3003 109 | FREQUENCY = 557000000 110 | MODULATION = QAM/64 111 | BANDWIDTH_HZ = 6000000 112 | INVERSION = AUTO 113 | CODE_RATE_HP = 2/3 114 | CODE_RATE_LP = 1/2 115 | GUARD_INTERVAL = 1/4 116 | TRANSMISSION_MODE = 8K 117 | HIERARCHY = NONE 118 | DELIVERY_SYSTEM = DVBT 119 | 120 | [民視第一台] 121 | SERVICE_ID = 301 122 | NETWORK_ID = 8350 123 | TRANSPORT_ID = 28 124 | VIDEO_PID = 3011 125 | AUDIO_PID = 3012 3013 126 | FREQUENCY = 557000000 127 | MODULATION = QAM/64 128 | BANDWIDTH_HZ = 6000000 129 | INVERSION = AUTO 130 | CODE_RATE_HP = 2/3 131 | CODE_RATE_LP = 1/2 132 | GUARD_INTERVAL = 1/4 133 | TRANSMISSION_MODE = 8K 134 | HIERARCHY = NONE 135 | DELIVERY_SYSTEM = DVBT 136 | 137 | [民視新聞台] 138 | SERVICE_ID = 302 139 | NETWORK_ID = 8350 140 | TRANSPORT_ID = 28 141 | VIDEO_PID = 3021 142 | AUDIO_PID = 3022 143 | FREQUENCY = 557000000 144 | MODULATION = QAM/64 145 | BANDWIDTH_HZ = 6000000 146 | INVERSION = AUTO 147 | CODE_RATE_HP = 2/3 148 | CODE_RATE_LP = 1/2 149 | GUARD_INTERVAL = 1/4 150 | TRANSMISSION_MODE = 8K 151 | HIERARCHY = NONE 152 | DELIVERY_SYSTEM = DVBT 153 | 154 | [民視台灣台] 155 | SERVICE_ID = 304 156 | NETWORK_ID = 8350 157 | TRANSPORT_ID = 28 158 | VIDEO_PID = 3041 159 | AUDIO_PID = 3042 3043 160 | FREQUENCY = 557000000 161 | MODULATION = QAM/64 162 | BANDWIDTH_HZ = 6000000 163 | INVERSION = AUTO 164 | CODE_RATE_HP = 2/3 165 | CODE_RATE_LP = 1/2 166 | GUARD_INTERVAL = 1/4 167 | TRANSMISSION_MODE = 8K 168 | HIERARCHY = NONE 169 | DELIVERY_SYSTEM = DVBT 170 | 171 | [公視3台 PTS3] 172 | SERVICE_ID = 200 173 | NETWORK_ID = 8350 174 | TRANSPORT_ID = 30 175 | VIDEO_PID = 2001 176 | AUDIO_PID = 2002 2003 177 | FREQUENCY = 569000000 178 | MODULATION = QAM/64 179 | BANDWIDTH_HZ = 6000000 180 | INVERSION = AUTO 181 | CODE_RATE_HP = 2/3 182 | CODE_RATE_LP = 1/2 183 | GUARD_INTERVAL = 1/4 184 | TRANSMISSION_MODE = 8K 185 | HIERARCHY = NONE 186 | DELIVERY_SYSTEM = DVBT 187 | 188 | [客家電視] 189 | SERVICE_ID = 204 190 | NETWORK_ID = 8350 191 | TRANSPORT_ID = 30 192 | VIDEO_PID = 2041 193 | AUDIO_PID = 2042 2043 194 | FREQUENCY = 569000000 195 | MODULATION = QAM/64 196 | BANDWIDTH_HZ = 6000000 197 | INVERSION = AUTO 198 | CODE_RATE_HP = 2/3 199 | CODE_RATE_LP = 1/2 200 | GUARD_INTERVAL = 1/4 201 | TRANSMISSION_MODE = 8K 202 | HIERARCHY = NONE 203 | DELIVERY_SYSTEM = DVBT 204 | 205 | [原住民族電視台] 206 | SERVICE_ID = 205 207 | NETWORK_ID = 8350 208 | TRANSPORT_ID = 30 209 | VIDEO_PID = 2051 210 | AUDIO_PID = 2052 2053 211 | FREQUENCY = 569000000 212 | MODULATION = QAM/64 213 | BANDWIDTH_HZ = 6000000 214 | INVERSION = AUTO 215 | CODE_RATE_HP = 2/3 216 | CODE_RATE_LP = 1/2 217 | GUARD_INTERVAL = 1/4 218 | TRANSMISSION_MODE = 8K 219 | HIERARCHY = NONE 220 | DELIVERY_SYSTEM = DVBT 221 | 222 | [台灣電視台] 223 | SERVICE_ID = 400 224 | NETWORK_ID = 8350 225 | TRANSPORT_ID = 32 226 | VIDEO_PID = 4001 227 | AUDIO_PID = 4002 4003 228 | FREQUENCY = 581000000 229 | MODULATION = QAM/64 230 | BANDWIDTH_HZ = 6000000 231 | INVERSION = AUTO 232 | CODE_RATE_HP = 2/3 233 | CODE_RATE_LP = 1/2 234 | GUARD_INTERVAL = 1/4 235 | TRANSMISSION_MODE = 8K 236 | HIERARCHY = NONE 237 | DELIVERY_SYSTEM = DVBT 238 | 239 | [台視新聞台] 240 | SERVICE_ID = 401 241 | NETWORK_ID = 8350 242 | TRANSPORT_ID = 32 243 | VIDEO_PID = 4011 244 | AUDIO_PID = 4012 245 | FREQUENCY = 581000000 246 | MODULATION = QAM/64 247 | BANDWIDTH_HZ = 6000000 248 | INVERSION = AUTO 249 | CODE_RATE_HP = 2/3 250 | CODE_RATE_LP = 1/2 251 | GUARD_INTERVAL = 1/4 252 | TRANSMISSION_MODE = 8K 253 | HIERARCHY = NONE 254 | DELIVERY_SYSTEM = DVBT 255 | 256 | [台視財經台] 257 | SERVICE_ID = 402 258 | NETWORK_ID = 8350 259 | TRANSPORT_ID = 32 260 | VIDEO_PID = 4021 261 | AUDIO_PID = 4022 262 | FREQUENCY = 581000000 263 | MODULATION = QAM/64 264 | BANDWIDTH_HZ = 6000000 265 | INVERSION = AUTO 266 | CODE_RATE_HP = 2/3 267 | CODE_RATE_LP = 1/2 268 | GUARD_INTERVAL = 1/4 269 | TRANSMISSION_MODE = 8K 270 | HIERARCHY = NONE 271 | DELIVERY_SYSTEM = DVBT 272 | 273 | [台視綜合台] 274 | SERVICE_ID = 403 275 | NETWORK_ID = 8350 276 | TRANSPORT_ID = 32 277 | VIDEO_PID = 4031 278 | AUDIO_PID = 4032 279 | FREQUENCY = 581000000 280 | MODULATION = QAM/64 281 | BANDWIDTH_HZ = 6000000 282 | INVERSION = AUTO 283 | CODE_RATE_HP = 2/3 284 | CODE_RATE_LP = 1/2 285 | GUARD_INTERVAL = 1/4 286 | TRANSMISSION_MODE = 8K 287 | HIERARCHY = NONE 288 | DELIVERY_SYSTEM = DVBT 289 | 290 | [華視CTS] 291 | SERVICE_ID = 501 292 | NETWORK_ID = 8350 293 | TRANSPORT_ID = 34 294 | VIDEO_PID = 5011 295 | AUDIO_PID = 5012 5013 296 | FREQUENCY = 593000000 297 | MODULATION = QAM/64 298 | BANDWIDTH_HZ = 6000000 299 | INVERSION = AUTO 300 | CODE_RATE_HP = 2/3 301 | CODE_RATE_LP = 1/2 302 | GUARD_INTERVAL = 1/4 303 | TRANSMISSION_MODE = 8K 304 | HIERARCHY = NONE 305 | DELIVERY_SYSTEM = DVBT 306 | 307 | [華視教育體育文化台] 308 | SERVICE_ID = 502 309 | NETWORK_ID = 8350 310 | TRANSPORT_ID = 34 311 | VIDEO_PID = 5021 312 | AUDIO_PID = 5022 313 | FREQUENCY = 593000000 314 | MODULATION = QAM/64 315 | BANDWIDTH_HZ = 6000000 316 | INVERSION = AUTO 317 | CODE_RATE_HP = 2/3 318 | CODE_RATE_LP = 1/2 319 | GUARD_INTERVAL = 1/4 320 | TRANSMISSION_MODE = 8K 321 | HIERARCHY = NONE 322 | DELIVERY_SYSTEM = DVBT 323 | 324 | [華視新聞資訊台] 325 | SERVICE_ID = 503 326 | NETWORK_ID = 8350 327 | TRANSPORT_ID = 34 328 | VIDEO_PID = 5031 329 | AUDIO_PID = 5032 330 | FREQUENCY = 593000000 331 | MODULATION = QAM/64 332 | BANDWIDTH_HZ = 6000000 333 | INVERSION = AUTO 334 | CODE_RATE_HP = 2/3 335 | CODE_RATE_LP = 1/2 336 | GUARD_INTERVAL = 1/4 337 | TRANSMISSION_MODE = 8K 338 | HIERARCHY = NONE 339 | DELIVERY_SYSTEM = DVBT 340 | 341 | [國會頻道1] 342 | SERVICE_ID = 504 343 | NETWORK_ID = 8350 344 | TRANSPORT_ID = 34 345 | VIDEO_PID = 5041 346 | AUDIO_PID = 5042 347 | FREQUENCY = 593000000 348 | MODULATION = QAM/64 349 | BANDWIDTH_HZ = 6000000 350 | INVERSION = AUTO 351 | CODE_RATE_HP = 2/3 352 | CODE_RATE_LP = 1/2 353 | GUARD_INTERVAL = 1/4 354 | TRANSMISSION_MODE = 8K 355 | HIERARCHY = NONE 356 | DELIVERY_SYSTEM = DVBT 357 | 358 | [國會頻道2] 359 | SERVICE_ID = 505 360 | NETWORK_ID = 8350 361 | TRANSPORT_ID = 34 362 | VIDEO_PID = 5051 363 | AUDIO_PID = 5052 364 | FREQUENCY = 593000000 365 | MODULATION = QAM/64 366 | BANDWIDTH_HZ = 6000000 367 | INVERSION = AUTO 368 | CODE_RATE_HP = 2/3 369 | CODE_RATE_LP = 1/2 370 | GUARD_INTERVAL = 1/4 371 | TRANSMISSION_MODE = 8K 372 | HIERARCHY = NONE 373 | DELIVERY_SYSTEM = DVBT 374 | 375 | -------------------------------------------------------------------------------- /iso_639.awk: -------------------------------------------------------------------------------- 1 | #! /usr/bin/awk -f 2 | BEGIN \ 3 | { 4 | print "#include \"tv_grab_dvb.h\"" 5 | print "const struct lookup_table languageid_table[] = {" 6 | } 7 | /^#/ \ 8 | { 9 | next 10 | } 11 | /^$/ \ 12 | { 13 | next 14 | } 15 | $3 == "XX" \ 16 | { 17 | next 18 | } 19 | { 20 | print "\t{{.c=\""$1"\"}, \""$3"\"}," 21 | } 22 | $1 != $2 \ 23 | { 24 | print "\t{{.c=\""$2"\"}, \""$3"\"}," 25 | } 26 | END \ 27 | { 28 | print "\t{{-1}, NULL}," 29 | print "};" 30 | } 31 | -------------------------------------------------------------------------------- /iso_639.tab: -------------------------------------------------------------------------------- 1 | 2 | ## iso-639.tab 3 | ## 4 | ## Copyright (C) 2005 Alastair McKinstry 5 | ## Released under the GNU License; see file COPYING for details 6 | ## 7 | ## PLEASE NOTE: THIS FILE IS DEPRECATED AND SCHEDULED TO BE REMOVED. 8 | ## IT IS FOR BACKWARD-COMPATIBILITY ONLY: PLEASE USE THE ISO-639.XML 9 | ## FILE INSTEAD. 10 | ## 11 | ## This file gives a list of all languages in the ISO-639 12 | ## standard, and is used to provide translations (via gettext) 13 | ## 14 | ## Status: ISO 639-2:1998 + additions and changes until 2003-03-05 15 | ## Source: http://lcweb.loc.gov/standards/iso639-2/englangn.html 16 | ## 17 | ## Columns: 18 | ## iso-639-2 terminology code 19 | ## iso-639-2 bibliography code 20 | ## iso-639-1 code (XX if none exists) 21 | ## Name (English) 22 | ## 23 | ## 24 | aar aar aa Afar 25 | abk abk ab Abkhazian 26 | ace ace XX Achinese 27 | ach ach XX Acoli 28 | ada ada XX Adangme 29 | ady ady XX Adyghe; Adygei 30 | afa afa XX Afro-Asiatic (Other) 31 | afh afh XX Afrihili 32 | afr afr af Afrikaans 33 | ain ain XX Ainu 34 | aka aka ak Akan 35 | akk akk XX Akkadian 36 | ale ale XX Aleut 37 | alg alg XX Algonquian languages 38 | alt alt XX Southern Altai 39 | amh amh am Amharic 40 | ang ang XX English, Old (ca. 450-1100) 41 | anp anp XX Angika 42 | apa apa XX Apache languages 43 | ara ara ar Arabic 44 | arc arc XX Aramaic 45 | arg arg an Aragonese 46 | arn arn XX Araucanian 47 | arp arp XX Arapaho 48 | art art XX Artificial (Other) 49 | arw arw XX Arawak 50 | asm asm as Assamese 51 | ast ast XX Asturian; Bable 52 | ath ath XX Athapascan languages 53 | aus aus XX Australian languages 54 | ava ava av Avaric 55 | ave ave ae Avestan 56 | awa awa XX Awadhi 57 | aym aym ay Aymara 58 | aze aze az Azerbaijani 59 | bad bad XX Banda 60 | bai bai XX Bamileke languages 61 | bak bak ba Bashkir 62 | bal bal XX Baluchi 63 | bam bam bm Bambara 64 | ban ban XX Balinese 65 | bas bas XX Basa 66 | bat bat XX Baltic (Other) 67 | bej bej XX Beja 68 | bel bel be Belarusian 69 | bem bem XX Bemba 70 | ben ben bn Bengali 71 | ber ber XX Berber (Other) 72 | bho bho XX Bhojpuri 73 | bih bih bh Bihari 74 | bik bik XX Bikol 75 | bin bin XX Bini 76 | bis bis bi Bislama 77 | bla bla XX Siksika 78 | bnt bnt XX Bantu (Other) 79 | bod tib bo Tibetan 80 | bos bos bs Bosnian 81 | bra bra XX Braj 82 | bre bre br Breton 83 | btk btk XX Batak (Indonesia) 84 | bua bua XX Buriat 85 | bug bug XX Buginese 86 | bul bul bg Bulgarian 87 | byn byn XX Blin; Bilin 88 | cad cad XX Caddo 89 | cai cai XX Central American Indian (Other) 90 | car car XX Carib 91 | cat cat ca Catalan; Valencian 92 | cau cau XX Caucasian (Other) 93 | ceb ceb XX Cebuano 94 | cel cel XX Celtic (Other) 95 | ces cze cs Czech 96 | cha cha ch Chamorro 97 | chb chb XX Chibcha 98 | che che ce Chechen 99 | chg chg XX Chagatai 100 | chk chk XX Chuukese 101 | chm chm XX Mari 102 | chn chn XX Chinook jargon 103 | cho cho XX Choctaw 104 | chp chp XX Chipewyan 105 | chr chr XX Cherokee 106 | chu chu cu Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic 107 | chv chv cv Chuvash 108 | chy chy XX Cheyenne 109 | cmc cmc XX Chamic languages 110 | cop cop XX Coptic 111 | cor cor kw Cornish 112 | cos cos co Corsican 113 | cpe cpe XX Creoles and pidgins, English based (Other) 114 | cpf cpf XX Creoles and pidgins, French-based (Other) 115 | cpp cpp XX Creoles and pidgins, Portuguese-based (Other) 116 | cre cre cr Cree 117 | crh crh XX Crimean Tatar; Crimean Turkish 118 | crp crp XX Creoles and pidgins (Other) 119 | csb csb XX Kashubian 120 | cus cus XX Cushitic (Other) 121 | cym wel cy Welsh 122 | dak dak XX Dakota 123 | dan dan da Danish 124 | dar dar XX Dargwa 125 | day day XX Dayak 126 | del del XX Delaware 127 | den den XX Slave (Athapascan) 128 | deu ger de German 129 | dgr dgr XX Dogrib 130 | din din XX Dinka 131 | div div dv Divehi; Dhivehi; Maldivian 132 | doi doi XX Dogri 133 | dra dra XX Dravidian (Other) 134 | dsb dsb XX Lower Sorbian 135 | dua dua XX Duala 136 | dum dum XX Dutch, Middle (ca. 1050-1350) 137 | dyu dyu XX Dyula 138 | dzo dzo dz Dzongkha 139 | efi efi XX Efik 140 | egy egy XX Egyptian (Ancient) 141 | eka eka XX Ekajuk 142 | ell gre el Greek, Modern (1453-) 143 | elx elx XX Elamite 144 | eng eng en English 145 | enm enm XX English, Middle (1100-1500) 146 | epo epo eo Esperanto 147 | est est et Estonian 148 | eus baq eu Basque 149 | ewe ewe ee Ewe 150 | ewo ewo XX Ewondo 151 | fan fan XX Fang 152 | fao fao fo Faroese 153 | fas per fa Persian 154 | fat fat XX Fanti 155 | fij fij fj Fijian 156 | fil fil XX Filipino; Pilipino 157 | fin fin fi Finnish 158 | fiu fiu XX Finno-Ugrian (Other) 159 | fon fon XX Fon 160 | fra fre fr French 161 | frm frm XX French, Middle (ca. 1400-1600) 162 | fro fro XX French, Old (842-ca. 1400) 163 | frr frr XX Northern Frisian 164 | frs frs XX Eastern Frisian 165 | fry fry fy Western Frisian 166 | ful ful ff Fulah 167 | fur fur XX Friulian 168 | gaa gaa XX Ga 169 | gay gay XX Gayo 170 | gba gba XX Gbaya 171 | gem gem XX Germanic (Other) 172 | gez gez XX Geez 173 | gil gil XX Gilbertese 174 | gla gla gd Gaelic; Scottish Gaelic 175 | gle gle ga Irish 176 | glg glg gl Galician 177 | glv glv gv Manx 178 | gmh gmh XX German, Middle High (ca. 1050-1500) 179 | goh goh XX German, Old High (ca. 750-1050) 180 | gon gon XX Gondi 181 | gor gor XX Gorontalo 182 | got got XX Gothic 183 | grb grb XX Grebo 184 | grc grc XX Greek, Ancient (to 1453) 185 | grn grn gn Guarani 186 | gsw gsw XX Alemanic; Swiss German 187 | guj guj gu Gujarati 188 | gwi gwi XX Gwich´in 189 | hai hai XX Haida 190 | hat hat ht Haitian; Haitian Creole 191 | hau hau ha Hausa 192 | haw haw XX Hawaiian 193 | heb heb he Hebrew 194 | her her hz Herero 195 | hil hil XX Hiligaynon 196 | him him XX Himachali 197 | hin hin hi Hindi 198 | hit hit XX Hittite 199 | hmn hmn XX Hmong 200 | hmo hmo ho Hiri Motu 201 | hrv scr hr Croatian 202 | hsb hsb XX Upper Sorbian 203 | hun hun hu Hungarian 204 | hup hup XX Hupa 205 | hye arm hy Armenian 206 | iba iba XX Iban 207 | ibo ibo ig Igbo 208 | ido ido io Ido 209 | iii iii ii Sichuan Yi 210 | ijo ijo XX Ijo 211 | iku iku iu Inuktitut 212 | ile ile ie Interlingue 213 | ilo ilo XX Iloko 214 | ina ina ia Interlingua (International Auxiliary Language Association) 215 | inc inc XX Indic (Other) 216 | ind ind id Indonesian 217 | ine ine XX Indo-European (Other) 218 | inh inh XX Ingush 219 | ipk ipk ik Inupiaq 220 | ira ira XX Iranian (Other) 221 | iro iro XX Iroquoian languages 222 | isl ice is Icelandic 223 | ita ita it Italian 224 | jav jav jv Javanese 225 | jbo jbo XX Lojban 226 | jpn jpn ja Japanese 227 | jpr jpr XX Judeo-Persian 228 | jrb jrb XX Judeo-Arabic 229 | kaa kaa XX Kara-Kalpak 230 | kab kab XX Kabyle 231 | kac kac XX Kachin 232 | kal kal kl Kalaallisut; Greenlandic 233 | kam kam XX Kamba 234 | kan kan kn Kannada 235 | kar kar XX Karen 236 | kas kas ks Kashmiri 237 | kat geo ka Georgian 238 | kau kau kr Kanuri 239 | kaw kaw XX Kawi 240 | kaz kaz kk Kazakh 241 | kbd kbd XX Kabardian 242 | kha kha XX Khasi 243 | khi khi XX Khoisan (Other) 244 | khm khm km Khmer 245 | kho kho XX Khotanese 246 | kik kik ki Kikuyu; Gikuyu 247 | kin kin rw Kinyarwanda 248 | kir kir ky Kirghiz 249 | kmb kmb XX Kimbundu 250 | kok kok XX Konkani 251 | kom kom kv Komi 252 | kon kon kg Kongo 253 | kor kor ko Korean 254 | kos kos XX Kosraean 255 | kpe kpe XX Kpelle 256 | krc krc XX Karachay-Balkar 257 | krl krl XX Karelian 258 | kro kro XX Kru 259 | kru kru XX Kurukh 260 | kua kua kj Kuanyama; Kwanyama 261 | kum kum XX Kumyk 262 | kur kur ku Kurdish 263 | kut kut XX Kutenai 264 | lad lad XX Ladino 265 | lah lah XX Lahnda 266 | lam lam XX Lamba 267 | lao lao lo Lao 268 | lat lat la Latin 269 | lav lav lv Latvian 270 | lez lez XX Lezghian 271 | lim lim li Limburgan; Limburger; Limburgish 272 | lin lin ln Lingala 273 | lit lit lt Lithuanian 274 | lol lol XX Mongo 275 | loz loz XX Lozi 276 | ltz ltz lb Luxembourgish; Letzeburgesch 277 | lua lua XX Luba-Lulua 278 | lub lub lu Luba-Katanga 279 | lug lug lg Ganda 280 | lui lui XX Luiseno 281 | lun lun XX Lunda 282 | luo luo XX Luo (Kenya and Tanzania) 283 | lus lus XX Lushai 284 | mad mad XX Madurese 285 | mag mag XX Magahi 286 | mah mah mh Marshallese 287 | mai mai XX Maithili 288 | mak mak XX Makasar 289 | mal mal ml Malayalam 290 | man man XX Mandingo 291 | map map XX Austronesian (Other) 292 | mar mar mr Marathi 293 | mas mas XX Masai 294 | mdf mdf XX Moksha 295 | mdr mdr XX Mandar 296 | men men XX Mende 297 | mga mga XX Irish, Middle (900-1200) 298 | mic mic XX Mi'kmaq; Micmac 299 | min min XX Minangkabau 300 | mis mis XX Miscellaneous languages 301 | mkd mac mk Macedonian 302 | mkh mkh XX Mon-Khmer (Other) 303 | mlg mlg mg Malagasy 304 | mlt mlt mt Maltese 305 | mnc mnc XX Manchu 306 | mni mni XX Manipuri 307 | mno mno XX Manobo languages 308 | moh moh XX Mohawk 309 | mol mol mo Moldavian 310 | mon mon mn Mongolian 311 | mos mos XX Mossi 312 | mri mao mi Maori 313 | msa may ms Malay 314 | mul mul XX Multiple languages 315 | mun mun XX Munda languages 316 | mus mus XX Creek 317 | mwl mwl XX Mirandese 318 | mwr mwr XX Marwari 319 | mya bur my Burmese 320 | myn myn XX Mayan languages 321 | myv myv XX Erzya 322 | nah nah XX Nahuatl 323 | nai nai XX North American Indian 324 | nap nap XX Neapolitan 325 | nau nau na Nauru 326 | nav nav nv Navajo; Navaho 327 | nbl nbl nr Ndebele, South; South Ndebele 328 | nde nde nd Ndebele, North; North Ndebele 329 | ndo ndo ng Ndonga 330 | nds nds XX Low German; Low Saxon; German, Low; Saxon, Low 331 | nep nep ne Nepali 332 | new new XX Newari; Nepal Bhasa 333 | nia nia XX Nias 334 | nic nic XX Niger-Kordofanian (Other) 335 | niu niu XX Niuean 336 | nld dut nl Dutch; Flemish 337 | nno nno nn Norwegian Nynorsk; Nynorsk, Norwegian 338 | nob nob nb Norwegian Bokmål; Bokmål, Norwegian 339 | nog nog XX Nogai 340 | non non XX Norse, Old 341 | nor nor no Norwegian 342 | nqo nqo XX N'ko 343 | nso nso XX Northern Sotho, Pedi; Sepedi 344 | nub nub XX Nubian languages 345 | nwc nwc XX Classical Newari; Old Newari; Classical Nepal Bhasa 346 | nya nya ny Chichewa; Chewa; Nyanja 347 | nym nym XX Nyamwezi 348 | nyn nyn XX Nyankole 349 | nyo nyo XX Nyoro 350 | nzi nzi XX Nzima 351 | oci oci oc Occitan (post 1500); Provençal 352 | oji oji oj Ojibwa 353 | ori ori or Oriya 354 | orm orm om Oromo 355 | osa osa XX Osage 356 | oss oss os Ossetian; Ossetic 357 | ota ota XX Turkish, Ottoman (1500-1928) 358 | oto oto XX Otomian languages 359 | paa paa XX Papuan (Other) 360 | pag pag XX Pangasinan 361 | pal pal XX Pahlavi 362 | pam pam XX Pampanga 363 | pan pan pa Panjabi; Punjabi 364 | pap pap XX Papiamento 365 | pau pau XX Palauan 366 | peo peo XX Persian, Old (ca. 600-400 B.C.) 367 | phi phi XX Philippine (Other) 368 | phn phn XX Phoenician 369 | pli pli pi Pali 370 | pol pol pl Polish 371 | pon pon XX Pohnpeian 372 | por por pt Portuguese 373 | pra pra XX Prakrit languages 374 | pro pro XX Provençal, Old (to 1500) 375 | pus pus ps Pushto 376 | qaa-qtz qaa-qtz XX Reserved for local use 377 | que que qu Quechua 378 | raj raj XX Rajasthani 379 | rap rap XX Rapanui 380 | rar rar XX Rarotongan 381 | roa roa XX Romance (Other) 382 | roh roh rm Raeto-Romance 383 | rom rom XX Romany 384 | ron rum ro Romanian 385 | run run rn Rundi 386 | rup rup XX Aromanian; Arumanian; Macedo-Romanian 387 | rus rus ru Russian 388 | sad sad XX Sandawe 389 | sag sag sg Sango 390 | sah sah XX Yakut 391 | sai sai XX South American Indian (Other) 392 | sal sal XX Salishan languages 393 | sam sam XX Samaritan Aramaic 394 | san san sa Sanskrit 395 | sas sas XX Sasak 396 | sat sat XX Santali 397 | scn scn XX Sicilian 398 | sco sco XX Scots 399 | sel sel XX Selkup 400 | sem sem XX Semitic (Other) 401 | sga sga XX Irish, Old (to 900) 402 | sgn sgn XX Sign Languages 403 | shn shn XX Shan 404 | sid sid XX Sidamo 405 | sin sin si Sinhala; Sinhalese 406 | sio sio XX Siouan languages 407 | sit sit XX Sino-Tibetan (Other) 408 | sla sla XX Slavic (Other) 409 | slk slo sk Slovak 410 | slv slv sl Slovenian 411 | sma sma XX Southern Sami 412 | sme sme se Northern Sami 413 | smi smi XX Sami languages (Other) 414 | smj smj XX Lule Sami 415 | smn smn XX Inari Sami 416 | smo smo sm Samoan 417 | sms sms XX Skolt Sami 418 | sna sna sn Shona 419 | snd snd sd Sindhi 420 | snk snk XX Soninke 421 | sog sog XX Sogdian 422 | som som so Somali 423 | son son XX Songhai 424 | sot sot st Sotho, Southern 425 | spa spa es Spanish; Castilian 426 | sqi alb sq Albanian 427 | srd srd sc Sardinian 428 | srn srn XX Sranan Tongo 429 | srp scc sr Serbian 430 | srr srr XX Serer 431 | ssa ssa XX Nilo-Saharan (Other) 432 | ssw ssw ss Swati 433 | suk suk XX Sukuma 434 | sun sun su Sundanese 435 | sus sus XX Susu 436 | sux sux XX Sumerian 437 | swa swa sw Swahili 438 | swe swe sv Swedish 439 | syr syr XX Syriac 440 | tah tah ty Tahitian 441 | tai tai XX Tai (Other) 442 | tam tam ta Tamil 443 | tat tat tt Tatar 444 | tel tel te Telugu 445 | tem tem XX Timne 446 | ter ter XX Tereno 447 | tet tet XX Tetum 448 | tgk tgk tg Tajik 449 | tgl tgl tl Tagalog 450 | tha tha th Thai 451 | tig tig XX Tigre 452 | tir tir ti Tigrinya 453 | tiv tiv XX Tiv 454 | tkl tkl XX Tokelau 455 | tlh tlh XX Klingon; tlhIngan-Hol 456 | tli tli XX Tlingit 457 | tmh tmh XX Tamashek 458 | tog tog XX Tonga (Nyasa) 459 | ton ton to Tonga (Tonga Islands) 460 | tpi tpi XX Tok Pisin 461 | tsi tsi XX Tsimshian 462 | tsn tsn tn Tswana 463 | tso tso ts Tsonga 464 | tuk tuk tk Turkmen 465 | tum tum XX Tumbuka 466 | tup tup XX Tupi languages 467 | tur tur tr Turkish 468 | tut tut XX Altaic (Other) 469 | tvl tvl XX Tuvalu 470 | twi twi tw Twi 471 | tyv tyv XX Tuvinian 472 | udm udm XX Udmurt 473 | uga uga XX Ugaritic 474 | uig uig ug Uighur; Uyghur 475 | ukr ukr uk Ukrainian 476 | umb umb XX Umbundu 477 | und und XX Undetermined 478 | urd urd ur Urdu 479 | uzb uzb uz Uzbek 480 | vai vai XX Vai 481 | ven ven ve Venda 482 | vie vie vi Vietnamese 483 | vol vol vo Volapük 484 | vot vot XX Votic 485 | wak wak XX Wakashan languages 486 | wal wal XX Walamo 487 | war war XX Waray 488 | was was XX Washo 489 | wen wen XX Sorbian languages 490 | wln wln wa Walloon 491 | wol wol wo Wolof 492 | xal xal XX Kalmyk; Oirat 493 | xho xho xh Xhosa 494 | yao yao XX Yao 495 | yap yap XX Yapese 496 | yid yid yi Yiddish 497 | yor yor yo Yoruba 498 | ypk ypk XX Yupik languages 499 | zap zap XX Zapotec 500 | zen zen XX Zenaga 501 | zha zha za Zhuang; Chuang 502 | zho chi zh Chinese 503 | znd znd XX Zande 504 | zul zul zu Zulu 505 | zun zun XX Zuni 506 | zxx zxx XX No linguistic content 507 | zza zza XX Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki 508 | -------------------------------------------------------------------------------- /iso_639.xsl: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | #include "tv_grab_dvb.h" 8 | const struct lookup_table languageid_table[] = { 9 | 10 | 11 | {{.c=" 12 | 13 | "}, " 14 | 15 | "}, 16 | 17 | 18 | {{.c=" 19 | 20 | "}, " 21 | 22 | "}, 23 | 24 | 25 | 26 | {{-1}, NULL}, 27 | }; 28 | 29 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /lookup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "tv_grab_dvb.h" 5 | 6 | char *lookup(const struct lookup_table *l, int id) { 7 | // printf("Looked up %x", id); 8 | while ((l->u.i != id) && (l->u.i != -1)) 9 | l++; 10 | return l->desc; 11 | } 12 | 13 | /* Read lookup_table from file into newly allocated table. 14 | * The table is a single allocation consisting of two parts: 15 | * first the array of structs, followed by a char-array of strings. */ 16 | int load_lookup(struct lookup_table **l, const char *file) { 17 | int name; 18 | char value[256]; 19 | int n = 1, size = sizeof(struct lookup_table); 20 | 21 | if (file == NULL) 22 | return -1; 23 | 24 | FILE *fd = fopen(file, "r"); 25 | if (!fd) 26 | return -1; 27 | 28 | // 1st: determine size needed 29 | while (fscanf(fd, "%d %255s", &name, value) == 2) { 30 | n++; 31 | size += sizeof(struct lookup_table); 32 | size += strlen(value) + 1; 33 | } 34 | struct lookup_table *p = *l = malloc(size); 35 | if (p == NULL) 36 | return -1; 37 | 38 | // 2nd: read data 39 | rewind(fd); 40 | char *c = (char *)(p + n); 41 | while (fscanf(fd, "%d %255s", &p->u.i, c) == 2) { 42 | p->desc = c; 43 | c += strlen(c) + 1; 44 | p++; 45 | } 46 | p->u.i = -1; 47 | p->desc = NULL; 48 | 49 | fclose(fd); 50 | return 0; 51 | } 52 | 53 | #ifdef MAIN 54 | int main(int argc; char **argv;) { 55 | struct lookup_table *t; 56 | if (load_lookup(&t, "chanidents") != 0) 57 | return -1; 58 | if (argc > 1) 59 | printf("%s\n", lookup(t, atoi(argv[1]))); 60 | return 0; 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /patches/README: -------------------------------------------------------------------------------- 1 | A couple of subtitle info patches for UK descriptions. 2 | 3 | I'm a little reluctant to add these at the moment, as I can't test them 4 | (No TV Antenna in new flat yet) and they need a little work so they don't 5 | affect people outside the UK. I might do a hybrid patch of both. Cheers to 6 | Jon Dye and John Pullan for 7 | supplying them. 8 | 9 | -------------------------------------------------------------------------------- /patches/subtitle-char.patch: -------------------------------------------------------------------------------- 1 | --- ../tv_grab_dvb-0.8.ori/tv_grab_dvb.c 2004-07-15 23:26:51.000000000 +0100 2 | +++ tv_grab_dvb.c 2004-08-12 20:59:27.317105264 +0100 3 | @@ -73,6 +73,7 @@ 4 | bool ignore_updates = true; 5 | bool use_chanidents = false; 6 | bool silent = false; 7 | +int subtitle_description_limit = 0; 8 | 9 | typedef struct chninfo 10 | { 11 | @@ -96,7 +97,7 @@ 12 | 13 | void usage() 14 | { 15 | - errmsg ("tv_grab_dvb - Version 0.8\n\n usage: %s [-d] [-u] [-c] [-n|m|p] [-s] [-t timeout] [-o offset] > dump.xmltv\n\n" 16 | + errmsg ("tv_grab_dvb - Version 0.8\n\n usage: %s [-d] [-u] [-c] [-q limit] [-n|m|p] [-s] [-t timeout] [-o offset] > dump.xmltv\n\n" 17 | "\t\t-t timeout - Stop after timeout seconds of no new data\n" 18 | "\t\t-o offset - time offset in hours from -12 to 12\n" 19 | "\t\t-c - Use Channel Identifiers from file 'chanidents'\n" 20 | @@ -106,6 +107,7 @@ 21 | "\t\t-m - current multiplex now_next only\n" 22 | "\t\t-p - other multiplex now_next only\n" 23 | "\t\t-s - silent - no status ouput\n" 24 | + "\t\t-q - try and create the sub title from the description\n" 25 | "\t\t-u - output updated info - will result in repeated information\n\n", ProgName); 26 | _exit(1); 27 | } 28 | @@ -129,7 +131,7 @@ 29 | int Option_Index = 0; 30 | 31 | while (1) { 32 | - c = getopt_long(arg_count, arg_strings, "udscmpnht:o:", Long_Options, &Option_Index); 33 | + c = getopt_long(arg_count, arg_strings, "udscmpnhq:t:o:", Long_Options, &Option_Index); 34 | if (c == EOF) 35 | break; 36 | switch (c) { 37 | @@ -171,6 +173,13 @@ 38 | case 's': 39 | silent = true; 40 | break; 41 | + case 'q': 42 | + subtitle_description_limit = atoi(optarg); 43 | + if (0 == subtitle_description_limit) { 44 | + errmsg("%s: invalid limit value\n", ProgName); 45 | + usage(); 46 | + } 47 | + break; 48 | case 'h': 49 | case '?': 50 | usage(); 51 | @@ -282,7 +291,20 @@ 52 | 53 | printf("\t%s\n",lang,xmlify(evt)); 54 | if (*dsc) 55 | + { 56 | + if (subtitle_description_limit) 57 | + { 58 | + char *sub = strchr(dsc,':'); 59 | + if (sub && ((sub-dsc) < subtitle_description_limit)) 60 | + { 61 | + //Hacky but cheap. 62 | + *sub=0; 63 | + printf("\t%s\n",lang,xmlify(dsc)); 64 | + *sub=':'; 65 | + } 66 | + } 67 | printf("\t%s\n",lang,xmlify(dsc)); 68 | + } 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /patches/subtitle-pct.patch: -------------------------------------------------------------------------------- 1 | diff -Naur tv_grab_dvb-0.8/tv_grab_dvb.c tv_grab_dvb-0.8.new/tv_grab_dvb.c 2 | --- tv_grab_dvb-0.8/tv_grab_dvb.c 2004-07-29 21:02:00.804715821 +0100 3 | +++ tv_grab_dvb-0.8.new/tv_grab_dvb.c 2004-07-29 20:43:33.365383506 +0100 4 | @@ -69,6 +69,7 @@ 5 | int invalid_date_count = 0; 6 | int chan_filter = 0; 7 | int chan_filter_mask = 0; 8 | +float const subtitleratio = 0.33; 9 | bool ignore_bad_dates = true; 10 | bool ignore_updates = true; 11 | bool use_chanidents = false; 12 | @@ -269,19 +270,41 @@ 13 | int evtlen,dsclen; 14 | char lang[3]; 15 | char evt[256]; 16 | - char dsc[256]; 17 | + char dscbuf[256]; 18 | + char * subtitle = 0; 19 | + char * dsc = 0; 20 | 21 | evtlen=*(evtdesc+5) &0xff; 22 | dsclen=*(evtdesc+6+evtlen) &0xff; 23 | strncpy((char*)&lang,(char*)(evtdesc+2),3); 24 | strncpy((char*)&evt,(char*)(evtdesc+6),evtlen); 25 | - strncpy((char*)&dsc,(char*)(evtdesc+7+evtlen),dsclen); 26 | + strncpy((char*)&dscbuf,(char*)(evtdesc+7+evtlen),dsclen); 27 | lang[3]=0; 28 | evt[evtlen]=0; 29 | - dsc[dsclen]=0; 30 | + dscbuf[dsclen]=0; 31 | + dsc = dsclen > 0 ? dscbuf : 0; 32 | + 33 | + /* Find any sub-title */ 34 | + if(dsc) 35 | + { 36 | + char * dscpos = strstr(dsc, ": "); 37 | + if(dscpos) 38 | + { 39 | + int const subtitlelen = (dscpos-dsc); 40 | + if(subtitlelen < (dsclen * subtitleratio)) 41 | + { 42 | + *dscpos = '\0'; 43 | + subtitle = dscbuf; 44 | + dsc = dscpos + 2; 45 | + dsclen = strlen(dsc); 46 | + } 47 | + } 48 | + } 49 | 50 | printf("\t%s\n",lang,xmlify(evt)); 51 | - if (*dsc) 52 | + if(subtitle) 53 | + printf("\t%s\n",lang,xmlify(subtitle)); 54 | + if(dsc) 55 | printf("\t%s\n",lang,xmlify(dsc)); 56 | 57 | } 58 | -------------------------------------------------------------------------------- /samples/channels.conf: -------------------------------------------------------------------------------- 1 | 中視數位台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1002:100 2 | 中視新聞台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1011:1012:101 3 | 中視綜藝台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1021:1022:102 4 | 中視HD台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1031:1032:103 5 | 公共電視 PTS:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2011:2012:201 6 | 公視2台 PTS2:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2021:2022:202 7 | 客家電視 HTV:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2031:2032:203 8 | 民視綜合台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3001:3002:300 9 | 民視交通台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3011:3012:301 10 | 民視新聞台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3021:3022:302 11 | 民視資料廣播:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:303 12 | 民視HD台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3041:3042:304 13 | 公視 HD:569000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2001:2002:200 14 | 台灣電視台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4001:4002:400 15 | 台視財經台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4011:4012:401 16 | 台視綜合台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4021:4022:402 17 | 台視 HD台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4031:4032:403 18 | 華視CTS:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5011:5012:501 19 | 華視教育台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5021:5022:502 20 | 華視新聞資訊台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5031:5032:503 21 | 華視HD:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5041:5042:504 22 | -------------------------------------------------------------------------------- /samples/ptshd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 物滿為患 7 | 第1集 8 | 9 | 10 | 陪文夏去旅行演唱會 11 | 第1集陪文夏去旅行演唱會 (2-2) 12 | 13 | 14 | 3D台灣 15 | 曲全立導演以3D技術,紀錄台灣人文與生態之美。..... 16 | 17 | 18 | 走過1/4世紀的執著 19 | 第1集 20 | 21 | 22 | 單數絕配 23 | 第10集 24 | 25 | 26 | 卡滋幫 27 | 第8集卡滋幫第三季 28 | 29 | 30 | 水果冰淇淋 31 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....洗壞的玩具 32 | 33 | 34 | 黑熊這一家 35 | 第2集 36 | 37 | 38 | 博物館的秘密(1) 39 | 第2集 40 | 41 | 42 | 台灣囝仔Do Re Mi(HD) 43 | 第6集台灣囝仔Do Re Mi (HD) 44 | 45 | 46 | 結婚不結婚 47 | 100年度公視人生劇展第二次公開徵案通過審查案;本片為都會愛情喜劇,藉輕熟女思涵面臨結婚的荒謬進行式.....結婚不結婚 Get Married 48 | 49 | 50 | 沒有名字的甜點店 51 | 本劇劇本係為行政院新聞局99年度舉辦首屆「電視節目劇本創作獎」的得獎作品(原作林涵),並獲得新聞局(..... 52 | 53 | 54 | 結婚不結婚幕後花絮 55 | 100年度公視人生劇展第二次公開徵案通過審查案;本片為都會愛情喜劇,藉輕熟女思涵面臨結婚的荒謬進行式..... 56 | 57 | 58 | 晚秋 59 | 2012金穗獎學生短片獲劇情片優等及最佳編劇..... 60 | 61 | 62 | 見證大團 63 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 64 | 65 | 66 | 見證大團 67 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 68 | 69 | 70 | 波麗露左左左 71 | 台北市立交響樂團推出「波麗露左左左」音樂會,由恩斯特o柯瓦契奇指揮,蓋瑞o葛拉夫曼擔任鋼琴演奏與台北..... 72 | 73 | 74 | 75 | 第1集 76 | 77 | 78 | BWF世界羽球超級系列賽 79 | 世界羽球超級系列賽,是世界羽球聯盟 為提升羽球運動的品質而推出的比賽,前身是國際羽總大獎賽。超級系列..... 80 | 81 | 82 | 卡滋幫 83 | 第8集卡滋幫第三季 84 | 85 | 86 | 水果冰淇淋 87 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....洗壞的玩具 88 | 89 | 90 | 博物館的秘密(1) 91 | 第2集 92 | 93 | 94 | 2013第21屆亞洲桌球錦標賽7 95 | 亞洲桌球錦標賽是一個每兩年舉行一次,由國際桌球總會認可的亞洲桌球賽事,簡稱「亞桌賽」。從1952年到.....2013第21屆亞洲桌球錦標賽7(2-1) 96 | 97 | 98 | 2013第21屆亞洲桌球錦標賽7 99 | 亞洲桌球錦標賽是一個每兩年舉行一次,由國際桌球總會認可的亞洲桌球賽事,簡稱「亞桌賽」。從1952年到.....2013第21屆亞洲桌球錦標賽7(2-2) 100 | 101 | 102 | 台灣囝仔Do Re Mi(HD) 103 | 第6集台灣囝仔Do Re Mi (HD) 104 | 105 | 106 | 爸媽囧很大 107 | 新製九點帶狀棚內談話性節目,週一至週四播出,李四端主持,探討性與性別議題,以父母和孩子溝通為主軸,帶..... 108 | 109 | 110 | 城市。獵人 111 | 本案為「101年高畫質電視節目製播計劃」之連續劇集徵案節目。本節目是關於台東泰雅族的獵人來到城市打拼.....城市。獵人 - 6 112 | 113 | 114 | 疑犯追蹤 115 | 第18集 116 | 117 | 118 | 陪文夏去旅行演唱會 119 | 台灣音樂文化國際交流協會於台北市信義區ATT 4 FUN show box,舉辦【陪文夏去旅行演唱會..... 120 | 121 | 122 | 陪文夏去旅行演唱會 123 | 第1集陪文夏去旅行演唱會 (2-2) 124 | 125 | 126 | 下課花路米 127 | 這是一個專為國小中、高年級同學量身定製的新型態兒童鄉土探索節目,雖然鄉土,卻一點也不含糊,主持人賢賢.....獵龍計畫 128 | 129 | 130 | 公視藝文大道 131 | 本節目為藝文訪談節目,長度為60分鐘,在HI-HD頻道及主頻播出。以國內當時的重要藝文活動為主要取材.....充滿熱情與歷史的鑄劍工藝 132 | 133 | 134 | 見證大團 135 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 136 | 137 | 138 | 見證大團 139 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 140 | 141 | 142 | 轟動演唱會 143 | 公視表演廳。兆婕豐有限公司將以布袋戲編劇手法,串連葉璦菱、殷正洋等多位歌王歌后樂曲,搭配上黃俊雄大師.....轟動演唱會(2-1) 144 | 145 | 146 | 黑熊這一家 147 | 第2集 148 | 149 | 150 | 衝鋒特警隊第二季 151 | 第12集特警出擊 第二季 152 | 153 | 154 | 收播 155 | 第1集 156 | 157 | 158 | 轟動演唱會 159 | 公視表演廳。兆婕豐有限公司將以布袋戲編劇手法,串連葉璦菱、殷正洋等多位歌王歌后樂曲,搭配上黃俊雄大師.....轟動演唱會(2-2) 160 | 161 | 162 | 2012世界衝浪冠軍系列 163 | 第1集葡萄牙職業賽 164 | 165 | 166 | 3D台灣 167 | 曲全立導演以3D技術,紀錄台灣人文與生態之美。..... 168 | 169 | 170 | 卡滋幫 171 | 第9集卡滋幫第三季 172 | 173 | 174 | 水果冰淇淋 175 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....大紅蘿蔔 176 | 177 | 178 | 博物館的秘密(1) 179 | 第3集 180 | 181 | 182 | 卡滋幫 183 | 第7集卡滋幫第三季 184 | 185 | 186 | 水果冰淇淋 187 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....英雄大對決 188 | 189 | 190 | 博物館的秘密(1) 191 | 第1集 192 | 193 | 194 | 水藍的C調樂章 195 | 國立台灣交響樂團的新樂季以貝多芬「永恆久九」系列為主軸,開季音樂會推出「水藍的C調樂章」,由藝術顧..... 196 | 197 | 198 | 單數絕配 199 | 第11集 200 | 201 | 202 | 那人.那歌.那歲月 203 | 「台灣音樂之父」許常惠,不但是現代音樂創作的先驅者,更從事民族音樂的田野研究,發掘許多民間樂人;今年..... 204 | 205 | 206 | 單數絕配 207 | 第9集 208 | 209 | 210 | 卡滋幫 211 | 第7集卡滋幫第三季 212 | 213 | 214 | 水果冰淇淋 215 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....英雄大對決 216 | 217 | 218 | 黑熊這一家 219 | 第1集 220 | 221 | 222 | 博物館的秘密(1) 223 | 第1集 224 | 225 | 226 | 卡滋幫 227 | 第9集卡滋幫第三季 228 | 229 | 230 | 水果冰淇淋 231 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....大紅蘿蔔 232 | 233 | 234 | 黑熊這一家 235 | 第3集 236 | 237 | 238 | 博物館的秘密(1) 239 | 第3集 240 | 241 | 242 | 等待回家的日子 243 | 第1集 244 | 245 | 246 | BWF世界羽球超級系列賽 247 | 世界羽球超級系列賽,是世界羽球聯盟 為提升羽球運動的品質而推出的比賽,前身是國際羽總大獎賽。超級系列.....BWF世界羽球超級系列賽 1 248 | 249 | 250 | 卡滋幫 251 | 第7集卡滋幫第三季 252 | 253 | 254 | 水果冰淇淋 255 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....英雄大對決 256 | 257 | 258 | 博物館的秘密(1) 259 | 第1集 260 | 261 | 262 | 小孩‧狗 263 | 第1集 264 | 265 | 266 | BWF世界羽球超級系列賽 267 | 世界羽球超級系列賽,是世界羽球聯盟 為提升羽球運動的品質而推出的比賽,前身是國際羽總大獎賽。超級系列..... 268 | 269 | 270 | 爸媽囧很大 271 | 新製九點帶狀棚內談話性節目,週一至週四播出,李四端主持,探討性與性別議題,以父母和孩子溝通為主軸,帶..... 272 | 273 | 274 | 城市。獵人 275 | 本案為「101年高畫質電視節目製播計劃」之連續劇集徵案節目。本節目是關於台東泰雅族的獵人來到城市打拼.....城市。獵人 - 5 276 | 277 | 278 | 疑犯追蹤 279 | 第17集 280 | 281 | 282 | 卡滋幫 283 | 第9集卡滋幫第三季 284 | 285 | 286 | 水果冰淇淋 287 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....大紅蘿蔔 288 | 289 | 290 | 博物館的秘密(1) 291 | 第3集 292 | 293 | 294 | 黑熊這一家 295 | 第1集 296 | 297 | 298 | 衝鋒特警隊第二季 299 | 第11集特警出擊 第二季 300 | 301 | 302 | 收播 303 | 第1集 304 | 305 | 306 | 爸媽囧很大 307 | 新製九點帶狀棚內談話性節目,週一至週四播出,李四端主持,探討性與性別議題,以父母和孩子溝通為主軸,帶..... 308 | 309 | 310 | 小孩‧大人 311 | 這是個有關情愛的故事,包括親情、愛情、友情等等,但它想敘述的,其實也是個關於掠奪與占有的故事,它始於.....小孩.大人 - 1 312 | 313 | 314 | 疑犯追蹤 315 | 第19集 316 | 317 | 318 | 卡滋幫 319 | 第8集卡滋幫第三季 320 | 321 | 322 | 水果冰淇淋 323 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....洗壞的玩具 324 | 325 | 326 | 博物館的秘密(1) 327 | 第2集 328 | 329 | 330 | 黑熊這一家 331 | 第3集 332 | 333 | 334 | 衝鋒特警隊第二季 335 | 第13集特警出擊 第二季 336 | 337 | 338 | 收播 339 | 第1集 340 | 341 | 342 | 美女與野獸 343 | 第15集美女與野獸(2013) 344 | 345 | 346 | 美女與野獸 347 | 第16集美女與野獸(2013) 348 | 349 | 350 | 收播 351 | 第1集 352 | 353 | 354 | 卡滋幫 355 | 第10集卡滋幫第三季 356 | 357 | 358 | 水果冰淇淋 359 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....準時訓練 360 | 361 | 362 | 就是印象派 363 | 第2集 364 | 365 | 366 | 部落風 367 | 原視音雄榜的英雄們,從不同的部落,把邀請函送傳給王宏恩,邀請他一起去部落,採集部落的聲音,感受部落的.....屏東199縣道之旅 368 | 369 | 370 | 野蓮香 371 | 全心全意只想照顧好家庭的外籍媳婦瓊娥,不僅需挑起夫家的農事家事,另一方面還得照顧寡言,老被學校誤以為..... 372 | 373 | 374 | 2013第21屆亞洲桌球錦標賽5 375 | 亞洲桌球錦標賽是一個每兩年舉行一次,由國際桌球總會認可的亞洲桌球賽事,簡稱「亞桌賽」。從1952年到..... 376 | 377 | 378 | 2012 NTSO兩岸青少年管弦樂團音樂會 379 | 國立台灣交響樂團為培養樂壇優秀新血,自1991年起每年暑假特別規劃青少年管絃樂營,今年由國際知名音樂..... 380 | 381 | 382 | 單數絕配 383 | 第12集 384 | 385 | 386 | 美女與野獸 387 | 第15集美女與野獸(2013) 388 | 389 | 390 | 美女與野獸 391 | 第16集美女與野獸(2013) 392 | 393 | 394 | 感恩故事集 395 | 本會與感恩基金會96年度合作計畫,感恩基金會贊助本會製播10集公益節目。2008第二季11-23集.....蘇花公路人 396 | 397 | 398 | 下課花路米 399 | 這是一個專為國小中、高年級同學量身定製的新型態兒童鄉土探索節目,雖然鄉土,卻一點也不含糊,主持人賢賢.....為領角鴞打造一個家 400 | 401 | 402 | 卡滋幫 403 | 第10集卡滋幫第三季 404 | 405 | 406 | 水果冰淇淋 407 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....準時訓練 408 | 409 | 410 | 人狗萬事通 411 | 第1集 412 | 413 | 414 | 就是印象派 415 | 第2集 416 | 417 | 418 | 見證大團 419 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 420 | 421 | 422 | 見證大團 423 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 424 | 425 | 426 | 那些年我們的歌特輯 427 | 102年HD節目製作案邀案,澎恰恰、康康主持,兩集內容包含:「老歌新詮釋」、「一曲兩風格」。.....那些年我們的歌特輯 - 老歌新風貌 428 | 429 | 430 | 部落風 431 | 原視音雄榜的英雄們,從不同的部落,把邀請函送傳給王宏恩,邀請他一起去部落,採集部落的聲音,感受部落的.....屏東199縣道之旅 432 | 433 | 434 | 冰峰救援 435 | 第1集 436 | 437 | 438 | BWF世界羽球超級系列賽 439 | 世界羽球超級系列賽,是世界羽球聯盟 為提升羽球運動的品質而推出的比賽,前身是國際羽總大獎賽。超級系列..... 440 | 441 | 442 | Yaya 443 | 第1集 444 | 445 | 446 | 2013第21屆亞洲桌球錦標賽6 447 | 亞洲桌球錦標賽是一個每兩年舉行一次,由國際桌球總會認可的亞洲桌球賽事,簡稱「亞桌賽」。從1952年到..... 448 | 449 | 450 | 感恩故事集 451 | 本會與感恩基金會96年度合作計畫,感恩基金會贊助本會製播10集公益節目。2008第二季11-23集.....蘇花公路人 452 | 453 | 454 | 下課花路米 455 | 這是一個專為國小中、高年級同學量身定製的新型態兒童鄉土探索節目,雖然鄉土,卻一點也不含糊,主持人賢賢.....為領角鴞打造一個家 456 | 457 | 458 | 卡滋幫 459 | 第10集卡滋幫第三季 460 | 461 | 462 | 水果冰淇淋 463 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....準時訓練 464 | 465 | 466 | 就是印象派 467 | 第2集 468 | 469 | 470 | 日光大道 471 | 本節目為藝文訪談節目,規劃小帶狀播出,長度為60分鐘,預訂在HI-HD頻道及主頻播出。以國內當時的重.....李泰祥 472 | 473 | 474 | 見證大團 475 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 476 | 477 | 478 | 見證大團 479 | 《見證大團》以「樂團大登陸,電視新地景」的理念,錄製台灣高規格音樂節目,動用7台HD攝影機拍攝,總共..... 480 | 481 | 482 | 陪文夏去旅行演唱會 483 | 台灣音樂文化國際交流協會於台北市信義區ATT 4 FUN show box,舉辦【陪文夏去旅行演唱會..... 484 | 485 | 486 | 爸媽囧很大 487 | 新製九點帶狀棚內談話性節目,週一至週四播出,李四端主持,探討性與性別議題,以父母和孩子溝通為主軸,帶..... 488 | 489 | 490 | 小孩‧大人 491 | 這是個有關情愛的故事,包括親情、愛情、友情等等,但它想敘述的,其實也是個關於掠奪與占有的故事,它始於.....小孩.大人 - 2 492 | 493 | 494 | 疑犯追蹤 495 | 第20集 496 | 497 | 498 | 人狗萬事通 499 | 第1集 500 | 501 | 502 | 衝鋒特警隊第二季 503 | 第14集特警出擊 第二季 504 | 505 | 506 | 收播 507 | 第1集 508 | 509 | 510 | 卡滋幫 511 | 第11集卡滋幫第三季 512 | 513 | 514 | 水果冰淇淋 515 | 這是公視獻給所有三至六歲兒童的甜蜜禮物。頑皮的趙自強反串 『水果奶奶』,帶小朋友進入童話般的歡樂世界.....最漂亮的花戒指 516 | 517 | 518 | 啊!設計 519 | 本節目為日本NHK最新兒童美學教育影片,每集15分鐘,共計20集。透過本節目潛移默化的引導,將帶給國..... 520 | 521 | 522 | 啊!設計 523 | 本節目為日本NHK最新兒童美學教育影片,每集15分鐘,共計20集。透過本節目潛移默化的引導,將帶給國..... 524 | 525 | 526 | 話。畫-清明上河圖 527 | 台法合製,法國導演Alain Jaubert繼"黃帝的玩具箱”後另一巨作,故宮國寶"清明上河圖”首次.....清明上河圖 528 | 529 | 530 | -------------------------------------------------------------------------------- /tv_grab_dvb.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .TH TV_GRAB_DVB 1 "2007-08-22" 3 | .\" Please adjust this date whenever revising the manpage. 4 | .SH NAME 5 | tv_grab_dvb \- Grab TV listings for DVB EIT data. 6 | .SH SYNOPSIS 7 | .B tv_grab_dvb 8 | .RI [ options ] 9 | .BI \-f \ file 10 | .br 11 | .B tv_grab_dvb 12 | .RI [ options ] 13 | .BI > \ file 14 | .SH DESCRIPTION 15 | This manual page documents briefly the 16 | .B tv_grab_dvb 17 | command. 18 | After tuning your DVB tuner to a multiplex using \fBczap\fP, \fBszap\fP, \fBtzap\fP or any other tuning programm, \fBtv_grab_dvb\fP can be used to convert the data from the Event Information Table (EIT) into an xmltv listing. 19 | .SH OPTIONS 20 | A summary of options is included below. 21 | .TP 22 | .BI \-i\ path 23 | Read data from \fIpath\fP instead of \fB/dev/dvb/adapter0/demux0\fP. 24 | \fIpath\fP might specify an alternative demultiplexer device node or a file, 25 | which contains captured EIT data. 26 | \fB\-\fP is interpreted as stdin. 27 | .TP 28 | .BI \-f\ file 29 | Write output to \fIfile\fP instead of stdout. 30 | .TP 31 | .BI \-t\ timeout 32 | Overwrite the \fItimeout\fP in seconds, after which \fBtv_grab_dvb\fP exits, if no new data arrives that long. 33 | .TP 34 | .BI \-o\ offset 35 | Additional offset in hours from \fB\-12\fP to \fB12\fP to add to any time stamp. 36 | .TP 37 | .B \-c 38 | Use channel identifiers from the file \fBchanidents\fP instead of \fIsidnumber\fP\fB.dvb.guide\fP. 39 | .TP 40 | .B \-d 41 | Show all shows, even when their start-date is before yesterday or after two weeks from now. 42 | .TP 43 | .B \-n 44 | Show only shows on now or later, but not before. 45 | .TP 46 | .B \-m 47 | Show only shows on now or later of the currently tuned multiplex. 48 | .TP 49 | .B \-p 50 | Show only shows on now or later of other multiplexes than the currently tuned one. 51 | .TP 52 | .B \-s 53 | Silent mode, disables status output of received packets and shows. 54 | .TP 55 | .B \-u 56 | Allow output of updated info, disables filtering out duplicate shows. 57 | Might result in multiple entries for a show. 58 | .TP 59 | .BI \-e\ encoding 60 | Overwrite default character encoding used instead of \fBISO6937\fP. 61 | DVB supports multiple character encodings. 62 | But many stations seem to think, that \fBISO8859\-1\fP is used when no explicit encoding is given. 63 | Since this is not so, the default character encoding can be changed to any encoding listed by \fBiconv \-l\fP. 64 | .SH BUGS 65 | Rule number one: 66 | It's the fault of your broadcast station. 67 | The information transmitted varies greatly and there is no simple way to extract useful information from many stations data. 68 | \fBtv_grab_dvb\fP can't create data from thin air and text parsing becomes very ugly very fast. 69 | Please bear this in mind when you start complaining. 70 | .PP 71 | If \fBtv_grab_dvb\fP segfaults or reports an error, please try to capture some data using \fBdvbsnoop \-s sec 18 \-b \-n 200 > file\fP, until you're able to reproduce the bug using \fBtv_grab_dvb \-i file \-o /dev/null\fP. 72 | Than please send us that file. 73 | .SH SEE ALSO 74 | .BR xmltv (3pm), 75 | .BR czap (1), 76 | .BR szap (1), 77 | .BR tzap (1). 78 | .SH AUTHOR 79 | tv_grab_dvb was written by Mark Bryars and Philipp Hahn . 80 | -------------------------------------------------------------------------------- /tv_grab_dvb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tv_grab_dvb - dump dvb epg info in xmltv 3 | * Version 0.2 - 20/04/2004 - First Public Release 4 | * 5 | * Copyright (C) 2004 Mark Bryars 6 | * 7 | * DVB code Mercilessly ripped off from dvddate 8 | * dvbdate Copyright (C) Laurence Culhane 2002 9 | * 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License 12 | * as published by the Free Software Foundation; either version 2 13 | * of the License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 24 | */ 25 | 26 | const char *id = "@(#) $Id: tv_grab_dvb.c 86 2010-10-29 20:27:31Z pmhahn $"; 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | #include "si_tables.h" 48 | #include "tv_grab_dvb.h" 49 | 50 | /* FIXME: put these as options */ 51 | #define CHANNELS_CONF "channels.conf" 52 | #define CHANIDENTS "chanidents" 53 | 54 | static char *ProgName; 55 | static char *demux = "/dev/dvb/adapter0/demux0"; 56 | 57 | static int timeout = 10; 58 | static int packet_count = 0; 59 | static int programme_count = 0; 60 | static int update_count = 0; 61 | static int crcerr_count = 0; 62 | static int time_offset = 0; 63 | static int invalid_date_count = 0; 64 | static int chan_filter = 0; 65 | static int chan_filter_mask = 0; 66 | static bool ignore_bad_dates = true; 67 | static bool ignore_updates = true; 68 | static bool use_chanidents = false; 69 | static bool silent = false; 70 | 71 | typedef struct chninfo { 72 | struct chninfo *next; 73 | int sid; 74 | int eid; 75 | int ver; 76 | } chninfo_t; 77 | 78 | static struct lookup_table *channelid_table; 79 | static struct chninfo *channels; 80 | 81 | /* Print usage information. {{{ */ 82 | static void usage() { 83 | fprintf(stderr, "Usage: %s [-d] [-u] [-c] [-n|m|p] [-s] [-t timeout]\n" 84 | "\t[-e encoding] [-o offset] [-i file] [-f file]\n\n" 85 | "\t-i file - Read from file/device instead of %s\n" 86 | "\t-f file - Write output to file instead of stdout\n" 87 | "\t-t timeout - Stop after timeout seconds of no new data\n" 88 | "\t-o offset - time offset in hours from -12 to 12\n" 89 | "\t-c - Use Channel Identifiers from file 'chanidents'\n" 90 | "\t (rather than sidnumber.dvb.guide)\n" 91 | "\t-d - output invalid dates\n" 92 | "\t-n - now next info only\n" 93 | "\t-m - current multiplex now_next only\n" 94 | "\t-p - other multiplex now_next only\n" 95 | "\t-s - silent - no status ouput\n" 96 | "\t-u - output updated info - will result in repeated information\n" 97 | "\t-e encoding - Use other than ISO-6937 default encoding\n" 98 | "\n", ProgName, demux); 99 | _exit(1); 100 | } /*}}}*/ 101 | 102 | /* Print progress indicator. {{{ */ 103 | static void status() { 104 | if (!silent) { 105 | fprintf(stderr, "\r Status: %d pkts, %d prgms, %d updates, %d invalid, %d CRC err", 106 | packet_count, programme_count, update_count, invalid_date_count, crcerr_count); 107 | } 108 | } /*}}}*/ 109 | 110 | /* Parse command line arguments. {{{ */ 111 | static int do_options(int arg_count, char **arg_strings) { 112 | static const struct option Long_Options[] = { 113 | {"help", 0, 0, 'h'}, 114 | {"timeout", 1, 0, 't'}, 115 | {"chanidents", 1, 0, 'c'}, 116 | {0, 0, 0, 0} 117 | }; 118 | int Option_Index = 0; 119 | int fd; 120 | 121 | while (1) { 122 | int c = getopt_long(arg_count, arg_strings, "udscmpnht:o:f:i:e:", Long_Options, &Option_Index); 123 | if (c == EOF) 124 | break; 125 | switch (c) { 126 | case 'i': 127 | demux = strcmp(optarg, "-") ? optarg : NULL; 128 | break; 129 | case 'f': 130 | if ((fd = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0) { 131 | fprintf(stderr, "%s: Can't write file %s\n", ProgName, optarg); 132 | usage(); 133 | } 134 | dup2(fd, STDOUT_FILENO); 135 | close(fd); 136 | break; 137 | case 't': 138 | timeout = atoi(optarg); 139 | if (0 == timeout) { 140 | fprintf(stderr, "%s: Invalid timeout value\n", ProgName); 141 | usage(); 142 | } 143 | break; 144 | case 'o': 145 | time_offset = atoi(optarg); 146 | if ((time_offset < -12) || (time_offset > 12)) { 147 | fprintf(stderr, "%s: Invalid time offset\n", ProgName); 148 | usage(); 149 | } 150 | break; 151 | case 'u': 152 | ignore_updates = false; 153 | break; 154 | case 'd': 155 | ignore_bad_dates = false; 156 | break; 157 | case 'c': 158 | use_chanidents = true; 159 | break; 160 | case 'n': 161 | chan_filter = 0x4e; 162 | chan_filter_mask = 0xfe; 163 | break; 164 | case 'm': 165 | chan_filter = 0x4e; 166 | chan_filter_mask = 0xff; 167 | break; 168 | case 'p': 169 | chan_filter = 0x4f; 170 | chan_filter_mask = 0xff; 171 | break; 172 | case 's': 173 | silent = true; 174 | break; 175 | case 'e': 176 | iso6937_encoding = optarg; 177 | break; 178 | case 'h': 179 | case '?': 180 | usage(); 181 | break; 182 | case 0: 183 | default: 184 | fprintf(stderr, "%s: unknown getopt error - returned code %02x\n", ProgName, c); 185 | _exit(1); 186 | } 187 | } 188 | return 0; 189 | } /*}}}*/ 190 | 191 | /* Lookup channel-id. {{{ */ 192 | static char *get_channelident(int chanid) { 193 | static char returnstring[256]; 194 | 195 | if (use_chanidents && channelid_table) { 196 | char *c = lookup(channelid_table, chanid); 197 | if (c) 198 | return c; 199 | } 200 | sprintf(returnstring, "%d.dvb.guide", chanid); 201 | return returnstring; 202 | } /*}}}*/ 203 | 204 | /* Parse language-id translation file. {{{ */ 205 | static char *xmllang(u_char *l) { 206 | static union lookup_key lang; 207 | lang.c[0] = (char)l[0]; 208 | lang.c[1] = (char)l[1]; 209 | lang.c[2] = (char)l[2]; 210 | lang.c[3] = '\0'; 211 | 212 | char *c = lookup(languageid_table, lang.i); 213 | return c ? c : lang.c; 214 | } /*}}}*/ 215 | 216 | /* Parse 0x4D Short Event Descriptor. {{{ */ 217 | enum ER { TITLE, SUB_TITLE }; 218 | static void parseEventDescription(void *data, enum ER round) { 219 | assert(GetDescriptorTag(data) == 0x4D); 220 | struct descr_short_event *evtdesc = data; 221 | char evt[256]; 222 | char dsc[256]; 223 | 224 | int evtlen = evtdesc->event_name_length; 225 | if (round == TITLE) { 226 | if (!evtlen) 227 | return; 228 | assert(evtlen < sizeof(evt)); 229 | memcpy(evt, (char *)&evtdesc->data, evtlen); 230 | evt[evtlen] = '\0'; 231 | printf("\t%s\n", xmllang(&evtdesc->lang_code1), xmlify(evt, evtlen)); 232 | return; 233 | } 234 | 235 | if (round == SUB_TITLE) { 236 | int dsclen = evtdesc->data[evtlen]; 237 | assert(dsclen < sizeof(dsc)); 238 | memcpy(dsc, (char *)&evtdesc->data[evtlen+1], dsclen); 239 | dsc[dsclen] = '\0'; 240 | 241 | if (*dsc) { 242 | char *d = xmlify(dsc, dsclen); 243 | if (d && *d) 244 | printf("\t%s\n", xmllang(&evtdesc->lang_code1), d); 245 | } 246 | } 247 | } /*}}}*/ 248 | 249 | /* Parse 0x4E Extended Event Descriptor. {{{ */ 250 | void parseLongEventDescription(void *data) { 251 | assert(GetDescriptorTag(data) == 0x4E); 252 | struct descr_extended_event *levt = data; 253 | char dsc[256]; 254 | bool non_empty = (levt->descriptor_number || levt->last_descriptor_number || levt->length_of_items || levt->data[0]); 255 | 256 | if (non_empty && levt->descriptor_number == 0) 257 | printf("\t", xmllang(&levt->lang_code1)); 258 | 259 | void *p = &levt->data; 260 | void *data_end = data + DESCR_GEN_LEN + GetDescriptorLength(data); 261 | while (p < (void *)levt->data + levt->length_of_items) { 262 | struct item_extended_event *name = p; 263 | int name_len = name->item_description_length; 264 | assert(p + ITEM_EXTENDED_EVENT_LEN + name_len < data_end); 265 | assert(name_len < sizeof(dsc)); 266 | memcpy(dsc, (char *)&name->data, name_len); 267 | dsc[name_len] = '\0'; 268 | printf("%s: ", xmlify(dsc, name_len)); 269 | 270 | p += ITEM_EXTENDED_EVENT_LEN + name_len; 271 | 272 | struct item_extended_event *value = p; 273 | int value_len = value->item_description_length; 274 | assert(p + ITEM_EXTENDED_EVENT_LEN + value_len < data_end); 275 | assert(value_len < sizeof(dsc)); 276 | memcpy(dsc, (char *)&value->data, value_len); 277 | dsc[value_len] = '\0'; 278 | printf("%s; ", xmlify(dsc, value_len)); 279 | 280 | p += ITEM_EXTENDED_EVENT_LEN + value_len; 281 | } 282 | struct item_extended_event *text = p; 283 | int len = text->item_description_length; 284 | if (non_empty && len) { 285 | assert(len < sizeof(dsc)); 286 | memcpy(dsc, (char *)&text->data, len); 287 | dsc[len] = '\0'; 288 | printf("%s", xmlify(dsc, len)); 289 | } 290 | 291 | //printf("/%d/%d/%s", levt->descriptor_number, levt->last_descriptor_number, xmlify(dsc)); 292 | if (non_empty && levt->descriptor_number == levt->last_descriptor_number) 293 | printf("\n"); 294 | } /*}}}*/ 295 | 296 | /* Parse 0x50 Component Descriptor. {{{ 297 | video is a flag, 1=> output the video information, 0=> output the 298 | audio information. seen is a pointer to a counter to ensure we 299 | only output the first one of each (XMLTV can't cope with more than 300 | one) */ 301 | enum CR { LANGUAGE, VIDEO, AUDIO, SUBTITLES }; 302 | static void parseComponentDescription(void *data, enum CR round, int *seen) { 303 | assert(GetDescriptorTag(data) == 0x50); 304 | struct descr_component *dc = data; 305 | char buf[256]; 306 | 307 | int len = dc->descriptor_length; 308 | assert(len < sizeof(buf)); 309 | memcpy(buf, (char *)&dc->data, len); 310 | buf[len] = '\0'; 311 | 312 | switch (dc->stream_content) { 313 | case 0x01: // Video Info 314 | if (round == VIDEO && !*seen) { 315 | //if ((dc->component_type-1)&0x08) //HD TV 316 | //if ((dc->component_type-1)&0x04) //30Hz else 25 317 | printf("\t\n"); 320 | (*seen)++; 321 | } 322 | break; 323 | case 0x02: // Audio Info 324 | if (round == AUDIO && !*seen) { 325 | printf("\t\n"); 328 | (*seen)++; 329 | } 330 | if (round == LANGUAGE) { 331 | if (!*seen) 332 | printf("\t%s\n", xmllang(&dc->lang_code1)); 333 | else 334 | printf("\t\n", xmllang(&dc->lang_code1)); 335 | (*seen)++; 336 | } 337 | break; 338 | case 0x03: // Teletext Info 339 | if (round == SUBTITLES) { 340 | // FIXME: is there a suitable XMLTV output for this? 341 | // if ((dc->component_type)&0x10) //subtitles 342 | // if ((dc->component_type)&0x20) //subtitles for hard of hearing 343 | printf("\t\n"); 344 | printf("\t\t%s\n", xmllang(&dc->lang_code1)); 345 | printf("\t\n"); 346 | } 347 | break; 348 | // case 0x04: // AC3 info 349 | } 350 | #if 0 351 | printf("\t\n"); 352 | printf("\t\t%d\n", dc->stream_content); 353 | printf("\t\t%x\n", dc->component_type); 354 | printf("\t\t%x\n", dc->component_tag); 355 | printf("\t\t%d\n", dc->component_tag, dc->descriptor_length-6); 356 | printf("\t\t%s\n", lang); 357 | printf("\t\t%s\n", buf); 358 | printf("\t\n"); 359 | #endif 360 | } /*}}}*/ 361 | 362 | static inline void set_bit(int *bf, int b) { 363 | int i = b / 8 / sizeof(int); 364 | int s = b % (8 * sizeof(int)); 365 | bf[i] |= (1 << s); 366 | } 367 | 368 | static inline bool get_bit(int *bf, int b) { 369 | int i = b / 8 / sizeof(int); 370 | int s = b % (8 * sizeof(int)); 371 | return bf[i] & (1 << s); 372 | } 373 | 374 | /* Parse 0x54 Content Descriptor. {{{ */ 375 | static void parseContentDescription(void *data) { 376 | assert(GetDescriptorTag(data) == 0x54); 377 | struct descr_content *dc = data; 378 | int once[256/8/sizeof(int)] = {0,}; 379 | void *p; 380 | for (p = &dc->data; p < data + dc->descriptor_length; p += NIBBLE_CONTENT_LEN) { 381 | struct nibble_content *nc = p; 382 | int c1 = (nc->content_nibble_level_1 << 4) + nc->content_nibble_level_2; 383 | #ifdef CATEGORY_UNKNOWN 384 | int c2 = (nc->user_nibble_1 << 4) + nc->user_nibble_2; 385 | #endif 386 | if (c1 > 0 && !get_bit(once, c1)) { 387 | set_bit(once, c1); 388 | char *c = lookup(description_table, c1); 389 | if (c) 390 | if (c[0]) 391 | printf("\t%s\n", c); 392 | #ifdef CATEGORY_UNKNOWN 393 | else 394 | printf("\t\n", c+1, c1, c2); 395 | else 396 | printf("\t\n", c1, c2); 397 | #endif 398 | } 399 | // This is weird in the uk, they use user but not content, and almost the same values 400 | } 401 | } /*}}}*/ 402 | 403 | /* Parse 0x55 Rating Descriptor. {{{ */ 404 | void parseRatingDescription(void *data) { 405 | assert(GetDescriptorTag(data) == 0x55); 406 | struct descr_parental_rating *pr = data; 407 | void *p; 408 | for (p = &pr->data; p < data + pr->descriptor_length; p += PARENTAL_RATING_ITEM_LEN) { 409 | struct parental_rating_item *pr = p; 410 | switch (pr->rating) { 411 | case 0x00: /*undefined*/ 412 | break; 413 | case 0x01 ... 0x0F: 414 | printf("\t\n"); 415 | printf("\t\t%d\n", pr->rating + 3); 416 | printf("\t\n"); 417 | break; 418 | case 0x10 ... 0xFF: /*broadcaster defined*/ 419 | break; 420 | } 421 | } 422 | } /*}}}*/ 423 | 424 | /* Parse 0x5F Private Data Specifier. {{{ */ 425 | int parsePrivateDataSpecifier(void *data) { 426 | assert(GetDescriptorTag(data) == 0x5F); 427 | return GetPrivateDataSpecifier(data); 428 | } /*}}}*/ 429 | 430 | /* Parse 0x76 Content Identifier Descriptor. {{{ */ 431 | /* See ETSI TS 102 323, section 12 */ 432 | void parseContentIdentifierDescription(void *data) { 433 | assert(GetDescriptorTag(data) == 0x76); 434 | struct descr_content_identifier *ci = data; 435 | void *p; 436 | for (p = &ci->data; p < data + ci->descriptor_length; /* at end */) { 437 | struct descr_content_identifier_crid *crid = p; 438 | struct descr_content_identifier_crid_local *crid_data; 439 | 440 | int crid_length = 3; 441 | 442 | char type_buf[32]; 443 | char *type; 444 | char buf[256]; 445 | 446 | type = lookup(crid_type_table, crid->crid_type); 447 | if (type == NULL) 448 | { 449 | type = type_buf; 450 | sprintf(type_buf, "0x%2x", crid->crid_type); 451 | } 452 | 453 | switch (crid->crid_location) 454 | { 455 | case 0x00: /* Carried explicitly within descriptor */ 456 | crid_data = (descr_content_identifier_crid_local_t *)&crid->crid_ref_data; 457 | int cridlen = crid_data->crid_length; 458 | assert(cridlen < sizeof(buf)); 459 | memcpy(buf, (char *)&crid_data->crid_byte, cridlen); 460 | buf[cridlen] = '\0'; 461 | 462 | printf("\t%s\n", type, xmlify(buf, cridlen)); 463 | crid_length = 2 + crid_data->crid_length; 464 | break; 465 | case 0x01: /* Carried in Content Identifier Table (CIT) */ 466 | break; 467 | default: 468 | break; 469 | } 470 | 471 | p += crid_length; 472 | } 473 | } /*}}}*/ 474 | 475 | /* Parse Descriptor. {{{ 476 | * Tags should be output in this order: 477 | 478 | 'title', 'sub-title', 'desc', 'credits', 'date', 'category', 'language', 479 | 'orig-language', 'length', 'icon', 'url', 'country', 'episode-num', 480 | 'video', 'audio', 'previously-shown', 'premiere', 'last-chance', 481 | 'new', 'subtitles', 'rating', 'star-rating' 482 | */ 483 | static void parseDescription(void *data, size_t len) { 484 | int round, pds = 0; 485 | 486 | for (round = 0; round < 8; round++) { 487 | int seen = 0; // no title/language/video/audio/subtitles seen in this round 488 | void *p; 489 | for (p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { 490 | struct descr_gen *desc = p; 491 | switch (GetDescriptorTag(desc)) { 492 | case 0: 493 | break; 494 | case 0x4D: //short evt desc, [title] [sub-title] 495 | // there can be multiple language versions of these 496 | if (round == 0) { 497 | parseEventDescription(desc, TITLE); 498 | } 499 | else if (round == 1) 500 | parseEventDescription(desc, SUB_TITLE); 501 | break; 502 | case 0x4E: //long evt descriptor [desc] 503 | if (round == 2) 504 | parseLongEventDescription(desc); 505 | break; 506 | case 0x50: //component desc [language] [video] [audio] [subtitles] 507 | if (round == 4) 508 | parseComponentDescription(desc, LANGUAGE, &seen); 509 | else if (round == 5) 510 | parseComponentDescription(desc, VIDEO, &seen); 511 | else if (round == 6) 512 | parseComponentDescription(desc, AUDIO, &seen); 513 | else if (round == 7) 514 | parseComponentDescription(desc, SUBTITLES, &seen); 515 | break; 516 | case 0x53: // CA Identifier Descriptor 517 | break; 518 | case 0x54: // content desc [category] 519 | if (round == 3) 520 | parseContentDescription(desc); 521 | break; 522 | case 0x55: // Parental Rating Descriptor [rating] 523 | if (round == 7) 524 | parseRatingDescription(desc); 525 | break; 526 | case 0x5f: // Private Data Specifier 527 | pds = parsePrivateDataSpecifier(desc); 528 | break; 529 | case 0x64: // Data broadcast desc - Text Desc for Data components 530 | break; 531 | case 0x69: // Programm Identification Label 532 | break; 533 | case 0x81: // TODO ??? 534 | if (pds == 5) // ARD_ZDF_ORF 535 | break; 536 | case 0x82: // VPS (ARD, ZDF, ORF) 537 | if (pds == 5) // ARD_ZDF_ORF 538 | // TODO: 539 | break; 540 | case 0x4F: // Time Shifted Event 541 | case 0x52: // Stream Identifier Descriptor 542 | case 0x5E: // Multi Lingual Component Descriptor 543 | case 0x83: // Logical Channel Descriptor (some kind of news-ticker on ARD-MHP-Data?) 544 | case 0x84: // Preferred Name List Descriptor 545 | case 0x85: // Preferred Name Identifier Descriptor 546 | case 0x86: // Eacem Stream Identifier Descriptor 547 | break; 548 | case 0x76: // Content identifier descriptor 549 | if (round == 5) 550 | parseContentIdentifierDescription(desc); 551 | break; 552 | default: 553 | if (round == 0) 554 | printf("\t\n", GetDescriptorTag(desc), GetDescriptorLength(desc)); 555 | } 556 | } 557 | } 558 | } /*}}}*/ 559 | 560 | /* Check that program has at least a title as is required by xmltv.dtd. {{{ */ 561 | static bool validateDescription(void *data, size_t len) { 562 | void *p; 563 | for (p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { 564 | struct descr_gen *desc = p; 565 | if (GetDescriptorTag(desc) == 0x4D) { 566 | struct descr_short_event *evtdesc = p; 567 | // make sure that title isn't empty 568 | if (evtdesc->event_name_length) return true; 569 | } 570 | } 571 | return false; 572 | } /*}}}*/ 573 | 574 | /* Use the routine specified in ETSI EN 300 468 V1.4.1, {{{ 575 | * "Specification for Service Information in Digital Video Broadcasting" 576 | * to convert from Modified Julian Date to Year, Month, Day. */ 577 | static void parseMJD(long int mjd, struct tm *t) { 578 | int year = (int) ((mjd - 15078.2) / 365.25); 579 | int month = (int) ((mjd - 14956.1 - (int) (year * 365.25)) / 30.6001); 580 | int day = mjd - 14956 - (int) (year * 365.25) - (int) (month * 30.6001); 581 | int i = (month == 14 || month == 15) ? 1 : 0; 582 | year += i ; 583 | month = month - 2 - i * 12; 584 | 585 | t->tm_mday = day; 586 | t->tm_mon = month; 587 | t->tm_year = year; 588 | t->tm_isdst = -1; 589 | t->tm_wday = t->tm_yday = 0; 590 | } /*}}}*/ 591 | 592 | /* Parse Event Information Table. {{{ */ 593 | static void parseEIT(void *data, size_t len) { 594 | struct eit *e = data; 595 | void *p; 596 | struct tm dvb_time; 597 | char date_strbuf[256]; 598 | 599 | len -= 4; //remove CRC 600 | 601 | // For each event listing 602 | for (p = &e->data; p < data + len; p += EIT_EVENT_LEN + GetEITDescriptorsLoopLength(p)) { 603 | struct eit_event *evt = p; 604 | struct chninfo *c; 605 | // find existing information? 606 | for (c = channels; c != NULL; c = c->next) { 607 | // found it 608 | if (c->sid == HILO(e->service_id) && (c->eid == HILO(evt->event_id))) { 609 | if (c->ver <= e->version_number) // seen it before or its older FIXME: wrap-around to 0 610 | return; 611 | else { 612 | c->ver = e->version_number; // update outputted version 613 | update_count++; 614 | if (ignore_updates) 615 | return; 616 | break; 617 | } 618 | } 619 | } 620 | 621 | // its a new program 622 | if (c == NULL) { 623 | chninfo_t *nc = malloc(sizeof(struct chninfo)); 624 | nc->sid = HILO(e->service_id); 625 | nc->eid = HILO(evt->event_id); 626 | nc->ver = e->version_number; 627 | nc->next = channels; 628 | channels = nc; 629 | } 630 | 631 | /* we have more data, refresh alarm */ 632 | if (timeout) alarm(timeout); 633 | 634 | // No program info at end! Just skip it 635 | if (GetEITDescriptorsLoopLength(evt) == 0) 636 | return; 637 | 638 | parseMJD(HILO(evt->mjd), &dvb_time); 639 | 640 | dvb_time.tm_sec = BcdCharToInt(evt->start_time_s); 641 | dvb_time.tm_min = BcdCharToInt(evt->start_time_m); 642 | dvb_time.tm_hour = BcdCharToInt(evt->start_time_h) + time_offset; 643 | time_t start_time = timegm(&dvb_time); 644 | 645 | dvb_time.tm_sec += BcdCharToInt(evt->duration_s); 646 | dvb_time.tm_min += BcdCharToInt(evt->duration_m); 647 | dvb_time.tm_hour += BcdCharToInt(evt->duration_h); 648 | time_t stop_time = timegm(&dvb_time); 649 | 650 | time_t now; 651 | time(&now); 652 | // basic bad date check. if the program ends before this time yesterday, or two weeks from today, forget it. 653 | if ((difftime(stop_time, now) < -24*60*60) || (difftime(now, stop_time) > 14*24*60*60) ) { 654 | invalid_date_count++; 655 | if (ignore_bad_dates) 656 | return; 657 | } 658 | 659 | // a program must have a title that isn't empty 660 | if (!validateDescription(&evt->data, GetEITDescriptorsLoopLength(evt))) { 661 | return; 662 | } 663 | 664 | programme_count++; 665 | 666 | printf("service_id))); 667 | strftime(date_strbuf, sizeof(date_strbuf), "start=\"%Y%m%d%H%M%S %z\"", localtime(&start_time) ); 668 | printf("%s ", date_strbuf); 669 | strftime(date_strbuf, sizeof(date_strbuf), "stop=\"%Y%m%d%H%M%S %z\"", localtime(&stop_time)); 670 | printf("%s>\n ", date_strbuf); 671 | 672 | //printf("\t%i\n", HILO(evt->event_id)); 673 | //printf("\t%i\n", evt->running_status); 674 | //1 Airing, 2 Starts in a few seconds, 3 Pausing, 4 About to air 675 | 676 | parseDescription(&evt->data, GetEITDescriptorsLoopLength(evt)); 677 | printf("\n"); 678 | } 679 | } /*}}}*/ 680 | 681 | /* Exit hook: close xml tags. {{{ */ 682 | static void finish_up() { 683 | if (!silent) 684 | fprintf(stderr, "\n"); 685 | printf("\n"); 686 | exit(0); 687 | } /*}}}*/ 688 | 689 | /* Read EIT segments from DVB-demuxer or file. {{{ */ 690 | static void readEventTables(void) { 691 | int r, n = 0; 692 | char buf[1<<12], *bhead = buf; 693 | 694 | /* The dvb demultiplexer simply outputs individual whole packets (good), 695 | * but reading captured data from a file needs re-chunking. (bad). */ 696 | do { 697 | if (n < sizeof(struct si_tab)) 698 | goto read_more; 699 | struct si_tab *tab = (struct si_tab *)bhead; 700 | if (GetTableId(tab) == 0) 701 | goto read_more; 702 | size_t l = sizeof(struct si_tab) + GetSectionLength(tab); 703 | if (n < l) 704 | goto read_more; 705 | packet_count++; 706 | if (_dvb_crc32((uint8_t *)bhead, l) != 0) { 707 | /* data or length is wrong. skip bytewise. */ 708 | //l = 1; // FIXME 709 | crcerr_count++; 710 | } else 711 | parseEIT(bhead, l); 712 | status(); 713 | /* remove packet */ 714 | n -= l; 715 | bhead += l; 716 | continue; 717 | read_more: 718 | /* move remaining data to front of buffer */ 719 | if (n > 0) 720 | memmove(buf, bhead, n); 721 | /* fill with fresh data */ 722 | r = read(STDIN_FILENO, buf+n, sizeof(buf)-n); 723 | bhead = buf; 724 | n += r; 725 | } while (r > 0); 726 | } /*}}}*/ 727 | 728 | /* Setup demuxer or open file as STDIN. {{{ */ 729 | static int openInput(void) { 730 | int fd_epg, to; 731 | struct stat stat_buf; 732 | 733 | if (demux == NULL) 734 | return 0; // Read from STDIN, which is open al 735 | 736 | if ((fd_epg = open(demux, O_RDWR)) < 0) { 737 | perror("fd_epg DEVICE: "); 738 | return -1; 739 | } 740 | 741 | if (fstat(fd_epg, &stat_buf) < 0) { 742 | perror("fd_epg DEVICE: "); 743 | return -1; 744 | } 745 | if (S_ISCHR(stat_buf.st_mode)) { 746 | bool found = false; 747 | struct dmx_sct_filter_params sctFilterParams = { 748 | .pid = 18, // EIT data 749 | .timeout = 0, 750 | .flags = DMX_IMMEDIATE_START, 751 | .filter = { 752 | .filter[0] = chan_filter, // 4e is now/next this multiplex, 4f others 753 | .mask[0] = chan_filter_mask, 754 | }, 755 | }; 756 | 757 | if (ioctl(fd_epg, DMX_SET_FILTER, &sctFilterParams) < 0) { 758 | perror("DMX_SET_FILTER:"); 759 | close(fd_epg); 760 | return -1; 761 | } 762 | 763 | for (to = timeout; to > 0; to--) { 764 | int res; 765 | struct pollfd ufd = { 766 | .fd = fd_epg, 767 | .events = POLLIN, 768 | }; 769 | 770 | res = poll(&ufd, 1, 1000); 771 | if (0 == res) { 772 | fprintf(stderr, "."); 773 | fflush(stderr); 774 | continue; 775 | } 776 | if (1 == res) { 777 | found = true; 778 | break; 779 | } 780 | fprintf(stderr, "error polling for data\n"); 781 | close(fd_epg); 782 | return -1; 783 | } 784 | fprintf(stdout, "\n"); 785 | if (!found) { 786 | fprintf(stderr, "timeout - try tuning to a multiplex?\n"); 787 | close(fd_epg); 788 | return -1; 789 | } 790 | 791 | signal(SIGALRM, finish_up); 792 | alarm(timeout); 793 | } else { 794 | // disable alarm timeout for normal files 795 | timeout = 0; 796 | } 797 | 798 | dup2(fd_epg, STDIN_FILENO); 799 | close(fd_epg); 800 | 801 | return 0; 802 | } /*}}}*/ 803 | 804 | /* Read [cst]zap channels.conf file and print as XMLTV channel info. {{{ */ 805 | static void readZapInfo() { 806 | FILE *fd_zap; 807 | char buf[256]; 808 | if ((fd_zap = fopen(CHANNELS_CONF, "r")) == NULL) { 809 | fprintf(stderr, "No [cst]zap channels.conf to produce channel info\n"); 810 | return; 811 | } 812 | 813 | /* name:freq:inversion:symbol_rate:fec:quant:vid:aid:chanid:... */ 814 | while (fgets(buf, sizeof(buf), fd_zap)) { 815 | int i = 0; 816 | char *c, *id = NULL; 817 | for (c = buf; *c; c++) 818 | if (*c == ':') { 819 | *c = '\0'; 820 | if (++i == 8) /* chanid */ 821 | id = c + 1; 822 | } 823 | if (id && *id) { 824 | int chanid = atoi(id); 825 | if (chanid) { 826 | printf("\n", get_channelident(chanid)); 827 | printf("\t%s\n", xmlify(buf, sizeof(c))); 828 | printf("\n"); 829 | } 830 | } 831 | } 832 | 833 | fclose(fd_zap); 834 | } /*}}}*/ 835 | 836 | /* Main function. {{{ */ 837 | int main(int argc, char **argv) { 838 | /* Remove path from command */ 839 | ProgName = strrchr(argv[0], '/'); 840 | if (ProgName == NULL) 841 | ProgName = argv[0]; 842 | else 843 | ProgName++; 844 | /* Process command line arguments */ 845 | do_options(argc, argv); 846 | /* Load lookup tables. */ 847 | if (use_chanidents && load_lookup(&channelid_table, CHANIDENTS)) 848 | fprintf(stderr, "Error loading %s, continuing.\n", CHANIDENTS); 849 | if (!silent) 850 | fprintf(stderr, "\n"); 851 | 852 | printf("\n"); 853 | printf("\n"); 854 | printf("\n"); 855 | if (openInput() != 0) { 856 | fprintf(stderr, "Unable to get event data from multiplex.\n"); 857 | exit(1); 858 | } 859 | 860 | readZapInfo(); 861 | readEventTables(); 862 | finish_up(); 863 | 864 | return 0; 865 | } /*}}}*/ 866 | -------------------------------------------------------------------------------- /tv_grab_dvb.h: -------------------------------------------------------------------------------- 1 | #ifndef __tv_grab_dvd 2 | #define __tv_grab_dvd 3 | 4 | #include 5 | #include 6 | 7 | /* lookup.c */ 8 | union lookup_key { 9 | int i; 10 | char c[4]; 11 | }; 12 | struct lookup_table { 13 | union lookup_key u; 14 | char *desc; 15 | }; 16 | 17 | extern char *lookup(const struct lookup_table *l, int id); 18 | extern int load_lookup(struct lookup_table **l, const char *file); 19 | 20 | /* dvb_info_tables.c */ 21 | extern const struct lookup_table description_table[]; 22 | extern const struct lookup_table aspect_table[]; 23 | extern const struct lookup_table audio_table[]; 24 | extern const struct lookup_table crid_type_table[]; 25 | 26 | /* langidents.c */ 27 | extern const struct lookup_table languageid_table[]; 28 | 29 | /* crc32.c */ 30 | extern uint32_t _dvb_crc32(const uint8_t *data, size_t len); 31 | 32 | /* dvb_text.c */ 33 | extern char *xmlify(const char *s, int len); 34 | extern char *iso6937_encoding; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tv_grab_dvb.spec: -------------------------------------------------------------------------------- 1 | # Note that this is NOT a relocatable package 2 | Name: tv_grab_dvb 3 | Version: 0.10 4 | Release: 1 5 | Summary: dump dvb epg info in xmltv 6 | URL: http://www.darkskiez.co.uk/index.php?page=tv_grab_dvb 7 | License: GPL 8 | Group: Applications/Multimedia 9 | Packager: Antonio Beamud Montero 10 | Source: %{name}.tar.gz 11 | BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot 12 | 13 | %description 14 | A Linux program to dump DVB EPG info in xmltv format..i.e. Extract the TV Guide from the digital TV broadcasts. 15 | 16 | %prep 17 | %setup -n %{name} 18 | 19 | %build 20 | make 21 | 22 | %install 23 | install -m 644 -d $RPM_BUILD_ROOT%{_bindir}/ 24 | install -m 644 -d $RPM_BUILD_ROOT%{_mandir}/man1/ 25 | install -m 644 -d $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/ 26 | install -m 755 tv_grab_dvb $RPM_BUILD_ROOT%{_bindir}/ 27 | install -m 644 tv_grab_dvb.1 $RPM_BUILD_ROOT%{_mandir}/man1/ 28 | install -m 644 README ChangeLog channels.conf chanidents $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/ 29 | 30 | %clean 31 | [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT 32 | 33 | %files 34 | %defattr(-,root,root) 35 | %doc %{_mandir}/man1/* 36 | %doc %{_defaultdocdir}/%{name} 37 | %{_bindir}/* 38 | --------------------------------------------------------------------------------