os/mm/mmlibs/mmfw/Recogniser/src/rmparser.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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 "parsers.h"
sl@0
    17
sl@0
    18
static const TUint32 KRMFileHeaderId = MAKE_INT32('.', 'R', 'M', 'F');
sl@0
    19
static const TUint32 KRMMediaPropertiesId = MAKE_INT32('M', 'D', 'P', 'R');
sl@0
    20
static const TInt KRMMaxMimeTypeLen = 255;	// Specified by an 8-bit field
sl@0
    21
sl@0
    22
#define KRMExtensionBit			KBit0
sl@0
    23
#define KRMFileHeaderBit		KBit1
sl@0
    24
#define KRMMediaPropertiesBit	KBit2
sl@0
    25
#define KRMVideoBit				KBit3
sl@0
    26
sl@0
    27
#define KRMVideoMask			0x08	// 0000 1000
sl@0
    28
#define KRMConfidenceMask 		0x07	// 0000 0111
sl@0
    29
sl@0
    30
//
sl@0
    31
// This truth table maps the following flags to a confidence level.
sl@0
    32
// -----------------------------------------------------------------
sl@0
    33
// A: MediaProperties chunk found
sl@0
    34
// B: FileHeader signature found
sl@0
    35
// C: Extension recognised.
sl@0
    36
//
sl@0
    37
// A B C -> Confidence
sl@0
    38
// ===================
sl@0
    39
// 0 0 0 -> ENotRecognized
sl@0
    40
// 0 0 1 -> EPossible
sl@0
    41
// 0 1 0 -> EPossible (EPossible beacuse the header is ASCII and may match plaintext)
sl@0
    42
// 0 1 1 -> ECertain
sl@0
    43
// 1 0 0 -> ENotRecognised (Can't have MediaProperties without FileHeader)
sl@0
    44
// 1 0 1 -> ENotRecognised (Can't have MediaProperties without FileHeader)
sl@0
    45
// 1 1 0 -> EProbable
sl@0
    46
// 1 1 1 -> ECertain
sl@0
    47
//
sl@0
    48
static const TInt KRMFlagsToConfidence[] =
sl@0
    49
	{
sl@0
    50
	KConfNotRecognised,
sl@0
    51
	KConfPossible,
sl@0
    52
	KConfPossible,
sl@0
    53
	KConfCertain,
sl@0
    54
	KConfNotRecognised,
sl@0
    55
	KConfNotRecognised,
sl@0
    56
	KConfProbable,
sl@0
    57
	KConfCertain
sl@0
    58
	};
sl@0
    59
sl@0
    60
sl@0
    61
//
sl@0
    62
// Constructor.
sl@0
    63
//
sl@0
    64
TRMParser::TRMParser(CReader& aReader, TFlags& aFlags)
sl@0
    65
 :	iReader(aReader),
sl@0
    66
	iFlags(aFlags)
sl@0
    67
	{
sl@0
    68
	}
sl@0
    69
sl@0
    70
sl@0
    71
//
sl@0
    72
// The main RealMedia parsing function.
sl@0
    73
//
sl@0
    74
void TRMParser::DoRecognise(const TDesC& aFileExt, CReader& aReader, TMatch& aMatch)
sl@0
    75
	{
sl@0
    76
	TFlags flags;
sl@0
    77
	TRMParser parser(aReader, flags);
sl@0
    78
sl@0
    79
	parser.MatchExtension(aFileExt);
sl@0
    80
sl@0
    81
	TRAP_IGNORE(parser.ParseL());
sl@0
    82
sl@0
    83
	TInt confIndex = flags.GetBitField(KRMConfidenceMask);
sl@0
    84
	aMatch.iConfidence = KRMFlagsToConfidence[confIndex];
sl@0
    85
sl@0
    86
	if (aMatch.iConfidence != KConfNotRecognised)
sl@0
    87
		{
sl@0
    88
		aMatch.iMime = (flags.GetBitField(KRMVideoMask) ? KMimeRM_V : KMimeRM_A);
sl@0
    89
		}
sl@0
    90
	}
sl@0
    91
sl@0
    92
sl@0
    93
//
sl@0
    94
// Match the file extension given by AppArc against known
sl@0
    95
// extensions for this format.
sl@0
    96
//
sl@0
    97
void TRMParser::MatchExtension(const TDesC& aFileExt)
sl@0
    98
	{
sl@0
    99
	TBool match;
sl@0
   100
sl@0
   101
	match = (aFileExt.MatchF(TPtrC(KExtRMF)) != KErrNotFound);
sl@0
   102
	match |= (aFileExt.MatchF(TPtrC(KExtRM)) != KErrNotFound);
sl@0
   103
sl@0
   104
	if (match)
sl@0
   105
		{
sl@0
   106
		iFlags.SetExtensionFlag();
sl@0
   107
		}
sl@0
   108
	}
sl@0
   109
sl@0
   110
//
sl@0
   111
// RealMedia files are divided into chunks. Chunks begins with a 32-bit identifier
sl@0
   112
// which is followed by a 32-bit unsigned field that specifies the size of the chunk
sl@0
   113
// in bytes. Since the size field is unsigned, it must be cast to a TInt64 in order
sl@0
   114
// for SeekL() to work reliably. The size field also includes the length of the chunk
sl@0
   115
// identifier and the length of the size field itself, so these must be subtracted
sl@0
   116
// from any seek operation.
sl@0
   117
//
sl@0
   118
