|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Extracts metadata from a file |
|
15 * Version : %version: da1mmcf#38.1.4.2.6.1.5 % << Don't touch! Updated by Synergy at check-out. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <e32base.h> |
|
21 #include <badesca.h> |
|
22 #include <apgcli.h> |
|
23 #include <MetaDataUtility.h> |
|
24 #include <MetaDataFieldContainer.h> |
|
25 |
|
26 #ifdef RD_MPX_TNM_INTEGRATION |
|
27 #include <hash.h> |
|
28 #include <f32file.h> |
|
29 #include <sysutil.h> |
|
30 #include <thumbnailmanager.h> |
|
31 #endif //RD_MPX_TNM_INTEGRATION |
|
32 |
|
33 |
|
34 #include <mpxlog.h> |
|
35 #include <mpxmedia.h> |
|
36 #include <mpxcollectionpath.h> |
|
37 #include <mpxcollectiontype.h> |
|
38 #include <mpxdrmmediautility.h> |
|
39 |
|
40 #include <mpxmediamusicdefs.h> |
|
41 #include <mpxmediageneraldefs.h> |
|
42 #include <mpxmediaaudiodefs.h> |
|
43 #include <mpxmediadrmdefs.h> |
|
44 #include <mpxmediamtpdefs.h> |
|
45 |
|
46 #include "mpxmetadataextractor.h" |
|
47 #include "mpxfileinfoutility.h" |
|
48 #ifdef RD_MPX_TNM_INTEGRATION |
|
49 _LIT( KImageFileType, "image/jpeg" ); |
|
50 const TInt KMPXTimeoutTimer = 3000000; // 3 seconds |
|
51 const TInt KMPXMaxThumbnailRequest = 5; |
|
52 #endif //RD_MPX_TNM_INTEGRATION |
|
53 |
|
54 //Helper functions |
|
55 static void FindAndReplaceForbiddenChars(TDes& aString, TInt aLen) |
|
56 { |
|
57 MPX_ASSERT(aLen == aString.Length()); |
|
58 |
|
59 for (TInt i = 0; i < aLen; ++i) |
|
60 { |
|
61 if (aString[i] == TText('\t')) |
|
62 { |
|
63 aString[i] = TText(' '); |
|
64 } |
|
65 } |
|
66 } |
|
67 |
|
68 // --------------------------------------------------------------------------- |
|
69 // Constructor |
|
70 // --------------------------------------------------------------------------- |
|
71 // |
|
72 CMPXMetadataExtractor::CMPXMetadataExtractor( |
|
73 RFs& aFs, |
|
74 RApaLsSession& aAppArc, |
|
75 RPointerArray<CMPXCollectionType>& aTypes ) |
|
76 : iFs( aFs ), |
|
77 iAppArc( aAppArc ), |
|
78 iSupportedTypes( aTypes ), |
|
79 iOutstandingThumbnailRequest(0), |
|
80 iTNMBlockCount(0) |
|
81 { |
|
82 |
|
83 } |
|
84 |
|
85 |
|
86 // --------------------------------------------------------------------------- |
|
87 // 2nd Phase Constructor |
|
88 // --------------------------------------------------------------------------- |
|
89 // |
|
90 void CMPXMetadataExtractor::ConstructL() |
|
91 { |
|
92 iMetadataUtility = CMetaDataUtility::NewL(); |
|
93 iDrmMediaUtility = CMPXDrmMediaUtility::NewL(); |
|
94 iFileInfoUtil = CMPXFileInfoUtility::NewL(); |
|
95 |
|
96 #ifdef RD_MPX_TNM_INTEGRATION |
|
97 // Create Thumbnail Manager instance. This object is the observer. |
|
98 iTNManager = CThumbnailManager::NewL( *this ); |
|
99 iTNManager->SetFlagsL( CThumbnailManager::EDefaultFlags ); |
|
100 iTNManager->SetQualityPreferenceL( CThumbnailManager::EOptimizeForQuality); |
|
101 // create wait loop |
|
102 iTNSyncWait = new (ELeave) CActiveSchedulerWait; |
|
103 iTimer = CPeriodic::NewL( CActive::EPriorityIdle ); |
|
104 #endif //RD_MPX_TNM_INTEGRATION |
|
105 } |
|
106 |
|
107 // --------------------------------------------------------------------------- |
|
108 // Two-Phased Constructor |
|
109 // --------------------------------------------------------------------------- |
|
110 // |
|
111 EXPORT_C CMPXMetadataExtractor* CMPXMetadataExtractor::NewL( |
|
112 RFs& aFs, |
|
113 RApaLsSession& aAppArc, |
|
114 RPointerArray<CMPXCollectionType>& aTypes ) |
|
115 { |
|
116 CMPXMetadataExtractor* self = new( ELeave ) CMPXMetadataExtractor( aFs, |
|
117 aAppArc, |
|
118 aTypes ); |
|
119 CleanupStack::PushL( self ); |
|
120 self->ConstructL(); |
|
121 CleanupStack::Pop( self ); |
|
122 return self; |
|
123 } |
|
124 |
|
125 |
|
126 // --------------------------------------------------------------------------- |
|
127 // Destructor |
|
128 // --------------------------------------------------------------------------- |
|
129 // |
|
130 CMPXMetadataExtractor::~CMPXMetadataExtractor() |
|
131 { |
|
132 delete iMetadataUtility; |
|
133 delete iFileInfoUtil; |
|
134 delete iDrmMediaUtility; |
|
135 #ifdef RD_MPX_TNM_INTEGRATION |
|
136 delete iTNManager; |
|
137 if (iTNSyncWait && iTNSyncWait->IsStarted() ) |
|
138 { |
|
139 iTNSyncWait->AsyncStop(); |
|
140 } |
|
141 delete iTNSyncWait; |
|
142 delete iTimer; |
|
143 #endif //RD_MPX_TNM_INTEGRATION |
|
144 |
|
145 MPX_DEBUG2("CMPXMetadataExtractor: TNM Block Count: %d ", iTNMBlockCount ); |
|
146 } |
|
147 |
|
148 // --------------------------------------------------------------------------- |
|
149 // Constructs a media properties object |
|
150 // --------------------------------------------------------------------------- |
|
151 // |
|
152 EXPORT_C void CMPXMetadataExtractor::CreateMediaL( const TDesC& aFile, |
|
153 CMPXMedia*& aNewProperty, |
|
154 TBool aMetadataOnly ) |
|
155 { |
|
156 // make a copy of aFile |
|
157 HBufC* fileName = HBufC::NewL(KMaxFileName); |
|
158 CleanupStack::PushL( fileName ); |
|
159 fileName->Des().Append( aFile ); |
|
160 MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL %S <---", fileName ); |
|
161 |
|
162 RArray<TInt> contentIDs; |
|
163 contentIDs.AppendL( KMPXMediaIdGeneral ); |
|
164 contentIDs.AppendL( KMPXMediaIdAudio ); |
|
165 contentIDs.AppendL( KMPXMediaIdMusic ); |
|
166 contentIDs.AppendL( KMPXMediaIdDrm ); |
|
167 contentIDs.AppendL( KMPXMediaIdMTP ); |
|
168 aNewProperty = NULL; |
|
169 CMPXMedia* media = CMPXMedia::NewL( contentIDs.Array() ); |
|
170 CleanupStack::PushL( media ); |
|
171 contentIDs.Close(); |
|
172 |
|
173 // CMPXMedia default types |
|
174 |
|
175 media->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, |
|
176 EMPXItem ); |
|
177 media->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, |
|
178 EMPXSong ); |
|
179 |
|
180 TParsePtrC parse( *fileName ); |
|
181 |
|
182 // Title, default is file name |
|
183 media->SetTextValueL( KMPXMediaGeneralTitle, |
|
184 parse.Name() ); |
|
185 |
|
186 // Default album track |
|
187 media->SetTextValueL( KMPXMediaMusicAlbumTrack, |
|
188 KNullDesC ); |
|
189 |
|
190 // Set the Mime Type and collection UID |
|
191 // |
|
192 if( !aMetadataOnly ) |
|
193 { |
|
194 TInt index(KErrNotFound); |
|
195 TInt count( iSupportedTypes.Count() ); |
|
196 for (TInt i=0; i <count; ++i) |
|
197 { |
|
198 TInt index2(KErrNotFound); |
|
199 const CDesCArray& exts = iSupportedTypes[i]->Extensions(); |
|
200 const TDesC& ext = parse.Ext(); |
|
201 if (!exts.FindIsq(ext, index2)) |
|
202 { // found |
|
203 index = i; |
|
204 break; |
|
205 } |
|
206 } |
|
207 if( KErrNotFound != index ) |
|
208 { |
|
209 MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc <---" ); |
|
210 TInt mimeIndex = SupportedContainerTypeL( *fileName, index ); |
|
211 User::LeaveIfError( mimeIndex ); |
|
212 MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc --->" ); |
|
213 |
|
214 media->SetTextValueL( KMPXMediaGeneralMimeType, |
|
215 iSupportedTypes[index]->Mimetypes()[mimeIndex] ); |
|
216 |
|
217 media->SetTObjectValueL( KMPXMediaGeneralCollectionId, |
|
218 iSupportedTypes[index]->Uid() ); |
|
219 } |
|
220 else |
|
221 { |
|
222 User::Leave(KErrNotSupported); |
|
223 } |
|
224 } |
|
225 else // other case use apparc to fetch and set mimetype |
|
226 { |
|
227 TDataType dataType; |
|
228 TUid dummyUid(KNullUid); |
|
229 iAppArc.AppForDocument(*fileName, dummyUid, dataType); |
|
230 media->SetTextValueL( KMPXMediaGeneralMimeType,dataType.Des() ); |
|
231 } |
|
232 |
|
233 // Use file handle here |
|
234 // |
|
235 RFile file; |
|
236 TInt err = file.Open( iFs, *fileName, EFileRead | EFileShareReadersOrWriters ); |
|
237 CleanupClosePushL(file); |
|
238 |
|
239 // Metadata related |
|
240 // |
|
241 if( err == KErrNone ) |
|
242 { |
|
243 const TDesC& mimeType = media->ValueText( KMPXMediaGeneralMimeType ); |
|
244 HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() ); |
|
245 mimeType8->Des().Append( mimeType ); |
|
246 TRAPD( metadataerror, iMetadataUtility->OpenFileL( file, *mimeType8 ) ); |
|
247 CleanupStack::PopAndDestroy( mimeType8 ); |
|
248 |
|
249 // No problem |
|
250 if( KErrNone == metadataerror ) |
|
251 { |
|
252 // Add TRAPD to capture exception KErrNoMemory. |
|
253 //If album art size is too large, trap this exception and SetDefaultL. |
|
254 //Fix EYLU-7ESE5L |
|
255 TRAPD( err, SetMediaPropertiesL( *media, *fileName ) ); |
|
256 if ( KErrNoMemory == err ) |
|
257 { |
|
258 SetDefaultL( *media ); |
|
259 } |
|
260 } |
|
261 else // Error, Set defaults |
|
262 { |
|
263 SetDefaultL( *media ); |
|
264 } |
|
265 |
|
266 // Reset the utility |
|
267 iMetadataUtility->ResetL(); |
|
268 } |
|
269 else // Error, Set defaults |
|
270 { |
|
271 SetDefaultL( *media ); |
|
272 } |
|
273 |
|
274 // Common properties that we can extract |
|
275 // |
|
276 SetExtMediaPropertiesL( *media, *fileName, aMetadataOnly, file, err ); |
|
277 CleanupStack::PopAndDestroy(&file); |
|
278 |
|
279 // Set the pointers now that the object is ready |
|
280 // |
|
281 CleanupStack::Pop( media ); |
|
282 aNewProperty = media; |
|
283 |
|
284 CleanupStack::PopAndDestroy( fileName ); |
|
285 MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL --->"); |
|
286 } |
|
287 |
|
288 // --------------------------------------------------------------------------- |
|
289 // Sets all of the default media properties |
|
290 // --------------------------------------------------------------------------- |
|
291 // |
|
292 void CMPXMetadataExtractor::SetDefaultL( CMPXMedia& aMediaProp ) |
|
293 { |
|
294 // Comment |
|
295 aMediaProp.SetTextValueL( KMPXMediaGeneralComment, |
|
296 KNullDesC ); |
|
297 // Artist |
|
298 aMediaProp.SetTextValueL( KMPXMediaMusicArtist, |
|
299 KNullDesC ); |
|
300 // Album |
|
301 aMediaProp.SetTextValueL( KMPXMediaMusicAlbum, |
|
302 KNullDesC ); |
|
303 // Year |
|
304 aMediaProp.SetTObjectValueL<TInt64>( KMPXMediaMusicYear, |
|
305 (TInt64) 0 ); |
|
306 // Track |
|
307 aMediaProp.SetTextValueL( KMPXMediaMusicAlbumTrack, |
|
308 KNullDesC ); |
|
309 // Genre |
|
310 aMediaProp.SetTextValueL( KMPXMediaMusicGenre, |
|
311 KNullDesC ); |
|
312 // Composer |
|
313 aMediaProp.SetTextValueL( KMPXMediaMusicComposer, |
|
314 KNullDesC ); |
|
315 // Album artFilename |
|
316 aMediaProp.SetTextValueL( KMPXMediaMusicAlbumArtFileName, |
|
317 KNullDesC ); |
|
318 // URL |
|
319 aMediaProp.SetTextValueL( KMPXMediaMusicURL, |
|
320 KNullDesC ); |
|
321 } |
|
322 |
|
323 // --------------------------------------------------------------------------- |
|
324 // Sets media object attributes from metadata utilities |
|
325 // --------------------------------------------------------------------------- |
|
326 // |
|
327 void CMPXMetadataExtractor::SetMediaPropertiesL( CMPXMedia& aMedia, |
|
328 const TDesC& aFile ) |
|
329 { |
|
330 MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL <---" ); |
|
331 |
|
332 const CMetaDataFieldContainer& metaCont = |
|
333 iMetadataUtility->MetaDataFieldsL(); |
|
334 TInt count( metaCont.Count() ); |
|
335 for( TInt i=0; i<count; ++i ) |
|
336 { |
|
337 TMetaDataFieldId fieldType; |
|
338 |
|
339 HBufC* value = NULL; |
|
340 TRAPD( err, value = metaCont.At( i, fieldType ).AllocL() ); |
|
341 CleanupStack::PushL(value); |
|
342 if ( KErrNone != err ) |
|
343 { |
|
344 CleanupStack::PopAndDestroy(value); |
|
345 continue; |
|
346 } |
|
347 |
|
348 switch( fieldType ) |
|
349 { |
|
350 case EMetaDataSongTitle: |
|
351 { |
|
352 TPtr valptr = value->Des(); |
|
353 valptr.Trim(); |
|
354 TInt vallen = value->Length(); |
|
355 if (vallen>0) |
|
356 { |
|
357 FindAndReplaceForbiddenChars(valptr, vallen); |
|
358 aMedia.SetTextValueL(KMPXMediaGeneralTitle, *value); |
|
359 } |
|
360 break; |
|
361 } |
|
362 case EMetaDataArtist: |
|
363 { |
|
364 TPtr valptr = value->Des(); |
|
365 valptr.Trim(); |
|
366 TInt vallen = value->Length(); |
|
367 if (vallen>0) |
|
368 { |
|
369 FindAndReplaceForbiddenChars(valptr, vallen); |
|
370 aMedia.SetTextValueL(KMPXMediaMusicArtist, *value); |
|
371 } |
|
372 break; |
|
373 } |
|
374 case EMetaDataAlbum: |
|
375 { |
|
376 TPtr valptr = value->Des(); |
|
377 valptr.Trim(); |
|
378 TInt vallen = value->Length(); |
|
379 if (vallen>0) |
|
380 { |
|
381 FindAndReplaceForbiddenChars(valptr, vallen); |
|
382 aMedia.SetTextValueL(KMPXMediaMusicAlbum, *value ); |
|
383 } |
|
384 break; |
|
385 } |
|
386 case EMetaDataYear: |
|
387 { |
|
388 // Perform the date time conversion |
|
389 TLex lexer( *value ); |
|
390 TInt year( 0 ); |
|
391 lexer.Val( year ); |
|
392 |
|
393 // Convert from TInt -> TDateTime -> TTime -> TInt64 |
|
394 TDateTime dt; |
|
395 dt.SetYear( year ); |
|
396 TTime time( dt ); |
|
397 aMedia.SetTObjectValueL<TInt64>( KMPXMediaMusicYear, |
|
398 time.Int64() ); |
|
399 break; |
|
400 } |
|
401 case EMetaDataComment: |
|
402 { |
|
403 aMedia.SetTextValueL( KMPXMediaGeneralComment, |
|
404 *value ); |
|
405 break; |
|
406 } |
|
407 case EMetaDataAlbumTrack: |
|
408 { |
|
409 aMedia.SetTextValueL( KMPXMediaMusicAlbumTrack, |
|
410 *value ); |
|
411 break; |
|
412 } |
|
413 case EMetaDataGenre: |
|
414 { |
|
415 TPtr valptr = value->Des(); |
|
416 valptr.Trim(); |
|
417 TInt vallen = value->Length(); |
|
418 if (vallen>0) |
|
419 { |
|
420 FindAndReplaceForbiddenChars(valptr, vallen); |
|
421 aMedia.SetTextValueL(KMPXMediaMusicGenre, *value); |
|
422 } |
|
423 break; |
|
424 } |
|
425 case EMetaDataComposer: |
|
426 { |
|
427 TPtr valptr = value->Des(); |
|
428 valptr.Trim(); |
|
429 TInt vallen = value->Length(); |
|
430 if (vallen>0) |
|
431 { |
|
432 FindAndReplaceForbiddenChars(valptr, vallen); |
|
433 aMedia.SetTextValueL(KMPXMediaMusicComposer, *value); |
|
434 } |
|
435 break; |
|
436 } |
|
437 case EMetaDataUrl: |
|
438 case EMetaDataUserUrl: // fall through |
|
439 { |
|
440 aMedia.SetTextValueL( KMPXMediaMusicURL, |
|
441 *value ); |
|
442 break; |
|
443 } |
|
444 case EMetaDataJpeg: |
|
445 { |
|
446 #ifdef RD_MPX_TNM_INTEGRATION |
|
447 MPX_PERF_START(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM); |
|
448 HBufC8* value8 = MPXUser::Alloc8L(metaCont.At( i, fieldType )); |
|
449 CleanupStack::PushL( value8 ); |
|
450 AddMediaAlbumArtL( aMedia, aFile, *value8 ); |
|
451 CleanupStack::Pop(value8); |
|
452 MPX_PERF_END(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM); |
|
453 #else //RD_MPX_TNM_INTEGRATION |
|
454 aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, |
|
455 aFile ); |
|
456 #endif //RD_MPX_TNM_INTEGRATION |
|
457 break; |
|
458 } |
|
459 case EMetaDataCopyright: |
|
460 { |
|
461 aMedia.SetTextValueL( KMPXMediaGeneralCopyright, |
|
462 *value ); |
|
463 break; |
|
464 } |
|
465 case EMetaDataOriginalArtist: // fall through |
|
466 case EMetaDataVendor: // fall through |
|
467 case EMetaDataRating: // fall through |
|
468 case EMetaDataUniqueFileIdentifier: // fall through |
|
469 case EMetaDataDuration: // fall through |
|
470 case EMetaDataDate: // fall through |
|
471 { |
|
472 // not used |
|
473 break; |
|
474 } |
|
475 default: |
|
476 { |
|
477 //ASSERT(0); |
|
478 break; |
|
479 } |
|
480 } |
|
481 CleanupStack::PopAndDestroy(value); |
|
482 } |
|
483 |
|
484 MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL --->" ); |
|
485 } |
|
486 |
|
487 // --------------------------------------------------------------------------- |
|
488 // Sets extra media properties not returned by metadata utilities |
|
489 // --------------------------------------------------------------------------- |
|
490 // |
|
491 void CMPXMetadataExtractor::SetExtMediaPropertiesL( CMPXMedia& aProp, |
|
492 const TDesC& aFile, |
|
493 TBool aMetadataOnly, |
|
494 RFile& aFileHandle, |
|
495 TInt aFileErr ) |
|
496 { |
|
497 MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL <---"); |
|
498 |
|
499 // DB Flags to set |
|
500 // |
|
501 TUint dbFlags(KMPXMediaGeneralFlagsSetOrUnsetBit); |
|
502 |
|
503 // File Path |
|
504 // |
|
505 TParsePtrC parse( aFile ); |
|
506 aProp.SetTextValueL( KMPXMediaGeneralUri, |
|
507 aFile ); |
|
508 aProp.SetTextValueL( KMPXMediaGeneralDrive, |
|
509 parse.Drive() ); |
|
510 |
|
511 // DRM Rights |
|
512 // |
|
513 CMPXMedia* drm = NULL; |
|
514 TRAPD( drmError, iDrmMediaUtility->InitL( aFile ); |
|
515 drm = CMPXMedia::NewL( *iDrmMediaUtility->GetMediaL( KMPXMediaDrmProtected.iAttributeId | |
|
516 KMPXMediaDrmRightsStatus.iAttributeId ) ); |
|
517 ); |
|
518 |
|
519 TBool prot(EFalse); |
|
520 if( drm ) |
|
521 { |
|
522 CleanupStack::PushL( drm ); |
|
523 MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL -- is a drm file"); |
|
524 if( drm->IsSupported( KMPXMediaDrmProtected ) ) |
|
525 { |
|
526 prot = drm->ValueTObjectL<TBool>( KMPXMediaDrmProtected ); |
|
527 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL protected %i", prot); |
|
528 } |
|
529 |
|
530 TMPXMediaDrmRightsStatus status(EMPXDrmRightsFull); |
|
531 if( drm->IsSupported( KMPXMediaDrmRightsStatus ) ) |
|
532 { |
|
533 status = drm->ValueTObjectL<TMPXMediaDrmRightsStatus>(KMPXMediaDrmRightsStatus); |
|
534 aProp.SetTObjectValueL<TInt>(KMPXMediaDrmRightsStatus, status ); |
|
535 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- status %i", status); |
|
536 } |
|
537 |
|
538 // Set DB flags |
|
539 dbFlags |= KMPXMediaGeneralFlagsIsDrmProtected; |
|
540 if( status != EMPXDrmRightsFull && status != EMPXDrmRightsRestricted && status != EMPXDrmRightsPreview ) |
|
541 { |
|
542 dbFlags |= KMPXMediaGeneralFlagsIsDrmLicenceInvalid; |
|
543 } |
|
544 CleanupStack::PopAndDestroy( drm ); |
|
545 } |
|
546 |
|
547 // Trapped PV DRM error. If -46, we know the file has no rights |
|
548 // |
|
549 if( drmError == KErrPermissionDenied ) |
|
550 { |
|
551 dbFlags |= KMPXMediaGeneralFlagsIsDrmLicenceInvalid; |
|
552 } |
|
553 else |
|
554 { |
|
555 User::LeaveIfError( drmError ); |
|
556 } |
|
557 |
|
558 aProp.SetTObjectValueL<TBool>( KMPXMediaDrmProtected, prot ); |
|
559 aProp.SetTObjectValueL<TUint16>( KMPXMediaMTPDrmStatus, (TUint16)prot ); |
|
560 |
|
561 iDrmMediaUtility->Close(); |
|
562 |
|
563 // File Size |
|
564 // |
|
565 TInt size( 0 ); |
|
566 if( aFileErr == KErrNone ) |
|
567 { |
|
568 aFileHandle.Size( size ); |
|
569 aProp.SetTObjectValueL<TInt>( KMPXMediaGeneralSize, |
|
570 size ); |
|
571 |
|
572 // Duration, bitrate, samplerate, etc |
|
573 // |
|
574 if( !aMetadataOnly ) |
|
575 { |
|
576 TRAPD(err2, iFileInfoUtil->OpenFileL( |
|
577 aFileHandle, |
|
578 aProp.ValueText(KMPXMediaGeneralMimeType))); |
|
579 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, file info util error %i", err2); |
|
580 if( KErrNone == err2 ) |
|
581 { |
|
582 aProp.SetTObjectValueL<TUint>( KMPXMediaAudioBitrate, |
|
583 iFileInfoUtil->BitRate() ); |
|
584 aProp.SetTObjectValueL<TUint>( KMPXMediaAudioSamplerate, |
|
585 iFileInfoUtil->SampleRate() ); |
|
586 TInt64 duration = (TInt64) iFileInfoUtil->Duration().Int64() / 1000; // ms |
|
587 aProp.SetTObjectValueL<TInt32>( KMPXMediaGeneralDuration, |
|
588 duration ); |
|
589 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- duration %i", duration); |
|
590 } |
|
591 } |
|
592 } |
|
593 else if( aFileErr == KErrNotFound || aFileErr == KErrPathNotFound ) |
|
594 { |
|
595 dbFlags |= KMPXMediaGeneralFlagsIsInvalid; |
|
596 } |
|
597 // Finally set the db flag |
|
598 // |
|
599 aProp.SetTObjectValueL( KMPXMediaGeneralFlags, |
|
600 dbFlags ); |
|
601 |
|
602 iFileInfoUtil->Reset(); |
|
603 |
|
604 MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL --->"); |
|
605 } |
|
606 |
|
607 // --------------------------------------------------------------------------- |
|
608 // Check to see if this file is a supported container |
|
609 // --------------------------------------------------------------------------- |
|
610 // |
|
611 TInt CMPXMetadataExtractor::SupportedContainerTypeL( const TDesC& aFile, |
|
612 TInt aIndex ) |
|
613 { |
|
614 TInt index(KErrNotFound); |
|
615 |
|
616 TDataType dataType; |
|
617 TUid dummyUid(KNullUid); |
|
618 iAppArc.AppForDocument(aFile, dummyUid, dataType); |
|
619 |
|
620 TInt index2(KErrNotFound); |
|
621 const CDesCArray& mimeTypes = iSupportedTypes[aIndex]->Mimetypes(); |
|
622 if (!mimeTypes.FindIsq(dataType.Des(), index2)) |
|
623 { // found |
|
624 index = index2; |
|
625 } |
|
626 |
|
627 return ( index == KErrNotFound ? KErrNotSupported : index ); |
|
628 } |
|
629 |
|
630 |
|
631 // --------------------------------------------------------------------------- |
|
632 // CMPXMetadataExtractor::ThumbnailPreviewReady |
|
633 // Callback but not used here |
|
634 // --------------------------------------------------------------------------- |
|
635 void CMPXMetadataExtractor::ThumbnailPreviewReady( |
|
636 MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ ) |
|
637 { |
|
638 MPX_FUNC("CMPXMetadataExtractor::ThumbnailPreviewReady()"); |
|
639 } |
|
640 |
|
641 |
|
642 // --------------------------------------------------------------------------- |
|
643 // CMPXMetadataExtractor::ThumbnailReady |
|
644 // Callback but not used here |
|
645 // --------------------------------------------------------------------------- |
|
646 void CMPXMetadataExtractor::ThumbnailReady( TInt /*aError*/, |
|
647 MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ ) |
|
648 { |
|
649 MPX_FUNC("CMPXMetadataExtractor::ThumbnailReady()"); |
|
650 iOutstandingThumbnailRequest--; |
|
651 if ( iOutstandingThumbnailRequest <= KMPXMaxThumbnailRequest ) |
|
652 { |
|
653 StopWaitLoop(); |
|
654 } |
|
655 } |
|
656 |
|
657 // ---------------------------------------------------------------------------- |
|
658 // Callback for timer. |
|
659 // ---------------------------------------------------------------------------- |
|
660 TInt CMPXMetadataExtractor::TimeoutTimerCallback(TAny* aPtr) |
|
661 { |
|
662 MPX_FUNC("CMPXMetadataExtractor::TimeoutTimerCallback()"); |
|
663 |
|
664 CMPXMetadataExtractor* ptr = |
|
665 static_cast<CMPXMetadataExtractor*>(aPtr); |
|
666 |
|
667 // Timer expired before thumbnail callback occurred. Stop wait loop to unblock. |
|
668 ptr->StopWaitLoop(); |
|
669 return KErrNone; |
|
670 } |
|
671 |
|
672 // ---------------------------------------------------------------------------- |
|
673 // Stop the wait loop. |
|
674 // ---------------------------------------------------------------------------- |
|
675 void CMPXMetadataExtractor::StopWaitLoop() |
|
676 { |
|
677 MPX_FUNC("CMPXMetadataExtractor::StopWaitLoop()"); |
|
678 // Cancel timer |
|
679 CancelTimeoutTimer(); |
|
680 |
|
681 // Stop wait loop to unblock. |
|
682 if ( iTNSyncWait->IsStarted() ) |
|
683 { |
|
684 MPX_DEBUG1("CMPXMetadataExtractor::StopWaitLoop(): Stopping the wait loop."); |
|
685 iTNSyncWait->AsyncStop(); |
|
686 } |
|
687 } |
|
688 |
|
689 // ---------------------------------------------------------------------------- |
|
690 // Cancel timer. |
|
691 // ---------------------------------------------------------------------------- |
|
692 void CMPXMetadataExtractor::CancelTimeoutTimer() |
|
693 { |
|
694 MPX_FUNC("CMPXMetadataExtractor::CancelTimeoutTimer()"); |
|
695 |
|
696 // Cancel timer. |
|
697 if ( iTimer && iTimer->IsActive() ) |
|
698 { |
|
699 MPX_DEBUG1("CMPXMetadataExtractor::CancelTimeoutTimer(): Timer active, cancelling"); |
|
700 iTimer->Cancel(); |
|
701 } |
|
702 } |
|
703 |
|
704 // ---------------------------------------------------------------------------- |
|
705 // Extract album art from a file and add to thumbnail manager. |
|
706 // ---------------------------------------------------------------------------- |
|
707 EXPORT_C TInt CMPXMetadataExtractor::ExtractAlbumArtL( CMPXMedia* aMedia ) |
|
708 { |
|
709 MPX_FUNC("CMPXMetadataExtractor::ExtractAlbumArtL()"); |
|
710 TInt err = KErrNone; |
|
711 |
|
712 if ( !aMedia->IsSupported(KMPXMediaGeneralUri) ) |
|
713 { |
|
714 return KErrArgument; |
|
715 } |
|
716 |
|
717 // Get full file name. |
|
718 const TDesC& path = aMedia->ValueText(KMPXMediaGeneralUri); |
|
719 MPX_DEBUG2("CMPXMetadataExtractor::ExtractAlbumArtL Filename:%S ", &path ); |
|
720 |
|
721 // create wanted fields array |
|
722 RArray<TMetaDataFieldId> wantedFields; |
|
723 CleanupClosePushL( wantedFields ); |
|
724 wantedFields.Append(EMetaDataJpeg); |
|
725 |
|
726 // Open file |
|
727 if ( aMedia->IsSupported(KMPXMediaGeneralMimeType) ) |
|
728 { |
|
729 const TDesC& mimeType = aMedia->ValueText( KMPXMediaGeneralMimeType ); |
|
730 MPX_DEBUG2("CMPXMetadataExtractor::ExtractAlbumArtL MimeType:%S ", &mimeType ); |
|
731 HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() ); |
|
732 mimeType8->Des().Append( mimeType ); |
|
733 TRAP( err, iMetadataUtility->OpenFileL( path, wantedFields, *mimeType8 ) ); |
|
734 CleanupStack::PopAndDestroy( mimeType8 ); |
|
735 } |
|
736 else |
|
737 { |
|
738 TRAP( err, iMetadataUtility->OpenFileL( path, wantedFields ) ); |
|
739 } |
|
740 CleanupStack::PopAndDestroy( &wantedFields ); |
|
741 |
|
742 if ( !err ) |
|
743 { |
|
744 TRAP( err, GetMediaAlbumArtL( *aMedia, path )); |
|
745 } |
|
746 |
|
747 // Reset the utility |
|
748 iMetadataUtility->ResetL(); |
|
749 |
|
750 return err; |
|
751 } |
|
752 |
|
753 // ---------------------------------------------------------------------------- |
|
754 // Set album art. |
|
755 // ---------------------------------------------------------------------------- |
|
756 TInt CMPXMetadataExtractor::GetMediaAlbumArtL( CMPXMedia& aMedia, |
|
757 const TDesC& aFile ) |
|
758 { |
|
759 MPX_FUNC("CMPXMetadataExtractor::GetMediaAlbumArtL()"); |
|
760 TInt err = KErrNone; |
|
761 // get metadata container. |
|
762 const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL(); |
|
763 |
|
764 TPtrC data = metaCont.Field( EMetaDataJpeg ); |
|
765 |
|
766 if ( data.Length() ) |
|
767 { |
|
768 MPX_DEBUG1("CMPXMetadataExtractor::GetMediaAlbumArtL(): Album art exist."); |
|
769 #ifdef RD_MPX_TNM_INTEGRATION |
|
770 HBufC8* value8 = MPXUser::Alloc8L( data ); |
|
771 CleanupStack::PushL( value8 ); |
|
772 AddMediaAlbumArtL( aMedia, aFile, *value8 ); |
|
773 CleanupStack::Pop(value8); |
|
774 #else // RD_MPX_TNM_INTEGRATION |
|
775 aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile ); |
|
776 #endif // RD_MPX_TNM_INTEGRATION |
|
777 } |
|
778 else |
|
779 { |
|
780 err = KErrNotFound; |
|
781 } |
|
782 |
|
783 return err; |
|
784 } |
|
785 |
|
786 // ---------------------------------------------------------------------------- |
|
787 // Add album art to media object. |
|
788 // ---------------------------------------------------------------------------- |
|
789 void CMPXMetadataExtractor::AddMediaAlbumArtL( CMPXMedia& aMedia, |
|
790 const TDesC& aFile, |
|
791 TDesC8& aValue ) |
|
792 { |
|
793 MPX_FUNC("CMPXMetadataExtractor::AddMediaAlbumArtL()"); |
|
794 #ifdef RD_MPX_TNM_INTEGRATION |
|
795 |
|
796 // If thumbnail creation is ongoing, wait til it is done |
|
797 if ( iOutstandingThumbnailRequest > KMPXMaxThumbnailRequest ) |
|
798 { |
|
799 MPX_DEBUG1("CMPXMetadataExtractor::AddMediaAlbumArtL(): Thumbnail creation ongoing!"); |
|
800 iTNMBlockCount++; |
|
801 // Cancel timer. |
|
802 CancelTimeoutTimer(); |
|
803 // Start timer in case there is no callback from ThumbNail Manager. |
|
804 iTimer->Start( |
|
805 KMPXTimeoutTimer, |
|
806 KMPXTimeoutTimer, |
|
807 TCallBack(TimeoutTimerCallback, this )); |
|
808 |
|
809 // Start wait loop until we get a callback from ThumbNail Manager. |
|
810 if ( !iTNSyncWait->IsStarted() ) |
|
811 { |
|
812 iTNSyncWait->Start(); |
|
813 } |
|
814 } |
|
815 |
|
816 aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile ); |
|
817 |
|
818 TBuf<256> mimeType; |
|
819 mimeType.Copy( KImageFileType ); |
|
820 CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC( |
|
821 &aValue, mimeType, aFile ); |
|
822 iTNManager->CreateThumbnails( *source ); |
|
823 CleanupStack::PopAndDestroy( source ); |
|
824 aMedia.SetTextValueL( KMPXMediaMusicOriginalAlbumArtFileName, aFile ); |
|
825 iOutstandingThumbnailRequest++; |
|
826 |
|
827 #endif // RD_MPX_TNM_INTEGRATION |
|
828 } |