Esempio n. 1
0
void DirectShowSampleScheduler::setFlushing(bool flushing)
{
    QMutexLocker locker(&m_mutex);

    const bool isFlushing = m_state & Flushing;

    if (isFlushing != flushing) {
        if (flushing) {
            m_state |= Flushing;

            for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) {
                sample->unschedule(m_clock);

                m_semaphore.release(1);
            }
            m_head = 0;
            m_tail = 0;

            ::SetEvent(m_flushEvent);
        } else {
            m_state &= ~Flushing;

            if (m_state != Stopped)
                ::ResetEvent(m_flushEvent);
        }
    }
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
void DirectShowSampleScheduler::pause()
{
    QMutexLocker locker(&m_mutex);

    m_state = (m_state & Flushing) | Paused;

    for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample())
        sample->unschedule(m_clock);
}
Esempio n. 4
0
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);
    }
}
Esempio n. 5
0
void DirectShowSampleScheduler::stop()
{
    QMutexLocker locker(&m_mutex);

    m_state = m_state & Flushing;

    for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) {
        sample->unschedule(m_clock);
        
        m_semaphore.release(1);
    }

    m_head = 0;
    m_tail = 0;
}
Esempio n. 6
0
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;
    }
}