diff -r 51035f0751c2 -r 4740b34b83ce mmappcomponents/harvester/metadataextractor/src/mpxmetadataextractor.cpp --- a/mmappcomponents/harvester/metadataextractor/src/mpxmetadataextractor.cpp Wed Apr 14 16:28:17 2010 +0300 +++ b/mmappcomponents/harvester/metadataextractor/src/mpxmetadataextractor.cpp Tue Apr 27 17:09:22 2010 +0300 @@ -12,7 +12,7 @@ * Contributors: * * Description: Extracts metadata from a file -* Version : %version: da1mmcf#38.1.4.2.6.1.9 % << Don't touch! Updated by Synergy at check-out. +* Version : %version: da1mmcf#38.1.4.2.6.1.10 % << Don't touch! Updated by Synergy at check-out. * */ @@ -41,6 +41,7 @@ #include #include #include +#include #include "mpxmetadataextractor.h" #include "mpxfileinfoutility.h" @@ -82,8 +83,11 @@ : iFs( aFs ), iAppArc( aAppArc ), iSupportedTypes( aTypes ), - iOutstandingThumbnailRequest(0), - iTNMBlockCount(0) + iCancelled( EFalse ), + iObs( NULL ), + iMedia( NULL ), + iMetadataOnly( EFalse ), + iFileOpenError( KErrNone ) { } @@ -98,6 +102,7 @@ iMetadataUtility = CMetaDataUtility::NewL(); iDrmMediaUtility = CMPXDrmMediaUtility::NewL(); iFileInfoUtil = CMPXFileInfoUtility::NewL(); + iTaskTimer = CPeriodic::NewL( CActive::EPriorityIdle ); #ifdef RD_MPX_TNM_INTEGRATION // Create Thumbnail Manager instance. This object is the observer. @@ -107,6 +112,8 @@ // create wait loop iTNSyncWait = new (ELeave) CActiveSchedulerWait; iTimer = CPeriodic::NewL( CActive::EPriorityIdle ); + iArrayTNRequestId.Reset(); + iArrayTasks.Reset(); #endif //RD_MPX_TNM_INTEGRATION } @@ -138,6 +145,8 @@ delete iMetadataUtility; delete iFileInfoUtil; delete iDrmMediaUtility; + delete iTaskTimer; + iFile.Close(); #ifdef RD_MPX_TNM_INTEGRATION delete iTNManager; if (iTNSyncWait && iTNSyncWait->IsStarted() ) @@ -146,137 +155,64 @@ } delete iTNSyncWait; delete iTimer; + iArrayTNRequestId.Close(); + iArrayTasks.Close(); #endif //RD_MPX_TNM_INTEGRATION - - MPX_DEBUG2("CMPXMetadataExtractor: TNM Block Count: %d ", iTNMBlockCount ); } // --------------------------------------------------------------------------- -// Constructs a media properties object +// Constructs a media properties object : synchronous function // --------------------------------------------------------------------------- // EXPORT_C void CMPXMetadataExtractor::CreateMediaL( const TDesC& aFile, CMPXMedia*& aNewProperty, TBool aMetadataOnly ) { - // make a copy of aFile - HBufC* fileName = HBufC::NewL(KMaxFileName); - CleanupStack::PushL( fileName ); - fileName->Des().Append( aFile ); - MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL %S <---", fileName ); - - RArray contentIDs; - contentIDs.AppendL( KMPXMediaIdGeneral ); - contentIDs.AppendL( KMPXMediaIdAudio ); - contentIDs.AppendL( KMPXMediaIdMusic ); - contentIDs.AppendL( KMPXMediaIdDrm ); - contentIDs.AppendL( KMPXMediaIdMTP ); - aNewProperty = NULL; - CMPXMedia* media = CMPXMedia::NewL( contentIDs.Array() ); - CleanupStack::PushL( media ); - contentIDs.Close(); - - // CMPXMedia default types - - media->SetTObjectValueL( KMPXMediaGeneralType, - EMPXItem ); - media->SetTObjectValueL( KMPXMediaGeneralCategory, - EMPXSong ); + MPX_FUNC("CMPXMetadataExtractor::CreateMediaL()"); + // check if we are still processing a request. + if ( iArrayTasks.Count() ) + { + MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaL Request ongoing. Abort!" ); + User::Leave( KErrAbort ); + } - TParsePtrC parse( *fileName ); - - // Title, default is file name - media->SetTextValueL( KMPXMediaGeneralTitle, - parse.Name() ); - - // Default album track - media->SetTextValueL( KMPXMediaMusicAlbumTrack, - KNullDesC ); - - // Set the Mime Type and collection UID - // - if( !aMetadataOnly ) + iCancelled = EFalse; + iFileOpenError = KErrNone; + iObs = NULL; + aNewProperty = NULL; + iFileName = aFile; + iMetadataOnly = aMetadataOnly; + + // populate the task array + AddTasksL(); + + // execute all tasks in the array + while ( iArrayTasks.Count() ) { - TInt index(KErrNotFound); - TInt count( iSupportedTypes.Count() ); - for (TInt i=0; i Extensions(); - const TDesC& ext = parse.Ext(); - if (!exts.FindIsq(ext, index2)) - { // found - index = i; - break; + // cleanup + if ( iMedia != NULL ) + { + delete iMedia; + iMedia = NULL; } + iArrayTasks.Reset(); + if ( error ) + { + CleanUp(); + User::LeaveIfError( error ); + } + break; } - if( KErrNotFound != index ) - { - MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc <---" ); - TInt mimeIndex = SupportedContainerTypeL( *fileName, index ); - User::LeaveIfError( mimeIndex ); - MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc --->" ); - - media->SetTextValueL( KMPXMediaGeneralMimeType, - iSupportedTypes[index]->Mimetypes()[mimeIndex] ); - - media->SetTObjectValueL( KMPXMediaGeneralCollectionId, - iSupportedTypes[index]->Uid() ); - } - else - { - User::Leave(KErrNotSupported); - } - } - else // other case use apparc to fetch and set mimetype - { - TDataType dataType; - TUid dummyUid(KNullUid); - iAppArc.AppForDocument(*fileName, dummyUid, dataType); - media->SetTextValueL( KMPXMediaGeneralMimeType,dataType.Des() ); - } - // Use file handle here - // - RFile file; - TInt err = file.Open( iFs, *fileName, EFileRead | EFileShareReadersOrWriters ); - CleanupClosePushL(file); - - // Initially set default tags. - SetDefaultL( *media ); - // Metadata related - // - if( err == KErrNone ) - { - const TDesC& mimeType = media->ValueText( KMPXMediaGeneralMimeType ); - HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() ); - mimeType8->Des().Append( mimeType ); - TRAPD( metadataerror, iMetadataUtility->OpenFileL( file, *mimeType8 ) ); - MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d parsing metadata", - metadataerror ); - CleanupStack::PopAndDestroy( mimeType8 ); - - // Even if there is error extracting metadata, fill extracted tags. - TRAP( metadataerror, SetMediaPropertiesL( *media, *fileName ) ); - MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d setting tags", - metadataerror ); - - // Reset the utility - iMetadataUtility->ResetL(); + iArrayTasks.Remove( 0 ); } - // Common properties that we can extract - // - SetExtMediaPropertiesL( *media, *fileName, aMetadataOnly, file, err ); - CleanupStack::PopAndDestroy(&file); - - // Set the pointers now that the object is ready - // - CleanupStack::Pop( media ); - aNewProperty = media; - - CleanupStack::PopAndDestroy( fileName ); - MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL --->"); + aNewProperty = iMedia; + CleanUp(); } // --------------------------------------------------------------------------- @@ -285,6 +221,7 @@ // void CMPXMetadataExtractor::SetDefaultL( CMPXMedia& aMediaProp ) { + MPX_FUNC("CMPXMetadataExtractor::SetDefaultL()"); // Comment aMediaProp.SetTextValueL( KMPXMediaGeneralComment, KNullDesC ); @@ -318,13 +255,21 @@ // Sets media object attributes from metadata utilities // --------------------------------------------------------------------------- // -void CMPXMetadataExtractor::SetMediaPropertiesL( CMPXMedia& aMedia, - const TDesC& aFile ) +void CMPXMetadataExtractor::SetMediaPropertiesL() { - MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL <---" ); + MPX_FUNC("CMPXMetadataExtractor::SetMediaPropertiesL()"); - const CMetaDataFieldContainer& metaCont = - iMetadataUtility->MetaDataFieldsL(); + const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType ); + HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() ); + mimeType8->Des().Append( mimeType ); + + // Continue to extract metadata even if fail. + TRAPD( metadataerror, iMetadataUtility->OpenFileL( iFile, *mimeType8 ) ); + MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d parsing metadata", + metadataerror ); + CleanupStack::PopAndDestroy( mimeType8 ); + + const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL(); TInt count( metaCont.Count() ); for( TInt i=0; i0) { FindAndReplaceForbiddenChars(valptr, vallen); - aMedia.SetTextValueL(KMPXMediaGeneralTitle, *value); + iMedia->SetTextValueL(KMPXMediaGeneralTitle, *value); } break; } @@ -368,7 +312,7 @@ if (vallen>0) { FindAndReplaceForbiddenChars(valptr, vallen); - aMedia.SetTextValueL(KMPXMediaMusicArtist, *value); + iMedia->SetTextValueL(KMPXMediaMusicArtist, *value); } break; } @@ -380,7 +324,7 @@ if (vallen>0) { FindAndReplaceForbiddenChars(valptr, vallen); - aMedia.SetTextValueL(KMPXMediaMusicAlbum, *value ); + iMedia->SetTextValueL(KMPXMediaMusicAlbum, *value ); } break; } @@ -395,19 +339,19 @@ TDateTime dt; dt.SetYear( year ); TTime time( dt ); - aMedia.SetTObjectValueL( KMPXMediaMusicYear, + iMedia->SetTObjectValueL( KMPXMediaMusicYear, time.Int64() ); break; } case EMetaDataComment: { - aMedia.SetTextValueL( KMPXMediaGeneralComment, + iMedia->SetTextValueL( KMPXMediaGeneralComment, *value ); break; } case EMetaDataAlbumTrack: { - aMedia.SetTextValueL( KMPXMediaMusicAlbumTrack, + iMedia->SetTextValueL( KMPXMediaMusicAlbumTrack, *value ); break; } @@ -419,7 +363,7 @@ if (vallen>0) { FindAndReplaceForbiddenChars(valptr, vallen); - aMedia.SetTextValueL(KMPXMediaMusicGenre, *value); + iMedia->SetTextValueL(KMPXMediaMusicGenre, *value); } break; } @@ -431,54 +375,31 @@ if (vallen>0) { FindAndReplaceForbiddenChars(valptr, vallen); - aMedia.SetTextValueL(KMPXMediaMusicComposer, *value); + iMedia->SetTextValueL(KMPXMediaMusicComposer, *value); } break; } case EMetaDataUrl: case EMetaDataUserUrl: // fall through { - aMedia.SetTextValueL( KMPXMediaMusicURL, + iMedia->SetTextValueL( KMPXMediaMusicURL, *value ); break; } case EMetaDataJpeg: { -#ifdef RD_MPX_TNM_INTEGRATION - MPX_PERF_START(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM); - TPtrC8 ptr8 = metaCont.Field8( EMetaDataJpeg ); - HBufC8* value8; - TRAPD( err, value8 = ptr8.AllocL() ); - if ( KErrNone != err ) - { - MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL - error jpeg = %i", err); - } - else - { - CleanupStack::PushL( value8 ); - TRAPD( err, AddMediaAlbumArtL( aMedia, aFile, *value8 ) ); - if ( KErrNone != err ) - { - MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL - error album art = %i", err); - } - CleanupStack::Pop( value8 ); - } - MPX_PERF_END(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM); -#else //RD_MPX_TNM_INTEGRATION - aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, - aFile ); -#endif //RD_MPX_TNM_INTEGRATION + // Album art handled in AddMediaAlbumArtL() break; } case EMetaDataCopyright: { - aMedia.SetTextValueL( KMPXMediaGeneralCopyright, + iMedia->SetTextValueL( KMPXMediaGeneralCopyright, *value ); break; } case EMetaDataDuration: { - const TDesC& mimeType = aMedia.ValueText( KMPXMediaGeneralMimeType ); + const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType ); MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, mimeType = %S", &mimeType); // Verify if WMA, get the duration @@ -492,7 +413,7 @@ lexer.Val( duration ); // [second] duration *= 1000; // [msec] - aMedia.SetTObjectValueL( KMPXMediaGeneralDuration, + iMedia->SetTObjectValueL( KMPXMediaGeneralDuration, duration ); MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL- duration = %i", duration); @@ -519,21 +440,15 @@ CleanupStack::PopAndDestroy( value ); } } - - MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL --->" ); } // --------------------------------------------------------------------------- // Sets extra media properties not returned by metadata utilities // --------------------------------------------------------------------------- // -void CMPXMetadataExtractor::SetExtMediaPropertiesL( CMPXMedia& aProp, - const TDesC& aFile, - TBool aMetadataOnly, - RFile& aFileHandle, - TInt aFileErr ) +void CMPXMetadataExtractor::SetExtMediaPropertiesL() { - MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL <---"); + MPX_FUNC("CMPXMetadataExtractor::SetExtMediaPropertiesL()"); // DB Flags to set // @@ -541,18 +456,16 @@ // File Path // - TParsePtrC parse( aFile ); - aProp.SetTextValueL( KMPXMediaGeneralUri, - aFile ); - aProp.SetTextValueL( KMPXMediaGeneralDrive, - parse.Drive() ); + TParsePtrC parse( iFileName ); + iMedia->SetTextValueL( KMPXMediaGeneralUri, iFileName ); + iMedia->SetTextValueL( KMPXMediaGeneralDrive, parse.Drive() ); // DRM Rights // CMPXMedia* drm = NULL; - TRAPD( drmError, iDrmMediaUtility->InitL( aFile ); - drm = CMPXMedia::NewL( *iDrmMediaUtility->GetMediaL( KMPXMediaDrmProtected.iAttributeId | - KMPXMediaDrmRightsStatus.iAttributeId ) ); + TRAPD( drmError, iDrmMediaUtility->InitL( iFileName ); + drm = CMPXMedia::NewL( *iDrmMediaUtility->GetMediaL( KMPXMediaDrmProtected.iAttributeId | + KMPXMediaDrmRightsStatus.iAttributeId ) ); ); TBool prot(EFalse); @@ -570,7 +483,7 @@ if( drm->IsSupported( KMPXMediaDrmRightsStatus ) ) { status = drm->ValueTObjectL(KMPXMediaDrmRightsStatus); - aProp.SetTObjectValueL(KMPXMediaDrmRightsStatus, status ); + iMedia->SetTObjectValueL(KMPXMediaDrmRightsStatus, status ); MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- status %i", status); } @@ -594,8 +507,8 @@ User::LeaveIfError( drmError ); } - aProp.SetTObjectValueL( KMPXMediaDrmProtected, prot ); - aProp.SetTObjectValueL( KMPXMediaMTPDrmStatus, (TUint16)prot ); + iMedia->SetTObjectValueL( KMPXMediaDrmProtected, prot ); + iMedia->SetTObjectValueL( KMPXMediaMTPDrmStatus, (TUint16)prot ); iDrmMediaUtility->Close(); @@ -603,9 +516,9 @@ // File Size --- The following needs MMF support // TInt size( 0 ); - if( aFileErr == KErrNone ) + if( iFileOpenError == KErrNone ) { - const TDesC& mimeType = aProp.ValueText( KMPXMediaGeneralMimeType ); + const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType ); MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, mimeType = %S", &mimeType); // Verify if WMA, skip getting info from MMF @@ -617,25 +530,25 @@ else { MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL, get MMF controller"); - aFileHandle.Size( size ); - aProp.SetTObjectValueL( KMPXMediaGeneralSize, size ); + iFile.Size( size ); + iMedia->SetTObjectValueL( KMPXMediaGeneralSize, size ); // Duration, bitrate, samplerate, etc // - if( !aMetadataOnly ) + if( !iMetadataOnly ) { TRAPD(err2, iFileInfoUtil->OpenFileL( - aFileHandle, - aProp.ValueText(KMPXMediaGeneralMimeType))); + iFile, + iMedia->ValueText(KMPXMediaGeneralMimeType))); MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, file info util error %i", err2); if( KErrNone == err2 ) { - aProp.SetTObjectValueL( KMPXMediaAudioBitrate, + iMedia->SetTObjectValueL( KMPXMediaAudioBitrate, iFileInfoUtil->BitRate() ); - aProp.SetTObjectValueL( KMPXMediaAudioSamplerate, + iMedia->SetTObjectValueL( KMPXMediaAudioSamplerate, iFileInfoUtil->SampleRate() ); TInt64 duration = (TInt64) iFileInfoUtil->Duration().Int64() / 1000; // ms - aProp.SetTObjectValueL( KMPXMediaGeneralDuration, + iMedia->SetTObjectValueL( KMPXMediaGeneralDuration, duration ); MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- duration %i", duration); @@ -645,16 +558,14 @@ } } } - else if( aFileErr == KErrNotFound || aFileErr == KErrPathNotFound ) + else if( iFileOpenError == KErrNotFound || iFileOpenError == KErrPathNotFound ) { dbFlags |= KMPXMediaGeneralFlagsIsInvalid; } // Finally set the db flag // - aProp.SetTObjectValueL( KMPXMediaGeneralFlags, + iMedia->SetTObjectValueL( KMPXMediaGeneralFlags, dbFlags ); - - MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL --->"); } // --------------------------------------------------------------------------- @@ -664,6 +575,7 @@ TInt CMPXMetadataExtractor::SupportedContainerTypeL( const TDesC& aFile, TInt aIndex ) { + MPX_FUNC("CMPXMetadataExtractor::SupportedContainerTypeL()"); TInt index(KErrNotFound); TDataType dataType; @@ -697,13 +609,20 @@ // Callback but not used here // --------------------------------------------------------------------------- void CMPXMetadataExtractor::ThumbnailReady( TInt /*aError*/, - MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ ) + MThumbnailData& /*aThumbnail*/, TThumbnailRequestId aId ) { MPX_FUNC("CMPXMetadataExtractor::ThumbnailReady()"); - MPX_DEBUG2("CMPXMetadataExtractor::ThumbnailReady(): iOutstandingThumbnailRequest %d", - iOutstandingThumbnailRequest); - iOutstandingThumbnailRequest--; - if ( iOutstandingThumbnailRequest < KMPXMaxThumbnailRequest ) + + // Remove thumbnail id from array. + TInt index = iArrayTNRequestId.Find( aId ); + if ( index >= 0 ) + { + iArrayTNRequestId.Remove( index ); + } + MPX_DEBUG2("CMPXMetadataExtractor::ThumbnailReady(): Outstanding Thumbnail Request = %d", + iArrayTNRequestId.Count()); + + if ( iArrayTNRequestId.Count() < KMPXMaxThumbnailRequest ) { StopWaitLoop(); } @@ -762,7 +681,8 @@ EXPORT_C TInt CMPXMetadataExtractor::ExtractAlbumArtL( CMPXMedia* aMedia ) { MPX_FUNC("CMPXMetadataExtractor::ExtractAlbumArtL()"); - TInt err = KErrNone; + TInt err = KErrNone; + iCancelled = EFalse; if ( !aMedia->IsSupported(KMPXMediaGeneralUri) ) { @@ -778,25 +698,18 @@ if (ext.CompareF(KNonEmbeddedArtExt)== 0) { #ifdef RD_MPX_TNM_INTEGRATION - //check if can send TN request, If thumbnail creation is ongoing, wait til it is done CheckBeforeSendRequest(); - CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC( path, KImageFileType ); - - - - iTNManager->CreateThumbnails( *source ); - - iOutstandingThumbnailRequest++; + TThumbnailRequestId tnId = iTNManager->CreateThumbnails( *source ); + iArrayTNRequestId.Append( tnId ); CleanupStack::PopAndDestroy( source ); - - #endif + #endif // RD_MPX_TNM_INTEGRATION } else { -#endif +#endif // ABSTRACTAUDIOALBUM_INCLUDED // create wanted fields array RArray wantedFields; CleanupClosePushL( wantedFields ); @@ -820,54 +733,16 @@ if ( !err ) { - TRAP( err, GetMediaAlbumArtL( *aMedia, path )); + //check if can send TN request, If thumbnail creation is ongoing, wait til it is done + CheckBeforeSendRequest(); + TRAP( err, AddMediaAlbumArtL( *aMedia, path )); } // Reset the utility iMetadataUtility->ResetL(); #ifdef ABSTRACTAUDIOALBUM_INCLUDED } -#endif - return err; - } - -// ---------------------------------------------------------------------------- -// Set album art. -// ---------------------------------------------------------------------------- -TInt CMPXMetadataExtractor::GetMediaAlbumArtL( CMPXMedia& aMedia, - const TDesC& aFile ) - { - MPX_FUNC("CMPXMetadataExtractor::GetMediaAlbumArtL()"); - TInt err = KErrNone; - // get metadata container. - const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL(); - - TPtrC8 data8 = metaCont.Field8( EMetaDataJpeg ); - - if ( data8.Length() ) - { - MPX_DEBUG1("CMPXMetadataExtractor::GetMediaAlbumArtL(): Album art exist."); - -#ifdef RD_MPX_TNM_INTEGRATION - HBufC8* value8; - TRAPD( err, value8 = data8.AllocL() ); - if ( KErrNone != err ) - { - MPX_DEBUG2("CMPXMetadataExtractor::GetMediaAlbumArtL - error jpeg = %i", err); - User::Leave( err ); - } - CleanupStack::PushL( value8 ); - AddMediaAlbumArtL( aMedia, aFile, *value8 ); - CleanupStack::Pop( value8 ); -#else // RD_MPX_TNM_INTEGRATION - aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile ); -#endif // RD_MPX_TNM_INTEGRATION - } - else - { - err = KErrNotFound; - } - +#endif // ABSTRACTAUDIOALBUM_INCLUDED return err; } @@ -875,40 +750,53 @@ // Add album art to media object. // ---------------------------------------------------------------------------- void CMPXMetadataExtractor::AddMediaAlbumArtL( CMPXMedia& aMedia, - const TDesC& aFile, - TDesC8& aValue ) + const TDesC& aFile ) { MPX_FUNC("CMPXMetadataExtractor::AddMediaAlbumArtL()"); -#ifdef RD_MPX_TNM_INTEGRATION - - //check if can send TN request, If thumbnail creation is ongoing, wait til it is done - CheckBeforeSendRequest(); - - aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile ); - TBuf<256> mimeType; - mimeType.Copy( KImageFileType ); - CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC( - &aValue, mimeType, aFile ); - iTNManager->CreateThumbnails( *source ); - CleanupStack::PopAndDestroy( source ); - aMedia.SetTextValueL( KMPXMediaMusicOriginalAlbumArtFileName, aFile ); - iOutstandingThumbnailRequest++; + // get metadata container. + const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL(); + TPtrC8 data8 = metaCont.Field8( EMetaDataJpeg ); + + if ( data8.Length() ) + { + MPX_DEBUG1("CMPXMetadataExtractor::GetMediaAlbumArtL(): Album art exist."); +#ifdef RD_MPX_TNM_INTEGRATION + HBufC8* value8 = NULL; + TRAPD( err, value8 = data8.AllocL() ); + if ( KErrNone != err ) + { + MPX_DEBUG2("CMPXMetadataExtractor::GetMediaAlbumArtL - error jpeg = %i", err); + return; + } + CleanupStack::PushL( value8 ); + TBuf<256> mimeType; + mimeType.Copy( KImageFileType ); + CThumbnailObjectSource* source = CThumbnailObjectSource::NewL( + value8, mimeType, aFile ); + TThumbnailRequestId tnId = iTNManager->CreateThumbnails( *source ); + iArrayTNRequestId.Append( tnId ); // add thumbnail id to array + CleanupStack::Pop( value8 ); + aMedia.SetTextValueL( KMPXMediaMusicOriginalAlbumArtFileName, aFile ); #endif // RD_MPX_TNM_INTEGRATION + aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile ); + } } +// ---------------------------------------------------------------------------- +// Check if can send request to TNM or not. +// ---------------------------------------------------------------------------- void CMPXMetadataExtractor::CheckBeforeSendRequest() { MPX_FUNC("CMPXMetadataExtractor::CheckBeforeSendRequest()"); #ifdef RD_MPX_TNM_INTEGRATION - MPX_DEBUG2("CMPXMetadataExtractor::CheckBeforeSendRequest(): iOutstandingThumbnailRequest %d", - iOutstandingThumbnailRequest); + MPX_DEBUG2("CMPXMetadataExtractor::CheckBeforeSendRequest(): Outstanding Thumbnail Request = %d", + iArrayTNRequestId.Count()); // If thumbnail creation is ongoing, wait til it is done - if ( iOutstandingThumbnailRequest >= KMPXMaxThumbnailRequest ) + if ( iArrayTNRequestId.Count() >= KMPXMaxThumbnailRequest ) { MPX_DEBUG1("CMPXMetadataExtractor::CheckBeforeSendRequest(): Thumbnail creation ongoing!"); - iTNMBlockCount++; // Cancel timer. CancelTimeoutTimer(); // Start timer in case there is no callback from ThumbNail Manager. @@ -925,3 +813,292 @@ } #endif // RD_MPX_TNM_INTEGRATION } + +// ---------------------------------------------------------------------------- +// Cancel request. This will empty the task array and stop the wait loop. This +// will cause the CreateMediaL() to finish more quickly. +// ---------------------------------------------------------------------------- +EXPORT_C void CMPXMetadataExtractor::CancelRequest() + { + MPX_FUNC("CMPXMetadataExtractor::CancelRequest()"); + iCancelled = ETrue; + // Cancel all tasks + iArrayTasks.Reset(); + // Cancel all thumbnail request + CancelAllThumbnailRequests(); + StopWaitLoop(); + } + +// ---------------------------------------------------------------------------- +// Cancel all outstanding thumbnail requests. +// ---------------------------------------------------------------------------- +void CMPXMetadataExtractor::CancelAllThumbnailRequests() + { + MPX_FUNC("CMPXMetadataExtractor::CancelAllThumbnailRequests()"); +#ifdef RD_MPX_TNM_INTEGRATION + // TODO: remove comments when TNM make CancelRequest asynchronous. + /*TInt count = iArrayTNRequestId.Count(); + for ( TInt i=0; iCancelRequest( iArrayTNRequestId[i] ); + } + */ + iArrayTNRequestId.Reset(); +#endif // RD_MPX_TNM_INTEGRATION + } + +// ---------------------------------------------------------------------------- +// Create media and set default data and mimetype. +// ---------------------------------------------------------------------------- +void CMPXMetadataExtractor::DoCreateMediaL() + { + MPX_FUNC("CMPXMetadataExtractor::DoCreateMediaL()"); + RArray contentIDs; + contentIDs.AppendL( KMPXMediaIdGeneral ); + contentIDs.AppendL( KMPXMediaIdAudio ); + contentIDs.AppendL( KMPXMediaIdMusic ); + contentIDs.AppendL( KMPXMediaIdDrm ); + contentIDs.AppendL( KMPXMediaIdMTP ); + iMedia = CMPXMedia::NewL( contentIDs.Array() ); + contentIDs.Close(); + + // CMPXMedia default types + iMedia->SetTObjectValueL( KMPXMediaGeneralType, + EMPXItem ); + iMedia->SetTObjectValueL( KMPXMediaGeneralCategory, + EMPXSong ); + + TParsePtrC parse( iFileName ); + // Title, default is file name + iMedia->SetTextValueL( KMPXMediaGeneralTitle, + parse.Name() ); + // Default album track + iMedia->SetTextValueL( KMPXMediaMusicAlbumTrack, + KNullDesC ); + + // Set the Mime Type and collection UID + // + if( !iMetadataOnly ) + { + TInt index(KErrNotFound); + TInt count( iSupportedTypes.Count() ); + for (TInt i=0; i Extensions(); + const TDesC& ext = parse.Ext(); + if (!exts.FindIsq(ext, index2)) + { // found + index = i; + break; + } + } + if( KErrNotFound != index ) + { + MPX_DEBUG1("CMPXMetadataExtractor::DoCreateMediaL apparc <---" ); + TInt mimeIndex = SupportedContainerTypeL( iFileName, index ); + User::LeaveIfError( mimeIndex ); + MPX_DEBUG1("CMPXMetadataExtractor::DoCreateMediaL apparc --->" ); + + iMedia->SetTextValueL( KMPXMediaGeneralMimeType, + iSupportedTypes[index]->Mimetypes()[mimeIndex] ); + + iMedia->SetTObjectValueL( KMPXMediaGeneralCollectionId, + iSupportedTypes[index]->Uid() ); + } + else + { + User::Leave(KErrNotSupported); + } + } + else // other case use apparc to fetch and set mimetype + { + TDataType dataType; + TUid dummyUid(KNullUid); + iAppArc.AppForDocument(iFileName, dummyUid, dataType); + iMedia->SetTextValueL( KMPXMediaGeneralMimeType,dataType.Des() ); + } + + // Initially set default tags. + SetDefaultL( *iMedia ); + } + +// ---------------------------------------------------------------------------- +// Execute task at index 0. +// ---------------------------------------------------------------------------- +void CMPXMetadataExtractor::ExecuteTaskL() + { + MPX_FUNC("CMPXMetadataExtractor::ExecuteTasksL()"); + + if ( iArrayTasks.Count() ) + { + switch ( iArrayTasks[0] ) + { + case ETaskCreateMedia: + DoCreateMediaL(); + break; + case ETaskAddMetadata: + SetMediaPropertiesL(); + break; + case ETaskAddExtMetadata: + SetExtMediaPropertiesL(); + break; + case ETaskAddAlbumArt: + AddMediaAlbumArtL( *iMedia, iFileName ); + break; + case ETaskCheckBeforeSend: + CheckBeforeSendRequest(); + break; + default: + MPX_ASSERT(0); // Should never get here + } + } + } + +// --------------------------------------------------------------------------- +// Constructs a media properties object : asynchronous funcion +// --------------------------------------------------------------------------- +// +EXPORT_C void CMPXMetadataExtractor::CreateMediaAsyncL( const TDesC& aFile, + MMPXMetadataExtractorObserver* aObs, + TBool aMetadataOnly ) + { + MPX_FUNC("CMPXMetadataExtractor::CreateMediaAsyncL()"); + // check if we are still processing a request. + if ( iArrayTasks.Count() ) + { + MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaAsyncL Request ongoing. Abort!" ); + User::Leave( KErrAbort ); + } + + iCancelled = EFalse; + iFileOpenError = KErrNone; + iFileName = aFile; + iObs = aObs; + iMetadataOnly = aMetadataOnly; + + // populate the task array + AddTasksL(); + + // Start task timer to execute task + if ( iArrayTasks.Count() ) + { + if ( iTaskTimer->IsActive() ) + { + iTaskTimer->Cancel(); + } + iTaskTimer->Start( 0, 0, TCallBack(TaskTimerCallback, this )); + } + } + +// --------------------------------------------------------------------------- +// Opens the file +// --------------------------------------------------------------------------- +// +TInt CMPXMetadataExtractor::OpenFile() + { + MPX_FUNC("CMPXMetadataExtractor::OpenFile()"); + + // Open the file + iFile.Close(); + TInt error = iFile.Open( iFs, iFileName, EFileRead | EFileShareReadersOrWriters ); + MPX_DEBUG2("CMPXMetadataExtractor::OpenFile open error = %d", error ); + return error; + } + +// --------------------------------------------------------------------------- +// Populat task array +// --------------------------------------------------------------------------- +// +void CMPXMetadataExtractor::AddTasksL() + { + MPX_FUNC("CMPXMetadataExtractor::AddTasks()"); + iFileOpenError = OpenFile(); + + // Do not change the order of the task below. + iArrayTasks.Reset(); + if ( iFileOpenError == KErrNone ) + { + iArrayTasks.AppendL(ETaskCreateMedia); + iArrayTasks.AppendL(ETaskAddMetadata); + iArrayTasks.AppendL(ETaskCheckBeforeSend); + iArrayTasks.AppendL(ETaskAddAlbumArt); + iArrayTasks.AppendL(ETaskAddExtMetadata); + } + else + { + iArrayTasks.AppendL(ETaskCreateMedia); + iArrayTasks.AppendL(ETaskAddExtMetadata); + } + } + +// ---------------------------------------------------------------------------- +// Callback for timer. +// ---------------------------------------------------------------------------- +TInt CMPXMetadataExtractor::TaskTimerCallback(TAny* aPtr) + { + MPX_FUNC("CMPXMetadataExtractor::TaskTimerCallback()"); + + CMPXMetadataExtractor* ptr = + static_cast(aPtr); + + ptr->HandleTaskTimerExpired(); + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// Handle task timer expired +// ---------------------------------------------------------------------------- +void CMPXMetadataExtractor::HandleTaskTimerExpired() + { + MPX_FUNC("CMPXMetadataExtractor::HandleTaskTimerExpired()"); + + iTaskTimer->Cancel(); + // execute task at index 0 + TRAPD( error, ExecuteTaskL() ); + if ( error || iCancelled ) + { + // cleanup + if ( iMedia != NULL ) + { + delete iMedia; + iMedia = NULL; + } + iArrayTasks.Reset(); + } + + // Remove task at index 0. + if ( iArrayTasks.Count() ) + { + iArrayTasks.Remove( 0 ); + } + + // check if we have any more task to run + if ( iArrayTasks.Count() ) + { + // start task timer + iTaskTimer->Start( 0, 0, TCallBack(TaskTimerCallback, this )); + } + else + { + // done + if ( iObs && !iCancelled ) + { + iObs->HandleCreateMediaComplete( iMedia, error ); + } + + CleanUp(); + } + } + +// ---------------------------------------------------------------------------- +// Callback for timer. +// ---------------------------------------------------------------------------- +void CMPXMetadataExtractor::CleanUp() + { + MPX_FUNC("CMPXMetadataExtractor::CleanUp()"); + // Reset the utility + TRAP_IGNORE( iMetadataUtility->ResetL() ); + iFile.Close(); + } +