mmserv/metadatautility/Src/MetaDataParser3gp.cpp
changeset 0 71ca22bcf22a
child 28 ebf79c79991a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2004 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:  This class implements an 3gp metadata parser as specified in
       
    15 *                www.3gpp.org (specification 3GPP TS 26.244 V6.0.0).
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <centralrepository.h>
       
    23 #include "MetadataUtilityCRKeys.h"
       
    24 #include	"MetaDataParser3gp.h"
       
    25 #ifdef _DEBUG
       
    26 #include	<e32svr.h>
       
    27 #endif
       
    28 
       
    29 // CONSTANTS
       
    30 // ('udta'-box pecification found in www.3gpp.org, 3GPP TS 26.244)
       
    31 const TUint32 K3gpMetaTitle 		= 0x7469746c; 	// 'titl'
       
    32 const TUint32 K3gpMetaDescription 	= 0x64736370;	// 'dscp'
       
    33 const TUint32 K3gpMetaCopyright		= 0x63707274;	// 'cprt'
       
    34 const TUint32 K3gpMetaPerformer		= 0x70657266;	// 'perf'
       
    35 const TUint32 K3gpMetaAuthor		= 0x61757468;	// 'auth'
       
    36 const TUint32 K3gpMetaGenre			= 0x676e7265;	// 'gnre'
       
    37 const TUint32 K3gpMetaRating		= 0x72746e67;	// 'rtng'
       
    38 const TUint32 K3gpMetaAlbum			= 0x616c626d;	// 'albm' 
       
    39 const TUint32 K3gpMetaYear			= 0x79727263;	// 'yrrc'
       
    40 
       
    41 
       
    42 
       
    43 // ============================ MEMBER FUNCTIONS ===============================
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CMetaDataParser3gp::CMetaDataParser3gp
       
    47 // C++ default constructor can NOT contain any code, that
       
    48 // might leave.
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 CMetaDataParser3gp::CMetaDataParser3gp()
       
    52 	{
       
    53     }
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CMetaDataParser3gp::ConstructL
       
    57 // Symbian 2nd phase constructor can leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 void CMetaDataParser3gp::ConstructL()
       
    61     {
       
    62     // Check for Cenrep key
       
    63 	CRepository *metadataRepository = CRepository::NewL(KCRUidMetadataUtility);
       
    64 	TInt err = KErrNone;
       
    65 	iVFKK = EFalse;
       
    66 	err = metadataRepository->Get(KMetadataUtilityVFKKSpecificMapping, iVFKK);
       
    67 	if(err)
       
    68 		{
       
    69 		iVFKK = EFalse;	
       
    70 		}
       
    71 	delete metadataRepository;
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CMetaDataParser3gp::NewL
       
    76 // Two-phased constructor.
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CMetaDataParser3gp* CMetaDataParser3gp::NewL()
       
    80     {
       
    81 #ifdef _DEBUG
       
    82 	RDebug::Print(_L("CMetaDataParser3gp::NewL"));
       
    83 #endif
       
    84 	CMetaDataParser3gp* self = new( ELeave ) CMetaDataParser3gp;
       
    85     CleanupStack::PushL( self );
       
    86     self->ConstructL();
       
    87     CleanupStack::Pop();
       
    88     return self;
       
    89     }
       
    90 
       
    91 // Destructor
       
    92 CMetaDataParser3gp::~CMetaDataParser3gp()
       
    93 	{
       
    94 	
       
    95 	}
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // CMetaDataParser3gp::ParseL
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 void CMetaDataParser3gp::ParseL(
       
   102 	const RArray<TMetaDataFieldId>& aWantedFields,
       
   103 	CMetaDataFieldContainer& aContainer )
       
   104     {
       
   105 #ifdef _DEBUG
       
   106 	RDebug::Print(_L("CMetaDataParser3gp::ParseL"));
       
   107 #endif
       
   108 	iContainer = &aContainer;
       
   109 	TInt err = KErrNone; // ignore err, as some entry may be extracted without exception
       
   110 	if ( aWantedFields.Count() == 0 )
       
   111 		{
       
   112 		TRAP(err, GetAssetBoxL(K3gpMetaTitle, EMetaDataSongTitle));
       
   113 		TRAP(err, GetAssetBoxL(K3gpMetaDescription, EMetaDataComment));
       
   114 		TRAP(err, GetAssetBoxL(K3gpMetaCopyright, EMetaDataCopyright));
       
   115 		if(iVFKK)
       
   116 			{
       
   117 			TRAP(err, GetAssetBoxL(K3gpMetaAuthor, EMetaDataArtist));	
       
   118 			}
       
   119 		else // as per the spec
       
   120 			{
       
   121 			TRAP(err, GetAssetBoxL(K3gpMetaPerformer, EMetaDataArtist));
       
   122 			}
       
   123 		TRAP(err, GetAssetBoxL(K3gpMetaAuthor, EMetaDataComposer));	
       
   124 		TRAP(err, GetAssetBoxL(K3gpMetaGenre, EMetaDataGenre));
       
   125 		TRAP(err, GetDurationL(EMetaDataDuration));
       
   126 		TRAP(err, GetAssetBoxL(K3gpMetaRating, EMetaDataRating));
       
   127 		TRAP(err, GetAssetBoxL(K3gpMetaAlbum, EMetaDataAlbum));
       
   128 		TRAP(err, GetAssetBoxL(K3gpMetaAlbum, EMetaDataAlbumTrack));
       
   129 		TRAP(err, GetAssetBoxL(K3gpMetaYear, EMetaDataYear));
       
   130 		}
       
   131 	else
       
   132 		{
       
   133 		// Look for it in the wanted field array
       
   134 		TInt count( aWantedFields.Count() );
       
   135 		for ( TInt i = 0; i < count; i++ )
       
   136 			{
       
   137 			switch ( aWantedFields[ i ] )
       
   138 				{
       
   139 				case EMetaDataSongTitle:
       
   140 					TRAP(err, GetAssetBoxL(K3gpMetaTitle, EMetaDataSongTitle));
       
   141 					break;
       
   142 				case EMetaDataComment:
       
   143 					TRAP(err, GetAssetBoxL(K3gpMetaDescription, EMetaDataComment));
       
   144 					break;
       
   145 				case EMetaDataCopyright:
       
   146 					TRAP(err, GetAssetBoxL(K3gpMetaCopyright, EMetaDataCopyright));
       
   147 					break;
       
   148 				case EMetaDataArtist:
       
   149 					if(iVFKK)
       
   150 						{
       
   151 						TRAP(err, GetAssetBoxL(K3gpMetaAuthor, EMetaDataArtist));	
       
   152 						}
       
   153 					else // as per the spec
       
   154 						{
       
   155 						TRAP(err, GetAssetBoxL(K3gpMetaPerformer, EMetaDataArtist));
       
   156 						}
       
   157 					break;
       
   158 				case EMetaDataComposer:
       
   159 					TRAP(err, GetAssetBoxL(K3gpMetaAuthor, EMetaDataComposer));
       
   160 					break;
       
   161 				case EMetaDataGenre:
       
   162 					TRAP(err, GetAssetBoxL(K3gpMetaGenre, EMetaDataGenre));
       
   163 					break;
       
   164 				case EMetaDataDuration:
       
   165 					TRAP(err, GetDurationL(EMetaDataDuration));
       
   166 					break;
       
   167 				case EMetaDataRating:
       
   168 					TRAP(err, GetAssetBoxL(K3gpMetaRating, EMetaDataRating));
       
   169 					break;
       
   170 				case EMetaDataAlbum:
       
   171 					TRAP(err, GetAssetBoxL(K3gpMetaAlbum, EMetaDataAlbum));
       
   172 					break;
       
   173 				case EMetaDataAlbumTrack:
       
   174 					TRAP(err, GetAssetBoxL(K3gpMetaAlbum, EMetaDataAlbumTrack));
       
   175 					break;
       
   176 				case EMetaDataYear:
       
   177 					TRAP(err, GetAssetBoxL(K3gpMetaYear, EMetaDataYear));
       
   178 					break;
       
   179 				default:
       
   180 					break;
       
   181 				}
       
   182 			}
       
   183 		}
       
   184  	}
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // CMetaDataParser3gp::GetAssetBoxL
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 void CMetaDataParser3gp::GetAssetBoxL(
       
   191 	TUint32 aBoxType,
       
   192 	TMetaDataFieldId aFieldId )
       
   193 	{
       
   194 #ifdef _DEBUG
       
   195 	RDebug::Print(_L("CMetaDataParser3gp::GetAssetBoxL [%d]"), aBoxType);
       
   196 #endif
       
   197 
       
   198 	HBufC8* frame = HBufC8::NewLC( K3gpMetaLength );
       
   199 	TUint8* buffer = CONST_CAST(TUint8*, frame->Ptr());
       
   200 
       
   201 	MP4Err err;
       
   202 	mp4_u8 udtaLocation = MP4_UDTA_MOOV;
       
   203 	mp4_u32 bufferSize = K3gpMetaLength;
       
   204 	mp4_u32 atomIndex = 0;
       
   205 
       
   206 	err = MP4ParseGetUserDataAtom(iMP4Handle, udtaLocation, aBoxType, buffer,
       
   207 			bufferSize, atomIndex);
       
   208 	if ( err == MP4_UDTA_NOT_FOUND )
       
   209 		{
       
   210 		if ( udtaLocation == MP4_UDTA_NONE || udtaLocation == MP4_UDTA_MOOV )
       
   211 			{
       
   212 #ifdef _DEBUG
       
   213 	RDebug::Print(_L("CMetaDataParser3gp::GetAssetBoxL - NotFound"));
       
   214 #endif
       
   215 			CleanupStack::PopAndDestroy();  // frame
       
   216 			return;
       
   217 			}
       
   218 		else
       
   219 			{
       
   220 			if ( udtaLocation & MP4_UDTA_AUDIOTRAK )
       
   221 				{
       
   222 				udtaLocation = MP4_UDTA_AUDIOTRAK;
       
   223 				}
       
   224 			else 	// MP4_UDTA_VIDEOTRAK
       
   225 				{
       
   226 				udtaLocation = MP4_UDTA_VIDEOTRAK;
       
   227 				}
       
   228 			}
       
   229 #ifdef _DEBUG
       
   230 	RDebug::Print(_L("CMetaDataParser3gp::GetAssetBoxL - New Location [%d]"), udtaLocation);
       
   231 #endif
       
   232 		err = MP4ParseGetUserDataAtom(iMP4Handle, udtaLocation, aBoxType, buffer,
       
   233 			bufferSize, atomIndex);
       
   234 		}
       
   235 
       
   236 	if ( err != MP4_OK )
       
   237 		{
       
   238 		if ( err == MP4_OUTPUT_BUFFER_TOO_SMALL )
       
   239 			{
       
   240 			CleanupStack::PopAndDestroy();  // frame
       
   241 			frame = NULL;
       
   242 			frame = HBufC8::NewLC( bufferSize );
       
   243 			buffer = CONST_CAST(TUint8*, frame->Ptr());
       
   244 #ifdef _DEBUG
       
   245 	RDebug::Print(_L("CMetaDataParser3gp::GetAssetBoxL - Buffer re-alloc"));
       
   246 #endif
       
   247 			err = MP4ParseGetUserDataAtom(iMP4Handle, udtaLocation, aBoxType, buffer,
       
   248 					bufferSize, atomIndex);
       
   249 			User::LeaveIfError(TranslateMP4Err(err));
       
   250 			}
       
   251 		else
       
   252 			{
       
   253 			CleanupStack::PopAndDestroy();  // frame
       
   254 			return;
       
   255 			//User::Leave( TranslateMP4Err(err) );
       
   256 			}
       
   257 		}
       
   258 
       
   259 #ifdef _DEBUG
       
   260 	RDebug::Print(_L("CMetaDataParser3gp::GetAssetBoxL - Found"));
       
   261 #endif
       
   262 
       
   263 	TPtr8 des(buffer, bufferSize, bufferSize);
       
   264 	// Skip 12 bytes for year - refer to standard
       
   265 	if(aFieldId == EMetaDataYear)
       
   266 		{
       
   267 		des = des.MidTPtr(12);
       
   268 		if(des.Length() < 2)
       
   269 			{
       
   270 			// corrpupt tag
       
   271 			CleanupStack::PopAndDestroy();  // frame
       
   272 			return;
       
   273 			}
       
   274 		TBuf8<2> yearData;
       
   275 		yearData.Copy(des.MidTPtr(0, 2));
       
   276 		TUint yearInt = 0; 
       
   277 		for(TInt i = 0; i < 2; i++)
       
   278 			{
       
   279 			yearInt <<= 8;
       
   280 			yearInt |= yearData[i]; 
       
   281 			}
       
   282 		TBuf<5> year;
       
   283 		year.AppendNum(yearInt);
       
   284 		iContainer->AppendL( EMetaDataYear, year );
       
   285 		CleanupStack::PopAndDestroy();  // frame
       
   286 		return;
       
   287 		}
       
   288 	// Skip 14 bytes for other tags - refer to standard
       
   289 	des = des.MidTPtr(14);
       
   290 	if(aFieldId == EMetaDataRating)
       
   291 		{
       
   292 		// Skip 8 more bytes for rtng - refer to standard
       
   293 		des = des.MidTPtr(8); 
       
   294 		}
       
   295 	if(aFieldId == EMetaDataAlbumTrack)
       
   296 		{
       
   297 		// check if album track exists
       
   298 		if(des[des.Length() - 1] != '\0')
       
   299 			{
       
   300 			TBuf8<1> trackData;
       
   301 			trackData.Copy(des.MidTPtr(des.Length() - 1,1));
       
   302 			TUint trackInt = 0;
       
   303 			trackInt |= trackData[0]; 
       
   304 			TBuf<3> track;
       
   305 			track.AppendNum(trackInt);
       
   306 			iContainer->AppendL( EMetaDataAlbumTrack, track );
       
   307 			CleanupStack::PopAndDestroy();  // frame
       
   308 			return;
       
   309 			}
       
   310 		}
       
   311 	if(aFieldId == EMetaDataAlbum)
       
   312 		{
       
   313 		// check if album track exists
       
   314 		if(des[des.Length() - 1] != '\0')
       
   315 			{
       
   316 			des = des.MidTPtr(0,des.Length() - 2);
       
   317 			}
       
   318 		}
       
   319 	TInt length = des.Length();
       
   320 	if ( length )
       
   321 		{
       
   322 		HBufC* data16 = HBufC::NewLC( length );
       
   323 		TPtr unicode( data16->Des() );
       
   324 		if ( ConvertToUnicodeL(des, unicode) == KErrNone )
       
   325 			{
       
   326 			iContainer->AppendL( aFieldId, unicode );
       
   327 			}
       
   328 		CleanupStack::PopAndDestroy();  // data16
       
   329 		}
       
   330 
       
   331 	CleanupStack::PopAndDestroy();  // frame
       
   332 	}
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // CMetaDataParserMP4::ValidateL
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 TBool CMetaDataParser3gp::ValidateL()
       
   339 	{
       
   340 	mp4_u32 audioLength, audioType, timeScale, averateBitRate;
       
   341 	mp4_u8 framesPerSample;
       
   342 
       
   343 	MP4Err err;
       
   344 	err = MP4ParseRequestAudioDescription(iMP4Handle, &audioLength, &audioType,
       
   345 			&framesPerSample, &timeScale, &averateBitRate);
       
   346 	if ( err == MP4_OK )
       
   347 		{
       
   348 		iExists = ETrue;
       
   349 		return ETrue;
       
   350 		}
       
   351 
       
   352 	return EFalse;
       
   353 	}
       
   354 
       
   355 
       
   356 
       
   357 //  End of File