285286
39
public:
39
public:
40
 
40
 
41
    ////////////////////////////////////////////////////////
41
    ////////////////////////////////////////////////////////
42
    // CProxyMemAllocator
 
 
43
 
 
 
44
    class ATL_NO_VTABLE CProxyMemAllocator :
 
 
45
        public CComObjectRootEx<CComMultiThreadModelNoCS>,
 
 
46
        public IMemAllocator
 
 
47
    {
 
 
48
    public:
 
 
49
 
 
 
50
    DECLARE_QI_TRACE(CProxyMemAllocator)
 
 
51
 
 
 
52
    BEGIN_COM_MAP(CProxyMemAllocator)
 
 
53
        COM_INTERFACE_ENTRY(IMemAllocator)
 
 
54
    END_COM_MAP()
 
 
55
 
 
 
56
    private:
 
 
57
        CMediaType m_pMediaType;
 
 
58
        CComPtr<IMemAllocator> m_pInnerMemAllocator;
 
 
59
 
 
 
60
    public:
 
 
61
    // CProxyMemAllocator
 
 
62
        CProxyMemAllocator() throw()
 
 
63
        {
 
 
64
            _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
 
 
65
        }
 
 
66
        ~CProxyMemAllocator() throw()
 
 
67
        {
 
 
68
            _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
 
 
69
        }
 
 
70
        VOID Initialize(const CMediaType& pMediaType, IMemAllocator* pInnerMemAllocator)
 
 
71
        {
 
 
72
            _A(pMediaType && pInnerMemAllocator);
 
 
73
            m_pMediaType = pMediaType;
 
 
74
            m_pInnerMemAllocator = pInnerMemAllocator;
 
 
75
        }
 
 
76
        const CComPtr<IMemAllocator>& GetInnerMemAllocator() const throw()
 
 
77
        {
 
 
78
            return m_pInnerMemAllocator;
 
 
79
        }
 
 
80
 
 
 
81
    // IMemAllocator
 
 
82
        STDMETHOD(SetProperties)(ALLOCATOR_PROPERTIES* pRequestedProperties, ALLOCATOR_PROPERTIES* pActualProperties) throw()
 
 
83
        {
 
 
84
            _Z4(atlTraceCOM, 4, _T("...\n"));
 
 
85
            _ATLTRY
 
 
86
            {
 
 
87
                _A(m_pMediaType && m_pInnerMemAllocator);
 
 
88
                const HRESULT nSetPropertiesResult = m_pInnerMemAllocator->SetProperties(pRequestedProperties, pActualProperties);
 
 
89
                if(FAILED(nSetPropertiesResult))
 
 
90
                    _Z4(atlTraceGeneral, 4, _T("nSetPropertiesResult 0x%08x\n"), nSetPropertiesResult);
 
 
91
                // NOTE: Ignore requested properties, VMR allocator does not allow setting them which prevents decoder from using the allocator
 
 
92
                __C(m_pInnerMemAllocator->GetProperties(pActualProperties));
 
 
93
                _Z4(atlTraceGeneral, 4, _T("pRequestedProperties->cBuffers %d, ->cbBuffer %d, pActualProperties->cBuffers %d, ->cbBuffer %d\n"), pRequestedProperties->cBuffers, pRequestedProperties->cbBuffer, pActualProperties->cBuffers, pActualProperties->cbBuffer);
 
 
94
            }
 
 
95
            _ATLCATCH(Exception)
 
 
96
            {
 
 
97
                _C(Exception);
 
 
98
            }
 
 
99
            return S_OK;
 
 
100
        }
 
 
101
        STDMETHOD(GetProperties)(ALLOCATOR_PROPERTIES* pProperties) throw()
 
 
102
        {
 
 
103
            _Z4(atlTraceCOM, 4, _T("...\n"));
 
 
104
            _ATLTRY
 
 
105
            {
 
 
106
                _A(m_pInnerMemAllocator);
 
 
107
                __C(m_pInnerMemAllocator->GetProperties(pProperties));
 
 
108
            }
 
 
109
            _ATLCATCH(Exception)
 
 
110
            {
 
 
111
                _C(Exception);
 
 
112
            }
 
 
113
            return S_OK;
 
 
114
        }
 
 
115
        STDMETHOD(Commit)() throw()
 
 
116
        {
 
 
117
            _Z4(atlTraceCOM, 4, _T("...\n"));
 
 
118
            _ATLTRY
 
 
119
            {
 
 
120
                _A(m_pInnerMemAllocator);
 
 
121
                _FilterGraphHelper::TraceMemAllocator(m_pInnerMemAllocator);
 
 
122
                __C(m_pInnerMemAllocator->Commit());
 
 
123
            }
 
 
124
            _ATLCATCH(Exception)
 
 
125
            {
 
 
126
                _C(Exception);
 
 
127
            }
 
 
128
            return S_OK;
 
 
129
        }
 
 
130
        STDMETHOD(Decommit)() throw()
 
 
131
        {
 
 
132
            _Z4(atlTraceCOM, 4, _T("...\n"));
 
 
133
            _ATLTRY
 
 
134
            {
 
 
135
                _A(m_pInnerMemAllocator);
 
 
136
                __C(m_pInnerMemAllocator->Decommit());
 
 
137
            }
 
 
138
            _ATLCATCH(Exception)
 
 
139
            {
 
 
140
                _C(Exception);
 
 
141
            }
 
 
142
            return S_OK;
 
 
143
        }
 
 
144
        STDMETHOD(GetBuffer)(IMediaSample** ppMediaSample, REFERENCE_TIME* pnStartTime, REFERENCE_TIME* pnEndTime, DWORD nFlags) throw()
 
 
145
        {
 
 
146
            _Z4(atlTraceCOM, 4, _T("nFlags 0x%x\n"), nFlags);
 
 
147
            _ATLTRY
 
 
148
            {
 
 
149
                _A(m_pInnerMemAllocator);
 
 
150
                _C(m_pInnerMemAllocator->GetBuffer(ppMediaSample, pnStartTime, pnEndTime, nFlags));
 
 
151
            }
 
 
152
            _ATLCATCH(Exception)
 
 
153
            {
 
 
154
                _C(Exception);
 
 
155
            }
 
 
156
            return S_OK;
 
 
157
        }
 
 
158
        STDMETHOD(ReleaseBuffer)(IMediaSample* pMediaSample) throw()
 
 
159
        {
 
 
160
            _Z4(atlTraceCOM, 4, _T("pMediaSample 0x%p\n"), pMediaSample);
 
 
161
            pMediaSample;
 
 
162
            _A(FALSE);
 
 
163
            return S_OK;
 
 
164
        }
 
 
165
    };
 
 
