[wdmaudiodev] Re: How to implement KSPROPSETID_AudioSignalProcessing Property Set in AVstream mini-driver

  • From: Yudi Cao <yudi.cao@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Tue, 23 May 2017 17:35:42 +0800

Yes. You are right.
With KSDATAFORMAT_ATTRIBUTES in the KSDATAFORMAT, the driver pass HLK test "KS
Topology Filters\KS Pins\Check Processing Modes".

Thank you for your help,
Hunter

On Thu, May 18, 2017 at 11:26 PM, Matthew van Eerde <
dmarc-noreply@xxxxxxxxxxxxx> wrote:

It looks like what is happening is:

   1. Windows and the test are calling your data intersection handler and
   getting a KSDATAFORMAT back
   2. This format does not have the KSDATAFORMAT_ATTRIBUTES flag set
   3. Windows and the test knows that your driver is “mode aware” because
   you support KSPROPERTY_AUDIOSIGNALPROCESSING_MODES so they modify the
   format to set the flag and use AUDIO_SIGNALPROCESSINGMODE_RAW
   4. Windows and the test call KsCreatePin with the modified format
   5. This fails with ERROR_NOT_FOUND (probably mapped from
   STATUS_NO_MATCH) – since your pin creation dispatch routine is not being
   invoked, it must be failing above you, probably in ks.sys



Verify that you updated your pin’s advertised data ranges to include
KSDATARANGE_ATTRIBUTES, followed by an attribute list, for each supported
data range. As an example see MicArrayPinDataRangesProcessedStream in the
SysVad sample.



https://github.com/Microsoft/Windows-driver-samples/blob/
master/audio/sysvad/EndpointsCommon/micarraywavtable.h



*From: *Yudi Cao <yudi.cao@xxxxxxxxx>
*Sent: *Thursday, May 18, 2017 6:34 AM
*To: *wdmaudiodev@xxxxxxxxxxxxx

*Subject: *[wdmaudiodev] Re: How to implement 
KSPROPSETID_AudioSignalProcessing
Property Set in AVstream mini-driver



Hi Mathew,



In "KS Topology Filters\KS Pins\Check Processing Modes", there will be
error: "pCPinInstance->CreatePin() failed with 0x90000491."



The detail log is below:



      Pin[00] ()

      Pin[00] : Basic support: 0x201

    KSPROPERTY_AUDIOSIGNALPROCESSING_MODES response: KSMULTIPLE_ITEM.Size
= 24, KSMULTIPLE_ITEM.Count = 1, buffer size = 24

    AUDIO_SIGNALPROCESSINGMODE_RAW is mode 0

    Message:Driver supports processing modes but the preferred formats
donot have the attribute flag set, so setting it [hr = E_INVALIDARG
(0x80070057)]

    pCPinInstance->CreatePin() failed with 0x90000491.

      FAIL: Pin[00] : Pin creation failed for
AUDIO_SIGNALPROCESSINGMODE_RAW

      Pin[01] (Capture)

      Pin[01] Capture: Basic support: 0x201

    KSPROPERTY_AUDIOSIGNALPROCESSING_MODES response: KSMULTIPLE_ITEM.Size
= 24, KSMULTIPLE_ITEM.Count = 1, buffer size = 24

    AUDIO_SIGNALPROCESSINGMODE_RAW is mode 0

    Message:Driver supports processing modes but the preferred formats
donot have the attribute flag set, so setting it [hr = E_INVALIDARG
(0x80070057)]

    pCPinInstance->CreatePin() failed with 0x90000491.

      FAIL: Pin[01] Capture: Pin creation failed for
AUDIO_SIGNALPROCESSINGMODE_RAW

      Pin[02] (Microphone)

      Pin[03] (Speakers)



With the same device with inbox usbaudio driver, the test will pass with
the log below:

Pin[00] ()

      Pin[00] : Basic support: 0x201

    KSPROPERTY_AUDIOSIGNALPROCESSING_MODES response: KSMULTIPLE_ITEM.Size
= 24, KSMULTIPLE_ITEM.Count = 1, buffer size = 24

    AUDIO_SIGNALPROCESSINGMODE_RAW is mode 0

    Message:Driver supports processing modes but the preferred formats
