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

  • From: Yudi Cao <yudi.cao@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Tue, 9 May 2017 12:00:59 +0800

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
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 - 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: