summaryrefslogtreecommitdiff
path: root/third_party/BaseClasses/source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/BaseClasses/source.cpp')
-rw-r--r--third_party/BaseClasses/source.cpp522
1 files changed, 0 insertions, 522 deletions
diff --git a/third_party/BaseClasses/source.cpp b/third_party/BaseClasses/source.cpp
deleted file mode 100644
index ef7795c4..00000000
--- a/third_party/BaseClasses/source.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-//------------------------------------------------------------------------------
-// File: Source.cpp
-//
-// Desc: DirectShow base classes - implements CSource, which is a Quartz
-// source filter 'template.'
-//
-// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------------------------
-
-
-// Locking Strategy.
-//
-// Hold the filter critical section (m_pFilter->pStateLock()) to serialise
-// access to functions. Note that, in general, this lock may be held
-// by a function when the worker thread may want to hold it. Therefore
-// if you wish to access shared state from the worker thread you will
-// need to add another critical section object. The execption is during
-// the threads processing loop, when it is safe to get the filter critical
-// section from within FillBuffer().
-
-#include <streams.h>
-
-
-//
-// CSource::Constructor
-//
-// Initialise the pin count for the filter. The user will create the pins in
-// the derived class.
-CSource::CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
-}
-
-CSource::CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
- UNREFERENCED_PARAMETER(phr);
-}
-
-#ifdef UNICODE
-CSource::CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
-}
-
-CSource::CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr)
- : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
- m_iPins(0),
- m_paStreams(NULL)
-{
- UNREFERENCED_PARAMETER(phr);
-}
-#endif
-
-//
-// CSource::Destructor
-//
-CSource::~CSource()
-{
- /* Free our pins and pin array */
- while (m_iPins != 0) {
- // deleting the pins causes them to be removed from the array...
- delete m_paStreams[m_iPins - 1];
- }
-
- ASSERT(m_paStreams == NULL);
-}
-
-
-//
-// Add a new pin
-//
-HRESULT CSource::AddPin(__in CSourceStream *pStream)
-{
- CAutoLock lock(&m_cStateLock);
-
- /* Allocate space for this pin and the old ones */
- CSourceStream **paStreams = new CSourceStream *[m_iPins + 1];
- if (paStreams == NULL) {
- return E_OUTOFMEMORY;
- }
- if (m_paStreams != NULL) {
- CopyMemory((PVOID)paStreams, (PVOID)m_paStreams,
- m_iPins * sizeof(m_paStreams[0]));
- paStreams[m_iPins] = pStream;
- delete [] m_paStreams;
- }
- m_paStreams = paStreams;
- m_paStreams[m_iPins] = pStream;
- m_iPins++;
- return S_OK;
-}
-
-//
-// Remove a pin - pStream is NOT deleted
-//
-HRESULT CSource::RemovePin(__in CSourceStream *pStream)
-{
- int i;
- for (i = 0; i < m_iPins; i++) {
- if (m_paStreams[i] == pStream) {
- if (m_iPins == 1) {
- delete [] m_paStreams;
- m_paStreams = NULL;
- } else {
- /* no need to reallocate */
- while (++i < m_iPins)
- m_paStreams[i - 1] = m_paStreams[i];
- }
- m_iPins--;
- return S_OK;
- }
- }
- return S_FALSE;
-}
-
-//
-// FindPin
-//
-// Set *ppPin to the IPin* that has the id Id.
-// or to NULL if the Id cannot be matched.
-STDMETHODIMP CSource::FindPin(LPCWSTR Id, __deref_out IPin **ppPin)
-{
- CheckPointer(ppPin,E_POINTER);
- ValidateReadWritePtr(ppPin,sizeof(IPin *));
- // The -1 undoes the +1 in QueryId and ensures that totally invalid
- // strings (for which WstrToInt delivers 0) give a deliver a NULL pin.
- int i = WstrToInt(Id) -1;
- *ppPin = GetPin(i);
- if (*ppPin!=NULL){
- (*ppPin)->AddRef();
- return NOERROR;
- } else {
- return VFW_E_NOT_FOUND;
- }
-}
-
-//
-// FindPinNumber
-//
-// return the number of the pin with this IPin* or -1 if none
-int CSource::FindPinNumber(__in IPin *iPin) {
- int i;
- for (i=0; i<m_iPins; ++i) {
- if ((IPin *)(m_paStreams[i])==iPin) {
- return i;
- }
- }
- return -1;
-}
-
-//
-// GetPinCount
-//
-// Returns the number of pins this filter has
-int CSource::GetPinCount(void) {
-
- CAutoLock lock(&m_cStateLock);
- return m_iPins;
-}
-
-
-//
-// GetPin
-//
-// Return a non-addref'd pointer to pin n
-// needed by CBaseFilter
-CBasePin *CSource::GetPin(int n) {
-
- CAutoLock lock(&m_cStateLock);
-
- // n must be in the range 0..m_iPins-1
- // if m_iPins>n && n>=0 it follows that m_iPins>0
- // which is what used to be checked (i.e. checking that we have a pin)
- if ((n >= 0) && (n < m_iPins)) {
-
- ASSERT(m_paStreams[n]);
- return m_paStreams[n];
- }
- return NULL;
-}
-
-
-//
-
-
-// *
-// * --- CSourceStream ----
-// *
-
-//
-// Set Id to point to a CoTaskMemAlloc'd
-STDMETHODIMP CSourceStream::QueryId(__deref_out LPWSTR *Id) {
- CheckPointer(Id,E_POINTER);
- ValidateReadWritePtr(Id,sizeof(LPWSTR));
-
- // We give the pins id's which are 1,2,...
- // FindPinNumber returns -1 for an invalid pin
- int i = 1+ m_pFilter->FindPinNumber(this);
- if (i<1) return VFW_E_NOT_FOUND;
- *Id = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * 12);
- if (*Id==NULL) {
- return E_OUTOFMEMORY;
- }
- IntToWstr(i, *Id);
- return NOERROR;
-}
-
-
-
-//
-// CSourceStream::Constructor
-//
-// increments the number of pins present on the filter
-CSourceStream::CSourceStream(
- __in_opt LPCTSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *ps,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
- m_pFilter(ps) {
-
- *phr = m_pFilter->AddPin(this);
-}
-
-#ifdef UNICODE
-CSourceStream::CSourceStream(
- __in_opt LPCSTR pObjectName,
- __inout HRESULT *phr,
- __inout CSource *ps,
- __in_opt LPCWSTR pPinName)
- : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
- m_pFilter(ps) {
-
- *phr = m_pFilter->AddPin(this);
-}
-#endif
-//
-// CSourceStream::Destructor
-//
-// Decrements the number of pins on this filter
-CSourceStream::~CSourceStream(void) {
-
- m_pFilter->RemovePin(this);
-}
-
-
-//
-// CheckMediaType
-//
-// Do we support this type? Provides the default support for 1 type.
-HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- CMediaType mt;
- GetMediaType(&mt);
-
- if (mt == *pMediaType) {
- return NOERROR;
- }
-
- return E_FAIL;
-}
-
-
-//
-// GetMediaType/3
-//
-// By default we support only one type
-// iPosition indexes are 0-n
-HRESULT CSourceStream::GetMediaType(int iPosition, __inout CMediaType *pMediaType) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- if (iPosition<0) {
- return E_INVALIDARG;
- }
- if (iPosition>0) {
- return VFW_S_NO_MORE_ITEMS;
- }
- return GetMediaType(pMediaType);
-}
-
-
-//
-// Active
-//
-// The pin is active - start up the worker thread
-HRESULT CSourceStream::Active(void) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- HRESULT hr;
-
- if (m_pFilter->IsActive()) {
- return S_FALSE; // succeeded, but did not allocate resources (they already exist...)
- }
-
- // do nothing if not connected - its ok not to connect to
- // all pins of a source filter
- if (!IsConnected()) {
- return NOERROR;
- }
-
- hr = CBaseOutputPin::Active();
- if (FAILED(hr)) {
- return hr;
- }
-
- ASSERT(!ThreadExists());
-
- // start the thread
- if (!Create()) {
- return E_FAIL;
- }
-
- // Tell thread to initialize. If OnThreadCreate Fails, so does this.
- hr = Init();
- if (FAILED(hr))
- return hr;
-
- return Pause();
-}
-
-
-//
-// Inactive
-//
-// Pin is inactive - shut down the worker thread
-// Waits for the worker to exit before returning.
-HRESULT CSourceStream::Inactive(void) {
-
- CAutoLock lock(m_pFilter->pStateLock());
-
- HRESULT hr;
-
- // do nothing if not connected - its ok not to connect to
- // all pins of a source filter
- if (!IsConnected()) {
- return NOERROR;
- }
-
- // !!! need to do this before trying to stop the thread, because
- // we may be stuck waiting for our own allocator!!!
-
- hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
- if (FAILED(hr)) {
- return hr;
- }
-
- if (ThreadExists()) {
- hr = Stop();
-
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = Exit();
- if (FAILED(hr)) {
- return hr;
- }
-
- Close(); // Wait for the thread to exit, then tidy up.
- }
-
- // hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
- //if (FAILED(hr)) {
- // return hr;
- //}
-
- return NOERROR;
-}
-
-
-//
-// ThreadProc
-//
-// When this returns the thread exits
-// Return codes > 0 indicate an error occured
-DWORD CSourceStream::ThreadProc(void) {
-
- HRESULT hr; // the return code from calls
- Command com;
-
- do {
- com = GetRequest();
- if (com != CMD_INIT) {
- DbgLog((LOG_ERROR, 1, TEXT("Thread expected init command")));
- Reply((DWORD) E_UNEXPECTED);
- }
- } while (com != CMD_INIT);
-
- DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread initializing")));
-
- hr = OnThreadCreate(); // perform set up tasks
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread.")));
- OnThreadDestroy();
- Reply(hr); // send failed return code from OnThreadCreate
- return 1;
- }
-
- // Initialisation suceeded
- Reply(NOERROR);
-
- Command cmd;
- do {
- cmd = GetRequest();
-
- switch (cmd) {
-
- case CMD_EXIT:
- Reply(NOERROR);
- break;
-
- case CMD_RUN:
- DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???")));
- // !!! fall through???
-
- case CMD_PAUSE:
- Reply(NOERROR);
- DoBufferProcessingLoop();
- break;
-
- case CMD_STOP:
- Reply(NOERROR);
- break;
-
- default:
- DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd));
- Reply((DWORD) E_NOTIMPL);
- break;
- }
- } while (cmd != CMD_EXIT);
-
- hr = OnThreadDestroy(); // tidy up.
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadDestroy failed. Exiting thread.")));
- return 1;
- }
-
- DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread exiting")));
- return 0;
-}
-
-
-//
-// DoBufferProcessingLoop
-//
-// Grabs a buffer and calls the users processing function.
-// Overridable, so that different delivery styles can be catered for.
-HRESULT CSourceStream::DoBufferProcessingLoop(void) {
-
- Command com;
-
- OnThreadStartPlay();
-
- do {
- while (!CheckRequest(&com)) {
-
- IMediaSample *pSample;
-
- HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
- if (FAILED(hr)) {
- Sleep(1);
- continue; // go round again. Perhaps the error will go away
- // or the allocator is decommited & we will be asked to
- // exit soon.
- }
-
- // Virtual function user will override.
- hr = FillBuffer(pSample);
-
- if (hr == S_OK) {
- hr = Deliver(pSample);
- pSample->Release();
-
- // downstream filter returns S_FALSE if it wants us to
- // stop or an error if it's reporting an error.
- if(hr != S_OK)
- {
- DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
- return S_OK;
- }
-
- } else if (hr == S_FALSE) {
- // derived class wants us to stop pushing data
- pSample->Release();
- DeliverEndOfStream();
- return S_OK;
- } else {
- // derived class encountered an error
- pSample->Release();
- DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
- DeliverEndOfStream();
- m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
- return hr;
- }
-
- // all paths release the sample
- }
-
- // For all commands sent to us there must be a Reply call!
-
- if (com == CMD_RUN || com == CMD_PAUSE) {
- Reply(NOERROR);
- } else if (com != CMD_STOP) {
- Reply((DWORD) E_UNEXPECTED);
- DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
- }
- } while (com != CMD_STOP);
-
- return S_FALSE;
-}
-