Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/sanear.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dll/src/baseclasses/strmctl.cpp')
-rw-r--r--dll/src/baseclasses/strmctl.cpp402
1 files changed, 0 insertions, 402 deletions
diff --git a/dll/src/baseclasses/strmctl.cpp b/dll/src/baseclasses/strmctl.cpp
deleted file mode 100644
index b7f5952..0000000
--- a/dll/src/baseclasses/strmctl.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-//------------------------------------------------------------------------------
-// File: StrmCtl.cpp
-//
-// Desc: DirectShow base classes.
-//
-// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-#include <streams.h>
-#include <strmctl.h>
-
-CBaseStreamControl::CBaseStreamControl(__inout HRESULT *phr)
-: m_StreamState(STREAM_FLOWING)
-, m_StreamStateOnStop(STREAM_FLOWING) // means no pending stop
-, m_tStartTime(MAX_TIME)
-, m_tStopTime(MAX_TIME)
-, m_StreamEvent(FALSE, phr)
-, m_dwStartCookie(0)
-, m_dwStopCookie(0)
-, m_pRefClock(NULL)
-, m_FilterState(State_Stopped)
-, m_bIsFlushing(FALSE)
-, m_bStopSendExtra(FALSE)
-{}
-
-CBaseStreamControl::~CBaseStreamControl()
-{
- // Make sure we release the clock.
- SetSyncSource(NULL);
- return;
-}
-
-
-STDMETHODIMP CBaseStreamControl::StopAt(const REFERENCE_TIME * ptStop, BOOL bSendExtra, DWORD dwCookie)
-{
- CAutoLock lck(&m_CritSec);
- m_bStopSendExtra = FALSE; // reset
- m_bStopExtraSent = FALSE;
- if (ptStop)
- {
- if (*ptStop == MAX_TIME)
- {
- DbgLog((LOG_TRACE,2,TEXT("StopAt: Cancel stop")));
- CancelStop();
- // If there's now a command to start in the future, we assume
- // they want to be stopped when the graph is first run
- if (m_FilterState == State_Stopped && m_tStartTime < MAX_TIME) {
- m_StreamState = STREAM_DISCARDING;
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING")));
- }
- return NOERROR;
- }
- DbgLog((LOG_TRACE,2,TEXT("StopAt: %dms extra=%d"),
- (int)(*ptStop/10000), bSendExtra));
- // if the first command is to stop in the future, then we assume they
- // want to be started when the graph is first run
- if (m_FilterState == State_Stopped && m_tStartTime > *ptStop) {
- m_StreamState = STREAM_FLOWING;
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING")));
- }
- m_bStopSendExtra = bSendExtra;
- m_tStopTime = *ptStop;
- m_dwStopCookie = dwCookie;
- m_StreamStateOnStop = STREAM_DISCARDING;
- }
- else
- {
- DbgLog((LOG_TRACE,2,TEXT("StopAt: now")));
- // sending an extra frame when told to stop now would mess people up
- m_bStopSendExtra = FALSE;
- m_tStopTime = MAX_TIME;
- m_dwStopCookie = 0;
- m_StreamState = STREAM_DISCARDING;
- m_StreamStateOnStop = STREAM_FLOWING; // no pending stop
- }
- // we might change our mind what to do with a sample we're blocking
- m_StreamEvent.Set();
- return NOERROR;
-}
-
-STDMETHODIMP CBaseStreamControl::StartAt
-( const REFERENCE_TIME *ptStart, DWORD dwCookie )
-{
- CAutoLock lck(&m_CritSec);
- if (ptStart)
- {
- if (*ptStart == MAX_TIME)
- {
- DbgLog((LOG_TRACE,2,TEXT("StartAt: Cancel start")));
- CancelStart();
- // If there's now a command to stop in the future, we assume
- // they want to be started when the graph is first run
- if (m_FilterState == State_Stopped && m_tStopTime < MAX_TIME) {
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING")));
- m_StreamState = STREAM_FLOWING;
- }
- return NOERROR;
- }
- DbgLog((LOG_TRACE,2,TEXT("StartAt: %dms"), (int)(*ptStart/10000)));
- // if the first command is to start in the future, then we assume they
- // want to be stopped when the graph is first run
- if (m_FilterState == State_Stopped && m_tStopTime >= *ptStart) {
- DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING")));
- m_StreamState = STREAM_DISCARDING;
- }
- m_tStartTime = *ptStart;
- m_dwStartCookie = dwCookie;
- // if (m_tStopTime == m_tStartTime) CancelStop();
- }
- else
- {
- DbgLog((LOG_TRACE,2,TEXT("StartAt: now")));
- m_tStartTime = MAX_TIME;
- m_dwStartCookie = 0;
- m_StreamState = STREAM_FLOWING;
- }
- // we might change our mind what to do with a sample we're blocking
- m_StreamEvent.Set();
- return NOERROR;
-}
-
-// Retrieve information about current settings
-STDMETHODIMP CBaseStreamControl::GetInfo(__out AM_STREAM_INFO *pInfo)
-{
- if (pInfo == NULL)
- return E_POINTER;
-
- pInfo->tStart = m_tStartTime;
- pInfo->tStop = m_tStopTime;
- pInfo->dwStartCookie = m_dwStartCookie;
- pInfo->dwStopCookie = m_dwStopCookie;
- pInfo->dwFlags = m_bStopSendExtra ? AM_STREAM_INFO_STOP_SEND_EXTRA : 0;
- pInfo->dwFlags |= m_tStartTime == MAX_TIME ? 0 : AM_STREAM_INFO_START_DEFINED;
- pInfo->dwFlags |= m_tStopTime == MAX_TIME ? 0 : AM_STREAM_INFO_STOP_DEFINED;
- switch (m_StreamState) {
- default:
- DbgBreak("Invalid stream state");
- case STREAM_FLOWING:
- break;
- case STREAM_DISCARDING:
- pInfo->dwFlags |= AM_STREAM_INFO_DISCARDING;
- break;
- }
- return S_OK;
-}
-
-
-void CBaseStreamControl::ExecuteStop()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_StreamState = m_StreamStateOnStop;
- if (m_dwStopCookie && m_pSink) {
- DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STOPPED (%d)"),
- m_dwStopCookie));
- m_pSink->Notify(EC_STREAM_CONTROL_STOPPED, (LONG_PTR)this, m_dwStopCookie);
- }
- CancelStop(); // This will do the tidy up
-}
-
-void CBaseStreamControl::ExecuteStart()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_StreamState = STREAM_FLOWING;
- if (m_dwStartCookie) {
- DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STARTED (%d)"),
- m_dwStartCookie));
- m_pSink->Notify(EC_STREAM_CONTROL_STARTED, (LONG_PTR)this, m_dwStartCookie);
- }
- CancelStart(); // This will do the tidy up
-}
-
-void CBaseStreamControl::CancelStop()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_tStopTime = MAX_TIME;
- m_dwStopCookie = 0;
- m_StreamStateOnStop = STREAM_FLOWING;
-}
-
-void CBaseStreamControl::CancelStart()
-{
- ASSERT(CritCheckIn(&m_CritSec));
- m_tStartTime = MAX_TIME;
- m_dwStartCookie = 0;
-}
-
-
-// This guy will return one of the three StreamControlState's. Here's what the caller
-// should do for each one:
-//
-// STREAM_FLOWING: Proceed as usual (render or pass the sample on)
-// STREAM_DISCARDING: Calculate the time 'til *pSampleStart and wait that long
-// for the event handle (GetStreamEventHandle()). If the
-// wait expires, throw the sample away. If the event
-// fires, call me back, I've changed my mind.
-// I use pSampleStart (not Stop) so that live sources don't
-// block for the duration of their samples, since the clock
-// will always read approximately pSampleStart when called
-
-
-// All through this code, you'll notice the following rules:
-// - When start and stop time are the same, it's as if start was first
-// - An event is considered inside the sample when it's >= sample start time
-// but < sample stop time
-// - if any part of the sample is supposed to be sent, we'll send the whole
-// thing since we don't break it into smaller pieces
-// - If we skip over a start or stop without doing it, we still signal the event
-// and reset ourselves in case somebody's waiting for the event, and to make
-// sure we notice that the event is past and should be forgotten
-// Here are the 19 cases that have to be handled (x=start o=stop <-->=sample):
-//
-// 1. xo<--> start then stop
-// 2. ox<--> stop then start
-// 3. x<o-> start
-// 4. o<x-> stop then start
-// 5. x<-->o start
-// 6. o<-->x stop
-// 7. <x->o start
-// 8. <o->x no change
-// 9. <xo> start
-// 10. <ox> stop then start
-// 11. <-->xo no change
-// 12. <-->ox no change
-// 13. x<--> start
-// 14. <x-> start
-// 15. <-->x no change
-// 16. o<--> stop
-// 17. <o-> no change
-// 18. <-->o no change
-// 19. <--> no change
-
-
-enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckSampleTimes
-( __in const REFERENCE_TIME * pSampleStart, __in const REFERENCE_TIME * pSampleStop )
-{
- CAutoLock lck(&m_CritSec);
-
- ASSERT(!m_bIsFlushing);
- ASSERT(pSampleStart && pSampleStop);
-
- // Don't ask me how I came up with the code below to handle all 19 cases
- // - DannyMi
-
- if (m_tStopTime >= *pSampleStart)
- {
- if (m_tStartTime >= *pSampleStop)
- return m_StreamState; // cases 8 11 12 15 17 18 19
- if (m_tStopTime < m_tStartTime)
- ExecuteStop(); // case 10
- ExecuteStart(); // cases 3 5 7 9 13 14
- return m_StreamState;
- }
-
- if (m_tStartTime >= *pSampleStop)
- {
- ExecuteStop(); // cases 6 16
- return m_StreamState;
- }
-
- if (m_tStartTime <= m_tStopTime)
- {
- ExecuteStart();
- ExecuteStop();
- return m_StreamState; // case 1
- }
- else
- {
- ExecuteStop();
- ExecuteStart();
- return m_StreamState; // cases 2 4
- }
-}
-
-
-enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckStreamState( IMediaSample * pSample )
-{
-
- REFERENCE_TIME rtBufferStart, rtBufferStop;
- const BOOL bNoBufferTimes =
- pSample == NULL ||
- FAILED(pSample->GetTime(&rtBufferStart, &rtBufferStop));
-
- StreamControlState state;
- LONG lWait;
-
- do
- {
- // something has to break out of the blocking
- if (m_bIsFlushing || m_FilterState == State_Stopped)
- return STREAM_DISCARDING;
-
- if (bNoBufferTimes) {
- // Can't do anything until we get a time stamp
- state = m_StreamState;
- break;
- } else {
- state = CheckSampleTimes( &rtBufferStart, &rtBufferStop );
- if (state == STREAM_FLOWING)
- break;
-
- // we aren't supposed to send this, but we've been
- // told to send one more than we were supposed to
- // (and the stop isn't still pending and we're streaming)
- if (m_bStopSendExtra && !m_bStopExtraSent &&
- m_tStopTime == MAX_TIME &&
- m_FilterState != State_Stopped) {
- m_bStopExtraSent = TRUE;
- DbgLog((LOG_TRACE,2,TEXT("%d sending an EXTRA frame"),
- m_dwStopCookie));
- state = STREAM_FLOWING;
- break;
- }
- }
-
- // We're in discarding mode
-
- // If we've no clock, discard as fast as we can
- if (!m_pRefClock) {
- break;
-
- // If we're paused, we can't discard in a timely manner because
- // there's no such thing as stream times. We must block until
- // we run or stop, or we'll end up throwing the whole stream away
- // as quickly as possible
- } else if (m_FilterState == State_Paused) {
- lWait = INFINITE;
-
- } else {
- // wait until it's time for the sample until we say "discard"
- // ("discard in a timely fashion")
- REFERENCE_TIME rtNow;
- EXECUTE_ASSERT(SUCCEEDED(m_pRefClock->GetTime(&rtNow)));
- rtNow -= m_tRunStart; // Into relative ref-time
- lWait = LONG((rtBufferStart - rtNow)/10000); // 100ns -> ms
- if (lWait < 10) break; // Not worth waiting - discard early
- }
-
- } while(WaitForSingleObject(GetStreamEventHandle(), lWait) != WAIT_TIMEOUT);
-
- return state;
-}
-
-
-void CBaseStreamControl::NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart )
-{
- CAutoLock lck(&m_CritSec);
-
- // or we will get confused
- if (m_FilterState == new_state)
- return;
-
- switch (new_state)
- {
- case State_Stopped:
-
- DbgLog((LOG_TRACE,2,TEXT("Filter is STOPPED")));
-
- // execute any pending starts and stops in the right order,
- // to make sure all notifications get sent, and we end up
- // in the right state to begin next time (??? why not?)
-
- if (m_tStartTime != MAX_TIME && m_tStopTime == MAX_TIME) {
- ExecuteStart();
- } else if (m_tStopTime != MAX_TIME && m_tStartTime == MAX_TIME) {
- ExecuteStop();
- } else if (m_tStopTime != MAX_TIME && m_tStartTime != MAX_TIME) {
- if (m_tStartTime <= m_tStopTime) {
- ExecuteStart();
- ExecuteStop();
- } else {
- ExecuteStop();
- ExecuteStart();
- }
- }
- // always start off flowing when the graph starts streaming
- // unless told otherwise
- m_StreamState = STREAM_FLOWING;
- m_FilterState = new_state;
- break;
-
- case State_Running:
-
- DbgLog((LOG_TRACE,2,TEXT("Filter is RUNNING")));
-
- m_tRunStart = tStart;
- // fall-through
-
- default: // case State_Paused:
- m_FilterState = new_state;
- }
- // unblock!
- m_StreamEvent.Set();
-}
-
-
-void CBaseStreamControl::Flushing(BOOL bInProgress)
-{
- CAutoLock lck(&m_CritSec);
- m_bIsFlushing = bInProgress;
- m_StreamEvent.Set();
-}