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

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/includes/ILAVDynamicAllocator.h30
-rw-r--r--demuxer/LAVSplitter/LAVSplitter.vcxproj1
-rw-r--r--demuxer/LAVSplitter/LAVSplitter.vcxproj.filters3
-rw-r--r--demuxer/LAVSplitter/OutputPin.cpp2
-rw-r--r--demuxer/LAVSplitter/PacketAllocator.cpp116
-rw-r--r--demuxer/LAVSplitter/PacketAllocator.h13
-rw-r--r--demuxer/LAVSplitter/dllmain.cpp1
7 files changed, 129 insertions, 37 deletions
diff --git a/common/includes/ILAVDynamicAllocator.h b/common/includes/ILAVDynamicAllocator.h
new file mode 100644
index 00000000..2002156c
--- /dev/null
+++ b/common/includes/ILAVDynamicAllocator.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010-2017 Hendrik Leppkes
+ * http://www.1f0.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#pragma once
+
+// {8FBB906B-D1DB-4528-9498-563241CCD43D}
+DEFINE_GUID(IID_ILAVDynamicAllocator,
+0x8fbb906b, 0xd1db, 0x4528, 0x94, 0x98, 0x56, 0x32, 0x41, 0xcc, 0xd4, 0x3d);
+
+interface __declspec(uuid("8FBB906B-D1DB-4528-9498-563241CCD43D")) ILAVDynamicAllocator : public IUnknown
+{
+ // Query wether this allocator is using dynamic allocation of samples and will not run out of samples
+ STDMETHOD_(BOOL,IsDynamicAllocator)() PURE;
+};
diff --git a/demuxer/LAVSplitter/LAVSplitter.vcxproj b/demuxer/LAVSplitter/LAVSplitter.vcxproj
index 30768bd9..b64034b8 100644
--- a/demuxer/LAVSplitter/LAVSplitter.vcxproj
+++ b/demuxer/LAVSplitter/LAVSplitter.vcxproj
@@ -114,6 +114,7 @@
<ClInclude Include="..\..\common\includes\IDSMResourceBag.h" />
<ClInclude Include="..\..\common\includes\IGraphRebuildDelegate.h" />
<ClInclude Include="..\..\common\includes\IKeyFrameInfo.h" />
+ <ClInclude Include="..\..\common\includes\ILAVDynamicAllocator.h" />
<ClInclude Include="..\..\common\includes\ILAVPinInfo.h" />
<ClInclude Include="..\..\common\includes\ISpecifyPropertyPages2.h" />
<ClInclude Include="..\..\common\includes\IStreamSourceControl.h" />
diff --git a/demuxer/LAVSplitter/LAVSplitter.vcxproj.filters b/demuxer/LAVSplitter/LAVSplitter.vcxproj.filters
index 3689aaa4..8121654b 100644
--- a/demuxer/LAVSplitter/LAVSplitter.vcxproj.filters
+++ b/demuxer/LAVSplitter/LAVSplitter.vcxproj.filters
@@ -119,6 +119,9 @@
<ClInclude Include="..\..\common\includes\IDSMResourceBag.h">
<Filter>Header Files\common</Filter>
</ClInclude>
+ <ClInclude Include="..\..\common\includes\ILAVDynamicAllocator.h">
+ <Filter>Header Files\common</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="LAVSplitter.rc">
diff --git a/demuxer/LAVSplitter/OutputPin.cpp b/demuxer/LAVSplitter/OutputPin.cpp
index e6b36a5c..66f0aa25 100644
--- a/demuxer/LAVSplitter/OutputPin.cpp
+++ b/demuxer/LAVSplitter/OutputPin.cpp
@@ -164,7 +164,7 @@ HRESULT CLAVOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERT
HRESULT hr = S_OK;
- pProperties->cBuffers = max(pProperties->cBuffers, (m_bPacketAllocator ? 10 : m_nBuffers));
+ pProperties->cBuffers = max(pProperties->cBuffers, (m_bPacketAllocator ? 20 : m_nBuffers));
pProperties->cbBuffer = max(max(m_mt.lSampleSize, 256000), (ULONG)pProperties->cbBuffer);
// Vorbis requires at least 2 buffers
diff --git a/demuxer/LAVSplitter/PacketAllocator.cpp b/demuxer/LAVSplitter/PacketAllocator.cpp
index 30456e5c..4ae27f7b 100644
--- a/demuxer/LAVSplitter/PacketAllocator.cpp
+++ b/demuxer/LAVSplitter/PacketAllocator.cpp
@@ -127,6 +127,16 @@ CPacketAllocator::~CPacketAllocator(void)
ReallyFree();
}
+STDMETHODIMP CPacketAllocator::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
+{
+ if (riid == IID_ILAVDynamicAllocator) {
+ return GetInterface((ILAVDynamicAllocator *) this, ppv);
+ }
+ else {
+ return __super::NonDelegatingQueryInterface(riid, ppv);
+ }
+}
+
STDMETHODIMP CPacketAllocator::SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual)
{
CheckPointer(pActual,E_POINTER);
@@ -215,47 +225,13 @@ HRESULT CPacketAllocator::Alloc(void)
return E_OUTOFMEMORY;
}
- /* Compute the aligned size */
- LONG lAlignedSize = m_lSize + m_lPrefix;
-
- /* Check overflow */
- if (lAlignedSize < m_lSize) {
- return E_OUTOFMEMORY;
- }
-
- if (m_lAlignment > 1) {
- LONG lRemainder = lAlignedSize % m_lAlignment;
- if (lRemainder != 0) {
- LONG lNewSize = lAlignedSize + m_lAlignment - lRemainder;
- if (lNewSize < lAlignedSize) {
- return E_OUTOFMEMORY;
- }
- lAlignedSize = lNewSize;
- }
- }
-
- /* Create the contiguous memory block for the samples
- making sure it's properly aligned (64K should be enough!)
- */
- ASSERT(lAlignedSize % m_lAlignment == 0);
-
- LONGLONG lToAllocate = m_lCount * (LONGLONG)lAlignedSize;
-
- /* Check overflow */
- if (lToAllocate > MAXLONG) {
- return E_OUTOFMEMORY;
- }
-
m_bAllocated = TRUE;
CMediaPacketSample *pSample = nullptr;
ASSERT(m_lAllocated == 0);
- // Create the new samples - we have allocated m_lSize bytes for each sample
- // plus m_lPrefix bytes per sample as a prefix. We set the pointer to
- // the memory after the prefix - so that GetPointer() will return a pointer
- // to m_lSize bytes.
+ // Create the initial set of samples
for (; m_lAllocated < m_lCount; m_lAllocated++) {
pSample = new CMediaPacketSample(NAME("LAV Package media sample"), this, &hr);
@@ -272,6 +248,76 @@ HRESULT CPacketAllocator::Alloc(void)
return NOERROR;
}
+// get container for a sample. Blocking, synchronous call to get the
+// next free buffer (as represented by an IMediaSample interface).
+// on return, the time etc properties will be invalid, but the buffer
+// pointer and size will be correct.
+
+HRESULT CPacketAllocator::GetBuffer(__deref_out IMediaSample **ppBuffer,
+ __in_opt REFERENCE_TIME *pStartTime,
+ __in_opt REFERENCE_TIME *pEndTime,
+ DWORD dwFlags
+)
+{
+ UNREFERENCED_PARAMETER(pStartTime);
+ UNREFERENCED_PARAMETER(pEndTime);
+ UNREFERENCED_PARAMETER(dwFlags);
+ CMediaSample *pSample;
+
+ *ppBuffer = NULL;
+ for (;;)
+ {
+ { // scope for lock
+ CAutoLock cObjectLock(this);
+
+ /* Check we are committed */
+ if (!m_bCommitted) {
+ return VFW_E_NOT_COMMITTED;
+ }
+ pSample = (CMediaSample *)m_lFree.RemoveHead();
+
+ /* if no sample was available, allocate a new one */
+ if (pSample == NULL) {
+ HRESULT hr = S_OK;
+ pSample = new CMediaPacketSample(NAME("LAV Package media sample"), this, &hr);
+ ASSERT(SUCCEEDED(hr));
+
+ if (pSample) {
+ m_lAllocated++;
+ DbgLog((LOG_TRACE, 10, "Allocated new sample, %d total", m_lAllocated));
+ }
+ }
+ }
+
+ /* If we didn't get a sample then wait for the list to signal */
+
+ if (pSample) {
+ break;
+ }
+ if (dwFlags & AM_GBF_NOWAIT) {
+ return VFW_E_TIMEOUT;
+ }
+ ASSERT(m_hSem != NULL);
+ WaitForSingleObject(m_hSem, INFINITE);
+ }
+
+ /* Addref the buffer up to one. On release
+ back to zero instead of being deleted, it will requeue itself by
+ calling the ReleaseBuffer member function. NOTE the owner of a
+ media sample must always be derived from CBaseAllocator */
+
+
+ ASSERT(pSample->m_cRef == 0);
+ pSample->m_cRef = 1;
+ *ppBuffer = pSample;
+
+#ifdef DXMPERF
+ PERFLOG_GETBUFFER((IMemAllocator *) this, pSample);
+#endif // DXMPERF
+
+ return NOERROR;
+}
+
// override this to free up any resources we have allocated.
// called from the base class on Decommit when all buffers have been
diff --git a/demuxer/LAVSplitter/PacketAllocator.h b/demuxer/LAVSplitter/PacketAllocator.h
index 1de13118..8f3b03b1 100644
--- a/demuxer/LAVSplitter/PacketAllocator.h
+++ b/demuxer/LAVSplitter/PacketAllocator.h
@@ -25,6 +25,7 @@
#include "Packet.h"
#include "IMediaSideData.h"
#include "IMediaSideDataFFmpeg.h"
+#include "ILAVDynamicAllocator.h"
interface __declspec(uuid("0B2EE323-0ED8-452D-B31E-B9B4DE2C0C39"))
ILAVMediaSample : public IUnknown {
@@ -54,7 +55,7 @@ protected:
MediaSideDataFFMpeg *m_pSideData = nullptr;
};
-class CPacketAllocator : public CBaseAllocator
+class CPacketAllocator : public CBaseAllocator, public ILAVDynamicAllocator
{
protected:
BOOL m_bAllocated = FALSE;
@@ -69,9 +70,19 @@ protected:
// overriden to allocate the memory when commit called
HRESULT Alloc(void);
+
public:
CPacketAllocator(LPCTSTR pName, LPUNKNOWN pUnk, HRESULT *phr);
virtual ~CPacketAllocator(void);
+ // CUnknown support
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ // CBaseAllocator overrides
STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual);
+ STDMETHODIMP GetBuffer(IMediaSample **ppBuffer, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags);
+
+ // ILAVDynamicAllocator
+ STDMETHODIMP_(BOOL) IsDynamicAllocator() { return TRUE; }
};
diff --git a/demuxer/LAVSplitter/dllmain.cpp b/demuxer/LAVSplitter/dllmain.cpp
index f65df0d3..1d6e0a74 100644
--- a/demuxer/LAVSplitter/dllmain.cpp
+++ b/demuxer/LAVSplitter/dllmain.cpp
@@ -37,6 +37,7 @@
#include "registry.h"
#include "IGraphRebuildDelegate.h"
#include "IMediaSideDataFFmpeg.h"
+#include "ILAVDynamicAllocator.h"
// The GUID we use to register the splitter media types
DEFINE_GUID(MEDIATYPE_LAVSplitter,