accessoryservices/pluggeddisplay/pluggeddisplayengine/src/edidhandler.cpp
changeset 0 4e1aa6a622a0
child 3 a811597961f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/pluggeddisplay/pluggeddisplayengine/src/edidhandler.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1397 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:  EDID data Handler class for HDMI Cable Status FSM.
+ *
+ */
+
+#include <tvoutconfig.h>
+#include <accpolhdmisink.h>
+#include <accpolhdmiaudioformat.h>
+#include <accpolhdmivideoformat.h>
+#include <accpolhdmilatency.h>
+#include <accpolhdmispeakerallocation.h>
+#include <e32cmn.h>
+#include <e32math.h>
+#include <accessoriescrkeys.h>
+#include <centralrepository.h>
+
+#include "pdeconstants.h"
+#include "tvoutconfigforhdmi.h"
+#include "edidhandler.h"
+#include "edidparserbase.h"
+#include "cea861edidparser.h"
+#include "multifinitestatemachine.h"
+#include "trace.h"
+#include "traceediddata.h"
+
+const TReal K16d9 = 1.778;
+const TReal K4d3 = 1.333;
+
+const TInt KDefaultCEAMode = E640x480p59_94d60Hz4d3;
+const TInt KDefaultCEAModeIndex = 0;
+
+// Retry Delay for EDID access
+const TInt KRetryDelay = 50 * 1000; // 50 milliseconds
+
+// Maximum retry count for EDID access
+const TInt KMaxRetryCount = 40;  // 40 * 50ms = 2 Seconds
+
+const TUint16 KDefaultCEAModePhysImgAspRatioNr = 4;
+
+const TUint16 KDefaultCEAModePhysImgAspRatioDr = 3;
+
+//------------------------------------------------------------------------------
+// Symbian two-phased constructor
+//------------------------------------------------------------------------------
+//
+CEDIDHandler* CEDIDHandler::NewL( MFSMForBody& aFSM,
+    CTVOutConfigForHDMI& aTVOutConfigForHDMI )
+    {
+    FUNC_LOG;
+    CEDIDHandler* self = new ( ELeave ) CEDIDHandler(
+            aFSM, aTVOutConfigForHDMI );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+//------------------------------------------------------------------------------
+// Destructor
+//------------------------------------------------------------------------------
+//
+CEDIDHandler::~CEDIDHandler()
+    {
+    FUNC_LOG;
+    
+    Cancel();
+    delete iDdcPortAccess;
+    delete iDataBlockPtr;
+    delete iExtensionParserPtr;
+    delete iEdidParserPtr;
+    iRetryTimer.Close();
+    }
+
+//------------------------------------------------------------------------------
+// FetchEDIDData
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::FetchEDIDData()
+    {
+    FUNC_LOG;
+    
+    TInt retVal( KErrNone );
+    TUint apiVersion = iDdcPortAccess->ApiVersion();
+    if( KDdcAccessVersion != apiVersion )
+        {
+        INFO_1( "iDdcPortAccess->ApiVersion() returned unsupported version != KDdcAccessVersion: %d", apiVersion );
+        retVal = KErrNotSupported;
+        }
+    else
+        {
+        iRetryCounter = KErrNone;
+        TInt err = KErrNone;
+        TRAP( retVal , err = ReadEDIDDataL() );
+        if ( err != KErrNone )
+            {
+            retVal = err;
+            }
+        }
+    INFO_1( "CEDIDHandler::FetchEDIDData() retVal: %d", retVal );
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetVideoParameters
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetVideoParameters()
+    {
+    FUNC_LOG;
+
+    TInt retVal = KErrNone;
+    RArray<TTvSettings> analogConfigs;
+    RArray<THdmiDviTimings> hdmiConfigs;
+    
+    // Update overscan values from cenrep
+    UpdateOverscanValues();
+
+    // Set video parameters
+    INFO( "--------------------------------------------------------------------" );
+    INFO( "SETTING CEA AND DMT TIMINGS:" );
+    retVal = SetCeaModes( hdmiConfigs );
+    ERROR( retVal, "Failed to set CEA modes" );
+    
+    if( KErrNone == retVal )
+        {
+        retVal = SetDmtModes( hdmiConfigs );
+        ERROR( retVal, "Failed to set DMT modes" );
+        INFO( "--------------------------------------------------------------------" );
+        
+        if( KErrNone == retVal )
+            {
+            // Filtering out the unsupported modes
+            // Logical AND(Sink supported modes AND HW supported modes)
+            INFO( "Filtering out the unsupported modes" );
+            retVal = FilterAvailableTvConfigList( hdmiConfigs );
+            ERROR( retVal, "Failed to filter the TV config list." );
+    
+            if( KErrNone == retVal )
+                {
+                retVal = iTVOutConfigForHDMI.SetAvailableTvConfigList( analogConfigs, hdmiConfigs );
+                ERROR( retVal, "Failed to set available TV config list." );
+                }            
+            }
+        }
+    
+    // Clean up
+    hdmiConfigs.Close();
+    analogConfigs.Close();
+
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// GetEDIDDataL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::ResetData()
+    {
+    FUNC_LOG;
+    
+    delete iDataBlockPtr;
+    iDataBlockPtr = NULL;
+    delete iEdidParserPtr;
+    iEdidParserPtr = NULL;
+    delete iExtensionParserPtr;
+    iExtensionParserPtr = NULL;
+    }
+
+//------------------------------------------------------------------------------
+// CreateHdmiSinkL
+//------------------------------------------------------------------------------
+//
+CAccPolHdmiSink* CEDIDHandler::CreateHdmiSinkL()
+    {
+    FUNC_LOG;
+    
+    CAccPolHdmiSink* hdmiSink( NULL );
+    if( iExtensionParserPtr && iTVOutConfigForHDMI.GetTvOutConfig() )
+        {
+        hdmiSink = CAccPolHdmiSink::NewL(
+            iExtensionParserPtr->BasicAudio(),
+            iTVOutConfigForHDMI.GetTvOutConfig()->CopyProtectionStatus() );
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    return hdmiSink;
+    }
+
+//------------------------------------------------------------------------------
+// CreateHdmiVideoFormatL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::CreateHdmiVideoFormatL( RAccPolHdmiVideoFormatArray& aHdmiVideoFormatArray )
+    {
+    FUNC_LOG;
+    
+    // Active Video Format object values can be fetched from TvOutConfig interface.
+    if( iEdidParserPtr && iTVOutConfigForHDMI.GetTvOutConfig() )
+        {
+        THdmiDviTimings hdmiDviTimings;
+        TInt retVal = iTVOutConfigForHDMI.GetTvOutConfig()->GetConfig(
+            hdmiDviTimings );
+        if( KErrNone == retVal )
+            {
+            CAccPolHdmiVideoFormat* hdmiVideoFormat = CAccPolHdmiVideoFormat::NewLC();            
+            hdmiVideoFormat->SetCeaFixedMode( hdmiDviTimings.iCeaMode );
+            hdmiVideoFormat->SetDmtFixedMode( EDmtFixedModeNone );
+            hdmiVideoFormat->SetPixelRepeat( hdmiDviTimings.iPixelRepeat );
+            hdmiVideoFormat->SetInterlaced( hdmiDviTimings.iInterlaced );
+            aHdmiVideoFormatArray.AppendL( hdmiVideoFormat );
+            CleanupStack::Pop( hdmiVideoFormat );
+            }
+        else
+            {
+            User::Leave( retVal );
+            }
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+//------------------------------------------------------------------------------
+// CreateHdmiLatencyL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::CreateHdmiLatencyL( RAccPolHdmiLatencyArray& aHdmiLatencyArray )
+    {
+    FUNC_LOG;
+    
+    if( iEdidParserPtr && iExtensionParserPtr )
+        {
+        // Interlaced audio and video latency
+        CAccPolHdmiLatency* hdmiLatency = CAccPolHdmiLatency::NewLC(
+            HdmiLatency::KUidInterlacedLatency,
+            iExtensionParserPtr->GetInterlacedAudioLatency(),
+            iExtensionParserPtr->GetInterlacedVideoLatency() ); 
+        aHdmiLatencyArray.AppendL( hdmiLatency );
+        CleanupStack::Pop( hdmiLatency );
+
+        // Progressive audio and video latency
+        hdmiLatency = CAccPolHdmiLatency::NewLC(
+            HdmiLatency::KUidLatency,
+            iExtensionParserPtr->GetAudioLatency(),
+            iExtensionParserPtr->GetVideoLatency() );
+        aHdmiLatencyArray.AppendL( hdmiLatency );
+        CleanupStack::Pop( hdmiLatency );
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+//------------------------------------------------------------------------------
+// CreateHdmiAudioFormatL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::CreateHdmiAudioFormatL( RAccPolHdmiAudioFormatArray& aHdmiAudioFormatArray )
+    {
+    FUNC_LOG;
+    
+    if( iExtensionParserPtr )
+        {
+        if( iExtensionParserPtr->IsAudioDataBlockSupported() )
+            {
+            TCEA861AudioDataBlock
+                * audioDataBlock =
+                    iExtensionParserPtr->GetParsedInformation()->iShortAudioDescriptors;
+            while( audioDataBlock )
+                {
+                    CAccPolHdmiAudioFormat* hdmiAudioFormat =
+                        CAccPolHdmiAudioFormat::NewL();
+                    CleanupStack::PushL( hdmiAudioFormat );
+
+                    // Set audio format
+                    TUid audioFormat;
+                    audioFormat.iUid = audioDataBlock->iAudioFormatCode;
+                    hdmiAudioFormat->SetAudioFormat( audioFormat ); // const TUid aAudioFormat,
+
+                    // Set bit resolution
+                    TUint32 bitResolution( CAccPolHdmiAudioFormat::EUnknownBitsPerSample );
+                    if( audioDataBlock->iSupport24Bit )
+                        {
+                        bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample24;
+                        }
+                    if( audioDataBlock->iSupport20Bit )
+                        {
+                        bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample20;
+                        }
+                    if( audioDataBlock->iSupport16Bit )
+                        {
+                        bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample16;
+                        }
+                    hdmiAudioFormat->SetBitResolution( bitResolution ); // const TUint32 aBitResolution,
+                    hdmiAudioFormat->SetMaxBitResolution( audioDataBlock->iMaxBitrate ); // const TUint32 aMaxBitResolution,
+                    hdmiAudioFormat->SetChannelCount( audioDataBlock->iMaxChannels ); // const TUint32 aMaxChannelCount,
+
+                    // Set sample frequency 
+                    TUint32 samFreq( CAccPolHdmiAudioFormat::EUnknownFrequency );
+                    if( audioDataBlock->iSupport192kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq192KHz;
+                        }
+                    if( audioDataBlock->iSupport176kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq176KHz;
+                        }
+                    if( audioDataBlock->iSupport96kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq96KHz;
+                        }
+                    if( audioDataBlock->iSupport88kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq88KHz;
+                        }
+                    if( audioDataBlock->iSupport48kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq48KHz;
+                        }
+                    if( audioDataBlock->iSupport44kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq44KHz;
+                        }
+                    if( audioDataBlock->iSupport32kHz )
+                        {
+                        samFreq
+                            |= CAccPolHdmiAudioFormat::ESamplingFreq32KHz;
+                        }
+                    hdmiAudioFormat->SetSamFreq( samFreq ); // const TUint32 aSamFreq,
+                    hdmiAudioFormat->SetFormatDependentValue( audioDataBlock->iAudioFormatCodeExtension ); // const TUint32 aFormatDependentValue
+                    aHdmiAudioFormatArray.AppendL( hdmiAudioFormat );
+                    CleanupStack::Pop( hdmiAudioFormat );
+                    
+                    audioDataBlock = audioDataBlock->iNext;
+                }
+            }
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+//------------------------------------------------------------------------------
+// CreateHdmiAudioFormatL
+//------------------------------------------------------------------------------
+//
+CAccPolHdmiSpeakerAllocation* CEDIDHandler::CreateHdmiSpeakerAllocationL()
+    {
+    FUNC_LOG;
+    
+    CAccPolHdmiSpeakerAllocation* hdmiSpeakerAllocation( NULL );
+    if( iExtensionParserPtr )
+        {
+        if( iExtensionParserPtr->IsSpeakerAllocationDataBlockSupported() )
+            {
+            TCEA861SpeakerAllocationData
+                * speakerAllocationData =
+                    &( iExtensionParserPtr->GetParsedInformation()->iSpeakerAllocationData );
+            if( speakerAllocationData )
+                {
+                hdmiSpeakerAllocation
+                    = CAccPolHdmiSpeakerAllocation::NewL( speakerAllocationData->FL_FR(), //const TBool aFrontSpeakers,
+                        speakerAllocationData->RL_RR(), //const TBool aRearSpeakers,
+                        speakerAllocationData->LFE(), //const TBool aLowFrequencyEffect,
+                        speakerAllocationData->FC(), //const TBool aFrontCenter,
+                        speakerAllocationData->FCH(), //const TBool aFrontCenterHigh,
+                        speakerAllocationData->TC(), //const TBool aTopCenter,
+                        speakerAllocationData->RC(), //const TBool aRearCenter,
+                        speakerAllocationData->FLC_FRC(), //const TBool aFrontLeftRightCenter,
+                        speakerAllocationData->RLC_RRC(), //const TBool aRearLeftRightCenter,
+                        speakerAllocationData->FLW_FRW(), //const TBool aFrontWideSpeakers,
+                        speakerAllocationData->FLH_FRH() //const TBool aFrontHighSpeakers         
+                    );
+                }
+            }
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    return hdmiSpeakerAllocation;
+    }
+
+//------------------------------------------------------------------------------
+// GetHdcpSupportStatus
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::GetHdcpSupportStatus( TBool& aHdcpSupportStatus ) const
+    {
+    FUNC_LOG;
+    
+    TInt retVal( KErrNone );
+    if( iTVOutConfigForHDMI.GetTvOutConfig() )
+        {
+        aHdcpSupportStatus
+            = ( iTVOutConfigForHDMI.GetTvOutConfig() )->CopyProtectionStatus();
+        }
+    else
+        {
+        retVal = KErrNotFound;
+        }
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// RunL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::RunL()
+    {
+
+    FUNC_LOG;
+    
+    switch ( iRequestID )
+        {
+        case EDdcReadRequest:
+            {
+            if( KErrNone == iStatus.Int() )
+                {
+                TPtrC8
+                    dataBlockDes( iDataBlockPtr->iDataBlock, sizeof( *iDataBlockPtr ) );
+                iEdidParserPtr = CEdidParserBase::NewL( dataBlockDes );
+                TInt nbrOfExtensions = iEdidParserPtr->GetNumberOfExtensions();
+                for( TInt i = 0; i < nbrOfExtensions; ++i )
+                    {
+                    if( ECea861Ext == iEdidParserPtr->GetExtensionType( i + 1 ) )
+                        {
+                        INFO_1( "ECea861Ext extension data block number: %d", ( i+1 ) );
+                        iExtensionParserPtr
+                            = iEdidParserPtr->CreateCea861ExtensionParserL( i + 1 );
+                        break;
+                        }
+                    }
+                INFO_1( "Data block count in nbrOfExtensions: %d", nbrOfExtensions );
+                iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetched );
+                iRetryCounter = KErrNone;
+                }
+            else
+                {
+                INFO_1( "CDdcPortAccess::Read failed, error code: %d", iStatus.Int() );
+                
+                if( (iStatus.Int() == KErrNotReady) && (iRetryCounter < KMaxRetryCount) )
+                    {
+                    iRetryCounter++;
+                    iRequestID = ERetryTimerRequest;
+                    iRetryTimer.After( iStatus, KRetryDelay );
+                    SetActive();
+                    }
+                else
+                    {
+                    iRetryCounter = KErrNone;
+                    iFSM.Input( EPDEIfEDIDHandler,
+                        EPDEIfEDIDHandlerEventEdidDataFetchFailed );
+                    }
+                }
+            break;
+            }
+        case ERetryTimerRequest:
+            {
+            INFO_1( "Retrying... count: %d", iRetryCounter );
+            if( ReadEDIDDataL() != KErrNone )
+                {
+                iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetchFailed );
+                }
+            break;
+            }
+        default:
+            {
+            INFO_1( "Undefined Request ID %d", iRequestID );
+            break;
+            }
+        }
+    }
+
+//------------------------------------------------------------------------------
+// From class CActive.
+// RunL
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::RunError( TInt aError )
+    {
+    FUNC_LOG;
+    
+    /*TInt err( aError );
+    // Avoid Panic in CActiveScheduler
+    if ( err )
+        {
+        INFO_1( "aError %d", err );
+        }*/
+    iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetchFailed );
+        
+    return KErrNone;
+    }
+
+//-------------------------------------------------------------------------------
+// DoCancel
+//
+//-------------------------------------------------------------------------------
+//
+void CEDIDHandler::DoCancel()
+    {
+    FUNC_LOG;
+    
+    iDdcPortAccess->CancelAll();
+    }
+
+//------------------------------------------------------------------------------
+// ReadEDIDDataL
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::ReadEDIDDataL()
+    {
+    FUNC_LOG;
+    
+    TInt retVal( KErrNone );
+    
+    iRequestID = EDdcReadRequest;
+    
+    if( iDataBlockPtr == NULL )
+        {
+        iDataBlockPtr = new(ELeave) TDataBlock;
+        }
+    
+    retVal = iDdcPortAccess->Read( EMonitorPort, 0, // First block contains EDID data if that exists
+        iDataBlockPtr->iDataBlock,
+        iStatus );
+        
+    SetActive();
+        
+    ERROR(retVal, "iDdcPortAccess->Read failed" );
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// CEDIDHandler::FillCommonHdmiDviTimings
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::FillCommonHdmiDviTimings( THdmiDviTimings& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    aTimings.iTvPhysicalImageWidthMm = iEdidParserPtr->GetHorizontalScreenSize() * 10;
+    aTimings.iTvPhysicalImageHeightMm = iEdidParserPtr->GetVerticalScreenSize() * 10;
+    aTimings.iTvPhysicalImageAspectRatioNumerator = 0;
+    aTimings.iTvPhysicalImageAspectRatioDenominator = 0;
+    aTimings.iHorizontalBorderPixels = 0;
+    aTimings.iVerticalBorderLinesField1 = 0;
+    aTimings.iVerticalBorderLinesField2 = 0;
+    aTimings.iLeftBorderPixels = 0;
+    aTimings.iRightBorderPixels = 0;
+    aTimings.iUnderscanEnabled = EFalse;
+    
+    if( iExtensionParserPtr )
+        {
+        aTimings.iUnderscanEnabled = iExtensionParserPtr->Underscan();
+        }
+    
+    if( aTimings.iUnderscanEnabled )
+        {
+        // Underscan
+        aTimings.iLeftTopCorner.iX = 0;
+        aTimings.iLeftTopCorner.iY = 0;
+        aTimings.iRightBottomCorner.iX = aTimings.iHorizontalActivePixels;
+        aTimings.iRightBottomCorner.iY = aTimings.iVerticalActiveLines;
+        }
+    else
+        {
+        // Calculate overscan
+        CalculateOverscan( aTimings.iLeftTopCorner,
+            aTimings.iRightBottomCorner );                
+        }
+    aTimings.iTvPhysicalImageAspectRatioNumerator = iEdidParserPtr->GetAspectRatioLandscape();
+    aTimings.iTvPhysicalImageAspectRatioDenominator = iEdidParserPtr->GetAspectRatioPortrait();
+    aTimings.iConnector = TTvSettings::EHDMI;
+    aTimings.iTvColorCoordinates.iRed.iX = iEdidParserPtr->GetColorCoordinatesRedX();
+    aTimings.iTvColorCoordinates.iRed.iY = iEdidParserPtr->GetColorCoordinatesRedY();
+    aTimings.iTvColorCoordinates.iGreen.iX = iEdidParserPtr->GetColorCoordinatesGreenX();
+    aTimings.iTvColorCoordinates.iGreen.iY = iEdidParserPtr->GetColorCoordinatesGreenY();
+    aTimings.iTvColorCoordinates.iBlue.iX = iEdidParserPtr->GetColorCoordinatesBlueX();
+    aTimings.iTvColorCoordinates.iBlue.iY = iEdidParserPtr->GetColorCoordinatesBlueY();
+    aTimings.iTvColorCoordinates.iWhite.iX = iEdidParserPtr->GetColorCoordinatesWhiteX();
+    aTimings.iTvColorCoordinates.iWhite.iY = iEdidParserPtr->GetColorCoordinatesWhiteY();
+    aTimings.iTvHdmiVersion = iEdidParserPtr->GetVersion();
+    aTimings.iTvHdmiRevision = iEdidParserPtr->GetRevision();
+    Mem::FillZ( ( TAny* )&aTimings.iProductName, ( sizeof( TChar ) * KProductNameChars ) );
+    Mem::FillZ( ( TAny* )&aTimings.iProductDescription, ( sizeof( TChar ) * KProductDescriptorsChars ) );
+    aTimings.iSourceType = THdmiDviTimings::ESourceTypeUnknown;
+    }
+
+//------------------------------------------------------------------------------
+// CEDIDHandler::FillHdmiDviTimings
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::FillHdmiDviTimings( const TTimingItem& aItem,
+    THdmiDviTimings& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    // Fill attributes from the static table
+    if( aItem.iTimingType == ETimingModeCEA )
+        {
+        // CEA
+        aTimings.iCeaMode = static_cast<TFixedModeCea>( aItem.iTimingId );
+        }
+    else
+        {
+        // DMT
+        aTimings.iDmtMode = static_cast<TFixedModeDmt>( aItem.iTimingId );
+        }
+    aTimings.iPixelClockKHz = aItem.iDotClock;
+    aTimings.iHorizontalActivePixels = aItem.iHorizontalActive;
+    aTimings.iHorizontalBlankingPixels = aItem.iHorizontalBlanking;
+    aTimings.iHorizontalSyncOffsetPixels = aItem.iHorizontalFrontPorch;
+    aTimings.iHorizontalSyncPulseWidthPixels = aItem.iHorizontalSync;
+    aTimings.iVerticalActiveLines = aItem.iVertical1stActive;
+    aTimings.iVerticalBlankingLines = aItem.iVertical1stBlanking;
+    aTimings.iVerticalSyncOffsetLinesField1 = aItem.iVertical1stFrontPorch;
+    aTimings.iVerticalSyncPulseWidthLinesField1 = aItem.iVertical1stSync;
+    aTimings.iVerticalSyncOffsetLinesField2 = aItem.iVertical2ndFrontPorch;
+    aTimings.iVerticalSyncPulseWidthLinesField2 = aItem.iVertical2ndSync;
+    aTimings.iInterlaced = aItem.iInterlaced;
+    aTimings.iHorizontalSyncPolarity = aItem.iHorizontalSyncPolarity;
+    aTimings.iVerticalSyncPolarity = aItem.iVerticalSyncPolarity;
+    aTimings.iPixelRepeat = aItem.iPixelRepeat;
+    aTimings.iRightBottomCorner.iX = aItem.iWidth;
+    aTimings.iRightBottomCorner.iY = aItem.iHeight;
+    aTimings.iImageAspectRatio = aItem.iAspectRatio;
+    if( aTimings.iImageAspectRatio == TTvSettings::EUndefRatio )
+        {
+        // Resolve ratio from width and height
+        aTimings.iImageAspectRatio = ResolveAspectRatio( aItem.iWidth, aItem.iHeight );
+        }
+    aTimings.iPixelAspectRatioNumerator = aItem.iPixelAspectRatioNumerator;
+    aTimings.iPixelAspectRatioDenominator = aItem.iPixelAspectRatioDenominator;
+
+    // Fill the common attributes 
+    FillCommonHdmiDviTimings( aTimings );
+    
+    TRACE_TIMINGS( aTimings );
+    }
+
+//------------------------------------------------------------------------------
+// CEDIDHandler::FillHdmiDviTimings
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::FillHdmiDviTimings( const TEdidDescriptorBlock& aDescBlock,
+    THdmiDviTimings& aTimings ) const
+    {
+    FUNC_LOG;
+
+    // Fill attributes from timing descriptor
+    aTimings.iCeaMode = ECeaFixedModeNone;
+    aTimings.iDmtMode = EDmtFixedModeNone;
+    aTimings.iPixelClockKHz = aDescBlock.iPixelClock;
+    aTimings.iHorizontalActivePixels = aDescBlock.iHorizontalAddressableVideoPixels;
+    aTimings.iHorizontalBlankingPixels = aDescBlock.iHorizontalBlanking;
+    aTimings.iHorizontalSyncOffsetPixels = aDescBlock.iHorizontalFrontPorch;
+    aTimings.iHorizontalSyncPulseWidthPixels = aDescBlock.iHorizontalSyncPulse;
+    aTimings.iHorizontalBorderPixels = aDescBlock.iHorizontalBorder;
+    aTimings.iVerticalActiveLines = aDescBlock.iVerticalAddressableVideoPixels;
+    aTimings.iVerticalBlankingLines = aDescBlock.iVerticalBlanking;
+    aTimings.iVerticalSyncOffsetLinesField1 = aDescBlock.iVerticalFrontPorch;
+    aTimings.iVerticalSyncPulseWidthLinesField1 = aDescBlock.iVerticalSyncPulse;
+    aTimings.iVerticalBorderLinesField1 = aDescBlock.iVerticalBorder;
+    aTimings.iInterlaced = aDescBlock.iInterlacedVideo;
+    if( aDescBlock.iSyncs ==
+        EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsNegative )
+        {
+        aTimings.iVerticalSyncPolarity = EFalse;
+        aTimings.iHorizontalSyncPolarity = EFalse;
+        }
+    else if( aDescBlock.iSyncs ==
+        EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsPositive )
+        {
+        aTimings.iVerticalSyncPolarity = EFalse;
+        aTimings.iHorizontalSyncPolarity = ETrue;
+        }
+    else if( aDescBlock.iSyncs ==
+        EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsNegative )
+        {
+        aTimings.iVerticalSyncPolarity = ETrue;
+        aTimings.iHorizontalSyncPolarity = EFalse;
+        }
+    else if( aDescBlock.iSyncs ==
+        EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsPositive )
+        {
+        aTimings.iVerticalSyncPolarity = ETrue;
+        aTimings.iHorizontalSyncPolarity = ETrue;
+        }
+    aTimings.iPixelRepeat = 1;
+    aTimings.iRightBottomCorner.iX = aDescBlock.iHorizontalAddressableVideoPixels;
+    aTimings.iRightBottomCorner.iY = aDescBlock.iVerticalAddressableVideoPixels;
+    aTimings.iImageAspectRatio = ResolveAspectRatio(
+        aTimings.iHorizontalActivePixels,
+        aTimings.iVerticalActiveLines );
+
+    // Fill the common attributes 
+    FillCommonHdmiDviTimings( aTimings );
+
+    TRACE_TIMINGS( aTimings );
+    }
+
+//------------------------------------------------------------------------------
+// SetCeaModes
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetCeaModes( RArray<THdmiDviTimings>& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    TInt retVal(KErrNone);
+
+    // Use only CEA-861 extension parser
+    if( iExtensionParserPtr )
+        {
+        // Get parsed information
+        CCea861ExtEdidInformation* info =
+            iExtensionParserPtr->GetParsedInformation();
+        if( info )
+            {
+            // Go through all supported CEA modes
+            TCEA861VideoDataBlock* vdb = info->iShortVideoDescriptors;
+            THdmiDviTimings timings;
+            while( vdb )
+                {
+                // Get a timing item matched with the VIC mode
+                TInt index = vdb->iVIC - 1;
+                if( ( index >= 0 ) && ( index < KCEATimingCount ) )
+                    {
+                    const TTimingItem* item = TimingByIndex( index, ETimingModeCEA );
+                    if( item )
+                        {
+                        Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
+                        FillHdmiDviTimings( *item, timings );
+                        retVal = aTimings.Append( timings );
+                        ERROR_1( retVal, "Failed to append CEA timing: %S in array", item->iTimingName );
+                        }
+                    else
+                        {
+                        ERROR_1( KErrArgument, "CEA timing item not found for VIC mode: %d", index );
+                        }
+                    }
+                vdb = vdb->iNext;
+                }
+            }
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModes
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetDmtModes( RArray<THdmiDviTimings>& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    TInt retVal(KErrNone);
+    
+    // Check established timings 1 and 2
+    retVal = SetDmtModesFromEstablishedTimings( aTimings );
+    
+    if( KErrNone == retVal )
+        {
+        // Check standard timings
+        retVal = SetDmtModesFromStandardTimings( aTimings );
+        
+        if( KErrNone == retVal )
+            {
+            // Check timing descriptors
+            retVal = SetDmtModesFromTimingDescriptors( aTimings );        
+            }
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModesFromEstablishedTimings
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetDmtModesFromEstablishedTimings(
+    RArray<THdmiDviTimings>& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    TUint8 timings = 0;
+    TUint16 width = 0;
+    TUint16 height = 0;
+    TUint16 refreshRate = 0;
+    TInt retVal(KErrNone);
+    
+    // Established timings 1
+    // Bits 4, 6 and 7 left out since these does not match to DMT
+    timings = iEdidParserPtr->GetEstablishedTimings1();
+    if( timings & E800x600_60Hz ) // Bit 0
+        {
+        width = 800;
+        height = 600;
+        refreshRate = 60;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E800x600_56Hz ) // Bit 1
+        {
+        width = 800;
+        height = 600;
+        refreshRate = 56;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E640x480_75Hz ) // Bit 2
+        {
+        width = 640;
+        height = 480;
+        refreshRate = 75;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E640x480_72Hz ) // Bit 3
+        {
+        width = 640;
+        height = 480;
+        refreshRate = 72;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E640x480_60Hz ) // Bit 5
+        {
+        width = 640;
+        height = 480;
+        refreshRate = 60;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+
+    // Established timings 2
+    // Bit 5 left out since it does not match to DMT
+    timings = iEdidParserPtr->GetEstablishedTimings2();
+    if( timings & E1280x1024_75Hz ) // Bit 0
+        {
+        width = 1280;
+        height = 1024;
+        refreshRate = 75;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E1024x768_75Hz ) // Bit 1
+        {
+        width = 1024;
+        height = 768;
+        refreshRate = 75;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E1024x768_70Hz ) // Bit 2
+        {
+        width = 1280;
+        height = 768;
+        refreshRate = 70;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E1024x768_60Hz ) // Bit 3
+        {
+        width = 1280;
+        height = 768;
+        refreshRate = 60;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E1024x768_87Hz ) // Bit 4
+        {
+        width = 1280;
+        height = 768;
+        refreshRate = 87;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E800x600_75Hz ) // Bit 6
+        {
+        width = 800;
+        height = 600;
+        refreshRate = 75;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    if( timings & E800x600_72Hz ) // Bit 7
+        {
+        width = 800;
+        height = 600;
+        refreshRate = 72;
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModesFromStandardTimings
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetDmtModesFromStandardTimings(
+    RArray<THdmiDviTimings>& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    // One timing descriptor is specified in two bytes:
+    // 26h:
+    // -------------------------------------------------------------------------
+    //      01h-FFh:
+    //      Horizontal addressable pixels: Value Stored (in hex) =
+    //          (Horizontal addressable pixels / 8) – 31
+    //      Range: 256 pixels -> 2288 pixels, in increments of 8 pixels
+    //      --------------------------------------------------------------------
+    //      00h:
+    //      Reserved. Do not use!
+    // -------------------------------------------------------------------------
+    // 27h: 
+    // -------------------------------------------------------------------------
+    //      Bits 7 - 6:
+    //      Image Aspect Ratio:
+    //      0 0 _ _ _ _ _ _ (16 : 10 AR)
+    //      0 1 _ _ _ _ _ _ ( 4 : 3  AR)
+    //      1 0 _ _ _ _ _ _ ( 5 : 4  AR)
+    //      1 1 _ _ _ _ _ _ (16 : 9  AR)
+    //      --------------------------------------------------------------------
+    //      Bits 0 - 5:
+    //      Field Refresh Rate: Value Stored (in binary) =
+    //          Field Refresh Rate (in Hz) – 60
+    //      Range: 60 Hz -> 123Hz
+    // -------------------------------------------------------------------------
+    // 27h: 
+    // 28h: 
+    // -------------------------------------------------------------------------
+    // etc.
+
+    // There can be up to 8 standard timings (2 bytes * 8)
+    const TInt KStandardTimingBytes = 16;
+    const TUint KRefreshRateMask = 0x3F; // --XXXXXX
+    TInt retVal(KErrNone);
+    
+    TUint16 width = 0;
+    TUint16 height = 0;
+    TUint16 refreshRate = 0;
+    TUint8 byte1 = 0;
+    TUint8 byte2 = 0;
+    for( TInt i = 0; i < KStandardTimingBytes; i += 2 )
+        {
+        byte1 = iEdidParserPtr->GetStandardTimings( i );
+        byte2 = iEdidParserPtr->GetStandardTimings( i + 1 );
+        
+        // Horizontal pixels
+        width = ( byte1 + 31 ) * 8;
+        
+        // Aspect ratio & vertical lines
+        if( !( byte2 & KBit7 ) && !( byte2 & KBit6 ) )
+            {
+            // 16 : 10 AR
+            height = ( width * 10 ) / 16;
+            }
+        else if( !( byte2& KBit7 ) && ( byte2 & KBit6 ) )
+            {
+            // 4 : 3 AR
+            height = ( width * 3 ) / 4;
+            }
+        else if( ( byte2 & KBit7 ) && !( byte2& KBit6 ) )
+            {
+            // 5 : 4 AR
+            height = ( width * 4 ) / 5;
+            }
+        else // ( byte2 & KBit7 ) && ( byte2 & KBit6 )
+            {
+            // 16 : 9 AR
+            height = ( width * 9 ) / 16;
+            }
+        
+        // Refresh rate
+        // Nullify bits 6 and 7
+        byte2 = byte2 & KRefreshRateMask;
+        refreshRate = byte2 + 60;
+        
+        // Set timing item by resolution
+        retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModesFromTimingDescriptors
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetDmtModesFromTimingDescriptors(
+    RArray<THdmiDviTimings>& aTimings ) const
+    {
+    FUNC_LOG;
+    
+    // 1st 18 byte timing descriptor
+    THdmiDviTimings timings;
+    TInt retVal(KErrNone);
+    
+    TEdidDescriptorBlock first =
+        iEdidParserPtr->GetDescriptorBlock( EEdidDescriptorBlockFirstTiming );
+    FillHdmiDviTimings( first, timings );
+    retVal = aTimings.Append( timings );
+    ERROR( retVal, "Failed to append 1st timing descriptor in array" );
+
+    if( KErrNone == retVal )
+        {
+        // 2nd 18 byte timing descriptor
+        Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
+        TEdidDescriptorBlock second =
+            iEdidParserPtr->GetDescriptorBlock( EEdidDescriptorBlockSecondTiming );
+        FillHdmiDviTimings( second, timings );
+        retVal = aTimings.Append( timings );
+        ERROR( retVal, "Failed to append 2nd timing descriptor in array" );
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// TimingByIndex
+//------------------------------------------------------------------------------
+//
+const TTimingItem* CEDIDHandler::TimingByIndex( TInt aIndex,
+    TTimingModeType aType ) const
+    {
+    FUNC_LOG;
+    
+    const TTimingItem* item = NULL;
+    if( aIndex >= 0 )
+        {
+        if( aType == ETimingModeCEA )
+            {
+            if( aIndex < KCEATimingCount )
+                {
+                item = &KCEATimings[aIndex];
+                }
+            }
+        else
+            {
+            if( aIndex < KDMTTimingCount )
+                {
+                item = &KDMTTimings[aIndex];
+                }
+            }
+        }
+
+    return item;
+    }
+
+//------------------------------------------------------------------------------
+// TimingByResolution
+//------------------------------------------------------------------------------
+//
+const TTimingItem* CEDIDHandler::TimingByResolution( TUint16 aWidth,
+    TUint16 aHeight,
+    TUint16 aRefreshRate,
+    TTimingModeType aType ) const
+    {
+    FUNC_LOG;
+
+    const TTimingItem* item = NULL;
+    if( aType == ETimingModeCEA )
+        {
+        // CEA mode
+        for( TInt i = 0; i < KCEATimingCount; i++ )
+            {
+            item = &KCEATimings[i];
+            if( item->iWidth == aWidth &&
+                item->iHeight == aHeight &&
+                item->iFieldRate == aRefreshRate )
+                {
+                // Item found, break
+                break;
+                }
+            item = NULL;
+            }
+        }
+    else
+        {
+        // DMT mode
+        for( TInt i = 0; i < KDMTTimingCount; i++ )
+            {
+            item = &KDMTTimings[i];
+            if( item->iWidth == aWidth &&
+                item->iHeight == aHeight &&
+                item->iFieldRate == aRefreshRate )
+                {
+                // Item found, break
+                break;
+                }
+            item = NULL;
+            }
+        }
+
+    return item;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModeByResolution
+//------------------------------------------------------------------------------
+//
+TInt CEDIDHandler::SetDmtModeByResolution( RArray<THdmiDviTimings>& aTimings,
+    TUint16 aWidth,
+    TUint16 aHeight,
+    TUint16 aRefreshRate ) const
+    {
+    FUNC_LOG;
+    
+    TInt retVal(KErrNone);
+
+    const TTimingItem* item = TimingByResolution( aWidth,
+        aHeight, aRefreshRate, ETimingModeDMT );
+    if( item )
+        {
+        THdmiDviTimings timings;
+        FillHdmiDviTimings( *item, timings );
+        retVal = aTimings.Append( timings );
+        ERROR_1( retVal, "Failed to append DMT timing: %S in array",
+            item->iTimingName );
+        }
+    else
+        {
+        ERROR_3( KErrArgument, "DMT timing item not found for width: %d, height: %d, refresh rate: %d",
+            aWidth, aHeight, aRefreshRate );
+        }
+    
+    return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// SetDmtModeByResolution
+//------------------------------------------------------------------------------
+//
+TTvSettings::TAspectRatio CEDIDHandler::ResolveAspectRatio( TUint16 aWidth,
+    TUint16 aHeight ) const
+    {
+    FUNC_LOG;
+    
+    TTvSettings::TAspectRatio aspectRatio = TTvSettings::EUndefRatio;
+    TReal source = ( TReal )aWidth / ( TReal )aHeight;
+    TReal target = 0.0;
+    if( Math::Round( target, source, 3 ) == KErrNone )
+        {
+        if( target == K16d9 )
+            {
+            // 16:9
+            aspectRatio = TTvSettings::E16d9;
+            }
+        else if( target == K4d3 )
+            {
+            // 4:3
+            aspectRatio = TTvSettings::E4d3;
+            }
+        }
+    
+    return aspectRatio;
+    }
+
+//------------------------------------------------------------------------------
+// CalculateOverscan
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::CalculateOverscan( TPoint& aTLCorner,
+    TPoint& aBRCorner ) const
+    {
+    FUNC_LOG;
+
+    // No need to calculate if the screen size is zero
+    if( aBRCorner.iX > 0 && aBRCorner.iY > 0 )
+        {
+        // hOverscanPixels = ( ( Width * hOverscan ) + 50 ) / 20000
+        //
+        //  hOverscanPixels:
+        //      pixels which are needed to be added to top left X
+        //      pixels which are needed to be reduced from bottom right X
+        //  Width:
+        //      Horizontal resolution
+        //  hOverscan:
+        //      Horizontal overscan in percents (1% == 100)
+        //  50:
+        //      Used to round up possible decimals
+        //  20000:
+        //      Used to get rid of percentage multiplier and to get the overscan value
+        //      for one side
+        TInt hOverscanPixels = ( aBRCorner.iX * iHOverscan + 50 ) / 20000;
+        aTLCorner.iX = hOverscanPixels;
+        aBRCorner.iX = ( aBRCorner.iX - hOverscanPixels );
+        
+        // vOverscanPixels = ( ( Height * vOverscan ) + 50 ) / 20000
+        //
+        //  vOverscanPixels:
+        //      pixels which are needed to be added to top left Y
+        //      pixels which are needed to be reduced from bottom right Y
+        //  Height:
+        //      Horizontal resolution
+        //  vOverscan:
+        //      Vertical overscan in percents (1% == 100)
+        //  50:
+        //      Used to round up possible decimals
+        //  20000:
+        //      Used to get rid of percentage multiplier and to get the overscan value
+        //      for one side
+        TInt vOverscanPixels = ( aBRCorner.iY * iVOverscan + 50 ) / 20000;
+        aTLCorner.iY = vOverscanPixels;
+        aBRCorner.iY = ( aBRCorner.iY - vOverscanPixels );
+        }
+    }
+
+//------------------------------------------------------------------------------
+// CalculateOverscan
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::UpdateOverscanValues()
+    {
+    FUNC_LOG;
+
+    // Overscan from cenrep
+    TInt hOverscan = 0;
+    TInt vOverscan = 0;
+    CRepository* cenRep = NULL;
+    TInt err = KErrNone;
+    
+    TRAP( err, cenRep = CRepository::NewL( KCRUidTvoutSettings ) );
+    if( err == KErrNone )
+        {
+        
+        // Horizontal
+        err = cenRep->Get( KSettingsTvoutHorizontalOverscan, hOverscan );
+        if( err != KErrNone )
+            {
+            hOverscan = 0;
+            }
+        
+        // Vertical
+        err = cenRep->Get( KSettingsTvoutVerticalOverscan, vOverscan );
+        if( err != KErrNone )
+            {
+            vOverscan = 0;
+            }
+        
+        // Cleanup
+        delete cenRep;
+        }
+    
+    // Update overscan values
+    iHOverscan = hOverscan;
+    iVOverscan = vOverscan;
+    }
+
+// ----------------------------------------------------------------------------
+// CEDIDHandler::FilterAvailableTvConfigList
+//
+// ----------------------------------------------------------------------------
+//
+TInt CEDIDHandler::FilterAvailableTvConfigList( RArray<THdmiDviTimings>& aHdmiConfigs )
+    {
+    FUNC_LOG;
+    
+	TUint supportedCount;
+	TInt  retVal( KErrNotFound );
+	TInt  availableCount( aHdmiConfigs.Count() );
+	RArray<TSupportedHdmiDviMode> supportedModes;
+
+	INFO_1( "HDMI CONFIGS --- From SINK -- Total : %d", availableCount );
+
+	retVal = iTVOutConfigForHDMI.GetSupportedHdmiModes( supportedModes );
+
+	if( KErrNone == retVal )
+		{
+		TInt availableIndex = 0;
+		TBool found( EFalse );
+		TBool defaultCEAmode( EFalse );
+		supportedCount = supportedModes.Count();
+		INFO_1( "HDMI CONFIGS --- From HW -- Total : %d", supportedCount );
+
+		INFO( "Filtered list -- START" );
+		while( availableIndex < availableCount )
+			{
+			found = EFalse;
+			
+			for( TInt supportedIndex = 0; (supportedIndex < supportedCount); supportedIndex++ )
+				{
+				// Check CEA mode
+				if( aHdmiConfigs[ availableIndex ].iCeaMode && 
+					(TSupportedHdmiDviMode::ECea == supportedModes[ supportedIndex ].iStandardModeType) &&
+					(aHdmiConfigs[ availableIndex ].iCeaMode == supportedModes[ supportedIndex ].iStandardMode) )
+					{
+					found = ETrue;
+					if( aHdmiConfigs[ availableIndex].iCeaMode == KDefaultCEAMode )
+					    {
+					    defaultCEAmode = ETrue;
+					    }
+					TRACE_TIMINGS( (aHdmiConfigs[ availableIndex ]) );
+					break;
+					}
+
+				// Check DMT mode
+				if( aHdmiConfigs[ availableIndex ].iDmtMode &&
+					(TSupportedHdmiDviMode::EDmt == supportedModes[ supportedIndex ].iStandardModeType) &&
+					(aHdmiConfigs[ availableIndex ].iDmtMode == supportedModes[ supportedIndex ].iStandardMode) )
+					{
+					found = ETrue;
+					TRACE_TIMINGS( (aHdmiConfigs[ availableIndex ]) );
+					break;
+					}
+				}
+
+			if( EFalse == found )
+				{
+				// Remove from the list
+				aHdmiConfigs.Remove( availableIndex );
+				availableCount--;
+				continue;
+				}
+
+			availableIndex++;
+			}
+		
+		    if( ( (KDefaultCEAModePhysImgAspRatioNr == iEdidParserPtr->GetAspectRatioLandscape()) 
+		            && (KDefaultCEAModePhysImgAspRatioDr == iEdidParserPtr->GetAspectRatioPortrait()) ) 
+		            && !defaultCEAmode )		    
+
+			{
+            THdmiDviTimings timings;
+            
+            // Get a timing item for default CEA Mode (1)
+            const TTimingItem* item = TimingByIndex( KDefaultCEAModeIndex, ETimingModeCEA );
+            if( item )
+                {
+                Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
+                FillHdmiDviTimings( *item, timings );
+                retVal = aHdmiConfigs.Append( timings );
+                ERROR( retVal, "Failed to append CEA timing in available config array" );
+                }
+			}
+
+		INFO( "Filtered list -- END" );
+		supportedModes.Close();
+		}
+
+	return retVal;
+    }
+
+//------------------------------------------------------------------------------
+// C++ constructor
+//------------------------------------------------------------------------------
+//
+CEDIDHandler::CEDIDHandler( MFSMForBody& aFSM,
+    CTVOutConfigForHDMI& aTVOutConfigForHDMI ) :
+    CActive( CActive::EPriorityLow ),
+    iFSM( aFSM ),
+    iTVOutConfigForHDMI( aTVOutConfigForHDMI ),
+    iRetryCounter( 0 ),
+    iRequestID( EUndefRequest )
+    {
+    FUNC_LOG;
+    }
+
+//------------------------------------------------------------------------------
+// ConstructL
+//------------------------------------------------------------------------------
+//
+void CEDIDHandler::ConstructL()
+    {
+    FUNC_LOG;
+    
+    INFO( "Creating Retry Timer object" );
+    User::LeaveIfError(iRetryTimer.CreateLocal());
+    
+    INFO( "Creating CDdcPortAccess object" );
+    iDdcPortAccess = CDdcPortAccess::NewL();
+
+    CActiveScheduler::Add( this );
+    }
+
+// ======== GLOBAL FUNCTIONS ========
+
+