📄 parsebuffer.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 + -