HRESULT DirectShowSampleScheduler::Receive(IMediaSample *pSample) { if (!pSample) return E_POINTER; m_semaphore.acquire(1); QMutexLocker locker(&m_mutex); if (m_state & Flushing) { m_semaphore.release(1); return S_FALSE; } else if (m_state == Stopped) { m_semaphore.release(); return VFW_E_WRONG_STATE; } else { DirectShowTimedSample *timedSample = new DirectShowTimedSample(pSample); if (m_tail) m_tail->setNextSample(timedSample); else m_head = timedSample; m_tail = timedSample; if (m_state == Running) { if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) { // Timing information is unavailable, so schedule frames immediately. QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); } else { locker.unlock(); HANDLE handles[] = { m_flushEvent, m_timeoutEvent }; DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE); locker.relock(); if (result == WAIT_OBJECT_0 + 1) QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); } } else if (m_tail == m_head) { // If this is the first frame make it available. QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); if (m_state == Paused) { ::ResetEvent(m_timeoutEvent); locker.unlock(); HANDLE handles[] = { m_flushEvent, m_timeoutEvent }; ::WaitForMultipleObjects(2, handles, FALSE, INFINITE); locker.relock(); } } return S_OK; } }
void DirectShowSampleScheduler::run(REFERENCE_TIME startTime) { QMutexLocker locker(&m_mutex); m_state = (m_state & Flushing) | Running; m_startTime = startTime; for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) { sample->schedule(m_clock, m_startTime, m_timeoutEvent); } }
HRESULT DirectShowSampleScheduler::Receive(IMediaSample *pSample) { if (!pSample) return E_POINTER; m_semaphore.acquire(1); QMutexLocker locker(&m_mutex); if (m_state & Flushing) { m_semaphore.release(1); return S_FALSE; } else if (m_state == Stopped) { m_semaphore.release(); return VFW_E_WRONG_STATE; } else { DirectShowTimedSample *timedSample = new DirectShowTimedSample(pSample); if (m_tail) m_tail->setNextSample(timedSample); else m_head = timedSample; m_tail = timedSample; if (m_state == Running) { if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) { // Timing information is unavailable, so schedule frames immediately. QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection); } } else if (m_tail == m_head) { // If this is the first frame make is available. QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection); } return S_OK; } }