Support unrar64.dll
[xy_vsfilter.git] / src / subpic / SimpleSubPicProviderImpl.cpp
blob230d63033c007cbc055e7bc986f09afb59a3c8dc
1 #include "stdafx.h"
2 #include "SimpleSubPicProviderImpl.h"
3 #include "SimpleSubPicWrapper.h"
4 #include "../subtitles/xy_bitmap.h"
5 #include "SimpleSubpicImpl.h"
6 #include "PooledSubPic.h"
7 #include "IDirectVobSubXy.h"
9 //////////////////////////////////////////////////////////////////////////
11 // SimpleSubPicProvider
12 //
15 SimpleSubPicProvider::SimpleSubPicProvider( int alpha_blt_dst_type, SIZE spd_size, RECT video_rect, IDirectVobSubXy *consumer
16 , HRESULT* phr/*=NULL*/ )
17 : CUnknown(NAME("CSubPicQueueImpl"), NULL)
18 , m_alpha_blt_dst_type(alpha_blt_dst_type)
19 , m_spd_size(spd_size)
20 , m_video_rect(video_rect)
21 , m_rtNow(0)
22 , m_fps(25.0)
23 , m_consumer(consumer)
25 if(phr) {
26 *phr = consumer ? S_OK : E_INVALIDARG;
29 m_prefered_colortype.AddTail(MSP_AYUV_PLANAR);
30 m_prefered_colortype.AddTail(MSP_AYUV);
31 m_prefered_colortype.AddTail(MSP_XY_AUYV);
32 m_prefered_colortype.AddTail(MSP_RGBA);
35 SimpleSubPicProvider::~SimpleSubPicProvider()
40 STDMETHODIMP SimpleSubPicProvider::NonDelegatingQueryInterface( REFIID riid, void** ppv )
42 return
43 QI(ISimpleSubPicProvider)
44 __super::NonDelegatingQueryInterface(riid, ppv);
47 STDMETHODIMP SimpleSubPicProvider::SetSubPicProvider( IUnknown* subpic_provider )
49 if (subpic_provider!=NULL)
51 CComQIPtr<ISubPicProviderEx2> tmp = subpic_provider;
52 if (tmp)
54 CAutoLock cAutoLock(&m_csSubPicProvider);
55 m_pSubPicProviderEx = tmp;
57 if(m_pSubPicProviderEx!=NULL)
59 POSITION pos = m_prefered_colortype.GetHeadPosition();
60 while(pos!=NULL)
62 int color_type = m_prefered_colortype.GetNext(pos);
63 if( m_pSubPicProviderEx->IsColorTypeSupported( color_type ) &&
64 IsSpdColorTypeSupported( color_type ) )
66 m_spd_type = color_type;
67 break;
71 Invalidate();
73 return S_OK;
76 return E_NOTIMPL;
79 return S_OK;
82 STDMETHODIMP SimpleSubPicProvider::GetSubPicProvider( IUnknown** subpic_provider )
84 if(!subpic_provider) {
85 return E_POINTER;
88 CAutoLock cAutoLock(&m_csSubPicProvider);
90 if(m_pSubPicProviderEx) {
91 *subpic_provider = m_pSubPicProviderEx;
92 (*subpic_provider)->AddRef();
95 return !!*subpic_provider ? S_OK : E_FAIL;
98 STDMETHODIMP SimpleSubPicProvider::SetFPS( double fps )
100 m_fps = fps;
102 return S_OK;
105 STDMETHODIMP SimpleSubPicProvider::SetTime( REFERENCE_TIME rtNow )
107 m_rtNow = rtNow;
109 return S_OK;
112 STDMETHODIMP SimpleSubPicProvider::Invalidate( REFERENCE_TIME rtInvalidate /*= -1*/ )
114 CAutoLock cQueueLock(&m_csLock);
116 if( m_pSubPic && m_subpic_stop >= rtInvalidate)
118 m_pSubPic = NULL;
120 return S_OK;
123 STDMETHODIMP_(bool) SimpleSubPicProvider::LookupSubPic( REFERENCE_TIME now /*[in]*/, ISimpleSubPic** output_subpic /*[out]*/ )
125 if(output_subpic!=NULL)
127 *output_subpic = NULL;
128 CComPtr<IXySubRenderFrame> temp = NULL;
129 bool result = LookupSubPicEx(now, &temp);
130 if (result && temp)
132 (*output_subpic = new SimpleSubpic(temp, m_alpha_blt_dst_type))->AddRef();
134 return result;
136 return false;
139 STDMETHODIMP SimpleSubPicProvider::GetStats( int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop )
141 CAutoLock cAutoLock(&m_csLock);
143 nSubPics = 0;
144 rtNow = m_rtNow;
145 rtStart = rtStop = 0;
147 if(m_pSubPic)
149 nSubPics = 1;
150 rtStart = m_subpic_start;
151 rtStop = m_subpic_stop;
154 return S_OK;
157 STDMETHODIMP SimpleSubPicProvider::GetStats( int nSubPic, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop )
159 CAutoLock cAutoLock(&m_csLock);
161 if(!m_pSubPic || nSubPic != 0)
162 return E_INVALIDARG;
164 rtStart = m_subpic_start;
165 rtStop = m_subpic_stop;
167 return S_OK;
170 bool SimpleSubPicProvider::LookupSubPicEx(REFERENCE_TIME rtNow, IXySubRenderFrame** sub_render_frame)
172 if(!sub_render_frame)
173 return(false);
175 *sub_render_frame = NULL;
177 if(m_subpic_start <= rtNow && rtNow < m_subpic_stop && m_pSubPic)
179 (*sub_render_frame = m_pSubPic)->AddRef();
181 else
183 CComPtr<ISubPicProviderEx2> pSubPicProvider;
184 if(SUCCEEDED(GetSubPicProviderEx(&pSubPicProvider)) && pSubPicProvider
185 && SUCCEEDED(pSubPicProvider->Lock()))
187 double fps = m_fps;
189 if(POSITION pos = pSubPicProvider->GetStartPosition(rtNow, fps))
191 REFERENCE_TIME rtStart = pSubPicProvider->GetStart(pos, fps);
192 REFERENCE_TIME rtStop = pSubPicProvider->GetStop(pos, fps);
194 if(rtStart <= rtNow && rtNow < rtStop)
196 RenderTo(sub_render_frame, rtNow, rtNow+1, fps, true);
200 pSubPicProvider->Unlock();
202 if(*sub_render_frame)
204 CAutoLock cAutoLock(&m_csLock);
206 m_pSubPic = *sub_render_frame;
210 return(!!*sub_render_frame);
213 HRESULT SimpleSubPicProvider::GetSubPicProviderEx( ISubPicProviderEx2** pSubPicProviderEx )
215 if(!pSubPicProviderEx) {
216 return E_POINTER;
219 CAutoLock cAutoLock(&m_csSubPicProvider);
221 if(m_pSubPicProviderEx) {
222 *pSubPicProviderEx = m_pSubPicProviderEx;
223 (*pSubPicProviderEx)->AddRef();
226 return !!*pSubPicProviderEx ? S_OK : E_FAIL;
229 HRESULT SimpleSubPicProvider::RenderTo( IXySubRenderFrame** pSubPic, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double fps, BOOL bIsAnimated )
231 HRESULT hr = E_FAIL;
233 if(!pSubPic) {
234 return hr;
237 CComPtr<ISubPicProviderEx2> pSubPicProviderEx;
238 if(FAILED(GetSubPicProviderEx(&pSubPicProviderEx)) || !pSubPicProviderEx) {
239 return hr;
242 if(FAILED(pSubPicProviderEx->Lock())) {
243 return hr;
246 CAtlList<CRect> rectList;
248 CComPtr<IXySubRenderFrame> sub_render_frame;
249 SIZE size_render_with;
250 ASSERT(m_consumer);
251 hr = m_consumer->XyGetSize(DirectVobSubXyOptions::SIZE_LAYOUT_WITH, &size_render_with);
252 if (FAILED(hr))
254 return hr;
257 hr = pSubPicProviderEx->RenderEx(pSubPic, m_spd_type, m_spd_size,
258 size_render_with, CRect(0,0,size_render_with.cx,size_render_with.cy),
259 bIsAnimated ? rtStart : ((rtStart+rtStop)/2), fps);
261 POSITION pos = pSubPicProviderEx->GetStartPosition(rtStart, fps);
263 pSubPicProviderEx->GetStartStop(pos, fps, m_subpic_start, m_subpic_stop);
265 pSubPicProviderEx->Unlock();
267 return hr;
270 bool SimpleSubPicProvider::IsSpdColorTypeSupported( int type )
272 if( (type==MSP_RGBA)
274 (type==MSP_XY_AUYV && m_alpha_blt_dst_type == MSP_YUY2)
276 (type==MSP_AYUV && m_alpha_blt_dst_type == MSP_AYUV)//ToDo: fix me MSP_AYUV
278 (type==MSP_AYUV_PLANAR && (m_alpha_blt_dst_type == MSP_IYUV ||
279 m_alpha_blt_dst_type == MSP_YV12 ||
280 m_alpha_blt_dst_type == MSP_P010 ||
281 m_alpha_blt_dst_type == MSP_P016 ||
282 m_alpha_blt_dst_type == MSP_NV12 ||
283 m_alpha_blt_dst_type == MSP_NV21)) )
285 return true;
287 return false;
290 //////////////////////////////////////////////////////////////////////////
292 // SimpleSubPicProvider2
295 SimpleSubPicProvider2::SimpleSubPicProvider2( int alpha_blt_dst_type, SIZE max_size, SIZE cur_size, RECT video_rect,
296 IDirectVobSubXy *consumer, HRESULT* phr/*=NULL*/)
297 : CUnknown(NAME("SimpleSubPicProvider2"), NULL)
298 , m_alpha_blt_dst_type(alpha_blt_dst_type)
299 , m_max_size(max_size)
300 , m_cur_size(cur_size)
301 , m_video_rect(video_rect)
302 , m_now(0)
303 , m_fps(25.0)
304 , m_consumer(consumer)
306 if (phr)
308 *phr= consumer ? S_OK : E_INVALIDARG;
310 m_ex_provider = NULL;
311 m_old_provider = NULL;
312 m_cur_provider = NULL;
315 SimpleSubPicProvider2::~SimpleSubPicProvider2()
317 delete m_ex_provider;
318 delete m_old_provider;
321 STDMETHODIMP SimpleSubPicProvider2::NonDelegatingQueryInterface( REFIID riid, void** ppv )
323 return
324 QI(ISimpleSubPicProvider)
325 __super::NonDelegatingQueryInterface(riid, ppv);
328 STDMETHODIMP SimpleSubPicProvider2::SetSubPicProvider( IUnknown* subpic_provider )
330 const int MAX_SUBPIC_QUEUE_LENGTH = 1;
332 if (subpic_provider!=NULL)
334 HRESULT hr;
335 CComQIPtr<ISubPicProviderEx2> tmp = subpic_provider;
336 if (tmp)
338 m_cur_provider = NULL;
339 delete m_old_provider;
340 m_old_provider = NULL;
341 if (!m_ex_provider)
343 m_ex_provider = new SimpleSubPicProvider(m_alpha_blt_dst_type, m_cur_size, m_video_rect, m_consumer, &hr);
344 m_ex_provider->SetFPS(m_fps);
345 m_ex_provider->SetTime(m_now);
347 if (m_ex_provider==NULL)
349 ASSERT(m_ex_provider!=NULL);
350 return E_FAIL;
352 m_cur_provider = m_ex_provider;
354 else
356 m_cur_provider = NULL;
357 delete m_ex_provider;
358 m_ex_provider = NULL;
359 if (!m_old_provider)
361 CComPtr<ISubPicExAllocator> pSubPicAllocator = new CPooledSubPicAllocator(m_alpha_blt_dst_type,
362 m_max_size, MAX_SUBPIC_QUEUE_LENGTH + 1);
363 ASSERT(pSubPicAllocator);
364 pSubPicAllocator->SetCurSize(m_cur_size);
365 pSubPicAllocator->SetCurVidRect(m_video_rect);
366 m_old_provider = new CSubPicQueueNoThread(pSubPicAllocator, &hr);
367 m_old_provider->SetFPS(m_fps);
368 m_old_provider->SetTime(m_now);
369 if (FAILED(hr) || m_old_provider==NULL)
371 ASSERT(SUCCEEDED(hr));
372 return hr;
375 m_cur_provider = m_old_provider;
377 return m_cur_provider->SetSubPicProvider(subpic_provider);
379 else
381 if (m_cur_provider!=NULL)
383 m_cur_provider->SetSubPicProvider(NULL);
385 m_cur_provider = NULL;
387 return S_OK;
390 STDMETHODIMP SimpleSubPicProvider2::GetSubPicProvider( IUnknown** subpic_provider )
392 if (!m_cur_provider)
394 return S_FALSE;
396 return m_cur_provider->GetSubPicProvider(subpic_provider);
399 STDMETHODIMP SimpleSubPicProvider2::SetFPS( double fps )
401 m_fps = fps;
402 if (!m_cur_provider)
404 return S_FALSE;
406 return m_cur_provider->SetFPS(fps);
409 STDMETHODIMP SimpleSubPicProvider2::SetTime( REFERENCE_TIME rtNow )
411 m_now = rtNow;
412 if (!m_cur_provider)
414 return S_FALSE;
416 return m_cur_provider->SetTime(rtNow);
419 STDMETHODIMP SimpleSubPicProvider2::Invalidate( REFERENCE_TIME rtInvalidate /*= -1*/ )
421 //ASSERT(m_cur_provider);
422 if (!m_cur_provider)
424 return S_FALSE;
426 return m_cur_provider->Invalidate(rtInvalidate);
429 STDMETHODIMP_(bool) SimpleSubPicProvider2::LookupSubPic( REFERENCE_TIME now /*[in]*/, ISimpleSubPic** output_subpic/*[out]*/ )
431 if (!m_cur_provider)
433 return false;
435 return m_cur_provider->LookupSubPic(now, output_subpic);
438 STDMETHODIMP SimpleSubPicProvider2::GetStats( int& nSubPics, REFERENCE_TIME& rtNow, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop )
440 nSubPics = 0;
441 if (!m_cur_provider)
443 return S_FALSE;
445 return m_cur_provider->GetStats(nSubPics, rtNow, rtStart, rtStop);
448 STDMETHODIMP SimpleSubPicProvider2::GetStats( int nSubPic, REFERENCE_TIME& rtStart, REFERENCE_TIME& rtStop )
450 if (!m_cur_provider)
452 return S_FALSE;
454 return m_cur_provider->GetStats(nSubPic, rtStart, rtStop);