Apply .gitattributes normalization to convert all CRLF line endings inherited from Windows-origin source files to Unix LF. 175 files, zero content changes.
693 lines
25 KiB
C++
693 lines
25 KiB
C++
/*****************************************************************************
|
|
Company : Shree Ganesha Inc.
|
|
File Name : SkyWalker1CapturePin.cpp
|
|
Author :
|
|
Date :
|
|
Purpose : This file contains header for the video capture pin on
|
|
the capture filter.
|
|
|
|
Revision History:
|
|
===============================================================================
|
|
DATE VERSION AUTHOR REMARK
|
|
===============================================================================
|
|
|
|
XXth April,2009 01 Initial Version
|
|
|
|
*****************************************************************************/
|
|
/* Include the Library and Other header file */
|
|
|
|
#include "SkyWalker1Main.h" //Common For all the Definitions,
|
|
//Declarations and Library Routines
|
|
|
|
/* End of Inclusion the Library and Other header file */
|
|
|
|
/* Macro Definitions */
|
|
/* End of Macro Definitions */
|
|
|
|
/* Global & Static variables Declaration */
|
|
/* End of Global & Static variables Declaration */
|
|
|
|
/* External Variable Declaration */
|
|
/* End of External Variable Declaration */
|
|
|
|
/* Declare Enumerations here */
|
|
/* End of Enumeration declaration */
|
|
|
|
/* Function Prototypes */
|
|
VOID PrintStream(IN PKSSTREAM_POINTER pStreamPointer);
|
|
/* End of Function prototype definitions */
|
|
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin
|
|
Description : Constructor of the CCapturePin Class
|
|
IN PARAM : NONE
|
|
OUT PARAM : NONE
|
|
PreCondition : pKSPin Object is not created
|
|
PostCondtion : pKSPin Object is created and Initialzed on successful execution
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
CCapturePin::CCapturePin(IN PKSPIN pKSPin) :
|
|
m_Pin (pKSPin)
|
|
{
|
|
PKSDEVICE pKSDevice = KsPinGetDevice (pKSPin);
|
|
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
//Set up our device pointer. This gives us access to "Hardware I/O"
|
|
//during the capture routines.
|
|
m_Device = reinterpret_cast <CSkyWalker1Device *> (pKSDevice->Context);
|
|
|
|
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin
|
|
Description : Destructor of the CCapturePin Class
|
|
IN PARAM : NONE
|
|
OUT PARAM : NONE
|
|
PreCondition : pKSPin Object is created
|
|
PostCondtion : pKSPin Object is Removed and Memory freed
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
CCapturePin::~CCapturePin()
|
|
{
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::PinCreate
|
|
Description : An AVStream minidriver's AVStrMiniPinCreate routine is
|
|
called when a pin is created. Typically, this routine is
|
|
used by minidrivers that want to initialize the context
|
|
and resources associated with the pin.
|
|
IN PARAM : <PKSPIN> Pointer to the KSPIN that was just created.
|
|
<PIRP> Pointer to the IRP_MJ_CREATE for pKSPin
|
|
OUT PARAM : <NTSTATUS> STATUS_SUCCESS in case of successful pin creation
|
|
Failure Code in other cases
|
|
PreCondition : None
|
|
PostCondtion : Create a new capture pin. This is the creation dispatch for
|
|
the video capture pin.
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
NTSTATUS CCapturePin::PinCreate ( IN PKSPIN pKSPin,
|
|
IN PIRP pIoRequestPacket
|
|
)
|
|
{
|
|
|
|
NTSTATUS ntCreateStatus = STATUS_SUCCESS;
|
|
PBDA_TRANSPORT_INFO pTransportInfo = NULL;
|
|
CCapturePin *pCapturePin = new (NonPagedPool, CAPTURE_MEM_TAG) CCapturePin (pKSPin);
|
|
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
if (!IS_VALID(pCapturePin))
|
|
{
|
|
//Return failure if we couldn't create the pin.
|
|
ntCreateStatus = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
else
|
|
{
|
|
//Add the item to the object bag if we we were successful.
|
|
//Whenever the pin closes, the bag is cleaned up and we will be
|
|
//freed.
|
|
|
|
ntCreateStatus = KsAddItemToObjectBag (
|
|
pKSPin->Bag,
|
|
reinterpret_cast <PVOID> (pCapturePin),
|
|
reinterpret_cast <PFNKSFREE> (CCapturePin::Cleanup)
|
|
);
|
|
|
|
if (!NT_SUCCESS (ntCreateStatus))
|
|
{
|
|
delete pCapturePin;
|
|
}
|
|
else
|
|
{
|
|
pKSPin->Context = reinterpret_cast <PVOID> (pCapturePin);
|
|
}
|
|
|
|
}
|
|
|
|
//If we succeeded so far, stash the video info header away and change
|
|
//our allocator framing to reflect the fact that only now do we know
|
|
//the framing requirements based on the connection format.
|
|
if (NT_SUCCESS (ntCreateStatus))
|
|
{
|
|
|
|
pTransportInfo = pCapturePin->CaptureBdaTransportInfo();
|
|
if (!pTransportInfo)
|
|
{
|
|
ntCreateStatus = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS (ntCreateStatus))
|
|
{
|
|
//We need to edit the descriptor to ensure we don't mess up any other
|
|
//pins using the descriptor or touch read-only memory.
|
|
|
|
ntCreateStatus = KsEdit (pKSPin, &pKSPin->Descriptor, CAPTURE_MEM_TAG);
|
|
|
|
if (NT_SUCCESS (ntCreateStatus))
|
|
{
|
|
ntCreateStatus = KsEdit (
|
|
pKSPin,
|
|
&(pKSPin->Descriptor->AllocatorFraming),
|
|
CAPTURE_MEM_TAG
|
|
);
|
|
}
|
|
|
|
//If the edits proceeded without running out of memory, adjust
|
|
//the framing based on the video info header.
|
|
if (NT_SUCCESS (ntCreateStatus))
|
|
{
|
|
|
|
//We've KsEdit'ed this... I'm safe to cast away constness as
|
|
//long as the edit succeeded.
|
|
PKSALLOCATOR_FRAMING_EX pFraming =
|
|
const_cast <PKSALLOCATOR_FRAMING_EX> (
|
|
pKSPin->Descriptor-> AllocatorFraming
|
|
);
|
|
|
|
pFraming->FramingItem[0].Frames = NUMBER_OF_FRAMES;
|
|
|
|
//The physical and optimal ranges must be biSizeImage. We only
|
|
//support one frame size, precisely the size of each capture
|
|
//image.
|
|
pFraming->FramingItem[0].PhysicalRange.MinFrameSize =
|
|
pFraming->FramingItem[0].PhysicalRange.MaxFrameSize =
|
|
pFraming->FramingItem[0].FramingRange.Range.MinFrameSize =
|
|
pFraming->FramingItem[0].FramingRange.Range.MaxFrameSize =
|
|
pTransportInfo->ulcbPhyiscalFrame;
|
|
|
|
pFraming->FramingItem[0].PhysicalRange.Stepping =
|
|
pFraming->FramingItem[0].FramingRange.Range.Stepping =
|
|
0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PrintFunctionExit(__FUNCTION__,ntCreateStatus);
|
|
return ntCreateStatus;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::CaptureBdaTransportInfo
|
|
Description : Capture the video info header out of the connection format.
|
|
This is what we use to base synthesized images off.
|
|
IN PARAM : NONE
|
|
OUT PARAM : <PBDA_TRANSPORT_INFO> The captured video info header or
|
|
NULL if there is insufficient memory.
|
|
PreCondition : None
|
|
PostCondtion : Create a new capture pin. This is the creation dispatch for
|
|
the video capture pin.
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
PBDA_TRANSPORT_INFO CCapturePin::CaptureBdaTransportInfo()
|
|
{
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
m_TransportInfo = reinterpret_cast <PBDA_TRANSPORT_INFO> (
|
|
ExAllocatePoolWithTag (
|
|
NonPagedPool,
|
|
sizeof(BDA_TRANSPORT_INFO),
|
|
CAPTURE_MEM_TAG
|
|
)
|
|
);
|
|
|
|
if (!IS_VALID(m_TransportInfo))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//Bag the newly allocated header space. This will get cleaned up
|
|
//automatically when the pin closes.
|
|
NTSTATUS Status =
|
|
KsAddItemToObjectBag (
|
|
m_Pin->Bag,
|
|
reinterpret_cast <PVOID> (m_TransportInfo),
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS (Status))
|
|
{
|
|
ExFreePoolWithTag (m_TransportInfo, CAPTURE_MEM_TAG);
|
|
return NULL;
|
|
|
|
}
|
|
else
|
|
{
|
|
m_TransportInfo->ulcbPhyiscalPacket = TRANSPORT_PACKET_SIZE;
|
|
m_TransportInfo->ulcbPhyiscalFrame = TRANSPORT_PACKET_SIZE * TRANSPORT_PACKET_COUNT;
|
|
m_TransportInfo->ulcbPhyiscalFrameAlignment = 1;
|
|
m_TransportInfo->AvgTimePerFrame = ((ULONGLONG)(19200)/* Maximum Sample Frequency */ *
|
|
10000 /* Maximum Bits Per second */ *
|
|
NUMBER_OF_FRAMES) /*Maximum Channels */ /
|
|
(TRANSPORT_PACKET_SIZE * TRANSPORT_PACKET_COUNT);
|
|
|
|
}
|
|
|
|
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
|
|
return m_TransportInfo;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::CleanupReferences
|
|
Description : Clean up any references we're holding on frames after
|
|
we abruptly stop the hardware.
|
|
IN PARAM : NONE
|
|
OUT PARAM : <NTSTATUS> Success / Failure
|
|
PreCondition : NONE
|
|
PostCondtion : NONE
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
NTSTATUS CCapturePin::CleanupReferences ()
|
|
{
|
|
PKSSTREAM_POINTER pCloneStream = KsPinGetFirstCloneStreamPointer(m_Pin);
|
|
PKSSTREAM_POINTER pNextCloneStream = NULL;
|
|
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
//Walk through the clones, deleting them, and setting DataUsed to
|
|
//zero since we didn't use any data!
|
|
while (pCloneStream)
|
|
{
|
|
|
|
pNextCloneStream = KsStreamPointerGetNextClone(pCloneStream);
|
|
|
|
pCloneStream->StreamHeader->DataUsed = 0;
|
|
KsStreamPointerDelete (pCloneStream);
|
|
|
|
pCloneStream = pNextCloneStream;
|
|
|
|
}
|
|
|
|
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::SetState
|
|
Description : This is called when the caputre pin transitions state.
|
|
The routine attempts to acquire / release any hardware
|
|
resources and start up or shut down capture based on
|
|
the states we are transitioning to and away from.
|
|
IN PARAM : <KSSTATE> ToState : The state we're transitioning to
|
|
<KSSTATE> FromState : The state we're transitioning away from
|
|
OUT PARAM : <NTSTATUS> Success / Failure
|
|
PreCondition : NONE
|
|
PostCondtion : NONE
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
NTSTATUS CCapturePin::SetState (
|
|
IN KSSTATE ToState,
|
|
IN KSSTATE FromState
|
|
)
|
|
{
|
|
|
|
NTSTATUS ntSetStatus = STATUS_SUCCESS;
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
PrintDeviceChangeState(ToState,FromState);
|
|
|
|
switch (ToState)
|
|
{
|
|
|
|
case KSSTATE_STOP:
|
|
//Stopping the Device Operation
|
|
if (m_HardwareState != HardwareStopped)
|
|
{
|
|
ntSetStatus = m_Device->StopStream();
|
|
m_HardwareState = HardwareStopped;
|
|
}
|
|
|
|
|
|
//The Device is Stopped
|
|
//It has cancelled the IRPs and Stopped the Streaming
|
|
//In case any Streaming Pointer is left Clean it up
|
|
ntSetStatus = CleanupReferences();
|
|
|
|
//Release any hardware resources related to this pin.
|
|
if (m_AcquiredResources)
|
|
{
|
|
//Release the Clock Reference on the Pin
|
|
if (m_Clock)
|
|
{
|
|
m_Clock->Release();
|
|
m_Clock = NULL;
|
|
}
|
|
|
|
m_Device->RemoveCaptureSink();
|
|
m_AcquiredResources = FALSE;
|
|
}
|
|
break;
|
|
|
|
case KSSTATE_ACQUIRE:
|
|
|
|
//Acquire Hardware resources here instead of Filter
|
|
//Creation Time.So that the Filter creation does not
|
|
//Fail because of Limited Hardware resources.
|
|
if (FromState == KSSTATE_STOP)
|
|
{
|
|
ntSetStatus = m_Device->SetupCaptureSink(this,m_TransportInfo);
|
|
|
|
if (NT_SUCCESS (ntSetStatus))
|
|
{
|
|
m_AcquiredResources = TRUE;
|
|
|
|
//Attempt to get an interface to the master clock.
|
|
//This will fail if one has not been assigned. Since
|
|
//one must be assigned while the pin is still in
|
|
//KSSTATE_STOP, this is a guranteed method of getting
|
|
//the clock should one be assigned.
|
|
|
|
if (!NT_SUCCESS (KsPinGetReferenceClockInterface(m_Pin,
|
|
&m_Clock)))
|
|
{
|
|
//If we could not get an interface to the clock,
|
|
//don't use one.
|
|
SkyWalkerDebugPrint(ENTRY_LEVEL,("No Clock Assigned to the Pin\n"));
|
|
m_Clock = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
m_AcquiredResources = FALSE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
//Standard transport pins will always receive transitions in
|
|
//+/- 1 manner. This means we'll always see a PAUSE->ACQUIRE
|
|
//transition before stopping the pin.
|
|
//
|
|
//The below is done because on DirectX 8.0, when the pin gets
|
|
//a message to stop, the queue is inaccessible. The reset
|
|
//which comes on every stop happens after this (at which time
|
|
//the queue is inaccessible also). So, for compatibility with
|
|
//DirectX 8.0, I am stopping the hardware at this
|
|
//point and cleaning up all references we have on frames.See
|
|
//the comments above regarding the CleanupReferences call.
|
|
|
|
if (m_HardwareState != HardwareStopped)
|
|
{
|
|
ntSetStatus = m_Device->StopStream();
|
|
m_HardwareState = HardwareStopped;
|
|
}
|
|
|
|
ntSetStatus = CleanupReferences ();
|
|
}
|
|
|
|
break;
|
|
|
|
case KSSTATE_PAUSE:
|
|
|
|
//Stop the Streaming if we're coming down from run.
|
|
if (FromState == KSSTATE_RUN)
|
|
{
|
|
|
|
ntSetStatus = m_Device->PauseStream(TRUE);
|
|
|
|
if (NT_SUCCESS (ntSetStatus))
|
|
{
|
|
m_HardwareState = HardwarePaused;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case KSSTATE_RUN:
|
|
|
|
//Start the Streaming or unpause it depending on
|
|
//whether we're initially running or we've paused and restarted.
|
|
if (m_HardwareState == HardwarePaused)
|
|
{
|
|
ntSetStatus = m_Device->PauseStream (FALSE);
|
|
}
|
|
else
|
|
{
|
|
ntSetStatus = m_Device->StartStream();
|
|
}
|
|
|
|
if (NT_SUCCESS (ntSetStatus))
|
|
{
|
|
m_HardwareState = HardwareRunning;
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("Completed the State Change\n"));
|
|
PrintFunctionExit(__FUNCTION__,ntSetStatus);
|
|
return ntSetStatus;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::Process
|
|
Description : The process dispatch for the pin bridges to this location.
|
|
We handle setting up scatter gather mappings, etc...
|
|
IN PARAM : NONE
|
|
OUT PARAM : <NTSTATUS> Success / Failure
|
|
PreCondition : NONE
|
|
PostCondtion : NONE
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : Future Approach for the Streaming Buffer
|
|
1) Create a Buffer of Size Stream->Data/m_SampleSize Here
|
|
2) Store the reference of the Newly Created Buffer into the
|
|
Stream Context
|
|
3) Send the Buffer to the ReadStream(BufferPointer)
|
|
4) When CompleteMapping is returned Copy Data from Stream
|
|
Context to Stream->Data
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
NTSTATUS CCapturePin::Process()
|
|
{
|
|
NTSTATUS ntProcessStatus = STATUS_SUCCESS;
|
|
PKSSTREAM_POINTER pLeadingStream = NULL;
|
|
PKSSTREAM_POINTER pCloneStream = NULL;
|
|
PSTREAM_POINTER_CONTEXT pStreamContext = NULL;
|
|
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
pLeadingStream = KsPinGetLeadingEdgeStreamPointer (
|
|
m_Pin,
|
|
KSSTREAM_POINTER_STATE_LOCKED
|
|
);
|
|
|
|
|
|
if( !pLeadingStream )
|
|
{
|
|
//no system buffer available
|
|
//This case can happen if it is the last pointer in the queue or
|
|
//the system cannot give us the required buffer
|
|
SkyWalkerDebugPrint(ENTRY_LEVEL,("Warning: No system buffer available\n"));
|
|
ntProcessStatus = STATUS_UNSUCCESSFUL;
|
|
goto CompleteProcessing;
|
|
}
|
|
else
|
|
{
|
|
|
|
//First thing we need to do is clone the leading edge. This allows
|
|
//us to keep reference on the frames while they're in DMA.
|
|
ntProcessStatus = KsStreamPointerClone (
|
|
pLeadingStream,
|
|
NULL,
|
|
sizeof (STREAM_POINTER_CONTEXT),
|
|
&pCloneStream
|
|
);
|
|
|
|
if( !NT_SUCCESS(ntProcessStatus) )
|
|
{
|
|
//No System Buffer Available
|
|
SkyWalkerDebugPrint(ENTRY_LEVEL,
|
|
("Error: Streampointer cloning unsuccessful\n"));
|
|
ntProcessStatus = STATUS_UNSUCCESSFUL;
|
|
goto CompleteProcessing;
|
|
}
|
|
|
|
//Is the buffer size correct
|
|
if( pCloneStream->StreamHeader->FrameExtent <
|
|
(static_cast <DWORD>(m_TransportInfo->ulcbPhyiscalFrame)) )
|
|
{
|
|
//Buffer size incorrect
|
|
KsStreamPointerDelete(pCloneStream); //void function
|
|
SkyWalkerDebugPrint(ENTRY_LEVEL,("Error: Buffer size Incorrect\n"));
|
|
ntProcessStatus = STATUS_UNSUCCESSFUL;
|
|
goto CompleteProcessing;
|
|
}
|
|
|
|
//Set the stream header data used to 0. We update this
|
|
//in the USB Data Read completions.
|
|
pCloneStream->StreamHeader->DataUsed = 0;
|
|
|
|
pStreamContext = reinterpret_cast <PSTREAM_POINTER_CONTEXT>
|
|
(pCloneStream->Context);
|
|
|
|
//Set the Stream Index
|
|
pStreamContext->ulFrameIndex = m_CurrentFrameIndex;
|
|
|
|
PrintStream(pLeadingStream);
|
|
|
|
//(Refer NOTE above) Create a Stream Buffer Here and Submit
|
|
//it for the Reading / DMA
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("Current Stream Index = %lu",m_CurrentFrameIndex));
|
|
m_Device->ReadStream(m_CurrentFrameIndex);
|
|
m_CurrentFrameIndex = (m_CurrentFrameIndex+1) % NUMBER_OF_FRAMES;
|
|
|
|
//Advance Stream pointer to the next available data frame
|
|
ntProcessStatus = KsStreamPointerAdvance(pLeadingStream);
|
|
|
|
if( (ntProcessStatus != STATUS_DEVICE_NOT_READY) &&
|
|
(ntProcessStatus != STATUS_SUCCESS) )
|
|
{
|
|
SkyWalkerDebugPrint(ENTRY_LEVEL,
|
|
("Error: Video Capture Streampointer Advacement Failed\n"));
|
|
}
|
|
}
|
|
|
|
CompleteProcessing:
|
|
|
|
PrintFunctionExit(__FUNCTION__,ntProcessStatus);
|
|
return ntProcessStatus;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
Function : CCapturePin::ReleaseStream
|
|
Description : Called to notify the pin that a given Stream is completed
|
|
IN PARAM : <ULONG> The Stream Index
|
|
OUT PARAM : NONE
|
|
PreCondition : NONE
|
|
PostCondtion : Stream data is filled from the Internal Stream Buffer
|
|
Other Stream Parameters are set and Clone is Deleted
|
|
Logic : NONE
|
|
Assumption : NONE
|
|
Note : NONE
|
|
Revision History: <REVISION HISTORY OF THE FUNCTION, MUST BE MAINTAINED BY MAINTAINER >
|
|
*****************************************************************************/
|
|
void CCapturePin::ReleaseStream(IN ULONG ulStreamIndex)
|
|
{
|
|
|
|
PrintFunctionEntry(__FUNCTION__);
|
|
|
|
//Walk through the clones list and delete clones whose time has come.
|
|
//The list is guaranteed to be kept in the order they were cloned.
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("Completing Stream %lu\n",ulStreamIndex));
|
|
|
|
PKSSTREAM_POINTER pCloneStream = KsPinGetFirstCloneStreamPointer (m_Pin);
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("Clone Stream pointer = 0x%p\n",pCloneStream));
|
|
|
|
if(pCloneStream)
|
|
{
|
|
//Copy the Stream data from the Corresponding Streaming Buffer
|
|
RtlCopyMemory((PUCHAR)pCloneStream->StreamHeader->Data,
|
|
m_Device->GetSynthBuffer(ulStreamIndex),
|
|
m_TransportInfo->ulcbPhyiscalFrame);
|
|
|
|
pCloneStream->StreamHeader->DataUsed = m_TransportInfo->ulcbPhyiscalFrame;
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pCloneStream->StreamHeader->DataUsed = "
|
|
"%lu\n",
|
|
pCloneStream->StreamHeader->DataUsed));
|
|
|
|
pCloneStream->StreamHeader->Duration = m_TransportInfo->AvgTimePerFrame;
|
|
|
|
pCloneStream->StreamHeader->PresentationTime.Numerator =
|
|
pCloneStream->StreamHeader->PresentationTime.Denominator = 1;
|
|
|
|
//If a clock has been assigned, timestamp the packets with the
|
|
//time shown on the clock.
|
|
if (m_Clock)
|
|
{
|
|
|
|
LONGLONG ClockTime = m_Clock->GetTime ();
|
|
pCloneStream->StreamHeader->PresentationTime.Time = ClockTime;
|
|
pCloneStream->StreamHeader->OptionsFlags =
|
|
KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
|
|
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
//If there is no clock, don't time stamp the packets.
|
|
pCloneStream->StreamHeader->PresentationTime.Time = 0;
|
|
|
|
}
|
|
|
|
PrintStream(pCloneStream);
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("Stream Processed thus deleting the Clone\n"));
|
|
KsStreamPointerDelete (pCloneStream);
|
|
|
|
}
|
|
|
|
PrintFunctionExit(__FUNCTION__,STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
VOID PrintStream(IN PKSSTREAM_POINTER pStreamPointer)
|
|
{
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Context = 0x%p\n",pStreamPointer->Context));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Pin = 0x%p\n",pStreamPointer->Pin));
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader = 0x%p\n",pStreamPointer->StreamHeader));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->Size = %lu\n",pStreamPointer->StreamHeader->Size));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->TypeSpecificFlags = %lu\n",pStreamPointer->StreamHeader->TypeSpecificFlags));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->PresentationTime.Time= %l\n",pStreamPointer->StreamHeader->PresentationTime.Time));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->PresentationTime.Numerator= %lu\n",pStreamPointer->StreamHeader->PresentationTime.Numerator));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->PresentationTime.Denominator= %lu\n",pStreamPointer->StreamHeader->PresentationTime.Denominator));
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->Duration = %l\n",pStreamPointer->StreamHeader->Duration));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->FrameExtent = %lu\n",pStreamPointer->StreamHeader->FrameExtent));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->DataUsed = %lu\n",pStreamPointer->StreamHeader->DataUsed));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->Data = 0x%p\n",pStreamPointer->StreamHeader->Data));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->StreamHeader->OptionsFlags = %lu\n",pStreamPointer->StreamHeader->OptionsFlags));
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Offset = 0x%p\n",pStreamPointer->Offset));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Offset->Data = 0x%p\n",pStreamPointer->Offset->Data));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Offset->Mappings = 0x%p\n",pStreamPointer->Offset->Mappings));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Offset->Count = %lu\n",pStreamPointer->Offset->Count));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->Offset->Remaining = %lu\n",pStreamPointer->Offset->Remaining));
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetIn.Data = 0x%p\n",pStreamPointer->OffsetIn.Data));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetIn.Mappings = 0x%p\n",pStreamPointer->OffsetIn.Mappings));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetIn.Count = %lu\n",pStreamPointer->OffsetIn.Count));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetIn.Remaining = %lu\n",pStreamPointer->OffsetIn.Remaining));
|
|
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetOut.Data = 0x%p\n",pStreamPointer->OffsetOut.Data));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetOut.Mappings = 0x%p\n",pStreamPointer->OffsetOut.Mappings));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetOut.Count = %lu\n",pStreamPointer->OffsetOut.Count));
|
|
SkyWalkerDebugPrint(EXTREME_LEVEL,("pStreamPointer->OffsetOut.Remaining = %lu\n",pStreamPointer->OffsetOut.Remaining));
|
|
} |