diff --git a/reactos/dll/directx/ksproxy/allocator.cpp b/reactos/dll/directx/ksproxy/allocator.cpp index e7c4b1f2436..8229bd2f56e 100644 --- a/reactos/dll/directx/ksproxy/allocator.cpp +++ b/reactos/dll/directx/ksproxy/allocator.cpp @@ -357,6 +357,7 @@ CKsAllocator::GetBuffer( if (!m_FreeList.empty()) { + OutputDebugStringW(L"CKsAllocator::GetBuffer HACK\n"); Sample = m_FreeList.top(); m_FreeList.pop(); } diff --git a/reactos/dll/directx/ksproxy/output_pin.cpp b/reactos/dll/directx/ksproxy/output_pin.cpp index f9f37725c53..bee119303ae 100644 --- a/reactos/dll/directx/ksproxy/output_pin.cpp +++ b/reactos/dll/directx/ksproxy/output_pin.cpp @@ -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