[KSPROXY]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 22 Mar 2010 21:40:29 +0000 (21:40 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 22 Mar 2010 21:40:29 +0000 (21:40 +0000)
- 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
reactos/dll/directx/ksproxy/clockforward.cpp
reactos/dll/directx/ksproxy/input_pin.cpp
reactos/dll/directx/ksproxy/interface.cpp
reactos/dll/directx/ksproxy/ksproxy.cpp
reactos/dll/directx/ksproxy/mediasample.cpp
reactos/dll/directx/ksproxy/output_pin.cpp
reactos/dll/directx/ksproxy/precomp.h

index 7db5234..f5b9c1e 100644 (file)
@@ -16,6 +16,7 @@ class CKsAllocator : public IKsAllocatorEx,
 {
 public:
     typedef std::stack<IMediaSample *>MediaSampleStack;
+    typedef std::list<IMediaSample *>MediaSampleList;
 
     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
index 80bf00f..d692dec 100644 (file)
@@ -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(
index ef1cb54..783ff70 100644 (file)
@@ -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
index dffed7d..3d1af0d 100644 (file)
@@ -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++)
     {
index f79a154..f1e17c9 100644 (file)
@@ -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;
index c9cb4cd..8e317ef 100644 (file)
@@ -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;
 }
 
index e3d620e..e5f172b 100644 (file)
@@ -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);
 
index 335ae19..c02b6ad 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <vector>
 #include <stack>
+#include <list>
 #include <assert.h>
 #include <ksmedia.h>
 //#include <debug.h>