2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
23 #include "SubPicQueueImpl.h"
24 #include "../DSUtil/DSUtil.h"
27 #include "SubPicProviderExWrapper.h"
28 #include "SimpleSubPicWrapper.h"
30 #define CSUBPICQUEUE_THREAD_PROC_WAIT_TIMEOUT 20
31 #define CSUBPICQUEUE_LOOKUP_WAIT_TIMEOUT 40
32 #define CSUBPICQUEUE_UPDATEQUEUE_WAIT_TIMEOUT 100
38 CSubPicQueueImpl::CSubPicQueueImpl(ISubPicExAllocator
* pAllocator
, HRESULT
* phr
, const int *prefered_colortype
/*=NULL*/, int prefered_colortype_num
/*=0*/)
39 : CUnknown(NAME("CSubPicQueueImpl"), NULL
)
40 , m_pAllocator(pAllocator
)
55 for (int i
=0;i
<prefered_colortype_num
;i
++)
57 m_prefered_colortype
.AddTail(prefered_colortype
[i
]);
59 if(m_prefered_colortype
.IsEmpty())
61 m_prefered_colortype
.AddTail(MSP_AYUV_PLANAR
);
62 m_prefered_colortype
.AddTail(MSP_AYUV
);
63 m_prefered_colortype
.AddTail(MSP_XY_AUYV
);
64 m_prefered_colortype
.AddTail(MSP_RGBA
);
68 CSubPicQueueImpl::~CSubPicQueueImpl()
72 STDMETHODIMP
CSubPicQueueImpl::NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
76 QI(ISimpleSubPicProvider
)
77 __super::NonDelegatingQueryInterface(riid
, ppv
);
82 STDMETHODIMP
CSubPicQueueImpl::SetSubPicProvider(ISubPicProvider
* pSubPicProvider
)
84 return SetSubPicProviderEx( CSubPicProviderExWrapper::GetSubPicProviderExWrapper(pSubPicProvider
) );
87 STDMETHODIMP
CSubPicQueueImpl::GetSubPicProvider(ISubPicProvider
** pSubPicProvider
)
89 if(!pSubPicProvider
) {
93 CAutoLock
cAutoLock(&m_csSubPicProvider
);
95 if(m_pSubPicProviderEx
) {
96 *pSubPicProvider
= m_pSubPicProviderEx
;
97 (*pSubPicProvider
)->AddRef();
100 return !!*pSubPicProvider
? S_OK
: E_FAIL
;
103 STDMETHODIMP
CSubPicQueueImpl::SetFPS(double fps
)
110 STDMETHODIMP
CSubPicQueueImpl::SetTime(REFERENCE_TIME rtNow
)
119 STDMETHODIMP
CSubPicQueueImpl::SetSubPicProvider( IUnknown
* subpic_provider
)
121 CComQIPtr
<ISubPicProviderEx
> tmp
= subpic_provider
;
124 return SetSubPicProviderEx(tmp
);
128 CComQIPtr
<ISubPicProvider
> tmp2
= subpic_provider
;
131 return SetSubPicProvider(tmp
);
137 STDMETHODIMP
CSubPicQueueImpl::GetSubPicProvider( IUnknown
** subpic_provider
)
139 if(!subpic_provider
) {
143 CAutoLock
cAutoLock(&m_csSubPicProvider
);
145 if(m_pSubPicProviderEx
) {
146 *subpic_provider
= m_pSubPicProviderEx
;
147 (*subpic_provider
)->AddRef();
150 return !!*subpic_provider
? S_OK
: E_FAIL
;
155 HRESULT
CSubPicQueueImpl::SetSubPicProviderEx( ISubPicProviderEx
* pSubPicProviderEx
)
157 // if(m_pSubPicProvider != pSubPicProvider)
159 CAutoLock
cAutoLock(&m_csSubPicProvider
);
160 m_pSubPicProviderEx
= pSubPicProviderEx
;
162 if(m_pSubPicProviderEx
!=NULL
&& m_pAllocator
!=NULL
)
164 POSITION pos
= m_prefered_colortype
.GetHeadPosition();
167 int color_type
= m_prefered_colortype
.GetNext(pos
);
168 if( m_pSubPicProviderEx
->IsColorTypeSupported( color_type
) &&
169 m_pAllocator
->IsSpdColorTypeSupported( color_type
) )
171 m_pAllocator
->SetSpdColorType(color_type
);
182 HRESULT
CSubPicQueueImpl::GetSubPicProviderEx( ISubPicProviderEx
** pSubPicProviderEx
)
184 if(!pSubPicProviderEx
) {
188 CAutoLock
cAutoLock(&m_csSubPicProvider
);
190 if(m_pSubPicProviderEx
) {
191 *pSubPicProviderEx
= m_pSubPicProviderEx
;
192 (*pSubPicProviderEx
)->AddRef();
195 return !!*pSubPicProviderEx
? S_OK
: E_FAIL
;
198 HRESULT
CSubPicQueueImpl::RenderTo(ISubPicEx
* pSubPic
, REFERENCE_TIME rtStart
, REFERENCE_TIME rtStop
, double fps
, BOOL bIsAnimated
)
206 CComPtr
<ISubPicProviderEx
> pSubPicProviderEx
;
207 if(FAILED(GetSubPicProviderEx(&pSubPicProviderEx
)) || !pSubPicProviderEx
) {
211 if(FAILED(pSubPicProviderEx
->Lock())) {
216 if(SUCCEEDED(pSubPic
->Lock(spd
)))
218 DWORD color
= 0xFF000000;
219 // if(spd.type == MSP_YUY2 || spd.type == MSP_YV12 || spd.type == MSP_IYUV)
221 // color = 0xFF801080;
222 // //color = 0xFF000000;
224 // else if(spd.type == MSP_AYUV)
226 // color = 0xFF108080;
230 // color = 0xFF000000;
232 if(SUCCEEDED(pSubPic
->ClearDirtyRect(color
)))
234 CAtlList
<CRect
> rectList
;
236 hr
= pSubPicProviderEx
->RenderEx(spd
, bIsAnimated
? rtStart
: ((rtStart
+rtStop
)/2), fps
, rectList
);
238 DbgLog((LOG_TRACE
, 3, "CSubPicQueueImpl::RenderTo => GetStartPosition"));
239 POSITION pos
= pSubPicProviderEx
->GetStartPosition(rtStart
, fps
);
241 DbgLog((LOG_TRACE
, 3, "CSubPicQueueImpl::RenderTo => GetStartStop rtStart:%lu", (ULONG
)rtStart
/10000));
242 pSubPicProviderEx
->GetStartStop(pos
, fps
, rtStart
, rtStop
);
243 DbgLog((LOG_TRACE
, 3, "rtStart:%lu", (ULONG
)rtStart
/10000));
245 //DbgLog((LOG_TRACE, 3, TEXT("rtStart=%lu rtStop=%lu pos:%x fps:%f"), (ULONG)rtStart/10000, (ULONG)rtStop/10000, pos, fps));
247 pSubPic
->SetStart(rtStart
);
248 pSubPic
->SetStop(rtStop
);
250 pSubPic
->Unlock(&rectList
);
254 pSubPicProviderEx
->Unlock();
263 CSubPicQueue::CSubPicQueue(int nMaxSubPic
, BOOL bDisableAnim
, ISubPicExAllocator
* pAllocator
, HRESULT
* phr
)
264 : CSubPicQueueImpl(pAllocator
, phr
)
265 , m_nMaxSubPic(nMaxSubPic
)
266 , m_bDisableAnim(bDisableAnim
)
270 DbgLog((LOG_TRACE
, 3, "CSubPicQueue::CSubPicQueue"));
271 //Trace(_T("SubPicQueue constructing\n"));
273 if(phr
&& FAILED(*phr
))
277 {if(phr
) *phr
= E_INVALIDARG
; return;}
279 m_fBreakBuffering
= false;
280 for(int i
= 0; i
< EVENT_COUNT
; i
++)
281 m_ThreadEvents
[i
] = CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
282 for(int i
=0;i
<QueueEvents_COUNT
; i
++)
283 m_QueueEvents
[i
] = CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
286 SetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
295 CSubPicQueue::~CSubPicQueue()
297 m_fBreakBuffering
= true;
298 //SetEvent(m_ThreadEvents[EVENT_EXIT]);
299 CAMThread::CallWorker(EVENT_EXIT
);
301 for(int i
=0;i
<QueueEvents_COUNT
; i
++)
302 CloseHandle(m_QueueEvents
[i
]);
303 for(int i
= 0; i
< EVENT_COUNT
; i
++)
304 CloseHandle(m_ThreadEvents
[i
]);
305 DbgLog((LOG_TRACE
, 3, "CSubPicQueue::~CSubPicQueue"));
311 STDMETHODIMP
CSubPicQueue::SetFPS(double fps
)
313 HRESULT hr
= __super::SetFPS(fps
);
314 if(FAILED(hr
)) return hr
;
316 //SetEvent(m_ThreadEvents[EVENT_TIME]);
317 //CallWorker(EVENT_TIME);
323 STDMETHODIMP
CSubPicQueue::SetTime(REFERENCE_TIME rtNow
)
325 HRESULT hr
= __super::SetTime(rtNow
);
326 if(FAILED(hr
)) return hr
;
328 //SetEvent(m_ThreadEvents[EVENT_TIME]);
329 //DbgLog((LOG_LOCKING, 3, "SetTime::CallWorker(EVENT_TIME)"));
330 //CallWorker(EVENT_TIME);
336 STDMETHODIMP
CSubPicQueue::Invalidate(REFERENCE_TIME rtInvalidate
)
339 // CAutoLock cQueueLock(&m_csQueueLock);
342 m_rtInvalidate
= rtInvalidate
;
343 m_fBreakBuffering
= true;
350 STDMETHODIMP_(bool) CSubPicQueue::LookupSubPic(REFERENCE_TIME rtNow
, ISubPic
** ppSubPic
)
352 CComPtr
<ISubPicProvider
> pSubPicProvider
;
355 //if(SUCCEEDED(GetSubPicProvider(&pSubPicProvider)) && pSubPicProvider)
357 // if(pSubPicProvider->GetStartPosition(rtNow, fps))
359 CAutoLock
cQueueLock(&m_csQueueLock
);
360 int count
= m_Queue
.GetCount();
362 if(WaitForSingleObject(m_QueueEvents
[QueueEvents_NOTEMPTY
], CSUBPICQUEUE_LOOKUP_WAIT_TIMEOUT
)==WAIT_OBJECT_0
)
364 POSITION pos
= m_Queue
.GetHeadPosition();
367 CComPtr
<ISubPic
> pSubPic
= m_Queue
.GetNext(pos
);
368 //DbgLog((LOG_TRACE, 3, "picStart:%lu picStop:%lu rtNow:%lu", (ULONG)pSubPic->GetStart()/10000, (ULONG)pSubPic->GetStop()/10000, (ULONG)rtNow/10000));
369 if(pSubPic
->GetStart() > rtNow
)
371 else if(rtNow
< pSubPic
->GetStop())
373 *ppSubPic
= pSubPic
.Detach();
377 int count
= m_Queue
.GetCount();
379 SetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
381 ResetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
382 if(count
<m_nMaxSubPic
)
383 SetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
385 ResetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
387 //DbgLog((LOG_TRACE, 3, "CSubPicQueue LookupSubPic return"));
395 STDMETHODIMP_(bool) CSubPicQueue::LookupSubPic( REFERENCE_TIME now
/*[in]*/, ISimpleSubPic
** output_subpic
/*[out]*/ )
401 STDMETHODIMP
CSubPicQueue::GetStats(int& nSubPics
, REFERENCE_TIME
& rtNow
, REFERENCE_TIME
& rtStart
, REFERENCE_TIME
& rtStop
)
403 CAutoLock
cQueueLock(&m_csQueueLock
);
405 nSubPics
= m_Queue
.GetCount();
407 rtStart
= m_rtQueueStart
;
408 rtStop
= m_Queue
.GetCount() > 0 ? m_Queue
.GetTail()->GetStop() : rtStart
;
413 STDMETHODIMP
CSubPicQueue::GetStats(int nSubPic
, REFERENCE_TIME
& rtStart
, REFERENCE_TIME
& rtStop
)
415 CAutoLock
cQueueLock(&m_csQueueLock
);
417 rtStart
= rtStop
= -1;
419 if(nSubPic
>= 0 && nSubPic
< (int)m_Queue
.GetCount())
421 if(POSITION pos
= m_Queue
.FindIndex(nSubPic
))
423 rtStart
= m_Queue
.GetAt(pos
)->GetStart();
424 rtStop
= m_Queue
.GetAt(pos
)->GetStop();
437 REFERENCE_TIME
CSubPicQueue::UpdateQueue()
439 //DbgLog((LOG_TRACE, 3, "CSubPicQueue UpdateQueue"));
440 REFERENCE_TIME rtNow
=0;
443 //if(WaitForMultipleObjects(QueueEvents_COUNT, m_QueueEvents, true, CSUBPICQUEUE_UPDATEQUEUE_WAIT_TIMEOUT))
445 CAutoLock
cQueueLock(&m_csQueueLock
);
447 int count
= m_Queue
.GetCount();
448 if(rtNow
< m_rtQueueStart
)
455 while(count
>0 && rtNow
>= m_Queue
.GetHead()->GetStop())
457 m_Queue
.RemoveHead();
462 rtNow
= m_Queue
.GetTail()->GetStop();
463 m_rtQueueStart
= m_rtNow
;
465 SetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
467 ResetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
468 if(count
<m_nMaxSubPic
)
469 SetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
471 ResetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
476 int CSubPicQueue::GetQueueCount()
478 CAutoLock
cQueueLock(&m_csQueueLock
);
480 return m_Queue
.GetCount();
482 void CSubPicQueue::AppendQueue(ISubPic
* pSubPic
)
484 CAutoLock
cQueueLock(&m_csQueueLock
);
486 m_Queue
.AddTail(pSubPic
);
491 DWORD
CSubPicQueue::ThreadProc()
493 BOOL bDisableAnim
= m_bDisableAnim
;
494 SetThreadPriority(m_hThread
, bDisableAnim
? THREAD_PRIORITY_LOWEST
: THREAD_PRIORITY_ABOVE_NORMAL
/*THREAD_PRIORITY_BELOW_NORMAL*/);
496 //Trace(_T("CSubPicQueue Thread Start\n"));
497 DbgLog((LOG_TRACE
, 3, "CSubPicQueue Thread Start"));
498 //while((WaitForMultipleObjects(EVENT_COUNT, m_ThreadEvents, FALSE, INFINITE) - WAIT_OBJECT_0) == EVENT_TIME)
502 if(CheckRequest(&request
))
504 if(request
==EVENT_EXIT
)
508 if(WaitForSingleObject(m_QueueEvents
[QueueEvents_NOTFULL
], CSUBPICQUEUE_THREAD_PROC_WAIT_TIMEOUT
)!=WAIT_OBJECT_0
)
512 bool reachEnd
= false;
513 CComPtr
<ISubPicEx
> pSubPic
;
514 CComPtr
<ISubPicEx
> pStatic
;
515 CComPtr
<ISubPicProviderEx
> pSubPicProviderEx
;
518 int nMaxSubPic
= m_nMaxSubPic
;
520 m_csQueueLock
.Lock();
521 REFERENCE_TIME rtNow
= 0;
522 if(m_Queue
.GetCount()>0)
523 rtNow
= m_Queue
.GetTail()->GetStop();
526 CComPtr
<ISubPicExAllocator
> pAllocator
= m_pAllocator
;
527 m_csQueueLock
.Unlock();
529 //for(int i=0;i<1;i++)
531 if(FAILED(pAllocator
->AllocDynamicEx(&pSubPic
))
532 || (pAllocator
->IsDynamicWriteOnly() && FAILED(pAllocator
->GetStaticEx(&pStatic
))))
535 if(SUCCEEDED(GetSubPicProviderEx(&pSubPicProviderEx
)) && pSubPicProviderEx
536 && SUCCEEDED(pSubPicProviderEx
->Lock()))
538 REFERENCE_TIME rtStart
, rtStop
;
540 //DbgLog((LOG_TRACE, 3, "CSubPicQueue::ThreadProc => GetStartPosition"));
541 POSITION pos
= pSubPicProviderEx
->GetStartPosition(rtNow
, fps
);
543 //DbgLog((LOG_TRACE, 3, "pos:%x, m_fBreakBuffering:%d GetCount():%d nMaxSubPic:%d", pos, m_fBreakBuffering, GetCount(), nMaxSubPic));
545 if(pos
!=NULL
)//!m_fBreakBuffering
548 ASSERT(m_Queue
.GetCount() < (size_t)nMaxSubPic
);
550 //DbgLog((LOG_TRACE, 3, "CSubPicQueue::ThreadProc => GetStartStop"));
551 pSubPicProviderEx
->GetStartStop(pos
, fps
, rtStart
, rtStop
);
553 //DbgLog((LOG_TRACE, 3, "rtStart=%lu rtStop=%lu fps=%f rtNow=%lu m_rtNow=%lu", (ULONG)rtStart/10000, (ULONG)rtStop/10000,
554 // fps, (ULONG)rtNow/10000, (ULONG)m_rtNow/10000));
556 if(m_rtNow
>= rtStop
)
558 //if(rtStart >= m_rtNow + 60*10000000i64) // we are already one minute ahead, this should be enough
563 bool bIsAnimated
= pSubPicProviderEx
->IsAnimated(pos
) && !bDisableAnim
;
564 if(pAllocator
->IsDynamicWriteOnly())
567 HRESULT hr
= RenderTo(pStatic
, rtStart
, rtStop
, fps
, bIsAnimated
);
569 || S_OK
!= hr
// subpic was probably empty
570 || FAILED(pStatic
->CopyTo(pSubPic
))
576 HRESULT hr
= RenderTo(pSubPic
, rtStart
, rtStop
, fps
, bIsAnimated
);
578 || S_OK
!= hr
// subpic was probably empty
582 /*DbgLog((LOG_TRACE, 3, "picStart:%lu picStop:%lu seg:%d idx:%d pos:%x",
583 (ULONG)pSubPic->GetStart()/10000,
584 (ULONG)pSubPic->GetStop()/10000,
585 (int)pos >> 16, (int)pos & ((1<<16)-1)));*/
591 pSubPicProviderEx
->Unlock();
592 pSubPicProviderEx
= NULL
;
596 m_csQueueLock
.Lock();
598 m_Queue
.AddTail(pSubPic
);
599 int count
= m_Queue
.GetCount();
601 SetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
603 ResetEvent(m_QueueEvents
[QueueEvents_NOTEMPTY
]);
604 if(count
<m_nMaxSubPic
)
605 SetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
607 ResetEvent(m_QueueEvents
[QueueEvents_NOTFULL
]);
608 m_csQueueLock
.Unlock();
611 Sleep(CSUBPICQUEUE_THREAD_PROC_WAIT_TIMEOUT
);
615 // if(pSubPicProvider!=NULL)
616 // pSubPicProvider->Unlock();
617 // ReleaseSemaphore(m_semNotFull, 1, NULL);
620 // ReleaseSemaphore(m_semNotEmpty, 1, NULL);
622 //DbgLog((LOG_LOCKING, 3, "ReleaseMutex m_mtxResetNotFull"));
623 //ReleaseMutex(m_mtxResetNotFull);
626 //Trace(_T("CSubPicQueue Thread Return\n"));
627 DbgLog((LOG_TRACE
, 3, "CSubPicQueue Thread Return"));
633 // CSubPicQueueNoThread
636 CSubPicQueueNoThread::CSubPicQueueNoThread(ISubPicExAllocator
* pAllocator
, HRESULT
* phr
, const int *prefered_colortype
/*=NULL*/, int prefered_colortype_num
/*=0*/)
637 : CSubPicQueueImpl(pAllocator
, phr
, prefered_colortype
, prefered_colortype_num
)
641 CSubPicQueueNoThread::~CSubPicQueueNoThread()
647 STDMETHODIMP
CSubPicQueueNoThread::Invalidate(REFERENCE_TIME rtInvalidate
)
649 CAutoLock
cQueueLock(&m_csLock
);
651 if( m_pSubPic
&& m_pSubPic
->GetStop() >= rtInvalidate
)
658 STDMETHODIMP_(bool) CSubPicQueueNoThread::LookupSubPic(REFERENCE_TIME rtNow
, ISubPic
** ppSubPic
)
663 bool result
= LookupSubPicEx(rtNow
, &temp
);
669 return LookupSubPicEx(rtNow
, NULL
);
673 STDMETHODIMP_(bool) CSubPicQueueNoThread::LookupSubPic( REFERENCE_TIME now
/*[in]*/, ISimpleSubPic
** output_subpic
/*[out]*/ )
675 if(output_subpic
!=NULL
)
677 CComPtr
<ISubPicEx
> temp
;
678 bool result
= LookupSubPicEx(now
, &temp
);
679 (*output_subpic
= new SimpleSubPicWrapper(temp
))->AddRef();
684 return LookupSubPicEx(now
, NULL
);
689 bool CSubPicQueueNoThread::LookupSubPicEx(REFERENCE_TIME rtNow
, ISubPicEx
** ppSubPic
)
696 CComPtr
<ISubPicEx
> pSubPic
;
699 CAutoLock
cAutoLock(&m_csLock
);
703 if(FAILED(m_pAllocator
->AllocDynamicEx(&m_pSubPic
))) {
711 if(pSubPic
->GetStart() <= rtNow
&& rtNow
< pSubPic
->GetStop())
713 (*ppSubPic
= pSubPic
)->AddRef();
717 CComPtr
<ISubPicProvider
> pSubPicProvider
;
718 if(SUCCEEDED(GetSubPicProvider(&pSubPicProvider
)) && pSubPicProvider
719 && SUCCEEDED(pSubPicProvider
->Lock()))
723 if(POSITION pos
= pSubPicProvider
->GetStartPosition(rtNow
, fps
))
725 REFERENCE_TIME rtStart
= pSubPicProvider
->GetStart(pos
, fps
);
726 REFERENCE_TIME rtStop
= pSubPicProvider
->GetStop(pos
, fps
);
728 if(rtStart
<= rtNow
&& rtNow
< rtStop
)
730 SIZE MaxTextureSize
, VirtualSize
;
731 POINT VirtualTopLeft
;
733 if (SUCCEEDED (hr2
= pSubPicProvider
->GetTextureSize(pos
, MaxTextureSize
, VirtualSize
, VirtualTopLeft
))) {
734 m_pAllocator
->SetMaxTextureSize(MaxTextureSize
);
736 if(m_pAllocator
->IsDynamicWriteOnly())
738 CComPtr
<ISubPicEx
> pStatic
;
739 if(SUCCEEDED(m_pAllocator
->GetStaticEx(&pStatic
))
740 && SUCCEEDED(RenderTo(pStatic
, rtNow
, rtNow
+1, fps
, true))
741 && SUCCEEDED(pStatic
->CopyTo(pSubPic
)))
742 (*ppSubPic
= pSubPic
)->AddRef();
746 if(SUCCEEDED(RenderTo(m_pSubPic
, rtNow
, rtNow
+1, fps
, true)))
747 (*ppSubPic
= pSubPic
)->AddRef();
752 pSubPicProvider
->Unlock();
756 CAutoLock
cAutoLock(&m_csLock
);
758 m_pSubPic
= *ppSubPic
;
765 STDMETHODIMP
CSubPicQueueNoThread::GetStats(int& nSubPics
, REFERENCE_TIME
& rtNow
, REFERENCE_TIME
& rtStart
, REFERENCE_TIME
& rtStop
)
767 CAutoLock
cAutoLock(&m_csLock
);
771 rtStart
= rtStop
= 0;
776 rtStart
= m_pSubPic
->GetStart();
777 rtStop
= m_pSubPic
->GetStop();
783 STDMETHODIMP
CSubPicQueueNoThread::GetStats(int nSubPic
, REFERENCE_TIME
& rtStart
, REFERENCE_TIME
& rtStop
)
785 CAutoLock
cAutoLock(&m_csLock
);
787 if(!m_pSubPic
|| nSubPic
!= 0)
790 rtStart
= m_pSubPic
->GetStart();
791 rtStop
= m_pSubPic
->GetStop();