mirror of
https://github.com/reactos/reactos.git
synced 2024-07-07 13:15:07 +00:00
[KSPROXY]
- Implement ISpecifyPropertyPages interface for CInputPin - Implement IKsInterfaceHandler::KsSetPin, IKsInterfaceHandler::KsProcessMediaSamples, IKsInterfaceHandler::KsCompleteIo svn path=/trunk/; revision=46205
This commit is contained in:
parent
7754d319f3
commit
59b9f20eee
|
@ -52,11 +52,11 @@ class CInputPin : public IPin,
|
||||||
public IKsControl,
|
public IKsControl,
|
||||||
public IKsObject,
|
public IKsObject,
|
||||||
public IKsPinEx,
|
public IKsPinEx,
|
||||||
public IMemInputPin
|
public IMemInputPin,
|
||||||
|
public ISpecifyPropertyPages
|
||||||
/*
|
/*
|
||||||
public IQualityControl,
|
public IQualityControl,
|
||||||
public IKsPinPipe,
|
public IKsPinPipe,
|
||||||
public ISpecifyPropertyPages,
|
|
||||||
public IStreamBuilder,
|
public IStreamBuilder,
|
||||||
public IKsPinFactory,
|
public IKsPinFactory,
|
||||||
public IKsAggregateControl
|
public IKsAggregateControl
|
||||||
|
@ -98,6 +98,9 @@ public:
|
||||||
HRESULT STDMETHODCALLTYPE EndFlush();
|
HRESULT STDMETHODCALLTYPE EndFlush();
|
||||||
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
|
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
|
||||||
|
|
||||||
|
// ISpecifyPropertyPages
|
||||||
|
HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
|
||||||
|
|
||||||
//IKsObject methods
|
//IKsObject methods
|
||||||
HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
|
HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
|
||||||
|
|
||||||
|
@ -205,7 +208,12 @@ CInputPin::QueryInterface(
|
||||||
reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
|
reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
|
||||||
return NOERROR;
|
return NOERROR;
|
||||||
}
|
}
|
||||||
|
else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
|
||||||
|
{
|
||||||
|
*Output = (ISpecifyPropertyPages*)(this);
|
||||||
|
reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
|
||||||
|
return NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
WCHAR Buffer[MAX_PATH];
|
WCHAR Buffer[MAX_PATH];
|
||||||
LPOLESTR lpstr;
|
LPOLESTR lpstr;
|
||||||
|
@ -217,6 +225,23 @@ CInputPin::QueryInterface(
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// ISpecifyPropertyPages
|
||||||
|
//
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
STDMETHODCALLTYPE
|
||||||
|
CInputPin::GetPages(CAUUID *pPages)
|
||||||
|
{
|
||||||
|
if (!pPages)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
pPages->cElems = 0;
|
||||||
|
pPages->pElems = NULL;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// IMemInputPin
|
// IMemInputPin
|
||||||
//
|
//
|
||||||
|
|
|
@ -35,14 +35,27 @@ public:
|
||||||
HRESULT STDMETHODCALLTYPE KsProcessMediaSamples(IKsDataTypeHandler *KsDataTypeHandler, IMediaSample** SampleList, PLONG SampleCount, KSIOOPERATION IoOperation, PKSSTREAM_SEGMENT *StreamSegment);
|
HRESULT STDMETHODCALLTYPE KsProcessMediaSamples(IKsDataTypeHandler *KsDataTypeHandler, IMediaSample** SampleList, PLONG SampleCount, KSIOOPERATION IoOperation, PKSSTREAM_SEGMENT *StreamSegment);
|
||||||
HRESULT STDMETHODCALLTYPE KsCompleteIo(PKSSTREAM_SEGMENT StreamSegment);
|
HRESULT STDMETHODCALLTYPE KsCompleteIo(PKSSTREAM_SEGMENT StreamSegment);
|
||||||
|
|
||||||
CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL){};
|
CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL), m_Pin(0){};
|
||||||
virtual ~CKsInterfaceHandler(){};
|
virtual ~CKsInterfaceHandler(){};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LONG m_Ref;
|
LONG m_Ref;
|
||||||
HANDLE m_Handle;
|
HANDLE m_Handle;
|
||||||
|
IKsPinEx * m_Pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
KSSTREAM_SEGMENT StreamSegment;
|
||||||
|
IMediaSample * MediaSample[64];
|
||||||
|
|
||||||
|
ULONG SampleCount;
|
||||||
|
ULONG ExtendedSize;
|
||||||
|
PKSSTREAM_HEADER StreamHeader;
|
||||||
|
OVERLAPPED Overlapped;
|
||||||
|
}KSSTREAM_SEGMENT_EXT, *PKSSTREAM_SEGMENT_EXT;
|
||||||
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
STDMETHODCALLTYPE
|
STDMETHODCALLTYPE
|
||||||
CKsInterfaceHandler::QueryInterface(
|
CKsInterfaceHandler::QueryInterface(
|
||||||
|
@ -66,22 +79,43 @@ CKsInterfaceHandler::KsSetPin(
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IKsObject * KsObject;
|
IKsObject * KsObject;
|
||||||
|
IKsPinEx * Pin;
|
||||||
|
|
||||||
// check if IKsObject is supported
|
// get IKsPinEx interface
|
||||||
hr = KsPin->QueryInterface(IID_IKsObject, (void**)&KsObject);
|
hr = KsPin->QueryInterface(IID_IKsPinEx, (void**)&Pin);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// get pin handle
|
// check if IKsObject is supported
|
||||||
m_Handle = KsObject->KsGetObjectHandle();
|
hr = KsPin->QueryInterface(IID_IKsObject, (void**)&KsObject);
|
||||||
|
|
||||||
// release IKsObject interface
|
if (SUCCEEDED(hr))
|
||||||
KsObject->Release();
|
|
||||||
|
|
||||||
if (!m_Handle)
|
|
||||||
{
|
{
|
||||||
// expected a file handle
|
// get pin handle
|
||||||
return E_UNEXPECTED;
|
m_Handle = KsObject->KsGetObjectHandle();
|
||||||
|
|
||||||
|
// release IKsObject interface
|
||||||
|
KsObject->Release();
|
||||||
|
|
||||||
|
if (!m_Handle)
|
||||||
|
{
|
||||||
|
// expected a file handle
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
Pin->Release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_Pin)
|
||||||
|
{
|
||||||
|
// release old interface
|
||||||
|
m_Pin->Release();
|
||||||
|
}
|
||||||
|
m_Pin = Pin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//release IKsPinEx interface
|
||||||
|
Pin->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,19 +130,333 @@ CKsInterfaceHandler::KsProcessMediaSamples(
|
||||||
IMediaSample** SampleList,
|
IMediaSample** SampleList,
|
||||||
PLONG SampleCount,
|
PLONG SampleCount,
|
||||||
KSIOOPERATION IoOperation,
|
KSIOOPERATION IoOperation,
|
||||||
PKSSTREAM_SEGMENT *StreamSegment)
|
PKSSTREAM_SEGMENT *OutStreamSegment)
|
||||||
{
|
{
|
||||||
OutputDebugString("UNIMPLEMENTED\n");
|
PKSSTREAM_SEGMENT_EXT StreamSegment;
|
||||||
return E_NOTIMPL;
|
ULONG ExtendedSize, Index, BytesReturned;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
OutputDebugString("CKsInterfaceHandler::KsProcessMediaSamples\n");
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
assert(*SampleCount);
|
||||||
|
|
||||||
|
if (*SampleCount == 0 || *SampleCount < 0)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
// zero stream segment
|
||||||
|
*OutStreamSegment = NULL;
|
||||||
|
|
||||||
|
// allocate stream segment
|
||||||
|
StreamSegment = (PKSSTREAM_SEGMENT_EXT)CoTaskMemAlloc(sizeof(KSSTREAM_SEGMENT_EXT));
|
||||||
|
if (!StreamSegment)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
// zero stream segment
|
||||||
|
ZeroMemory(StreamSegment, sizeof(KSSTREAM_SEGMENT_EXT));
|
||||||
|
|
||||||
|
//allocate event
|
||||||
|
StreamSegment->StreamSegment.CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
|
if (!StreamSegment->StreamSegment.CompletionEvent)
|
||||||
|
{
|
||||||
|
// failed to create event
|
||||||
|
CoTaskMemFree(StreamSegment);
|
||||||
|
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase our own reference count
|
||||||
|
AddRef();
|
||||||
|
|
||||||
|
// setup stream segment
|
||||||
|
StreamSegment->StreamSegment.KsDataTypeHandler = KsDataTypeHandler;
|
||||||
|
StreamSegment->StreamSegment.KsInterfaceHandler = (IKsInterfaceHandler*)this;
|
||||||
|
StreamSegment->StreamSegment.IoOperation = IoOperation;
|
||||||
|
StreamSegment->Overlapped.hEvent = StreamSegment->StreamSegment.CompletionEvent;
|
||||||
|
|
||||||
|
|
||||||
|
// ge extension size
|
||||||
|
ExtendedSize = 0;
|
||||||
|
if (KsDataTypeHandler)
|
||||||
|
{
|
||||||
|
// query extension size
|
||||||
|
KsDataTypeHandler->KsQueryExtendedSize(&ExtendedSize);
|
||||||
|
|
||||||
|
if (ExtendedSize)
|
||||||
|
{
|
||||||
|
// increment reference count
|
||||||
|
KsDataTypeHandler->AddRef();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no need for the datatype handler
|
||||||
|
StreamSegment->StreamSegment.KsDataTypeHandler = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamSegment->ExtendedSize = ExtendedSize;
|
||||||
|
StreamSegment->SampleCount = (ULONG)*SampleCount;
|
||||||
|
|
||||||
|
// calculate stream header size count
|
||||||
|
ULONG StreamHeaderSize = StreamSegment->SampleCount * (sizeof(KSSTREAM_HEADER) + ExtendedSize);
|
||||||
|
|
||||||
|
// allocate stream header
|
||||||
|
StreamSegment->StreamHeader = (PKSSTREAM_HEADER)CoTaskMemAlloc(StreamHeaderSize);
|
||||||
|
if (!StreamSegment->StreamHeader)
|
||||||
|
{
|
||||||
|
// not enough memory
|
||||||
|
CloseHandle(StreamSegment->StreamSegment.CompletionEvent);
|
||||||
|
|
||||||
|
if (StreamSegment->StreamSegment.KsDataTypeHandler)
|
||||||
|
StreamSegment->StreamSegment.KsDataTypeHandler->Release();
|
||||||
|
|
||||||
|
// free stream segment
|
||||||
|
CoTaskMemFree(StreamSegment);
|
||||||
|
|
||||||
|
//release our reference count
|
||||||
|
Release();
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero stream headers
|
||||||
|
ZeroMemory(StreamSegment->StreamHeader, StreamHeaderSize);
|
||||||
|
|
||||||
|
PKSSTREAM_HEADER CurStreamHeader = StreamSegment->StreamHeader;
|
||||||
|
|
||||||
|
// initialize all stream headers
|
||||||
|
for(Index = 0; Index < StreamSegment->SampleCount; Index++)
|
||||||
|
{
|
||||||
|
if (ExtendedSize)
|
||||||
|
{
|
||||||
|
// initialize extended size
|
||||||
|
hr = KsDataTypeHandler->KsPrepareIoOperation(SampleList[Index], (CurStreamHeader + 1), IoOperation);
|
||||||
|
// sanity check
|
||||||
|
assert(hr == NOERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// query for IMediaSample2 interface
|
||||||
|
IMediaSample2 * MediaSample;
|
||||||
|
AM_SAMPLE2_PROPERTIES Properties;
|
||||||
|
|
||||||
|
hr = SampleList[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
//get properties
|
||||||
|
|
||||||
|
hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
|
||||||
|
|
||||||
|
//release IMediaSample2 interface
|
||||||
|
MediaSample->Release();
|
||||||
|
if (FAILED(hr))
|
||||||
|
OutputDebugStringW(L"CKsInterfaceHandler::KsProcessMediaSamples MediaSample::GetProperties failed\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutputDebugStringW(L"CKsInterfaceHandler::KsProcessMediaSamples MediaSample:: only IMediaSample supported\n");
|
||||||
|
// get properties
|
||||||
|
hr = SampleList[Index]->GetPointer((BYTE**)&Properties.pbBuffer);
|
||||||
|
assert(hr == NOERROR);
|
||||||
|
hr = SampleList[Index]->GetTime(&Properties.tStart, &Properties.tStop);
|
||||||
|
assert(hr == NOERROR);
|
||||||
|
|
||||||
|
Properties.dwSampleFlags = 0;
|
||||||
|
|
||||||
|
if (SampleList[Index]->IsDiscontinuity() == S_OK)
|
||||||
|
Properties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
|
||||||
|
|
||||||
|
if (SampleList[Index]->IsPreroll() == S_OK)
|
||||||
|
Properties.dwSampleFlags |= AM_SAMPLE_PREROLL;
|
||||||
|
|
||||||
|
if (SampleList[Index]->IsSyncPoint() == S_OK)
|
||||||
|
Properties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR Buffer[100];
|
||||||
|
swprintf(Buffer, L"BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u\n", Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual);
|
||||||
|
OutputDebugStringW(Buffer);
|
||||||
|
|
||||||
|
CurStreamHeader->Size = sizeof(KSSTREAM_HEADER) + ExtendedSize;
|
||||||
|
CurStreamHeader->PresentationTime.Denominator = 1;
|
||||||
|
CurStreamHeader->PresentationTime.Numerator = 1;
|
||||||
|
CurStreamHeader->FrameExtent = Properties.cbBuffer;
|
||||||
|
CurStreamHeader->Data = Properties.pbBuffer;
|
||||||
|
|
||||||
|
if (IoOperation == KsIoOperation_Write)
|
||||||
|
{
|
||||||
|
// set flags
|
||||||
|
CurStreamHeader->OptionsFlags = Properties.dwSampleFlags;
|
||||||
|
CurStreamHeader->DataUsed = Properties.lActual;
|
||||||
|
// increment reference count
|
||||||
|
SampleList[Index]->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store sample in stream segment
|
||||||
|
StreamSegment->MediaSample[Index] = SampleList[Index];
|
||||||
|
|
||||||
|
// move to next header
|
||||||
|
CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// submit to device
|
||||||
|
m_Pin->KsIncrementPendingIoCount();
|
||||||
|
|
||||||
|
if (DeviceIoControl(m_Handle,
|
||||||
|
IoOperation == KsIoOperation_Write ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM,
|
||||||
|
NULL, 0,
|
||||||
|
StreamSegment->StreamHeader,
|
||||||
|
StreamHeaderSize,
|
||||||
|
&BytesReturned,
|
||||||
|
&StreamSegment->Overlapped))
|
||||||
|
{
|
||||||
|
// signal completion
|
||||||
|
SetEvent(StreamSegment->StreamSegment.CompletionEvent);
|
||||||
|
hr = S_OK;
|
||||||
|
*OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GetLastError() == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
*OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
STDMETHODCALLTYPE
|
STDMETHODCALLTYPE
|
||||||
CKsInterfaceHandler::KsCompleteIo(
|
CKsInterfaceHandler::KsCompleteIo(
|
||||||
PKSSTREAM_SEGMENT StreamSegment)
|
PKSSTREAM_SEGMENT InStreamSegment)
|
||||||
{
|
{
|
||||||
OutputDebugString("UNIMPLEMENTED\n");
|
PKSSTREAM_SEGMENT_EXT StreamSegment;
|
||||||
return E_NOTIMPL;
|
PKSSTREAM_HEADER CurStreamHeader;
|
||||||
|
DWORD dwError = ERROR_SUCCESS, BytesReturned;
|
||||||
|
BOOL bOverlapped;
|
||||||
|
ULONG Index;
|
||||||
|
HRESULT hr;
|
||||||
|
IMediaSample2 * MediaSample;
|
||||||
|
AM_SAMPLE2_PROPERTIES Properties;
|
||||||
|
REFERENCE_TIME Start, Stop;
|
||||||
|
|
||||||
|
OutputDebugStringW(L"CKsInterfaceHandler::KsCompleteIo\n");
|
||||||
|
|
||||||
|
// get private stream segment
|
||||||
|
StreamSegment = (PKSSTREAM_SEGMENT_EXT)InStreamSegment;
|
||||||
|
|
||||||
|
// get result
|
||||||
|
bOverlapped = GetOverlappedResult(m_Handle, &StreamSegment->Overlapped, &BytesReturned, FALSE);
|
||||||
|
dwError = GetLastError();
|
||||||
|
|
||||||
|
CurStreamHeader = StreamSegment->StreamHeader;
|
||||||
|
|
||||||
|
//iterate through all stream headers
|
||||||
|
for(Index = 0; Index < StreamSegment->SampleCount; Index++)
|
||||||
|
{
|
||||||
|
if (!bOverlapped)
|
||||||
|
{
|
||||||
|
// operation failed
|
||||||
|
m_Pin->KsNotifyError(StreamSegment->MediaSample[Index], MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, dwError));
|
||||||
|
}
|
||||||
|
|
||||||
|
// query IMediaSample2 interface
|
||||||
|
hr = StreamSegment->MediaSample[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
// media sample properties
|
||||||
|
hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
//update media sample properties
|
||||||
|
Properties.dwTypeSpecificFlags = CurStreamHeader->TypeSpecificFlags;
|
||||||
|
Properties.dwSampleFlags |= (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY);
|
||||||
|
|
||||||
|
MediaSample->SetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
|
||||||
|
}
|
||||||
|
// release IMediaSample2 interface
|
||||||
|
MediaSample->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// was an extended header used
|
||||||
|
if (StreamSegment->ExtendedSize)
|
||||||
|
{
|
||||||
|
// unprepare stream header extension
|
||||||
|
StreamSegment->StreamSegment.KsDataTypeHandler->KsCompleteIoOperation(StreamSegment->MediaSample[Index], (CurStreamHeader + 1), StreamSegment->StreamSegment.IoOperation, bOverlapped == FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Start = 0;
|
||||||
|
Stop = 0;
|
||||||
|
if (bOverlapped && StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
|
||||||
|
{
|
||||||
|
// update common media sample details
|
||||||
|
StreamSegment->MediaSample[Index]->SetSyncPoint((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT));
|
||||||
|
StreamSegment->MediaSample[Index]->SetPreroll((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_PREROLL));
|
||||||
|
StreamSegment->MediaSample[Index]->SetDiscontinuity((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY));
|
||||||
|
|
||||||
|
if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID)
|
||||||
|
{
|
||||||
|
// use valid timestamp
|
||||||
|
Start = CurStreamHeader->PresentationTime.Time;
|
||||||
|
|
||||||
|
if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID)
|
||||||
|
{
|
||||||
|
Stop = CurStreamHeader->PresentationTime.Time + CurStreamHeader->Duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now set time
|
||||||
|
hr = StreamSegment->MediaSample[Index]->SetTime(&Start, &Stop);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// use start time
|
||||||
|
StreamSegment->MediaSample[Index]->SetTime(&Start, &Start);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set valid data length
|
||||||
|
StreamSegment->MediaSample[Index]->SetActualDataLength(CurStreamHeader->DataUsed);
|
||||||
|
|
||||||
|
if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
|
||||||
|
{
|
||||||
|
if (bOverlapped)
|
||||||
|
{
|
||||||
|
// deliver sample
|
||||||
|
m_Pin->KsDeliver(StreamSegment->MediaSample[Index], CurStreamHeader->OptionsFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Write)
|
||||||
|
{
|
||||||
|
// release media sample reference
|
||||||
|
StreamSegment->MediaSample[Index]->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete stream headers
|
||||||
|
CoTaskMemFree(StreamSegment->StreamHeader);
|
||||||
|
|
||||||
|
if (StreamSegment->StreamSegment.KsDataTypeHandler)
|
||||||
|
{
|
||||||
|
// release reference
|
||||||
|
StreamSegment->StreamSegment.KsDataTypeHandler->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrement pending i/o count
|
||||||
|
m_Pin->KsDecrementPendingIoCount();
|
||||||
|
|
||||||
|
//notify of completion
|
||||||
|
m_Pin->KsMediaSamplesCompleted(InStreamSegment);
|
||||||
|
|
||||||
|
//destroy stream segment
|
||||||
|
CoTaskMemFree(StreamSegment);
|
||||||
|
|
||||||
|
//release reference to ourselves
|
||||||
|
Release();
|
||||||
|
|
||||||
|
// done
|
||||||
|
// Event handle is closed by caller
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
|
@ -165,3 +165,4 @@ CKsNode_Constructor(
|
||||||
LPVOID * ppv);
|
LPVOID * ppv);
|
||||||
|
|
||||||
extern const GUID IID_IKsObject;
|
extern const GUID IID_IKsObject;
|
||||||
|
extern const GUID IID_IKsPinEx;
|
||||||
|
|
Loading…
Reference in a new issue