donot have the attribute flag set, so setting it [hr = E_INVALIDARG
(0x80070057)]

    pCPinInstance->CreatePin() succeeded

    Pin creation successful for AUDIO_SIGNALPROCESSINGMODE_RAW

      Pin[01] (Capture)

      Pin[01] Capture: Basic support: 0x201

    KSPROPERTY_AUDIOSIGNALPROCESSING_MODES response: KSMULTIPLE_ITEM.Size
= 24, KSMULTIPLE_ITEM.Count = 1, buffer size = 24

    AUDIO_SIGNALPROCESSINGMODE_RAW is mode 0

    Message:Driver supports processing modes but the preferred formats
donot have the attribute flag set, so setting it [hr = E_INVALIDARG
(0x80070057)]

    pCPinInstance->CreatePin() succeeded

    Pin creation successful for AUDIO_SIGNALPROCESSINGMODE_RAW

      Pin[02] (Microphone)

      Pin[03] (Speakers)



When "pCPinInstance->CreatePin() failed with 0x90000491." error happens,
the test will call IntersectHandler of the pin once with supported format.
And

IntersectHandler() will return STATUS_SUCCESS. But the system seems stop
here with error.



And click the specific audio device in the "Sound" device panel,the
"Level" page will be blank with no Volume control and "Advanced" page is
missing.



Do you know why the system failed to create the specific pin? While with
KSStudio, the device can playback wave file.



Another question is about inbox usbaudio.sys. The usbaudio.sys defines
IntersectHandler (usbaudio!PinDataFormatIntersection).

But when I set breakpoint for this IntersectHandler 
(usbaudio!PinDataFormatIntersection),
the breakbpoint never been triggered before usbaudio!PinSetDataFormat().

It seems different with my AVstream mini-driver for format control.



Thank you for your help,

Hunter



On Tue, May 9, 2017 at 3:48 PM, Matthew van Eerde <
dmarc-noreply@xxxxxxxxxxxxx> wrote:

At this point you should run the HLK tests, which will find the problem
with your response and give you a (hopefully) helpful error message.



*From: *Yudi Cao <yudi.cao@xxxxxxxxx>
*Sent: *Monday, May 8, 2017 9:01 PM
*To: *wdmaudiodev@xxxxxxxxxxxxx
*Subject: *[wdmaudiodev] Re: How to implement 
KSPROPSETID_AudioSignalProcessing
Property Set in AVstream mini-driver



Thank you for your help.



When I return the status as STATUS_BUFFER_OVERFLOW instead of
STATUS_BUFFER_TOO_SMALL when pData is NULL,

the host will call the get handler with specific size to get the property
value.



But system will get an exception in 
MMDevAPI!CAudioSignalProcessingModes::GetModes.
And the device won't be listed

in the Sound device list.



Below are what I have done for the property get.

1. There are 4 pins for my AVstream mini-driver filter.

typedef enum _KSPIN_ID

{

    KSPIN_SINK_RENDER = 0,  //For playback.

KSPIN_SOURCE_CAPTURE,   //For capture

KSPIN_SINK_BRIDGE_MIC,

// Bridge Microphone

KSPIN_SOURCE_BRIDGE_SPEAKER //Bridge Speaker

}KSPIN_ID, *PKSPIN_ID;

2. Get and set the property value size with the IRP/IrpStack fields.

3. Implement the KSPROPERTY_AUDIOSIGNALPROCESSING_MODES as this link:

https://msdn.microsoft.com/en-us/library/windows/hardware/
dn457708(v=vs.85).aspx
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fwindows%2Fhardware%2Fdn457708(v%3Dvs.85).aspx&data=02%7C01%7CMatthew.van.Eerde%40microsoft.com%7C569c36861ca44765312a08d496902188%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636298993176644660&sdata=ptLm0Xy3baRFW4w9XJ4Li1Bsp948LTqTSUBVF8ZNEfo%3D&reserved=0>

3.1 Report the RAW+DEFAULT modes for the the playback and capture pins.

3.2 Report KSMULTIPLE_ITEM structure with its Count parameter set to zero
(0) for the bridge pins.



The codes are below:

#define SINGNAL_PROCESSINGMODE_NUMBER 2

