[MPlayer-dev-eng] [PATCH] Proper teletext language support

Michael Niedermayer michaelni at gmx.at
Sun Aug 26 23:14:22 CEST 2007


Hi

On Mon, Aug 27, 2007 at 02:39:18AM +0700, Vladimir Voroshilov wrote:
> Here is patch for proper teletext language support.
> 
> It adds support for X/28/0 packet carrying primary and secondary charset info.
> 
> I want to add later (in separate patch) new "default charset code"
> option for cases when X/28/0 is not transmitted by network provider.
> 
> Please anybody look at patch and say is it ok to commit ?
[...]

> Index: mplayer/stream/tvi_vbi.c
> ===================================================================
> --- mplayer/stream/tvi_vbi.c	(revision 24210)
> +++ mplayer/stream/tvi_vbi.c	(working copy)
> @@ -21,7 +21,7 @@
>   *
>   * 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.
> + * (decode_raw_line_runin,pll_add,pll_reset,hamm24) of MythTV project.
[...]
> +static short hamm24err[64] =
> +{
> +    0x0000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
> +    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
> +    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
> +    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
> +    0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
> +    0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
> +    0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
> +    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
> +};
>  
> -enum {
> -  LAT_UNI=0,
> -  RUS_UNI,
> -  LANGS
> +static int hamm24cor[64] =
> +{
> +    0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,
> +    0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,
> +    0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,
> +    0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,
> +    0x00000, 0x00000, 0x00000, 0x00001, 0x00000, 0x00002, 0x00004, 0x00008,
> +    0x00000, 0x00010, 0x00020, 0x00040, 0x00080, 0x00100, 0x00200, 0x00400,
> +    0x00000, 0x00800, 0x01000, 0x02000, 0x04000, 0x08000, 0x10000, 0x20000,
> +    0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,
>  };
>  
> +static char hamm24val[256] =
> +{
> +      0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0,  1,  1,  1,  1,
> +      2,  2,  2,  2,  3,  3,  3,  3,  2,  2,  2,  2,  3,  3,  3,  3,
> +      4,  4,  4,  4,  5,  5,  5,  5,  4,  4,  4,  4,  5,  5,  5,  5,
> +      6,  6,  6,  6,  7,  7,  7,  7,  6,  6,  6,  6,  7,  7,  7,  7,
> +      8,  8,  8,  8,  9,  9,  9,  9,  8,  8,  8,  8,  9,  9,  9,  9,
> +     10, 10, 10, 10, 11, 11, 11, 11, 10, 10, 10, 10, 11, 11, 11, 11,
> +     12, 12, 12, 12, 13, 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13,
> +     14, 14, 14, 14, 15, 15, 15, 15, 14, 14, 14, 14, 15, 15, 15, 15,
> +      0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0,  1,  1,  1,  1,
> +      2,  2,  2,  2,  3,  3,  3,  3,  2,  2,  2,  2,  3,  3,  3,  3,
> +      4,  4,  4,  4,  5,  5,  5,  5,  4,  4,  4,  4,  5,  5,  5,  5,
> +      6,  6,  6,  6,  7,  7,  7,  7,  6,  6,  6,  6,  7,  7,  7,  7,
> +      8,  8,  8,  8,  9,  9,  9,  9,  8,  8,  8,  8,  9,  9,  9,  9,
> +     10, 10, 10, 10, 11, 11, 11, 11, 10, 10, 10, 10, 11, 11, 11, 11,
> +     12, 12, 12, 12, 13, 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13,
> +     14, 14, 14, 14, 15, 15, 15, 15, 14, 14, 14, 14, 15, 15, 15, 15
> +};
> +
> +static char hamm24par[3][256] =
> +{
> +    { // parities of first byte
> +        0, 33, 34,  3, 35,  2,  1, 32, 36,  5,  6, 39,  7, 38, 37,  4,
> +       37,  4,  7, 38,  6, 39, 36,  5,  1, 32, 35,  2, 34,  3,  0, 33,
> +       38,  7,  4, 37,  5, 36, 39,  6,  2, 35, 32,  1, 33,  0,  3, 34,
> +        3, 34, 33,  0, 32,  1,  2, 35, 39,  6,  5, 36,  4, 37, 38,  7,
> +       39,  6,  5, 36,  4, 37, 38,  7,  3, 34, 33,  0, 32,  1,  2, 35,
> +        2, 35, 32,  1, 33,  0,  3, 34, 38,  7,  4, 37,  5, 36, 39,  6,
> +        1, 32, 35,  2, 34,  3,  0, 33, 37,  4,  7, 38,  6, 39, 36,  5,
> +       36,  5,  6, 39,  7, 38, 37,  4,  0, 33, 34,  3, 35,  2,  1, 32,
> +       40,  9, 10, 43, 11, 42, 41,  8, 12, 45, 46, 15, 47, 14, 13, 44,
> +       13, 44, 47, 14, 46, 15, 12, 45, 41,  8, 11, 42, 10, 43, 40,  9,
> +       14, 47, 44, 13, 45, 12, 15, 46, 42, 11,  8, 41,  9, 40, 43, 10,
> +       43, 10,  9, 40,  8, 41, 42, 11, 15, 46, 45, 12, 44, 13, 14, 47,
> +       15, 46, 45, 12, 44, 13, 14, 47, 43, 10,  9, 40,  8, 41, 42, 11,
> +       42, 11,  8, 41,  9, 40, 43, 10, 14, 47, 44, 13, 45, 12, 15, 46,
> +       41,  8, 11, 42, 10, 43, 40,  9, 13, 44, 47, 14, 46, 15, 12, 45,
> +       12, 45, 46, 15, 47, 14, 13, 44, 40,  9, 10, 43, 11, 42, 41,  8
> +    }, { // parities of second byte
> +        0, 41, 42,  3, 43,  2,  1, 40, 44,  5,  6, 47,  7, 46, 45,  4,
> +       45,  4,  7, 46,  6, 47, 44,  5,  1, 40, 43,  2, 42,  3,  0, 41,
> +       46,  7,  4, 45,  5, 44, 47,  6,  2, 43, 40,  1, 41,  0,  3, 42,
> +        3, 42, 41,  0, 40,  1,  2, 43, 47,  6,  5, 44,  4, 45, 46,  7,
> +       47,  6,  5, 44,  4, 45, 46,  7,  3, 42, 41,  0, 40,  1,  2, 43,
> +        2, 43, 40,  1, 41,  0,  3, 42, 46,  7,  4, 45,  5, 44, 47,  6,
> +        1, 40, 43,  2, 42,  3,  0, 41, 45,  4,  7, 46,  6, 47, 44,  5,
> +       44,  5,  6, 47,  7, 46, 45,  4,  0, 41, 42,  3, 43,  2,  1, 40,
> +       48, 25, 26, 51, 27, 50, 49, 24, 28, 53, 54, 31, 55, 30, 29, 52,
> +       29, 52, 55, 30, 54, 31, 28, 53, 49, 24, 27, 50, 26, 51, 48, 25,
> +       30, 55, 52, 29, 53, 28, 31, 54, 50, 27, 24, 49, 25, 48, 51, 26,
> +       51, 26, 25, 48, 24, 49, 50, 27, 31, 54, 53, 28, 52, 29, 30, 55,
> +       31, 54, 53, 28, 52, 29, 30, 55, 51, 26, 25, 48, 24, 49, 50, 27,
> +       50, 27, 24, 49, 25, 48, 51, 26, 30, 55, 52, 29, 53, 28, 31, 54,
> +       49, 24, 27, 50, 26, 51, 48, 25, 29, 52, 55, 30, 54, 31, 28, 53,
> +       28, 53, 54, 31, 55, 30, 29, 52, 48, 25, 26, 51, 27, 50, 49, 24
> +    }, { // parities of third byte
> +       63, 14, 13, 60, 12, 61, 62, 15, 11, 58, 57,  8, 56,  9, 10, 59,
> +       10, 59, 56,  9, 57,  8, 11, 58, 62, 15, 12, 61, 13, 60, 63, 14,
> +        9, 56, 59, 10, 58, 11,  8, 57, 61, 12, 15, 62, 14, 63, 60, 13,
> +       60, 13, 14, 63, 15, 62, 61, 12,  8, 57, 58, 11, 59, 10,  9, 56,
> +        8, 57, 58, 11, 59, 10,  9, 56, 60, 13, 14, 63, 15, 62, 61, 12,
> +       61, 12, 15, 62, 14, 63, 60, 13,  9, 56, 59, 10, 58, 11,  8, 57,
> +       62, 15, 12, 61, 13, 60, 63, 14, 10, 59, 56,  9, 57,  8, 11, 58,
> +       11, 58, 57,  8, 56,  9, 10, 59, 63, 14, 13, 60, 12, 61, 62, 15,
> +       31, 46, 45, 28, 44, 29, 30, 47, 43, 26, 25, 40, 24, 41, 42, 27,
> +       42, 27, 24, 41, 25, 40, 43, 26, 30, 47, 44, 29, 45, 28, 31, 46,
> +       41, 24, 27, 42, 26, 43, 40, 25, 29, 44, 47, 30, 46, 31, 28, 45,
> +       28, 45, 46, 31, 47, 30, 29, 44, 40, 25, 26, 43, 27, 42, 41, 24,
> +       40, 25, 26, 43, 27, 42, 41, 24, 28, 45, 46, 31, 47, 30, 29, 44,
> +       29, 44, 47, 30, 46, 31, 28, 45, 41, 24, 27, 42, 26, 43, 40, 25,
> +       30, 47, 44, 29, 45, 28, 31, 46, 42, 27, 24, 41, 25, 40, 43, 26,
> +       43, 26, 25, 40, 24, 41, 42, 27, 31, 46, 45, 28, 44, 29, 30, 47
> +    }
> +};
> +
> +static int corrHamm24(unsigned char *p, int *err)
> +{
> +    int e = hamm24par[0][p[0]] ^ hamm24par[1][p[1]] ^ hamm24par[2][p[2]];
> +    int x = hamm24val[p[0]] | ((p[1]&0x7)<<4) | ((p[2]&0x7)<<11);
> +
> +    *err += hamm24err[e];
> +    return x ^ hamm24cor[e];
> +}
> +

do NOT commit this shit! and please dont take ANY code from mythtv anymore
its total crap

use the following, untested but the description in the spec is clear enough so
you should not have a problem with fixing any silly +-1 errors i made :)

