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:
authorUnderground78 <underground78@users.sourceforge.net>2013-09-08 22:49:23 +0400
committerUnderground78 <underground78@users.sourceforge.net>2013-09-27 21:43:56 +0400
commit1c821dc0335af018da1b64ae3935ea15966d2bec (patch)
treeb0dd2365c0ab6d94bbc97fbfb8b00582691ac8c7
parent4a20646e056d612aea9eafbbfba59fc60ed7ce8c (diff)
[MPC-HC] LAV Splitter: Exhibits MKV attachments through IDSMResourceBag interface.mpc-hc-1.7.0-5
-rw-r--r--common/DSUtilLite/DSMResourceBag.cpp191
-rw-r--r--common/DSUtilLite/DSMResourceBag.h79
-rw-r--r--common/DSUtilLite/DSUtilLite.vcxproj2
-rw-r--r--common/DSUtilLite/DSUtilLite.vcxproj.filters6
-rw-r--r--demuxer/Demuxers/LAVFDemuxer.cpp28
-rw-r--r--demuxer/Demuxers/LAVFDemuxer.h4
-rw-r--r--demuxer/LAVSplitter/LAVSplitter.cpp3
7 files changed, 307 insertions, 6 deletions
diff --git a/common/DSUtilLite/DSMResourceBag.cpp b/common/DSUtilLite/DSMResourceBag.cpp
new file mode 100644
index 00000000..2e43ddf1
--- /dev/null
+++ b/common/DSUtilLite/DSMResourceBag.cpp
@@ -0,0 +1,191 @@
+/*
+ * (C) 2003-2006 Gabest
+ * (C) 2006-2013 see Authors.txt
+ *
+ * This file is part of MPC-HC.
+ *
+ * MPC-HC 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MPC-HC 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "stdafx.h"
+#include "DSMResourceBag.h"
+
+
+//
+// CDSMResource
+//
+
+CCritSec CDSMResource::m_csResources;
+std::map<uintptr_t, CDSMResource*> CDSMResource::m_resources;
+
+CDSMResource::CDSMResource()
+ : mime(L"application/octet-stream")
+ , tag(0)
+{
+ CAutoLock cAutoLock(&m_csResources);
+ m_resources[reinterpret_cast<uintptr_t>(this)] = this;
+}
+
+CDSMResource::CDSMResource(const CDSMResource& r)
+{
+ *this = r;
+
+ CAutoLock cAutoLock(&m_csResources);
+ m_resources[reinterpret_cast<uintptr_t>(this)] = this;
+}
+
+CDSMResource::CDSMResource(LPCWSTR name, LPCWSTR desc, LPCWSTR mime, BYTE* pData, int len, DWORD_PTR tag)
+{
+ this->name = name;
+ this->desc = desc;
+ this->mime = mime;
+ data.resize(len);
+ memcpy(data.data(), pData, data.size());
+ this->tag = tag;
+
+ CAutoLock cAutoLock(&m_csResources);
+ m_resources[reinterpret_cast<uintptr_t>(this)] = this;
+}
+
+CDSMResource::~CDSMResource()
+{
+ CAutoLock cAutoLock(&m_csResources);
+ m_resources.erase(reinterpret_cast<uintptr_t>(this));
+}
+
+CDSMResource& CDSMResource::operator=(const CDSMResource& r)
+{
+ if (this != &r) {
+ tag = r.tag;
+ name = r.name;
+ desc = r.desc;
+ mime = r.mime;
+ data = r.data;
+ }
+ return *this;
+}
+
+//
+// IDSMResourceBagImpl
+//
+
+IDSMResourceBagImpl::IDSMResourceBagImpl()
+{
+}
+
+// IDSMResourceBag
+
+STDMETHODIMP_(DWORD) IDSMResourceBagImpl::ResGetCount()
+{
+ return (DWORD)m_resources.size();
+}
+
+STDMETHODIMP IDSMResourceBagImpl::ResGet(DWORD iIndex, BSTR* ppName, BSTR* ppDesc, BSTR* ppMime, BYTE** ppData, DWORD* pDataLen, DWORD_PTR* pTag)
+{
+ if (ppData) {
+ CheckPointer(pDataLen, E_POINTER);
+ }
+
+ if (iIndex >= (DWORD)m_resources.size()) {
+ return E_INVALIDARG;
+ }
+
+ CDSMResource& r = m_resources[iIndex];
+
+ if (ppName) {
+ *ppName = SysAllocString(r.name.data());
+ if (*ppName == NULL)
+ return E_OUTOFMEMORY;
+ }
+ if (ppDesc) {
+ *ppDesc = SysAllocString(r.desc.data());
+ if (*ppDesc == NULL)
+ return E_OUTOFMEMORY;
+ }
+ if (ppMime) {
+ *ppMime = SysAllocString(r.mime.data());
+ if (*ppMime == NULL)
+ return E_OUTOFMEMORY;
+ }
+ if (ppData) {
+ *pDataLen = (DWORD)r.data.size();
+ memcpy(*ppData = (BYTE*)CoTaskMemAlloc(*pDataLen), r.data.data(), *pDataLen);
+ }
+ if (pTag) {
+ *pTag = r.tag;
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP IDSMResourceBagImpl::ResSet(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, const BYTE* pData, DWORD len, DWORD_PTR tag)
+{
+ if (iIndex >= (DWORD)m_resources.size()) {
+ return E_INVALIDARG;
+ }
+
+ CDSMResource& r = m_resources[iIndex];
+
+ if (pName) {
+ r.name = pName;
+ }
+ if (pDesc) {
+ r.desc = pDesc;
+ }
+ if (pMime) {
+ r.mime = pMime;
+ }
+ if (pData || len == 0) {
+ r.data.resize(len);
+ if (pData) {
+ memcpy(r.data.data(), pData, r.data.size());
+ }
+ }
+ r.tag = tag;
+
+ return S_OK;
+}
+
+STDMETHODIMP IDSMResourceBagImpl::ResAppend(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
+{
+ m_resources.push_back(CDSMResource());
+ return ResSet((DWORD)m_resources.size() - 1, pName, pDesc, pMime, pData, len, tag);
+}
+
+STDMETHODIMP IDSMResourceBagImpl::ResRemoveAt(DWORD iIndex)
+{
+ if (iIndex >= (DWORD)m_resources.size()) {
+ return E_INVALIDARG;
+ }
+
+ m_resources.erase(m_resources.cbegin() + iIndex);
+
+ return S_OK;
+}
+
+STDMETHODIMP IDSMResourceBagImpl::ResRemoveAll(DWORD_PTR tag)
+{
+ if (tag) {
+ for (auto crit = m_resources.cend() - 1; crit >= m_resources.begin(); --crit) {
+ if (crit->tag == tag) {
+ m_resources.erase(crit);
+ }
+ }
+ } else {
+ m_resources.clear();
+ }
+
+ return S_OK;
+}
diff --git a/common/DSUtilLite/DSMResourceBag.h b/common/DSUtilLite/DSMResourceBag.h
new file mode 100644
index 00000000..a42ee2e1
--- /dev/null
+++ b/common/DSUtilLite/DSMResourceBag.h
@@ -0,0 +1,79 @@
+/*
+ * (C) 2003-2006 Gabest
+ * (C) 2006-2013 see Authors.txt
+ *
+ * This file is part of MPC-HC.
+ *
+ * MPC-HC 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MPC-HC 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <map>
+
+// IDSMResourceBag
+
+interface __declspec(uuid("EBAFBCBE-BDE0-489A-9789-05D5692E3A93"))
+IDSMResourceBag :
+public IUnknown {
+ STDMETHOD_(DWORD, ResGetCount)() PURE;
+ STDMETHOD(ResGet)(DWORD iIndex, BSTR * ppName, BSTR * ppDesc, BSTR * ppMime, BYTE** ppData, DWORD * pDataLen, DWORD_PTR * pTag) PURE;
+ STDMETHOD(ResSet)(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, const BYTE * pData, DWORD len, DWORD_PTR tag) PURE;
+ STDMETHOD(ResAppend)(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE * pData, DWORD len, DWORD_PTR tag) PURE;
+ STDMETHOD(ResRemoveAt)(DWORD iIndex) PURE;
+ STDMETHOD(ResRemoveAll)(DWORD_PTR tag) PURE;
+};
+
+class CDSMResource
+{
+public:
+ DWORD_PTR tag;
+ std::wstring name, desc, mime;
+ std::vector<BYTE> data;
+ CDSMResource();
+ CDSMResource(const CDSMResource& r);
+ CDSMResource(LPCWSTR name, LPCWSTR desc, LPCWSTR mime, BYTE* pData, int len, DWORD_PTR tag = 0);
+ virtual ~CDSMResource();
+ CDSMResource& operator=(const CDSMResource& r);
+
+ // global access to all resources
+ static CCritSec m_csResources;
+ static std::map<uintptr_t, CDSMResource*> m_resources;
+};
+
+class IDSMResourceBagImpl : public IDSMResourceBag
+{
+protected:
+ std::vector<CDSMResource> m_resources;
+
+public:
+ IDSMResourceBagImpl();
+
+ void operator+=(const CDSMResource& r) { m_resources.push_back(r); }
+
+ // IDSMResourceBag
+
+ STDMETHODIMP_(DWORD) ResGetCount();
+ STDMETHODIMP ResGet(DWORD iIndex, BSTR* ppName, BSTR* ppDesc, BSTR* ppMime,
+ BYTE** ppData, DWORD* pDataLen, DWORD_PTR* pTag = nullptr);
+ STDMETHODIMP ResSet(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime,
+ const BYTE* pData, DWORD len, DWORD_PTR tag = 0);
+ STDMETHODIMP ResAppend(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime,
+ BYTE* pData, DWORD len, DWORD_PTR tag = 0);
+ STDMETHODIMP ResRemoveAt(DWORD iIndex);
+ STDMETHODIMP ResRemoveAll(DWORD_PTR tag = 0);
+};
diff --git a/common/DSUtilLite/DSUtilLite.vcxproj b/common/DSUtilLite/DSUtilLite.vcxproj
index 2eaca878..f937a291 100644
--- a/common/DSUtilLite/DSUtilLite.vcxproj
+++ b/common/DSUtilLite/DSUtilLite.vcxproj
@@ -70,6 +70,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="BaseDSPropPage.h" />
+ <ClInclude Include="DSMResourceBag.h" />
<ClInclude Include="PopupMenu.h" />
<ClInclude Include="BaseTrayIcon.h" />
<ClInclude Include="ByteParser.h" />
@@ -90,6 +91,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="BaseDSPropPage.cpp" />
+ <ClCompile Include="DSMResourceBag.cpp" />
<ClCompile Include="PopupMenu.cpp" />
<ClCompile Include="BaseTrayIcon.cpp" />
<ClCompile Include="ByteParser.cpp" />
diff --git a/common/DSUtilLite/DSUtilLite.vcxproj.filters b/common/DSUtilLite/DSUtilLite.vcxproj.filters
index 9073b986..dbe1b52f 100644
--- a/common/DSUtilLite/DSUtilLite.vcxproj.filters
+++ b/common/DSUtilLite/DSUtilLite.vcxproj.filters
@@ -75,6 +75,9 @@
<ClInclude Include="PopupMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="DSMResourceBag.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@@ -119,5 +122,8 @@
<ClCompile Include="PopupMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="DSMResourceBag.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/demuxer/Demuxers/LAVFDemuxer.cpp b/demuxer/Demuxers/LAVFDemuxer.cpp
index 1890abe5..4c4ac6dd 100644
--- a/demuxer/Demuxers/LAVFDemuxer.cpp
+++ b/demuxer/Demuxers/LAVFDemuxer.cpp
@@ -158,6 +158,7 @@ STDMETHODIMP CLAVFDemuxer::NonDelegatingQueryInterface(REFIID riid, void** ppv)
m_bEnableTrackInfo && QI(ITrackInfo)
QI2(IAMExtendedSeeking)
QI2(IAMMediaContent)
+ QI(IDSMResourceBag)
__super::NonDelegatingQueryInterface(riid, ppv);
}
@@ -491,11 +492,30 @@ STDMETHODIMP CLAVFDemuxer::InitAVFormat(LPCOLESTR pszFileName, BOOL bForce)
UpdateSubStreams();
- if (st->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT && (st->codec->codec_id == AV_CODEC_ID_TTF || st->codec->codec_id == AV_CODEC_ID_OTF)) {
- if (!m_pFontInstaller) {
- m_pFontInstaller = new CFontInstaller();
+ if (st->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
+ if (st->codec->codec_id == AV_CODEC_ID_TTF || st->codec->codec_id == AV_CODEC_ID_OTF) {
+ if (!m_pFontInstaller) {
+ m_pFontInstaller = new CFontInstaller();
+ }
+ m_pFontInstaller->InstallFont(st->codec->extradata, st->codec->extradata_size);
+ }
+
+ const AVDictionaryEntry* attachFilename = av_dict_get(st->metadata, "filename", NULL, 0);
+ const AVDictionaryEntry* attachMimeType = av_dict_get(st->metadata, "mimetype", NULL, 0);
+ if (attachFilename && attachMimeType) {
+ size_t len = strlen(attachFilename->value);
+ LPWSTR filename = new WCHAR[len + 1];
+ MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, attachFilename->value, -1, filename, len+1);
+
+ len = strlen(attachMimeType->value);
+ LPWSTR mimetype = new WCHAR[len + 1];
+ MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, attachMimeType->value, -1, mimetype, len+1);
+
+ ResAppend(filename, L"", mimetype, st->codec->extradata, (DWORD)st->codec->extradata_size);
+
+ delete [] filename;
+ delete [] mimetype;
}
- m_pFontInstaller->InstallFont(st->codec->extradata, st->codec->extradata_size);
}
}
diff --git a/demuxer/Demuxers/LAVFDemuxer.h b/demuxer/Demuxers/LAVFDemuxer.h
index 405f19e9..7051a6ae 100644
--- a/demuxer/Demuxers/LAVFDemuxer.h
+++ b/demuxer/Demuxers/LAVFDemuxer.h
@@ -25,6 +25,7 @@
#include "BaseDemuxer.h"
#include "IKeyFrameInfo.h"
#include "ITrackInfo.h"
+#include "DSMResourceBag.h"
#include "FontInstaller.h"
#define SUBMODE_FORCED_PGS_ONLY 0xFF
@@ -33,7 +34,8 @@ class FormatInfo;
class CBDDemuxer;
#define FFMPEG_FILE_BUFFER_SIZE 32768 // default reading size for ffmpeg
-class CLAVFDemuxer : public CBaseDemuxer, public IAMExtendedSeeking, public IKeyFrameInfo, public ITrackInfo, public IAMMediaContent
+class CLAVFDemuxer : public CBaseDemuxer, public IAMExtendedSeeking, public IKeyFrameInfo, public ITrackInfo, public IAMMediaContent,
+ public IDSMResourceBagImpl
{
public:
CLAVFDemuxer(CCritSec *pLock, ILAVFSettingsInternal *settings);
diff --git a/demuxer/LAVSplitter/LAVSplitter.cpp b/demuxer/LAVSplitter/LAVSplitter.cpp
index f55587f0..10661844 100644
--- a/demuxer/LAVSplitter/LAVSplitter.cpp
+++ b/demuxer/LAVSplitter/LAVSplitter.cpp
@@ -321,7 +321,8 @@ STDMETHODIMP CLAVSplitter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
*ppv = NULL;
- if (m_pDemuxer && (riid == __uuidof(IKeyFrameInfo) || riid == __uuidof(ITrackInfo) || riid == IID_IAMExtendedSeeking || riid == IID_IAMMediaContent)) {
+ if (m_pDemuxer
+ && (riid == __uuidof(IKeyFrameInfo) || riid == __uuidof(ITrackInfo) || riid == IID_IAMExtendedSeeking || riid == IID_IAMMediaContent || riid == __uuidof(IDSMResourceBag))) {
return m_pDemuxer->QueryInterface(riid, ppv);
}