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

📄 parsebuffer.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
字号:
/*+++ *******************************************************************\ 
* 
*  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 "ParseBuffer.h"
#include "BasePin.h"

/////////////////////////////////////////////////////////////////////////////////////////
ParseBuffer::ParseBuffer(DWORD line_size, DWORD lines_per_buffer):
_p_current_buffer(NULL),
_lines_completed(0),
_bytes_left_in_line(line_size),
_line_size(line_size),
_stride(line_size),
_lines_per_field(lines_per_buffer),
_current_field(FIELD_INVALID),
_p_pin(NULL)
{
    KeInitializeMutex(&_mutex, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////
ParseBuffer::~ParseBuffer()
{
    releasePin();
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID ParseBuffer::setPin(BasePin* p_pin)
{
    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );
    
    _p_pin = p_pin;

    setPinFormat();

    _p_current_buffer = NULL;
    _bytes_left_in_line = _line_size;

    KeReleaseMutex(&_mutex, FALSE);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID ParseBuffer::releasePin()
{
    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );
    
    _p_pin = NULL;
    _p_current_buffer = NULL;
    _bytes_left_in_line = _line_size;

    KeReleaseMutex(&_mutex, FALSE);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID ParseBuffer::setPinFormat()
{
   _stride = _p_pin->getStride();
   _lines_per_field = _p_pin->getLinesPerFrame() / 2;
   _line_size = _p_pin->getLineSize();

   _pin_format_changed = FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////
DWORD ParseBuffer::copyLine(PBYTE p_line, DWORD length, FIELD_TYPE field_number, BOOLEAN *partial_line)
{
    KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );

    if(_current_field != field_number)
    {
    	
        resetBuffer();
	
    }

    //Remember the field number for next time
    _current_field = field_number;

    //Get the number of bytes we need to copy for this line
    DWORD bytes_to_copy = _bytes_left_in_line;
    if(bytes_to_copy > length)
    {
        bytes_to_copy = length;
    }


    if(_lines_completed >= _lines_per_field)
    {
        _bytes_left_in_line -= bytes_to_copy;
        *partial_line = (_bytes_left_in_line == 0) ? FALSE : TRUE;
        KeReleaseMutex(&_mutex, FALSE);
        return 0;
    }

    *partial_line = TRUE;

    //If we don't have a buffer, just return the number of bytes we would
    // have copied if we had a buffer.
    if(!_p_current_buffer)
    {
        _bytes_left_in_line -= bytes_to_copy;
        *partial_line = (_bytes_left_in_line == 0) ? FALSE : TRUE;
        KeReleaseMutex(&_mutex, FALSE);
        return bytes_to_copy;
    }

    //We have a buffer.  Copy the line into it.
    doCopy(p_line, bytes_to_copy);

    _bytes_left_in_line -= bytes_to_copy;

    if(_bytes_left_in_line == 0)
    {
        //We have just completed a line
        _lines_completed++;
        _bytes_left_in_line = _line_size;
		*partial_line = FALSE;
    
        //Check if the buffer is complete
        if(isBufferDone())
        {         
            //complete the buffer
            _p_current_buffer->StreamHeader->DataUsed =_p_current_buffer->StreamHeader->FrameExtent;
            _p_pin->onBufferComplete(_current_field);

            //We no longer own the buffer
            _p_current_buffer = NULL;
            _lines_completed = 0;
        }
    }

    KeReleaseMutex(&_mutex, FALSE);
    return bytes_to_copy;
}
    

/////////////////////////////////////////////////////////////////////////////////////////
VOID ParseBuffer::resetBuffer()
{
    if(!_p_current_buffer && _p_pin)
    {
        _p_current_buffer = _p_pin->getNextBuffer();

        if(_pin_format_changed)
        {
            setPinFormat();
        }

    }

    _lines_completed = 0;
    _bytes_left_in_line = _line_size;
}

VOID ParseBuffer::doCopy(PBYTE p_buffer, DWORD bytes_to_copy)
{

    PBYTE p_out_buffer = (PBYTE)_p_current_buffer->StreamHeader->Data;
    DWORD current_line_bytes_copied = 0;
    if(_bytes_left_in_line != _line_size)
    {
        current_line_bytes_copied = _line_size - _bytes_left_in_line;
    }

    RtlCopyMemory(
        p_out_buffer + (_lines_completed * _stride) + current_line_bytes_copied,
        p_buffer,
        bytes_to_copy);
}

/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN ParseBuffer::isBufferDone()
{
    return (_lines_completed == _lines_per_field);
}

/*
//VBI stream must be parsed from VIP1.1/VIP2.0/BT656 inputs. 
//The parser logic will be provided by IC and then this function will be implemented.
DWORD ParseBuffer::parsevbiBuffer(BYTE* p_buffer, DWORD size,BYTE field_number)
{
	DWORD data = 0;
	data = size;
	KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL );
	if(_current_field != field_number)
    {
        resetBuffer();
    }
	 _current_field = (FIELD_TYPE)field_number;
	if(!_p_pin)
    {
        KeReleaseMutex(&_mutex, FALSE);
        return data;
    }
	if(!_p_current_buffer)
    {
        _p_current_buffer = _p_pin->getNextBuffer();
    }
 
    if(!_p_current_buffer)
    {
        KeReleaseMutex(&_mutex, FALSE);

        //No available buffer, nothing to do
        return data;
    }
	DWORD buffer_size = _p_current_buffer->StreamHeader->FrameExtent;
	 BYTE* p_out_buffer = (BYTE*)_p_current_buffer->StreamHeader->Data;
	 DWORD tmp = buffer_size - _current_copied_bytes;
	 if(size>tmp) // usb buffer > av buffer
	 {
	 	RtlCopyMemory(p_out_buffer+_current_copied_bytes,p_buffer,tmp);
		data = size - tmp;
		completeCurrentBuffer();

	 }
	 else  //usb buffer < av buffer
	 {
	 	RtlCopyMemory(p_out_buffer+_current_copied_bytes,p_buffer,size);
		_current_copied_bytes += size;
		 _p_current_buffer->StreamHeader->DataUsed = 
                _p_current_buffer->StreamHeader->FrameExtent;
        _p_pin->onBufferComplete(_current_field);
        _current_copied_bytes =0;
            //We no longer own the buffer
        _p_current_buffer = NULL;
		data = 0;
	 }
	 KeReleaseMutex(&_mutex, FALSE);
     return data;
}
VOID ParseBuffer::completeCurrentBuffer()
{
    if(!_p_current_buffer)
    {
        return;
    }

    DWORD buffer_size = _p_current_buffer->StreamHeader->FrameExtent;

    //complete the buffer if it is full
    _p_current_buffer->StreamHeader->DataUsed = buffer_size;
    

 	_current_copied_bytes = 0;
    _p_current_buffer = NULL;
}
*/

⌨️ 快捷键说明

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