os/mm/mmlibs/mmfw/Recogniser/src/aacparser.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/mmlibs/mmfw/Recogniser/src/aacparser.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,226 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "constants.h"
    1.20 +#include "parsers.h"
    1.21 +
    1.22 +// The length of the frame in written directly into the header.
    1.23 +// It is 13 bits in length and spans 3 bytes.
    1.24 +
    1.25 +#define AAC_SYNC1_MASK				0xff	// 11111111
    1.26 +#define AAC_SYNC2_MASK				0xf0	// 11110000
    1.27 +#define AAC_FRAME_LENGTH_MASK1		0x03	// 00000011
    1.28 +#define AAC_FRAME_LENGTH_MASK2		0xff	// 11111111
    1.29 +#define AAC_FRAME_LENGTH_MASK3		0xe0	// 11100000
    1.30 +#define AAC_LAYER_MASK				0x06	// 00000110
    1.31 +
    1.32 +#define AAC_GET_SYNC1(d)	(d)
    1.33 +#define AAC_GET_SYNC2(d)	((d & AAC_SYNC2_MASK) >> 4)
    1.34 +#define AAC_GET_LAYER(d)	(((d) & AAC_LAYER_MASK) >> 1)
    1.35 +#define AAC_GET_FRAME_LENGTH(a, b, c) \
    1.36 +							(((a) & AAC_FRAME_LENGTH_MASK1) << 11) | \
    1.37 +							(((b) & AAC_FRAME_LENGTH_MASK2) << 03) | \
    1.38 +							(((c) & AAC_FRAME_LENGTH_MASK3) >> 05)
    1.39 +							
    1.40 +
    1.41 +#define AAC_IS_BAD_SYNC1(s)			((s) != 0xff)
    1.42 +#define AAC_IS_BAD_SYNC2(s)			((s) != 0x0f)
    1.43 +#define AAC_IS_BAD_LAYER(l)			((l) != 0x00)
    1.44 +#define AAC_IS_BAD_FRAME_LENGTH(l)	((l) < KAACFrameHeaderSize)
    1.45 +
    1.46 +//
    1.47 +// The various states the recognition process goes through.
    1.48 +//
    1.49 +typedef enum
    1.50 +	{
    1.51 +	ESearchFrame1,
    1.52 +	ESearchFrame2
    1.53 +	}
    1.54 +TAACState;
    1.55 +
    1.56 +//
    1.57 +// This truth table maps the following flags to a confidence level.
    1.58 +//
    1.59 +// A: Extension identified.
    1.60 +// B: Frame1 found.
    1.61 +// C: Frame2 found.
    1.62 +//
    1.63 +// C B A -> Confidence
    1.64 +// ===================
    1.65 +// 0 0 0 -> ENotRecognised
    1.66 +// 0 0 1 -> EPossible
    1.67 +// 0 1 0 -> EProbable
    1.68 +// 0 1 1 -> ECertain
    1.69 +// 1 0 0 -> ENotRecognised (Can't have f2 without f1)
    1.70 +// 1 0 1 -> ENotRecognised (Can't have f2 without f1)
    1.71 +// 1 1 0 -> EProbable
    1.72 +// 1 1 1 -> ECertain
    1.73 +//
    1.74 +static const TInt KAACFlagsToConfidence[8] =
    1.75 +	{
    1.76 +	KConfNotRecognised,
    1.77 +	KConfPossible,
    1.78 +	KConfProbable,
    1.79 +	KConfCertain,
    1.80 +	KConfNotRecognised,
    1.81 +	KConfNotRecognised,
    1.82 +	KConfProbable,
    1.83 +	KConfCertain
    1.84 +	};
    1.85 +	
    1.86 +#define KAACConfidenceMask	0x07	// [0000 0111]
    1.87 +#define KAACFrame1Bit		KBit1
    1.88 +#define KAACFrame2Bit		KBit2
    1.89 +
    1.90 +
    1.91 +
    1.92 +//
    1.93 +// Constructs a TAACParser on the stack.
    1.94 +//
    1.95 +TAACParser::TAACParser(CReader& aReader, TFlags& aFlags)
    1.96 + :	iReader(aReader),
    1.97 + 	iFlags(aFlags)
    1.98 +	{
    1.99 +	}
   1.100 +
   1.101 +
   1.102 +//
   1.103 +//
   1.104 +//
   1.105 +void TAACParser::DoRecognise(const TDesC& aFileExt, CReader& aReader, TMatch& aMatch)
   1.106 +	{
   1.107 +	TFlags flags;
   1.108 +	TBool extMatch;
   1.109 +	
   1.110 +	// See if the extension is recognised.
   1.111 +	extMatch = (aFileExt.MatchF(TPtrC(KExtAAC)) != KErrNotFound);
   1.112 +	
   1.113 +	// Try to match a known header.
   1.114 +	if (aReader.Match(TPtrC8(_S8("ADIF*"))))
   1.115 +		{
   1.116 +		aMatch.iConfidence = (extMatch ? KConfCertain : KConfProbable);
   1.117 +		aMatch.iMime = KMimeAAC;
   1.118 +		return;
   1.119 +		}
   1.120 +	
   1.121 +	// No known header so try to parse it.
   1.122 +	// Parsing uses flags to track what has been identified.
   1.123 +	if (extMatch)
   1.124 +		{
   1.125 +		flags.SetExtensionFlag();
   1.126 +		}
   1.127 +	
   1.128 +	TAACParser parser(aReader, flags);
   1.129 +	TRAP_IGNORE(parser.ParseL());
   1.130 +	
   1.131 +	TInt confIndex = flags.GetBitField(KAACConfidenceMask);
   1.132 +	aMatch.iConfidence = KAACFlagsToConfidence[confIndex];
   1.133 +	if (aMatch.iConfidence != KConfNotRecognised)
   1.134 +		{
   1.135 +		aMatch.iMime = KMimeAAC;
   1.136 +		}
   1.137 +	}
   1.138 +
   1.139 +
   1.140 +//
   1.141 +// Looks for valid AAC frame headers; at the current position
   1.142 +// and immediately after (if one found).
   1.143 +//
   1.144 +void TAACParser::ParseL()
   1.145 +	{
   1.146 +	TInt frameLength;
   1.147 +	TAACState state = ESearchFrame1;
   1.148 +	
   1.149 +	// Check if it's an ADTS (raw) format AAC file.
   1.150 +	// There's no known metadata tag for AAC so the
   1.151 +	// first frame header should be at the start of the buffer.
   1.152 +	
   1.153 +	FOREVER
   1.154 +		{
   1.155 +		TID3Parser::ReadAndSkipID3L(iReader);
   1.156 +		
   1.157 +		TInt err = CheckForFrameHeaderL(frameLength);
   1.158 +		if (err == KErrNotFound)
   1.159 +			{
   1.160 +			return;
   1.161 +			}
   1.162 +			
   1.163 +		switch (state)
   1.164 +			{
   1.165 +			case ESearchFrame1:
   1.166 +				iFlags.SetBit(KAACFrame1Bit);
   1.167 +				state = ESearchFrame2;
   1.168 +				break;
   1.169 +					
   1.170 +			case ESearchFrame2:
   1.171 +				iFlags.SetBit(KAACFrame2Bit);
   1.172 +				return;
   1.173 +			}
   1.174 +		
   1.175 +		// Skip over the audio frame.
   1.176 +		// This should be done after flags have been set.
   1.177 +		iReader.SeekL(frameLength - KAACFrameHeaderSize);
   1.178 +		};
   1.179 +	}
   1.180 +
   1.181 +
   1.182 +//
   1.183 +// Looks for valid AAC frame header bit patterns.
   1.184 +// If one is not found KErrNotFound is returned and aFrameLength
   1.185 +// remains unchanged. If one is found KErrNone is retured and
   1.186 +// aFrameLength is set to the length of the frame.
   1.187 +//
   1.188 +TInt TAACParser::CheckForFrameHeaderL(TInt& aFrameLength)
   1.189 +	{
   1.190 +	TBuf8<KAACFrameHeaderSize> header;
   1.191 +	
   1.192 +	header.SetLength(KAACFrameHeaderSize);
   1.193 +	iReader.ReadBytesL(header);
   1.194 +	
   1.195 +	do
   1.196 +		{
   1.197 +		if (AAC_IS_BAD_SYNC1(AAC_GET_SYNC1(header[0])))
   1.198 +			{
   1.199 +			break;
   1.200 +			}
   1.201 +			
   1.202 +		if (AAC_IS_BAD_SYNC2(AAC_GET_SYNC2(header[1])))
   1.203 +			{
   1.204 +			break;
   1.205 +			}
   1.206 +			
   1.207 +		if (AAC_IS_BAD_LAYER(AAC_GET_LAYER(header[1])))
   1.208 +			{
   1.209 +			break;
   1.210 +			}
   1.211 +			
   1.212 +		TInt frameLength = AAC_GET_FRAME_LENGTH(header[3], header[4], header[5]);
   1.213 +		if (AAC_IS_BAD_FRAME_LENGTH(frameLength))
   1.214 +			{
   1.215 +			break;
   1.216 +			}
   1.217 +		// All is ok.
   1.218 +		aFrameLength = frameLength;
   1.219 +		return KErrNone;
   1.220 +		}
   1.221 +	while (EFalse);
   1.222 +	
   1.223 +	// No frame header was found.
   1.224 +	aFrameLength = 0;
   1.225 +	iReader.SeekL(-KAACFrameHeaderSize);
   1.226 +	return KErrNotFound;
   1.227 +	}
   1.228 +	
   1.229 +