/*
* 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 3GPExt metadata parser
*
*/
// INCLUDE FILES
#include "MetaDataParser3GPExt.h"
#include "3GPExtParser.h"
#ifdef _DEBUG
#include <e32svr.h>
#endif
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::CMetaDataParser3GPExt
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CMetaDataParser3GPExt::CMetaDataParser3GPExt()
{
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CMetaDataParser3GPExt::ConstructL()
{
i3GPExtParser = C3GPExtParser::NewL(iMP4Handle);
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CMetaDataParser3GPExt* CMetaDataParser3GPExt::NewL()
{
#ifdef _DEBUG
RDebug::Print(_L("CMetaDataParser3GPExt::NewL"));
#endif
CMetaDataParser3GPExt* self = new( ELeave ) CMetaDataParser3GPExt;
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
// Destructor
CMetaDataParser3GPExt::~CMetaDataParser3GPExt()
{
delete i3GPExtParser;
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::ConvertAndAppendL
// -----------------------------------------------------------------------------
void CMetaDataParser3GPExt::ConvertAndAppendL(
HBufC8** aBuf8, TMetaDataFieldId aFieldId)
{
CleanupStack::PushL(*aBuf8);
if ((*aBuf8) && (*aBuf8)->Length() > 0)
{
TInt length = (*aBuf8)->Length();
HBufC* data16 = HBufC::NewLC(length);
TPtr16 titleUnicode(data16->Des());
TPtrC8 title((*aBuf8)->Des());
if ( ConvertToUnicodeL(title, titleUnicode) == KErrNone )
{
iContainer->AppendL(aFieldId, data16->Des());
}
CleanupStack::PopAndDestroy(data16); // data16
}
CleanupStack::PopAndDestroy(*aBuf8); // *aBuf8
(*aBuf8) = NULL;
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::ParseL
// -----------------------------------------------------------------------------
void CMetaDataParser3GPExt::ParseL(
const RArray<TMetaDataFieldId>& aWantedFields,
CMetaDataFieldContainer& aContainer)
{
#ifdef _DEBUG
RDebug::Print(_L("CMetaDataParser3GPExt::ParseL"));
#endif
iContainer = &aContainer;
TInt err = KErrNone; // ignore err as some entry may be extracted without exception
HBufC* buf = NULL;
HBufC8* buf8 = NULL;
if ( aWantedFields.Count() == 0 )
{
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTitleFormat, EMetaDataSongTitle, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataSongTitle);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaArtistFormat, EMetaDataArtist, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataArtist);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaComposerFormat, EMetaDataComposer, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataComposer);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaAlbumFormat, EMetaDataAlbum, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataAlbum);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCommentFormat, EMetaDataComment, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataComment);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaGenre, EMetaDataGenre, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataGenre);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaYearFormat, EMetaDataYear, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataYear);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCustomGenreFormat, EMetaDataRating, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataGenre);
}
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTrack, EMetaDataAlbumTrack, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataAlbumTrack);
}
TRAP(err, GetDurationL(EMetaDataDuration));
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaJpeg, EMetaDataJpeg, &buf8));
if (KErrNone == err)
{
AppendL(&buf8, EMetaDataJpeg);
}
}
else
{
// Look in the wanted field array
TInt count( aWantedFields.Count() );
for ( TInt i = 0; i < count; i++ )
{
switch ( aWantedFields[ i ] )
{
case EMetaDataSongTitle:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTitleFormat, EMetaDataSongTitle, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataSongTitle);
}
break;
case EMetaDataComment:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCommentFormat, EMetaDataComment, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataComment);
}
break;
case EMetaDataAlbumTrack:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTrack, EMetaDataAlbumTrack, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataAlbumTrack);
}
break;
case EMetaDataArtist:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaArtistFormat, EMetaDataArtist, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataArtist);
}
break;
case EMetaDataComposer:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaComposerFormat, EMetaDataComposer, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataComposer);
}
break;
case EMetaDataAlbum:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaAlbumFormat, EMetaDataAlbum, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataAlbum);
}
break;
case EMetaDataGenre:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaGenre, EMetaDataGenre, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataGenre);
}
break;
case EMetaDataDuration:
TRAP(err, GetDurationL(EMetaDataDuration));
break;
case EMetaDataYear:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaYearFormat, EMetaDataYear, &buf));
if (KErrNone == err)
{
AppendL(&buf, EMetaDataYear);
}
break;
case EMetaDataRating:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCustomGenreFormat, EMetaDataRating, &buf8));
if (KErrNone == err)
{
ConvertAndAppendL(&buf8, EMetaDataGenre);
}
break;
case EMetaDataJpeg:
TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaJpeg, EMetaDataJpeg, &buf8));
if (KErrNone == err)
{
AppendL(&buf8, EMetaDataJpeg);
}
break;
default:
break;
}
}
}
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::ValidateL
// -----------------------------------------------------------------------------
//
TBool CMetaDataParser3GPExt::ValidateL()
{
#ifdef _DEBUG
RDebug::Print(_L("CMetaDataParser3GPExt::ValidateL"));
#endif
mp4_u32 audioLength, audioType, timeScale, averateBitRate;
mp4_u8 framesPerSample;
MP4Err err;
err = MP4ParseRequestAudioDescription(iMP4Handle, &audioLength, &audioType,
&framesPerSample, &timeScale, &averateBitRate);
if ( err == MP4_OK && i3GPExtParser->Is3GPExtMetadataL())
{
iExists = ETrue;
return ETrue;
}
return EFalse;
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::AppendL
// -----------------------------------------------------------------------------
//
void CMetaDataParser3GPExt::AppendL(HBufC** aBuf, TMetaDataFieldId aFieldId)
{
CleanupStack::PushL(*aBuf);
if((*aBuf) && (*aBuf)->Length() > 0)
{
iContainer->AppendL(aFieldId, (*aBuf)->Des()); // copy to container
}
CleanupStack::PopAndDestroy(); // *aBuf
(*aBuf) = NULL;
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::AppendL
// -----------------------------------------------------------------------------
//
void CMetaDataParser3GPExt::AppendL(HBufC8** aBuf, TMetaDataFieldId aFieldId)
{
CleanupStack::PushL(*aBuf);
if((*aBuf) && (*aBuf)->Length() > 0)
{
iContainer->AppendL(aFieldId, (*aBuf)->Des()); // copy to container
}
CleanupStack::PopAndDestroy(); // *aBuf
(*aBuf) = NULL;
}
// -----------------------------------------------------------------------------
// CMetaDataParser3GPExt::ConvertToUnicodeL
// -----------------------------------------------------------------------------
//
TInt CMetaDataParser3GPExt::ConvertToUnicodeL(const TDesC8& aDesc, TDes16& aUnicode )
{
TPtrC8 unicodeData;
TUint characterSetId = 0;
CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC();
TInt state = CCnvCharacterSetConverter::KStateDefault;
// M4A file format has UTF-8 BigEndian characters.
characterSetId = KCharacterSetIdentifierUtf8;
unicodeData.Set( aDesc );
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