166
 
 
 
167
    ////////////////////////////////////////////////////////
 
 
168
    // CInputPin
42
    // CInputPin
169
 
43
 
170
    class ATL_NO_VTABLE CInputPin :
44
    class ATL_NO_VTABLE CInputPin :
...
 
...
 
180
        COM_INTERFACE_ENTRY(IMemInputPin)
54
        COM_INTERFACE_ENTRY(IMemInputPin)
181
    END_COM_MAP()
55
    END_COM_MAP()
182
 
56
 
183
    private:
 
 
184
        CObjectPtr<CProxyMemAllocator> m_pProxyMemAllocator;
 
 
185
 
 
 
186
    public:
57
    public:
187
    // CInputPin
58
    // CInputPin
188
        CInputPin() throw()
59
        CInputPin() throw()
...
 
...
 
281
            _A(VerifyCriticalSectionLocked(GetDataCriticalSection()));
152
            _A(VerifyCriticalSectionLocked(GetDataCriticalSection()));
282
            const CObjectPtr<COutputPin>& pOutputPin = GetFilter()->GetOutputPin();
153
            const CObjectPtr<COutputPin>& pOutputPin = GetFilter()->GetOutputPin();
283
            if(pOutputPin->IsOutputMemAllocatorFixed())
154
            if(pOutputPin->IsOutputMemAllocatorFixed())
284
            {
155
                return CCreatedMemAllocator(pOutputPin->GetMemAllocator());
285
                CObjectPtr<CProxyMemAllocator> pProxyMemAllocator;
 
 
286
                pProxyMemAllocator.Construct()->Initialize(GetMediaTypeReference(), pOutputPin->GetMemAllocator());
 
 
287
                m_pProxyMemAllocator = pProxyMemAllocator;
 
 
288
                return CCreatedMemAllocator(pProxyMemAllocator);
 
 
289
            }
 
 
290
            return __super::CreateMemAllocator();
156
            return __super::CreateMemAllocator();
291
        }
157
        }
292
        BOOL CheckMemAllocator(IMemAllocator* pMemAllocator, const ALLOCATOR_PROPERTIES& Properties, BOOL bReadOnly) const throw()
158
        BOOL CheckMemAllocator(IMemAllocator* pMemAllocator, const ALLOCATOR_PROPERTIES& Properties, BOOL bReadOnly) const throw()
...
 
...
 
296
            if(pOutputPin->IsOutputMemAllocatorFixed())
162
            if(pOutputPin->IsOutputMemAllocatorFixed())
297
            {
163
            {
298
                _A(VerifyCriticalSectionLocked(GetDataCriticalSection()));
164
                _A(VerifyCriticalSectionLocked(GetDataCriticalSection()));
299
                _A(!m_pProxyMemAllocator || m_pProxyMemAllocator->GetInnerMemAllocator() == pOutputPin->GetMemAllocatorReference());
165
                return pMemAllocator == pOutputPin->GetMemAllocatorReference();
300
                return pMemAllocator == m_pProxyMemAllocator;
 
 
301
            }
166
            }
302
            return __super::CheckMemAllocator(pMemAllocator, Properties, bReadOnly);
167
            return __super::CheckMemAllocator(pMemAllocator, Properties, bReadOnly);
303
        }
168
        }
304
        CObjectPtr<CProxyMemAllocator> GetProxyMemAllocator() const throw()
 
 
305
        {
 
 
306
            CRoCriticalSectionLock DataLock(GetDataCriticalSection());
 
 
307
            return m_pProxyMemAllocator;
 
 
308
        }
 
 
309
    };
169
    };
310
 
170
 
311
    ////////////////////////////////////////////////////////
171
    ////////////////////////////////////////////////////////
...
 
...
 
375
            const CComPtr<IMemAllocator>& pMemAllocator = pInputPin->GetMemAllocatorReference();
235
            const CComPtr<IMemAllocator>& pMemAllocator = pInputPin->GetMemAllocatorReference();
376
            const HRESULT nNotifyAllocatorResult = GetPeerMemInputPinReference()->NotifyAllocator(pMemAllocator, pInputPin->GetMemAllocatorReadOnly());
236
            const HRESULT nNotifyAllocatorResult = GetPeerMemInputPinReference()->NotifyAllocator(pMemAllocator, pInputPin->GetMemAllocatorReadOnly());
377
            _Z4(atlTraceGeneral, SUCCEEDED(nNotifyAllocatorResult) ? 5 : 4, _T("nNotifyAllocatorResult 0x%08x\n"), nNotifyAllocatorResult);
237
            _Z4(atlTraceGeneral, SUCCEEDED(nNotifyAllocatorResult) ? 5 : 4, _T("nNotifyAllocatorResult 0x%08x\n"), nNotifyAllocatorResult);
378
            // TODO: Handle NotifyAllocator failures by propagating downstream memory allocator upwards, such as like in case of Video Renderer allocator
 
 
379
            if(FAILED(nNotifyAllocatorResult))
238
            if(FAILED(nNotifyAllocatorResult))
380
            {
239
            {
381
                #pragma region Try Downstream Allocator
240
                #pragma region Try Downstream Allocator
...
 
...
 
398
                        __C(pFilterGraph->Disconnect(pInputPeerPin));
257
                        __C(pFilterGraph->Disconnect(pInputPeerPin));
399
                        __C(pFilterGraph->Disconnect(pInputPin));
258
                        __C(pFilterGraph->Disconnect(pInputPin));
400
                        _Z4(atlTraceGeneral, 4, _T("pInputPeerPin \"%ls\"\n"), _FilterGraphHelper::GetPinFullName(pInputPeerPin));
259
                        _Z4(atlTraceGeneral, 4, _T("pInputPeerPin \"%ls\"\n"), _FilterGraphHelper::GetPinFullName(pInputPeerPin));
401
                        _FilterGraphHelper::TraceMediaType(pMediaType);
260
                        //_FilterGraphHelper::TraceMediaType(pMediaType);
402
                        _FilterGraphHelper::TraceMemAllocator(pMemAllocator);
261
                        //_FilterGraphHelper::TraceMemAllocator(pMemAllocator);
403
                        __C(pFilterGraph->ConnectDirect(pInputPeerPin, pInputPin, pMediaType));
262
                        __C(pFilterGraph->ConnectDirect(pInputPeerPin, pInputPin, pMediaType));
404
                        _A(pInputPin->GetPeerPinReference());
263
                        _A(pInputPin->GetPeerPinReference());
405
                        _A(pInputPin->GetPeerPinReference() == pInputPeerPin);
264
                        _A(pInputPin->GetPeerPinReference() == pInputPeerPin);
406
                        _A(pInputPin->GetMediaTypeReference() == pMediaType);
265
                        _A(pInputPin->GetMediaTypeReference() == pMediaType);
407
                        _A(pInputPin->GetMemAllocator() == pInputPin->GetProxyMemAllocator());
266
                        _A(pInputPin->GetMemAllocator() == pMemAllocator);
408
                        _A(pInputPin->GetProxyMemAllocator()->GetInnerMemAllocator() == pMemAllocator);
 
 
409
                        #pragma endregion 
267
                        #pragma endregion 
410
                    }
268
                    }
411
                    _ATLCATCHALL()
269
                    _ATLCATCHALL()
...
 
...
 
510
        CRoCriticalSectionLock ReceiveLock(GetReceiveCriticalSection());
368
        CRoCriticalSectionLock ReceiveLock(GetReceiveCriticalSection());
511
        if(!IsStreaming())
369
        if(!IsStreaming())
512
            return;
370
            return;
 
 
371
        CMediaSampleProperties Properties(pMediaSample);
 
 
372
        _A((Properties.pMediaType != NULL) ^ !(Properties.dwSampleFlags & AM_SAMPLE_TYPECHANGED));
 
 
373
        if(Properties.pMediaType)
 
 
374
        {
 
 
375
            const CMediaType& pMediaType = reinterpret_cast<const CMediaType&>(Properties.pMediaType);
 
 
376
            CRoCriticalSectionLock DataLock(GetDataCriticalSection());
 
 
377
            m_pInputPin->SetMediaType(pMediaType);
 
 
378
            m_pOutputPin->SetMediaType(pMediaType);
 
 
379
        }
513
        _A(m_pOutputPin->GetPeerMemInputPin());
380
        _A(m_pOutputPin->GetPeerMemInputPin());
514
        DeliverMediaSample(m_pOutputPin->GetPeerMemInputPin(), pMediaSample, nReceiveResult);
381
        DeliverMediaSample(m_pOutputPin->GetPeerMemInputPin(), pMediaSample, nReceiveResult);
515
    }
382
    }