mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 14:37:45 +00:00
[SPLITTER]
- Implement Splitter (WIP) svn path=/trunk/; revision=42650
This commit is contained in:
parent
d8fa27fec7
commit
2bddd27873
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,4 +58,13 @@ PinIntersectHandler(
|
|||
OUT PVOID Data OPTIONAL,
|
||||
OUT PULONG DataSize);
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG BytesAvailable;
|
||||
ULONG BytesProcessed;
|
||||
}PIN_CONTEXT, *PPIN_CONTEXT;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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[] =
|
||||
|
|
Loading…
Reference in a new issue