summaryrefslogtreecommitdiff
path: root/src/imaging/DSSampleGrabber.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imaging/DSSampleGrabber.cpp')
-rw-r--r--src/imaging/DSSampleGrabber.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/imaging/DSSampleGrabber.cpp b/src/imaging/DSSampleGrabber.cpp
new file mode 100644
index 0000000..1a62c2d
--- /dev/null
+++ b/src/imaging/DSSampleGrabber.cpp
@@ -0,0 +1,220 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DSSampleGrabber.h"
+
+#include <initguid.h>
+
+#pragma warning(disable: 4800)
+
+// {455A53B7-FC34-4960-94CE-A17A0B23F807}
+DEFINE_GUID(CLSID_libavgGrabber,
+0x455a53b7, 0xfc34, 0x4960, 0x94, 0xce, 0xa1, 0x7a, 0xb, 0x23, 0xf8, 0x7);
+
+namespace avg {
+
+class CSampleGrabberAllocator : public CMemAllocator
+{
+public:
+ CSampleGrabberAllocator(CSampleGrabberInPin* pParent, HRESULT* phr);
+ ~CSampleGrabberAllocator();
+
+ HRESULT Alloc();
+ void ReallyFree();
+ STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES* pRequest,
+ ALLOCATOR_PROPERTIES* pActual);
+
+protected:
+ CSampleGrabberInPin * m_pPin;
+
+private:
+ friend class CSampleGrabberInPin;
+ friend class CSampleGrabber;
+};
+
+class CSampleGrabberInPin : public CTransInPlaceInputPin
+{
+public:
+ CSampleGrabberInPin(CTransInPlaceFilter* pFilter, HRESULT* pHr);
+ ~CSampleGrabberInPin();
+
+ HRESULT GetMediaType(int iPosition, CMediaType* pMediaType);
+
+ // override this or GetMediaType is never called
+ STDMETHODIMP EnumMediaTypes(IEnumMediaTypes** ppEnum);
+
+ // we override this to tell whoever's upstream of us what kind of
+ // properties we're going to demand to have
+ STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
+
+private:
+ friend class CSampleGrabberAllocator;
+ friend class CSampleGrabber;
+
+ CSampleGrabberAllocator* m_pPrivateAllocator;
+ ALLOCATOR_PROPERTIES m_allocprops;
+ BYTE* m_pBuffer;
+ BOOL m_bMediaTypeChanged;
+};
+
+CSampleGrabber::CSampleGrabber(IUnknown * pOuter, HRESULT * phr)
+ : CTransInPlaceFilter(TEXT("libavg sample grabber"), (IUnknown*) pOuter,
+ CLSID_libavgGrabber, phr, false),
+ m_pCallback(NULL)
+{
+ m_pInput = (CTransInPlaceInputPin*) new CSampleGrabberInPin(this, phr);
+
+ IPin *pOutput = GetPin(1);
+}
+
+STDMETHODIMP CSampleGrabber::NonDelegatingQueryInterface(REFIID riid, void** ppv)
+{
+ AVG_ASSERT(ppv);
+
+ if (riid == IID_IlibavgGrabber) {
+ return GetInterface((IlibavgGrabber *)this, ppv);
+ } else {
+ return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
+ }
+}
+
+HRESULT CSampleGrabber::CheckInputType(const CMediaType* pmt)
+{
+ AVG_ASSERT(pmt);
+ CAutoLock lock(&m_Lock);
+
+ if (MEDIATYPE_Video == *pmt->Type( )) {
+ return NOERROR;
+ } else {
+ return VFW_E_INVALID_MEDIA_TYPE;
+ }
+}
+
+HRESULT CSampleGrabber::Receive(IMediaSample * pms)
+{
+ AVG_ASSERT(pms);
+
+ HRESULT hr;
+ AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
+
+ if (pProps->dwStreamId != AM_STREAM_MEDIA) {
+ if (m_pOutput->IsConnected()) {
+ return m_pOutput->Deliver(pms);
+ } else {
+ return NOERROR;
+ }
+ }
+ if (UsingDifferentAllocators()) {
+ pms = Copy(pms);
+ AVG_ASSERT(pms);
+ }
+
+ hr = Transform(pms);
+ AVG_ASSERT(!FAILED(hr));
+ hr = m_pOutput->Deliver(pms);
+ if (UsingDifferentAllocators()) {
+ pms->Release();
+ }
+ return hr;
+}
+
+HRESULT CSampleGrabber::Transform(IMediaSample* pms)
+{
+ AVG_ASSERT(pms);
+ CAutoLock lock(&m_Lock);
+
+ if (m_pCallback) {
+ REFERENCE_TIME StartTime;
+ REFERENCE_TIME StopTime;
+ pms->GetTime( &StartTime, &StopTime);
+
+ StartTime += m_pInput->CurrentStartTime();
+ StopTime += m_pInput->CurrentStartTime();
+
+ m_pCallback->onSample(pms);
+ }
+ return NOERROR;
+}
+
+void STDMETHODCALLTYPE CSampleGrabber::SetCallback(IDSSampleCallback* pCallback)
+{
+ CAutoLock lock( &m_Lock );
+ m_pCallback = pCallback;
+}
+
+CSampleGrabberInPin::CSampleGrabberInPin(CTransInPlaceFilter* pFilter, HRESULT* pHr)
+ : CTransInPlaceInputPin(TEXT("SampleGrabberInputPin\0"), pFilter, pHr, L"Input\0"),
+ m_pPrivateAllocator(NULL),
+ m_pBuffer(NULL),
+ m_bMediaTypeChanged(FALSE)
+{
+ memset(&m_allocprops, 0, sizeof(m_allocprops));
+}
+
+CSampleGrabberInPin::~CSampleGrabberInPin()
+{
+ if (m_pPrivateAllocator) {
+ delete m_pPrivateAllocator;
+ }
+}
+
+HRESULT CSampleGrabberInPin::GetMediaType(int iPosition, CMediaType* pMediaType)
+{
+ AVG_ASSERT(pMediaType);
+ AVG_ASSERT(iPosition >= 0);
+ if (iPosition > 0) {
+ return VFW_S_NO_MORE_ITEMS;
+ }
+
+ *pMediaType = CMediaType();
+ pMediaType->SetType(&MEDIATYPE_Video);
+
+ return S_OK;
+}
+
+STDMETHODIMP CSampleGrabberInPin::EnumMediaTypes(IEnumMediaTypes** ppEnum)
+{
+ AVG_ASSERT(ppEnum);
+ ValidateReadWritePtr(ppEnum, sizeof(IEnumMediaTypes *));
+
+ if(!((CSampleGrabber*)m_pTIPFilter)->OutputPin()->IsConnected())
+ {
+ *ppEnum = new CEnumMediaTypes(this, NULL);
+ return NOERROR;
+ }
+
+ return ((CSampleGrabber*)m_pTIPFilter)->OutputPin()->GetConnected()
+ ->EnumMediaTypes(ppEnum);
+}
+
+HRESULT CSampleGrabberInPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
+{
+ AVG_ASSERT(pProps);
+
+ if (m_pPrivateAllocator) {
+ *pProps = m_allocprops;
+ return S_OK;
+ } else {
+ return CTransInPlaceInputPin::GetAllocatorRequirements(pProps);
+ }
+}
+
+} \ No newline at end of file