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 +