⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recog_util.cpp

📁 symbian 下的helix player源代码
💻 CPP
字号:
/*============================================================================*
 *
 * (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
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -