[SPLITTER]

- Implement Splitter (WIP)

svn path=/trunk/; revision=42650
This commit is contained in:
Johannes Anderwald 2009-08-13 10:05:42 +00:00
parent d8fa27fec7
commit 2bddd27873
4 changed files with 228 additions and 13 deletions

View file

@ -14,7 +14,48 @@ FilterProcess(
IN PKSFILTER Filter,
IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
ULONG Index;
PKSPROCESSPIN CurPin, Pin;
BOOLEAN PendingFrames = FALSE;
if (ProcessPinsIndex->Count)
{
/* check if there are outstanding frames */
for(Index = 1; Index < ProcessPinsIndex->Count; Index++)
{
/* get current pin */
CurPin = ProcessPinsIndex->Pins[Index];
if (CurPin->BytesAvailable && CurPin->Pin->DeviceState == KSSTATE_RUN)
{
/* pin has pending frames
* to keep all pins synchronized, every pin has to wait untill each chained pin has send its frames downwards
*/
PendingFrames = TRUE;
}
}
}
if (!PendingFrames && ProcessPinsIndex->Count)
{
/* get first pin */
Pin = ProcessPinsIndex->Pins[0];
/* check if there is new data available */
if (Pin->BytesAvailable)
{
for(Index = 1; Index < ProcessPinsIndex->Count; Index++)
{
/* get current pin */
CurPin = ProcessPinsIndex->Pins[Index];
/* copy the frame to pin */
RtlMoveMemory(CurPin->Data, Pin->Data, Pin->BytesAvailable);
CurPin->BytesUsed = Pin->BytesAvailable;
}
}
}
/* done */
return STATUS_SUCCESS;
}

View file

