diff -r 3785f754ee62 -r 5360b7ddc251 upnpsharing/upnpdlnaprofiler/src/upnpresresolver.cpp --- a/upnpsharing/upnpdlnaprofiler/src/upnpresresolver.cpp Fri Sep 17 08:31:21 2010 +0300 +++ b/upnpsharing/upnpdlnaprofiler/src/upnpresresolver.cpp Mon Nov 01 12:37:49 2010 +0200 @@ -1,440 +1,511 @@ -/* -* 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 file of CUpnpResResolver class. -* CUpnpResResolver is a class used for resolving res field -* attributes for a given file. -* -*/ - - - - - - -// system includes -#include // RFile -#include // RApaLsSession -#include // CUpnpDlnaProtocolInfo -#include // CImageDecoder -#include // ContentAccess -#include <3gplibrary/mp4lib.h> // MP4ParseRequestAudioDescription -#include // EscapeUtils::ConvertFromUnicodeToUtf8L - -// user includes -#include "upnpresresolver.h" -#include "upnpdlnaprofiler.h" -#include "upnpresparameters.h" - -_LIT( KComponentLogfile, "dlnaprofiler.txt"); -#include "upnplog.h" - -// constants -_LIT8( KHttpGet8, "http-get" ); -_LIT8( KStar8, "*" ); - -const TInt KMicrosecondsInSecond = 1000000; -const TInt KMilliSecondsInSecond = 1000; - -// ======== LOCAL FUNCTIONS ======== -// NONE - -// ======== MEMBER FUNCTIONS ======== - -// -------------------------------------------------------------------------- -// CUpnpResResolver C++ constructor -// -------------------------------------------------------------------------- -// -CUpnpResResolver::CUpnpResResolver() : iDuration(0) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver constructor" ); - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::ConstructL -// -------------------------------------------------------------------------- -// -void CUpnpResResolver::ConstructL() - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::ConstructL" ); - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::NewL -// -------------------------------------------------------------------------- -// -EXPORT_C CUpnpResResolver* CUpnpResResolver::NewL() - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::NewL" ); - CUpnpResResolver* self = CUpnpResResolver::NewLC(); - CleanupStack::Pop( self ); - return self; - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::NewLC -// -------------------------------------------------------------------------- -// -EXPORT_C CUpnpResResolver* CUpnpResResolver::NewLC() - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::NewLC" ); - CUpnpResResolver* self = new( ELeave ) CUpnpResResolver; - CleanupStack::PushL( self ); - self->ConstructL(); - return self; - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver destructor -// -------------------------------------------------------------------------- -// -CUpnpResResolver::~CUpnpResResolver() - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver destructor" ); - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetResParametersL -// -------------------------------------------------------------------------- -// -EXPORT_C CUpnpResParameters* CUpnpResResolver::GetResParametersL( - const TDesC& aFilename ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetResParametersL" ); - // check that aFileName is reasonable - if ( aFilename.Length() <= 0 ) - { - User::Leave( KErrArgument ); - } - - // Create object that will be returned. - CUpnpResParameters* retval = CUpnpResParameters::NewLC(); - - // try to open file specified by aFileName - RFs fsSession; - User::LeaveIfError( fsSession.Connect() ); // connect session - CleanupClosePushL( fsSession ); - // without calling ShareProtected() RApaLsSession::RecognizeData - // does not work (leaves with KErrBadHandle). - fsSession.ShareProtected(); - - RFile file; - User::LeaveIfError( file.Open( fsSession, - aFilename, - EFileShareReadersOrWriters|EFileRead ) ); - CleanupClosePushL( file ); - - // Obtain mimetype of the file - HBufC8* mimetype = GetMimetypeL( file ); - CleanupStack::PushL( mimetype ); - retval->SetMimetypeL( *mimetype ); - - // Obtain file size - TInt filesize = GetFileSizeL( file ); - retval->SetFileSize( filesize ); - - // Obtain duration for video&audio files and resolution for images. - TSize imageResolution( KErrNotFound, KErrNotFound ); - if ( mimetype->Left( KMimeStartLength ).Compare( KVideo() ) == 0 ) - { - GetVideoDurationL( file ); - retval->SetDurationInSeconds( iDuration.Int64() ); - } - else if ( mimetype->Left( KMimeStartLength ).Compare( KAudio() ) == 0 ) - { - GetAudioDurationL( aFilename ); - retval->SetDurationInSeconds( - iDuration.Int64() / KMicrosecondsInSecond ); - } - else if ( mimetype->Left( KMimeStartLength ).Compare( KImage() ) == 0 ) - { - TRAPD( err, imageResolution = GetImageResolutionL( file, - *mimetype ) ); - if ( !err ) - { - retval->SetResolution( imageResolution ); - } - } - - // Construct CUpnpDlnaProtocolInfo object. - CUpnpDlnaProtocolInfo* protocolInfo = CUpnpDlnaProtocolInfo::NewL(); - CleanupStack::PushL( protocolInfo ); - protocolInfo->SetFirstFieldL( KHttpGet8() ); - protocolInfo->SetSecondFieldL( KStar8() ); - protocolInfo->SetThirdFieldL( *mimetype ); - - // Obtain DLNA Profile ID - CUpnpDlnaProfiler* profiler = CUpnpDlnaProfiler::NewLC(); - HBufC* PnParameter = NULL; - TRAPD( profileErr, - PnParameter = profiler->ProfileForFileL( aFilename, - file, - *retval ) ); - CleanupStack::PopAndDestroy( profiler ); - - if ( PnParameter && !profileErr ) - { - // Set DLNA Profile name (PN parameter) - CleanupStack::PushL( PnParameter ); - HBufC8* profileName8bit = - EscapeUtils::ConvertFromUnicodeToUtf8L( *PnParameter ); - CleanupStack::PushL( profileName8bit ); - protocolInfo->SetPnParameterL( *profileName8bit ); - CleanupStack::PopAndDestroy( profileName8bit ); - - // OP parameter is always the same in our CDS. - protocolInfo->SetOpParameterL( - UpnpDlnaProtocolInfo::KDEFAULT_DLNA_OP ); - - // Set Flags according to file type. - if ( mimetype->Left( KMimeStartLength ).Compare( KVideo() ) == 0 ) - { - protocolInfo->SetFlagsParameterL( - UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_AV ); - } - else if - ( mimetype->Left( KMimeStartLength ).Compare( KAudio() ) == 0 ) - { - protocolInfo->SetFlagsParameterL( - UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_AUDIO ); - } - else if - ( mimetype->Left( KMimeStartLength ).Compare( KImage() ) == 0 ) - { - protocolInfo->SetFlagsParameterL( - UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_IMAGE ); - } - - CleanupStack::PopAndDestroy( PnParameter ); - } - - retval->SetProtocolInfoL( protocolInfo->ProtocolInfoL() ); - - // clean up - CleanupStack::PopAndDestroy( protocolInfo ); - CleanupStack::PopAndDestroy( mimetype ); - CleanupStack::PopAndDestroy( &file ); - CleanupStack::PopAndDestroy( &fsSession ); - CleanupStack::Pop( retval ); - return retval; - - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetMimetypeL -// -------------------------------------------------------------------------- -// -HBufC8* CUpnpResResolver::GetMimetypeL( RFile& aFile ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetMimetypeL" ); - HBufC8* retval = NULL; - // Create an AppArc server session for mime type recognition - RApaLsSession sess; - User::LeaveIfError( sess.Connect() ); - CleanupClosePushL( sess ); - - // Try to get mime type from AppArc server - TDataRecognitionResult mimeResult; - User::LeaveIfError( sess.RecognizeData( aFile, mimeResult ) ); - - // close session handle - CleanupStack::PopAndDestroy( &sess ); - - // Data recognition done. Check results. - retval = mimeResult.iDataType.Des8().AllocL(); - return retval; - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetVideoDurationL -// -------------------------------------------------------------------------- -// -void CUpnpResResolver::GetVideoDurationL( RFile& aFile ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetVideoDurationL" ); - mp4_u32 videolength = 0; - mp4_double framerate = 0; - mp4_u32 videotype = 0; - mp4_u32 videowidth = 0; - mp4_u32 videoheight = 0; - mp4_u32 timescale = 0; - - MP4Handle myMp4Handle; - - // try open mp4 file handle - MP4Err openerr = MP4ParseOpenFileHandle( &myMp4Handle, &aFile ); - switch ( openerr ) - { - case MP4_OK : - { - // obtain necessary information from file - MP4Err requesterr = MP4ParseRequestVideoDescription( - myMp4Handle, - &videolength, - &framerate, - &videotype, - &videowidth, - &videoheight, - ×cale ); - - // close mp4 file handle - MP4Err closeerr = MP4ParseClose( myMp4Handle ); - if ( closeerr || requesterr ) - { - User::Leave( KErrGeneral ); - } - } - break; - case MP4_ERROR : - { - User::Leave( KErrGeneral ); - } - break; - case MP4_OUT_OF_MEMORY : - { - User::Leave( KErrNoMemory ); - } - break; - case MP4_FILE_ERROR : - { - User::Leave( KErrAccessDenied ); - } - break; - default : - User::Leave( KErrGeneral ); - break; - } - // videolength in milliseconds - iDuration = videolength/KMilliSecondsInSecond; - } - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetAudioDurationL -// -------------------------------------------------------------------------- -// -void CUpnpResResolver::GetAudioDurationL( const TDesC& aFilename ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetAudioDurationL" ); - - // create audioplayer if it does not exist - if ( !iAudioplayer ) - { - iAudioplayer = CMdaAudioPlayerUtility::NewL( *this ); - } - - // Create iWait if it does not exist. Create it here rather than after - // OpenL-call so that there will be no problems if somehow OpenFileL - // calls MapcInitComplete-callback before iWait is created and started. - if ( !iWait ) - { - iWait = new( ELeave ) CActiveSchedulerWait; - } - - // Open file specified in aFilename. This is an asynchronic operation. - // Calls MapcInitComplete callback after completed. - iAudioplayer->OpenFileL( aFilename ); - - // start CActiveSchedulerWait which is completed in MapcInitComplete - iWait->Start(); - - // clean up - delete iAudioplayer; - iAudioplayer = NULL; - - delete iWait; - iWait = NULL; - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetFileSizeL -// -------------------------------------------------------------------------- -// -TInt CUpnpResResolver::GetFileSizeL( RFile& aFile ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetFileSizeL" ); - TInt retval = KErrNone; - User::LeaveIfError( aFile.Size( retval ) ); - return retval; - } - - -// -------------------------------------------------------------------------- -// CUpnpResResolver::GetImageResolutionL -// -------------------------------------------------------------------------- -// -TSize CUpnpResResolver::GetImageResolutionL( RFile& aFile, - const TDesC8& aMimetype ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetImageResolutionL" ); - CImageDecoder* imageDecoder = NULL; - TRAPD( createError, imageDecoder = CImageDecoder::FileNewL( - aFile, - aMimetype, - ContentAccess::EPeek ) ); - - if ( createError ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetImageResolutionL \ -CreateError" ); - User::Leave( createError ); - } - - CleanupStack::PushL( imageDecoder ); - TSize imageResolution = imageDecoder->FrameInfo().iOverallSizeInPixels; - CleanupStack::PopAndDestroy( imageDecoder ); - - return imageResolution; - } - -// -------------------------------------------------------------------------- -// From class MMdaAudioPlayerCallback. -// MapcPlayComplete callback (not used) -// -------------------------------------------------------------------------- -// -void CUpnpResResolver::MapcPlayComplete( TInt /*aError*/ ) - { - //this callback is not needed - } - -// -------------------------------------------------------------------------- -// From class MMdaAudioPlayerCallback. -// MapcInitComplete callback is called after a call to -// CMdaAudioConvertUtility::OpenL has completed. -// -------------------------------------------------------------------------- -// -void CUpnpResResolver::MapcInitComplete( - TInt aError, - const TTimeIntervalMicroSeconds& aDuration ) - { - __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::MapcInitComplete" ); - - // if opening was successful, save duration to member variable - if( KErrNone == aError ) - { - iDuration = aDuration; - } - - // continue execution in GetAudioDurationL-method by stopping - // ActiveSchedulerWait - iWait->AsyncStop(); - } - -// 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 file of CUpnpResResolver class. +* CUpnpResResolver is a class used for resolving res field +* attributes for a given file. +* +*/ + + + + + + +// system includes +#include // RFile +#include // RApaLsSession +#include // CUpnpDlnaProtocolInfo +#include // CImageDecoder +#include // ContentAccess +#include <3gplibrary/mp4lib.h> // MP4ParseRequestAudioDescription +#include // EscapeUtils::ConvertFromUnicodeToUtf8L + +// user includes +#include "upnpresresolver.h" +#include "upnpdlnaprofiler.h" +#include "upnpresparameters.h" + +_LIT( KComponentLogfile, "dlnaprofiler.txt"); +#include "upnplog.h" + +// constants +_LIT8( KHttpGet8, "http-get" ); +_LIT8( KStar8, "*" ); + +const TInt KMicrosecondsInSecond = 1000000; +const TInt KMilliSecondsInSecond = 1000; + +// ======== LOCAL FUNCTIONS ======== +// NONE + +// ======== MEMBER FUNCTIONS ======== + +// -------------------------------------------------------------------------- +// CUpnpResResolver C++ constructor +// -------------------------------------------------------------------------- +// +CUpnpResResolver::CUpnpResResolver() : iDuration(0) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver constructor" ); + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::ConstructL +// -------------------------------------------------------------------------- +// +void CUpnpResResolver::ConstructL() + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::ConstructL" ); + + // open semaphore + User::LeaveIfError( iSemaphore.CreateLocal( 0 ) ); + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CUpnpResResolver* CUpnpResResolver::NewL() + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::NewL" ); + CUpnpResResolver* self = CUpnpResResolver::NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::NewLC +// -------------------------------------------------------------------------- +// +EXPORT_C CUpnpResResolver* CUpnpResResolver::NewLC() + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::NewLC" ); + CUpnpResResolver* self = new( ELeave ) CUpnpResResolver; + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver destructor +// -------------------------------------------------------------------------- +// +CUpnpResResolver::~CUpnpResResolver() + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver destructor" ); + + iSemaphore.Close(); + delete iAVFile; + } + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetResParametersL +// -------------------------------------------------------------------------- +// +EXPORT_C CUpnpResParameters* CUpnpResResolver::GetResParametersL( + const TDesC& aFilename ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetResParametersL" ); + // check that aFileName is reasonable + if ( aFilename.Length() <= 0 ) + { + User::Leave( KErrArgument ); + } + + // Create object that will be returned. + CUpnpResParameters* retval = CUpnpResParameters::NewLC(); + + // try to open file specified by aFileName + RFs fsSession; + User::LeaveIfError( fsSession.Connect() ); // connect session + CleanupClosePushL( fsSession ); + // without calling ShareProtected() RApaLsSession::RecognizeData + // does not work (leaves with KErrBadHandle). + fsSession.ShareProtected(); + + RFile file; + User::LeaveIfError( file.Open( fsSession, + aFilename, + EFileShareReadersOrWriters|EFileRead ) ); + CleanupClosePushL( file ); + + // Obtain mimetype of the file + HBufC8* mimetype = GetMimetypeL( file ); + CleanupStack::PushL( mimetype ); + retval->SetMimetypeL( *mimetype ); + + // Obtain file size + TInt filesize = GetFileSizeL( file ); + retval->SetFileSize( filesize ); + + // Obtain duration for video&audio files and resolution for images. + TSize imageResolution( KErrNotFound, KErrNotFound ); + if ( mimetype->Left( KMimeStartLength ).Compare( KVideo() ) == 0 ) + { + GetVideoDurationL( file ); + retval->SetDurationInSeconds( iDuration.Int64() ); + } + else if ( mimetype->Left( KMimeStartLength ).Compare( KAudio() ) == 0 ) + { + GetAudioDurationL( aFilename ); + retval->SetDurationInSeconds( + iDuration.Int64() / KMicrosecondsInSecond ); + } + else if ( mimetype->Left( KMimeStartLength ).Compare( KImage() ) == 0 ) + { + TRAPD( err, imageResolution = GetImageResolutionL( file, + *mimetype ) ); + if ( !err ) + { + retval->SetResolution( imageResolution ); + } + } + + // Construct CUpnpDlnaProtocolInfo object. + CUpnpDlnaProtocolInfo* protocolInfo = CUpnpDlnaProtocolInfo::NewL(); + CleanupStack::PushL( protocolInfo ); + protocolInfo->SetFirstFieldL( KHttpGet8() ); + protocolInfo->SetSecondFieldL( KStar8() ); + protocolInfo->SetThirdFieldL( *mimetype ); + + // Obtain DLNA Profile ID + CUpnpDlnaProfiler* profiler = CUpnpDlnaProfiler::NewLC(); + HBufC* PnParameter = NULL; + TRAPD( profileErr, + PnParameter = profiler->ProfileForFileL( aFilename, + file, + *retval ) ); + CleanupStack::PopAndDestroy( profiler ); + + if ( PnParameter && !profileErr ) + { + // Set DLNA Profile name (PN parameter) + CleanupStack::PushL( PnParameter ); + HBufC8* profileName8bit = + EscapeUtils::ConvertFromUnicodeToUtf8L( *PnParameter ); + CleanupStack::PushL( profileName8bit ); + protocolInfo->SetPnParameterL( *profileName8bit ); + CleanupStack::PopAndDestroy( profileName8bit ); + + // OP parameter is always the same in our CDS. + protocolInfo->SetOpParameterL( + UpnpDlnaProtocolInfo::KDEFAULT_DLNA_OP ); + + // Set Flags according to file type. + if ( mimetype->Left( KMimeStartLength ).Compare( KVideo() ) == 0 ) + { + protocolInfo->SetFlagsParameterL( + UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_AV ); + } + else if + ( mimetype->Left( KMimeStartLength ).Compare( KAudio() ) == 0 ) + { + protocolInfo->SetFlagsParameterL( + UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_AUDIO ); + } + else if + ( mimetype->Left( KMimeStartLength ).Compare( KImage() ) == 0 ) + { + protocolInfo->SetFlagsParameterL( + UpnpDlnaProtocolInfo::KDEFAULT_DLNA_FLAGS_IMAGE ); + } + + CleanupStack::PopAndDestroy( PnParameter ); + } + + retval->SetProtocolInfoL( protocolInfo->ProtocolInfoL() ); + + // clean up + CleanupStack::PopAndDestroy( protocolInfo ); + CleanupStack::PopAndDestroy( mimetype ); + CleanupStack::PopAndDestroy( &file ); + CleanupStack::PopAndDestroy( &fsSession ); + CleanupStack::Pop( retval ); + return retval; + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetMimetypeL +// -------------------------------------------------------------------------- +// +HBufC8* CUpnpResResolver::GetMimetypeL( RFile& aFile ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetMimetypeL" ); + HBufC8* retval = NULL; + // Create an AppArc server session for mime type recognition + RApaLsSession sess; + User::LeaveIfError( sess.Connect() ); + CleanupClosePushL( sess ); + + // Try to get mime type from AppArc server + TDataRecognitionResult mimeResult; + User::LeaveIfError( sess.RecognizeData( aFile, mimeResult ) ); + + // close session handle + CleanupStack::PopAndDestroy( &sess ); + + if( mimeResult.iDataType.Des8().Length() == 0 ) + { + User::Leave( KErrGeneral ); + } + + // Data recognition done. Check results. + retval = mimeResult.iDataType.Des8().AllocL(); + return retval; + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetVideoDurationL +// -------------------------------------------------------------------------- +// +void CUpnpResResolver::GetVideoDurationL( RFile& aFile ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetVideoDurationL" ); + mp4_u32 videolength = 0; + mp4_double framerate = 0; + mp4_u32 videotype = 0; + mp4_u32 videowidth = 0; + mp4_u32 videoheight = 0; + mp4_u32 timescale = 0; + + MP4Handle myMp4Handle; + + // try open mp4 file handle + MP4Err openerr = MP4ParseOpenFileHandle( &myMp4Handle, &aFile ); + switch ( openerr ) + { + case MP4_OK : + { + // obtain necessary information from file + MP4Err requesterr = MP4ParseRequestVideoDescription( + myMp4Handle, + &videolength, + &framerate, + &videotype, + &videowidth, + &videoheight, + ×cale ); + + // close mp4 file handle + MP4Err closeerr = MP4ParseClose( myMp4Handle ); + if ( closeerr || requesterr ) + { + User::Leave( KErrGeneral ); + } + } + break; + case MP4_ERROR : + { + User::Leave( KErrGeneral ); + } + break; + case MP4_OUT_OF_MEMORY : + { + User::Leave( KErrNoMemory ); + } + break; + case MP4_FILE_ERROR : + { + User::Leave( KErrAccessDenied ); + } + break; + default : + User::Leave( KErrGeneral ); + break; + } + // videolength in milliseconds + iDuration = videolength/KMilliSecondsInSecond; + } + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetAudioDurationL +// -------------------------------------------------------------------------- +// +void CUpnpResResolver::GetAudioDurationL( const TDesC& aFilename ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetAudioDurationL" ); + + TInt err = KErrNone; + + // store current av file + HBufC* avFile = aFilename.AllocL(); + delete iAVFile; + iAVFile = avFile; + + // create audio resolving thread + RThread thread; + User::LeaveIfError( thread.Create( + KNullDesC, ThreadFunction, KDefaultStackSize, &User::Allocator(), this ) ); + + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetAudioDurationL: Created audio resolving thread" ); + + // start thread and wait until it has finished + thread.Resume(); + iSemaphore.Wait(); + + // check return value and close thread + err = thread.ExitReason(); + thread.Close(); + + __LOG1( "[UPnPDlnaProfiler] CUpnpResResolver::GetAudioDurationL: Finished audio resolving thread with code (%d)", err ); + + // leave if could not resolve audio duration + User::LeaveIfError( err ); + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetFileSizeL +// -------------------------------------------------------------------------- +// +TInt CUpnpResResolver::GetFileSizeL( RFile& aFile ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetFileSizeL" ); + TInt retval = KErrNone; + User::LeaveIfError( aFile.Size( retval ) ); + return retval; + } + + +// -------------------------------------------------------------------------- +// CUpnpResResolver::GetImageResolutionL +// -------------------------------------------------------------------------- +// +TSize CUpnpResResolver::GetImageResolutionL( RFile& aFile, + const TDesC8& aMimetype ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetImageResolutionL" ); + CImageDecoder* imageDecoder = NULL; + TRAPD( createError, imageDecoder = CImageDecoder::FileNewL( + aFile, + aMimetype, + ContentAccess::EPeek ) ); + + if ( createError ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::GetImageResolutionL \ +CreateError" ); + User::Leave( createError ); + } + + CleanupStack::PushL( imageDecoder ); + TSize imageResolution = imageDecoder->FrameInfo().iOverallSizeInPixels; + CleanupStack::PopAndDestroy( imageDecoder ); + + return imageResolution; + } + +// -------------------------------------------------------------------------- +// From class MMdaAudioPlayerCallback. +// MapcPlayComplete callback (not used) +// -------------------------------------------------------------------------- +// +void CUpnpResResolver::MapcPlayComplete( TInt /*aError*/ ) + { + // not used. + } + +// -------------------------------------------------------------------------- +// From class MMdaAudioPlayerCallback. +// MapcInitComplete callback is called after a call to +// CMdaAudioConvertUtility::OpenL has completed. +// -------------------------------------------------------------------------- +// +void CUpnpResResolver::MapcInitComplete( TInt aError, + const TTimeIntervalMicroSeconds& aDuration ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::MapcInitComplete" ); + + // if opening was successful, save duration to member variable + if( KErrNone == aError ) + { + iDuration = aDuration; + } + + // stop scheduler for audio resolving thread + CActiveScheduler::Stop(); + } + +// ----------------------------------------------------------------------------- +// CUpnpResResolver::ThreadFunction +// ----------------------------------------------------------------------------- +// +TInt CUpnpResResolver::ThreadFunction( TAny* aSelf ) + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::ThreadFunction" ); + + TInt err = KErrNone; + + CUpnpResResolver* self = static_cast( aSelf ); + + // create cleanup stack + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if( cleanupStack ) + { + // execute thread function + TRAP( err, self->ResolveAudioDurationL() ); + + // cleanup + delete cleanupStack; + } + + // reset scheduler for this thread + CActiveScheduler::Install( NULL ); + + // signal main thread so that it can continue + self->iSemaphore.Signal(); + + return err; + } + +// ----------------------------------------------------------------------------- +// CUpnpResResolver::ResolveAudioDurationL +// ----------------------------------------------------------------------------- +// +void CUpnpResResolver::ResolveAudioDurationL() + { + __LOG( "[UPnPDlnaProfiler] CUpnpResResolver::ResolveAudioDurationL" ); + + CActiveScheduler* scheduler = new( ELeave ) CActiveScheduler; + if( scheduler ) + { + CleanupStack::PushL( scheduler ); + + // install the new scheduler in use for this thread + CActiveScheduler::Install( scheduler ); + + // create audio player utility + CMdaAudioPlayerUtility* audioPlayerUtility = + CMdaAudioPlayerUtility::NewL( *this ); + CleanupStack::PushL( audioPlayerUtility ); + + // open file and wait until the audio clip initialization is ready + audioPlayerUtility->OpenFileL( *iAVFile ); + + // start scheduler + CActiveScheduler::Start(); + + // cleanup + CleanupStack::PopAndDestroy( audioPlayerUtility ); + CleanupStack::PopAndDestroy( scheduler ); + } + } + +// end of file