--- 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