📄 videopin.cpp
字号:
{
DbgLogError(("setDataFormat invalid format change\n"));
return STATUS_NO_MATCH;
}
// Everything matched so copy the new settings
p_vid_pin->_format = new_format;
p_vid_pin->_info_hdr = p_new_format->VideoInfoHeader;
KSALLOCATOR_FRAMING_EX *p_framing =
const_cast<KSALLOCATOR_FRAMING_EX*>
(p_ks_pin->Descriptor->AllocatorFraming);
// Update the framing members that use
// biSizeImage since it changed
p_framing->FramingItem[0].PhysicalRange.MinFrameSize =
p_framing->FramingItem[0].PhysicalRange.MaxFrameSize =
p_framing->FramingItem[0].FramingRange.Range.MinFrameSize =
p_framing->FramingItem[0].FramingRange.Range.MaxFrameSize =
p_vid_pin->_info_hdr.bmiHeader.biSizeImage;
//Update the resolution in the video decoder object
IVideoDecoder* p_decoder = p_vid_pin->_p_device->getVidDec();
p_decoder->setResolution(new_format.imageWidth(), abs(new_format.imageHeight()));
p_vid_pin->_p_device->notifyPinFormatChange(p_vid_pin);
}
return STATUS_SUCCESS;
}
return STATUS_NO_MATCH;
}
/*************************************************************************
Routine Description:
This routine handles video pin intersection queries by determining the
intersection between two data ranges.
Arguments:
Filter -
Contains a void pointer to the filter structure.
Irp -
Contains a pointer to the data intersection property request.
PinInstance -
Contains a pointer to a structure indicating the pin in question.
CallerDataRange -
Contains a pointer to one of the data ranges supplied by the client
in the data intersection request. The format type, subtype and
specifier are compatible with the DescriptorDataRange.
DescriptorDataRange -
Contains a pointer to one of the data ranges from the pin descriptor
for the pin in question. The format type, subtype and specifier are
compatible with the CallerDataRange.
BufferSize -
Contains the size in bytes of the buffer pointed to by the Data
argument. For size queries, this value will be zero.
Data -
Optionally contains a pointer to the buffer to contain the data
format structure representing the best format in the intersection
of the two data ranges. For size queries, this pointer will be
NULL.
DataSize -
Contains a pointer to the location at which to deposit the size
of the data format. This information is supplied by the function
when the format is actually delivered and in response to size
queries.
Return Value:
STATUS_SUCCESS if there is an intersection and it fits in the supplied
buffer, STATUS_BUFFER_OVERFLOW for successful size queries,
STATUS_NO_MATCH if the intersection is empty, or
STATUS_BUFFER_TOO_SMALL if the supplied buffer is too small.
**************************************************************************/
NTSTATUS VideoPin::intersectRange(
PKSFILTER p_filter,
PIRP p_irp,
PKSP_PIN p_pin_instance,
PKS_DATARANGE_VIDEO p_caller_range,
PKS_DATARANGE_VIDEO p_our_range, // Data range from our descriptor
ULONG buffer_size,
PVOID p_data,
PULONG p_data_size)
{
Device *p_device = getDevice( p_irp );
if( IsEqualGUID( p_caller_range->DataRange.Specifier,
KSDATAFORMAT_SPECIFIER_VIDEOINFO ) )
{
ULONG caller_range_sz = p_caller_range->DataRange.FormatSize;
if(caller_range_sz < sizeof(KS_DATARANGE_VIDEO))
{
return STATUS_INVALID_PARAMETER;
}
// Make sure the two data ranges are the same
if((p_caller_range->bFixedSizeSamples != p_our_range->bFixedSizeSamples) ||
(p_caller_range->bTemporalCompression != p_our_range->bTemporalCompression) ||
(p_caller_range->StreamDescriptionFlags != p_our_range->StreamDescriptionFlags) ||
(p_caller_range->MemoryAllocationFlags != p_our_range->MemoryAllocationFlags) ||
(RtlCompareMemory(
&p_caller_range->ConfigCaps,
&p_our_range->ConfigCaps,
sizeof(KS_VIDEO_STREAM_CONFIG_CAPS)) != sizeof KS_VIDEO_STREAM_CONFIG_CAPS))
{
return STATUS_NO_MATCH;
}
// Check that we support the requested image dimensions.
if(!checkDimensions(
&p_caller_range->VideoInfoHeader,
&p_our_range->VideoInfoHeader,
&p_our_range->ConfigCaps,
p_device->IsSoftEncoderEnabled()))
{
return STATUS_NO_MATCH;
}
ULONG vid_hdr_sz = KS_SIZE_VIDEOHEADER(&p_caller_range->VideoInfoHeader);
ULONG calculated_range_sz =
FIELD_OFFSET(KS_DATARANGE_VIDEO, VideoInfoHeader ) + vid_hdr_sz;
if(calculated_range_sz != caller_range_sz)
{
return STATUS_INVALID_PARAMETER;
}
// Set the required output buffer size
ULONG data_format_sz = sizeof(KSDATAFORMAT) + vid_hdr_sz;
*p_data_size = data_format_sz;
// If buffer_size is 0 this is a size query
if(buffer_size == 0)
{
return STATUS_BUFFER_OVERFLOW;
}
// Check that the output data buffer is large enough
if(buffer_size < data_format_sz)
{
return STATUS_BUFFER_TOO_SMALL;
}
KS_DATAFORMAT_VIDEOINFOHEADER* p_out_format =
(KS_DATAFORMAT_VIDEOINFOHEADER*)p_data;
// Copy the DataFormat the the output struct
RtlCopyMemory(
&p_out_format->DataFormat,
p_our_range,
sizeof(KSDATAFORMAT));
// Since the input structs are KS_DATARANGE_VIDEO and the
// output struct is a KS_DATAFORMAT_VIDEOINFOHEADER we need
// to set the FormatSize according to the output struct.
p_out_format->DataFormat.FormatSize = data_format_sz;
// Copy the KS_VIDEOINFOHEADER to the output struct
RtlCopyMemory(
&p_out_format->VideoInfoHeader,
&p_caller_range->VideoInfoHeader,
vid_hdr_sz);
// Calculate the image size for this request, and put
// the result in both biSizeImage and SampleSize.
p_out_format->VideoInfoHeader.bmiHeader.biSizeImage =
p_out_format->DataFormat.SampleSize = KS_DIBSIZE( p_out_format->VideoInfoHeader.bmiHeader );
return STATUS_SUCCESS;
}
return STATUS_NO_MATCH;
}
VOID VideoPin::fillFrameInfo(PKSSTREAM_HEADER p_strm_hdr, FIELD_TYPE field_type)
{
if(p_strm_hdr->Size < (sizeof(KSSTREAM_HEADER) + sizeof(KS_FRAME_INFO)))
{
DbgLogError((
"VideoPin::fillFrameInfo Size = %d\n",
p_strm_hdr->Size));
return;
}
KS_FRAME_INFO *p_frame_info =
reinterpret_cast<KS_FRAME_INFO*>( p_strm_hdr + 1 );
p_frame_info->ExtendedHeaderSize = sizeof(KS_FRAME_INFO);
p_frame_info->dwFrameFlags = KS_VIDEO_FLAG_FRAME;
p_frame_info->PictureNumber = ++_picture_num;
p_frame_info->DropCount = _dropped_cnt;
}
PIN_TYPES VideoPin::getPinType()
{
return PIN_TYPE_VIDEO;
}
const KSPIN_DISPATCH VideoPinDispatch =
{
VideoPin::dispatchCreate, // Pin Create
BasePin::dispatchClose, // Pin Close
BasePin::dispatchProcess, // Pin Process
NULL, // Pin Reset
(PFNKSPINSETDATAFORMAT)VideoPin::dispatchSetFormat, // Pin Set Data Format
BasePin::dispatchSetState, // Pin Set Device State
NULL, // Pin Connect
NULL, // Pin Disconnect
NULL, // Clock Dispatch
NULL // Allocator Dispatch
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -