os/mm/mmlibs/mmfw/Recogniser/src/aacparser.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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