[wdmaudiodev] [AVStream] Extending avshws for audio capture

  • From: Manu R Iyengar <manu.gogeta@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Sat, 18 Jul 2015 22:59:28 +0530

I’m trying to come up with an AVStream minidriver for audio / video
capture. I’m using AVSHWS as my reference and trying to add audio capture
functionality.


Towards this, I have added an additional pin and pin info to filter
descriptor -


const

KSPIN_DESCRIPTOR_EX

CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT] = {

//

// Video Capture Pin

//

{

&CapturePinDispatch,

NULL,

{

0, // Interfaces (NULL, 0 ==
default)

NULL,

0, // Mediums (NULL, 0 == default)

NULL,

SIZEOF_ARRAY(CapturePinDataRanges),// Range Count

CapturePinDataRanges, // Ranges

KSPIN_DATAFLOW_OUT, // Dataflow

KSPIN_COMMUNICATION_BOTH, // Communication

&PIN_CATEGORY_CAPTURE, // Category

&g_PINNAME_VIDEO_CAPTURE, // Name

0 // Reserved

},

#ifdef _X86_

KSPIN_FLAG_GENERATE_MAPPINGS | // Pin Flags

#endif

KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY,

1, // Instances Possible

1, // Instances Necessary

&CapturePinAllocatorFraming, // Allocator Framing

reinterpret_cast <PFNKSINTERSECTHANDLEREX>

(CCapturePin::IntersectHandler)

},


//

// Audio Capture Pin

//

{

&AudioCapturePinDispatch,

NULL,

{

0, // Interfaces (NULL, 0 == default)

NULL,

0, // Mediums (NULL, 0 == default)

NULL,

SIZEOF_ARRAY(AudioCapturePinDataRanges),// Range Count

AudioCapturePinDataRanges, // Ranges

KSPIN_DATAFLOW_OUT, // Dataflow

KSPIN_COMMUNICATION_BOTH, // Communication

&KSCATEGORY_AUDIO, // Category

&g_PINNAME_AUDIO_CAPTURE, // Name

0 // Reserved

},

KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING | // Flags

KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY |

KSPIN_FLAG_FIXED_FORMAT,

1, // Instances Possible

0, // Instances Necessary

&AudCapturePinAllocatorFraming, // Allocator Framing

reinterpret_cast <PFNKSINTERSECTHANDLEREX>

(CAudioCapturePin::AudioIntersectHandler)

}

};

As a first step, I'm trying to see if this audio pin can be connected to
any standard render pin. But I get the following error in graphEdit -

Return code 0x80040274 (No Video port hardware is available or hardware is
not responding). However, the video capture pin is working fine

I checked what is happening through debugView. Looks like a whole lot of
IntersectHandler callbacks are being made. There are no errors caught
either.

Here's a snippet of my intersectHandler implementation -

...

const GUID AudioInfoSpecifier =
{ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) };

NT_ASSERT(Filter);
NT_ASSERT(Irp);
NT_ASSERT(PinInstance);
NT_ASSERT(CallerDataRange);
NT_ASSERT(DescriptorDataRange);
NT_ASSERT(DataSize);

ULONG DataFormatSize;

//
// Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
//
if (IsEqualGUID(CallerDataRange->Specifier, AudioInfoSpecifier) &&
CallerDataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO)) {

PKSDATARANGE_AUDIO callerDataRange =
reinterpret_cast <PKSDATARANGE_AUDIO> (CallerDataRange);

PKSDATARANGE_AUDIO descriptorDataRange =
reinterpret_cast <PKSDATARANGE_AUDIO> (DescriptorDataRange);

//
// If the passed buffer size is 0, it indicates that this is a size
// only query. Return the size of the intersecting data format and
// pass back STATUS_BUFFER_OVERFLOW.
//
if (BufferSize == 0) {

*DataSize = sizeof(KSDATAFORMAT_WAVEFORMATEX);

return STATUS_BUFFER_OVERFLOW;

}

//
// Check that the other fields match
//
if ((callerDataRange->MaximumBitsPerSample !=
descriptorDataRange->MaximumBitsPerSample) ||
(callerDataRange->MaximumChannels !=
descriptorDataRange->MaximumChannels) ||
(callerDataRange->MaximumSampleFrequency !=
descriptorDataRange->MaximumSampleFrequency) ||
(callerDataRange->MinimumBitsPerSample !=
descriptorDataRange->MinimumBitsPerSample) ||
(callerDataRange->MinimumSampleFrequency !=
descriptorDataRange->MinimumSampleFrequency))
{
return STATUS_NO_MATCH;
}

PKSDATAFORMAT_WAVEFORMATEX WaveFormat =
reinterpret_cast <PKSDATAFORMAT_WAVEFORMATEX> (Data);

DataFormatSize =
sizeof(KSDATAFORMAT_WAVEFORMATEX);

RtlCopyMemory(
&WaveFormat->DataFormat,
&descriptorDataRange->DataRange,
sizeof(KSDATAFORMAT)
);

//
// Verify that the provided structure is large enough to
// accept the result.
//
if (BufferSize < DataFormatSize)
{
return STATUS_BUFFER_TOO_SMALL;
}

WaveFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
WaveFormat->WaveFormatEx.nChannels =
(WORD)descriptorDataRange->MaximumChannels;
WaveFormat->WaveFormatEx.nSamplesPerSec =
descriptorDataRange->MaximumSampleFrequency;
WaveFormat->WaveFormatEx.wBitsPerSample =
(WORD)descriptorDataRange->MaximumBitsPerSample;
WaveFormat->WaveFormatEx.nBlockAlign =
(WaveFormat->WaveFormatEx.wBitsPerSample / 8) *
WaveFormat->WaveFormatEx.nChannels;
WaveFormat->WaveFormatEx.nAvgBytesPerSec =
WaveFormat->WaveFormatEx.nSamplesPerSec *
WaveFormat->WaveFormatEx.nBlockAlign;
WaveFormat->WaveFormatEx.cbSize = 0;
WaveFormat->DataFormat.SampleSize =
WaveFormat->WaveFormatEx.nBlockAlign;

//
// Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader
//
*DataSize = DataFormatSize;

//
// REVIEW - Perform other validation such as cropping and scaling checks
//

return STATUS_SUCCESS;

} // End of AudioInfoSpecifier
...

Please help me out here !!

--
Manu.

Other related posts:

  • » [wdmaudiodev] [AVStream] Extending avshws for audio capture - Manu R Iyengar