summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/dec_teletext.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-08-03 00:12:46 +0200
committerwm4 <wm4@nowhere>2012-08-03 00:12:46 +0200
commitebaaa41f2a4f2d492141f8af86a1d0694778baae (patch)
tree543b04f8928de5bd8a58c7622d410f9676f997f5 /libmpcodecs/dec_teletext.c
parent2aef9e2ef3a3c69466a3f0a737145f1f72c786f0 (diff)
downloadmpv-ebaaa41f2a4f2d492141f8af86a1d0694778baae.tar.bz2
mpv-ebaaa41f2a4f2d492141f8af86a1d0694778baae.tar.xz
Remove teletext support
Teletext requires special OSD support. Because I can't even test teletext, I can't restore support for it. Since teletext can be considered ancient and obscure, and since it doesn't make sense to keep the remaining teletext code without being able to use it, I'm removing it.
Diffstat (limited to 'libmpcodecs/dec_teletext.c')
-rw-r--r--libmpcodecs/dec_teletext.c1888
1 files changed, 0 insertions, 1888 deletions
diff --git a/libmpcodecs/dec_teletext.c b/libmpcodecs/dec_teletext.c
deleted file mode 100644
index 4ae94ec0d1..0000000000
--- a/libmpcodecs/dec_teletext.c
+++ /dev/null
@@ -1,1888 +0,0 @@
-/*
- * Teletext support
- *
- * Copyright (C) 2007 Vladimir Voroshilov <voroshil@gmail.com>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * Based on Attila Otvos' teletext patch, Michael Niedermayer's
- * proof-of-concept teletext capture utility and some parts
- * (decode_raw_line_runin,pll_add,pll_reset) of MythTV project.
- * Code for calculating [soc:eoc] is based on aletv of Edgar Toernig.
- *
- * Teletext system is described in
- * ETS 300 706 "Enhanced Teletext specification" : May 1997
- * http://www.themm.net/~mihu/linux/saa7146/specs/ets_300706e01p.pdf
- *
- * Some implementation details:
- * How to port teletext to another tvi_* driver (see tvi_v4l2.c for example):
- *
- * 1. Implement TVI_CONTROL_VBI_INIT (initialize driver-related vbi subsystem,
- * start grabbing thread)
- * input data: vbi device name.
- * (driver should also call TV_VBI_CONTROL_START for common vbi subsystem initialization
- * with pointer to initialized tt_stream_properties structure.
- * After ioctl call variable will contain pointer to initialized priv_vbi_t structure.
- *
- * 2. After receiving next chunk of raw vbi data call TV_VBI_CONTROL_DECODE_PAGE
- * ioctl with pointer to data buffer
- * 3. pass all other VBI related ioctl cmds to teletext_control routine
- *
- * Page displaying process consist of following stages:
- *
- * ---grabbing stage---
- * 0. stream/tvi_*.c: vbi_grabber(...)
- * getting vbi data from video device
- * ---decoding stage---
- * 1. libmpcodecs/dec_teletext.c: decode_raw_line_runin(...) or decode_raw_line_sine(...)
- * decode raw vbi data into sliced 45(?) bytes long packets
- * 2. libmpcodecs/dec_teletext.c: decode_pkt0(...), decode_pkt_page(...)
- * packets processing (header analyzing, storing complete page in cache,
- * only raw member of tt_char is filled at this stage)
- * 3. libmpcodecs/dec_teletext.c: decode_page(...)
- * page decoding. filling unicode,gfx,ctl,etc members of tt_char structure
- * with appropriate values according to teletext control chars, converting
- * text to utf8.
- * ---rendering stage---
- * 4. libmpcodecs/dec_teletext.c: prepare_visible_page(...)
- * processing page. adding number of just received by background process
- * teletext page, adding current time,etc.
- * 5. libvo/sub.c: vo_update_text_teletext(...)
- * rendering displayable osd with text and graphics
- *
- * TODO:
- * v4lv1,bktr support
- * spu rendering
- * is better quality on poor signal possible ?
- * link support
- * greyscale osd
- * slave command for dumping pages
- * fix bcd<->dec as suggested my Michael
- *
- * BUGS:
- * wrong colors in debug dump
- * blinking when visible page was just updated
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <math.h>
-#include <stdio.h>
-
-#ifdef HAVE_PTHREADS
-// pthreads are needed for async updates from v4l(2)
-// FIXME: try to avoid using pthread calls when running only a single
-// thread as e.g. with DVB teletext
-#include <pthread.h>
-#else
-#define pthread_mutex_init(m, p)
-#define pthread_mutex_destroy(m)
-#define pthread_mutex_lock(m)
-#define pthread_mutex_unlock(m)
-#endif
-
-#include "dec_teletext.h"
-#include "mp_msg.h"
-#include "libmpcodecs/img_format.h"
-#include "libavutil/common.h"
-#include "input/input.h"
-#include "osdep/timer.h"
-
-//#define DEBUG_DUMP 1
-
-/// page magazine entry structure
-typedef struct mag_s{
- tt_page* pt;
- int order;
-} mag_t;
-
-typedef struct {
- int on; ///< teletext on/off
- int pagenum; ///< seek page number
- int subpagenum; ///< seek subpage
- int curr_pagenum; ///< current page number
- int pagenumdec; ///< set page num with dec
-
- teletext_format tformat; ///< see teletext_format enum
- teletext_zoom zoom; ///< see teletext_zoom enum
- mag_t* mag; ///< pages magazine (has 8 entities)
- int primary_language; ///< primary character set
- int secondary_language; ///< secondary character set
- /// Currently displayed page (with additional info, e.g current time)
- tt_char display_page[VBI_ROWS*VBI_COLUMNS];
- /// number of raw bytes between two subsequent encoded bits
- int bpb;
- /// clock run-in sequence will be searched in buffer in [soc:eoc] bytes range
- int soc;
- int eoc;
- /// minimum number of raw vbi bytes wich can be decoded into 8 data bits
- int bp8bl;
- /// maximum number of raw vbi bytes wich can be decoded into 8 data bits
- int bp8bh;
-
- int pll_adj;
- int pll_dir;
- int pll_cnt;
- int pll_err;
- int pll_lerr;
- int pll_fixed;
- /// vbi stream properties (buffer size,bytes per line, etc)
- tt_stream_props* ptsp;
-#ifdef HAVE_PTHREADS
- pthread_mutex_t buffer_mutex;
-#endif
-
- tt_page** ptt_cache;
- unsigned char* ptt_cache_first_subpage;
- /// network info
- unsigned char initialpage;
- unsigned int initialsubpage;
- unsigned int networkid;
- int timeoffset; // timeoffset=realoffset*2
- unsigned int juliandate;
- unsigned int universaltime;
- unsigned char networkname[21];
- int cache_reset;
- /// "page changed" flag: 0-unchanged, 1-entire page, 3-only header
- int page_changed;
- int last_rendered;
-} priv_vbi_t;
-
-static unsigned char fixParity[256];
-
-static const tt_char tt_space={0x20,7,0,0,0,0,0,0,0x20};
-static const tt_char tt_error={'?',1,0,0,0,0,0,0,'?'}; // Red '?' on black background
-static double si[12];
-static double co[12];
-
-#define VBI_FORMAT(priv) (*(priv->ptsp))
-
-#define FIXP_SH 16
-#define ONE_FIXP (1<<FIXP_SH)
-#define FIXP2INT(a) ((a)>>FIXP_SH)
-#define ANY2FIXP(a) ((int)((a)*ONE_FIXP))
-
-static const unsigned char corrHamm48[256]={
- 0x01, 0xff, 0x01, 0x01, 0xff, 0x00, 0x01, 0xff,
- 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07,
- 0xff, 0x00, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00,
- 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff,
- 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07,
- 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x07,
- 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff,
- 0x06, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07,
- 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09,
- 0x02, 0x02, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff,
- 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff,
- 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03,
- 0x04, 0xff, 0xff, 0x05, 0x04, 0x04, 0x04, 0xff,
- 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07,
- 0xff, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, 0x05,
- 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff,
- 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09,
- 0x0a, 0xff, 0xff, 0x0b, 0x0a, 0x0a, 0x0a, 0xff,
- 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff,
- 0xff, 0x0b, 0x0b, 0x0b, 0x0a, 0xff, 0xff, 0x0b,
- 0x0c, 0x0c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff,
- 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07,
- 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x0d, 0x0d,
- 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff,
- 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x09,
- 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09,
- 0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09,
- 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff,
- 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09,
- 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0e, 0x0f, 0xff,
- 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff,
- 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e };
-
-
-enum {
- LATIN=0,
- CYRILLIC1,
- CYRILLIC2,
- CYRILLIC3,
- GREEK,
- LANGS
-};
-
-// conversion table for chars 0x20-0x7F (UTF8)
-// TODO: add another languages
-static const unsigned int lang_chars[LANGS][0x60]={
- {
- //Latin
- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
- 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
- 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
- 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
- 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
- 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
- },
- {
- //Cyrillic-1 (Serbian/Croatian)
- 0x20,0x21,0x22,0x23,0x24,0x25,0x044b,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x0427,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
- 0x0425,0x0418,0x0408,0x041a,0x041b,0x041c,0x041d,0x041e,
- 0x041f,0x040c,0x0420,0x0421,0x0422,0x0423,0x0412,0x0403,
- 0x0409,0x040a,0x0417,0x040b,0x0416,0x0402,0x0428,0x040f,
- 0x0447,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
- 0x0445,0x0438,0x0428,0x043a,0x043b,0x043c,0x043d,0x043e,
- 0x043f,0x042c,0x0440,0x0441,0x0442,0x0443,0x0432,0x0423,
- 0x0429,0x042a,0x0437,0x042b,0x0436,0x0422,0x0448,0x042f
- },
- {
- //Cyrillic-2 (Russian/Bulgarian)
- 0x20,0x21,0x22,0x23,0x24,0x25,0x044b,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
- 0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,
- 0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412,
- 0x042c,0x042a,0x0417,0x0428,0x042d,0x0429,0x0427,0x042b,
- 0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
- 0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,
- 0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432,
- 0x044c,0x044a,0x0437,0x0448,0x044d,0x0449,0x0447,0x044b
- },
- {
- //Cyrillic-3 (Ukrainian)
- 0x20,0x21,0x22,0x23,0x24,0x25,0xef,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
- 0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,
- 0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412,
- 0x042c,0x49,0x0417,0x0428,0x042d,0x0429,0x0427,0xcf,
- 0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
- 0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,
- 0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432,
- 0x044c,0x69,0x0437,0x0448,0x044d,0x0449,0x0447,0xFF
- },
- {
- //Greek
- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
- 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
- 0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,
- 0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f,
- 0x03a0,0x03a1,0x03a2,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,
- 0x03a8,0x03a9,0x03aa,0x03ab,0x03ac,0x03ad,0x03ae,0x03af,
- 0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,
- 0x03b8,0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf,
- 0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,
- 0x03c8,0x03c9,0x03ca,0x03cb,0x03cc,0x03cd,0x03ce,0x03cf
- }
-};
-
-/**
- * Latin National Option Sub-Sets
- * see Table 36 of ETS specification for details.
- *
- * 00: £ $ @ « ½ » ¬ # ­ ¼ ¦ ¾ ÷ English
- * 01: é ï à ë ê ù î # è â ô û ç French
- * 02: # ¤ É Ä Ö Å Ü _ é ä ö å ü Swedish/Finnish/Hungarian
- * 03: # ů č ť ž ý í ř é á ě ú š Czech/Slovak
- * 04: # $ § Ä Ö Ü ^ _ ° ä ö ü ß German
- * 05: ç $ ¡ á é í ó ú ¿ ü ñ è à Portuguese/Spanish
- * 06: £ $ é ° ç » ¬ # ù à ò è ì Italian
- *
- */
-static const unsigned int latin_subchars[8][13]={
- // English
- {0xa3,0x24,0x40,0xab,0xbd,0xbb,0xac,0x23,0xad,0xbc,0xa6,0xbe,0xf7},
- // French
- {0xe9,0xef,0xe0,0xeb,0xea,0xf9,0xee,0x23,0xe8,0xe2,0xf4,0xfb,0xe7},
- // Swedish/Finnish/Hungarian
- {0x23,0xa4,0xc9,0xc4,0xd6,0xc5,0xdc,0x5f,0xe9,0xe4,0xf6,0xe5,0xfc},
- // Czech/Slovak
- {0x23,0x16f,0x10d,0x165,0x17e,0xfd,0xed,0x159,0xe9,0xe1,0x11b,0xfa,0x161},
- // German
- {0x23,0x24,0xa7,0xc4,0xd6,0xdc,0x5e,0x5f,0xb0,0xe4,0xf6,0xfc,0xdf},
- // Portuguese/Spanish
- {0xe7,0x24,0xa1,0xe1,0xe9,0xed,0xf3,0xfa,0xbf,0xfc,0xf1,0xe8,0xe0},
- // Italian
- {0xa3,0x24,0xe9,0xb0,0xe7,0xbb,0xac,0x23,0xf9,0xe0,0xf2,0xe8,0xec},
- // Reserved
- {0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x7b,0x7c,0x7d,0x7e}
-};
-
-/**
- * List of supported languages.
- *
- * lang_code bits for primary Language:
- * bits 7-4 corresponds to bits 14-11 of 28 packet's first triplet
- * bits 3-1 corresponds to bits C12-C14 of packet 0 (lang)
- *
- * lang_code bits for secondary Language:
- * bits 7-5 corresponds to bits 3-1 of 28 packet's second triplet
- * bits 4,2 corresponds to bits 18,16 of 28 packet's first triplet
- * bits 3,1 corresponds to bits 15,17 of 28 packet's first triplet
- *
- * For details see Tables 32 and 33 of specification (subclause 15.2)
- */
-struct {
- unsigned char lang_code;
- unsigned char charset;
- const char* lang_name;
-} const tt_languages[]=
-{
- { 0x01, LATIN, "French"},
- { 0x02, LATIN, "Swedish/Finnish/Hungarian"},
- { 0x03, LATIN, "Czech/Slovak"},
- { 0x04, LATIN, "German"},
- { 0x05, LATIN, "Portuguese/Spanish"},
- { 0x06, LATIN, "Italian"},
-
- { 0x08, LATIN, "Polish"},
- { 0x09, LATIN, "French"},
- { 0x0a, LATIN, "Swedish/Finnish/Hungarian"},
- { 0x0b, LATIN, "Czech/Slovak"},
- { 0x0c, LATIN, "German"},
- { 0x0e, LATIN, "Italian"},
-
- { 0x10, LATIN, "English"},
- { 0x11, LATIN, "French"},
- { 0x12, LATIN, "Swedish/Finnish/Hungarian"},
- { 0x13, LATIN, "Turkish"},
- { 0x14, LATIN, "German"},
- { 0x15, LATIN, "Portuguese/Spanish"},
- { 0x16, LATIN, "Italian"},
-
- { 0x1d, LATIN, "Serbian/Croatian/Slovenian (Latin)"},
-
- { 0x20, CYRILLIC1, "Serbian/Croatian (Cyrillic)"},
- { 0x21, CYRILLIC2, "Russian, Bulgarian"},
- { 0x22, LATIN, "Estonian"},
- { 0x23, LATIN, "Czech/Slovak"},
- { 0x24, LATIN, "German"},
- { 0x25, CYRILLIC3, "Ukrainian"},
- { 0x26, LATIN, "Lettish/Lithuanian"},
-
- { 0x33, LATIN, "Turkish"},
- { 0x37, GREEK, "Greek"},
-
- { 0x40, LATIN, "English"},
- { 0x41, LATIN, "French"},
-// { 0x47, ARABIC, "Arabic"},
-
-// { 0x55, HEBREW, "Hebrew"},
-// { 0x57, ARABIC, "Arabic"},
-
- { 0x00, LATIN, "English"},
-};
-
-/**
- * \brief 24/18 Hamming code decoding
- * \param data bytes with hamming code (array must be at least 3 bytes long)
- * \return -1 if multiple bit error occured, D1-DI data bits - otherwise
- *
- * \note Bits must be correctly ordered, that is for 24/18 (lowest bit first)
- * P1 P2 D1 P3 D2 D3 D4 P4 D5 D6 D7 D8 D9 DA DB P5 DC DD DE DF DG DH DI P6
- */
-static int corrHamm24(unsigned char *data){
- unsigned char syndrom=0;
- int cw=data[0] | (data[1]<<8) | (data[2]<<16);
- int i;
-
- for(i=0;i<23;i++)
- syndrom^=((cw>>i)&1)*(i+33);
-
- syndrom^=(cw>>11)&32;
-
- if(syndrom&31){
- if(syndrom < 32 || syndrom > 55)
- return -1;
- cw ^= 1<<((syndrom&31)-1);
- }
-
- return (cw&4)>>2 |
- (cw&0x70)>>3 |
- (cw&0x3f00)>>4 |
- (cw&0x3f0000)>>5;
-}
-
-/**
- * \brief converts language bits to charset index
- * \param lang language bits
- * \return charset index in lang_chars array
- */
-static int lang2charset (int lang){
- int i;
- for(i=0;tt_languages[i].lang_code;i++)
- if(tt_languages[i].lang_code==lang)
- break;
-
- return tt_languages[i].charset;
-}
-
-/**
- * \brief convert chars from curent teletext codepage into MPlayer charset
- * \param p raw teletext char to decode
- * \param charset index on lang_chars
- * \param lang index in substitution array (latin charset only)
- * \return UTF8 char
- *
- * \remarks
- * routine will analyze raw member of given tt_char structure and
- * fill unicode member of the same struct with appropriate utf8 code.
- */
-static unsigned int conv2uni(unsigned int p,int charset,int lang)
-{
-
- if(p<0x80 && p>=0x20){
- if(charset==LATIN){
- lang&=7;
- if (p>=0x23 && p<=0x24){
- return latin_subchars[lang][p-0x23];
- }else if (p==0x40){
- return latin_subchars[lang][2];
- }else if (p>=0x5b && p<=0x60){
- return latin_subchars[lang][p-0x5b+3];
- }else if (p>=0x7b && p<=0x7e){
- return latin_subchars[lang][p-0x7b+9];
- }
- }
- return lang_chars[charset][p-0x20];
- }else
- return 0x20;
-}
-
-static void init_vbi_consts(priv_vbi_t* priv){
- int i,j;
- double ang;
- for(i=0; i<256; i++){
- j=i&0x7F;
- j^= j+j;
- j^= j<<2;
- j^= j<<4;
- fixParity[i]= i ^ (j&0x80) ^ 0x80;
- }
-
- for(i=0,ang=0; i<12; i++,ang+=M_PI/priv->bpb){
- si[i]= sin(ang);
- co[i]= cos(ang);
- }
-
- priv->bpb=(priv->ptsp->sampling_rate/6937500.0)*ONE_FIXP+0.5;
- priv->soc=FFMAX(9.2e-6*priv->ptsp->sampling_rate-priv->ptsp->offset, 0);
- priv->eoc=FFMIN(12.9e-6*priv->ptsp->sampling_rate-priv->ptsp->offset,
- priv->ptsp->samples_per_line-43*8*priv->bpb/ONE_FIXP);
- if (priv->eoc - priv->soc<16*priv->bpb/ONE_FIXP){ // invalid [soc:eoc]
- priv->soc=0;
- priv->eoc=92;
- }
- priv->bp8bl=0.97*8*priv->bpb/ONE_FIXP; // -3% tolerance
- priv->bp8bh=1.03*8*priv->bpb/ONE_FIXP; // +3% tolerance
-}
-/**
- * \brief calculate increased/decreased by given value page number
- * \param curr current page number in hexadecimal for
- * \param direction decimal value (can be negative) to add to value
- * of curr parameter
- * \return new page number in hexadecimal form
- *
- * VBI page numbers are represented in special hexadecimal form, e.g.
- * page with number 123 (as seen by user) internally has number 0x123.
- * and equation 0x123+8 should be equal to 0x131 instead of regular 0x12b.
- *
- *
- * Page numbers 0xYYY (where Y is not belongs to (0..9).
- * Page number belongs to [0x000,0x799] or [0x100:0x899] (first 0 can be
- * treated as '8')
- */
-static int steppage(int p, int direction, int skip_hidden)
-{
- if(skip_hidden)
- p=(p&15)+((p>>4)&15)*10+(p>>8)*100;
- p+=direction;
- if(skip_hidden){
- p=(p+800)%800;
- p=(p%10)+((p/10)%10)*16+(p/100)*256;
- }
-
- return p&0x7ff;
-}
-
-/*
-------------------------------------------------------------------
- Cache stuff
-------------------------------------------------------------------
-*/
-
-/**
- * \brief add/update entry in cache
- * \param priv private data structure
- * \param pg page to store in cache
- * \param line line to update (value below 0 means update entire page)
- */
-static void put_to_cache(priv_vbi_t* priv,tt_page* pg,int line){
- tt_page* pgc; //page in cache
- int i,j,count;
-
- if(line<0){
- i=0;
- count=VBI_ROWS*VBI_COLUMNS;
- }else if(line<VBI_ROWS){
- i=line*VBI_COLUMNS;
- count=(line+1)*VBI_COLUMNS;
- }else
- return;
-
- pthread_mutex_lock(&(priv->buffer_mutex));
-
- if(!priv->ptt_cache[pg->pagenum]){
- priv->ptt_cache[pg->pagenum]=calloc(1,sizeof(tt_page));
- pgc=priv->ptt_cache[pg->pagenum];
- }else{
- pgc=priv->ptt_cache[pg->pagenum];
- while(pgc->next_subpage && pgc->subpagenum!=pg->subpagenum)
- pgc=pgc->next_subpage;
-
- if(pgc->subpagenum!=pg->subpagenum){
- pgc->next_subpage=calloc(1,sizeof(tt_page));
- pgc=pgc->next_subpage;
- }
- }
- pgc->pagenum=pg->pagenum;
- pgc->subpagenum=pg->subpagenum;
- pgc->primary_lang=pg->primary_lang;
- pgc->secondary_lang=pg->secondary_lang;
- pgc->flags=pg->flags;
- for(j=0;j<6;++j)
- pgc->links[j]=pg->links[j];
- //instead of copying entire page into cache, copy only undamaged
- //symbols into cache
- for(;i<count;i++){
- if(!(pg->raw[i]&0x80))
- pgc->raw[i]=pg->raw[i];
- else
- mp_msg(MSGT_TELETEXT,MSGL_DBG3,"char error. pg:%x, c[%d]=0x%x\n",
- pg->pagenum,i,pg->raw[i]);
- }
- pgc->active=1;
- pthread_mutex_unlock(&(priv->buffer_mutex));
-}
-
-/**
- * \brief get any subpage number of given page
- * \param priv private data structure
- * \param pagenum page number to search subpages in
- *
- * \return subpage number of first found subpage which belongs to
- * given page number
- *
- * \note page itself is subpage too (and usually has subpage number 0)
- */
-static inline int get_subpagenum_from_cache(priv_vbi_t* priv, int pagenum){
- if (!priv->ptt_cache[pagenum])
- return 0x3f7f;
- else
- return priv->ptt_cache[pagenum]->subpagenum;
-}
-
-/**
- * \brief get page from cache by it page and subpage number
- * \param priv private data structure
- * \param pagenum page number
- * \param subpagenum subpage number
- *
- * \return pointer to tt_page structure if requested page is found
- * and NULL otherwise
- */
-static inline tt_page* get_from_cache(priv_vbi_t* priv, int pagenum,int subpagenum){
- tt_page* tp=priv->ptt_cache[pagenum];
-
- while(tp && tp->subpagenum!=subpagenum)
- tp=tp->next_subpage;
- return tp;
-}
-
-/**
- * \brief clears cache
- * \param priv private data structure
- *
- * Deletes all tt_page structures from cache and frees allocated memory.
- * Only zero-filled array of pointers remains in memory
- */
-static void clear_cache(priv_vbi_t* priv){
- int i;
- tt_page* tp;
-
- /*
- Skip next 5 buffers to avoid mixing teletext pages from different
- channels during channel switch
- */
- priv->cache_reset=5;
- for(i=0;i<VBI_MAX_PAGES;i++){
- while(priv->ptt_cache[i]){
- tp=priv->ptt_cache[i];
- priv->ptt_cache[i]=tp->next_subpage;
- free(tp);
- }
- }
- priv->initialsubpage=priv->networkid=0;
- priv->timeoffset=0;
- priv->juliandate=priv->universaltime=0;
- memset(priv->networkname,0,21);
-}
-
-/**
- * \brief cache initialization
- * \param priv private data structure
- *
- * \note Has to be called before any cache operations!
- */
-static void init_cache(priv_vbi_t* priv){
- priv->ptt_cache=calloc(VBI_MAX_PAGES,sizeof(tt_page*));
-}
-
-/**
- * \brief destroys cache
- * \param priv private data structure
- *
- * Frees all memory allocated for cache (including array of pointers).
- * It is safe to call this routine multiple times
- */
-static void destroy_cache(priv_vbi_t* priv){
- if(priv->ptt_cache){
- clear_cache(priv);
- free(priv->ptt_cache);
- priv->ptt_cache=NULL;
- }
-}
-
-/*
-------------------------------------------------------------------
- Decoder stuff
-------------------------------------------------------------------
-*/
-/**
- * \brief converts raw teletext page into useful format (1st rendering stage)
- * \param pg page to decode
- * \param raw raw data to decode page from
- * \param primary_lang primary language code
- * \param secondary_lang secondary language code
-*
- * Routine fills tt_char structure of each teletext_page character with proper
- * info about foreground and background colors, character
- * type (graphics/control/text).
- */
-static void decode_page(tt_char* p,unsigned char* raw,int primary_lang,int secondary_lang,int flags)
-{
- int row,col;
- int prim_charset=lang2charset(primary_lang);
- int sec_charset=lang2charset(secondary_lang);
-
- for(row=0;row<VBI_ROWS;row++) {
- int prim_lang=1;
- int gfx=0;
- int fg_color=7;
- int bg_color=0;
- int separated=0;
- int conceal=0;
- int hold=0;
- int flash=0;
- int box=0;
-
- tt_char tt_held=tt_space;
- for(col=0;col<VBI_COLUMNS;col++){
- int i=row*VBI_COLUMNS+col;
- int c=raw[i];
- p[i].raw=c;
- if(c&0x80){ //damaged char
- p[i]=tt_error;
- continue;
- }
- if((flags&TT_PGFL_SUBTITLE) || (flags&TT_PGFL_NEWFLASH))
- p[i].hidden=!box;
- else
- p[i].hidden=0;
- p[i].gfx=gfx?(separated?2:1):0;
- p[i].lng=prim_lang;
- p[i].ctl=(c&0x60)==0?1:0;
- p[i].fg=fg_color;
- p[i].bg=bg_color;
- p[i].flh=flash;
-
- if ((c&0x60)==0){ //control chars
- if(c>=0x08 && c<=0x09){//Flash/Steady
- flash=c==0x08;
- p[i].flh=flash;
- if(c==0x09){
- p[i].fg=fg_color;
- p[i].bg=bg_color;
- }
- }else if(c>=0x0a && c<=0x0b){
- box=c&1;
- }else if(c>=0x0c && c<=0x0f){
- }else if (c<=0x17){ //colors
- fg_color=c&0x0f;
- gfx=c>>4;
- conceal=0;
- if(!gfx) hold=0;
- }else if (c<=0x18){
- conceal=1;
- }else if (c<=0x1a){ //Contiguous/Separated gfx
- separated=!(c&1);
- }else if (c<=0x1b){
- prim_lang=!prim_lang;
- }else if (c<=0x1d){
- bg_color=(c&1)?fg_color:0;
- p[i].bg=bg_color;
- }else{ //Hold/Release Graphics
- hold=!(c&1);
- }
- p[i].ctl=1;
- if(hold || c==0x1f){
- p[i]=tt_held;
- p[i].fg=fg_color;
- p[i].bg=bg_color;
- }else
- p[i].unicode=p[i].gfx?0:' ';
- continue;
- }
-
- if(conceal){
- p[i].gfx=0;
- p[i].unicode=' ';
- }else if(gfx){
- p[i].unicode=c-0x20;
- if (p[i].unicode>0x3f) p[i].unicode-=0x20;
- tt_held=p[i];
- }else{
- if(p[i].lng){
- p[i].unicode=conv2uni(c,prim_charset,primary_lang&7);
- }else{
- p[i].unicode=conv2uni(c,sec_charset,secondary_lang&7);
- }
- }
- p[i].fg=fg_color;
- p[i].bg=bg_color;
- }
- }
-}
-
-/**
- * \brief prepares current page for displaying
- * \param priv_vbi private data structure
- *
- * Routine adds some useful info (time and page number of page, grabbed by
- * background thread to top line of current page). Displays "No teletext"
- * string if no vbi data available.
- */
-#define PRINT_HEX(dp,i,h) dp[i].unicode=((h)&0xf)>9?'A'+((h)&0xf)-10:'0'+((h)&0xf)
-static void prepare_visible_page(priv_vbi_t* priv){
- tt_page *pg,*curr_pg;
- unsigned char *p;
- int i;
-
- pthread_mutex_lock(&(priv->buffer_mutex));
- mp_msg(MSGT_TELETEXT,MSGL_DBG3,"dec_teletext: prepare_visible_page pg:0x%x, sub:0x%x\n",
- priv->pagenum,priv->subpagenum);
- if(priv->subpagenum==0x3f7f) //no page yet
- priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);
-
- pg=get_from_cache(priv,priv->pagenum,priv->subpagenum);
- mp_dbg(MSGT_TELETEXT,MSGL_DBG3,"dec_teletext: prepare_vibible_page2 pg:0x%x, sub:0x%x\n",
- priv->pagenum,priv->subpagenum);
-
- curr_pg=get_from_cache(priv,priv->curr_pagenum,
- get_subpagenum_from_cache(priv,priv->curr_pagenum));
- if (!pg && !curr_pg){
- p=_("No teletext");
- for(i=0;i<VBI_COLUMNS && *p;i++){
- GET_UTF8(priv->display_page[i].unicode,*p++,break;);
- }
- for(;i<VBI_ROWS*VBI_COLUMNS;i++)
- priv->display_page[i]=tt_space;
- pthread_mutex_unlock(&(priv->buffer_mutex));
- return;
- }
-
- if (!pg || !pg->active){
- for(i=0;i<VBI_ROWS*VBI_COLUMNS;i++){
- priv->display_page[i]=tt_space;
- }
- }else{
- decode_page(priv->display_page,pg->raw,pg->primary_lang,pg->secondary_lang,pg->flags);
- mp_msg(MSGT_TELETEXT,MSGL_DBG3,"page #%x was decoded!\n",pg->pagenum);
- }
-
- PRINT_HEX(priv->display_page,0,(priv->curr_pagenum&0x700)?priv->curr_pagenum>>8:8);
- PRINT_HEX(priv->display_page,1,priv->curr_pagenum>>4);
- PRINT_HEX(priv->display_page,2,priv->curr_pagenum);
- priv->display_page[3].unicode=' ';
- priv->display_page[4].unicode=' ';
- switch(priv->pagenumdec>>12){
- case 1:
- priv->display_page[5].unicode='_';
- priv->display_page[6].unicode='_';
- PRINT_HEX(priv->display_page,7,priv->pagenumdec);
- break;
- case 2:
- priv->display_page[5].unicode='_';
- PRINT_HEX(priv->display_page,6,priv->pagenumdec>>4);
- PRINT_HEX(priv->display_page,7,priv->pagenumdec);
- break;
- default:
- PRINT_HEX(priv->display_page,5,(priv->pagenum&0x700)?priv->pagenum>>8:8);
- PRINT_HEX(priv->display_page,6,priv->pagenum>>4);
- PRINT_HEX(priv->display_page,7,priv->pagenum);
- }
- if(priv->subpagenum!=0x3f7f){
- priv->display_page[8].unicode='.';
- PRINT_HEX(priv->display_page,9,priv->subpagenum>>4);
- PRINT_HEX(priv->display_page,10,priv->subpagenum);
- }else{
- priv->display_page[8].unicode=' ';
- priv->display_page[9].unicode=' ';
- priv->display_page[10].unicode=' ';
- }
- priv->display_page[11].unicode=' ';
- for(i=VBI_COLUMNS;i>VBI_TIME_LINEPOS ||
- ((curr_pg->raw[i]&0x60) && curr_pg->raw[i]!=0x20 && i>11);
- --i)
- if(curr_pg->raw[i]&0x60)
- priv->display_page[i].unicode=curr_pg->raw[i];
- else
- priv->display_page[i].unicode=' ';
- pthread_mutex_unlock(&(priv->buffer_mutex));
-}
-/*
-------------------------------------------------------------------
- Renderer stuff
-------------------------------------------------------------------
-*/
-#ifdef DEBUG_DUMP
-/**
- * \brief renders teletext page into given file
- * \param pt page to render
- * \param f opened file descriptor
- * \param pagenum which page to render
- * \param colored use colors not implemented yet)
- *
- * Text will be UTF8 encoded
- */
-static void render2text(tt_page* pt,FILE* f,int colored){
- int i,j;
- unsigned int u;
- unsigned char buf[8];
- unsigned char tmp;
- int pos;
- tt_char dp[VBI_ROWS*VBI_COLUMNS];
- int color=0;
- int bkg=0;
- int c1,b1;
- if(!pt)
- return;
- fprintf(f,"+========================================+\n");
- fprintf(f,"| lang:%d pagenum:0x%x subpagenum:%d flags:0x%x|\n",
- pt->lang,
- pt->pagenum,
- pt->subpagenum,
- 0);
- fprintf(f,"+----------------------------------------+\n");
-
- decode_page(dp,pt->raw,pt->primary_lang,pt->secondary_lang,pt->flags);
- for(i=0;i<VBI_ROWS;i++){
- fprintf(f,"|");
- if(colored) fprintf(f,"\033[40m");
- for(j=0;j<VBI_COLUMNS;j++)
- {
- u=dp[i*VBI_COLUMNS+j].unicode;
- if(dp[i*VBI_COLUMNS+j].fg <= 7)
- c1=30+dp[i*VBI_COLUMNS+j].fg;
- else
- c1=38;
- if(dp[i*VBI_COLUMNS+j].bg <= 7)
- b1=40+dp[i*VBI_COLUMNS+j].bg;
- else
- b1=40;
- if (b1!=bkg && colored){
- fprintf(f,"\033[%dm",b1);
- bkg=b1;
- }
- if(c1!=color && colored){
- fprintf(f,"\033[%dm",c1);
- color=c1;
- }
- if(dp[i*VBI_COLUMNS+j].gfx){
- fprintf(f,"*");
- }else{
- pos=0;
- PUT_UTF8(u,tmp,if(pos<7) buf[pos++]=tmp;);
- buf[pos]='\0';
- fprintf(f,"%s",buf);
- }
- }
-
- if (colored) fprintf(f,"\033[0m");
- color=-1;bkg=-1;
- fprintf(f,"|\n");
- }
- //for debug
- fprintf(f,"+====================raw=================+\n");
- for(i=0;i<VBI_ROWS;i++){
- for(j=0;j<VBI_COLUMNS;j++)
- fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].raw);
- fprintf(f,"\n");
- }
- fprintf(f,"+====================lng=================+\n");
- for(i=0;i<VBI_ROWS;i++){
- for(j=0;j<VBI_COLUMNS;j++)
- fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].lng);
- fprintf(f,"\n");
- }
- fprintf(f,"+========================================+\n");
-}
-
-/**
- * \brief dump page into pgXXX.txt file in vurrent directory
- * \param pt page to dump
- *
- * \note XXX in filename is page number
- * \note use only for debug purposes
- */
-static void dump_page(tt_page* pt)
-{
- FILE*f;
- char name[100];
- snprintf(name,99,"pg%x.txt",pt->pagenum);