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

📄 videoparsebuffer.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 "VideoParseBuffer.h"
#include "BasePin.h"

/////////////////////////////////////////////////////////////////////////////////////////
VideoParseBuffer::VideoParseBuffer(DWORD line_size, DWORD lines_per_buffer):
ParseBuffer(line_size, lines_per_buffer),
_field1_done(FALSE),
_is_single_field_stream(FALSE)
{
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID VideoParseBuffer::doDualFieldCopy(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;
    }

    //Offset field 2 one line from the top of the buffer
    //DWORD offset = (_current_field == FIELD_2) ? 0 : _stride; 
	 DWORD offset = (_current_field == FIELD_1) ? 0 : _stride; 


    //Offset for field 2
    PBYTE p_out_line = p_out_buffer + offset;       
    //lines already completed in the current field
    p_out_line += (_lines_completed * _stride * 2); 
    //bytes already completed in the current line
    p_out_line += current_line_bytes_copied;        

    //Do the copy
    RtlCopyMemory(
        p_out_line,
        p_buffer,
        bytes_to_copy);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID VideoParseBuffer::doSingleFieldCopy(PBYTE p_buffer, DWORD bytes_to_copy)
{
    //Do not copy anything from field 2
    if(_current_field == FIELD_2)
    {
        return;
    }

    PBYTE p_out_line = (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;
    }

    //lines already completed
    p_out_line += (_lines_completed * _stride); 
    //bytes already completed in the current line
    p_out_line += current_line_bytes_copied;        

    //Do the copy
    RtlCopyMemory(
        p_out_line,
        p_buffer,
        bytes_to_copy);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID VideoParseBuffer::doCopy(PBYTE p_buffer, DWORD bytes_to_copy)
{
    if(_is_single_field_stream)
    {
        doSingleFieldCopy(p_buffer, bytes_to_copy);
    }
    else
    {
        doDualFieldCopy(p_buffer, bytes_to_copy);    
    }

}

/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN VideoParseBuffer::isBufferDone()
{
    BOOLEAN buffer_complete = FALSE;

    if(!_is_single_field_stream)
    {
        //Dual field stream
        buffer_complete = 
            ((_current_field == FIELD_2) && 
            (_lines_completed >= _lines_per_field) &&
            _field1_done);
    }
    else
    {
        //Single field stream
        buffer_complete = 
            ((_current_field == FIELD_1) && 
            (_lines_completed >= _lines_per_field));

    }

    return (_p_current_buffer && buffer_complete);
}

/////////////////////////////////////////////////////////////////////////////////////////
VOID VideoParseBuffer::setPinFormat()
{
    _is_single_field_stream = _p_pin->isSingleFieldStream();
    _stride = _p_pin->getStride();
    _lines_per_field = _p_pin->getLinesPerFrame();
    _line_size = _p_pin->getLineSize();


 
    //For dual field streams, the lines per buffer is actually the lines per field
    if(!_is_single_field_stream)
    {
        _lines_per_field /= 2;
    }
    
    _pin_format_changed = FALSE;
}


/////////////////////////////////////////////////////////////////////////////////////////
//This is called when the field changes or when a buffer completes
//
VOID VideoParseBuffer::resetBuffer()
{
    //Handle the switch from field 1 to field 2
    if(_current_field == FIELD_1)
    {
        if(_lines_completed >= _lines_per_field)
        {
            _field1_done = TRUE;
        }
        else
        {
            _field1_done = FALSE;
        }
    }

    //Get a new buffer if we don't already have one.
    if(!_p_current_buffer && _p_pin)
    {
        _p_current_buffer = _p_pin->getNextBuffer();
        
        //Since the pin's format can change after we set the pin object,
        //update the pin's data here.
        if(_pin_format_changed)
        {
            setPinFormat();
        }

        _field1_done = FALSE;
    }
            
    //Reset our counters
    _lines_completed = 0;
    _bytes_left_in_line = _line_size;
}

⌨️ 快捷键说明

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