typedef struct _KSMULTIPLE_ITEM_CLSID {

KSMULTIPLE_ITEM KsMultiple_Item;

GUID

clsid[SINGNAL_PROCESSINGMODE_NUMBER];

} KSMULTIPLE_ITEM_CLSID, *PKSMULTIPLE_ITEM_CLSID;



GUID gProcessinModesTable[2] =

{

STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,

STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT

};

NTSTATUS CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessing(IN
PIRP pIrp, IN PKSP_PIN pKSP_Pin, IN OUT PKSMULTIPLE_ITEM pData)

{

PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.
OutputBufferLength;

switch (pKSP_Pin->PinId)

{

case KSPIN_SINK_RENDER:

case KSPIN_SOURCE_CAPTURE:

{

if (ulOutputBufferLength < sizeof(KSMULTIPLE_ITEM_CLSID))

{

pIrp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM_CLSID);

return STATUS_BUFFER_OVERFLOW;

}else

{

KSMULTIPLE_ITEM_CLSID Ks_Item;

Ks_Item.KsMultiple_Item.Count = SINGNAL_PROCESSINGMODE_NUMBER;

Ks_Item.KsMultiple_Item.Size = sizeof(KSMULTIPLE_ITEM_CLSID);

RtlCopyMemory(Ks_Item.clsid, gProcessinModesTable,
SINGNAL_PROCESSINGMODE_NUMBER * sizeof(GUID));



if (pData)

{

*((PKSMULTIPLE_ITEM_CLSID)pData) = Ks_Item;

}

}

}

break;

case KSPIN_SINK_BRIDGE_MIC:

case KSPIN_SOURCE_BRIDGE_SPEAKER:

{

if (ulOutputBufferLength < sizeof(KSMULTIPLE_ITEM))

{

pIrp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM);

return STATUS_BUFFER_OVERFLOW;

}

else

{

if (pData)

{

pData->Count = 0;

pData->Size = sizeof(KSMULTIPLE_ITEM);

}

}

}

break;



The exception contents are below:



*** An Access Violation occurred in c:\windows\system32\svchost.exe -k
localsystemnetworkrestricted -s AudioEndpointBuilder:



The instruction at 00007FFC59521EA2 tried to read from an invalid address,
0000000000000004



EXCEPTION_RECORD:  000000b03ea7ee30 -- (.exr 0xb03ea7ee30)

ExceptionAddress: 00007ffc59521ea2 (MMDevAPI!CAudioSignalProcessingModes::
GetModes+0x0000000000000022)

   ExceptionCode: c0000005 (Access violation)

  ExceptionFlags: 00000000

NumberParameters: 2

   Parameter[0]: 0000000000000000

   Parameter[1]: 0000000000000004

Attempt to read from address 0000000000000004



CONTEXT:  000000b03ea7e940 -- (.cxr 0xb03ea7e940)

rax=0000000000000000 rbx=ffffffffffffffff rcx=00000236dd83deb0

rdx=000000b03ea7f0d8 rsi=0000000000000000 rdi=000000b03ea7f0d8

rip=00007ffc59521ea2 rsp=000000b03ea7f060 rbp=000000b03ea7f1a0

 r8=000000b03ea7f0d0  r9=00000236dd83de90 r10=00000fff8b2a43d0

r11=0000100000010100 r12=00000236dd81de50 r13=00000236dd87ac70

r14=000000b03ea7f0d0 r15=ffffffffffffffff

iopl=0         nv up ei pl nz na po nc

cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b
efl=00010206

MMDevAPI!CAudioSignalProcessingModes::GetModes+0x22:

0033:00007ffc`59521ea2 8b6804          mov     ebp,dword ptr [rax+4]
ds:002b:00000000`00000004=????????

Resetting default scope



FOLLOWUP_IP:

MMDevAPI!CAudioSignalProcessingModes::GetModes+22

