📄 capture.cpp
字号:
if (OldFormat) {
//
// If we're in the stop state, we can handle just about any
// change. We don't support dynamic format changes.
//
if (Pin -> DeviceState == KSSTATE_STOP) {
if (!CapPin -> CaptureVideoInfoHeader ()) {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
//
// Because we don't accept dynamic format changes, we
// should never get here. Just being over-protective.
//
Status = STATUS_INVALID_DEVICE_STATE;
}
}
}
}
}
return Status;
}
/**************************************************************************
LOCKED CODE
**************************************************************************/
#ifdef ALLOC_PRAGMA
#pragma code_seg()
#endif // ALLOC_PRAGMA
void
CCapturePin::
CompleteMappings (
IN ULONG NumMappings
)
/*++
Routine Description:
Called to notify the pin that a given number of scatter / gather
mappings have completed. Let the buffers go if possible.
We're called at DPC.
Arguments:
NumMappings -
The number of mappings that have completed.
Return Value:
None
--*/
{
ULONG MappingsRemaining = NumMappings;
//
// Walk through the clones list and delete clones whose time has come.
// The list is guaranteed to be kept in the order they were cloned.
//
PKSSTREAM_POINTER Clone = KsPinGetFirstCloneStreamPointer (m_Pin);
while (MappingsRemaining && Clone) {
PKSSTREAM_POINTER NextClone = KsStreamPointerGetNextClone (Clone);
//
// Count up the number of bytes we've completed and mark this
// in the Stream Header. In mapped queues
// (KSPIN_FLAG_GENERATE_MAPPINGS), this is the responsibility of
// the minidriver. In non-mapped queues, AVStream performs this.
//
ULONG MappingsToCount =
(MappingsRemaining > Clone -> OffsetOut.Remaining) ?
Clone -> OffsetOut.Remaining :
MappingsRemaining;
//
// Update DataUsed according to the mappings.
//
for (ULONG CurMapping = 0; CurMapping < MappingsToCount; CurMapping++) {
Clone -> StreamHeader -> DataUsed +=
Clone -> OffsetOut.Mappings [CurMapping].ByteCount;
}
//
// If we have completed all remaining mappings in this clone, it
// is an indication that the clone is ready to be deleted and the
// buffer released. Set anything required in the stream header which
// has not yet been set. If we have a clock, we can timestamp the
// sample.
//
if (MappingsRemaining >= Clone -> OffsetOut.Remaining) {
Clone -> StreamHeader -> Duration =
m_VideoInfoHeader -> AvgTimePerFrame;
Clone -> StreamHeader -> PresentationTime.Numerator =
Clone -> StreamHeader -> PresentationTime.Denominator = 1;
//
// If a clock has been assigned, timestamp the packets with the
// time shown on the clock.
//
if (m_Clock) {
LONGLONG ClockTime = m_Clock -> GetTime ();
Clone -> StreamHeader -> PresentationTime.Time = ClockTime;
Clone -> StreamHeader -> OptionsFlags =
KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
} else {
//
// If there is no clock, don't time stamp the packets.
//
Clone -> StreamHeader -> PresentationTime.Time = 0;
}
MappingsRemaining -= Clone -> OffsetOut.Remaining;
//
// If all of the mappings in this clone have been completed,
// delete the clone. We've already updated DataUsed above.
//
KsStreamPointerDelete (Clone);
} else {
//
// If only part of the mappings in this clone have been completed,
// update the pointers. Since we're guaranteed this won't advance
// to a new frame by the check above, it won't fail.
//
KsStreamPointerAdvanceOffsets (
Clone,
0,
MappingsRemaining,
FALSE
);
MappingsRemaining = 0;
}
//
// Go to the next clone.
//
Clone = NextClone;
}
//
// If we've used all the mappings in hardware and pended, we can kick
// processing to happen again if we've completed mappings.
//
if (m_PendIo) {
m_PendIo = TRUE;
KsPinAttemptProcessing (m_Pin, TRUE);
}
}
/**************************************************************************
DISPATCH AND DESCRIPTOR LAYOUT
**************************************************************************/
#define D_X 320
#define D_Y 240
//
// FormatRGB24Bpp_Capture:
//
// This is the data range description of the RGB24 capture format we support.
//
const
KS_DATARANGE_VIDEO
FormatRGB24Bpp_Capture = {
//
// KSDATARANGE
//
{
sizeof (KS_DATARANGE_VIDEO), // FormatSize
0, // Flags
D_X * D_Y * 3, // SampleSize
0, // Reserved
STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO), // aka. MEDIATYPE_Video
0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20,
0xaf, 0x0b, 0xa7, 0x70, // aka. MEDIASUBTYPE_RGB24,
STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
},
TRUE, // BOOL, bFixedSizeSamples (all samples same size?)
TRUE, // BOOL, bTemporalCompression (all I frames?)
0, // Reserved (was StreamDescriptionFlags)
0, // Reserved (was MemoryAllocationFlags
// (KS_VIDEO_ALLOC_*))
//
// _KS_VIDEO_STREAM_CONFIG_CAPS
//
{
STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
KS_AnalogVideo_NTSC_M |
KS_AnalogVideo_PAL_B, // AnalogVideoStandard
720,480, // InputSize, (the inherent size of the incoming signal
// with every digitized pixel unique)
160,120, // MinCroppingSize, smallest rcSrc cropping rect allowed
720,480, // MaxCroppingSize, largest rcSrc cropping rect allowed
8, // CropGranularityX, granularity of cropping size
1, // CropGranularityY
8, // CropAlignX, alignment of cropping rect
1, // CropAlignY;
160, 120, // MinOutputSize, smallest bitmap stream can produce
720, 480, // MaxOutputSize, largest bitmap stream can produce
8, // OutputGranularityX, granularity of output bitmap size
1, // OutputGranularityY;
0, // StretchTapsX (0 no stretch, 1 pix dup, 2 interp...)
0, // StretchTapsY
0, // ShrinkTapsX
0, // ShrinkTapsY
333667, // MinFrameInterval, 100 nS units
640000000, // MaxFrameInterval, 100 nS units
8 * 3 * 30 * 160 * 120, // MinBitsPerSecond;
8 * 3 * 30 * 720 * 480 // MaxBitsPerSecond;
},
//
// KS_VIDEOINFOHEADER (default format)
//
{
0,0,0,0, // RECT rcSource;
0,0,0,0, // RECT rcTarget;
D_X * D_Y * 3 * 30, // DWORD dwBitRate;
0L, // DWORD dwBitErrorRate;
333667, // REFERENCE_TIME AvgTimePerFrame;
sizeof (KS_BITMAPINFOHEADER), // DWORD biSize;
D_X, // LONG biWidth;
-D_Y, // LONG biHeight;
1, // WORD biPlanes;
24, // WORD biBitCount;
KS_BI_RGB, // DWORD biCompression;
D_X * D_Y * 3, // DWORD biSizeImage;
0, // LONG biXPelsPerMeter;
0, // LONG biYPelsPerMeter;
0, // DWORD biClrUsed;
0 // DWORD biClrImportant;
}
};
#undef D_X
#undef D_Y
#define D_X 320
#define D_Y 240
//
// FormatUYU2_Capture:
//
// This is the data range description of the UYVY format we support.
//
const
KS_DATARANGE_VIDEO
FormatUYU2_Capture = {
//
// KSDATARANGE
//
{
sizeof (KS_DATARANGE_VIDEO), // FormatSize
0, // Flags
D_X * D_Y * 2, // SampleSize
0, // Reserved
STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO), // aka. MEDIATYPE_Video
0x59565955, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71, // aka. MEDIASUBTYPE_UYVY,
STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
},
TRUE, // BOOL, bFixedSizeSamples (all samples same size?)
TRUE, // BOOL, bTemporalCompression (all I frames?)
0, // Reserved (was StreamDescriptionFlags)
0, // Reserved (was MemoryAllocationFlags
// (KS_VIDEO_ALLOC_*))
//
// _KS_VIDEO_STREAM_CONFIG_CAPS
//
{
STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
KS_AnalogVideo_NTSC_M |
KS_AnalogVideo_PAL_B, // AnalogVideoStandard
720,480, // InputSize, (the inherent size of the incoming signal
// with every digitized pixel unique)
160,120, // MinCroppingSize, smallest rcSrc cropping rect allowed
720,480, // MaxCroppingSize, largest rcSrc cropping rect allowed
8, // CropGranularityX, granularity of cropping size
1, // CropGranularityY
8, // CropAlignX, alignment of cropping rect
1, // CropAlignY;
160, 120, // MinOutputSize, smallest bitmap stream can produce
720, 480, // MaxOutputSize, largest bitmap stream can produce
8, // OutputGranularityX, granularity of output bitmap size
1, // OutputGranularityY;
0, // StretchTapsX (0 no stretch, 1 pix dup, 2 interp...)
0, // StretchTapsY
0, // ShrinkTapsX
0, // ShrinkTapsY
333667, // MinFrameInterval, 100 nS units
640000000, // MaxFrameInterval, 100 nS units
8 * 2 * 30 * 160 * 120, // MinBitsPerSecond;
8 * 2 * 30 * 720 * 480 // MaxBitsPerSecond;
},
//
// KS_VIDEOINFOHEADER (default format)
//
{
0,0,0,0, // RECT rcSource;
0,0,0,0, // RECT rcTarget;
D_X * D_Y * 2 * 30, // DWORD dwBitRate;
0L, // DWORD dwBitErrorRate;
333667, // REFERENCE_TIME AvgTimePerFrame;
sizeof (KS_BITMAPINFOHEADER), // DWORD biSize;
D_X, // LONG biWidth;
D_Y, // LONG biHeight;
1, // WORD biPlanes;
16, // WORD biBitCount;
FOURCC_YUV422, // DWORD biCompression;
D_X * D_Y * 2, // DWORD biSizeImage;
0, // LONG biXPelsPerMeter;
0, // LONG biYPelsPerMeter;
0, // DWORD biClrUsed;
0 // DWORD biClrImportant;
}
};
//
// CapturePinDispatch:
//
// This is the dispatch table for the capture pin. It provides notifications
// about creation, closure, processing, data formats, etc...
//
const
KSPIN_DISPATCH
CapturePinDispatch = {
CCapturePin::DispatchCreate, // Pin Create
NULL, // Pin Close
CCapturePin::DispatchProcess, // Pin Process
NULL, // Pin Reset
CCapturePin::DispatchSetFormat, // Pin Set Data Format
CCapturePin::DispatchSetState, // Pin Set Device State
NULL, // Pin Connect
NULL, // Pin Disconnect
NULL, // Clock Dispatch
NULL // Allocator Dispatch
};
//
// CapturePinAllocatorFraming:
//
// This is the simple framing structure for the capture pin. Note that this
// will be modified via KsEdit when the actual capture format is determined.
//
DECLARE_SIMPLE_FRAMING_EX (
CapturePinAllocatorFraming,
STATICGUIDOF (KSMEMORY_TYPE_KERNEL_NONPAGED),
KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY,
2,
0,
2 * PAGE_SIZE,
2 * PAGE_SIZE
);
//
// CapturePinDataRanges:
//
// This is the list of data ranges supported on the capture pin. We support
// two: one RGB24, and one UYVY.
//
const
PKSDATARANGE
CapturePinDataRanges [CAPTURE_PIN_DATA_RANGE_COUNT] = {
(PKSDATARANGE) &FormatRGB24Bpp_Capture,
(PKSDATARANGE) &FormatUYU2_Capture
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -