285 | 286 | ||
---|---|---|---|
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 | } |