mmlibs/mmfw/Recogniser/src/aacparser.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "constants.h"
       
    17 #include "parsers.h"
       
    18 
       
    19 // The length of the frame in written directly into the header.
       
    20 // It is 13 bits in length and spans 3 bytes.
       
    21 
       
    22 #define AAC_SYNC1_MASK				0xff	// 11111111
       
    23 #define AAC_SYNC2_MASK				0xf0	// 11110000
       
    24 #define AAC_FRAME_LENGTH_MASK1		0x03	// 00000011
       
    25 #define AAC_FRAME_LENGTH_MASK2		0xff	// 11111111
       
    26 #define AAC_FRAME_LENGTH_MASK3		0xe0	// 11100000
       
    27 #define AAC_LAYER_MASK				0x06	// 00000110
       
    28 
       
    29 #define AAC_GET_SYNC1(d)	(d)
       
    30 #define AAC_GET_SYNC2(d)	((d & AAC_SYNC2_MASK) >> 4)
       
    31 #define AAC_GET_LAYER(d)	(((d) & AAC_LAYER_MASK) >> 1)
       
    32 #define AAC_GET_FRAME_LENGTH(a, b, c) \
       
    33 							(((a) & AAC_FRAME_LENGTH_MASK1) << 11) | \
       
    34 							(((b) & AAC_FRAME_LENGTH_MASK2) << 03) | \
       
    35 							(((c) & AAC_FRAME_LENGTH_MASK3) >> 05)
       
    36 							
       
    37 
       
    38 #define AAC_IS_BAD_SYNC1(s)			((s) != 0xff)
       
    39 #define AAC_IS_BAD_SYNC2(s)			((s) != 0x0f)
       
    40 #define AAC_IS_BAD_LAYER(l)			((l) != 0x00)
       
    41 #define AAC_IS_BAD_FRAME_LENGTH(l)	((l) < KAACFrameHeaderSize)
       
    42 
       
    43 //
       
    44 // The various states the recognition process goes through.
       
    45 //
       
    46 typedef enum
       
    47 	{
       
    48 	ESearchFrame1,
       
    49 	ESearchFrame2
       
    50 	}
       
    51 TAACState;
       
    52 
       
    53 //
       
    54 // This truth table maps the following flags to a confidence level.
       
    55 //
       
    56 // A: Extension identified.
       
    57 // B: Frame1 found.
       
    58 // C: Frame2 found.
       
    59 //
       
    60 // C B A -> Confidence
       
    61 // ===================
       
    62 // 0 0 0 -> ENotRecognised
       
    63 // 0 0 1 -> EPossible
       
    64 // 0 1 0 -> EProbable
       
    65 // 0 1 1 -> ECertain
       
    66 // 1 0 0 -> ENotRecognised (Can't have f2 without f1)
       
    67 // 1 0 1 -> ENotRecognised (Can't have f2 without f1)
       
    68 // 1 1 0 -> EProbable
       
    69 // 1 1 1 -> ECertain
       
    70 //
       
    71 static const TInt KAACFlagsToConfidence[8] =
       
    72 	{
       
    73 	KConfNotRecognised,
       
    74 	KConfPossible,
       
    75 	KConfProbable,
       
    76 	KConfCertain,
       
    77 	KConfNotRecognised,
       
    78 	KConfNotRecognised,
       
    79 	KConfProbable,
       
    80 	KConfCertain
       
    81 	};
       
    82 	
       
    83 #define KAACConfidenceMask	0x07	// [0000 0111]
       
    84 #define KAACFrame1Bit		KBit1
       
    85 #define KAACFrame2Bit		KBit2
       
    86 
       
    87 
       
    88 
       
    89 //
       
    90 // Constructs a TAACParser on the stack.
       
    91 //
       
    92 TAACParser::TAACParser(CReader& aReader, TFlags& aFlags)
       
    93  :	iReader(aReader),
       
    94  	iFlags(aFlags)
       
    95 	{
       
    96 	}
       
    97 
       
    98 
       
    99 //
       
   100 //
       
   101 //
       
   102 void TAACParser::DoRecognise(const TDesC& aFileExt, CReader& aReader, TMatch& aMatch)
       
   103 	{
       
   104 	TFlags flags;
       
   105 	TBool extMatch;
       
   106 	
       
   107 	// See if the extension is recognised.
       
   108 	extMatch = (aFileExt.MatchF(TPtrC(KExtAAC)) != KErrNotFound);
       
   109 	
       
   110 	// Try to match a known header.
       
   111 	if (aReader.Match(TPtrC8(_S8("ADIF*"))))
       
   112 		{
       
   113 		aMatch.iConfidence = (extMatch ? KConfCertain : KConfProbable);
       
   114 		aMatch.iMime = KMimeAAC;
       
   115 		return;
       
   116 		}
       
   117 	
       
   118 	// No known header so try to parse it.
       
   119 	// Parsing uses flags to track what has been identified.
       
   120 	if (extMatch)
       
   121 		{
       
   122 		flags.SetExtensionFlag();
       
   123 		}
       
   124 	
       
   125 	TAACParser parser(aReader, flags);
       
   126 	TRAP_IGNORE(parser.ParseL());
       
   127 	
       
   128 	TInt confIndex = flags.GetBitField(KAACConfidenceMask);
       
   129 	aMatch.iConfidence = KAACFlagsToConfidence[confIndex];
       
   130 	if (aMatch.iConfidence != KConfNotRecognised)
       
   131 		{
       
   132 		aMatch.iMime = KMimeAAC;
       
   133 		}
       
   134 	}
       
   135 
       
   136 
       
   137 //
       
   138 // Looks for valid AAC frame headers; at the current position
       
   139 // and immediately after (if one found).
       
   140 //
       
   141 void TAACParser::ParseL()
       
   142 	{
       
   143 	TInt frameLength;
       
   144 	TAACState state = ESearchFrame1;
       
   145 	
       
   146 	// Check if it's an ADTS (raw) format AAC file.
       
   147 	// There's no known metadata tag for AAC so the
       
   148 	// first frame header should be at the start of the buffer.
       
   149 	
       
   150 	FOREVER
       
   151 		{
       
   152 		TID3Parser::ReadAndSkipID3L(iReader);
       
   153 		
       
   154 		TInt err = CheckForFrameHeaderL(frameLength);
       
   155 		if (err == KErrNotFound)
       
   156 			{
       
   157 			return;
       
   158 			}
       
   159 			
       
   160 		switch (state)
       
   161 			{
       
   162 			case ESearchFrame1:
       
   163 				iFlags.SetBit(KAACFrame1Bit);
       
   164 				state = ESearchFrame2;
       
   165 				break;
       
   166 					
       
   167 			case ESearchFrame2:
       
   168 				iFlags.SetBit(KAACFrame2Bit);
       
   169 				return;
       
   170 			}
       
   171 		
       
   172 		// Skip over the audio frame.
       
   173 		// This should be done after flags have been set.
       
   174 		iReader.SeekL(frameLength - KAACFrameHeaderSize);
       
   175 		};
       
   176 	}
       
   177 
       
   178 
       
   179 //
       
   180 // Looks for valid AAC frame header bit patterns.
       
   181 // If one is not found KErrNotFound is returned and aFrameLength
       
   182 // remains unchanged. If one is found KErrNone is retured and
       
   183 // aFrameLength is set to the length of the frame.
       
   184 //
       
   185 TInt TAACParser::CheckForFrameHeaderL(TInt& aFrameLength)
       
   186 	{
       
   187 	TBuf8<KAACFrameHeaderSize> header;
       
   188 	
       
   189 	header.SetLength(KAACFrameHeaderSize);
       
   190 	iReader.ReadBytesL(header);
       
   191 	
       
   192 	do
       
   193 		{
       
   194 		if (AAC_IS_BAD_SYNC1(AAC_GET_SYNC1(header[0])))
       
   195 			{
       
   196 			break;
       
   197 			}
       
   198 			
       
   199 		if (AAC_IS_BAD_SYNC2(AAC_GET_SYNC2(header[1])))
       
   200 			{
       
   201 			break;
       
   202 			}
       
   203 			
       
   204 		if (AAC_IS_BAD_LAYER(AAC_GET_LAYER(header[1])))
       
   205 			{
       
   206 			break;
       
   207 			}
       
   208 			
       
   209 		TInt frameLength = AAC_GET_FRAME_LENGTH(header[3], header[4], header[5]);
       
   210 		if (AAC_IS_BAD_FRAME_LENGTH(frameLength))
       
   211 			{
       
   212 			break;
       
   213 			}
       
   214 		// All is ok.
       
   215 		aFrameLength = frameLength;
       
   216 		return KErrNone;
       
   217 		}
       
   218 	while (EFalse);
       
   219 	
       
   220 	// No frame header was found.
       
   221 	aFrameLength = 0;
       
   222 	iReader.SeekL(-KAACFrameHeaderSize);
       
   223 	return KErrNotFound;
       
   224 	}
       
   225 	
       
   226