accessoryservices/pluggeddisplay/edidparser/src/cea861edidparser.cpp
changeset 0 4e1aa6a622a0
child 7 1a73e8f1b64d
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 /*
       
     2  * Copyright (c) 2008,2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description:
       
    15  * Implementation of CCea861EdidParser class.
       
    16  *
       
    17  */
       
    18 
       
    19 #include "cea861edidparser.h"
       
    20 #include "trace.h"
       
    21 
       
    22 // ======== LOCAL FUNCTIONS ========
       
    23 
       
    24 
       
    25 // ======== MEMBER FUNCTIONS ========
       
    26 
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // CCea861EdidParser::CCea861EdidParser
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 CCea861EdidParser::CCea861EdidParser() :
       
    33     iParsed( EFalse ),
       
    34     iAudioDataBlockSupported( EFalse ),
       
    35     iVideoDataBlockSupported( EFalse ),
       
    36     iVendorSpecificDataBlockSupported( EFalse ),
       
    37     iSpeakerAllocationDataBlockSupported( EFalse )
       
    38     {
       
    39     FUNC_LOG;
       
    40     }
       
    41 
       
    42 // ---------------------------------------------------------------------------
       
    43 // CEdidParserBase::ConstructL
       
    44 // ---------------------------------------------------------------------------
       
    45 //
       
    46 void CCea861EdidParser::ConstructL( const TExtDataBlock& aData )
       
    47     {
       
    48     FUNC_LOG;
       
    49 
       
    50     iParsedInfo = CCea861ExtEdidInformation::NewL();
       
    51     ParseExtensionBlockL( aData );
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // CEdidParserBase::NewL
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 EXPORT_C CCea861EdidParser* CCea861EdidParser::NewL( const TExtDataBlock& aData )
       
    59     {
       
    60     FUNC_LOG;
       
    61 
       
    62     CCea861EdidParser* self = CCea861EdidParser::NewLC( aData );
       
    63     CleanupStack::Pop( self );
       
    64     return self;
       
    65     }
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // CEdidParserBase::NewLC
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 EXPORT_C CCea861EdidParser* CCea861EdidParser::NewLC( const TExtDataBlock& aData )
       
    72     {
       
    73     FUNC_LOG;
       
    74 
       
    75     CCea861EdidParser* self = new ( ELeave ) CCea861EdidParser();
       
    76     CleanupStack::PushL( self );
       
    77     self->ConstructL( aData );
       
    78     return self;
       
    79     }
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // CCea861EdidParser::~CCea861EdidParser
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 CCea861EdidParser::~CCea861EdidParser()
       
    86     {
       
    87     FUNC_LOG;
       
    88 
       
    89     delete iParsedInfo;
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // CCea861EdidParser::ParseExtensionBlockL
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 EXPORT_C TInt CCea861EdidParser::ParseExtensionBlockL( const TExtDataBlock& aData )
       
    97     {
       
    98     FUNC_LOG;
       
    99 
       
   100     TInt err( KErrNone );
       
   101     TInt index( 0 );
       
   102 
       
   103     // Check first byte to see if tag is 0x2.
       
   104     // If not return error.
       
   105     if( aData[index] != KBit1 )
       
   106         {
       
   107         return KErrNotSupported;
       
   108         }
       
   109 
       
   110     iParsedInfo->iExtensionTag = aData[index];
       
   111     index++;
       
   112 
       
   113     // Check revision
       
   114     iParsedInfo->iRevision = aData[index];
       
   115     index++;
       
   116     switch( iParsedInfo->iRevision )
       
   117         {
       
   118         case 1:
       
   119             err = ReadCeaVersion1L( aData, index );
       
   120             break;
       
   121         case 2:
       
   122             err = ReadCeaVersion2L( aData, index );
       
   123             break;
       
   124         case 3:
       
   125             err = ReadCeaVersion3L( aData, index );
       
   126             break;
       
   127         default:
       
   128             err = KErrNotSupported;
       
   129             break;
       
   130         }
       
   131 
       
   132     if( err == KErrNone )
       
   133         {
       
   134         iParsed = ETrue;
       
   135         }
       
   136 
       
   137     return err;
       
   138     }
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // CCea861EdidParser::isExtensionBlockParsed
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 EXPORT_C TBool CCea861EdidParser::IsExtensionBlockParsed()
       
   145     {
       
   146     FUNC_LOG;
       
   147 
       
   148     return iParsed;
       
   149     }
       
   150 
       
   151 // ----------------------------------------------------------------------------
       
   152 // CCea861EdidParser::GetVIC
       
   153 // ----------------------------------------------------------------------------
       
   154 //
       
   155 EXPORT_C TInt8 CCea861EdidParser::GetVIC( TUint8 aNumber )
       
   156     {
       
   157     FUNC_LOG;
       
   158 
       
   159     if( !iParsed )
       
   160         {
       
   161         return KErrNotFound;
       
   162         }
       
   163 
       
   164     if( IsVideoDataBlockSupported() )
       
   165         {
       
   166         return KErrNotFound;
       
   167         }
       
   168 
       
   169     if( iParsedInfo->iShortVideoDescriptors )
       
   170         {
       
   171         TCEA861VideoDataBlock* cur = iParsedInfo->iShortVideoDescriptors;
       
   172         TUint8 count = 0;
       
   173         while( cur )
       
   174             {
       
   175             if( cur->iNative )
       
   176                 {
       
   177                 if( count == aNumber )
       
   178                     {
       
   179                     return cur->iVIC;
       
   180                     }
       
   181                 count++;
       
   182                 }
       
   183             cur = cur->iNext;
       
   184             }
       
   185         }
       
   186 
       
   187     return KErrNotFound;
       
   188     }
       
   189 
       
   190 // ----------------------------------------------------------------------------
       
   191 // CCea861EdidParser::Underscan
       
   192 //
       
   193 // ----------------------------------------------------------------------------
       
   194 //
       
   195 EXPORT_C TBool CCea861EdidParser::Underscan()
       
   196     {
       
   197     FUNC_LOG;
       
   198 
       
   199     if( iParsedInfo->UnderscanDataSupported() )
       
   200         {
       
   201         return iParsedInfo->iUnderscan;
       
   202         }
       
   203     return EFalse;
       
   204     }
       
   205 
       
   206 // ----------------------------------------------------------------------------
       
   207 // CCea861EdidParser::BasicAudio
       
   208 //
       
   209 // ----------------------------------------------------------------------------
       
   210 //
       
   211 EXPORT_C TBool CCea861EdidParser::BasicAudio()
       
   212     {
       
   213     FUNC_LOG;
       
   214 
       
   215     if( iParsedInfo->AudioDataSupported() )
       
   216         {
       
   217         return iParsedInfo->iAudio;
       
   218         }
       
   219     return EFalse;
       
   220     }
       
   221 
       
   222 // ----------------------------------------------------------------------------
       
   223 // CCea861EdidParser::YCbCr444
       
   224 //
       
   225 // ----------------------------------------------------------------------------
       
   226 //
       
   227 EXPORT_C TBool CCea861EdidParser::YCbCr444()
       
   228     {
       
   229     FUNC_LOG;
       
   230 
       
   231     if( iParsedInfo->YCbCr444DataSupported() )
       
   232         {
       
   233         return iParsedInfo->iYCbCr444;
       
   234         }
       
   235     return EFalse;
       
   236     }
       
   237 
       
   238 // ----------------------------------------------------------------------------
       
   239 // CCea861EdidParser::YCbCr422
       
   240 //
       
   241 // ----------------------------------------------------------------------------
       
   242 //
       
   243 EXPORT_C TBool CCea861EdidParser::YCbCr422()
       
   244     {
       
   245     FUNC_LOG;
       
   246 
       
   247     if( iParsedInfo->YCbCr422DataSupported() )
       
   248         {
       
   249         return iParsedInfo->iYCbCr422;
       
   250         }
       
   251     return EFalse;
       
   252     }
       
   253 
       
   254 // ----------------------------------------------------------------------------
       
   255 // CCea861EdidParser::TotalNumberOfNativeFormats
       
   256 //
       
   257 // ----------------------------------------------------------------------------
       
   258 //
       
   259 EXPORT_C TUint8 CCea861EdidParser::TotalNumberOfNativeFormats()
       
   260     {
       
   261     FUNC_LOG;
       
   262     
       
   263     return iParsedInfo->TotalNumberOfNativeFormats();
       
   264     }
       
   265 
       
   266 // ----------------------------------------------------------------------------
       
   267 // CCea861EdidParser::IsAudioDataBlockSupported
       
   268 //
       
   269 // ----------------------------------------------------------------------------
       
   270 //
       
   271 EXPORT_C TBool CCea861EdidParser::IsAudioDataBlockSupported()
       
   272     {
       
   273     FUNC_LOG;
       
   274 
       
   275     return iAudioDataBlockSupported;
       
   276     }
       
   277 
       
   278 // ----------------------------------------------------------------------------
       
   279 // CCea861EdidParser::IsVideoDataBlockSupported
       
   280 //
       
   281 // ----------------------------------------------------------------------------
       
   282 //
       
   283 EXPORT_C TBool CCea861EdidParser::IsVideoDataBlockSupported()
       
   284     {
       
   285     FUNC_LOG;
       
   286 
       
   287     return iVideoDataBlockSupported;
       
   288     }
       
   289 
       
   290 // ----------------------------------------------------------------------------
       
   291 // CCea861EdidParser::IsVideoDataBlockSupported
       
   292 //
       
   293 // ----------------------------------------------------------------------------
       
   294 //
       
   295 EXPORT_C TBool CCea861EdidParser::IsVendorSpecificDataBlockSupported()
       
   296     {
       
   297     FUNC_LOG;
       
   298 
       
   299     return iVendorSpecificDataBlockSupported;
       
   300     }
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // CCea861EdidParser::GetParsedInformation
       
   304 //
       
   305 // ----------------------------------------------------------------------------
       
   306 //
       
   307 EXPORT_C CCea861ExtEdidInformation* CCea861EdidParser::GetParsedInformation()
       
   308     {
       
   309     FUNC_LOG;
       
   310 
       
   311     return iParsedInfo;
       
   312     }
       
   313 
       
   314 // ----------------------------------------------------------------------------
       
   315 // CCea861EdidParser::IsSpeakerAllocationDataBlockSupported
       
   316 //
       
   317 // ----------------------------------------------------------------------------
       
   318 //
       
   319 EXPORT_C TBool CCea861EdidParser::IsSpeakerAllocationDataBlockSupported()
       
   320     {
       
   321     FUNC_LOG;
       
   322 
       
   323     return iSpeakerAllocationDataBlockSupported;
       
   324     }
       
   325 
       
   326 // ----------------------------------------------------------------------------
       
   327 // CCea861EdidParser::GetVideoLatency
       
   328 //
       
   329 // ----------------------------------------------------------------------------
       
   330 //
       
   331 EXPORT_C TUint8 CCea861EdidParser::GetVideoLatency()
       
   332     {
       
   333     FUNC_LOG;
       
   334 
       
   335     // Video latency is kept in Vendor Specific Data Block according to
       
   336     // HDMISpecification13a.pdf, table 8-6
       
   337     TUint8 latency = 0;
       
   338     TCEA861VendorSpecificDataBlock* data = iParsedInfo->iVendorSpecificData;
       
   339     if( ( !data ) || ( !IsVendorSpecificDataBlockSupported() ) )
       
   340         {
       
   341         return latency;
       
   342         }
       
   343 
       
   344     TCEA861VendorSpecificDataBlockPayload* cur = data->iVendorSpecificPayloadStart;
       
   345 
       
   346     // According to HDMI spec table 8-6,  index of video latency is 9
       
   347     // Start counting from index 4 
       
   348     for( TInt ii = 0; ii < 6; ii++ )
       
   349         {
       
   350         if( !cur )
       
   351             {
       
   352             break;
       
   353             }
       
   354         
       
   355         // Byte 8
       
   356         else if( ii == 4 )
       
   357             {
       
   358             // Check if latency field bits are present
       
   359             if( !LatencyFieldsPresent( cur->iData ) )
       
   360                 {
       
   361                 // Latency fields are not present
       
   362                 break;
       
   363                 }
       
   364             }
       
   365 
       
   366         // Byte 9
       
   367         else if( ii == 5 )
       
   368             {
       
   369             // Get Video_latency byte
       
   370             latency = cur->iData;
       
   371             }
       
   372 
       
   373         cur = cur->iNext;
       
   374         }
       
   375     
       
   376     // Convert latency in to ms
       
   377     latency = LatencyInMs( latency );
       
   378 
       
   379     return latency;
       
   380     }
       
   381 
       
   382 // ----------------------------------------------------------------------------
       
   383 // CCea861EdidParser::GetAudioLatency
       
   384 //
       
   385 // ----------------------------------------------------------------------------
       
   386 //
       
   387 EXPORT_C TUint8 CCea861EdidParser::GetAudioLatency()
       
   388     {
       
   389     FUNC_LOG;
       
   390 
       
   391     // Audio latency is kept in Vendor Specific Data Block according to
       
   392     // HDMISpecification13a.pdf, table 8-6
       
   393     TUint8 latency = 0;
       
   394     TCEA861VendorSpecificDataBlock* data = iParsedInfo->iVendorSpecificData;
       
   395     if( ( !data ) || ( !IsVendorSpecificDataBlockSupported() ) )
       
   396         {
       
   397         return latency;
       
   398         }
       
   399 
       
   400     TCEA861VendorSpecificDataBlockPayload* cur = data->iVendorSpecificPayloadStart;
       
   401 
       
   402     // According to HDMI spec table 8-6,  index of audio latency is 10
       
   403     // Start counting from index 4 
       
   404     for( TInt ii = 0; ii < 7; ii++ )
       
   405         {
       
   406         if( !cur )
       
   407             {
       
   408             break;
       
   409             }
       
   410 
       
   411         // Byte 8
       
   412         else if( ii == 4 )
       
   413             {
       
   414             // Check if latency field bits are present
       
   415             if( !LatencyFieldsPresent( cur->iData ) )
       
   416                 {
       
   417                 // Latency fields are not present
       
   418                 break;
       
   419                 }
       
   420             }
       
   421         
       
   422         // Byte 10
       
   423         else if( ii == 6 )
       
   424             {
       
   425             latency = cur->iData;
       
   426             }
       
   427 
       
   428         cur = cur->iNext;
       
   429         }
       
   430 
       
   431     // Convert latency in to ms
       
   432     latency = LatencyInMs( latency );
       
   433 
       
   434     return latency;
       
   435     }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 // CCea861EdidParser::GetInterlacedVideoLatency
       
   439 //
       
   440 // ----------------------------------------------------------------------------
       
   441 //
       
   442 EXPORT_C TUint8 CCea861EdidParser::GetInterlacedVideoLatency()
       
   443     {
       
   444     // Video latency is kept in Vendor Specific Data Block according to
       
   445     // HDMISpecification13a.pdf, table 8-6
       
   446     TUint8 latency = 0;
       
   447     TCEA861VendorSpecificDataBlock* data = iParsedInfo->iVendorSpecificData;
       
   448     if( ( !data ) || ( !IsVendorSpecificDataBlockSupported() ) )
       
   449         {
       
   450         return latency;
       
   451         }
       
   452 
       
   453     TCEA861VendorSpecificDataBlockPayload* cur = data->iVendorSpecificPayloadStart;
       
   454 
       
   455     // According to HDMI spec table 8-6,  index of video latency is 9 or 11
       
   456     // Start counting from index 4
       
   457     
       
   458     // Start index == 4, video latency == 9 (4 + 5)
       
   459     TInt videoLatencyByte = 5;
       
   460     for( TInt ii = 0; ii < 8; ii++ )
       
   461         {
       
   462         if( !cur )
       
   463             {
       
   464             break;
       
   465             }
       
   466         
       
   467         // Byte 8
       
   468         else if( ii == 4 )
       
   469             {
       
   470             // Check if latency field bits are present
       
   471             TUint8 byte8 = cur->iData;
       
   472             if( InterlacedLatencyFieldsPresent( byte8 ) )
       
   473                 {
       
   474                 // Interlaced latency fields are present
       
   475                 // Start index == 4, interlaced video latency == 11 (4 + 7)
       
   476                 videoLatencyByte = 7;
       
   477                 }
       
   478             else if( !LatencyFieldsPresent( byte8 ) )
       
   479                 {
       
   480                 // Latency fields are not present
       
   481                 break;
       
   482                 }
       
   483             }
       
   484 
       
   485         // Byte 9 or Byte 11
       
   486         else if( ii == videoLatencyByte )
       
   487             {
       
   488             // Get Video_latency byte
       
   489             latency = cur->iData;
       
   490             }
       
   491 
       
   492         cur = cur->iNext;
       
   493         }
       
   494 
       
   495     // Convert latency in to ms
       
   496     latency = LatencyInMs( latency );
       
   497 
       
   498     return latency;
       
   499     }
       
   500 
       
   501 // ----------------------------------------------------------------------------
       
   502 // CCea861EdidParser::GetInterlacedAudioLatency
       
   503 //
       
   504 // ----------------------------------------------------------------------------
       
   505 //
       
   506 EXPORT_C TUint8 CCea861EdidParser::GetInterlacedAudioLatency()
       
   507     {
       
   508     FUNC_LOG;
       
   509 
       
   510     // Audio latency is kept in Vendor Specific Data Block according to
       
   511     // HDMISpecification13a.pdf, table 8-6
       
   512     TUint8 latency = 0;
       
   513     TCEA861VendorSpecificDataBlock* data = iParsedInfo->iVendorSpecificData;
       
   514     if( ( !data ) || ( !IsVendorSpecificDataBlockSupported() ) )
       
   515         {
       
   516         return latency;
       
   517         }
       
   518 
       
   519     TCEA861VendorSpecificDataBlockPayload* cur = data->iVendorSpecificPayloadStart;
       
   520 
       
   521     // According to HDMI spec table 8-6,  index of audio latency is 10 or 12
       
   522     // Start counting from index 4
       
   523     
       
   524     // Start index == 4, audio latency == 10 (4 + 6)
       
   525     TInt audioLatencyByte = 6;
       
   526     for( TInt ii = 0; ii < 9; ii++ )
       
   527         {
       
   528         if( !cur )
       
   529             {
       
   530             break;
       
   531             }
       
   532 
       
   533         // Byte 8
       
   534         else if( ii == 4 )
       
   535             {
       
   536             // Check if interlaced latency field bits are present
       
   537             TUint8 byte8 = cur->iData;
       
   538             if( InterlacedLatencyFieldsPresent( byte8 ) )
       
   539                 {
       
   540                 // Start index == 4, interlaced audio latency == 12 (4 + 8)
       
   541                 audioLatencyByte = 8;
       
   542                 }
       
   543             
       
   544             // Check if latency field bits are present
       
   545             else if( !LatencyFieldsPresent( byte8 ) )
       
   546                 {
       
   547                 // Latency fields are not present
       
   548                 break;
       
   549                 }
       
   550             }
       
   551         
       
   552         // Byte 10 or Byte 12
       
   553         else if( ii == audioLatencyByte )
       
   554             {
       
   555             latency = cur->iData;
       
   556             }
       
   557 
       
   558         cur = cur->iNext;
       
   559         }
       
   560 
       
   561     // Convert latency in to ms
       
   562     latency = LatencyInMs( latency );
       
   563 
       
   564     return latency;
       
   565     }
       
   566 
       
   567 // ---------------------------------------------------------------------------
       
   568 // CCea861EdidParser::ReadCeaVersion1L
       
   569 // ---------------------------------------------------------------------------
       
   570 //
       
   571 TInt CCea861EdidParser::ReadCeaVersion1L( const TExtDataBlock& aData,
       
   572     TInt aIndex )
       
   573     {
       
   574     FUNC_LOG;
       
   575 
       
   576     if( aIndex > KEdidParserSizeOfEdidBlock )
       
   577         {
       
   578         return KErrOverflow;
       
   579         }
       
   580 
       
   581     for( TInt index = aIndex; index < KEdidParserSizeOfEdidBlock; index++ )
       
   582         {
       
   583         // Offset. If this is a newer version of CEA-861,
       
   584         // then this is skipped (we are already past the offset)
       
   585         if( index == 2 )
       
   586             {
       
   587             iParsedInfo->iOffset = aData[index];
       
   588             // Skip over the offset
       
   589             while( index < iParsedInfo->iOffset )
       
   590                 {
       
   591                 index++;
       
   592                 }
       
   593             }
       
   594 
       
   595         if( aData[index] != KEdidPaddingByte ) // padding = 0x00
       
   596             {
       
   597             // start of 18-byte descriptors: See section 3.10.2 of VESA E-EDID Standard [10]
       
   598 
       
   599             TBool first = ETrue;
       
   600             if( iParsedInfo->iDescriptorBlocks == 0 )
       
   601                 {
       
   602                 iParsedInfo->iDescriptorBlocks
       
   603                     = new ( ELeave ) TCEA861TEdidDescriptorBlockList();
       
   604                 }
       
   605 
       
   606             // read the descriptors here
       
   607             TEdidDescriptorBlock tmp = GetDescriptorBlock( aData, index );
       
   608             if( first )
       
   609                 {
       
   610                 first = EFalse;
       
   611                 iParsedInfo->iDescriptorBlocks->iData = tmp;
       
   612                 continue;
       
   613                 }
       
   614             TCEA861TEdidDescriptorBlockList* last =
       
   615                 iParsedInfo->iDescriptorBlocks;
       
   616             while( last->iNext != 0 ) // go to last block
       
   617                 {
       
   618                 last = last->iNext;
       
   619                 }
       
   620             last->iNext = new ( ELeave ) TCEA861TEdidDescriptorBlockList();
       
   621             last = last->iNext;
       
   622             last->iData = tmp;
       
   623             }
       
   624         else
       
   625             {
       
   626             // this is only padding, no need to do anything
       
   627             }
       
   628 
       
   629         // after the descriptors there is padding to fill Extension block to 128 bytes.
       
   630         // beginning of padding               | End of padding  | Checksum
       
   631         // d+(18*n) ..........................| 126             | 127
       
   632         if( index == 0x7F )
       
   633             {
       
   634             iParsedInfo->iChecksum = aData[index];
       
   635             // Finished reading
       
   636             return KErrNone;
       
   637             }
       
   638         }
       
   639 
       
   640     return KErrNone;
       
   641     }
       
   642 
       
   643 // ---------------------------------------------------------------------------
       
   644 // CCea861EdidParser::ReadCeaVersion2L
       
   645 // ---------------------------------------------------------------------------
       
   646 //
       
   647 TInt CCea861EdidParser::ReadCeaVersion2L( const TExtDataBlock& aData,
       
   648     TInt aIndex )
       
   649     {
       
   650     FUNC_LOG;
       
   651 
       
   652     ReadCeaVersion2and3Common( aData, aIndex );
       
   653 
       
   654     return ReadCeaVersion1L( aData, aIndex );
       
   655     }
       
   656 
       
   657 // ---------------------------------------------------------------------------
       
   658 // CCea861EdidParser::ReadCeaVersion3L
       
   659 // ---------------------------------------------------------------------------
       
   660 //
       
   661 TInt CCea861EdidParser::ReadCeaVersion3L( const TExtDataBlock& aData,
       
   662     TInt aIndex )
       
   663     {
       
   664     FUNC_LOG;
       
   665 
       
   666     // first read the common information in versions 2 and 3
       
   667     ReadCeaVersion2and3Common( aData, aIndex );
       
   668 
       
   669     if( aIndex == 4 ) // start of the Data block collection (see table 39)
       
   670         {
       
   671         while( aIndex < iParsedInfo->iOffset ) // it is possible to have more than one DataBlockCollection
       
   672             {
       
   673             TInt ret = ReadCeaDataBlockCollectionL( aData, aIndex );
       
   674             if( ret != KErrNone )
       
   675                 {
       
   676                 return ret;
       
   677                 }
       
   678             if( aIndex > KEdidParserSizeOfEdidBlock )
       
   679                 {
       
   680                 return KErrOverflow;
       
   681                 }
       
   682             }
       
   683         // after reading the CEADataBlockCollections, we can read all the descriptors
       
   684         }
       
   685     else
       
   686         {
       
   687         // error
       
   688         if( aIndex < 4 )
       
   689             {
       
   690             return KErrNotFound;
       
   691             }
       
   692         else
       
   693             {
       
   694             return KErrOverflow;
       
   695             }
       
   696         }
       
   697     return ReadCeaVersion1L( aData, aIndex );
       
   698     }
       
   699 
       
   700 // ---------------------------------------------------------------------------
       
   701 // CCea861EdidParser::ReadCeaVersion2L
       
   702 // ---------------------------------------------------------------------------
       
   703 //
       
   704 TInt CCea861EdidParser::ReadCeaVersion2and3Common( const TExtDataBlock& aData,
       
   705     TInt& aIndex )
       
   706     {
       
   707     FUNC_LOG;
       
   708 
       
   709     for( TInt i = aIndex; i < KEdidParserSizeOfEdidBlock; i++ )
       
   710         {
       
   711         if( aIndex == 2 ) // offset
       
   712             {
       
   713             iParsedInfo->iOffset = aData[i];
       
   714             // don't skip over the offset
       
   715             }
       
   716         if( aIndex == 3 )
       
   717             {
       
   718             // bit 7 = underscan: 1 if sink underscans IT video formats by default
       
   719             // bit 6 = audio    : 1 if sink supports basic audio
       
   720             // bit 5 = YCbCr 4:4:4 = 1 if sink supports YCbCr 4:4:4 in addition to RGB
       
   721             // bit 4 = YCbCr 4:2:2 = 1 if sink supports YCbCr 4:2:2 in addition to RGB
       
   722             // lower 4 bits = total number of native DTDs (detailed timing descriptors) (see section 2.2 for definition of "native format")
       
   723             iParsedInfo->iUnderscan = ( KBit7 & aData[i] ? ETrue : EFalse );
       
   724             iParsedInfo->iAudio = ( KBit6 & aData[i] ? ETrue : EFalse );
       
   725             iParsedInfo->iYCbCr444 = ( KBit5 & aData[i] ? ETrue : EFalse );
       
   726             iParsedInfo->iYCbCr422 = ( KBit4 & aData[i] ? ETrue : EFalse );
       
   727             iParsedInfo->iTotalNumberOfNativeFormats = 0x0F & aData[i];
       
   728             aIndex++;
       
   729             return KErrNone; // end of common data
       
   730             }
       
   731         aIndex++;
       
   732         }
       
   733     return KErrNone;
       
   734     }
       
   735 
       
   736 // ----------------------------------------------------------------------------
       
   737 // CCea861EdidParser::GetDescriptorBlock
       
   738 //
       
   739 // ----------------------------------------------------------------------------
       
   740 //
       
   741 TEdidDescriptorBlock CCea861EdidParser::GetDescriptorBlock( const TExtDataBlock& aData,
       
   742     TInt& aIndex ) const
       
   743     {
       
   744     FUNC_LOG;
       
   745 
       
   746     TEdidDescriptorBlock descBlock;
       
   747 
       
   748     descBlock.iPixelClock = GetPixelClock( aData, aIndex );
       
   749 
       
   750     descBlock.iHorizontalAddressableVideoPixels
       
   751         = GetHorizontalAddressableVideoPixels( aData, aIndex );
       
   752 
       
   753     descBlock.iHorizontalBlanking = GetHorizontalBlanking( aData, aIndex );
       
   754 
       
   755     descBlock.iVerticalAddressableVideoPixels
       
   756         = GetVerticalAddressableVideoPixels( aData, aIndex );
       
   757 
       
   758     descBlock.iVerticalBlanking = GetVerticalBlanking( aData, aIndex );
       
   759 
       
   760     descBlock.iHorizontalFrontPorch = GetHorizontalFrontPorch( aData, aIndex );
       
   761 
       
   762     descBlock.iHorizontalSyncPulse
       
   763         = GetHorizontalSyncPulseWidth( aData, aIndex );
       
   764 
       
   765     descBlock.iVerticalFrontPorch = GetVerticalFrontPorch( aData, aIndex );
       
   766 
       
   767     descBlock.iVerticalSyncPulse = GetVerticalSyncPulseWidth( aData, aIndex );
       
   768 
       
   769     descBlock.iHorizontalAddressableImageSize
       
   770         = GetHorizontalAddressableImageSizeInMm( aData, aIndex );
       
   771 
       
   772     descBlock.iVerticalAddressableImageSize
       
   773         = GetVerticalAddressableImageSizeInMm( aData, aIndex );
       
   774 
       
   775     descBlock.iHorizontalBorder = GetHorizontalBorderSize( aData, aIndex );
       
   776 
       
   777     descBlock.iVerticalBorder = GetVerticalBorderSize( aData, aIndex );
       
   778 
       
   779     descBlock.iInterlacedVideo = GetVideoIsInterlaced( aData, aIndex );
       
   780 
       
   781     descBlock.iStereoSupport = GetStereoViewingSupport( aData, aIndex );
       
   782 
       
   783     descBlock.iSyncs = GetSyncSignalDefinitions( aData, aIndex );
       
   784 
       
   785     return descBlock;
       
   786     }
       
   787 
       
   788 // ----------------------------------------------------------------------------
       
   789 // CCea861EdidParser::GetPixelClock
       
   790 //
       
   791 // ----------------------------------------------------------------------------
       
   792 //
       
   793 TUint16 CCea861EdidParser::GetPixelClock( const TExtDataBlock& aData,
       
   794     TInt& aIndex ) const
       
   795     {
       
   796     FUNC_LOG;
       
   797 
       
   798     // Stored Value = Pixel clock ÷ 10,000
       
   799     // LSB stored in byte 0 and MSB stored in byte 1
       
   800     // 0, 1 2 Range: 10 kHz to 655.35 MHz in 10 kHz steps
       
   801     // (00 00)h Reserved: Do not use for Detailed Timing Descriptor
       
   802     TUint16 word1 = aData[aIndex];
       
   803     TUint16 word2 = aData[aIndex + 1];
       
   804 
       
   805     TUint16 pixelClock = word2; // xxxx xxxx 1010 1010
       
   806     pixelClock = pixelClock << 8; // 1010 1010 xxxx xxxx shifted to left (MSB)
       
   807     pixelClock += word1; // 1010 1010 0101 0101 add the LSB
       
   808 
       
   809     aIndex += 2;
       
   810 
       
   811     return pixelClock;
       
   812     }
       
   813 
       
   814 // ----------------------------------------------------------------------------
       
   815 // CCea861EdidParser::GetHorizontalAddressableVideoPixels
       
   816 //
       
   817 // ----------------------------------------------------------------------------
       
   818 //
       
   819 TUint16 CCea861EdidParser::GetHorizontalAddressableVideoPixels( const TExtDataBlock& aData,
       
   820     TInt& aIndex ) const
       
   821     {
       
   822     FUNC_LOG;
       
   823 
       
   824     // aIndex at byte #2
       
   825     TUint16 word1 = aData[aIndex];
       
   826     TUint16 word2 = aData[aIndex + 2];
       
   827 
       
   828     // 12bits long, defined in 8 bits of byte 2 and upper nibble of byte 4 (4bits), range 0-4095
       
   829     TUint16 horAddrVideo = 0;
       
   830 
       
   831     // nullify the 4 lsb
       
   832     // ---- ---- xxxx yyyy >> 4  = ---- ---- ---- xxxx
       
   833     horAddrVideo = word1 >> 4;
       
   834     // return back to original position (4)+4
       
   835     // ---- ---- ---- xxxx << 4  = ---- xxxx 0000 0000
       
   836     horAddrVideo = horAddrVideo << ( 4 + 4 );
       
   837     // ---- xxxx zzzz zzzz = correct values for the 12-bit-long var
       
   838     horAddrVideo += word2;
       
   839 
       
   840     aIndex++; // to byte #3
       
   841 
       
   842     return horAddrVideo;
       
   843     }
       
   844 
       
   845 // ----------------------------------------------------------------------------
       
   846 // CCea861EdidParser::GetHorizontalBlanking
       
   847 //
       
   848 // ----------------------------------------------------------------------------
       
   849 //
       
   850 TUint16 CCea861EdidParser::GetHorizontalBlanking( const TExtDataBlock& aData,
       
   851     TInt& aIndex ) const
       
   852     {
       
   853     FUNC_LOG;
       
   854 
       
   855     // aIndex at byte #3
       
   856     TUint16 word1 = aData[aIndex];
       
   857     TUint16 word2 = aData[aIndex + 1];
       
   858 
       
   859     TUint16 horBlanking = 0;
       
   860 
       
   861     // nullify the 4 msb
       
   862     // ---- ---- xxxx yyyy << 12 = yyyy ---- ---- ----
       
   863     horBlanking = word1 << 12;
       
   864     // nullify the 4 msb
       
   865     // yyyy ---- ---- ---- >> 4  = ---- yyyy ---- ----
       
   866     horBlanking = horBlanking >> 4;
       
   867     // ---- yyyy zzzz zzzz = correct values for the 12-bit-long var
       
   868     horBlanking += word2;
       
   869 
       
   870     aIndex += 2; // to byte #5
       
   871 
       
   872     return horBlanking;
       
   873     }
       
   874 
       
   875 // ----------------------------------------------------------------------------
       
   876 // CCea861EdidParser::GetVerticalAddressableVideoPixels
       
   877 // Vertical Addressable Video in lines
       
   878 //
       
   879 // ----------------------------------------------------------------------------
       
   880 //
       
   881 TUint16 CCea861EdidParser::GetVerticalAddressableVideoPixels( const TExtDataBlock& aData,
       
   882     TInt& aIndex ) const
       
   883     {
       
   884     FUNC_LOG;
       
   885 
       
   886     // aIndex at byte #5
       
   887     TUint16 word1 = aData[aIndex + 2];
       
   888     TUint16 word2 = aData[aIndex];
       
   889 
       
   890     //Upper nibble of byte 7 and the 8 bits of byte 5) - Range is 0 lines to 4095 lines
       
   891     TUint16 vertAddrVideo = 0;
       
   892     vertAddrVideo = word1 >> 4;
       
   893     vertAddrVideo = vertAddrVideo << ( 4 + 4 );
       
   894     vertAddrVideo += word2; // like before with HorAddrVideo
       
   895 
       
   896     aIndex++; // to byte #6
       
   897     return vertAddrVideo;
       
   898     }
       
   899 
       
   900 // ----------------------------------------------------------------------------
       
   901 // CCea861EdidParser::GetVerticalBlanking
       
   902 //
       
   903 // ----------------------------------------------------------------------------
       
   904 //
       
   905 TUint16 CCea861EdidParser::GetVerticalBlanking( const TExtDataBlock& aData,
       
   906     TInt& aIndex ) const
       
   907     {
       
   908     FUNC_LOG;
       
   909 
       
   910     // aIndex at byte #6
       
   911     TUint16 word1 = aData[aIndex + 1];
       
   912     TUint16 word2 = aData[aIndex];
       
   913 
       
   914     // 12bits long, defined in 8 bits of byte 2 and upper nibble of byte 4 (4bits), range 0-4095
       
   915     TUint16 vertBlanking = 0;
       
   916 
       
   917     // nullify the 4 msb
       
   918     // ---- ---- xxxx yyyy << 12 = yyyy ---- ---- ----
       
   919     vertBlanking = word1 << 12;
       
   920     // nullify the 4 msb
       
   921     // yyyy ---- ---- ---- >> 4  = 0000 yyyy ---- ----
       
   922     vertBlanking = vertBlanking >> 4;
       
   923     // ---- yyyy zzzz zzzz = correct values for the 12-bit-long var
       
   924     vertBlanking += word2;
       
   925 
       
   926     aIndex += 2; // to byte #8
       
   927     return vertBlanking;
       
   928     }
       
   929 
       
   930 // ----------------------------------------------------------------------------
       
   931 // CCea861EdidParser::GetHorizontalFrontPorch
       
   932 //
       
   933 // ----------------------------------------------------------------------------
       
   934 //
       
   935 TUint16 CCea861EdidParser::GetHorizontalFrontPorch( const TExtDataBlock& aData,
       
   936     TInt& aIndex ) const
       
   937     {
       
   938     FUNC_LOG;
       
   939 
       
   940     // aIndex at byte #8
       
   941 
       
   942     TUint16 word1 = aData[aIndex];
       
   943     TUint16 word2 = aData[aIndex + 3]; // 2 bits from #11
       
   944 
       
   945     // Horizontal Front Porch in Pixels (from blanking start to start of sync) is represented by a 10 bit
       
   946     // number (Bits 7 & 6 of byte 11 and the 8 bits of byte 8) - Range is 0 pixels to 1023 pixels.
       
   947 
       
   948     TUint16 horFrontPorch = 0;
       
   949 
       
   950     TUint8 bit67 = word1;
       
   951     bit67 = ( bit67 & KBit7 ) | ( bit67 & KBit6 ); // bits 6 and 7 remain
       
   952 
       
   953     horFrontPorch = bit67 << 2;
       
   954     horFrontPorch += word2;
       
   955 
       
   956     aIndex++; // to byte #9
       
   957     return horFrontPorch;
       
   958     }
       
   959 
       
   960 // ----------------------------------------------------------------------------
       
   961 // CCea861EdidParser::GetHorizontalSyncPulseWidth
       
   962 //
       
   963 // ----------------------------------------------------------------------------
       
   964 //
       
   965 TUint16 CCea861EdidParser::GetHorizontalSyncPulseWidth( const TExtDataBlock& aData,
       
   966     TInt& aIndex ) const
       
   967     {
       
   968     FUNC_LOG;
       
   969 
       
   970     // aIndex at byte #9
       
   971     TUint16 word1 = aData[aIndex];
       
   972     TUint16 word2 = aData[aIndex + 2]; // 2 bits from #11
       
   973 
       
   974     //Horizontal Sync Pulse Width in Pixels (from the end of the front porch to the start of the back
       
   975     //porch) is represented by a 10 bit number (Bits 5 & 4 of byte 11 and the 8 bits of byte 9) - Range
       
   976     //is 0 pixels to 1023 pixels.
       
   977 
       
   978     TUint16 horSyncPulseWidth = word1;
       
   979     horSyncPulseWidth = ( horSyncPulseWidth & KBit5 ) | ( horSyncPulseWidth
       
   980         & KBit4 ); // only bits 5 and 4 remain
       
   981     horSyncPulseWidth = horSyncPulseWidth << 4;
       
   982     horSyncPulseWidth += word2;
       
   983 
       
   984     aIndex++; // aIndex at byte #10
       
   985 
       
   986     return horSyncPulseWidth;
       
   987     }
       
   988 
       
   989 // ----------------------------------------------------------------------------
       
   990 // CCea861EdidParser::GetVerticalFrontPorch
       
   991 //
       
   992 // ----------------------------------------------------------------------------
       
   993 //
       
   994 TUint16 CCea861EdidParser::GetVerticalFrontPorch( const TExtDataBlock& aData,
       
   995     TInt& aIndex ) const
       
   996     {
       
   997     FUNC_LOG;
       
   998 
       
   999     // Vertical Front Porch in Lines (from blanking start to start of sync) is represented by a 6 bit
       
  1000     // number (Bits 3 & 2 of byte 11 and the upper nibble of byte 10) - Range is 0 lines to 63 lines.
       
  1001 
       
  1002     // aIndex at byte #10
       
  1003     TUint16 word1 = aData[aIndex + 1];
       
  1004     TUint16 word2 = aData[aIndex]; // 2 bits from #11
       
  1005 
       
  1006     TUint16 vertFrontPorch = 0;
       
  1007 
       
  1008     TUint8 bit23 = word1;
       
  1009     // bits 2 and 3 remain  0000 xx00
       
  1010     bit23 = ( bit23 & KBit3 ) | ( bit23 & KBit2 );
       
  1011 
       
  1012     // 00xx 0000
       
  1013     vertFrontPorch = bit23 << 2;
       
  1014     // 00xx yyyy
       
  1015     vertFrontPorch += ( word2 >> 4 );
       
  1016 
       
  1017     //Index remains at byte #10
       
  1018 
       
  1019     return vertFrontPorch;
       
  1020     }
       
  1021 
       
  1022 // ----------------------------------------------------------------------------
       
  1023 // CCea861EdidParser::GetVerticalSyncPulseWidth
       
  1024 //
       
  1025 // ----------------------------------------------------------------------------
       
  1026 //
       
  1027 TUint8 CCea861EdidParser::GetVerticalSyncPulseWidth( const TExtDataBlock& aData,
       
  1028     TInt& aIndex ) const
       
  1029     {
       
  1030     FUNC_LOG;
       
  1031 
       
  1032     // Vertical Sync Pulse Width in Lines (from the end of the front porch to the start of the back
       
  1033     // porch) is represented by a 6 bit number (Bits 1 & 0 of byte 11 and the lower nibble of byte 10 -
       
  1034     // Range is 0 lines to 63 lines.
       
  1035 
       
  1036     // aIndex at byte #10
       
  1037     TUint16 word1 = aData[aIndex];
       
  1038     TUint16 word2 = aData[aIndex + 1]; // 2 bits from #11
       
  1039 
       
  1040     // Vertical Sync Pulse Width in Lines (from the end of the front porch to the start of the back
       
  1041     // porch) is represented by a 6 bit number (Bits 1 & 0 of byte 11 and the lower nibble of byte 10 -
       
  1042     // Range is 0 lines to 63 lines.
       
  1043     TUint8 vertSyncPulse = 0;
       
  1044 
       
  1045     // bits 1 and 0 remain   0000 00xx
       
  1046     word2 = ( word2 & KBit1 ) | ( word2 & KBit0 );
       
  1047 
       
  1048     // 00xx 0000
       
  1049     vertSyncPulse = word2 << 4;
       
  1050     // only the lower nibble, %16 removes the upper nibble
       
  1051     word1 = word1 % 16;
       
  1052     // 00xx yyyy
       
  1053     vertSyncPulse += word1;
       
  1054 
       
  1055     aIndex += 2; // to byte #12
       
  1056 
       
  1057     return vertSyncPulse;
       
  1058     }
       
  1059 
       
  1060 // ----------------------------------------------------------------------------
       
  1061 // CCea861EdidParser::GetHorizontalAddressableImageSizeInMm
       
  1062 // Horizontal Addressable Video Image Size in mm
       
  1063 //
       
  1064 // ----------------------------------------------------------------------------
       
  1065 //
       
  1066 TUint16 CCea861EdidParser::GetHorizontalAddressableImageSizeInMm( const TExtDataBlock& aData,
       
  1067     TInt& aIndex ) const
       
  1068     {
       
  1069     FUNC_LOG;
       
  1070 
       
  1071     // aIndex at byte #12
       
  1072     TUint16 word1 = aData[aIndex + 2];
       
  1073     TUint16 word2 = aData[aIndex];
       
  1074 
       
  1075     //Horizontal Addressable Video Image Size in mm is represented by a 12 bit number (Upper
       
  1076     //nibble of byte 14 and the 8 bits of byte 12) - Range is 0 mm to 4095 mm.
       
  1077 
       
  1078     // first nullify 4 lsb
       
  1079     TUint16 hais = word1 >> 4;
       
  1080     // and then move back the first 4 and then again 4
       
  1081     hais = hais << ( 4 + 4 );
       
  1082     hais += word2;
       
  1083 
       
  1084     aIndex++; // to byte #13
       
  1085 
       
  1086     return hais;
       
  1087     }
       
  1088 
       
  1089 // ----------------------------------------------------------------------------
       
  1090 // CCea861EdidParser::GetVerticalAddressableImageSizeInMm
       
  1091 //
       
  1092 // ----------------------------------------------------------------------------
       
  1093 //
       
  1094 TUint16 CCea861EdidParser::GetVerticalAddressableImageSizeInMm( const TExtDataBlock& aData,
       
  1095     TInt& aIndex ) const
       
  1096     {
       
  1097     FUNC_LOG;
       
  1098 
       
  1099     // aIndex at byte #13
       
  1100     TUint16 word1 = aData[aIndex + 1];
       
  1101     TUint16 word2 = aData[aIndex];
       
  1102 
       
  1103     //Vertical Addressable Video Image Size in mm is represented by a 12 bit number (Lower nibble
       
  1104     //of byte 14 and the 8 bits of byte 13) - Range is 0 mm to 4095 mm.
       
  1105 
       
  1106     TUint16 vais = word1;
       
  1107     // first nullify 4 msb and then move back 1 nibble
       
  1108     vais = vais << 12;
       
  1109     vais = vais >> 4;
       
  1110     vais += word2;
       
  1111 
       
  1112     aIndex += 2; // to byte #15
       
  1113 
       
  1114     return vais;
       
  1115     }
       
  1116 
       
  1117 // ----------------------------------------------------------------------------
       
  1118 // CCea861EdidParser::GetHorizontalBorderSize
       
  1119 //
       
  1120 // ----------------------------------------------------------------------------
       
  1121 //
       
  1122 TUint8 CCea861EdidParser::GetHorizontalBorderSize( const TExtDataBlock& aData,
       
  1123     TInt& aIndex ) const
       
  1124     {
       
  1125     FUNC_LOG;
       
  1126 
       
  1127     // aIndex at byte #15
       
  1128     TUint16 word1 = aData[aIndex];
       
  1129 
       
  1130     //Right Horizontal Border or Left Horizontal Border in Pixels is represented by an 8 bit number
       
  1131     //(the 8 bits of byte 15) - Range is 0 pixels to 255 pixels.
       
  1132 
       
  1133     // the same value is used for (left and right) / (top and bottom)
       
  1134     aIndex++; // to byte #16
       
  1135     return word1;
       
  1136     }
       
  1137 
       
  1138 // ----------------------------------------------------------------------------
       
  1139 // CCea861EdidParser::GetVerticalBorderSize
       
  1140 // Top Vertical Border or Bottom Vertical Border in Lines
       
  1141 //
       
  1142 // ----------------------------------------------------------------------------
       
  1143 //
       
  1144 TUint8 CCea861EdidParser::GetVerticalBorderSize( const TExtDataBlock& aData,
       
  1145     TInt& aIndex ) const
       
  1146     {
       
  1147     FUNC_LOG;
       
  1148 
       
  1149     // aIndex at byte #16
       
  1150     TUint16 word1 = aData[aIndex];
       
  1151 
       
  1152     //Top Vertical Border or Bottom Vertical Border in Lines is represented by an 8 bit number (the
       
  1153     //8 bits of byte 16) - Range is 0 lines to 255 lines.
       
  1154 
       
  1155     aIndex++; // to byte #17
       
  1156     return word1;
       
  1157     }
       
  1158 
       
  1159 // ----------------------------------------------------------------------------
       
  1160 // CCea861EdidParser::GetVideoIsInterlaced
       
  1161 //
       
  1162 // ----------------------------------------------------------------------------
       
  1163 //
       
  1164 TBool CCea861EdidParser::GetVideoIsInterlaced( const TExtDataBlock& aData,
       
  1165     TInt& aIndex ) const
       
  1166     {
       
  1167     FUNC_LOG;
       
  1168 
       
  1169     // aIndex at byte #17
       
  1170     TUint16 word1 = aData[aIndex];
       
  1171 
       
  1172     // byte 17
       
  1173     //Bytes Bit Definitions Detailed Timing Definitions
       
  1174     //7 6 5 4 3 2 1 0 Signal Interface Type:
       
  1175     //0 _ _ _ _ _ _ _ Non-Interlaced (1 frame = 1 field)
       
  1176     //1 _ _ _ _ _ _ _ Interlaced (1 frame = 2 fields)
       
  1177 
       
  1178     // Index remains at byte #17
       
  1179 
       
  1180     return KBit7 & word1;
       
  1181     }
       
  1182 
       
  1183 // ----------------------------------------------------------------------------
       
  1184 // CCea861EdidParser::GetStereoViewingSupport
       
  1185 //
       
  1186 // ----------------------------------------------------------------------------
       
  1187 //
       
  1188 TEdidStereoViewingSupport CCea861EdidParser::GetStereoViewingSupport( const TExtDataBlock& aData,
       
  1189     TInt& aIndex ) const
       
  1190     {
       
  1191     FUNC_LOG;
       
  1192 
       
  1193     // aIndex at byte #17
       
  1194     TUint16 word1 = aData[aIndex];
       
  1195 
       
  1196     // See TEdidStereoViewingSupport enum declaration
       
  1197 
       
  1198     // byte 17
       
  1199     //Bytes Bit Definitions Detailed Timing Definitions
       
  1200     //_ 6 5 _ _ _ _ 0 Stereo Viewing Support:
       
  1201     //  0 0 _ _ _ _ x Normal Display – No Stereo. The value of bit 0 is "don't care"
       
  1202     //  0 1 _ _ _ _ 0 Field sequential stereo, right image when stereo sync signal = 1
       
  1203     //  1 0 _ _ _ _ 0 Field sequential stereo, left image when stereo sync signal = 1
       
  1204     //  0 1 _ _ _ _ 1 2-way interleaved stereo, right image on even lines
       
  1205     //  1 0 _ _ _ _ 1 2-way interleaved stereo, left image on even lines
       
  1206     //  1 1 _ _ _ _ 0 4-way interleaved stereo
       
  1207     //  1 1 _ _ _ _ 1 Side-by-Side interleaved stereo
       
  1208     TUint8 bit17 = word1;
       
  1209 
       
  1210     // Index remains at byte #17
       
  1211 
       
  1212     if( !( ( KBit6 & bit17 ) | ( KBit5 & bit17 ) ) ) //  0 0 _ _ _ _ x Normal Display – No Stereo.
       
  1213         { //                The value of bit 0 is "don't care"
       
  1214         return ENormalDisplay;
       
  1215         }
       
  1216     else
       
  1217         {
       
  1218         if( !( KBit6 & bit17 ) && ( KBit5 & bit17 ) && !( KBit0 & bit17 ) ) //  0 1 _ _ _ _ 0 Field sequential stereo,
       
  1219             { //                right image when stereo sync signal=1
       
  1220             return EFieldSequentialStereoRightWhenStereoSyncSignal1;
       
  1221             }
       
  1222         else
       
  1223             {
       
  1224             if( ( KBit6 & bit17 ) && !( KBit5 & bit17 ) && !( KBit0 & bit17 ) ) //  1 0 _ _ _ _ 0 Field sequential stereo,
       
  1225                 { //                left image when stereo sync signal=1
       
  1226                 return EFieldSequentialStereoLeftWhenStereoSyncSignal1;
       
  1227                 }
       
  1228             else
       
  1229                 {
       
  1230                 if( !( KBit6 & bit17 ) && ( KBit5 & bit17 ) && ( KBit0 & bit17 ) ) //  0 1 _ _ _ _ 1 2-way interleaved stereo,
       
  1231                     { //                right image on even lines
       
  1232                     return ETwoWayInterleavedStereoRightImageOnEvenLines;
       
  1233                     }
       
  1234                 else
       
  1235                     {
       
  1236                     if( ( KBit6 & bit17 ) && !( KBit5 & bit17 ) && ( KBit0
       
  1237                         & bit17 ) )//  1 0 _ _ _ _ 1 2-way interleaved stereo,
       
  1238                         { //                left image on even lines
       
  1239                         return ETwoWayInterleavedStereoLeftImageOnEvenLines;
       
  1240                         }
       
  1241                     else
       
  1242                         {
       
  1243                         if( ( KBit6 & bit17 ) && ( KBit5 & bit17 ) && !( KBit0
       
  1244                             & bit17 ) ) //  1 1 _ _ _ _ 0 4-way interleaved stereo
       
  1245                             {
       
  1246                             return EFourWayInterleaverStereo;
       
  1247                             }
       
  1248                         else
       
  1249                             {
       
  1250                             if( ( KBit6 & bit17 ) && ( KBit5 & bit17 )
       
  1251                                 && ( KBit0 & bit17 ) ) //  1 1 _ _ _ _ 1 Side-by-Side interleaved stereo
       
  1252                                 {
       
  1253                                 return ESideBySideInterleavedStere;
       
  1254                                 }
       
  1255                             else
       
  1256                                 {
       
  1257                                 return EUnknownStereoViewingSupport;
       
  1258                                 }
       
  1259                             }
       
  1260                         }
       
  1261                     }
       
  1262                 }
       
  1263             }
       
  1264         }
       
  1265     }
       
  1266 
       
  1267 // ----------------------------------------------------------------------------
       
  1268 // CCea861EdidParser::GetAnalogSyncSignalDefinitions
       
  1269 //
       
  1270 // ----------------------------------------------------------------------------
       
  1271 //
       
  1272 TEdidSyncSignalDefinitions CCea861EdidParser::GetSyncSignalDefinitions( const TExtDataBlock& aData,
       
  1273     TInt& aIndex ) const
       
  1274     {
       
  1275     FUNC_LOG;
       
  1276 
       
  1277     // aIndex at byte #18
       
  1278     TUint8 byte17 = aData[aIndex];
       
  1279 
       
  1280     // byte 17
       
  1281     // 4 3 2 1 _ Analog Sync Signal Definitions:
       
  1282     //------------------------------------------
       
  1283     // 0 0 _ _ _ Analog Composite Sync:
       
  1284     // 0 1 _ _ _ Bipolar Analog Composite Sync:
       
  1285 
       
  1286     aIndex++; // advance to byte #18 finally -> this descriptor block is now finished
       
  1287 
       
  1288     if( !( KBit4 & byte17 ) ) // if bit4 == 0 then this is analog display
       
  1289         {
       
  1290         return GetAnalogSyncSignalDefinitions( byte17 );
       
  1291         }
       
  1292 
       
  1293     return GetDigitalSyncSignalDefinitions( byte17 );
       
  1294     }
       
  1295 
       
  1296 // ----------------------------------------------------------------------------
       
  1297 // CCea861EdidParser::GetAnalogSyncSignalDefinitions
       
  1298 //
       
  1299 // ----------------------------------------------------------------------------
       
  1300 //
       
  1301 TEdidSyncSignalDefinitions CCea861EdidParser::GetAnalogSyncSignalDefinitions( const TUint8 aByte17 )
       
  1302     {
       
  1303     FUNC_LOG;
       
  1304 
       
  1305     // byte 17
       
  1306     // 4 3 2 1 _ Analog Sync Signal Definitions:
       
  1307     //------------------------------------------
       
  1308     // 0 0 _ _ _ Analog Composite Sync:
       
  1309     // 0 1 _ _ _ Bipolar Analog Composite Sync:
       
  1310     // 0 _ 0 _ _ ---------- Without Serrations;
       
  1311     // 0 _ 1 _ _ ---------- With Serrations (H-sync during V-sync);
       
  1312     // 0 _ _ 0 _ -------------------- Sync On Green Signal only
       
  1313     // 0 _ _ 1 _ -------------------- Sync On all three (RGB) video signals
       
  1314 
       
  1315     TBool ACS = !( KBit3 & aByte17 ); // if true -> bipolar analog composite sync
       
  1316     TBool serrations = KBit2 & aByte17;
       
  1317     TBool syncOnGreen = !( KBit1 & aByte17 );
       
  1318 
       
  1319     if( ACS )
       
  1320         {
       
  1321         if( !serrations )
       
  1322             {
       
  1323             if( syncOnGreen )
       
  1324                 {
       
  1325                 return EAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
       
  1326                 }
       
  1327             else
       
  1328                 {
       
  1329                 return EAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
       
  1330                 }
       
  1331             }
       
  1332         else
       
  1333             {
       
  1334             if( syncOnGreen )
       
  1335                 {
       
  1336                 return EAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
       
  1337                 }
       
  1338             else
       
  1339                 {
       
  1340                 return EAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
       
  1341                 }
       
  1342             }
       
  1343         }
       
  1344     else
       
  1345         {
       
  1346         if( !serrations )
       
  1347             {
       
  1348             if( syncOnGreen )
       
  1349                 {
       
  1350                 return EAnalogBipolarAnalogCompositeSyncWithoutSerrationsSyncSyncOnGreenSignalOnly;
       
  1351                 }
       
  1352             else
       
  1353                 {
       
  1354                 return EAnalogBipolarAnalogCompositeSyncWithoutSerrationsSyncOnAllThreeVideoSignals;
       
  1355                 }
       
  1356             }
       
  1357         else
       
  1358             {
       
  1359             if( syncOnGreen )
       
  1360                 {
       
  1361                 return EAnalogBipolarAnalogCompositeSyncWithSerrationsSyncSyncOnGreenSignalOnly;
       
  1362                 }
       
  1363             else
       
  1364                 {
       
  1365                 return EAnalogBipolarAnalogCompositeSyncWithSerrationsSyncOnAllThreeVideoSignals;
       
  1366                 }
       
  1367             }
       
  1368         }
       
  1369     // unreachable
       
  1370     }
       
  1371 
       
  1372 // ----------------------------------------------------------------------------
       
  1373 // CCea861EdidParser::GetDigitalSyncSignalDefinitions
       
  1374 //
       
  1375 // ----------------------------------------------------------------------------
       
  1376 //
       
  1377 TEdidSyncSignalDefinitions CCea861EdidParser::GetDigitalSyncSignalDefinitions( const TUint8 aByte17 )
       
  1378     {
       
  1379     FUNC_LOG;
       
  1380 
       
  1381     //        4 3 2 1 0 bit
       
  1382     //        --------------
       
  1383     //        1 0 _ _ _ Digital Composite Sync:
       
  1384     //        1 0 0 _ _ ---------- Without Serrations;
       
  1385     //        1 0 1 _ _ ---------- With Serrations (H-sync during V-sync);
       
  1386     //        1 1 _ _ _ Digital Separate Sync:
       
  1387     //        1 1 0 _ _ ---------- Vertical Sync is Negative;
       
  1388     //        1 1 1 _ _ ---------- Vertical Sync is Positive;
       
  1389     //        1 _ _ 0 _ -------------------- Horizontal Sync is Negative (outside of V-sync)
       
  1390     //        1 _ _ 1 _ -------------------- Horizontal Sync is Positive (outside of V-sync)
       
  1391 
       
  1392     TBool digComp = !( KBit3 & aByte17 ); // ETrue == digital separate sync
       
  1393     TBool bit2 = KBit2 & aByte17;
       
  1394 
       
  1395     if( digComp ) // digital composite sync
       
  1396         {
       
  1397         if( !bit2 ) // without serrations
       
  1398             {
       
  1399             return EDigitalCompositeSyncWithoutSerrations;
       
  1400             }
       
  1401         else // with serrations
       
  1402             {
       
  1403             return EDigitalCompositeSyncWithSerrations;
       
  1404             }
       
  1405         } // endif  digital composite sync
       
  1406     else //        digital separate sync
       
  1407         {
       
  1408         TBool bit1 = KBit1 & aByte17;
       
  1409 
       
  1410         if( !bit2 ) // vertical = neg
       
  1411             {
       
  1412             if( !bit1 )
       
  1413                 { // vertical = neg, horizontal = neg
       
  1414                 return EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsNegative;
       
  1415                 }
       
  1416             else
       
  1417                 { // vertical = neg, horizontal = pos
       
  1418                 return EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsPositive;
       
  1419                 }
       
  1420             }
       
  1421         else // vertical = pos
       
  1422             {
       
  1423             if( !bit1 )
       
  1424                 { // vertical = pos, horizontal = neg
       
  1425                 return EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsNegative;
       
  1426                 }
       
  1427             else
       
  1428                 { // vertical = pos, horizontal = pos
       
  1429                 return EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsPositive;
       
  1430                 }
       
  1431             }
       
  1432         }
       
  1433     // unreachable
       
  1434     }
       
  1435 
       
  1436 // ----------------------------------------------------------------------------
       
  1437 // CCea861EdidParser::ReadCeaDataBlockCollectionL
       
  1438 //
       
  1439 // ----------------------------------------------------------------------------
       
  1440 //
       
  1441 TInt CCea861EdidParser::ReadCeaDataBlockCollectionL( const TExtDataBlock& aData,
       
  1442     TInt& aIndex )
       
  1443     {
       
  1444     FUNC_LOG;
       
  1445 
       
  1446     // bits 5-7         | bits 0-4
       
  1447     // Tag Code         | Length = total number of video bytes following this byte (L1)
       
  1448     TInt tag = 0; // video tag code
       
  1449     TInt L1 = 0; // lenght (L1)
       
  1450     if( KBit7 & aData[aIndex] )
       
  1451         {
       
  1452         tag += 4;
       
  1453         }
       
  1454     if( KBit6 & aData[aIndex] )
       
  1455         {
       
  1456         tag += 2;
       
  1457         }
       
  1458     if( KBit5 & aData[aIndex] )
       
  1459         {
       
  1460         tag += 1;
       
  1461         }
       
  1462     L1 = aData[aIndex] & 0x1F; // clear the 3 MSBits
       
  1463 
       
  1464     aIndex++; // jump over the first byte
       
  1465 
       
  1466     TInt auxTag = 0;
       
  1467     switch( tag )
       
  1468         {
       
  1469         case 0:
       
  1470             //reserved
       
  1471             break;
       
  1472         case 1:
       
  1473             ReadCea861ShortAudioDataBlockL( aData, aIndex, L1 );
       
  1474             break;
       
  1475         case 2:
       
  1476             ReadCea861ShortVideoDataBlockL( aData, aIndex, L1 );
       
  1477             break;
       
  1478         case 3:
       
  1479             ReadCea861VendorSpecificDataBlockL( aData, aIndex, L1 );
       
  1480             break;
       
  1481         case 4:
       
  1482             ReadCea861SpeakerAllocationDataBlock( aData, aIndex, L1 );
       
  1483             break;
       
  1484         case 5:
       
  1485             //VESA DTC Data Block
       
  1486             ReadUnknownTagCode( aData, aIndex, L1 );
       
  1487             break;
       
  1488         case 6:
       
  1489             //reserved
       
  1490             ReadUnknownTagCode( aData, aIndex, L1 );
       
  1491             break;
       
  1492         case 7:
       
  1493             //use extended tag (second byte holds the extended tag-code)
       
  1494             // (see table 43 in CEA-861 spec) (if using repeater, then these information must be re-transmitted)
       
  1495             auxTag = aData[aIndex + 1];
       
  1496             if( auxTag == 5 ) // colorimetry, see table 51, table 52 and table 53 in CEA-861-E.pdf
       
  1497                 {
       
  1498                 }
       
  1499             else if( auxTag == 0x07 ) // video Capability Data Block, see table 54
       
  1500                 {
       
  1501                 ReadVideoCapabilityDataBlockL( aData, aIndex, L1 );
       
  1502                 }
       
  1503             else if( auxTag == 0x01 ) // Vendor-Specific Video Data Block, see table 56
       
  1504                 {
       
  1505                 }
       
  1506             else if( auxTag == 0x11 ) // Vendor-Specific Audio Data Block, see table 57
       
  1507                 {
       
  1508                 }
       
  1509             // TODO: these should be read as well, not just as unknown
       
  1510             ReadUnknownTagCode( aData, aIndex, L1 );
       
  1511             break;
       
  1512         default:
       
  1513             // if tag-code is unknown, we still must read through it
       
  1514             ReadUnknownTagCode( aData, aIndex, L1 );
       
  1515             break;
       
  1516         }
       
  1517 
       
  1518     return KErrNone;
       
  1519     }
       
  1520 
       
  1521 // ----------------------------------------------------------------------------
       
  1522 // CCea861EdidParser::ReadCea861ShortAudioDataBlockL
       
  1523 //
       
  1524 // ----------------------------------------------------------------------------
       
  1525 //
       
  1526 void CCea861EdidParser::ReadCea861ShortAudioDataBlockL( const TExtDataBlock& aData,
       
  1527     TInt& aIndex,
       
  1528     const TInt8 aLen )
       
  1529     {
       
  1530     FUNC_LOG;
       
  1531 
       
  1532     iAudioDataBlockSupported = ETrue;
       
  1533 
       
  1534     if( !iParsedInfo->iShortAudioDescriptors ) // linked list
       
  1535         {
       
  1536         iParsedInfo->iShortAudioDescriptors
       
  1537             = new ( ELeave ) TCEA861AudioDataBlock();
       
  1538         }
       
  1539     TCEA861AudioDataBlock* cur = iParsedInfo->iShortAudioDescriptors;
       
  1540 
       
  1541     while( cur->iNext != 0 )
       
  1542         {
       
  1543         cur = cur->iNext; // jump to the end
       
  1544         }
       
  1545 
       
  1546     TBool first = ETrue;
       
  1547     for( int i = 0; i < aLen; i++ )
       
  1548         {
       
  1549         // read aLen-amount of short video descriptors
       
  1550 
       
  1551         // first link is a special case
       
  1552         if( ( iParsedInfo->iShortAudioDescriptors == cur ) && first )
       
  1553             {
       
  1554             first = EFalse;
       
  1555             cur->iByte1 = aData[aIndex];
       
  1556             cur->iByte2 = aData[aIndex + 1];
       
  1557             cur->iByte3 = aData[aIndex + 2];
       
  1558             DetermineAudioBlockInformation( cur );
       
  1559             aIndex += 3;
       
  1560             i += 3;
       
  1561             continue;
       
  1562             }
       
  1563 
       
  1564         // create new data blocks
       
  1565         cur->iNext = new ( ELeave ) TCEA861AudioDataBlock();
       
  1566         cur = cur->iNext;
       
  1567         cur->iByte1 = aData[aIndex];
       
  1568         cur->iByte2 = aData[aIndex + 1];
       
  1569         cur->iByte3 = aData[aIndex + 2];
       
  1570         cur->iNext = 0;
       
  1571 
       
  1572         DetermineAudioBlockInformation( cur );
       
  1573 
       
  1574         aIndex += 3;
       
  1575         i += 3;
       
  1576         }
       
  1577     }
       
  1578 
       
  1579 // ----------------------------------------------------------------------------
       
  1580 // CCea861EdidParser::ReadCea861ShortVideoDataBlockL
       
  1581 //
       
  1582 // ----------------------------------------------------------------------------
       
  1583 //
       
  1584 void CCea861EdidParser::ReadCea861ShortVideoDataBlockL( const TExtDataBlock& aData,
       
  1585     TInt& aIndex,
       
  1586     const TInt8 aLen )
       
  1587     {
       
  1588     FUNC_LOG;
       
  1589 
       
  1590     TBool first = ETrue;
       
  1591     iVideoDataBlockSupported = ETrue;
       
  1592     if( !iParsedInfo->iShortVideoDescriptors ) // linked list
       
  1593         {
       
  1594         iParsedInfo->iShortVideoDescriptors
       
  1595             = new ( ELeave ) TCEA861VideoDataBlock();
       
  1596         iParsedInfo->iShortVideoDescriptors->iNext = 0; // make sure there are no stray pointers
       
  1597         }
       
  1598 
       
  1599     TCEA861VideoDataBlock* cur = iParsedInfo->iShortVideoDescriptors;
       
  1600     while( cur->iNext != 0 )
       
  1601         {
       
  1602         cur = cur->iNext; // jump to the end
       
  1603         first = EFalse; // there is already some links, so set first to false
       
  1604         }
       
  1605 
       
  1606     for( int i = 0; i < aLen; i++ )
       
  1607         {
       
  1608 
       
  1609         // read aLen-amount of short video descriptors
       
  1610 
       
  1611         // first link is a special case
       
  1612         if( ( iParsedInfo->iShortVideoDescriptors == cur ) && first )
       
  1613             {
       
  1614             first = EFalse;
       
  1615             cur->iNative = KBit7 & aData[aIndex];
       
  1616             cur->iVIC = ( ~KBit7 ) & aData[aIndex]; // nullify the most signicant bit
       
  1617             cur->iNext = 0;
       
  1618             aIndex++;
       
  1619             continue;
       
  1620             }
       
  1621 
       
  1622         // create new data blocks
       
  1623         cur->iNext = new ( ELeave ) TCEA861VideoDataBlock();
       
  1624         cur = cur->iNext;
       
  1625         cur->iNative = KBit7 & aData[aIndex];
       
  1626         cur->iVIC = ( ~KBit7 ) & aData[aIndex]; // nullify the most signicant bit
       
  1627         cur->iNext = 0;
       
  1628         aIndex++;
       
  1629         }
       
  1630     }
       
  1631 
       
  1632 // ----------------------------------------------------------------------------
       
  1633 // CCea861EdidParser::ReadCea861VendorSpecificDataBlockL
       
  1634 //
       
  1635 // ----------------------------------------------------------------------------
       
  1636 //
       
  1637 void CCea861EdidParser::ReadCea861VendorSpecificDataBlockL( const TExtDataBlock& aData,
       
  1638     TInt& aIndex,
       
  1639     TInt8 aLen )
       
  1640     {
       
  1641     FUNC_LOG;
       
  1642 
       
  1643     iVendorSpecificDataBlockSupported = ETrue;
       
  1644 
       
  1645     if( !iParsedInfo->iVendorSpecificData )
       
  1646         {
       
  1647         iParsedInfo->iVendorSpecificData = new ( ELeave ) TCEA861VendorSpecificDataBlock();
       
  1648         }
       
  1649 
       
  1650 
       
  1651     TUint8 data1 = aData[aIndex]; // least significant byte first
       
  1652     TUint8 data2 = aData[aIndex + 1];
       
  1653     TUint8 data3 = aData[aIndex + 2];
       
  1654     aIndex += 3; // three bytes of IEEE registration identifier
       
  1655 
       
  1656     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier = 0; // convert from LSB -> MSB
       
  1657     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier += data3;
       
  1658     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier
       
  1659         = iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier
       
  1660             << 8;
       
  1661     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier += data2;
       
  1662     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier
       
  1663         = iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier
       
  1664             << 8;
       
  1665     iParsedInfo->iVendorSpecificData->iIEEE24bitRegistrationIdentifier += data1;
       
  1666 
       
  1667     aLen -= 3; // this is needed: Vendor specific payload length = L4-3bytes
       
  1668 
       
  1669     TBool first = ETrue;
       
  1670     if( iParsedInfo->iVendorSpecificData->iVendorSpecificPayloadStart == 0 )
       
  1671         {
       
  1672         iParsedInfo->iVendorSpecificData->iVendorSpecificPayloadStart
       
  1673             = new ( ELeave ) TCEA861VendorSpecificDataBlockPayload();
       
  1674         }
       
  1675     TCEA861VendorSpecificDataBlockPayload* cur =
       
  1676         iParsedInfo->iVendorSpecificData->iVendorSpecificPayloadStart;
       
  1677     // traverse to the end of the list
       
  1678     while( cur->iNext != 0 )
       
  1679         {
       
  1680         cur = cur->iNext;
       
  1681         }
       
  1682 
       
  1683     for( int i = 0; i < aLen; i++ )
       
  1684         {
       
  1685         if( ( cur == iParsedInfo->iVendorSpecificData->iVendorSpecificPayloadStart )
       
  1686             && first ) // first byte is special case
       
  1687             {
       
  1688             first = EFalse;
       
  1689             cur->iData = aData[aIndex];
       
  1690             cur->iNext = NULL;
       
  1691             aIndex++;
       
  1692             continue;
       
  1693             }
       
  1694         cur->iNext = new ( ELeave ) TCEA861VendorSpecificDataBlockPayload();
       
  1695         cur = cur->iNext;
       
  1696         cur->iData = aData[aIndex];
       
  1697         cur->iNext = 0;
       
  1698         aIndex++;
       
  1699         }
       
  1700     }
       
  1701 
       
  1702 // ----------------------------------------------------------------------------
       
  1703 // CCea861EdidParser::ReadCea861SpeakerAllocationDataBlock
       
  1704 //
       
  1705 // ----------------------------------------------------------------------------
       
  1706 //
       
  1707 void CCea861EdidParser::ReadCea861SpeakerAllocationDataBlock( const TExtDataBlock& aData,
       
  1708     TInt& aIndex,
       
  1709     const TInt8 aLen )
       
  1710     {
       
  1711     FUNC_LOG;
       
  1712 
       
  1713     // read the 3 bytes
       
  1714     if( aLen != 3 )
       
  1715         {
       
  1716         return;
       
  1717         }
       
  1718 
       
  1719     iSpeakerAllocationDataBlockSupported = ETrue;
       
  1720 
       
  1721     for( TInt i = 0; i < aLen; i++ )
       
  1722         {
       
  1723         switch( i )
       
  1724             {
       
  1725             case 0:
       
  1726                 iParsedInfo->iSpeakerAllocationData.iByte1 = aData[aIndex];
       
  1727                 break;
       
  1728             case 1:
       
  1729                 iParsedInfo->iSpeakerAllocationData.iByte2 = aData[aIndex];
       
  1730                 break;
       
  1731             case 2:
       
  1732                 iParsedInfo->iSpeakerAllocationData.iByte3 = aData[aIndex];
       
  1733                 break;
       
  1734             default:
       
  1735                 // error
       
  1736                 break;
       
  1737             }
       
  1738         aIndex++;
       
  1739         }
       
  1740     }
       
  1741 
       
  1742 // ----------------------------------------------------------------------------
       
  1743 // CCea861EdidParser::ReadVideoCapabilityDataBlockL
       
  1744 //
       
  1745 // ----------------------------------------------------------------------------
       
  1746 //
       
  1747 void CCea861EdidParser::ReadVideoCapabilityDataBlockL( const TExtDataBlock& aData,
       
  1748     TInt& aIndex,
       
  1749     const TInt8 aLen )
       
  1750     {
       
  1751     FUNC_LOG;
       
  1752 
       
  1753     aIndex++; // jump to the extended tag code (aLen is the length from extended tag to the end)
       
  1754 
       
  1755     if( iParsedInfo->iVideoCapabilityDataBlock == 0 )
       
  1756         {
       
  1757         iParsedInfo->iVideoCapabilityDataBlock
       
  1758             = new ( ELeave ) TCEA861VideoCapabilityDataBlock();
       
  1759         }
       
  1760     TCEA861VideoCapabilityDataBlock* cur =
       
  1761         iParsedInfo->iVideoCapabilityDataBlock;
       
  1762     TBool first = ETrue;
       
  1763     while( cur->iNext != 0 )
       
  1764         {
       
  1765         first = EFalse;
       
  1766         cur = cur->iNext;
       
  1767         }
       
  1768 
       
  1769     // Payload currently only contains a single byte in addition to the extended tag code. The Source should ignore such additional bytes when present.
       
  1770     for( int i = 0; i < aLen; i++ )
       
  1771         {
       
  1772         if( i == 1 )
       
  1773             {
       
  1774             if( !first ) // if this wasn't the first time we are reading to this
       
  1775                 {
       
  1776                 cur->iNext = new ( ELeave ) TCEA861VideoCapabilityDataBlock(); // sets Next to 0
       
  1777                 cur = cur->iNext;
       
  1778                 }
       
  1779             cur->iInitialized = ETrue;
       
  1780             cur->iQuantizationRange = aData[aIndex] & KBit7;
       
  1781             cur->iQuantizationRangeSelectable = aData[aIndex] & KBit6;
       
  1782             cur->iS_PT1 = aData[aIndex] & KBit5;
       
  1783             cur->iS_PT0 = aData[aIndex] & KBit4;
       
  1784             cur->iS_IT1 = aData[aIndex] & KBit3;
       
  1785             cur->iS_IT0 = aData[aIndex] & KBit2;
       
  1786             cur->iS_CE1 = aData[aIndex] & KBit1;
       
  1787             cur->iS_CE0 = aData[aIndex] & KBit0;
       
  1788             cur->iNext = 0;
       
  1789             }
       
  1790         aIndex++;
       
  1791         }
       
  1792     }
       
  1793 
       
  1794 // ----------------------------------------------------------------------------
       
  1795 // CCea861EdidParser::readUnknownTagCode
       
  1796 //
       
  1797 // ----------------------------------------------------------------------------
       
  1798 //
       
  1799 void CCea861EdidParser::ReadUnknownTagCode( const TExtDataBlock& /*aData*/,
       
  1800     TInt& aIndex,
       
  1801     const TInt8 aLen )
       
  1802     {
       
  1803     FUNC_LOG;
       
  1804 
       
  1805     // Skip the data. This must be done if the tag is unknown
       
  1806     aIndex += aLen;
       
  1807     }
       
  1808 
       
  1809 // ----------------------------------------------------------------------------
       
  1810 // CCea861EdidParser::DetermineAudioBlockInformation
       
  1811 //
       
  1812 // ----------------------------------------------------------------------------
       
  1813 //
       
  1814 void CCea861EdidParser::DetermineAudioBlockInformation( TCEA861AudioDataBlock* aAudioBlock )
       
  1815     {
       
  1816     FUNC_LOG;
       
  1817 
       
  1818     // x6543xxx we need the information in the bytes 6543
       
  1819     aAudioBlock->iAudioFormatCode = ( KBit3 | KBit2 | KBit1 | KBit0 )
       
  1820         & ( aAudioBlock->iByte1 >> 3 );
       
  1821     aAudioBlock->iSupport192kHz = ( aAudioBlock->iByte2 & KBit6 ? ETrue : EFalse );
       
  1822     aAudioBlock->iSupport176kHz = ( aAudioBlock->iByte2 & KBit5 ? ETrue : EFalse );
       
  1823     aAudioBlock->iSupport96kHz = ( aAudioBlock->iByte2 & KBit4 ? ETrue : EFalse );
       
  1824     aAudioBlock->iSupport88kHz = ( aAudioBlock->iByte2 & KBit3 ? ETrue: EFalse );
       
  1825     aAudioBlock->iSupport48kHz = ( aAudioBlock->iByte2 & KBit2 ? ETrue : EFalse );
       
  1826     aAudioBlock->iSupport44kHz = ( aAudioBlock->iByte2 & KBit1 ? ETrue : EFalse );
       
  1827     aAudioBlock->iSupport32kHz = ( aAudioBlock->iByte2 & KBit0 ? ETrue : EFalse );
       
  1828     aAudioBlock->iMaxChannels = aAudioBlock->iByte1 & 0x07; // only the 3 LSB is used
       
  1829     //TODO: 3rd byte shall be read according to the audioformatcode (see table 45 in CEA-861-E.pdf)
       
  1830     switch( aAudioBlock->iAudioFormatCode )
       
  1831         {
       
  1832         case 1:
       
  1833             aAudioBlock->iSupport24Bit = ( aAudioBlock->iByte3 & KBit2 ? ETrue : EFalse );
       
  1834             aAudioBlock->iSupport20Bit = ( aAudioBlock->iByte3 & KBit1 ? ETrue : EFalse );
       
  1835             aAudioBlock->iSupport16Bit = ( aAudioBlock->iByte3 & KBit0 ? ETrue : EFalse );
       
  1836             break;
       
  1837         case 2: //cases 2-8
       
  1838         case 3:
       
  1839         case 4:
       
  1840         case 5:
       
  1841         case 6:
       
  1842         case 7:
       
  1843         case 8:
       
  1844             aAudioBlock->iMaxBitrate = aAudioBlock->iByte3 * 8;
       
  1845             break;
       
  1846         case 9: // cases 9-13
       
  1847         case 10:
       
  1848         case 11:
       
  1849         case 12:
       
  1850         case 13:
       
  1851             // byte3 is Audio format code dependent value
       
  1852             break;
       
  1853         case 14:
       
  1854             // byte3 bits 0,1,2 is profile. bits 3-7 are reserved.
       
  1855             break;
       
  1856         case 15: // bits 7-3 = audio format code extension, bits 2-0
       
  1857             aAudioBlock->iAudioFormatCodeExtension = aAudioBlock->iByte3 >> 3;
       
  1858             break;
       
  1859         default:
       
  1860             // error
       
  1861             break;
       
  1862         }
       
  1863     }
       
  1864 
       
  1865 // ----------------------------------------------------------------------------
       
  1866 // CCea861EdidParser::LatencyFieldsPresent
       
  1867 //
       
  1868 // ----------------------------------------------------------------------------
       
  1869 //
       
  1870 TBool CCea861EdidParser::LatencyFieldsPresent( TUint8 aByte ) const
       
  1871     {
       
  1872     FUNC_LOG;
       
  1873     
       
  1874     TBool present = EFalse;
       
  1875     
       
  1876     // Latency_Fields_Preset bit is bit6 (01000000) in the aByte
       
  1877     if( aByte & 0x40 )
       
  1878         {
       
  1879         present = ETrue;
       
  1880         }
       
  1881     return present;
       
  1882     }
       
  1883 
       
  1884 // ----------------------------------------------------------------------------
       
  1885 // CCea861EdidParser::InterlacedLatencyFieldsPresent
       
  1886 //
       
  1887 // ----------------------------------------------------------------------------
       
  1888 //
       
  1889 TBool CCea861EdidParser::InterlacedLatencyFieldsPresent( TUint8 aByte ) const
       
  1890     {
       
  1891     FUNC_LOG;
       
  1892 
       
  1893     TBool present = EFalse;
       
  1894     
       
  1895     // Latency_Fields_Preset bit is bit7 (10000000) in the aByte
       
  1896     if( aByte & 0x80 )
       
  1897         {
       
  1898         present = ETrue;
       
  1899         }
       
  1900     return present;
       
  1901     }
       
  1902 
       
  1903 // ----------------------------------------------------------------------------
       
  1904 // CCea861EdidParser::InterlacedLatencyFieldsPresent
       
  1905 //
       
  1906 // ----------------------------------------------------------------------------
       
  1907 //
       
  1908 TUint8 CCea861EdidParser::LatencyInMs( TUint8 aByte ) const
       
  1909     {
       
  1910     FUNC_LOG;
       
  1911     
       
  1912     TUint8 latency = 0;
       
  1913     if( aByte > 0 && aByte <= 251 )
       
  1914         {
       
  1915         latency = ( aByte - 1 ) * 2;
       
  1916         }
       
  1917     
       
  1918     return latency;
       
  1919     }
       
  1920 
       
  1921 // End of file