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

📄 xdstorat.cpp

📁 pci-tv卡底层驱动源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// XDSToRat.cpp : Implementation of CXDSToRat
#include "stdafx.h"
#include "CxTVRate.h"
#include "XDSToRat.h"
#include "XDSPacket.h"
#include "assert.h"
#include "cxTVRateDbg.h"


static
XDSPacket*
findPacket( std::list<XDSPacket> &xdsPackets, BYTE byte1, BYTE byte2 )
{
    std::list<XDSPacket>::iterator i = xdsPackets.begin();  
    
    for( ; i != xdsPackets.end(); ++i )
        if( i->ctrlCode() == byte1 && i->typeCode() == byte2 )
            return &*i;

    return NULL;
}


/////////////////////////////////////////////////////////////////////////////
// CXDSToRat
CXDSToRat::CXDSToRat(): 
    _p_receivingPkt( NULL )
{
    InitializeCriticalSection( &_critSec );
}


CXDSToRat::~CXDSToRat()
{
    DeleteCriticalSection( &_critSec );
}


STDMETHODIMP 
CXDSToRat::Init()
{
    EnterCriticalSection( &_critSec );
    resetState();
    LeaveCriticalSection( &_critSec );
    
    DBP(( "XDStoRat::Init ------ called\n" ));
    return S_OK;
}


STDMETHODIMP 
CXDSToRat::ParseXDSBytePair( BYTE                  byte1, 
                             BYTE                  byte2, 
                             EnTvRat_System       *p_system, 
                             EnTvRat_GenericLevel *p_level, 
                             LONG                 *p_attrib )
{
    // If this byte pair does NOT complete a ratings(content advisory) 
    // packet we are supposed to return the following.
    *p_system = TvRat_SystemDontKnow;
    *p_level  = TvRat_LevelDontKnow;
    *p_attrib = BfAttrNone;
    
    // Data is seven bit ASCII so make sure high order bit is cleared.
    byte1 &= NBITS(7);
    byte2 &= NBITS(7);

    // If this byte pair is not: an XDS Control Code, a Caption/Text Control
    // Code, or we do not have a receiving packet, just drop the data.
    HRESULT hr = S_FALSE;

    // Lock access to object data
    EnterCriticalSection( &_critSec );

    // Handle the XDS Start and Continue Control Codes. EIA/CEA-608-B Sec. 9.3
    if( byte1 >= XDS_STRT_CUR && byte1 <= XDS_CONT_PRI )
    {
        if( byte1 & BIT(0) ) // Start Codes are odd.
        {
            // Check if this packet is already started and 
            // if so restart per EIA/CEA-608-B Sec. 8.6.8
            if( _p_receivingPkt = findPacket( _xdsPackets, byte1, byte2 ) )
            {
                _p_receivingPkt->clearInfo();
            }
            else // Packet not started so create a new one.
            {
                _xdsPackets.push_front( XDSPacket( byte1, byte2 ) );
                _p_receivingPkt = &*_xdsPackets.begin();
            }
        }
        else // Continue Codes are even.
        {
            _p_receivingPkt = findPacket( _xdsPackets, byte1, byte2 );
        }

        hr = S_FALSE;
    }
    // Handle the XDS End Control Code. EIA/CEA-608-B Sec. 9.3
    else if( byte1 == XDS_END_ALL )
    {
        hr = S_FALSE;

        if( _p_receivingPkt )
        {
            // We need to get the receiving packet off the packet list because
            // the decode functions may clear that list by calling Init().
            XDSPacket pkt( *_p_receivingPkt );
            _xdsPackets.remove( pkt );
            _p_receivingPkt = NULL;
            
            if( pkt.checkSum( byte2 ) )
                hr = decodePacket( &pkt, p_system, p_level, p_attrib );
            else
                DBP(( "XDStoRat::Parse checkSum = %02x failed\n", byte2 ));
        }
    }
    // Handle the Caption/Text Control Codes. EIA/CEA-608-B Sec. 8.6.2
    else if( byte1 >= CAPTION_CTRL_MIN && byte1 <= CAPTION_CTRL_MAX )
    {
        _p_receivingPkt = NULL;
        hr = S_FALSE;
    }
    // If we have a receiving packet add the byte pair to it.
    else if( _p_receivingPkt )
    {
        _p_receivingPkt->addBytePair( byte1, byte2 );
        hr = S_FALSE;
    }

    // Unlock access to object data
    LeaveCriticalSection( &_critSec );

    return hr;
}