0033:00007ffc`59521ea2 8b6804          mov     ebp,dword ptr [rax+4]



READ_ADDRESS:  0000000000000004



BUGCHECK_STR:  STATUS_BREAKPOINT



What's wrong in my implementation?



Thank you for your help,

Hunter





On Mon, May 8, 2017 at 10:55 PM, Matthew van Eerde <
dmarc-noreply@xxxxxxxxxxxxx> wrote:

Windows is not giving you a buffer because it doesn’t know how big of a
buffer to give you.



For documentation on writing kernel streaming property handlers directly,
see https://docs.microsoft.com/en-us/windows-hardware/drivers/
audio/audio-property-handlers
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows-hardware%2Fdrivers%2Faudio%2Faudio-property-handlers&data=02%7C01%7CMatthew.van.Eerde%40microsoft.com%7C569c36861ca44765312a08d496902188%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636298993176644660&sdata=fxBv1F%2B5Gfu84kzw0E1yRTSlbMhLjEO17E0jxqPNWaM%3D&reserved=0>
- in particular



Before submitting a get-property request to retrieve a property value, the
client should allocate an output buffer into which the miniport driver's
property handler can write the property value. For some properties, the
size of the output buffer is device-dependent and the client must query the
property handler for the required buffer size. In these cases, the client
submits an initial property request with a zero-length output buffer. The
handler responds by returning the required buffer size along with the
status code STATUS_BUFFER_OVERFLOW. (The handler writes the required size
into the ValueSize member of the PCPROPERTY_REQUEST structure.) The
client then retrieves the property value by allocating an output buffer of
the specified size and sending this buffer in a second get-property request.



*From: *Yudi Cao <yudi.cao@xxxxxxxxx>
*Sent: *Monday, May 8, 2017 1:40 AM
*To: *wdmaudiodev@xxxxxxxxxxxxx
*Subject: *[wdmaudiodev] How to implement KSPROPSETID_AudioSignalProcessing
Property Set in AVstream mini-driver



Hello,



I'm working on an AVstream audio driver for USB Headset (add some extra
formats comparing to inbox usbaudio.sys).

To integrate APO DLL to my driver package, I need implement the
KSPROPSETID_AudioSignalProcessing property set.



The property set AutomationTable definitions are below:

DEFINE_KSPROPERTY_TABLE(AudioFilterPropertySetTable)

{

        DEFINE_KSPROPERTY_ITEM

        (

                KSPROPERTY_AUDIOSIGNALPROCESSING_MODES,      // property
item defined in ksmedia.h

                CCaptureRenderFilter::FILTERPROP_
PropertyAudioSignalProcessing,

                sizeof(KSP_PIN),             // minimum buffer length for
property

                0,       // minimum buffer length for returned data

                NULL,

                NULL,                           // default values

                0,                              // related properties

                NULL,

                CCaptureRenderFilter::FILTERPROP_
PropertyAudioSignalProcessingBasicSupport,

                0                               // don't serialize

        )

};





DEFINE_KSPROPERTY_SET_TABLE(AudioFilterProperties)

{

        DEFINE_KSPROPERTY_SET

        (

                &KSPROPSETID_AudioSignalProcessing,
// property set defined in ksmedia.h

                SIZEOF_ARRAY(AudioFilterPropertySetTable),    // the
properties supported

                AudioFilterPropertySetTable,

                0,                                      // reserved

                NULL                                    // reserved

        )

};





DEFINE_KSAUTOMATION_TABLE(AudioFilterAutomationTable) {

        DEFINE_KSAUTOMATION_PROPERTIES(AudioFilterProperties),

                DEFINE_KSAUTOMATION_METHODS_NULL,

                DEFINE_KSAUTOMATION_EVENTS_NULL

};



        m_KSFilterDesc.AutomationTable = &AudioFilterAutomationTable;

The function declared as below:

NTSTATUS CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessing(IN
PIRP pIrp, IN PKSP_PIN pKSP_Pin, IN OUT PKSMULTIPLE_ITEM pData)

NTSTATUS 
CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessingBasicSupport(IN
PIRP pIrp, IN PKSP_PIN  Request, IN OUT PVOID  Data)



The problem is:

The system will call FILTERPROP_PropertyAudioSignalProcessing() for
several times with the pData==NULL. Why the pData is always null?



What's wrong with my code? Is there anywhere to get some sample code for
AVStream mini-driver to support KSPROPSETID_AudioSignalProcessing?



Thank you for your help,

Hunter













Other related posts: