123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- #include <streams.h>
- 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::~CSource()
- {
-
- while (m_iPins != 0) {
-
- delete m_paStreams[m_iPins - 1];
- }
- ASSERT(m_paStreams == NULL);
- }
- HRESULT CSource::AddPin(__in CSourceStream *pStream)
- {
- CAutoLock lock(&m_cStateLock);
-
- 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;
- }
- 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 {
-
- while (++i < m_iPins)
- m_paStreams[i - 1] = m_paStreams[i];
- }
- m_iPins--;
- return S_OK;
- }
- }
- return S_FALSE;
- }
- STDMETHODIMP CSource::FindPin(LPCWSTR Id, __deref_out IPin **ppPin)
- {
- CheckPointer(ppPin,E_POINTER);
- ValidateReadWritePtr(ppPin,sizeof(IPin *));
-
-
- int i = WstrToInt(Id) -1;
- *ppPin = GetPin(i);
- if (*ppPin!=NULL){
- (*ppPin)->AddRef();
- return NOERROR;
- } else {
- return VFW_E_NOT_FOUND;
- }
- }
- 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;
- }
- int CSource::GetPinCount(void) {
- CAutoLock lock(&m_cStateLock);
- return m_iPins;
- }
- CBasePin *CSource::GetPin(int n) {
- CAutoLock lock(&m_cStateLock);
-
-
-
- if ((n >= 0) && (n < m_iPins)) {
- ASSERT(m_paStreams[n]);
- return m_paStreams[n];
- }
- return NULL;
- }
- STDMETHODIMP CSourceStream::QueryId(__deref_out LPWSTR *Id) {
- CheckPointer(Id,E_POINTER);
- ValidateReadWritePtr(Id,sizeof(LPWSTR));
-
-
- 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::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::~CSourceStream(void) {
- m_pFilter->RemovePin(this);
- }
- HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) {
- CAutoLock lock(m_pFilter->pStateLock());
- CMediaType mt;
- GetMediaType(&mt);
- if (mt == *pMediaType) {
- return NOERROR;
- }
- return E_FAIL;
- }
- 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);
- }
- HRESULT CSourceStream::Active(void) {
- CAutoLock lock(m_pFilter->pStateLock());
- HRESULT hr;
- if (m_pFilter->IsActive()) {
- return S_FALSE;
- }
-
-
- if (!IsConnected()) {
- return NOERROR;
- }
- hr = CBaseOutputPin::Active();
- if (FAILED(hr)) {
- return hr;
- }
- ASSERT(!ThreadExists());
-
- if (!Create()) {
- return E_FAIL;
- }
-
- hr = Init();
- if (FAILED(hr))
- return hr;
- return Pause();
- }
- HRESULT CSourceStream::Inactive(void) {
- CAutoLock lock(m_pFilter->pStateLock());
- HRESULT hr;
-
-
- if (!IsConnected()) {
- return NOERROR;
- }
-
-
- hr = CBaseOutputPin::Inactive();
- if (FAILED(hr)) {
- return hr;
- }
- if (ThreadExists()) {
- hr = Stop();
- if (FAILED(hr)) {
- return hr;
- }
- hr = Exit();
- if (FAILED(hr)) {
- return hr;
- }
- Close();
- }
-
-
-
-
- return NOERROR;
- }
- DWORD CSourceStream::ThreadProc(void) {
- HRESULT hr;
- 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();
- if (FAILED(hr)) {
- DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread.")));
- OnThreadDestroy();
- Reply(hr);
- return 1;
- }
-
- 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???")));
-
-
- 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();
- 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;
- }
- 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;
-
-
- }
-
- hr = FillBuffer(pSample);
- if (hr == S_OK) {
- hr = Deliver(pSample);
- pSample->Release();
-
-
- if(hr != S_OK)
- {
- DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
- return S_OK;
- }
- } else if (hr == S_FALSE) {
-
- pSample->Release();
- DeliverEndOfStream();
- return S_OK;
- } else {
-
- pSample->Release();
- DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
- DeliverEndOfStream();
- m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
- return hr;
- }
-
- }
-
- 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;
- }
|