HRESULT 
CXDSToRat::decodePacket( XDSPacket            *p_pkt, 
                         EnTvRat_System       *p_system, 
                         EnTvRat_GenericLevel *p_level, 
                         LONG                 *p_attrib )
{
    assert( *p_system == TvRat_SystemDontKnow ); 
    assert( *p_level  == TvRat_LevelDontKnow );
    assert( *p_attrib == BfAttrNone );
    
    // Handle Program Identification number(PID) EIA/CEA-608-B Sec. 9.5.1.1
    if( p_pkt->ctrlCode() == XDS_STRT_CUR && p_pkt->typeCode() == TY_PROG_ID )
    {
        return decodePID( p_pkt->info() );
    }
    // Handle Program Name EIA/CEA-608-B Sec. 9.5.1.3
    else if( p_pkt->ctrlCode() == XDS_STRT_CUR && 
             p_pkt->typeCode() == TY_PROG_NAME )
    {
        return decodeProgName( p_pkt->info() );
    }
    // Handle Content Advisory(Program Rating) EIA/CEA-608-B Sec. 9.5.1.5
    else if( p_pkt->ctrlCode() == XDS_STRT_CUR && 
             p_pkt->typeCode() == TY_CONTENT_ADVISORY )
    {
        return decodeContAdv( (p_pkt->info())[0], (p_pkt->info())[1], 
                              true, // 2nd argument IS valid
                              p_system, p_level, p_attrib );
    }
    // Handle Composite Packet-1 to get the Program Name and Content Advisory
    else if( p_pkt->ctrlCode() == XDS_STRT_CUR && 
             p_pkt->typeCode() == TY_COMPOSITE_PKT1 )
    {
        if( p_pkt->info().size() < INFO_MIN_COMPOSITE_PKT1 )
            return S_FALSE;

        HRESULT nameHr = S_FALSE;
        
        // If name is in packet check for new name.
        if( p_pkt->info().size() > COMP_PKT1_PROG_NAME_OFST )
            nameHr = decodeProgName( std::string( p_pkt->info(), 
                                     COMP_PKT1_PROG_NAME_OFST,
                                     p_pkt->info().size() - 
                                     COMP_PKT1_PROG_NAME_OFST ) );

        // If no Content Advisory is available NULL will be inserted.
        if( (p_pkt->info())[COMP_PKT1_CONT_ADV_OFST] == 0 )
            return nameHr;
        
        HRESULT advHr = decodeContAdv( (p_pkt->info())[COMP_PKT1_CONT_ADV_OFST],
                                       'U',   // Unused argument 
                                       false, // 2nd argument is NOT valid
                                       p_system, p_level, p_attrib );

        return nameHr == S_OK || advHr == S_OK ? S_OK : S_FALSE;
    }
    // Handle Composite Packet-2 to get the PID EIA/CEA-608-B Sec. 9.5.1.11
    else if( p_pkt->ctrlCode() == XDS_STRT_CUR && 
             p_pkt->typeCode() == TY_COMPOSITE_PKT2 )
    {
        if( p_pkt->info().size() < INFO_MIN_COMPOSITE_PKT2 )
            return S_FALSE;

        // If no pid is available NULLs will be inserted Sec. 9.5.1.11
        if( (p_pkt->info())[0] == 0 && (p_pkt->info())[1] == 0 &&
            (p_pkt->info())[2] == 0 && (p_pkt->info())[3] == 0 )
            return S_FALSE;

        return decodePID( std::string( p_pkt->info(), 0, INFO_CNT_PROG_ID ) );
    }
    else
        return S_FALSE;
}


HRESULT 
CXDSToRat::decodePID( std::string newPID )
{
    if( newPID.size() == INFO_CNT_PROG_ID )
    {
        // Only low order bits are used per Sec. 9.5.1.1
        newPID[0] &= NBITS(6);
        newPID[1] &= NBITS(5);
        newPID[2] &= NBITS(5);
        newPID[3] &= NBITS(5);
        

⌨️ 快捷键说明

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