in reply to Re^6: encoding hdmi video byte
in thread encoding hdmi video byte

Okay. I took your spec and coded this slow and labourious implementation and applied it to the bytes 0 .. 255:

#! perl -slw use strict; use Data::Dump qw[ pp ]; my %map; for my $i ( 0 .. 255 ) { my @Q; my @D = split '', unpack 'b8', chr $i; $Q[ 0 ] = $D[ 0 ]; $Q[ 1 ] = $D[ 1 ] ^ $Q[ 0 ]; $Q[ 2 ] = $D[ 2 ] ^ $Q[ 1 ]; $Q[ 3 ] = $D[ 3 ] ^ $Q[ 2 ]; $Q[ 4 ] = $D[ 4 ] ^ $Q[ 3 ]; $Q[ 5 ] = $D[ 5 ] ^ $Q[ 4 ]; $Q[ 6 ] = $D[ 6 ] ^ $Q[ 5 ]; $Q[ 7 ] = $D[ 7 ] ^ $Q[ 6 ]; my $outb = ord pack 'b8', "@Q"; $map{ $i } = $outb; } pp \%map;

And it produced this output:

That's a byte to byte mapping table. I then used that to build the translation table I posted.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re^8: encoding hdmi video byte
by AnomalousMonk (Archbishop) on Feb 24, 2010 at 23:54 UTC

    A couple of points I don't understand about Re^7: encoding hdmi video byte.

    First, in the statement
        my $outb = ord pack 'b8',"@Q";
    will not  "@Q" interpolate the array with spaces between the elements of  @Q and so give an oddball result (i.e., only 16 unique values) since a space (ASCII space == 0x20) is packed by b as a 0 bit and half the elements of  @Q will be ignored?
    I.e., shouldn't it be
        my $outb = ord pack 'b8',join '', @Q;
    instead?

    The other point I don't understand is that I took the OP statement

    Data byte D(0:7) encode this to make 9bit data q_m(0:8) q_m[0] = D(0); q_m(1) = q_m(0) XOR D(1); q_m(2) = q_m(1) XOR D(2); q_m(3) = q_m(2) XOR D(3); q_m(4) = q_m(3) XOR D(4); q_m(5) = q_m(4) XOR D(5); q_m(6) = q_m(5) XOR D(6); q_m(7) = q_m(6) XOR D(7); q_m(8) = 1;

    to be pseudo-code, and to be the equivalent (on a byte-for-byte basis) of

    $q_m_byte = (0x100 | ($D_byte ^ (0xff & ($q_m_byte << 1))));

    with a  $q_m_byte 'byte' of 9 bits always ending up with its bit-8 set, and bit-7 of the original value of  $q_m_byte always being lost.

    But

    $Q[ 0 ] = $D[ 0 ]; $Q[ 1 ] = $D[ 1 ] ^ $Q[ 0 ]; $Q[ 2 ] = $D[ 2 ] ^ $Q[ 1 ]; $Q[ 3 ] = $D[ 3 ] ^ $Q[ 2 ]; ...

    seems to be the equivalent of

    $Q[ 0 ] = $D[ 0 ]; $Q[ 1 ] = $D[ 1 ] ^ $D[ 0 ]; $Q[ 2 ] = $D[ 2 ] ^ $D[ 1 ] ^ $D[ 0 ]; $Q[ 3 ] = $D[ 3 ] ^ $D[ 2 ] ^ $D[ 1 ] ^ $D[ 0 ]; ...

    which is very different.

      You're right on the "@Q" part. Dumb mistake. With that corrected, the mapping makes a lot more sense.

      As for the right interpretation of the spec, I guess you'll have to ask the OP. I believe, (with the "deliberate" error:) and constant 9th bit excepted), I coded a direct implementation of the spec. If the spec is wrong, or my interpretation of it is wrong, then the OP will have to correct it.

      The main point was to answer the OPs question of the best way to perform the mapping efficiently, and that is tr/// with the appropriate translation strings. On a gig of data, doing 10 x 100MB tr///s, (or even 1 x 1GB if he has the memory), is going to beat performing half a dozens boolean operations on every byte, hands down.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
      Hi AnomalousMonk, Here is the quote from my req... "...the LSb of the output (Q[0] = D[0]) matches the LSb of the input. With the starting value established, the remaining 7bits of the output (9th bit always 1) is derived from sequential XORing of each bit of the input with the previously derived bit...." Therefore i coded it this way. In a very simple way. pls let me know if it is clear now. Also i was looking for some input to make my code smaller/smarter than it is now.
      my %map; for my $i ( 0 .. 255 ) { my @Q = qw(0 0 0 0 0 0 0 0 0); my $result; #Step 1 : $Q[0] = D[0] $Q[0] = ($i & 0x01); #Step 2 : $Q[1] = D[1] ^ $Q[0] $Q[1] = (($i & 0x02) ^ ($Q[0] << 1)); #Step 3 : $Q[2] = D[2] ^ $Q[1] $Q[2] = ($i & 0x04) ^ ($Q[1] << 1); #Step 4 : $Q[3] = D[3] ^ $Q[2] $Q[3] = ($i & 0x08) ^ ($Q[2] << 1); #Step 5 : $Q[4] = D[4] ^ $Q[3] $Q[4] = ($i & 0x10) ^ ($Q[3] << 1); #Step 6 : $Q[5] = D[5] ^ $Q[4] $Q[5] = ($i & 0x20) ^ ($Q[4] << 1); #Step 7 : $Q[6] = D[6] ^ $Q[5] $Q[6] = ($i & 0x40) ^ ($Q[5] << 1); #Step 8 : $Q[7] = D[7] ^ $Q[6] $Q[7] = ($i & 0x80) ^ ($Q[6] << 1); #Step 9 : $Q[8] = 1 $Q[8] = 0x100; $result = ($Q[0] | $Q[1] | $Q[2] | $Q[3] | $Q[4] | $Q[5] | $Q[6] | + $Q[7] | $Q[8]); $map{ $i } = $result; #print "$result "; } pp \%map;

        My (mis)understanding on first reading the OP was that the needed data transformation was q_m = f(q_m, D), whereas BrowserUk understood it to be q_m = f(D).

        Looking at Re^9: encoding hdmi video byte, it is clear that BrowserUk had the right idea, and a quick check of the output of this implementation and BrowserUk's (after the  "@Q" bit is fixed, and ignoring those pesky high bits) shows they are functionally the same.

        All the rest is as BrowserUk wrote. Just use the info in  %map to create a  tr/// translator. This you can do by hand or, as I think BrowserUk wrote somewhere, create a translator function on the fly with eval. This will zip through the input data pretty quickly (either in one big Gig or in several smaller chunks). Then, the only problem remaining is the pesky high-order constant bit(s?), bit-8 (and -9?), which, again as BrowserUk wrote, it would be simplest and quickest just to spit out alternately with the transformed input bytes. Happy hdmi-ing!

Re^8: encoding hdmi video byte
by hdmiguru (Initiate) on Feb 24, 2010 at 22:01 UTC
    Thanks a lot! Mr. BrowserUK.... that is really a ery big help !!!!

      Just to clarify, is the proper interpretation of your OP that of Re^7: encoding hdmi video byte, or is it more like

      Data byte D(0:7) encode this to make 9bit data q_m(0:8) new previous bit of bit of q_m(0) = D(0); q_m(1) = q_m(0) XOR D(1); q_m(2) = q_m(1) XOR D(2); q_m(3) = q_m(2) XOR D(3); q_m(4) = q_m(3) XOR D(4); q_m(5) = q_m(4) XOR D(5); q_m(6) = q_m(5) XOR D(6); q_m(7) = q_m(6) XOR D(7); q_m(8) = 1;

        For the record. Once the translation tables are correct, whatever the proper encoding is, tr/// will process 1GB in 17 seconds, including the read and write time,


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Yes what you have said is correct. The encoding starts with taking the bit 0 (D[0]) of input data and that becomes the bit 0 of result (Q[0]). Then XOR the bit 0 of the result with bit 1 of input data. That becomes bit 1 of the result (Q1). Then XOR the bit 1 of the result with the bit 2 of input data. That becomes bit 2 of the result (Q2). Then XOR the bit 2 of the result with bit 3 of input data. That becomes bit 3 of the result (Q3). Then XOR the bit 3 of the result with the bit 4 of input data. That becomes bit 4 of the result (Q4). Then XOR the bit 4 of the result with bit 5 of input data. That becomes bit 5 of the result (Q5). Then XOR the bit 5 of the result with the bit 6 of input data. That becomes bit 6 of the result (Q6). Then XOR the bit 6 of the result with bit 7 of input data. That becomes bit 7 of the result (Q7). Th bit 8 of the result is always 1 (which indicates that we used XOR to the receiver). example input data 1010 0101 output data 1 0110 0011