From 89cff88aa28926c56179d27a85e3281521d2679e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 22 Mar 2010 21:40:29 +0000 Subject: [PATCH 1/1] [KSPROXY] - HACK: Return the oldest used sample when the allocator runs out of samples. Fixes playback as the render does not seem to release the media samples - Start implementing IKsClockForwarder interface - Fix a few bugs in KsOpenDefaultDevice - Implement IMediaSample::GetMediaType - Always use the CKsAllocator interface for allocating samples svn path=/trunk/; revision=46346 --- reactos/dll/directx/ksproxy/allocator.cpp | 14 +- reactos/dll/directx/ksproxy/clockforward.cpp | 195 +++++++++++++++++-- reactos/dll/directx/ksproxy/input_pin.cpp | 8 +- reactos/dll/directx/ksproxy/interface.cpp | 24 +-- reactos/dll/directx/ksproxy/ksproxy.cpp | 4 +- reactos/dll/directx/ksproxy/mediasample.cpp | 46 +++-- reactos/dll/directx/ksproxy/output_pin.cpp | 46 ++--- reactos/dll/directx/ksproxy/precomp.h | 1 + 8 files changed, 261 insertions(+), 77 deletions(-) diff --git a/reactos/dll/directx/ksproxy/allocator.cpp b/reactos/dll/directx/ksproxy/allocator.cpp index 7db52344d3d..f5b9c1e1e6a 100644 --- a/reactos/dll/directx/ksproxy/allocator.cpp +++ b/reactos/dll/directx/ksproxy/allocator.cpp @@ -16,6 +16,7 @@ class CKsAllocator : public IKsAllocatorEx, { public: typedef std::stackMediaSampleStack; + typedef std::listMediaSampleList; STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); @@ -77,6 +78,7 @@ protected: BOOL m_Commited; CRITICAL_SECTION m_CriticalSection; MediaSampleStack m_FreeList; + MediaSampleList m_UsedList; LPVOID m_Buffer; BOOL m_FreeSamples; }; @@ -118,6 +120,7 @@ CKsAllocator::CKsAllocator() : m_Ref(0), m_cbPrefix(0), m_Commited(FALSE), m_FreeList(), + m_UsedList(), m_Buffer(0), m_FreeSamples(FALSE) { @@ -362,12 +365,20 @@ CKsAllocator::GetBuffer( if (!Sample) { // no sample acquired - return VFW_E_TIMEOUT; + //HACKKKKKKK + Sample = m_UsedList.back(); + m_UsedList.pop_back(); + + if (!Sample) + return VFW_E_TIMEOUT; } // store result *ppBuffer = Sample; + // store sample in used list + m_UsedList.push_front(Sample); + // done return NOERROR; } @@ -387,6 +398,7 @@ CKsAllocator::ReleaseBuffer( // add the sample to the free list m_FreeList.push(pBuffer); + if (m_FreeSamples) { // pending de-commit diff --git a/reactos/dll/directx/ksproxy/clockforward.cpp b/reactos/dll/directx/ksproxy/clockforward.cpp index 80bf00fe421..d692dec5f63 100644 --- a/reactos/dll/directx/ksproxy/clockforward.cpp +++ b/reactos/dll/directx/ksproxy/clockforward.cpp @@ -12,6 +12,8 @@ const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; #endif +DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter); + class CKsClockForwarder : public IDistributorNotify, public IKsObject { @@ -45,14 +47,38 @@ public: // IKsObject interface HANDLE STDMETHODCALLTYPE KsGetObjectHandle(); - CKsClockForwarder(HANDLE handle) : m_Ref(0), m_Handle(handle){} - virtual ~CKsClockForwarder(){ if (m_Handle) CloseHandle(m_Handle);} - + CKsClockForwarder(HANDLE handle); + virtual ~CKsClockForwarder(){}; + HRESULT STDMETHODCALLTYPE SetClockState(KSSTATE State); protected: LONG m_Ref; HANDLE m_Handle; + IReferenceClock * m_Clock; + HANDLE m_hEvent; + HANDLE m_hThread; + BOOL m_ThreadStarted; + BOOL m_PendingStop; + BOOL m_ForceStart; + KSSTATE m_State; + REFERENCE_TIME m_Time; + + friend DWORD WINAPI CKsClockForwarder_ThreadStartup(LPVOID lpParameter); }; +CKsClockForwarder::CKsClockForwarder( + HANDLE handle) : m_Ref(0), + m_Handle(handle), + m_Clock(0), + m_hEvent(NULL), + m_hThread(NULL), + m_ThreadStarted(FALSE), + m_PendingStop(FALSE), + m_ForceStart(FALSE), + m_State(KSSTATE_STOP), + m_Time(0) +{ +} + HRESULT STDMETHODCALLTYPE CKsClockForwarder::QueryInterface( @@ -100,16 +126,79 @@ HRESULT STDMETHODCALLTYPE CKsClockForwarder::Stop() { - OutputDebugString("UNIMPLEMENTED\n"); - return E_NOTIMPL; + OutputDebugString("CKsClockForwarder::Stop\n"); + + if (m_ThreadStarted) + { + // signal pending stop + m_PendingStop = true; + + assert(m_hThread); + assert(m_hEvent); + + // set stop event + SetEvent(m_hEvent); + + // wait untill the thread has finished + WaitForSingleObject(m_hThread, INFINITE); + + // close thread handle + CloseHandle(m_hThread); + + // zero handle + m_hThread = NULL; + } + + if (m_hEvent) + { + // close stop event + CloseHandle(m_hEvent); + m_hEvent = NULL; + } + + m_PendingStop = false; + + SetClockState(KSSTATE_STOP); + return NOERROR; } HRESULT STDMETHODCALLTYPE CKsClockForwarder::Pause() { - OutputDebugString("UNIMPLEMENTED\n"); - return E_NOTIMPL; + OutputDebugString("CKsClockForwarder::Pause\n"); + + if (!m_hEvent) + { + m_hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!m_hEvent) + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + if (m_State <= KSSTATE_PAUSE) + { + if (m_State == KSSTATE_STOP) + SetClockState(KSSTATE_ACQUIRE); + + if (m_State == KSSTATE_ACQUIRE) + SetClockState(KSSTATE_PAUSE); + } + else + { + if (!m_ForceStart) + { + SetClockState(KSSTATE_PAUSE); + } + } + + if (!m_hThread) + { + m_hThread = CreateThread(NULL, 0, CKsClockForwarder_ThreadStartup, (LPVOID)this, 0, NULL); + if (!m_hThread) + return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); + } + + return NOERROR; } HRESULT @@ -117,8 +206,26 @@ STDMETHODCALLTYPE CKsClockForwarder::Run( REFERENCE_TIME tStart) { - OutputDebugString("UNIMPLEMENTED\n"); - return E_NOTIMPL; + OutputDebugString("CKsClockForwarder::Run\n"); + + m_Time = tStart; + + if (!m_hEvent || !m_hThread) + { + m_ForceStart = TRUE; + HRESULT hr = Pause(); + m_ForceStart = FALSE; + + if (FAILED(hr)) + return hr; + } + + assert(m_hThread); + + SetClockState(KSSTATE_RUN); + SetEvent(m_hEvent); + + return NOERROR; } HRESULT @@ -126,15 +233,25 @@ STDMETHODCALLTYPE CKsClockForwarder::SetSyncSource( IReferenceClock *pClock) { - OutputDebugString("UNIMPLEMENTED\n"); - return E_NOTIMPL; + OutputDebugString("CKsClockForwarder::SetSyncSource\n"); + + if (pClock) + pClock->AddRef(); + + if (m_Clock) + m_Clock->Release(); + + + m_Clock = pClock; + return NOERROR; } HRESULT STDMETHODCALLTYPE CKsClockForwarder::NotifyGraphChange() { - OutputDebugString("UNIMPLEMENTED\n"); + OutputDebugString("CKsClockForwarder::NotifyGraphChange\n"); + DebugBreak(); return E_NOTIMPL; } @@ -149,6 +266,60 @@ CKsClockForwarder::KsGetObjectHandle() return m_Handle; } +//------------------------------------------------------------------- +HRESULT +STDMETHODCALLTYPE +CKsClockForwarder::SetClockState(KSSTATE State) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + Property.Set = KSPROPSETID_Clock; + Property.Id = KSPROPERTY_CLOCK_STATE; + Property.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &BytesReturned); + if (SUCCEEDED(hr)) + m_State = State; + + return hr; +} + +DWORD +WINAPI +CKsClockForwarder_ThreadStartup(LPVOID lpParameter) +{ + REFERENCE_TIME Time; + ULONG BytesReturned; + + CKsClockForwarder * Fwd = (CKsClockForwarder*)lpParameter; + + Fwd->m_ThreadStarted = TRUE; + + do + { + if (Fwd->m_PendingStop) + break; + + if (Fwd->m_State != KSSTATE_RUN) + WaitForSingleObject(Fwd->m_hEvent, INFINITE); + + KSPROPERTY Property; + Property.Set = KSPROPSETID_Clock; + Property.Id = KSPROPERTY_CLOCK_TIME; + Property.Flags = KSPROPERTY_TYPE_SET; + + Fwd->m_Clock->GetTime(&Time); + Time -= Fwd->m_Time; + + KsSynchronousDeviceControl(Fwd->m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), &Time, sizeof(REFERENCE_TIME), &BytesReturned); + } + while(TRUE); + + Fwd->m_ThreadStarted = FALSE; + return NOERROR; +} + HRESULT WINAPI CKsClockForwarder_Constructor( diff --git a/reactos/dll/directx/ksproxy/input_pin.cpp b/reactos/dll/directx/ksproxy/input_pin.cpp index ef1cb544563..783ff703e5e 100644 --- a/reactos/dll/directx/ksproxy/input_pin.cpp +++ b/reactos/dll/directx/ksproxy/input_pin.cpp @@ -657,6 +657,7 @@ STDMETHODCALLTYPE CInputPin::Receive(IMediaSample *pSample) { OutputDebugStringW(L"CInputPin::Receive NotImplemented\n"); + DebugBreak(); return E_NOTIMPL; } @@ -665,6 +666,7 @@ STDMETHODCALLTYPE CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) { OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n"); + DebugBreak(); return E_NOTIMPL; } @@ -673,6 +675,7 @@ STDMETHODCALLTYPE CInputPin::ReceiveCanBlock( void) { OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n"); + DebugBreak(); return S_FALSE; } @@ -744,8 +747,6 @@ CInputPin::KsPropagateAcquire() ULONG BytesReturned; HRESULT hr; - OutputDebugStringW(L"CInputPin::KsPropagateAcquire\n"); - assert(m_hPin != INVALID_HANDLE_VALUE); Property.Set = KSPROPSETID_Connection; @@ -838,6 +839,7 @@ CInputPin::KsQualityNotify( REFERENCE_TIME TimeDelta) { OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n"); + DebugBreak(); return E_NOTIMPL; } @@ -1025,6 +1027,7 @@ STDMETHODCALLTYPE CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { OutputDebugStringW(L"CInputPin::Connect NotImplemented\n"); + DebugBreak(); return NOERROR; } @@ -1104,6 +1107,7 @@ CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) return VFW_E_NOT_CONNECTED; OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); + DebugBreak(); return E_NOTIMPL; } HRESULT diff --git a/reactos/dll/directx/ksproxy/interface.cpp b/reactos/dll/directx/ksproxy/interface.cpp index dffed7d6f8e..3d1af0db1b0 100644 --- a/reactos/dll/directx/ksproxy/interface.cpp +++ b/reactos/dll/directx/ksproxy/interface.cpp @@ -134,22 +134,6 @@ CKsInterfaceHandler::KsSetPin( } pPin->Release(); } - - IKsAllocatorEx * Allocator; - - if (SUCCEEDED(KsPin->QueryInterface(IID_IKsAllocatorEx, (void**)&Allocator))) - { - PALLOCATOR_PROPERTIES_EX Properties = Allocator->KsGetProperties(); - - if (Properties) - { - WCHAR Buffer[100]; - swprintf(Buffer, L"CKsInterfaceHandler::KsSetPin PinName %s Properties.cbAlign %u cbBuffer %u cbPrefix %u cBuffers %u\n", m_PinName, Properties->cbAlign, Properties->cbBuffer, Properties->cbPrefix, Properties->cBuffers); - OutputDebugStringW(Buffer); - } - Allocator->Release(); - } - #endif // done @@ -268,6 +252,7 @@ CKsInterfaceHandler::KsProcessMediaSamples( // query for IMediaSample2 interface IMediaSample2 * MediaSample; AM_SAMPLE2_PROPERTIES Properties; + ZeroMemory(&Properties, sizeof(AM_SAMPLE2_PROPERTIES)); hr = SampleList[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample); if (SUCCEEDED(hr)) @@ -285,7 +270,6 @@ CKsInterfaceHandler::KsProcessMediaSamples( hr = SampleList[Index]->GetPointer((BYTE**)&Properties.pbBuffer); assert(hr == NOERROR); hr = SampleList[Index]->GetTime(&Properties.tStart, &Properties.tStop); - assert(hr == NOERROR); Properties.cbBuffer = SampleList[Index]->GetSize(); assert(Properties.cbBuffer); @@ -303,7 +287,7 @@ CKsInterfaceHandler::KsProcessMediaSamples( } WCHAR Buffer[200]; - swprintf(Buffer, L"CKsInterfaceHandler::KsProcessMediaSamples PinName %s BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u\n", m_PinName, Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual); + swprintf(Buffer, L"CKsInterfaceHandler::KsProcessMediaSamples PinName %s BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u dwSampleFlags %lx\n", m_PinName, Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual, Properties.dwSampleFlags); //OutputDebugStringW(Buffer); CurStreamHeader->Size = sizeof(KSSTREAM_HEADER) + ExtendedSize; @@ -379,10 +363,6 @@ CKsInterfaceHandler::KsCompleteIo( CurStreamHeader = StreamSegment->StreamHeader; - WCHAR Buffer[100]; - swprintf(Buffer, L"CKsInterfaceHandler::KsCompleteIo PinName %s bOverlapped %u hr %lx\n", m_PinName, bOverlapped, dwError); - //OutputDebugStringW(Buffer); - //iterate through all stream headers for(Index = 0; Index < StreamSegment->SampleCount; Index++) { diff --git a/reactos/dll/directx/ksproxy/ksproxy.cpp b/reactos/dll/directx/ksproxy/ksproxy.cpp index f79a154574b..f1e17c96922 100644 --- a/reactos/dll/directx/ksproxy/ksproxy.cpp +++ b/reactos/dll/directx/ksproxy/ksproxy.cpp @@ -117,7 +117,7 @@ KsOpenDefaultDevice( WCHAR Path[MAX_PATH+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)]; /* open device list */ - hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE /* | DIGCF_PRESENT*/); + hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hList == INVALID_HANDLE_VALUE) { @@ -129,7 +129,7 @@ KsOpenDefaultDevice( DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - if (SetupDiEnumDeviceInterfaces(hList, &DeviceInfoData, &Category, 0, &DeviceInterfaceData)) + if (SetupDiEnumDeviceInterfaces(hList, NULL, &Category, 0, &DeviceInterfaceData)) { /* setup interface data struct */ DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)Path; diff --git a/reactos/dll/directx/ksproxy/mediasample.cpp b/reactos/dll/directx/ksproxy/mediasample.cpp index c9cb4cd0ff3..8e317efef61 100644 --- a/reactos/dll/directx/ksproxy/mediasample.cpp +++ b/reactos/dll/directx/ksproxy/mediasample.cpp @@ -56,34 +56,47 @@ public: virtual ~CMediaSample(){} protected: - LONG m_Ref; - IMemAllocator * m_Allocator; + ULONG m_Flags; + ULONG m_TypeFlags; BYTE * m_Buffer; - LONG m_BufferSize; LONG m_ActualLength; + LONG m_BufferSize; + IMemAllocator * m_Allocator; + CMediaSample * m_Next; REFERENCE_TIME m_StartTime; REFERENCE_TIME m_StopTime; - ULONG m_Flags; - BOOL m_bMediaTimeValid; LONGLONG m_MediaStart; LONGLONG m_MediaStop; + AM_MEDIA_TYPE * m_MediaType; + ULONG m_StreamId; + +public: + LONG m_Ref; + + BOOL m_bMediaTimeValid; + }; CMediaSample::CMediaSample( IMemAllocator * Allocator, BYTE * Buffer, - LONG BufferSize) : m_Ref(0), - m_Allocator(Allocator), + LONG BufferSize) : + m_Flags(0), + m_TypeFlags(0), m_Buffer(Buffer), - m_BufferSize(BufferSize), m_ActualLength(BufferSize), + m_BufferSize(BufferSize), + m_Allocator(Allocator), + m_Next(0), m_StartTime(0), m_StopTime(0), - m_Flags(0), - m_bMediaTimeValid(0), m_MediaStart(0), - m_MediaStop(0) + m_MediaStop(0), + m_MediaType(0), + m_StreamId(0), + m_Ref(0), + m_bMediaTimeValid(0) { } @@ -254,8 +267,15 @@ HRESULT STDMETHODCALLTYPE CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType) { - OutputDebugStringW(L"CMediaSample::GetMediaType NotImplemented\n"); - DebugBreak(); + OutputDebugStringW(L"CMediaSample::GetMediaType\n"); + + if (!m_MediaType) + { + *ppMediaType = NULL; + return S_FALSE; + } + + assert(0); return E_NOTIMPL; } diff --git a/reactos/dll/directx/ksproxy/output_pin.cpp b/reactos/dll/directx/ksproxy/output_pin.cpp index e3d620e368d..e5f172bf2e0 100644 --- a/reactos/dll/directx/ksproxy/output_pin.cpp +++ b/reactos/dll/directx/ksproxy/output_pin.cpp @@ -1280,11 +1280,12 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) m_MemInputPin->GetAllocatorRequirements(&Properties); //FIXME determine allocator properties - Properties.cBuffers = 16; + Properties.cBuffers = 32; Properties.cbBuffer = 2048 * 188; //2048 frames * MPEG2 TS Payload size Properties.cbAlign = 4; // get input pin allocator +#if 0 hr = m_MemInputPin->GetAllocator(&m_MemAllocator); if (SUCCEEDED(hr)) { @@ -1293,8 +1294,9 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) if (FAILED(hr)) m_MemAllocator->Release(); } +#endif - if (FAILED(hr)) + if (1) { hr = CKsAllocator_Constructor(NULL, IID_IMemAllocator, (void**)&m_MemAllocator); if (FAILED(hr)) @@ -1444,8 +1446,6 @@ HRESULT STDMETHODCALLTYPE COutputPin::QueryPinInfo(PIN_INFO *pInfo) { - OutputDebugStringW(L"COutputPin::QueryPinInfo\n"); - wcscpy(pInfo->achName, m_PinName); pInfo->dir = PINDIR_OUTPUT; pInfo->pFilter = m_ParentFilter; @@ -1457,8 +1457,6 @@ HRESULT STDMETHODCALLTYPE COutputPin::QueryDirection(PIN_DIRECTION *pPinDir) { - OutputDebugStringW(L"COutputPin::QueryDirection\n"); - if (pPinDir) { *pPinDir = PINDIR_OUTPUT; @@ -1471,8 +1469,6 @@ HRESULT STDMETHODCALLTYPE COutputPin::QueryId(LPWSTR *Id) { - OutputDebugStringW(L"COutputPin::QueryId\n"); - *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR)); if (!*Id) return E_OUTOFMEMORY; @@ -1496,8 +1492,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) AM_MEDIA_TYPE * MediaTypes; HANDLE hFilter; - OutputDebugStringW(L"COutputPin::EnumMediaTypes called\n"); - if (!m_KsObjectParent) { // no interface @@ -1511,7 +1505,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount); if (FAILED(hr) || !MediaTypeCount) { - OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n"); return hr; } @@ -1520,7 +1513,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) if (!MediaTypes) { // not enough memory - OutputDebugStringW(L"COutputPin::EnumMediaTypes CoTaskMemAlloc\n"); return E_OUTOFMEMORY; } @@ -1535,7 +1527,6 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) { // failed CoTaskMemFree(MediaTypes); - OutputDebugStringW(L"COutputPin::EnumMediaTypes failed\n"); return hr; } } @@ -1546,7 +1537,6 @@ HRESULT STDMETHODCALLTYPE COutputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) { - OutputDebugStringW(L"COutputPin::QueryInternalConnections called\n"); return E_NOTIMPL; } HRESULT @@ -1612,7 +1602,6 @@ COutputPin::CheckFormat( { // format is supported CoTaskMemFree(MultipleItem); - OutputDebugStringW(L"COutputPin::CheckFormat format OK\n"); return S_OK; } DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize); @@ -1687,7 +1676,6 @@ COutputPin::CreatePin( if (FAILED(hr)) { // failed to load interface handler plugin - OutputDebugStringW(L"COutputPin::CreatePin failed to load InterfaceHandlerPlugin\n"); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); @@ -1699,7 +1687,6 @@ COutputPin::CreatePin( if (FAILED(hr)) { // failed to load interface handler plugin - OutputDebugStringW(L"COutputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n"); InterfaceHandler->Release(); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); @@ -1887,10 +1874,11 @@ COutputPin::IoProcessRoutine() if (FAILED(hr)) { + OutputDebugStringW(L"OutOfSamples\n"); m_Pin->BeginFlush(); - OutputDebugStringW(L"Beginning flushing...\n"); WaitForSingleObject(m_hBufferAvailable, INFINITE); m_Pin->EndFlush(); + OutputDebugStringW(L"After Wait OutOfSamples\n"); // now retry again continue; } @@ -1899,8 +1887,7 @@ COutputPin::IoProcessRoutine() SampleCount = 1; Samples[0] = Sample; - - Sample->SetTime(&Start, &Stop); + Sample->SetTime(NULL, NULL); hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */ Samples, &SampleCount, @@ -1908,9 +1895,11 @@ COutputPin::IoProcessRoutine() &StreamSegment); if (FAILED(hr) || !StreamSegment) { - swprintf(Buffer, L"COutputPin::IoProcessRoutine KsProcessMediaSamples PinName %s hr %lx StreamSegment %p\n", m_PinName, hr, StreamSegment); + swprintf(Buffer, L"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName, hr); OutputDebugStringW(Buffer); - break; + SetEvent(m_hStopEvent); + m_IoThreadStarted = false; + ExitThread(0); } // get completion event @@ -1927,15 +1916,19 @@ COutputPin::IoProcessRoutine() if (SUCCEEDED(hr)) { - Sample->GetTime(&Start, &Stop); + LONG Length = Sample->GetActualDataLength(); + Stop += Length; + // Sample->SetMediaTime(&Start, &Stop); Start = Stop; - Stop++; // now deliver the sample hr = m_MemInputPin->Receive(Sample); - swprintf(Buffer, L"COutputPin::IoProcessRoutine IMemInputPin::Receive hr %lx Start %I64u Stop %I64u\n", hr, Start, Stop); + swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator); OutputDebugStringW(Buffer); + if (FAILED(hr)) + DebugBreak(); + Sample = NULL; } }while(TRUE); @@ -2118,6 +2111,9 @@ COutputPin_SetState( if (FAILED(hr)) return hr; + // release any waiting threads + SetEvent(pPin->m_hBufferAvailable); + // wait until i/o thread is done WaitForSingleObject(pPin->m_hStopEvent, INFINITE); diff --git a/reactos/dll/directx/ksproxy/precomp.h b/reactos/dll/directx/ksproxy/precomp.h index 335ae19e1f1..c02b6adb6f4 100644 --- a/reactos/dll/directx/ksproxy/precomp.h +++ b/reactos/dll/directx/ksproxy/precomp.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include //#include -- 2.17.1