/**
 *
 * Note, bits must be correctly ordered, that is for 8,4
 * P1 P2 D1 P3 D2 D3 D4 P4
 * and for 24,18
 * P1 P2 D1 P3 D2 D3 D4 P4  D5 D6 D7 D8 D9 DA DB P5  DC DD DE DF DG DH DI P6
 * @param len the length of the hamming code for example 7 (for 8,4) or 23 for (24,8)
 * @param ext 1 if the code is a extended hamming code 0 of not (all in teletext are extended)
 */
int decode_hamm(unsigned codeword, int len, int ext){
    unsigned syndrom=0;
    unsigned data=0;
    int i;

    for(i=0; i<len; i++)
        syndrom ^= (((codeword>>i)&1)*(i+1);

    if(syndrom > len)
        return -1;

    if(syndrom){
        codeword ^= 1<<(syndrom-1);
        if(ext){
            unsigned parity=1;
            for(i=0; i<=len; i++)
                parity ^= (codeword>>i)&1;
            if(parity)
                return -1;
        }
    }

    for(i=len; i>0; i--){
        if(i & (i-1))
            data= 2*data + ((codeword>>(i-1))&1);
    }
    return data;
}


> +typedef enum {
> +  LATIN=0,
> +  CYRILLIC2,
> +  LANGS
> +} teletext_charsets;

the typedef should be closer to the top of the file IMHO


[...]
> +/**
> + * \brief converts language bits to primary charset index
> + * \param lang language bits
> + * \return charset index in lang_chars array
> + *
> + * 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)
> + * For details see Table 32 of specification (subclause 15.2)
> + *
> + * \todo
> + * Add remaining charsets
> + *
> + */
> +static int lang2prim_charset (int lang){
> +    switch(lang){
> +    case 0x21: //Cyrillic-2 (Russian, Bulgarian)
> +        return CYRILLIC2;
> +    //Charsets below are not yet supported      
> +    case 0x20: //Cyrillic-1 (Serbian/Croatian)
> +    case 0x25: //Cyrillic-3 (Ukrainian)
> +    case 0x37: //Greek
> +    case 0x47: //Arabic
> +    case 0x55: //Hebrew
> +    case 0x57: //Arabic
> +    default:   //Latin
> +        return LATIN;
[...]
> +static int lang2sec_charset (int lang){
> +    switch(lang){
> +    case 0x24: //Cyrillic-2 (Russian, Bulgarian)
> +        return CYRILLIC2;
> +       //Charsets below are not yet supported      
> +    case 0x20: //Cyrillic-1 (Serbian/Croatian)
> +    case 0x25: //Cyrillic-3 (Ukrainian)
> +    case 0x37: //Greek
> +    case 0x47: //Arabic
> +    case 0x55: //Hebrew
> +    case 0x57: //Arabic
> +    default:   //Latin
> +        return LATIN;
> +    }
> +}

code duplication, these differ only in one entry, a single function
with a if() would do too
or maybe simple exchanging bit 1 and 4 ? it would remove the difference in the
code though ive not checked the spec ...


[...]
> -static unsigned int conv2uni(unsigned int p,int lang)
> +static unsigned int conv2uni(unsigned int p,int charset,int subset)
>  {
> -    int charset=lang2id(lang);
>      if(p<0x80 && p>=0x20){
> -        if(charset==LAT_UNI){
> +        if(charset==LATIN){
>              if (p>=0x23 && p<=0x24){
> -                return latin_subchars[lang][p-0x23];
> +                return latin_subchars[subset&7][p-0x23];
>              }else if (p==0x40){
> -                return latin_subchars[lang][2];
> +                return latin_subchars[subset&7][2];
>              }else if (p>=0x5b && p<=0x60){
> -                return latin_subchars[lang][p-0x5b+3];
> +                return latin_subchars[subset&7][p-0x5b+3];
>              }else if (p>=0x7b && p<=0x7e){
> -                return latin_subchars[lang][p-0x7b+9];
> -	    }
> -	}
> +                return latin_subchars[subset&7][p-0x7b+9];
> + 	    }
> +        }

cosmetic lanf/subset renaming
also the code mixes tabs and space i think this is not good


[...]
> @@ -526,7 +695,7 @@
>                  continue;
>              }
>              p[i].gfx=gfx?(separated?2:1):0;
> -            p[i].lng=lat?0:lang;
> +            p[i].lng=prim_lang?0:1;

p[i].lng= !prim_lang;

(please please use some more spaces it makes the code more readable ...)


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Those who are too smart to engage in politics are punished by being
governed by those who are dumber. -- Plato 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20070826/0e994dc6/attachment.pgp>


More information about the MPlayer-dev-eng mailing list