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

📄 parse656data.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*+++ *******************************************************************\ 
* 
*  Copyright and Disclaimer: 
*  
*     --------------------------------------------------------------- 
*     This software is provided "AS IS" without warranty of any kind, 
*     either expressed or implied, including but not limited to the 
*     implied warranties of noninfringement, merchantability and/or 
*     fitness for a particular purpose.
*     --------------------------------------------------------------- 
*   
*     Copyright (c) 2008 Conexant Systems, Inc. 
*     All rights reserved. 
*
\******************************************************************* ---*/ 

#include "Parse656Data.h"
#include "BasePin.h"


#define SAV_ACTIVE_VIDEO_FIELD1	    0x80
#define EAV_ACTIVE_VIDEO_FIELD1		0x90

#define SAV_ACTIVE_VIDEO_FIELD2		0xC0
#define EAV_ACTIVE_VIDEO_FIELD2		0xD0

#define SAV_VBLANK_FIELD1		    0xA0
#define EAV_VBLANK_FIELD1		    0xB0

#define SAV_VBLANK_FIELD2		    0xE0
#define EAV_VBLANK_FIELD2		    0xF0

#define SAV_VBI_FIELD1	            0x20
#define EAV_VBI_FIELD1	            0x30

#define SAV_VBI_FIELD2	            0x60
#define EAV_VBI_FIELD2	            0x70

//This is not a real SAV, but a value used to save the state when we had a partial ancillary
// buffer at a buffer boundary
#define SAV_PARTIAL_ANCILLARY       0xA5

//Ancillary packet data ID's
#define ANCILLARY_DID_AUDIO         0xBF
#define ANCILLARY_DID_VBI_FIELD1    0x91
#define ANCILLARY_DID_VBI_FIELD2    0x55


