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