mirror of
https://github.com/reactos/reactos.git
synced 2024-08-01 17:11:35 +00:00
- Implement looped streaming (needed for dsound bringup)
- Implement GetPosition handler for looped streaming, WIP svn path=/trunk/; revision=43868
This commit is contained in:
parent
a51c149046
commit
46c8396918
|
@ -322,9 +322,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
||||||
IN PVOID SilenceBuffer) PURE;
|
IN PVOID SilenceBuffer) PURE;
|
||||||
|
|
||||||
STDMETHOD_(NTSTATUS, AddMapping)(THIS_
|
STDMETHOD_(NTSTATUS, AddMapping)(THIS_
|
||||||
IN PUCHAR Buffer,
|
IN PIRP Irp,
|
||||||
IN ULONG BufferSize,
|
OUT PULONG Data) PURE;
|
||||||
IN PIRP Irp) PURE;
|
|
||||||
|
|
||||||
STDMETHOD_(NTSTATUS, GetMapping)(THIS_
|
STDMETHOD_(NTSTATUS, GetMapping)(THIS_
|
||||||
OUT PUCHAR * Buffer,
|
OUT PUCHAR * Buffer,
|
||||||
|
@ -372,9 +371,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
||||||
IN PVOID SilenceBuffer); \
|
IN PVOID SilenceBuffer); \
|
||||||
\
|
\
|
||||||
STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \
|
STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \
|
||||||
IN PUCHAR Buffer, \
|
IN PIRP Irp, \
|
||||||
IN ULONG BufferSize, \
|
OUT PULONG Data); \
|
||||||
IN PIRP Irp); \
|
|
||||||
\
|
\
|
||||||
STDMETHODIMP_(NTSTATUS) GetMapping(THIS_ \
|
STDMETHODIMP_(NTSTATUS) GetMapping(THIS_ \
|
||||||
OUT PUCHAR * Buffer, \
|
OUT PUCHAR * Buffer, \
|
||||||
|
|
|
@ -39,7 +39,7 @@ protected:
|
||||||
LONG m_NumMappings;
|
LONG m_NumMappings;
|
||||||
ULONG m_NumDataAvailable;
|
ULONG m_NumDataAvailable;
|
||||||
BOOL m_StartStream;
|
BOOL m_StartStream;
|
||||||
KSPIN_CONNECT * m_ConnectDetails;
|
PKSPIN_CONNECT m_ConnectDetails;
|
||||||
PKSDATAFORMAT_WAVEFORMATEX m_DataFormat;
|
PKSDATAFORMAT_WAVEFORMATEX m_DataFormat;
|
||||||
|
|
||||||
KSPIN_LOCK m_IrpListLock;
|
KSPIN_LOCK m_IrpListLock;
|
||||||
|
@ -110,9 +110,8 @@ CIrpQueue::Init(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CIrpQueue::AddMapping(
|
CIrpQueue::AddMapping(
|
||||||
IN PUCHAR Buffer,
|
IN PIRP Irp,
|
||||||
IN ULONG BufferSize,
|
OUT PULONG Data)
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
{
|
||||||
PKSSTREAM_HEADER Header;
|
PKSSTREAM_HEADER Header;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
@ -125,8 +124,6 @@ CIrpQueue::AddMapping(
|
||||||
// get current irp stack location
|
// get current irp stack location
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
PC_ASSERT(!Buffer);
|
|
||||||
|
|
||||||
if (!Irp->MdlAddress)
|
if (!Irp->MdlAddress)
|
||||||
{
|
{
|
||||||
// ioctl from KsStudio
|
// ioctl from KsStudio
|
||||||
|
@ -172,8 +169,8 @@ CIrpQueue::AddMapping(
|
||||||
|
|
||||||
NumData = 0;
|
NumData = 0;
|
||||||
// prepare all headers
|
// prepare all headers
|
||||||
for(Index = 0; Index < NumHeaders; Index++)
|
for(Index = 0; Index < NumHeaders; Index++)
|
||||||
{
|
{
|
||||||
// sanity checks
|
// sanity checks
|
||||||
PC_ASSERT(Header);
|
PC_ASSERT(Header);
|
||||||
PC_ASSERT(Mdl);
|
PC_ASSERT(Mdl);
|
||||||
|
@ -181,17 +178,17 @@ CIrpQueue::AddMapping(
|
||||||
Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
|
Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
|
||||||
|
|
||||||
if (!Header->Data)
|
if (!Header->Data)
|
||||||
{
|
{
|
||||||
// insufficient resources
|
// insufficient resources
|
||||||
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
|
||||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||||
// complete and forget request
|
// complete and forget request
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment num mappings
|
// increment num mappings
|
||||||
InterlockedIncrement(&m_NumMappings);
|
InterlockedIncrement(&m_NumMappings);
|
||||||
|
@ -207,10 +204,10 @@ CIrpQueue::AddMapping(
|
||||||
|
|
||||||
// move to next mdl
|
// move to next mdl
|
||||||
Mdl = Mdl->Next;
|
Mdl = Mdl->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("StreamHeaders %u NumData %u FrameSize %u NumDataAvailable %u\n", NumHeaders, NumData, m_MaxFrameSize, m_NumDataAvailable);
|
DPRINT("StreamHeaders %u NumData %u FrameSize %u NumDataAvailable %u\n", NumHeaders, NumData, m_MaxFrameSize, m_NumDataAvailable);
|
||||||
|
*Data = NumData;
|
||||||
|
|
||||||
// mark irp as pending
|
// mark irp as pending
|
||||||
IoMarkIrpPending(Irp);
|
IoMarkIrpPending(Irp);
|
||||||
|
@ -330,7 +327,7 @@ CIrpQueue::UpdateMapping(
|
||||||
if (m_CurrentOffset >= Size)
|
if (m_CurrentOffset >= Size)
|
||||||
{
|
{
|
||||||
if (STREAMHEADER_INDEX(m_Irp) + 1 < STREAMHEADER_COUNT(m_Irp))
|
if (STREAMHEADER_INDEX(m_Irp) + 1 < STREAMHEADER_COUNT(m_Irp))
|
||||||
{
|
{
|
||||||
// the irp has at least one more stream header
|
// the irp has at least one more stream header
|
||||||
m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(STREAMHEADER_INDEX(m_Irp) + 1);
|
m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(STREAMHEADER_INDEX(m_Irp) + 1);
|
||||||
|
|
||||||
|
@ -345,7 +342,7 @@ CIrpQueue::UpdateMapping(
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// irp has been processed completly
|
// irp has been processed completly
|
||||||
|
|
||||||
|
@ -354,7 +351,7 @@ CIrpQueue::UpdateMapping(
|
||||||
|
|
||||||
// loop all stream headers
|
// loop all stream headers
|
||||||
for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
|
for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
|
||||||
{
|
{
|
||||||
PC_ASSERT(StreamHeader);
|
PC_ASSERT(StreamHeader);
|
||||||
|
|
||||||
// add size of buffer
|
// add size of buffer
|
||||||
|
@ -369,20 +366,30 @@ CIrpQueue::UpdateMapping(
|
||||||
|
|
||||||
// get next stream header
|
// get next stream header
|
||||||
StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
|
StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
||||||
|
{
|
||||||
|
// looped streaming repeat the buffers untill
|
||||||
|
// the caller decides to stop the streams
|
||||||
|
|
||||||
|
// reset stream header index
|
||||||
|
m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0);
|
||||||
|
// re-insert irp
|
||||||
|
KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL);
|
||||||
|
// clear current irp
|
||||||
|
m_Irp = NULL;
|
||||||
|
// reset offset
|
||||||
|
m_CurrentOffset = 0;
|
||||||
|
// increment available data
|
||||||
|
InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, NumData);
|
||||||
|
// done
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_Irp->IoStatus.Status = STATUS_SUCCESS;
|
m_Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
m_Irp->IoStatus.Information = NumData;
|
m_Irp->IoStatus.Information = NumData;
|
||||||
|
|
||||||
#if 0
|
|
||||||
PC_ASSERT_IRQL(DISPATCH_LEVEL);
|
|
||||||
MmUnlockPages(m_Irp->MdlAddress);
|
|
||||||
IoFreeMdl(m_Irp->MdlAddress);
|
|
||||||
m_Irp->MdlAddress = NULL;
|
|
||||||
ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
|
|
||||||
m_Irp->AssociatedIrp.SystemBuffer = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// complete the request
|
// complete the request
|
||||||
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
|
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
|
||||||
// remove irp as it is complete
|
// remove irp as it is complete
|
||||||
|
|
|
@ -59,7 +59,7 @@ protected:
|
||||||
PMINIPORTWAVECYCLICSTREAM m_Stream;
|
PMINIPORTWAVECYCLICSTREAM m_Stream;
|
||||||
KSSTATE m_State;
|
KSSTATE m_State;
|
||||||
PKSDATAFORMAT m_Format;
|
PKSDATAFORMAT m_Format;
|
||||||
KSPIN_CONNECT * m_ConnectDetails;
|
PKSPIN_CONNECT m_ConnectDetails;
|
||||||
|
|
||||||
PVOID m_CommonBuffer;
|
PVOID m_CommonBuffer;
|
||||||
ULONG m_CommonBufferSize;
|
ULONG m_CommonBufferSize;
|
||||||
|
@ -187,6 +187,7 @@ PinWaveCyclicAudioPosition(
|
||||||
{
|
{
|
||||||
CPortPinWaveCyclic *Pin;
|
CPortPinWaveCyclic *Pin;
|
||||||
PSUBDEVICE_DESCRIPTOR Descriptor;
|
PSUBDEVICE_DESCRIPTOR Descriptor;
|
||||||
|
PKSAUDIO_POSITION Position;
|
||||||
|
|
||||||
// get sub device descriptor
|
// get sub device descriptor
|
||||||
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
|
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
|
||||||
|
@ -206,9 +207,21 @@ PinWaveCyclicAudioPosition(
|
||||||
{
|
{
|
||||||
// FIXME non multithreading-safe
|
// FIXME non multithreading-safe
|
||||||
// copy audio position
|
// copy audio position
|
||||||
RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION));
|
|
||||||
|
|
||||||
DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset);
|
Position = (PKSAUDIO_POSITION)Data;
|
||||||
|
|
||||||
|
if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_STREAMING)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION));
|
||||||
|
DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset);
|
||||||
|
}
|
||||||
|
else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
||||||
|
{
|
||||||
|
Position->PlayOffset = Pin->m_Position.PlayOffset % Pin->m_Position.WriteOffset;
|
||||||
|
Position->WriteOffset = Pin->m_IrpQueue->NumData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION);
|
Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -584,25 +597,21 @@ CPortPinWaveCyclic::HandleKsStream(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG Data = 0;
|
||||||
InterlockedIncrement((PLONG)&m_TotalPackets);
|
InterlockedIncrement((PLONG)&m_TotalPackets);
|
||||||
|
|
||||||
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
|
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
|
||||||
|
|
||||||
Status = m_IrpQueue->AddMapping(NULL, 0, Irp);
|
Status = m_IrpQueue->AddMapping(Irp, &Data);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
||||||
PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
PC_ASSERT(Header);
|
|
||||||
|
|
||||||
if (m_Capture)
|
if (m_Capture)
|
||||||
m_Position.WriteOffset += Header->FrameExtent;
|
m_Position.WriteOffset += Data;
|
||||||
else
|
else
|
||||||
m_Position.WriteOffset += Header->DataUsed;
|
m_Position.WriteOffset += Data;
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -665,22 +665,19 @@ CPortPinWavePci::HandleKsStream(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG Data = 0;
|
||||||
InterlockedIncrement((PLONG)&m_TotalPackets);
|
InterlockedIncrement((PLONG)&m_TotalPackets);
|
||||||
|
|
||||||
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
|
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
|
||||||
|
|
||||||
Status = m_IrpQueue->AddMapping(NULL, 0, Irp);
|
Status = m_IrpQueue->AddMapping(Irp, &Data);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
||||||
PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
PC_ASSERT(Header);
|
|
||||||
|
|
||||||
if (m_Capture)
|
if (m_Capture)
|
||||||
m_Position.WriteOffset += Header->FrameExtent;
|
m_Position.WriteOffset += Data;
|
||||||
else
|
else
|
||||||
m_Position.WriteOffset += Header->DataUsed;
|
m_Position.WriteOffset += Data;
|
||||||
|
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,22 @@
|
||||||
|
|
||||||
#include "private.hpp"
|
#include "private.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
KSPIN_INTERFACE PinInterfaces[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{STATIC_KSINTERFACESETID_Standard},
|
||||||
|
KSINTERFACE_STANDARD_STREAMING,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{STATIC_KSINTERFACESETID_Standard},
|
||||||
|
KSINTERFACE_STANDARD_LOOPED_STREAMING,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
KsoDispatchCreateWithGenericFactory(
|
KsoDispatchCreateWithGenericFactory(
|
||||||
|
@ -450,6 +466,9 @@ PcCreateSubdeviceDescriptor(
|
||||||
{
|
{
|
||||||
RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
|
RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
|
||||||
|
|
||||||
|
Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces;
|
||||||
|
Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE);
|
||||||
|
|
||||||
DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount);
|
DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount);
|
||||||
|
|
||||||
Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
|
Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
|
||||||
|
|
Loading…
Reference in a new issue