AVStream minidriver question (Stream Pointers)

Hello,

On the USB BDA driver currently am working on has this problem.

Capture out pin is registered with capability of handling MaxFrameSize as 58656 bytes(188(TS packets) * 312).
When 58656 bytes of data has been accumulated from USB pipe, a call is made to KsPinAttemptProcessing to get Process callback.
In process callback, KsPinGetLeadingEdgeStreamPointer is called to get the Stream Pointer and copying captured data to stream pointer’s buffer.
Most of the times Stream pointer will have buffer of size 58656 bytes.
Sometimes, the stream pointer will have a buffer size in the order of 60 or 70MB.
Pin is registered for a queue of 8 frames. When i get this buffer of random size, data is copied but is limited to what i have and doesn’t fill the entire buffer of stream pointer and cannot see the video.
During Pin creation, IntersectDataFormat is also matching.

I would appreciate if anybody can throw some tips on countering this problem.

/////////////////////////////////////////////////////////////////
Process Callback

stream_pointer = KsPinGetLeadingEdgeStreamPointer(GlobalBDA_CapPinOut, KSSTREAM_POINTER_STATE_LOCKED);
if (!stream_pointer)
{
BDA_DEBUG0(“StreamThread: stream_pointer:(%p) FAILED - no data frame associated with the leading edge.”,
stream_pointer);

}
else
{
if( (GlobalDevExtPtr->TsBuffPtr) && (stream_pointer) )
{

if (stream_pointer->OffsetOut.Remaining > TS_FRAME_SIZE)
{
BDA_DEBUG0(" CATCH : – Ghost Size %d", stream_pointer->OffsetOut.Remaining);
BDA_DEBUG0(" StreamHeader: – FrameExtent %d", stream_pointer->StreamHeader->FrameExtent);
BDA_DEBUG0(" StreamHeader: – DataUsed %d", stream_pointer->StreamHeader->DataUsed);

stream_pointer->OffsetOut.Remaining = TS_FRAME_SIZE;
stream_pointer->StreamHeader->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_TYPECHANGED;
stream_pointer->StreamHeader->Data = (PVOID)&FormatCaptureOut1;
stream_pointer->StreamHeader->Size = sizeof(KSSTREAM_HEADER);

}
else
{
RtlCopyMemory(stream_pointer->OffsetOut.Data,
GlobalDevExtPtr->TsBuffPtr,
TS_FRAME_SIZE);

KsStreamPointerAdvanceOffsetsAndUnlock(stream_pointer,
0,
stream_pointer->OffsetOut.Count,
TRUE);
}
}
}

/////////////////////////////////////////////////////
Capture Out PIN data format

const KSDATARANGE FormatCaptureOut =
{
{
sizeof( KSDATARANGE), // ULONG FormatSize - Specifies the size, in bytes, of this structure.
0, // ULONG Flags - This member is ignored.
58646, // 58656 – ULONG SampleSize - This member is ignored.
0, // ULONG Reserved.
{ STATIC_KSDATAFORMAT_TYPE_STREAM }, // GUID MajorFormat - major format of a data format.
{ STATIC_KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT },// GUID SubFormat - subformat of a data format.
{ STATIC_KSDATAFORMAT_SPECIFIER_NONE } // GUID Specifier - specifier of the data format.
}
};

////////////////////////////////////////////////////////////
Capture Out Pin Allocation

DECLARE_SIMPLE_FRAMING_EX (
CaptureOutPinAllocatorFraming, // FramingExName
STATICGUIDOF (KSMEMORY_TYPE_KERNEL_NONPAGED), // MemoryType
KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY, // Flags
8, // Frames
FILE_BYTE_ALIGNMENT, // Alignment FILE_BYTE_ALIGNMENT
188, // 188 – MinFrameSize
58646 // 58646 – MaxFrameSize
);

///////////////////////////////////////////////////////////

PIN Description.

const KSPIN_DESCRIPTOR_EX BdaCaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT] = {
//
// Capture Input Pin
//
{
&CaptureInPinDispatch, // const KSPIN_DISPATCH* Dispatch
NULL, // const KSAUTOMATION_TABLE* AutomationTable
{ // KSPIN_DESCRIPTOR PinDescriptor
0, // ULONG InterfacesCount
NULL, // const KSPIN_INTERFACE* Interfaces
1, // ULONG MediumsCount
&TransportPinMedium, // const KSPIN_MEDIUM *Mediums
SIZEOF_ARRAY (CaptureInPinDataRanges), // Range Count
CaptureInPinDataRanges, // Ranges
KSPIN_DATAFLOW_IN, // Dataflow
KSPIN_COMMUNICATION_BOTH, // Communication
NULL, // Category
NULL, // Name
0 // Reserved
},
KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT |
KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING |
KSPIN_FLAG_FIXED_FORMAT,
1, // Instances Possible
1, // Instances Necessary
NULL, // Allocator Framing
NULL // Pin Intersect Handler
},
//
// Capture Output Pin
//
{
&CaptureOutPinDispatch, // Dispatch: Dispatch table and a process dispatch.
NULL, // AutomationTable: Contains the properties, methods, and events supported by the pin.
{ // PinDescriptor: This member specifies a structure of type KSPIN_DESCRIPTOR.
NULL, // InterfacesCount: Size of array pointed to by Interfaces (NULL, 0 == default)
0, // Interfaces: An array of KSPIN_INTERFACE structures.
NULL, // MediumsCount: Specifies the number of elements in the array pointed to by Mediums.
0, // Mediums: Mediums supported by this pin type.
SIZEOF_ARRAY (CaptureOutPinDataRanges), // DataRangesCount: Specifies the size of the array pointed to by DataRanges.
CaptureOutPinDataRanges, // DataRanges: Data ranges supported by this pin type.
KSPIN_DATAFLOW_OUT, // Dataflow:
KSPIN_COMMUNICATION_BOTH, // Communication:
NULL, // Category: Specifies the category GUID.
NULL, // Name:
0 // Reserved:
},
KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | // Pin Flags:
KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING, //
1, // Instances Possible: Possible instances of this pin.
1, // Instances Necessary: Minimum number of pins of a given pin type.
&CaptureOutPinAllocatorFraming, // Allocator Framing: A pointer to a KSALLOCATOR_FRAMING_EX structure.
NULL // Format Intersect Handler
}
};

xxxxx@gmail.com wrote:

On the USB BDA driver currently am working on has this problem.

Capture out pin is registered with capability of handling MaxFrameSize as 58656 bytes(188(TS packets) * 312).
When 58656 bytes of data has been accumulated from USB pipe, a call is made to KsPinAttemptProcessing to get Process callback.
In process callback, KsPinGetLeadingEdgeStreamPointer is called to get the Stream Pointer and copying captured data to stream pointer’s buffer.
Most of the times Stream pointer will have buffer of size 58656 bytes.
Sometimes, the stream pointer will have a buffer size in the order of 60 or 70MB.

Sometimes, for reasons I was never sure of, you will get a valid stream
pointer where StreamHeader->Data is NULL. In that case, the rest of the
parameters are garbage. If that happens, you should just call
KsStreamPointerAdvance and try again.

Do you realize that your Process callback will also get called any time
a new buffer arrives at your pin? You need to be ready to handle the
case where you are called but have nothing to send. It looks to me like
you leave the leading edge locked in that case.

if( (GlobalDevExtPtr->TsBuffPtr) && (stream_pointer) )
{
if (stream_pointer->OffsetOut.Remaining > TS_FRAME_SIZE)
{
BDA_DEBUG0(" CATCH : – Ghost Size %d", stream_pointer->OffsetOut.Remaining);
BDA_DEBUG0(" StreamHeader: – FrameExtent %d", stream_pointer->StreamHeader->FrameExtent);
BDA_DEBUG0(" StreamHeader: – DataUsed %d", stream_pointer->StreamHeader->DataUsed);

stream_pointer->OffsetOut.Remaining = TS_FRAME_SIZE;
stream_pointer->StreamHeader->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_TYPECHANGED;
stream_pointer->StreamHeader->Data = (PVOID)&FormatCaptureOut1;
stream_pointer->StreamHeader->Size = sizeof(KSSTREAM_HEADER);

Where did you get this code? You are overwriting the Data pointer to
point to your own buffer? What happens to the buffer that USED to be in
StreamHeader->Data?

{
RtlCopyMemory(stream_pointer->OffsetOut.Data,
GlobalDevExtPtr->TsBuffPtr,
TS_FRAME_SIZE);

KsStreamPointerAdvanceOffsetsAndUnlock(stream_pointer,
0,
stream_pointer->OffsetOut.Count,
TRUE);

If you want to advance the whole packet, you can just call
KsStreamPointerAdvance


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim,

Code was gifted to me by one of my friend at work.

In my case, StreamHeader->Data is NOT NULL and yet the buffer sizes are garbage.
After using KsStreamPointerAdvance on these stream pointers its of no use as the next stream pointer is also same(random size). Only way for me to get out of this is to rebuild the graph. I know DirectShow sends random buffer size if the minidriver doesnt specify frame size’s. But in this case Directshow is sending random size even if minidriver has valid frame sizes and IntersectDataFormat also matches.

I did try to enable KSSTREAM_HEADER_OPTIONSF_TYPECHANGED flag on the stream header and passed on the minidriver’s Data Format but there was no difference.

I did change the code my as per your tips and now use StreamHeader->Data, instead of stream_pointer->OffsetOut.Data,. and unlocking the stream pointer if i don’t have any data to send.

Thanks,
M