@ -14,8 +14,45 @@ PinCreate(
IN PKSPIN Pin,
IN PIRP Irp)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
PKSFILTER Filter;
PKSPIN FirstPin;
PPIN_CONTEXT PinContext;
/* first get the parent filter */
Filter = KsPinGetParentFilter(Pin);
/* now get first child pin */
FirstPin = KsFilterGetFirstChildPin(Filter, Pin->Id);
/* sanity check */
ASSERT(FirstPin);
if (FirstPin != Pin)
{
/* a previous pin already exists */
if (RtlCompareMemory(FirstPin->ConnectionFormat, Pin->ConnectionFormat, Pin->ConnectionFormat->FormatSize) != Pin->ConnectionFormat->FormatSize)
{
/* each instantiated pin must have the same connection format */
return STATUS_INVALID_PARAMETER;
}
}
/* allocate pin context */
PinContext = ExAllocatePool(NonPagedPool, sizeof(PIN_CONTEXT));
if (!PinContext)
return STATUS_INSUFFICIENT_RESOURCES;
/* store pin context */
Pin->Context = PinContext;
/* clear pin context */
RtlZeroMemory(PinContext, sizeof(PIN_CONTEXT));
/* FIXME
* check allocator framing and apply to all pins
*/
return STATUS_SUCCESS;
}
NTSTATUS
@ -24,8 +61,14 @@ PinClose(
IN PKSPIN Pin,
IN PIRP Irp)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
/* is there a context */
if (Pin->Context)
{
/* free pin context */
ExFreePool(Pin->Context);
}
return STATUS_SUCCESS;
}
VOID
@ -33,7 +76,22 @@ NTAPI
PinReset(
IN PKSPIN Pin)
{
UNIMPLEMENTED
PKSFILTER Filter;
/* sanity check */
ASSERT(Pin->Context);
/* clear pin context */
RtlZeroMemory(Pin->Context, sizeof(PIN_CONTEXT));
/* get parent filter */
Filter = KsPinGetParentFilter(Pin);
/* sanity check */
ASSERT(Filter);
/* attempt processing */
KsFilterAttemptProcessing(Filter, TRUE);
}
NTSTATUS
@ -43,8 +101,25 @@ PinState(
IN KSSTATE ToState,
IN KSSTATE FromState)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
PKSFILTER Filter;
/* should the pin stop */
if (ToState == KSSTATE_STOP)
{
/* clear pin context */
RtlZeroMemory(Pin->Context, sizeof(PIN_CONTEXT));
}
/* get parent filter */
Filter = KsPinGetParentFilter(Pin);
/* sanity check */
ASSERT(Filter);
/* attempt processing */
KsFilterAttemptProcessing(Filter, TRUE);
return STATUS_SUCCESS;
}
NTSTATUS
@ -54,8 +129,49 @@ AudioPositionPropertyHandler(
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
PKSFILTER Filter;
PKSPIN Pin, FirstPin;
PFILE_OBJECT FileObject;
NTSTATUS Status;
ULONG BytesReturned;
/* first get the pin */
Pin = KsGetPinFromIrp(Irp);
/* sanity check */
ASSERT(Pin);
/* get parent filter */
Filter = KsPinGetParentFilter(Pin);
/* acquire filter control mutex */
KsFilterAcquireControl(Filter);
/* get first pin */
FirstPin = KsFilterGetFirstChildPin(Filter, Pin->Id);
/* get connected pin of first pin */
FileObject = KsPinGetConnectedPinFileObject(FirstPin);
if (!FileObject)
{
/* no pin connected */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* perform request */
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)Request, sizeof(KSPROPERTY), Data, sizeof(KSAUDIO_POSITION), &BytesReturned);
/* store result size */
Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION);
}
/* release control */
KsFilterReleaseControl(Filter);
/* done */
return Status;
}
NTSTATUS
@ -70,7 +186,54 @@ PinIntersectHandler(
OUT PVOID Data OPTIONAL,
OUT PULONG DataSize)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
PKSPIN FirstPin;
NTSTATUS Status;
/* get first pin */
FirstPin = KsFilterGetFirstChildPin((PKSFILTER)Context, Pin->PinId);
/* sanity check */
ASSERT(FirstPin);
/* check for matching dataformat */
if (!IsEqualGUIDAligned(&FirstPin->ConnectionFormat->SubFormat, &DataRange->SubFormat) ||
!IsEqualGUIDAligned(&FirstPin->ConnectionFormat->Specifier, &DataRange->Specifier) ||
!IsEqualGUIDAligned(&GUID_NULL, &DataRange->SubFormat) ||
!IsEqualGUIDAligned(&GUID_NULL, &DataRange->Specifier))
{
/* no match */
return STATUS_NO_MATCH;
}
if (DataBufferSize)
{
/* there is output buffer */
if (DataBufferSize >= FirstPin->ConnectionFormat->FormatSize)
{
/* copy dataformat */
RtlMoveMemory(Data, FirstPin->ConnectionFormat, FirstPin->ConnectionFormat->FormatSize);
/* store output length */
*DataSize = FirstPin->ConnectionFormat->FormatSize;
Status = STATUS_SUCCESS;
}
else
{
/* buffer too small */
Status = STATUS_BUFFER_TOO_SMALL;
}
}
else
{
/* store output length */
*DataSize = FirstPin->ConnectionFormat->FormatSize;
Status = STATUS_BUFFER_OVERFLOW;
}
/* done */
return Status;
}

View file

@ -58,4 +58,13 @@ PinIntersectHandler(
OUT PVOID Data OPTIONAL,
OUT PULONG DataSize);
typedef struct
{
ULONG BytesAvailable;
ULONG BytesProcessed;
}PIN_CONTEXT, *PPIN_CONTEXT;
#endif

View file

@ -12,6 +12,8 @@ const GUID PIN_VIDEO_CAPTURE = {0xfb6c4281, 0x0353, 0x11d1, {0x90, 0x5f, 0x0, 0x
const GUID KSPROPSETID_Audio = {0x45FFAAA0, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
const GUID KSCATEGORY_AUDIO_SPLITTER = {0x9EA331FA, 0xB91B, 0x45F8, {0x92, 0x85, 0xBD, 0x2B, 0xC7, 0x7A, 0xFC, 0xDE}};
const GUID KSNAME_Filter = {0x9b365890, 0x165f, 0x11d0, {0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
const GUID GUID_NULL = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
KSPROPERTY_ITEM
PinPropertyTable[] =