Author: janderwald Date: Tue Apr 6 16:32:35 2010 New Revision: 46749
URL: http://svn.reactos.org/svn/reactos?rev=46749&view=rev Log: [KSPROXY] - Implement sending multiple media samples to tv tuner at once in order to avoid the kernel irp queue running out
Modified: trunk/reactos/dll/directx/ksproxy/allocator.cpp trunk/reactos/dll/directx/ksproxy/output_pin.cpp
Modified: trunk/reactos/dll/directx/ksproxy/allocator.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/allocat... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/allocator.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/allocator.cpp [iso-8859-1] Tue Apr 6 16:32:35 2010 @@ -357,6 +357,7 @@
if (!m_FreeList.empty()) { + OutputDebugStringW(L"CKsAllocator::GetBuffer HACK\n"); Sample = m_FreeList.top(); m_FreeList.pop(); }
Modified: trunk/reactos/dll/directx/ksproxy/output_pin.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/ksproxy/output_... ============================================================================== --- trunk/reactos/dll/directx/ksproxy/output_pin.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/directx/ksproxy/output_pin.cpp [iso-8859-1] Tue Apr 6 16:32:35 2010 @@ -2383,16 +2383,47 @@ 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 @@
// 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 @@ 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 @@ 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 @@
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