void TRMParser::ParseL()
sl@0
   119
	{
sl@0
   120
	TUint32 objectId;
sl@0
   121
	TUint32 size;
sl@0
   122
	const TInt KChunkHeaderSize = sizeof(TUint32) * 2; // sizeof objectId and size fields.
sl@0
   123
sl@0
   124
	// The first chunk must be the FileHeader.
sl@0
   125
	ReadChunkHeaderL(objectId, size, ETrue);
sl@0
   126
sl@0
   127
	// Assume there's video content if we only have buffer data.
sl@0
   128
	if (iReader.Type() == CReader::EBuffer)
sl@0
   129
		{
sl@0
   130
		iFlags.SetBit(KRMVideoBit);
sl@0
   131
		}
sl@0
   132
sl@0
   133
	iReader.SeekL(TInt64(size - KChunkHeaderSize));
sl@0
   134
sl@0
   135
	// The other chunks can occur in any order.
sl@0
   136
	TBool complete = EFalse;
sl@0
   137
	do
sl@0
   138
		{
sl@0
   139
		ReadChunkHeaderL(objectId, size);
sl@0
   140
sl@0
   141
		if (objectId == KRMMediaPropertiesId)
sl@0
   142
			{
sl@0
   143
			iFlags.SetBit(KRMMediaPropertiesBit);
sl@0
   144
			if (ReadMediaPropertiesL())
sl@0
   145
				{
sl@0
   146
				// Exit early if the video flag has been set by ReadMediaPropertiesL.
sl@0
   147
				complete = ETrue;
sl@0
   148
				}
sl@0
   149
			}
sl@0
   150
		else
sl@0
   151
			{
sl@0
   152
			// Skip over the unneeded chunk.
sl@0
   153
			iReader.SeekL(TInt64(size - KChunkHeaderSize));
sl@0
   154
			}
sl@0
   155
		}
sl@0
   156
	while (!complete);
sl@0
   157
	}
sl@0
   158
sl@0
   159
sl@0
   160
//
sl@0
   161
// Reads the chunk identifier and size.
sl@0
   162
//
sl@0
   163
void TRMParser::ReadChunkHeaderL(TUint32& aObjectId, TUint32& aSize, TBool aFirstChunk)
sl@0
   164
	{
sl@0
   165
	iReader.Read32L(aObjectId);
sl@0
   166
sl@0
   167
	if (aFirstChunk)
sl@0
   168
		{
sl@0
   169
		if (aObjectId == KRMFileHeaderId)
sl@0
   170
			{
sl@0
   171
			iFlags.SetBit(KRMFileHeaderBit);
sl@0
   172
			}
sl@0
   173
		else
sl@0
   174
			{
sl@0
   175
			User::Leave(KErrCorrupt);
sl@0
   176
			}
sl@0
   177
		}
sl@0
   178
sl@0
   179
	iReader.Read32L(aSize);
sl@0
   180
	if (aSize == 0)
sl@0
   181
		{
sl@0
   182
		User::Leave(KErrCorrupt);
sl@0
   183
		}
sl@0
   184
	}
sl@0
   185
sl@0
   186
sl@0
   187
//
sl@0
   188
// The MediaProperties chunk describes a stream in the RM file. There
sl@0
   189
// may be several MediaProperties chunks in one file. In order to determine
sl@0
   190
// if video content is present we must look at the MIME-type that may
sl@0
   191
// be present in each MediaProperties chunk.
sl@0
   192
// Return ETrue if this function set the video bit.
sl@0
   193
//
sl@0
   194
TBool TRMParser::ReadMediaPropertiesL()
sl@0
   195
	{
sl@0
   196
	const TInt KBytesToFieldSize = 30;
sl@0
   197
	
sl@0
   198
	// ObjectId and size fields have already been read.
sl@0
   199
	TBool setVideo = EFalse;
sl@0
   200
	TUint16 objectVersion;
sl@0
   201
sl@0
   202
	iReader.Read16L(objectVersion);
sl@0
   203
sl@0
   204
	if (objectVersion == 0)
sl@0
   205
		{
sl@0
   206
		TUint8 fieldSize;
sl@0
   207
		TBuf8<KRMMaxMimeTypeLen> mimeType;
sl@0
   208
		_LIT8(KVideoStar, "video/*");
sl@0
   209
sl@0
   210
		// Skip unneeded information.
sl@0
   211
		iReader.SeekL(KBytesToFieldSize);
sl@0
   212
sl@0
   213
		// Read stream_name_size so we can skip over it.
sl@0
   214
		iReader.ReadByteL(fieldSize);
sl@0
   215
		iReader.SeekL(fieldSize);
sl@0
   216
sl@0
   217
		// Read the mime_type_size. Because it's 8-bit, it has a max length of 256 bytes.
sl@0
   218
		iReader.ReadByteL(fieldSize);
sl@0
   219
sl@0
   220
		mimeType.SetLength(fieldSize);
sl@0
   221
		iReader.ReadBytesL(mimeType);
sl@0
   222
sl@0
   223
		// Now check if the mime-type field indicates video content.
sl@0
   224
		if (mimeType.MatchF(KVideoStar) != KErrNotFound)
sl@0
   225
			{
sl@0
   226
			iFlags.SetBit(KRMVideoBit);
sl@0
   227
			setVideo = ETrue;
sl@0
   228
			}
sl@0
   229
sl@0
   230
		// Read the type_specific_len so we can skip over it.
sl@0
   231
		TUint32 typeSpecificLen;
sl@0
   232
		iReader.Read32L(typeSpecificLen);
sl@0
   233
		iReader.SeekL(TInt64(typeSpecificLen));
sl@0
   234
		}
sl@0
   235
sl@0
   236
	return setVideo;
sl@0
   237
	}
sl@0
   238