diff -r 000000000000 -r 71ca22bcf22a mmserv/metadatautility/Src/MetaDataParserMP4.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmserv/metadatautility/Src/MetaDataParserMP4.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,248 @@ +/* +* Copyright (c) 2004 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: This class implements an MP4 metadata parser +* +*/ + + + +// INCLUDE FILES +#include "MetaDataParserMP4.h" +#ifdef _DEBUG +#include +#endif + +const TUint KCustomFileBufferSize = 10*1024; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::CMetaDataParserMP4 +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMetaDataParserMP4::CMetaDataParserMP4() + : iMP4Handle(NULL) + { + } + +// Destructor +CMetaDataParserMP4::~CMetaDataParserMP4() + { + MP4ParseClose(iMP4Handle); + if ( iExists ) + { + delete iCharacterSet; + iFs.Close(); + } + } + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::InitializeFileL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMetaDataParserMP4::InitializeFileL( + ContentAccess::CData *aData ) + { + MP4Err err; + //TBuf<256> name(aFileName); + err = MP4ParseOpenCAF(&iMP4Handle, aData); +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserMP4::InitializeFileL - MP4ParseOpen err = %d"), err); +#endif + User::LeaveIfError(TranslateMP4Err(err)); + MP4SetCustomFileBufferSizes( iMP4Handle, 0, 0, KCustomFileBufferSize); + if ( ValidateL() ) + { + User::LeaveIfError(iFs.Connect()); + // Get list of charconv supported character sets + iCharacterSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs); + } +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserMP4::InitializeFileL - Done")); +#endif + } + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::InitializeDesL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMetaDataParserMP4::InitializeDesL( + const TDesC8& aDes ) + { + MP4Err err; + err = MP4ParseOpen(&iMP4Handle, NULL); +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserMP4::InitializeDesL - MP4ParseOpen err = %d"), err); +#endif + User::LeaveIfError(TranslateMP4Err(err)); + + TUint8* buffer = CONST_CAST(TUint8*, aDes.Ptr()); + err = MP4ParseWriteData(iMP4Handle, buffer, aDes.Size()); + User::LeaveIfError(TranslateMP4Err(err)); + + // This call with empty buffer indicates to the MP4 library that this is the last buffer. + err = MP4ParseWriteData(iMP4Handle, NULL, 0); + User::LeaveIfError(TranslateMP4Err(err)); + + if ( ValidateL() ) + { + User::LeaveIfError(iFs.Connect()); + // Get list of charconv supported character sets + iCharacterSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs); + } +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserMP4::InitializeDesL - Done")); +#endif + } + + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::TranslateMP4Err +// ----------------------------------------------------------------------------- +// +TInt CMetaDataParserMP4::TranslateMP4Err( + MP4Err aError ) + { +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserMP4::TranslateMP4Err [%d]"), aError); +#endif + TInt err; + switch ( aError ) + { + case MP4_OK: + err = KErrNone; + break; + case MP4_OUT_OF_MEMORY: + err = KErrNoMemory; + break; + case MP4_NOT_AVAILABLE: + case MP4_UDTA_NOT_FOUND: + err = KErrNotReady; + break; + case MP4_FILE_ERROR: + err = KErrBadHandle; + break; + case MP4_INVALID_TYPE: + err = KErrNotSupported; + break; + case MP4_TIMESCALE_NOT_SET: + err = KErrNotReady; + break; + case MP4_NOT_STREAMABLE: + case MP4_NO_REQUESTED_FRAME: + case MP4_CANT_SEEK: + case MP4_INVALID_INPUT_STREAM: + case MP4_NO_FRAME: + err = KErrArgument; + break; + case MP4_ERROR: + case MP4_FILE_MODE: + case MP4_BUFFER_TOO_SMALL: + case MP4_END_OF_VIDEO: + case MP4_METADATA_ERROR: + case MP4_NO_VIDEO: + case MP4_NO_AUDIO: + err = KErrGeneral; + break; + default: + err = KErrGeneral; + break; + } + return err; + } + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::GetDurationL +// ----------------------------------------------------------------------------- +// +void CMetaDataParserMP4::GetDurationL( + TMetaDataFieldId aFieldId ) + { +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParser3gp::GetDurationL")); +#endif + MP4Err err; + mp4_u32 audiolength = 0; + mp4_u32 audiotype = 0; + mp4_u8 framespersample = 0; + mp4_u32 timescale = 0; + mp4_u32 averagebitrate = 0; + err = MP4ParseRequestAudioDescription(iMP4Handle, &audiolength, &audiotype, &framespersample, ×cale, &averagebitrate); + if(err == MP4_OK) + { + TBuf16<10> data16; + TReal duration = (TReal)audiolength / 1000; // seconds + TRealFormat realFormat(9, 3); + data16.AppendNum(duration, realFormat); + iContainer->AppendL( aFieldId, data16); + } + } + + +// ----------------------------------------------------------------------------- +// CMetaDataParserMP4::ConvertToUnicodeL +// ----------------------------------------------------------------------------- +// +TInt CMetaDataParserMP4::ConvertToUnicodeL( + const TDesC8& aDesc, + TDes16& aUnicode ) + { + TPtrC8 unicodeData; + TUint characterSetId = 0; + CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC(); + TInt state = CCnvCharacterSetConverter::KStateDefault; + + TInt bom = UnicodeBOM(aDesc); + if ( bom == KUnicodeBOMBigEndian ) + { + // UTF-16 Big Endian with BOM + // characterSetId = KCharacterSetIdentifierUcs2; + TPtrC8 text = StripTrailingZeroes(aDesc, 1); + characterSetId = KCharacterSetIdentifierUnicodeBig; + // Skip BOM & Terminate marks + unicodeData.Set( text.Mid(2) ); + } + else if ( bom == KUnicodeBOMLittleEndian ) + { + // UTF-16 Big Endian with BOM + characterSetId = KCharacterSetIdentifierUnicodeLittle; + TPtrC8 text = StripTrailingZeroes(aDesc, 1); + // Skip BOM & Terminate marks + unicodeData.Set( text.Mid( 2) ); + } + else // KUnicodeBOMNotFound + { + // UTF-8 + TPtrC8 text = StripTrailingZeroes(aDesc, 0); + characterSetId = KCharacterSetIdentifierUtf8; + unicodeData.Set( text ); + } + + charSetConv->PrepareToConvertToOrFromL(characterSetId, *iCharacterSet, iFs); + TInt err = charSetConv->ConvertToUnicode(aUnicode, unicodeData, state); + +#ifdef _DEBUG + RDebug::Print(_L("CMetaDataParserID3v24::ConvertToUnicode :-> Tag Size[%d] Unicode Tag Size[%d]Bytes Unconverted[%d]"), + unicodeData.Length(), aUnicode.Length(), err); +#endif + + CleanupStack::PopAndDestroy(); // charSetConv + return err; + } + +// End of File