/////////////////////////////////////////////////////////////////////////////////////////
Parse656Data:: Parse656Data():
_is_partial_line(FALSE),
_last_sav(0),
_last_video_sav(0),
_video_parse_buffer(1440, 240),
_vbi_parse_buffer(1440, 12),
_field_num(0)
{
    for(DWORD i = 0; i < 4; i++)
    {
        _end_of_buffer_bytes[i] = 0;
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID Parse656Data::setPin(BasePin* p_pin)
{
    PIN_TYPES pin_type = p_pin->getPinType();

    switch(pin_type)
    {
    case PIN_TYPE_VIDEO:
        _video_parse_buffer.setPin(p_pin);
        break;

    case PIN_TYPE_VBI:
        _vbi_parse_buffer.setPin(p_pin);
        break;

    case PIN_TYPE_AUDIO:  //for HANC Audio use
        _audio_parse_buffer.setPin(p_pin);
        break;

    case PIN_TYPE_SLICED_CC:
        _sliced_cc_buffer.setPin(p_pin);
        break;
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID Parse656Data::releasePin(BasePin* p_pin)
{
    PIN_TYPES pin_type = p_pin->getPinType();

    switch(pin_type)
    {
    case PIN_TYPE_VIDEO:
        _video_parse_buffer.releasePin();
        break;

    case PIN_TYPE_VBI:
        _vbi_parse_buffer.releasePin();
        break;

    case PIN_TYPE_AUDIO:   // for HANC Audio use
        _audio_parse_buffer.releasePin();
        break;

    case PIN_TYPE_SLICED_CC:
        _sliced_cc_buffer.releasePin();  //different class
        break;
    }

}

VOID Parse656Data::notifyPinFormatChange(BasePin* p_pin)
{
    PIN_TYPES pin_type = p_pin->getPinType();

    switch(pin_type)
    {
    case PIN_TYPE_VIDEO:
        _video_parse_buffer.notifyPinFormatChange();
        break;

    case PIN_TYPE_VBI:
        _vbi_parse_buffer.notifyPinFormatChange();
        break;

    }

}


/////////////////////////////////////////////////////////////////////////////////////////
DWORD Parse656Data::getLine(BYTE sav_eav, PBYTE p_buffer, DWORD buffer_size)
{
    DWORD bytes_copied = 0;

    ParseBuffer* p_parse_buffer = NULL;
    FIELD_TYPE current_field = FIELD_INVALID;

    switch(sav_eav)
    {
    case SAV_ACTIVE_VIDEO_FIELD1:
        // looking for skipped line which occurred in PAL 720x480 mode. In this case,
		// there will be no active data contained between the SAV and EAV
        if ( (buffer_size > 3) &&
		     (p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
			 ( (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1)	|| (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
			   (p_buffer[3] == EAV_VBLANK_FIELD1)	    || (p_buffer[3] == EAV_VBLANK_FIELD2)
			 )
		   )
		{
		    return bytes_copied;
		}
        p_parse_buffer = &_video_parse_buffer;
        current_field = FIELD_1;
        break;

    case SAV_ACTIVE_VIDEO_FIELD2:
        // looking for skipped line which occurred in PAL 720x480 mode. In this case,
		// there will be no active data contained between the SAV and EAV
        if ( (buffer_size > 3) &&
		     (p_buffer[0] == 0xFF) && (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
			 ( (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1)	|| (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
			   (p_buffer[3] == EAV_VBLANK_FIELD1)	    || (p_buffer[3] == EAV_VBLANK_FIELD2)
			 )
		   )
		{
		    return bytes_copied;
		}        
        p_parse_buffer = &_video_parse_buffer;
        current_field = FIELD_2;
        break;


    case SAV_VBI_FIELD1:
        p_parse_buffer = &_vbi_parse_buffer;
        current_field = FIELD_1;
        break;

    case SAV_VBI_FIELD2:
        p_parse_buffer = &_vbi_parse_buffer;
        current_field = FIELD_2;
        break;

    //Special case to specify that we were part way through an ancillary packet at 
    // a buffer break.  Since audio buffers are small, there should be no 
    // way for one to span more than two buffers.
    case SAV_PARTIAL_ANCILLARY:

        bytes_copied = _ancillary_packet.submitData(p_buffer, buffer_size);

        //Handle the case where the packet was not valid.
        if(bytes_copied == 0)
        {
            //Invalid ancillary packet
            _ancillary_packet.clearData();
            break;
        }


        p_buffer += bytes_copied;
        buffer_size -= bytes_copied;

        if(_ancillary_packet.isPacketComplete())
        {
            //complete the packet
            completeAncillaryPacket();

            _is_partial_line = FALSE;
        }
        else
        {
            //It is unlikely we will ever need to cross two buffer boundaries
            //But break if we do.
            break;
        }


        
    //FALL THROUGH to test for another ancillary packet immediately following       


    //Search for ancillary packets.  Audio is stored in ancillary data packets, which 
    //are found immediately after an EAV code.  The packet will always start with
    //the pattern 0x00 0xFF 0xFF.  The packets are of variable length, but will
    //be a maximum of 16 data bytes and 6 header bytes.
    case EAV_ACTIVE_VIDEO_FIELD1:
    case EAV_ACTIVE_VIDEO_FIELD2:
    case EAV_VBI_FIELD1:
    case EAV_VBI_FIELD2:
    case EAV_VBLANK_FIELD1:
    case EAV_VBLANK_FIELD2:
        {
            DWORD total_bytes_copied = bytes_copied;
            
            while(buffer_size > 0)
            {
                //Although ancillary packets should follow one another without gaps,
                //there is apparantly a bug where Mako is duplicating the last byte 
                // of the sliced CC packets, causing there to be one more byte in the
                // packet than expected.  This can cause us to lose the packet following
                // it because the packet header will be off one byte from what we expect. 
                // To work around it, if the next byte is not 00, check the one after it.
                if(*p_buffer != 0x00)
                {
                    //If the second byte is 00 and the first byte was not 0xFF 
                    // (which would be the case for an FF 00 00 SAV/EAV code)
                    // then advance the buffer pointer by one and try to find an ancillary
                    // packet.
                    if((buffer_size >= 2) &&
                        (p_buffer[0] != 0xFF) && 
                        (p_buffer[1] == 0x00))
                    {
                        p_buffer++;
                        buffer_size--;
                        total_bytes_copied++;
                    }
                    else
                    {
                        break;
                    }
                }

                //Parse the ancillary packet
                bytes_copied = _ancillary_packet.submitData(p_buffer, buffer_size);

                //Handle the case where the packet is not valid.
                if(bytes_copied == 0)
                {
                    //Invalid ancillary packet
                    _ancillary_packet.clearData();
                    break;
                }
                
                if(_ancillary_packet.isPacketComplete())
                {
                    //complete the packet
                    completeAncillaryPacket();

                    _is_partial_line = FALSE;

                    p_buffer += bytes_copied;
                    buffer_size -= bytes_copied;
                    total_bytes_copied += bytes_copied;
                }
                else
                {
                    //The packet must be overlapping a buffer boundary.  Mark that it 
                    // is a partial line and return.
                    _is_partial_line = TRUE;
                    _last_sav = SAV_PARTIAL_ANCILLARY;
                    total_bytes_copied += bytes_copied;
                    return total_bytes_copied;
                }
                
            }
            
            return total_bytes_copied;
        }

    }

    _is_partial_line = FALSE;
    if(p_parse_buffer)
    {
        _last_sav = sav_eav;

        bytes_copied = p_parse_buffer->copyLine(p_buffer, buffer_size, current_field, &_is_partial_line);
    }

    return bytes_copied;
}


/////////////////////////////////////////////////////////////////////////////////////////
//This function is called when we have a complete ancillary packet.  Pass it to the 
// approptiate parse buffer to complete a buffer.
//
VOID Parse656Data::completeAncillaryPacket()
{
    BYTE data_id = _ancillary_packet.getDataID();
  
    switch(data_id)
    {
    case ANCILLARY_DID_AUDIO:
        _audio_parse_buffer.parseBuffer(&_ancillary_packet);
        break;

    case ANCILLARY_DID_VBI_FIELD1:   
	  
        _sliced_cc_buffer.parseBuffer(&_ancillary_packet);

⌨️ 快捷键说明

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