recog_util.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:10k
- /*============================================================================*
- *
- * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
- *
- *
- * Recognition helpers for recognizing file datatype given buffer and filename
- *
- *============================================================================*/
-
- #include <e32svr.h>
- #include <apmrec.h>
- #include <apmstd.h>
- #include "mpa_frame_header.h"
- #include "hxassert.h"
- #include "hxsym_mimetypes.h"
- #include "recog_util.h"
- namespace RecogUtil
- {
- //
- // constants
- //
- // magic numbers
- _LIT8(KMagicRMF, ".RMF");
- _LIT8(KMagic3GPP, "ftyp3gp");
- _LIT8(KMagicMPEG4, "moov");
- _LIT8(KMagicAMR, "#!AMR");
- _LIT8(KMagicSDP, "v=");
-
- enum RecognitionLevel
- {
- ECertain=CApaDataRecognizerType::ECertain,
- EProbable=CApaDataRecognizerType::EProbable,
- EPossible=CApaDataRecognizerType::EPossible,
- EUnlikely=CApaDataRecognizerType::EUnlikely,
- ENotRecognized=CApaDataRecognizerType::ENotRecognized
- };
- void IncRecogLevel(RecognitionLevel& level)
- {
- switch( level)
- {
- case ECertain:
- // highest level already
- break;
- case EProbable:
- level = ECertain;
- break;
- case EPossible:
- level = EProbable;
- break;
- case EUnlikely:
- case ENotRecognized:
- level = EPossible;
- break;
- default:
- HX_ASSERT(false);
- break;
- }
- }
- TBool FindScheme(const TDesC& aScheme, const TDesC& aUrl)
- {
- TInt colonPos = aUrl.Locate(':');
- TInt schemePos = KErrNotFound;
- schemePos = aUrl.FindF(aScheme);
- TBool found = (schemePos >= 0 && aScheme.Length() == colonPos);
- return found;
- }
- TInt IsRMFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- TInt confidence = ENotRecognized;
- const TDesC8& magic = KMagicRMF;
- TBool validMagic=ETrue;
- TInt i;
- for (i=0; i<aBuffer.Length() && i<4; i++)
- {
- if (aBuffer[i] != magic[i])
- {
- validMagic = EFalse;
- break;
- }
- }
- if (validMagic)
- {
- confidence = ECertain;
- }
- return confidence;
- }
- TInt IsAMRFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- TInt confidence = ENotRecognized;
- const TDesC8& magic = KMagicAMR;
- TBool validMagic=ETrue;
- TInt i;
- for (i=0; i<aBuffer.Length() && i<KMagicAMR().Length(); i++)
- {
- if (aBuffer[i] != magic[i])
- {
- validMagic = EFalse;
- break;
- }
- }
- if (validMagic)
- {
- confidence = ECertain;
- }
- return confidence;
- }
- TInt IsSMILFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- //
- //<?xml version="1.0"?>
- //<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
- //<body>
- //</body>
- //</smil
- //
- bool bHasExt = false;
- TInt confidence = ENotRecognized;
- // check for .smi or .smil extension
- TInt idxDot = aName.LocateReverse('.');
- if(idxDot != KErrNotFound)
- {
- _LIT(KSmilExtShort, ".smi");
- _LIT(KSmilExtLong, ".smil");
- TPtrC ptrExt = aName.Mid(idxDot);
- if( !ptrExt.CompareF(KSmilExtShort) || !ptrExt.CompareF(KSmilExtLong) )
- {
- // has extension, therefore probably a smil file
- bHasExt = true;
- confidence = EProbable;
- }
- }
- // both of these are required smil tags
- _LIT8(KXmlSMILTag, "<smil");
- _LIT8(KXmlBODYTag, "<body");
-
- if (aBuffer.FindF(KXmlSMILTag) != KErrNotFound)
- {
- if(bHasExt)
- {
- // has smil tag as well as extension, therefore certainly a smil file
- confidence = ECertain;
- }
- else
- {
- // has smil tag but no extension, therefore possibly a smil file
- confidence = EPossible;
- if(aBuffer.FindF(KXmlBODYTag) != KErrNotFound)
- {
- // body tag as well, therefore probably a smil file
- confidence = EProbable;
- }
- }
- }
- return confidence;
- }
-
- TInt IsRAMFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- TBool nameRecognized=EFalse;
- TInt confidence = ENotRecognized;
-
- if ((aBuffer.FindF(_L8("rtsp://")) != KErrNotFound ||
- aBuffer.FindF(_L8("file://")) != KErrNotFound ||
- aBuffer.FindF(_L8("http://")) != KErrNotFound) &&
- aBuffer.FindF(_L8("<html>")) == KErrNotFound)
- {
- confidence = EPossible;
- }
- if (aName.Length()>4)
- {
- _LIT(KRamExt, ".ram");
- if (aName.Right(4).CompareF(KRamExt)==0)
- {
- nameRecognized=ETrue;
- }
- }
- if (confidence == EPossible && nameRecognized)
- {
- confidence = ECertain;
- }
- return confidence;
- }
- RecognitionLevel TestForMP3FrameHeaders(const TDesC8& buffer)
- {
- TInt idxEnd = buffer.Length() - MPA_FRAME_HDR_SZ;
- for(TInt idx = 0; idx < idxEnd; ++idx)
- {
- const unsigned char* pBuf = buffer.Ptr() + idx;
-
- // try and parse mp3 frame at this location
- MPAFrameHeader frame;
- if( frame.Unpack(pBuf) && (MPA_LAYER3 == frame.m_layer) )
- {
- // looks like a valid frame so far; now move on past frame (header + data)
- pBuf += frame.m_frameSize;
- if(pBuf < buffer.Ptr() + idxEnd)
- {
- // look for second frame header with matching attributes
- MPAFrameHeader frame2;
- if( frame2.Unpack(pBuf)
- && (frame2.m_version == frame.m_version)
- && (frame2.m_layer == frame.m_layer)
- && (frame2.m_sampleRate == frame.m_sampleRate) )
- {
- // highly likely this is mp3
- return EProbable;
- }
- }
- else
- {
- // good chance this is mp3 (frame size exceeds the buffer we get)
- return EPossible;
- }
- }
-
- }
- return ENotRecognized;
- }
- TInt IsMP3File(const TDesC& aName, const TDesC8& aBuffer)
- {
- RecognitionLevel confidence = ENotRecognized;
- //RDebug::Print(_L("looking at '%S'"), &aName);
- _LIT8(KMagicID3, "ID3");
- _LIT(KMP3Ext, ".mp3");
- // look for mp3 extension
- bool bHasExtension = (0 == aName.Right(4).CompareF(KMP3Ext));
- // look for start of ID3v2 header
- bool bHasID3 = (0 == aBuffer.Left(3).Compare(KMagicID3));
-
- if(bHasID3)
- {
- // other MPA types as well as AAC may have an ID3 header; the header
- // can be quite long so we often can't find frame headers because the
- // buffer is too small
- confidence = EPossible;
- }
- else
- {
- confidence = TestForMP3FrameHeaders(aBuffer);
- }
- if(bHasExtension)
- {
- IncRecogLevel(confidence);
- }
- return confidence;
- }
- TInt Is3GPPFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- _LIT8(KFtyp3gpp, "3gp"); // 3gp4 and 3gp5
- TInt confidence = IsISOMediaFile(aName, aBuffer, KFtyp3gpp);
- if( ENotRecognized != confidence )
- {
- TInt index = aBuffer.Find(KFtyp3gpp);
- HX_ASSERT(index != KErrNotFound);
- if(index != KErrNotFound)
- {
- // look at character after '3gp'
- index += KFtyp3gpp().Length();
- HX_ASSERT(index < aBuffer.Length());
- if (aBuffer[index] != '4' && aBuffer[index] != '5')
- {
- // we only recognize 3gp4 and 3gp5
- confidence = ENotRecognized;
- }
- }
- }
- return confidence;
- }
- TInt IsMPEG4File(const TDesC& aName, const TDesC8& aBuffer)
- {
- _LIT8(KFtypMP4, "mp4"); // mp41 and others
-
- return IsISOMediaFile(aName, aBuffer, KFtypMP4);
- }
- TInt IsMPEG4Audio(const TDesC& aName, const TDesC8& aBuffer)
- {
- TInt confidence = ENotRecognized;
- _LIT8(KSampleEntryMPEG4Video, "mp4v");
- _LIT8(KSampleEntryH263Video, "s263");
- if (aBuffer.Find(KSampleEntryH263Video) != KErrNotFound &&
- aBuffer.Find(KSampleEntryMPEG4Video) != KErrNotFound)
- confidence = EProbable;
- return confidence;
- }
- TInt IsSDPFile(const TDesC& aName, const TDesC8& aBuffer)
- {
- TInt confidence = ENotRecognized;
- const TDesC8& magic = KMagicSDP;
- TBool validMagic=ETrue;
- TInt i;
- for (i=0; i<aBuffer.Length() && i<KMagicSDP().Length(); i++)
- {
- if (aBuffer[i] != magic[i])
- {
- validMagic = EFalse;
- break;
- }
- }
- if (validMagic)
- confidence = ECertain;
- return confidence;
- }
- inline
- TUint32 UnpackUint32(const TUint8* buf)
- {
- return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
- }
- TInt IsISOMediaFile(const TDesC& aName, const TDesC8& aBuffer, const TDesC8& brand)
- {
- _LIT8(KAtomFTYP, "ftyp");
- HX_ASSERT(brand.Length() <= 4);
- TInt confidence = ENotRecognized;
- TInt idx = aBuffer.Find(KAtomFTYP);
- if( idx >= 4)
- {
- // back up to size field; preceeds object identifier
- idx -= 4;
-
- // get size of potential atom(box) data
- TInt cbAtomData = UnpackUint32(aBuffer.Ptr() + idx) - 8;
- // index past size + 'ftype' to beginning of atom data
- idx += 8;
- TInt cbLeft = aBuffer.Length() - idx;
- if( cbLeft > cbAtomData )
- {
- // likely case since ftyp atom is small and buffer is large; we'll only look at potential ftyp atom
- cbLeft = cbAtomData;
- }
- // now look for matching brand (3gp?, isom, mp4?, etc.)
- enum
- {
- getFirst,
- getOthers
- } state = getFirst;
- // look at 4-byte objects (every field is four bytes in ftyp atom/box)
- for(TInt idxLast = idx + cbLeft - 4; idx <= idxLast; idx += 4)
- {
- TPtrC8 ptr = aBuffer.Mid(idx, brand.Length());
- if(0 == ptr.Compare(brand))
- {
- // found matching brand
- confidence = ECertain;
- break;
- }
- if( getFirst == state )
- {
- // skip past minor version and continue searching for compatible brands
- idx += 4;
- state = getOthers;
- }
- }
-
- }
- return confidence;
- }
- } // ns RecogUtil
-