mmserv/metadatautility/Src/MetaDataParserMP4.cpp
changeset 0 71ca22bcf22a
child 43 9894ed580e4a
--- /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	<e32svr.h>
+#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, &timescale, &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