qtmobility/plugins/multimedia/directshow/player/directshowsamplescheduler.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "directshowsamplescheduler.h"
    42 #include "directshowsamplescheduler.h"
    43 
    43 
       
    44 #include <QtCore/qcoreapplication.h>
    44 #include <QtCore/qcoreevent.h>
    45 #include <QtCore/qcoreevent.h>
    45 
    46 
    46 class DirectShowTimedSample
    47 class DirectShowTimedSample
    47 {
    48 {
    48 public:
    49 public:
   113     }
   114     }
   114     return true;
   115     return true;
   115 }
   116 }
   116 
   117 
   117 DirectShowSampleScheduler::DirectShowSampleScheduler(IUnknown *pin, QObject *parent)
   118 DirectShowSampleScheduler::DirectShowSampleScheduler(IUnknown *pin, QObject *parent)
   118     : QWinEventNotifier(parent)
   119     : QObject(parent)
   119     , m_pin(pin)
   120     , m_pin(pin)
   120     , m_clock(0)
   121     , m_clock(0)
   121     , m_allocator(0)
   122     , m_allocator(0)
   122     , m_head(0)
   123     , m_head(0)
   123     , m_tail(0)
   124     , m_tail(0)
   124     , m_maximumSamples(2)
   125     , m_maximumSamples(1)
   125     , m_state(Stopped)
   126     , m_state(Stopped)
   126     , m_startTime(0)
   127     , m_startTime(0)
   127     , m_timeoutEvent(::CreateEvent(0, 0, 0, 0))
   128     , m_timeoutEvent(::CreateEvent(0, 0, 0, 0))
       
   129     , m_flushEvent(::CreateEvent(0, 0, 0, 0))
   128 {
   130 {
   129     m_semaphore.release(m_maximumSamples);
   131     m_semaphore.release(m_maximumSamples);
   130 
       
   131     setHandle(m_timeoutEvent);
       
   132     setEnabled(true);
       
   133 }
   132 }
   134 
   133 
   135 DirectShowSampleScheduler::~DirectShowSampleScheduler()
   134 DirectShowSampleScheduler::~DirectShowSampleScheduler()
   136 {
   135 {
   137     setEnabled(false);
       
   138 
       
   139     ::CloseHandle(m_timeoutEvent);
   136     ::CloseHandle(m_timeoutEvent);
       
   137     ::CloseHandle(m_flushEvent);
   140 
   138 
   141     Q_ASSERT(!m_clock);
   139     Q_ASSERT(!m_clock);
   142     Q_ASSERT(!m_allocator);
   140     Q_ASSERT(!m_allocator);
   143 }
   141 }
   144 
   142 
   250         m_tail = timedSample;
   248         m_tail = timedSample;
   251 
   249 
   252         if (m_state == Running) {
   250         if (m_state == Running) {
   253             if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) {
   251             if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) {
   254                 // Timing information is unavailable, so schedule frames immediately.
   252                 // Timing information is unavailable, so schedule frames immediately.
   255                 QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection);
   253                 QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
       
   254             } else {
       
   255                 locker.unlock();
       
   256                 HANDLE handles[] = { m_flushEvent, m_timeoutEvent };
       
   257                 DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
       
   258                 locker.relock();
       
   259 
       
   260                 if (result == WAIT_OBJECT_0 + 1)
       
   261                     QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
   256             }
   262             }
   257         } else if (m_tail == m_head) {
   263         } else if (m_tail == m_head) {
   258             // If this is the first frame make is available.
   264             // If this is the first frame make it available.
   259             QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection);
   265             QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
       
   266 
       
   267             if (m_state == Paused) {
       
   268                 ::ResetEvent(m_timeoutEvent);
       
   269 
       
   270                 locker.unlock();
       
   271                 HANDLE handles[] = { m_flushEvent, m_timeoutEvent };
       
   272                 ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
       
   273                 locker.relock();
       
   274             }
   260         }
   275         }
   261 
   276 
   262         return S_OK;
   277         return S_OK;
   263     }
   278     }
   264 }
   279 }
   291     m_startTime = startTime;
   306     m_startTime = startTime;
   292 
   307 
   293     for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) {
   308     for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) {
   294         sample->schedule(m_clock, m_startTime, m_timeoutEvent);
   309         sample->schedule(m_clock, m_startTime, m_timeoutEvent);
   295     }
   310     }
       
   311     
       
   312     if (!(m_state & Flushing))
       
   313         ::ResetEvent(m_flushEvent);
       
   314     
       
   315     if (!m_head)
       
   316         ::SetEvent(m_timeoutEvent);
       
   317 
   296 }
   318 }
   297 
   319 
   298 void DirectShowSampleScheduler::pause()
   320 void DirectShowSampleScheduler::pause()
   299 {
   321 {
   300     QMutexLocker locker(&m_mutex);
   322     QMutexLocker locker(&m_mutex);
   301 
   323 
   302     m_state = (m_state & Flushing) | Paused;
   324     m_state = (m_state & Flushing) | Paused;
   303 
   325 
   304     for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample())
   326     for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample())
   305         sample->unschedule(m_clock);
   327         sample->unschedule(m_clock);
       
   328 
       
   329     if (!(m_state & Flushing))
       
   330         ::ResetEvent(m_flushEvent);
   306 }
   331 }
   307 
   332 
   308 void DirectShowSampleScheduler::stop()
   333 void DirectShowSampleScheduler::stop()
   309 {
   334 {
   310     QMutexLocker locker(&m_mutex);
   335     QMutexLocker locker(&m_mutex);
   317         m_semaphore.release(1);
   342         m_semaphore.release(1);
   318     }
   343     }
   319 
   344 
   320     m_head = 0;
   345     m_head = 0;
   321     m_tail = 0;
   346     m_tail = 0;
       
   347 
       
   348     ::SetEvent(m_flushEvent);
   322 }
   349 }
   323 
   350 
   324 void DirectShowSampleScheduler::setFlushing(bool flushing)
   351 void DirectShowSampleScheduler::setFlushing(bool flushing)
   325 {
   352 {
   326     QMutexLocker locker(&m_mutex);
   353     QMutexLocker locker(&m_mutex);
   336 
   363 
   337                 m_semaphore.release(1);
   364                 m_semaphore.release(1);
   338             }
   365             }
   339             m_head = 0;
   366             m_head = 0;
   340             m_tail = 0;
   367             m_tail = 0;
       
   368 
       
   369             ::SetEvent(m_flushEvent);
   341         } else {
   370         } else {
   342             m_state &= ~Flushing;
   371             m_state &= ~Flushing;
       
   372 
       
   373             if (m_state != Stopped)
       
   374                 ::ResetEvent(m_flushEvent);
   343         }
   375         }
   344     }
   376     }
   345 }
   377 }
   346 
   378 
   347 void DirectShowSampleScheduler::setClock(IReferenceClock *clock)
   379 void DirectShowSampleScheduler::setClock(IReferenceClock *clock)
   363 
   395 
   364     if (m_head && m_head->isReady(m_clock)) {
   396     if (m_head && m_head->isReady(m_clock)) {
   365         IMediaSample *sample = m_head->sample();
   397         IMediaSample *sample = m_head->sample();
   366         sample->AddRef();
   398         sample->AddRef();
   367 
   399 
   368         if (m_state == Running) {
   400         *eos =  m_head->isLast();
   369             *eos =  m_head->isLast();
   401 
   370 
   402         m_head = m_head->remove();
   371             m_head = m_head->remove();
   403 
   372 
   404         if (!m_head)
   373             if (!m_head)
   405             m_tail = 0;
   374                 m_tail = 0;
   406 
   375 
   407         m_semaphore.release(1);
   376             m_semaphore.release(1);
       
   377         }
       
   378 
   408 
   379         return sample;
   409         return sample;
   380     } else {
   410     } else {
   381         return 0;
   411         return 0;
   382     }
   412     }
   395     }
   425     }
   396 }
   426 }
   397 
   427 
   398 bool DirectShowSampleScheduler::event(QEvent *event)
   428 bool DirectShowSampleScheduler::event(QEvent *event)
   399 {
   429 {
   400     if (event->type() == QEvent::WinEventAct) {
   430     if (event->type() == QEvent::UpdateRequest) {
   401         QObject::event(event);
       
   402 
       
   403         emit sampleReady();
   431         emit sampleReady();
   404 
   432 
   405         return true;
   433         return true;
   406     } else {
   434     } else {
   407         return QWinEventNotifier::event(event);
   435         return QObject::event(event);
   408     }
   436     }
   409 }
   437 }