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