[KSPROXY]

- Implement sending multiple media samples to tv tuner at once in order to avoid the kernel irp queue running out

svn path=/trunk/; revision=46749
This commit is contained in:
Johannes Anderwald 2010-04-06 14:32:35 +00:00
parent f9e0e0d0b3
commit 35ac4e1e92
2 changed files with 59 additions and 10 deletions

View file

@ -357,6 +357,7 @@ CKsAllocator::GetBuffer(
if (!m_FreeList.empty())
{
OutputDebugStringW(L"CKsAllocator::GetBuffer HACK\n");
Sample = m_FreeList.top();
m_FreeList.pop();
}

View file

@ -2383,17 +2383,48 @@ COutputPin::IoProcessRoutine()
IMediaSample *Sample;
LONG SampleCount;
HRESULT hr;
PKSSTREAM_SEGMENT StreamSegment;
PKSSTREAM_SEGMENT * StreamSegment;
HANDLE hEvent;
IMediaSample * Samples[1];
IMediaSample ** Samples;
LONG NumHandles;
DWORD dwStatus;
#ifdef KSPROXY_TRACE
WCHAR Buffer[200];
#endif
NumHandles = m_Properties.cBuffers / 2;
if (!NumHandles)
NumHandles = 8;
assert(NumHandles);
//allocate stream segment array
StreamSegment = (PKSSTREAM_SEGMENT*)CoTaskMemAlloc(sizeof(PKSSTREAM_SEGMENT) * NumHandles);
if (!StreamSegment)
{
OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
return E_FAIL;
}
// allocate handle array
Samples = (IMediaSample**)CoTaskMemAlloc(sizeof(IMediaSample*) * NumHandles);
if (!Samples)
{
OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
return E_FAIL;
}
// zero handles array
ZeroMemory(StreamSegment, sizeof(PKSSTREAM_SEGMENT) * NumHandles);
ZeroMemory(Samples, sizeof(IMediaSample*) * NumHandles);
// first wait for the start event to signal
WaitForSingleObject(m_hStartEvent, INFINITE);
m_IoCount = 0;
assert(m_InterfaceHandler);
do
{
@ -2418,14 +2449,14 @@ COutputPin::IoProcessRoutine()
// fill buffer
SampleCount = 1;
Samples[0] = Sample;
Samples[m_IoCount] = Sample;
Sample->SetTime(NULL, NULL);
hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */
Samples,
&Samples[m_IoCount],
&SampleCount,
KsIoOperation_Read,
&StreamSegment);
&StreamSegment[m_IoCount]);
if (FAILED(hr) || !StreamSegment)
{
#ifdef KSPROXY_TRACE
@ -2435,14 +2466,26 @@ COutputPin::IoProcessRoutine()
break;
}
// get completion event
hEvent = StreamSegment->CompletionEvent;
// interface handle should increment pending i/o count
assert(m_IoCount >= 1);
swprintf(Buffer, L"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount, NumHandles);
OutputDebugStringW(Buffer);
if (m_IoCount != NumHandles)
continue;
// get completion handle
hEvent = StreamSegment[0]->CompletionEvent;
// wait for i/o completion
WaitForSingleObject(hEvent, INFINITE);
dwStatus = WaitForSingleObject(hEvent, INFINITE);
swprintf(Buffer, L"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus, GetLastError(), NumHandles);
OutputDebugStringW(Buffer);
// perform completion
m_InterfaceHandler->KsCompleteIo(StreamSegment);
m_InterfaceHandler->KsCompleteIo(StreamSegment[0]);
// close completion event
CloseHandle(hEvent);
@ -2452,7 +2495,7 @@ COutputPin::IoProcessRoutine()
assert(m_MemInputPin);
// now deliver the sample
hr = m_MemInputPin->Receive(Sample);
hr = m_MemInputPin->Receive(Samples[0]);
#ifdef KSPROXY_TRACE
swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator);
@ -2464,6 +2507,11 @@ COutputPin::IoProcessRoutine()
Sample = NULL;
}
//circular stream segment array
RtlMoveMemory(StreamSegment, &StreamSegment[1], sizeof(PKSSTREAM_SEGMENT) * (NumHandles - 1));
RtlMoveMemory(Samples, &Samples[1], sizeof(IMediaSample*) * (NumHandles - 1));
}while(TRUE);
// signal end of i/o thread