upnpsharing/upnpdlnaprofiler/src/upnpavsolverbase.cpp
branchnew development branch with rendering state machine and other goodies
changeset 38 5360b7ddc251
parent 0 7f85d04be362
--- a/upnpsharing/upnpdlnaprofiler/src/upnpavsolverbase.cpp	Fri Sep 17 08:31:21 2010 +0300
+++ b/upnpsharing/upnpdlnaprofiler/src/upnpavsolverbase.cpp	Mon Nov 01 12:37:49 2010 +0200
@@ -1,448 +1,492 @@
-/*
-* Copyright (c) 2006-2007 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:      Implementation of base DLNA profile resolver class for av 
-*                files.
-*
-*/
-
-
-
-
-
-
-// includes
-#include <badesca.h> // CDesC16ArrayFlat
-#include <3gplibrary/mp4lib.h>
-#include "upnpavsolverbase.h"
-
-_LIT( KComponentLogfile, "dlnaprofiler.txt");
-#include "upnplog.h"
-
-// constants
-_LIT8( KVideoMp4, "video/mp4" );
-
-_LIT( KMpeg4_p2_mp4_sp_l2_aac,      "MPEG4_P2_MP4_SP_L2_AAC" );
-_LIT( KMpeg4_p2_mp4_sp_aac,         "MPEG4_P2_MP4_SP_AAC" );
-_LIT( KMpeg4_p2_mp4_sp_vga_aac,     "MPEG4_P2_MP4_SP_VGA_AAC" );
-_LIT( KMpeg4_p2_mp4_sp_l5_aac,      "MPEG4_P2_MP4_SP_L5_AAC" );
-
-_LIT( KAvc_mp4_bl_cif15_aac,        "AVC_MP4_BL_CIF15_AAC" );
-_LIT( KAvc_mp4_bl_cif15_aac_520,    "AVC_MP4_BL_CIF15_AAC_520" );
-
-const TUint32 KSimpleProfileLevel2 = 0x02;
-const TUint32 KSimpleProfileLevel3 = 0x03;
-const TUint32 KSimpleProfileLevel4 = 0x04;
-const TUint32 KSimpleProfileLevel5 = 0x05;
-
-
-const mp4_u32 KMaxXResolutionCif = 352;
-const mp4_u32 KMaxYResolutionCif = 288;
-const mp4_u32 KMaxXResolutionVga = 640;
-const mp4_u32 KMaxYResolutionVga = 480;
-
-//const TInt  KBitrateAverageToMaxFactor = 20;
-//const mp4_u32 KMaxBitrateCif520 = 520;
-//const mp4_u32 KMaxBitrateCif = 384;
-//const TUint32 KAdvancedSimpleProfileLevel1 = 0x91;
-//const TUint32 KAdvancedSimpleProfileLevel2 = 0x92;
-//const TUint32 KAdvancedSimpleProfileLevel3 = 0x93;
-//const TUint32 KAdvancedSimpleProfileLevel4 = 0x94;
-//const TUint32 KAvcBaseline1_2 = 12;
-
-/*
-===========================================================================
-Codec-specific details are explained here
-(for the part that is currently required by upnp framework)
-
-MPEG4 part2
-------------
-see ISO/IEC 14496-2, chapter 6.2.2 and annex G
-(http://akuvian.org/src/x264/ISO-IEC-14496-2_2001_MPEG4_Visual.pdf.gz)
-
-32 bit: visual_object_sequence_start_code (not interesting)
-8 bit: profile_and_level_indication, where:
-   0x02 = simple profile, level 2
-   0x03 = simple profile, level 3
-
-   0x04 = simple profile, level 4a
-   0x05 = simple profile, level 5
-   
-   0x91 = advanced simple profile, level 1
-   0x92 = advanced simple profile, level 2
-   0x93 = advanced simple profile, level 3
-   0x94 = advanced simple profile, level 4
-   
-...
-
-MPEG4 part 10 (AVC)
--------------------
-see ISO/IEC 14496-15, chapter 5.2.4.1.1
-(http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=43178)
-
-8 bit: version (not interesting)
-8 bit: AVC profile indication, where
-   0x42 = AVC baseline
-   0x4D = AVC main
-   0x58 = AVC extended
-8 bit: compatibility flags (not interesting)
-8 bit: AVC level indication, where
-   10 = baseline level 1.0
-   11 = baseline level 1.1
-   12 = baseline level 1.2
-   13 = baseline level 1.3
-   20 = baseline level 2.0
-   21 = baseline level 2.1
-   22 = baseline level 2.2
-   30 = baseline level 3.0
-...
-
-===========================================================================
-*/
-
-
-// --------------------------------------------------------------------------
-// CUpnpAvSolverBase C++ constructor
-// --------------------------------------------------------------------------
-//
-CUpnpAvSolverBase::CUpnpAvSolverBase()
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase constructor" );
-    }
-    
-// --------------------------------------------------------------------------
-// CUpnpAvSolverBase::ConstructL
-// --------------------------------------------------------------------------
-//
-void CUpnpAvSolverBase::ConstructL()
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::ConstructL" );
-    }
-
-
-// --------------------------------------------------------------------------
-// CUpnpAvSolverBase::NewL
-// --------------------------------------------------------------------------
-//
-CUpnpAvSolverBase* CUpnpAvSolverBase::NewL()
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::NewL" );
-    CUpnpAvSolverBase* self = CUpnpAvSolverBase::NewLC();
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-
-// --------------------------------------------------------------------------
-// CUpnpAvSolverBase::NewLC
-// --------------------------------------------------------------------------
-//
-CUpnpAvSolverBase* CUpnpAvSolverBase::NewLC()
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::NewLC" );
-    CUpnpAvSolverBase* self = new( ELeave ) CUpnpAvSolverBase;
-    CleanupStack::PushL( self );
-    self->ConstructL();
-    return self;
-    }
-
-
-// --------------------------------------------------------------------------
-// CUpnpAvSolverBase destructor
-// --------------------------------------------------------------------------
-//
-CUpnpAvSolverBase::~CUpnpAvSolverBase()
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase destructor" );
-    }
-
-// --------------------------------------------------------------------------
-// From class MUpnpProfiler.
-// SupportedProfilesL returns DLNA profiles that are currently supported.
-// --------------------------------------------------------------------------
-//
-TInt CUpnpAvSolverBase::SupportedProfilesL( 
-                                        CDesC16ArrayFlat* aProfiles ) const
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::SupportedProfilesL" );
-    TInt retval = KErrNone;
-    
-        if ( !aProfiles ) 
-        {
-        // Invalid parameter
-        retval = KErrArgument;
-        }
-    else 
-        {
-        // append all new profiles recognized by this solver
-        // do not allow duplicates
-        TInt tempPos = KErrNotFound;
-
-        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_l2_aac(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KMpeg4_p2_mp4_sp_l2_aac() );
-            }
-        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_aac(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KMpeg4_p2_mp4_sp_aac() );
-            }
-        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_vga_aac(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KMpeg4_p2_mp4_sp_vga_aac() );
-            }
-        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_l5_aac(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KMpeg4_p2_mp4_sp_l5_aac() );
-            }
-        if ( aProfiles->Find( KAvc_mp4_bl_cif15_aac(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KAvc_mp4_bl_cif15_aac() );
-            }
-        if ( aProfiles->Find( KAvc_mp4_bl_cif15_aac_520(), 
-                              tempPos, 
-                              ECmpFolded ) ) 
-            {
-            aProfiles->AppendL( KAvc_mp4_bl_cif15_aac_520() );
-            }
-        }
-
-    return retval;
-    }
-    
-// --------------------------------------------------------------------------
-// From class MUpnpProfiler.
-// ProfileForFileL is for resolving a DLNA profile of a given file. Besides 
-// of file name, also mime type of the file is passed as a parameter in order
-// to avoid re-opening the file.
-// --------------------------------------------------------------------------
-//
-HBufC* CUpnpAvSolverBase::ProfileForFileL( const TDesC& /*aFilename*/,
-                                           const TDesC8& aMimetype, 
-                                           RFile& aFile )
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::\
-ProfileForFileL" );
-    HBufC* retval = NULL;
-
-
-    
-    if ( aMimetype.Compare( KVideoMp4() ) == 0 ) 
-        {
-        GetVideoFileInformationL( aFile );
-
-
-
-        if ( iVideoType == MP4_TYPE_MPEG4_VIDEO &&
-             iAudioType == MP4_TYPE_MPEG4_AUDIO )
-            {
-            // MPEG4 level 2
-
-            TUint32 level = iCodecInfo.iData[1] & 0x000000FF;
-            
-            __LOG1( "[CUpnpAvSolverBase] CUpnpAvSolverBase::\
-            GetVideoFileInformationL level %d", level );
-
-            if ( level == KSimpleProfileLevel2 )
-                {
-                // Simple profile level 2
-                retval = HBufC::NewL( KMpeg4_p2_mp4_sp_l2_aac().Length() );
-                retval->Des().Append( KMpeg4_p2_mp4_sp_l2_aac() ); 
-                }
-            else if ( level == KSimpleProfileLevel3 )
-                {
-                // Simple profile level 3
-                if ( iVideoResolutionX <= KMaxXResolutionCif &&
-                    iVideoResolutionY <= KMaxYResolutionCif )
-                    {
-                    // resolution below CIF standard
-                    retval = HBufC::NewL( KMpeg4_p2_mp4_sp_aac().Length() );
-                    retval->Des().Append( KMpeg4_p2_mp4_sp_aac() ); 
-                    }
-                else if ( iVideoResolutionX <= KMaxXResolutionVga &&
-                    iVideoResolutionY <= KMaxYResolutionVga )
-                    {
-                    // resolution below VGA standard
-                    retval = HBufC::NewL(
-                        KMpeg4_p2_mp4_sp_vga_aac().Length() );
-                    retval->Des().Append( KMpeg4_p2_mp4_sp_vga_aac() ); 
-                    }
-                }
-
-            else if ( level == KSimpleProfileLevel4 )
-                {
-                // Simple profile level 4a
-                retval = HBufC::NewL( KMpeg4_p2_mp4_sp_vga_aac().Length() );
-                retval->Des().Append( KMpeg4_p2_mp4_sp_vga_aac() ); 
-                }
-            
-            else if ( level == KSimpleProfileLevel5 )
-                {
-                // Simple profile level 5
-                retval = HBufC::NewL( KMpeg4_p2_mp4_sp_l5_aac().Length() );
-                retval->Des().Append( KMpeg4_p2_mp4_sp_l5_aac() ); 
-                }                
-                
-/*
-
-Not needed yet:
-
-            else if ( level == KAdvancedSimpleProfileLevel1 ||
-                level == KAdvancedSimpleProfileLevel2 ||
-                level == KAdvancedSimpleProfileLevel3 ||
-                level == KAdvancedSimpleProfileLevel4 )
-                {
-                // Advanced simple profile (levels 1-4)
-                retval = HBufC::NewL( KMpeg4_p2_mp4_sp_l5_aac().Length() );
-                retval->Des().Append( KMpeg4_p2_mp4_sp_l5_aac() ); 
-                }
-*/
-                
-            }
-            
-
-/*
-  Temporary solution, based on AVC video resolution. 
-  iLevel should be used instead, see above Mp4 P2.
-*/
-        else if ( iVideoType == MP4_TYPE_AVC_PROFILE_BASELINE &&
-            iAudioType == MP4_TYPE_MPEG4_AUDIO )
-            {
-            // MPEG4 part 10 (AVC)
-            
-            	if (iVideoResolutionX <= KMaxXResolutionCif && 
-            		iVideoResolutionY <= KMaxYResolutionCif )
-            	{
-                    retval = HBufC::NewL( KAvc_mp4_bl_cif15_aac_520().Length() );
-                    retval->Des().Append( KAvc_mp4_bl_cif15_aac_520() );            		
-            	}
-        	
-            }
-            
-            
-
-        }
-           
-    return retval;
-    }
-
-
-// --------------------------------------------------------------------------
-// GetVideoFileInformationL is for resolving audio file attributes by using 
-// CMdaAudioConvertUtility. 
-// --------------------------------------------------------------------------
-//
-TInt CUpnpAvSolverBase::GetVideoFileInformationL( RFile& aFile )
-    {
-    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::\
-GetVideoFileInformationL" );
-    TInt retval = KErrNone;
-
-    // video description
-    mp4_u32 videolength;
-    mp4_u32 videotimescale;
-    // audio params
-    mp4_u32 audiolength = 0;
-    mp4_u8 audioframes = 0;
-    mp4_u32 audiotimescale = 0;
-    mp4_u32 audiobitrate = 0;
-    // stream params
-    mp4_u32 streamsize = 0;
-
-    // reset old values 
-    iStreamAverageBitrate = 0;
-
-    MP4Handle myMp4Handle;
-    
-    // try open mp4 file handle
-    MP4Err openerr = MP4ParseOpenFileHandle( &myMp4Handle, &aFile );
-    if ( openerr == MP4_OK )
-        {
-        MP4Err requesterr = MP4ParseRequestVideoDescription(
-                                            myMp4Handle,
-                                            &videolength,
-                                            &iVideoFramerate,
-                                            &iVideoType,
-                                            &iVideoResolutionX,
-                                            &iVideoResolutionY,
-                                            &videotimescale );
-        if ( requesterr != MP4_OK )
-            {
-            MP4ParseClose( myMp4Handle );
-            User::Leave( KErrGeneral );
-            }
-
-
-        requesterr = MP4ParseRequestAudioDescription( 
-                                            myMp4Handle, 
-                                            &audiolength, 
-                                            &iAudioType,
-                                            &audioframes, 
-                                            &audiotimescale, 
-                                            &audiobitrate );
-        if ( requesterr != MP4_OK )
-            {
-            MP4ParseClose( myMp4Handle );
-            User::Leave( KErrGeneral );
-            }
-
-        requesterr = MP4ParseRequestStreamDescription(
-                                            myMp4Handle, 
-                                            &streamsize, 
-                                            &iStreamAverageBitrate );
-
-
-        if ( requesterr != MP4_OK )
-            {
-            MP4ParseClose( myMp4Handle );
-            User::Leave( KErrGeneral );
-            }
-
-        TMP4DecoderSpecificInfo iDecoderInfo;
-        mp4_u32 decoderInfoSize;
-
-        requesterr = MP4ParseReadVideoDecoderSpecificInfo(
-                                            myMp4Handle,
-                                            (mp4_u8*)&iDecoderInfo,
-                                            sizeof( iDecoderInfo ),
-                                            &decoderInfoSize );
-       
-
-		iCodecInfo = iDecoderInfo;
-        // close mp4 file handle
-        MP4Err closeerr = MP4ParseClose( myMp4Handle );
-        if ( closeerr ) 
-            {
-            User::Leave( KErrGeneral );
-            }
-        }
-    else 
-        {
-        // can not open file
-        User::Leave( KErrBadHandle );
-        }
-    
-    return retval;
-    }
-
-    
-// end of file
+/*
+* Copyright (c) 2006-2007 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:      Implementation of base DLNA profile resolver class for av 
+*                files.
+*
+*/
+
+
+
+
+
+
+// includes
+#include <badesca.h> // CDesC16ArrayFlat
+#include <3gplibrary/mp4lib.h> 
+#include "upnpavsolverbase.h"
+
+_LIT( KComponentLogfile, "dlnaprofiler.txt");
+#include "upnplog.h"
+
+// constants
+_LIT8( KVideoMp4, "video/mp4" );
+
+_LIT( KMpeg4_p2_mp4_sp_l2_aac,      "MPEG4_P2_MP4_SP_L2_AAC" );
+_LIT( KMpeg4_p2_mp4_sp_aac,         "MPEG4_P2_MP4_SP_AAC" );
+_LIT( KMpeg4_p2_mp4_sp_vga_aac,     "MPEG4_P2_MP4_SP_VGA_AAC" );
+_LIT( KMpeg4_p2_mp4_asp_l4_so_aac,  "MPEG4_P2_MP4_ASP_L4_SO_AAC" );
+_LIT( KMpeg4_p2_mp4_sp_l5_aac,      "MPEG4_P2_MP4_SP_L5_AAC" );
+
+_LIT( KAvc_mp4_bl_cif15_aac,        "AVC_MP4_BL_CIF15_AAC" );
+_LIT( KAvc_mp4_bl_cif15_aac_520,    "AVC_MP4_BL_CIF15_AAC_520" );
+
+_LIT( KAvc_mp4_mp_hd_720p_aac,      "AVC_MP4_MP_HD_720p_AAC" );
+_LIT( KAvc_mp4_hp_hd_aac,           "AVC_MP4_HP_HD_AAC" );
+
+_LIT( KAvc_mp4_bl_l31_hd_aac,       "AVC_MP4_BL_L31_HD_AAC" );
+
+const TUint32 KSimpleProfileLevel2 = 0x02;
+const TUint32 KSimpleProfileLevel3 = 0x03;
+const TUint32 KSimpleProfileLevel4 = 0x04;
+const TUint32 KSimpleProfileLevel5 = 0x05;
+
+
+const mp4_u32 KMaxXResolutionCif = 352;
+const mp4_u32 KMaxYResolutionCif = 288;
+const mp4_u32 KMaxXResolutionVga = 640;
+const mp4_u32 KMaxYResolutionVga = 480;
+
+const TUint32 KAvcLevel31 = 31;
+const TUint32 KAvcLevel40 = 40;
+
+//const TInt  KBitrateAverageToMaxFactor = 20;
+//const mp4_u32 KMaxBitrateCif520 = 520;
+//const mp4_u32 KMaxBitrateCif = 384;
+//const TUint32 KAdvancedSimpleProfileLevel1 = 0x91;
+//const TUint32 KAdvancedSimpleProfileLevel2 = 0x92;
+//const TUint32 KAdvancedSimpleProfileLevel3 = 0x93;
+//const TUint32 KAdvancedSimpleProfileLevel4 = 0x94;
+//const TUint32 KAvcBaseline1_2 = 12;
+
+/*
+===========================================================================
+Codec-specific details are explained here
+(for the part that is currently required by upnp framework)
+
+MPEG4 part2
+------------
+see ISO/IEC 14496-2, chapter 6.2.2 and annex G
+(http://akuvian.org/src/x264/ISO-IEC-14496-2_2001_MPEG4_Visual.pdf.gz)
+
+32 bit: visual_object_sequence_start_code (not interesting)
+8 bit: profile_and_level_indication, where:
+   0x02 = simple profile, level 2
+   0x03 = simple profile, level 3
+
+   0x04 = simple profile, level 4a
+   0x05 = simple profile, level 5
+   
+   0x91 = advanced simple profile, level 1
+   0x92 = advanced simple profile, level 2
+   0x93 = advanced simple profile, level 3
+   0x94 = advanced simple profile, level 4
+   
+...
+
+MPEG4 part 10 (AVC)
+-------------------
+see ISO/IEC 14496-15, chapter 5.2.4.1.1
+(http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=43178)
+
+8 bit: version (not interesting)
+8 bit: AVC profile indication, where
+   0x42 = AVC baseline
+   0x4D = AVC main
+   0x58 = AVC extended
+8 bit: compatibility flags (not interesting)
+8 bit: AVC level indication, where
+   10 = baseline level 1.0
+   11 = baseline level 1.1
+   12 = baseline level 1.2
+   13 = baseline level 1.3
+   20 = baseline level 2.0
+   21 = baseline level 2.1
+   22 = baseline level 2.2
+   30 = baseline level 3.0
+...
+
+===========================================================================
+*/
+
+
+// --------------------------------------------------------------------------
+// CUpnpAvSolverBase C++ constructor
+// --------------------------------------------------------------------------
+//
+CUpnpAvSolverBase::CUpnpAvSolverBase()
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase constructor" );
+    }
+    
+// --------------------------------------------------------------------------
+// CUpnpAvSolverBase::ConstructL
+// --------------------------------------------------------------------------
+//
+void CUpnpAvSolverBase::ConstructL()
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::ConstructL" );
+    }
+
+
+// --------------------------------------------------------------------------
+// CUpnpAvSolverBase::NewL
+// --------------------------------------------------------------------------
+//
+CUpnpAvSolverBase* CUpnpAvSolverBase::NewL()
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::NewL" );
+    CUpnpAvSolverBase* self = CUpnpAvSolverBase::NewLC();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// --------------------------------------------------------------------------
+// CUpnpAvSolverBase::NewLC
+// --------------------------------------------------------------------------
+//
+CUpnpAvSolverBase* CUpnpAvSolverBase::NewLC()
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::NewLC" );
+    CUpnpAvSolverBase* self = new( ELeave ) CUpnpAvSolverBase;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// --------------------------------------------------------------------------
+// CUpnpAvSolverBase destructor
+// --------------------------------------------------------------------------
+//
+CUpnpAvSolverBase::~CUpnpAvSolverBase()
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase destructor" );
+    }
+
+// --------------------------------------------------------------------------
+// From class MUpnpProfiler.
+// SupportedProfilesL returns DLNA profiles that are currently supported.
+// --------------------------------------------------------------------------
+//
+TInt CUpnpAvSolverBase::SupportedProfilesL( 
+                                        CDesC16ArrayFlat* aProfiles ) const
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::SupportedProfilesL" );
+    TInt retval = KErrNone;
+    
+        if ( !aProfiles ) 
+        {
+        // Invalid parameter
+        retval = KErrArgument;
+        }
+    else 
+        {
+        // append all new profiles recognized by this solver
+        // do not allow duplicates
+        TInt tempPos = KErrNotFound;
+
+        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_l2_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KMpeg4_p2_mp4_sp_l2_aac() );
+            }
+        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KMpeg4_p2_mp4_sp_aac() );
+            }
+        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_vga_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KMpeg4_p2_mp4_sp_vga_aac() );
+            }
+        if ( aProfiles->Find( KMpeg4_p2_mp4_asp_l4_so_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KMpeg4_p2_mp4_asp_l4_so_aac() );
+            }
+        if ( aProfiles->Find( KMpeg4_p2_mp4_sp_l5_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KMpeg4_p2_mp4_sp_l5_aac() );
+            }
+        if ( aProfiles->Find( KAvc_mp4_bl_cif15_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KAvc_mp4_bl_cif15_aac() );
+            }
+        if ( aProfiles->Find( KAvc_mp4_bl_cif15_aac_520(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KAvc_mp4_bl_cif15_aac_520() );
+            }
+        if ( aProfiles->Find( KAvc_mp4_mp_hd_720p_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KAvc_mp4_mp_hd_720p_aac() );
+            }
+        if ( aProfiles->Find( KAvc_mp4_hp_hd_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KAvc_mp4_hp_hd_aac() );
+            }
+        if ( aProfiles->Find( KAvc_mp4_bl_l31_hd_aac(), 
+                              tempPos, 
+                              ECmpFolded ) ) 
+            {
+            aProfiles->AppendL( KAvc_mp4_bl_l31_hd_aac() );
+            }
+        }
+
+    return retval;
+    }
+    
+// --------------------------------------------------------------------------
+// From class MUpnpProfiler.
+// ProfileForFileL is for resolving a DLNA profile of a given file. Besides 
+// of file name, also mime type of the file is passed as a parameter in order
+// to avoid re-opening the file.
+// --------------------------------------------------------------------------
+//
+HBufC* CUpnpAvSolverBase::ProfileForFileL( const TDesC& /*aFilename*/,
+                                           const TDesC8& aMimetype, 
+                                           RFile& aFile )
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::ProfileForFileL" );
+    HBufC* retval = NULL;
+
+    if ( aMimetype.Compare( KVideoMp4() ) == 0 ) 
+        {
+        GetVideoFileInformationL( aFile );
+
+        __LOG2( "[UPnPDlnaProfiler] CUpnpAvSolverBase::ProfileForFileL: Video type = 0x%x, Audio type = 0x%x",
+            iVideoType, iAudioType );
+
+        if ( iVideoType == MP4_TYPE_MPEG4_VIDEO &&
+             iAudioType == MP4_TYPE_MPEG4_AUDIO )
+            {
+            // MPEG4 level 2
+
+            TUint32 level = iCodecInfo.iData[1] & 0x000000FF;
+            
+            __LOG1( "[CUpnpAvSolverBase] CUpnpAvSolverBase::\
+            GetVideoFileInformationL level %d", level );
+
+            if ( level == KSimpleProfileLevel2 )
+                {
+                // Simple profile level 2
+                retval = KMpeg4_p2_mp4_sp_l2_aac().AllocL(); 
+                }
+            else if ( level == KSimpleProfileLevel3 )
+                {
+                // Simple profile level 3
+                if ( iVideoResolutionX <= KMaxXResolutionCif &&
+                    iVideoResolutionY <= KMaxYResolutionCif )
+                    {
+                    // resolution below CIF standard
+                    retval = KMpeg4_p2_mp4_sp_aac().AllocL(); 
+                    }
+                else if ( iVideoResolutionX <= KMaxXResolutionVga &&
+                    iVideoResolutionY <= KMaxYResolutionVga )
+                    {
+                    // resolution below VGA standard
+                    retval = KMpeg4_p2_mp4_sp_vga_aac().AllocL(); 
+                    }
+                }
+
+            else if ( level == KSimpleProfileLevel4 )
+                {
+                // Simple profile level 4a
+                retval = KMpeg4_p2_mp4_asp_l4_so_aac().AllocL();
+                }
+            
+            else if ( level == KSimpleProfileLevel5 )
+                {
+                // Simple profile level 5
+                retval = KMpeg4_p2_mp4_sp_l5_aac().AllocL();
+                }                
+                
+/*
+
+Not needed yet:
+
+            else if ( level == KAdvancedSimpleProfileLevel1 ||
+                level == KAdvancedSimpleProfileLevel2 ||
+                level == KAdvancedSimpleProfileLevel3 ||
+                level == KAdvancedSimpleProfileLevel4 )
+                {
+                // Advanced simple profile (levels 1-4)
+                retval = HBufC::NewL( KMpeg4_p2_mp4_sp_l5_aac().Length() );
+                retval->Des().Append( KMpeg4_p2_mp4_sp_l5_aac() ); 
+                }
+*/
+                
+            }
+            
+
+/*
+  Temporary solution, based on AVC video resolution. 
+  iLevel should be used instead, see above Mp4 P2.
+*/
+        else if ( iVideoType == MP4_TYPE_AVC_PROFILE_BASELINE &&
+            iAudioType == MP4_TYPE_MPEG4_AUDIO )
+            {
+            // MPEG4 part 10 (AVC)
+            
+            	if (iVideoResolutionX <= KMaxXResolutionCif && 
+            		iVideoResolutionY <= KMaxYResolutionCif )
+            	{
+            	    retval = KAvc_mp4_bl_cif15_aac_520().AllocL();            		
+            	}
+            	else
+            	{
+                    TUint32 level = (iCodecInfo.iData[0] & 0xFF000000) >> 24;
+                    
+                    __LOG1( "[UPnPDlnaProfiler] CUpnpAvSolverBase::ProfileForFileL: Level = %d", level );
+                    
+                    if ( level == KAvcLevel31 )
+                    {
+                        retval = KAvc_mp4_bl_l31_hd_aac().AllocL();
+                    }
+            	}
+            }
+            
+        else if ( iVideoType == MP4_TYPE_AVC_PROFILE_MAIN && 
+                iAudioType == MP4_TYPE_MPEG4_AUDIO )
+            {
+            TUint32 level = (iCodecInfo.iData[0] & 0xFF000000) >> 24;
+            
+            if ( level == KAvcLevel31 )
+                {
+                retval = KAvc_mp4_mp_hd_720p_aac().AllocL();
+                }
+            }
+        }           
+    return retval;
+    }
+
+
+// --------------------------------------------------------------------------
+// GetVideoFileInformationL is for resolving audio file attributes by using 
+// CMdaAudioConvertUtility. 
+// --------------------------------------------------------------------------
+//
+TInt CUpnpAvSolverBase::GetVideoFileInformationL( RFile& aFile )
+    {
+    __LOG( "[UPnPDlnaProfiler] CUpnpAvSolverBase::GetVideoFileInformationL" );
+	
+    TInt retval = KErrNone;
+
+    // video description
+    mp4_u32 videolength;
+    mp4_u32 videotimescale;
+    // audio params
+    mp4_u32 audiolength = 0;
+    mp4_u8 audioframes = 0;
+    mp4_u32 audiotimescale = 0;
+    mp4_u32 audiobitrate = 0;
+    // stream params
+    mp4_u32 streamsize = 0;
+
+    // reset old values 
+    iStreamAverageBitrate = 0;
+
+    MP4Handle myMp4Handle;
+    
+    // try open mp4 file handle
+    MP4Err openerr = MP4ParseOpenFileHandle( &myMp4Handle, &aFile );
+    if ( openerr == MP4_OK )
+        {
+        MP4Err requesterr = MP4ParseRequestVideoDescription(
+                                            myMp4Handle,
+                                            &videolength,
+                                            &iVideoFramerate,
+                                            &iVideoType,
+                                            &iVideoResolutionX,
+                                            &iVideoResolutionY,
+                                            &videotimescale );
+        if ( requesterr != MP4_OK )
+            {
+            MP4ParseClose( myMp4Handle );
+            User::Leave( KErrGeneral );
+            }
+
+        requesterr = MP4ParseRequestAudioDescription( 
+                                            myMp4Handle, 
+                                            &audiolength, 
+                                            &iAudioType,
+                                            &audioframes, 
+                                            &audiotimescale, 
+                                            &audiobitrate );
+        if ( requesterr != MP4_OK )
+            {
+            MP4ParseClose( myMp4Handle );
+            User::Leave( KErrGeneral );
+            }
+
+        requesterr = MP4ParseRequestStreamDescription(
+                                            myMp4Handle, 
+                                            &streamsize, 
+                                            &iStreamAverageBitrate );
+
+
+        if ( requesterr != MP4_OK )
+            {
+            MP4ParseClose( myMp4Handle );
+            User::Leave( KErrGeneral );
+            }
+
+        TMP4DecoderSpecificInfo iDecoderInfo;
+        mp4_u32 decoderInfoSize;
+
+        requesterr = MP4ParseReadVideoDecoderSpecificInfo(
+                                            myMp4Handle,
+                                            (mp4_u8*)&iDecoderInfo,
+                                            sizeof( iDecoderInfo ),
+                                            &decoderInfoSize );
+        if ( requesterr != MP4_OK )
+            {
+            MP4ParseClose( myMp4Handle );
+            User::Leave( KErrGeneral );
+            }
+
+		iCodecInfo = iDecoderInfo;
+        // close mp4 file handle
+        MP4Err closeerr = MP4ParseClose( myMp4Handle );
+        if ( closeerr ) 
+            {
+            User::Leave( KErrGeneral );
+            }
+        }
+    else 
+        {
+        // can not open file
+        User::Leave( KErrBadHandle );
+        }
+    
+    return retval;
+    }
+
+    
+// end of file