aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeak3d <pfau@peak3d.de>2019-03-18 18:01:05 +0100
committerpeak3d <pfau@peak3d.de>2019-03-18 18:01:25 +0100
commit21912bb37d22edef271b8969d08380f43f9c1911 (patch)
tree2d06c7d4d690841be249da2d1fbffbdc369949ee
parentc7bac9713a508b54c91e4c57d2d33edc1c94975a (diff)
Decoderfilter implementation
-rw-r--r--cmake/treedata/android/subdirs.txt38
-rw-r--r--cmake/treedata/common/drm.txt1
-rw-r--r--cmake/treedata/common/media.txt2
-rw-r--r--cmake/treedata/common/subdirs.txt1
-rw-r--r--xbmc/ServiceBroker.cpp12
-rw-r--r--xbmc/ServiceBroker.h5
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp134
-rw-r--r--xbmc/interfaces/legacy/DrmCryptoSession.cpp2
-rw-r--r--xbmc/media/decoderfilter/CMakeLists.txt5
-rw-r--r--xbmc/media/decoderfilter/DecoderFilterManager.cpp175
-rw-r--r--xbmc/media/decoderfilter/DecoderFilterManager.h140
-rw-r--r--xbmc/media/drm/CMakeLists.txt (renamed from xbmc/drm/CMakeLists.txt)0
-rw-r--r--xbmc/media/drm/CryptoSession.cpp (renamed from xbmc/drm/CryptoSession.cpp)2
-rw-r--r--xbmc/media/drm/CryptoSession.h (renamed from xbmc/drm/CryptoSession.h)22
-rw-r--r--xbmc/platform/android/drm/MediaDrmCryptoSession.h76
-rw-r--r--xbmc/platform/android/media/decoderfilter/CMakeLists.txt5
-rw-r--r--xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.cpp58
-rw-r--r--xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h18
-rw-r--r--xbmc/platform/android/media/drm/CMakeLists.txt (renamed from xbmc/platform/android/drm/CMakeLists.txt)0
-rw-r--r--xbmc/platform/android/media/drm/MediaDrmCryptoSession.cpp (renamed from xbmc/platform/android/drm/MediaDrmCryptoSession.cpp)32
-rw-r--r--xbmc/platform/android/media/drm/MediaDrmCryptoSession.h76
-rw-r--r--xbmc/windowing/android/WinSystemAndroid.cpp54
-rw-r--r--xbmc/windowing/android/WinSystemAndroid.h2
23 files changed, 625 insertions, 235 deletions
diff --git a/cmake/treedata/android/subdirs.txt b/cmake/treedata/android/subdirs.txt
index 9c4232caff..53a04f04be 100644
--- a/cmake/treedata/android/subdirs.txt
+++ b/cmake/treedata/android/subdirs.txt
@@ -1,18 +1,20 @@
-xbmc/cores/RetroPlayer/process/android cores/RetroPlayer/process/android
-xbmc/input/touch input/touch
-xbmc/input/touch/generic input/touch/generic
-xbmc/windowing/android windowing/android
-xbmc/platform/posix platform/posix
-xbmc/platform/posix/filesystem platform/posix/filesystem
-xbmc/platform/posix/utils platform/posix/utils
-xbmc/platform/linux platform/linux
-xbmc/platform/linux/peripherals platform/linux/peripherals
-xbmc/platform/android/activity platform/android/activity
-xbmc/platform/android/bionic_supplement platform/android/bionicsupplement
-xbmc/platform/android/drm platform/android/drm
-xbmc/platform/android/filesystem platform/android/filesystem
-xbmc/platform/android/network platform/android/network
-xbmc/platform/android/peripherals platform/android/peripherals
-xbmc/platform/android/powermanagement platform/android/powermanagement
-xbmc/platform/android/storage platform/android/storage
-xbmc/cores/VideoPlayer/Process/android/ cores/VideoPlayer/Process/android/
+xbmc/cores/RetroPlayer/process/android cores/RetroPlayer/process/android
+xbmc/cores/VideoPlayer/Process/android/ cores/VideoPlayer/Process/android/
+xbmc/input/touch input/touch
+xbmc/input/touch/generic input/touch/generic
+xbmc/media/decoderfilter media/decoderfilter
+xbmc/windowing/android windowing/android
+xbmc/platform/posix platform/posix
+xbmc/platform/posix/filesystem platform/posix/filesystem
+xbmc/platform/posix/utils platform/posix/utils
+xbmc/platform/linux platform/linux
+xbmc/platform/linux/peripherals platform/linux/peripherals
+xbmc/platform/android/activity platform/android/activity
+xbmc/platform/android/bionic_supplement platform/android/bionicsupplement
+xbmc/platform/android/media/drm platform/android/media/drm
+xbmc/platform/android/media/decoderfilter platform/android/media/decoderfilter
+xbmc/platform/android/filesystem platform/android/filesystem
+xbmc/platform/android/network platform/android/network
+xbmc/platform/android/peripherals platform/android/peripherals
+xbmc/platform/android/powermanagement platform/android/powermanagement
+xbmc/platform/android/storage platform/android/storage
diff --git a/cmake/treedata/common/drm.txt b/cmake/treedata/common/drm.txt
deleted file mode 100644
index fbcc906b9b..0000000000
--- a/cmake/treedata/common/drm.txt
+++ /dev/null
@@ -1 +0,0 @@
-xbmc/drm drm
diff --git a/cmake/treedata/common/media.txt b/cmake/treedata/common/media.txt
new file mode 100644
index 0000000000..519fece955
--- /dev/null
+++ b/cmake/treedata/common/media.txt
@@ -0,0 +1,2 @@
+xbmc/media media
+xbmc/media/drm drm
diff --git a/cmake/treedata/common/subdirs.txt b/cmake/treedata/common/subdirs.txt
index 4a5f3a8434..083e8ef314 100644
--- a/cmake/treedata/common/subdirs.txt
+++ b/cmake/treedata/common/subdirs.txt
@@ -30,7 +30,6 @@ xbmc/input/keyboard/generic input/keyboard/generic
xbmc/input/mouse input/mouse
xbmc/input/mouse/generic input/mouse/generic
xbmc/listproviders listproviders
-xbmc/media media
xbmc/messaging messaging
xbmc/messaging/helpers messagingHelpers
xbmc/pictures pictures
diff --git a/xbmc/ServiceBroker.cpp b/xbmc/ServiceBroker.cpp
index 8bf3f087eb..f5265dffcb 100644
--- a/xbmc/ServiceBroker.cpp
+++ b/xbmc/ServiceBroker.cpp
@@ -251,3 +251,15 @@ void CServiceBroker::UnregisterAppPort()
{
m_pAppPort.reset();
}
+
+
+CDecoderFilterManager* CServiceBroker::m_decoderFilterManager = nullptr;
+void CServiceBroker::RegisterDecoderFilterManager(CDecoderFilterManager* manager)
+{
+ m_decoderFilterManager = manager;
+}
+
+CDecoderFilterManager* CServiceBroker::GetDecoderFilterManager()
+{
+ return m_decoderFilterManager;
+}
diff --git a/xbmc/ServiceBroker.h b/xbmc/ServiceBroker.h
index 9e11d323d5..66a3b7eec9 100644
--- a/xbmc/ServiceBroker.h
+++ b/xbmc/ServiceBroker.h
@@ -52,6 +52,7 @@ class CEventLog;
class CGUIComponent;
class CAppInboundProtocol;
class CSettingsComponent;
+class CDecoderFilterManager;
namespace KODI
{
@@ -127,6 +128,9 @@ public:
static void RegisterAppPort(std::shared_ptr<CAppInboundProtocol> port);
static void UnregisterAppPort();
+ static void RegisterDecoderFilterManager(CDecoderFilterManager* manager);
+ static CDecoderFilterManager* GetDecoderFilterManager();
+
private:
static std::shared_ptr<ANNOUNCEMENT::CAnnouncementManager> m_pAnnouncementManager;
static CGUIComponent* m_pGUI;
@@ -134,4 +138,5 @@ private:
static IAE* m_pActiveAE;
static std::shared_ptr<CAppInboundProtocol> m_pAppPort;
static CSettingsComponent* m_pSettingsComponent;
+ static CDecoderFilterManager* m_decoderFilterManager;
};
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
index eb51c164ba..70a565b438 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp
@@ -14,43 +14,43 @@
#include "DVDVideoCodecAndroidMediaCodec.h"
+#include <cassert>
+#include <memory>
+
#include <androidjni/ByteBuffer.h>
#include <androidjni/MediaCodecList.h>
#include <androidjni/MediaCodecInfo.h>
#include <androidjni/Surface.h>
#include <androidjni/SurfaceTexture.h>
-#include <media/NdkMediaCrypto.h>
-#include "Application.h"
-#include "ServiceBroker.h"
-#include "messaging/ApplicationMessenger.h"
-#include "cores/VideoPlayer/Interface/Addon/TimingConstants.h"
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
-#include "utils/BitstreamConverter.h"
-#include "utils/BitstreamWriter.h"
-#include "utils/CPUInfo.h"
-#include "utils/log.h"
+#include <media/NdkMediaCrypto.h>
+#include "Application.h"
#include "DVDCodecs/DVDFactoryCodec.h"
#include "platform/android/activity/XBMCApp.h"
#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
#include "cores/VideoPlayer/Interface/Addon/DemuxCrypto.h"
+#include "cores/VideoPlayer/Interface/Addon/TimingConstants.h"
#include "cores/VideoPlayer/Process/VideoBuffer.h"
+#include "media/decoderfilter/DecoderFilterManager.h"
+#include "messaging/ApplicationMessenger.h"
#include "platform/android/activity/AndroidFeatures.h"
#include "platform/android/activity/JNIXBMCSurfaceTextureOnFrameAvailableListener.h"
+#include "ServiceBroker.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "system.h"
-
+#include "utils/BitstreamConverter.h"
+#include "utils/BitstreamWriter.h"
+#include "utils/CPUInfo.h"
+#include "utils/log.h"
#include "utils/TimeUtils.h"
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <cassert>
-#include <memory>
#define XMEDIAFORMAT_KEY_ROTATION "rotation-degrees"
#define XMEDIAFORMAT_KEY_SLICE "slice-height"
@@ -73,31 +73,6 @@ enum MEDIACODEC_STATES
MEDIACODEC_STATE_STOPPED
};
-static bool IsBlacklisted(const std::string &name)
-{
- static const char *blacklisted_decoders[] = {
- // No software decoders
- "OMX.google",
- // For Rockchip non-standard components
- "AVCDecoder",
- "AVCDecoder_FLASH",
- "FLVDecoder",
- "M2VDecoder",
- "M4vH263Decoder",
- "RVDecoder",
- "VC1Decoder",
- "VPXDecoder",
- // End of Rockchip
- NULL
- };
- for (const char **ptr = blacklisted_decoders; *ptr; ptr++)
- {
- if (!strnicmp(*ptr, name.c_str(), strlen(*ptr)))
- return true;
- }
- return false;
-}
-
static bool IsSupportedColorFormat(int color_format)
{
static const int supported_colorformats[] = {
@@ -407,11 +382,6 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open - %s\n", "null size, cannot handle");
goto FAIL;
}
- else if (hints.stills)
- {
- // Won't work reliably
- goto FAIL;
- }
else if (hints.orientation && m_render_surface && CJNIBase::GetSDKVersion() < 23)
{
CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open - %s\n", "Surface does not support orientation before API 23");
@@ -599,42 +569,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
}
if (m_hints.cryptoSession)
- {
- CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec::Open Initializing MediaCrypto");
-
- const AMediaUUID *uuid(nullptr);
- const AMediaUUID wvuuid = {0xED,0xEF,0x8B,0xA9,0x79,0xD6,0x4A,0xCE,0xA3,0xC8,0x27,0xDC,0xD5,0x1D,0x21,0xED};
- const AMediaUUID pruuid = {0x9A,0x04,0xF0,0x79,0x98,0x40,0x42,0x86,0xAB,0x92,0xE6,0x5B,0xE0,0x88,0x5F,0x95};
-
- if (m_hints.cryptoSession->keySystem == CRYPTO_SESSION_SYSTEM_WIDEVINE)
- uuid = &wvuuid;
- else if (m_hints.cryptoSession->keySystem == CRYPTO_SESSION_SYSTEM_PLAYREADY)
- uuid = &pruuid;
- else
- {
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open Unsupported crypto-keysystem %u", m_hints.cryptoSession->keySystem);
- goto FAIL;
- }
-
- m_crypto = AMediaCrypto_new(*uuid, m_hints.cryptoSession->sessionId, m_hints.cryptoSession->sessionIdSize);
-
- if (!m_crypto)
- {
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open: MediaCrypto creation failed");
- goto FAIL;
- }
needSecureDecoder = AMediaCrypto_requiresSecureDecoderComponent(m_mime.c_str()) && (m_hints.cryptoSession->flags & DemuxCryptoSession::FLAG_SECURE_DECODER) != 0;
- }
-
- if (m_render_surface)
- {
- m_jnivideoview.reset(CJNIXBMCVideoView::createVideoView(this));
- if (!m_jnivideoview || !m_jnivideoview->waitForSurface(2000))
- {
- CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec: VideoView creation failed!!");
- goto FAIL;
- }
- }
m_codec = nullptr;
m_colorFormat = -1;
@@ -647,7 +582,7 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
continue;
m_codecname = codec_info.getName();
- if (IsBlacklisted(m_codecname))
+ if (!CServiceBroker::GetDecoderFilterManager()->isValid(m_codecname, m_hints))
continue;
CLog::Log(LOGNOTICE, "CDVDVideoCodecAndroidMediaCodec::Open Testing codec:%s", m_codecname.c_str());
@@ -714,6 +649,43 @@ bool CDVDVideoCodecAndroidMediaCodec::Open(CDVDStreamInfo &hints, CDVDCodecOptio
goto FAIL;
}
+ if (m_hints.cryptoSession)
+ {
+ CLog::Log(LOGDEBUG, "CDVDVideoCodecAndroidMediaCodec::Open Initializing MediaCrypto");
+
+ const AMediaUUID *uuid(nullptr);
+ const AMediaUUID wvuuid = {0xED,0xEF,0x8B,0xA9,0x79,0xD6,0x4A,0xCE,0xA3,0xC8,0x27,0xDC,0xD5,0x1D,0x21,0xED};
+ const AMediaUUID pruuid = {0x9A,0x04,0xF0,0x79,0x98,0x40,0x42,0x86,0xAB,0x92,0xE6,0x5B,0xE0,0x88,0x5F,0x95};
+
+ if (m_hints.cryptoSession->keySystem == CRYPTO_SESSION_SYSTEM_WIDEVINE)
+ uuid = &wvuuid;
+ else if (m_hints.cryptoSession->keySystem == CRYPTO_SESSION_SYSTEM_PLAYREADY)
+ uuid = &pruuid;
+ else
+ {
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open Unsupported crypto-keysystem %u", m_hints.cryptoSession->keySystem);
+ goto FAIL;
+ }
+
+ m_crypto = AMediaCrypto_new(*uuid, m_hints.cryptoSession->sessionId, m_hints.cryptoSession->sessionIdSize);
+
+ if (!m_crypto)
+ {
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::Open: MediaCrypto creation failed");
+ goto FAIL;
+ }
+ }
+
+ if (m_render_surface)
+ {
+ m_jnivideoview.reset(CJNIXBMCVideoView::createVideoView(this));
+ if (!m_jnivideoview || !m_jnivideoview->waitForSurface(2000))
+ {
+ CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec: VideoView creation failed!!");
+ goto FAIL;
+ }
+ }
+
// setup a YUV420P VideoPicture buffer.
// first make sure all properties are reset.
m_videobuffer.Reset();
diff --git a/xbmc/interfaces/legacy/DrmCryptoSession.cpp b/xbmc/interfaces/legacy/DrmCryptoSession.cpp
index f5c3677fa7..5bd4de163f 100644
--- a/xbmc/interfaces/legacy/DrmCryptoSession.cpp
+++ b/xbmc/interfaces/legacy/DrmCryptoSession.cpp
@@ -7,7 +7,7 @@
*/
#include "DrmCryptoSession.h"
-#include "drm/CryptoSession.h"
+#include "media/drm/CryptoSession.h"
using namespace XbmcCommons;
diff --git a/xbmc/media/decoderfilter/CMakeLists.txt b/xbmc/media/decoderfilter/CMakeLists.txt
new file mode 100644
index 0000000000..48febb7c34
--- /dev/null
+++ b/xbmc/media/decoderfilter/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(SOURCES DecoderFilterManager.cpp)
+
+set(HEADERS DecoderFilterManager.h)
+
+core_add_library(decoderfilter)
diff --git a/xbmc/media/decoderfilter/DecoderFilterManager.cpp b/xbmc/media/decoderfilter/DecoderFilterManager.cpp
new file mode 100644
index 0000000000..5b3dc0c2f2
--- /dev/null
+++ b/xbmc/media/decoderfilter/DecoderFilterManager.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2013-2019 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+
+ /**
+ * \file media\hwdecoder\DecoderFilterManager.cpp
+ * \brief Implements CDecoderFilterManager class.
+ *
+ */
+
+#include "DecoderFilterManager.h"
+#include "cores/VideoPlayer/DVDStreamInfo.h"
+
+#include "filesystem/File.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "utils/XMLUtils.h"
+#include "Util.h"
+
+static const char* TAG_ROOT = "decoderfilter";
+static const char* TAG_FILTER = "filter";
+static const char* TAG_NAME = "name";
+static const char* TAG_GENERAL = "allowed";
+static const char* TAG_STILLS = "stills-allowed";
+static const char* TAG_DVD = "dvd-allowed";
+static const char* TAG_MINHEIGHT = "min-height";
+static const char* HWDFFileName = "special://masterprofile/decoderfilter.xml";
+static const char* CLASSNAME = "CDecoderFilter";
+
+CDecoderFilter::CDecoderFilter(const std::string& name, uint32_t flags, int minHeight)
+ : m_name(name)
+ , m_flags(flags)
+ , m_minHeight(minHeight)
+{
+}
+
+bool CDecoderFilter::isValid(const CDVDStreamInfo& streamInfo) const
+{
+ uint32_t flags = FLAG_GENERAL_ALLOWED;
+
+ if (streamInfo.stills)
+ flags |= FLAG_STILLS_ALLOWED;
+
+ if (streamInfo.dvd)
+ flags |= FLAG_DVD_ALLOWED;
+
+ if ((flags & m_flags) != flags)
+ return false;
+
+ // remove codec pitch for comparision
+ if (m_minHeight && (streamInfo.height & ~31) <= m_minHeight)
+ return false;
+
+ return true;
+}
+
+bool CDecoderFilter::Load(const TiXmlNode *node)
+{
+ bool flagBool = false;
+
+ XMLUtils::GetString(node, TAG_NAME, m_name);
+ XMLUtils::GetBoolean(node, TAG_GENERAL, flagBool);
+ if (flagBool)
+ m_flags |= FLAG_GENERAL_ALLOWED;
+ flagBool = false;
+
+ XMLUtils::GetBoolean(node, TAG_STILLS, flagBool);
+ if (flagBool)
+ m_flags |= FLAG_STILLS_ALLOWED;
+ flagBool = false;
+
+ XMLUtils::GetBoolean(node, TAG_DVD, flagBool);
+ if (flagBool)
+ m_flags |= FLAG_DVD_ALLOWED;
+
+ XMLUtils::GetInt(node, TAG_MINHEIGHT, m_minHeight);
+
+ return true;
+}
+
+bool CDecoderFilter::Save(TiXmlNode *node) const
+{
+ // Now write each of the pieces of information we need...
+ XMLUtils::SetString(node, TAG_NAME, m_name);
+ XMLUtils::SetBoolean(node, TAG_GENERAL, (m_flags & FLAG_GENERAL_ALLOWED) != 0);
+ XMLUtils::SetBoolean(node, TAG_STILLS, (m_flags & FLAG_STILLS_ALLOWED) != 0);
+ XMLUtils::SetBoolean(node, TAG_DVD, (m_flags & FLAG_DVD_ALLOWED) != 0);
+ XMLUtils::SetInt(node, TAG_MINHEIGHT, m_minHeight);
+ return true;
+}
+
+
+/****************************************/
+
+bool CDecoderFilterManager::isValid(const std::string& name, const CDVDStreamInfo& streamInfo)
+{
+ CSingleLock lock(m_critical);
+ std::set<CDecoderFilter>::const_iterator filter(m_filters.find(name));
+ return filter != m_filters.end() ? filter->isValid(streamInfo) : m_filters.empty();
+}
+
+void CDecoderFilterManager::add(const CDecoderFilter& filter)
+{
+ CSingleLock lock(m_critical);
+ std::pair<std::set<CDecoderFilter>::iterator, bool> res = m_filters.insert(filter);
+ m_dirty = m_dirty || res.second;
+}
+
+bool CDecoderFilterManager::Load()
+{
+ CSingleLock lock(m_critical);
+
+ m_filters.clear();
+
+ std::string fileName = CUtil::TranslateSpecialSource(HWDFFileName);
+ if (!XFILE::CFile::Exists(fileName))
+ return true;
+
+ CLog::Log(LOGNOTICE, "%s: loading filters from %s", CLASSNAME, fileName.c_str());
+
+ CXBMCTinyXML xmlDoc;
+ if (!xmlDoc.LoadFile(fileName))
+ {
+ CLog::Log(LOGERROR, "%s: error loading: line %d, %s", CLASSNAME, xmlDoc.ErrorRow(), xmlDoc.ErrorDesc());
+ return false;
+ }
+
+ const TiXmlElement *pRootElement = xmlDoc.RootElement();
+ if (!pRootElement || !StringUtils::EqualsNoCase(pRootElement->ValueStr(), TAG_ROOT))
+ {
+ CLog::Log(LOGERROR, "%s: invalid root element (%s)", CLASSNAME, pRootElement->ValueStr().c_str());
+ return false;
+ }
+
+ const TiXmlElement *pFilter = pRootElement->FirstChildElement(TAG_FILTER);
+ while (pFilter)
+ {
+ CDecoderFilter filter("");
+ if (filter.Load(pFilter))
+ m_filters.insert(filter);
+ pFilter = pFilter->NextSiblingElement(TAG_FILTER);
+ }
+ return true;
+}
+
+bool CDecoderFilterManager::Save() const
+{
+ CSingleLock lock(m_critical);
+ if (!m_dirty || m_filters.empty())
+ return true;
+
+ CXBMCTinyXML doc;
+ TiXmlElement xmlRootElement(TAG_ROOT);
+ TiXmlNode *pRoot = doc.InsertEndChild(xmlRootElement);
+ if (pRoot == NULL)
+ return false;
+
+ for (const CDecoderFilter& filter : m_filters)
+ {
+ // Write the resolution tag
+ TiXmlElement filterElem(TAG_FILTER);
+ TiXmlNode *pNode = pRoot->InsertEndChild(filterElem);
+ if (pNode == NULL)
+ return false;
+
+ filter.Save(pNode);
+ }
+ std::string fileName = CUtil::TranslateSpecialSource(HWDFFileName);
+ return doc.SaveFile(fileName);
+}
diff --git a/xbmc/media/decoderfilter/DecoderFilterManager.h b/xbmc/media/decoderfilter/DecoderFilterManager.h
new file mode 100644
index 0000000000..ba43750b61
--- /dev/null
+++ b/xbmc/media/decoderfilter/DecoderFilterManager.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013-2019 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+/**
+ * \file platform\DecoderFilter.h
+ * \brief Declares CDecoderFilterManager which gives control about how / when to use platform decoder.
+ *
+ */
+#include <string>
+#include <cinttypes>
+#include <set>
+
+#include "threads/CriticalSection.h"
+
+class TiXmlNode;
+class CDVDStreamInfo;
+
+/**
+* @class CDecoderFilter
+*
+* @brief Declaration of CDecoderFilter.
+*
+*/
+class CDecoderFilter
+{
+public:
+ /**
+ * @brief Flags to control decoder validity.
+ */
+ enum : uint32_t
+ {
+ FLAG_GENERAL_ALLOWED = 1, ///< early false exit if set
+ FLAG_STILLS_ALLOWED = 2, ///< early false exit if set and stream is marked as "has stillframes"
+ FLAG_DVD_ALLOWED = 4 ///< early false exit if set and stream is marked as dvd
+ };
+
+ /**
+ * \fn CDecoderFilter::CDecoderFilter(const std::string& name);
+ * \brief constructs a CDecoderFilter
+ * \param name decodername
+ * \return nothing.
+ */
+ CDecoderFilter(const std::string& name) : m_name(name) {};
+
+ /**
+ * \fn CDecoderFilter::CDecoderFilter(const std::string& name, uint32_t flags, uint32_t maxWidth, uint32_t maxHeight);
+ * \brief constructs a CDecoderFilter
+ * \param name decodername
+ * \param flags collection of FLAG_ values, bitwise OR
+ * \param minHeight minimum height of stream allowed by this decoder
+ * \return nothing.
+ */
+ CDecoderFilter(const std::string& name, uint32_t flags, int minHeight);
+
+ virtual ~CDecoderFilter() = default;
+
+ /**
+ * \fn CDecoderFilter::operator < (const CDecoderFilter& other);
+ * \brief used for sorting / replacing / find
+ */
+ bool operator < (const CDecoderFilter& other) const { return m_name < other.m_name; };
+
+ /**
+ * \fn CDecoderFilter::isValid(const CDVDStreamInfo& streamInfo);
+ * \brief test if stream is allowed by filter.
+ * \return true if valid, false otherwise
+ */
+ virtual bool isValid(const CDVDStreamInfo& streamInfo) const;
+
+ /**
+ * \fn CDecoderFilter::Load(const TiXmlNode *settings);
+ * \brief load all members from XML node
+ * \param node filter node from where to get the values
+ * \return true if operation was successful, false on error
+ */
+ virtual bool Load(const TiXmlNode *node);
+
+ /**
+ * \fn CDecoderFilter::Save(TiXmlNode *settings);
+ * \brief store all members in XML node
+ * \param node a ready to use filter setting node
+ * \return true if operation was successful, false on error
+ */
+ virtual bool Save(TiXmlNode *node) const;
+
+
+private:
+ std::string m_name;
+
+ uint32_t m_flags = 0;
+ int m_minHeight = 0;
+};
+
+
+/**
+* @class CDecoderFilterManager
+*
+* @brief Class which handles multiple CDecoderFilter elements.
+*
+*/
+
+class CDecoderFilterManager
+{
+public:
+ CDecoderFilterManager() { Load(); };
+ virtual ~CDecoderFilterManager() { Save(); };
+
+ /**
+ * \fn bool CDecoderFilterManager::add(const CDecoderFilter& filter);
+ * \brief adds an CDecoderFilter if key [filter.name] is not yet existing.
+ * \param filter the decoder filter to add / replace.
+ * \return nothing.
+ */
+ void add(const CDecoderFilter& filter);
+
+
+ /**
+ * \fn bool CDecoderFilterManager::validate(const std::string& name, const CDVDStreamInfo& streamInfo);
+ * \brief Validates if decoder with name [name] is allowed to be used.
+ * \param streamInfo Stream information used to validate().
+ * \return true if HardwarDecoder could be used, false otherwise.
+ */
+ bool isValid(const std::string& name, const CDVDStreamInfo& streamInfo);
+
+protected:
+ bool Load();
+ bool Save() const;
+
+private:
+ bool m_dirty = false;
+ std::set<CDecoderFilter> m_filters;
+ mutable CCriticalSection m_critical;
+};
diff --git a/xbmc/drm/CMakeLists.txt b/xbmc/media/drm/CMakeLists.txt
index 15b2a8429f..15b2a8429f 100644
--- a/xbmc/drm/CMakeLists.txt
+++ b/xbmc/media/drm/CMakeLists.txt
diff --git a/xbmc/drm/CryptoSession.cpp b/xbmc/media/drm/CryptoSession.cpp
index 03c3f133e4..9e5e8888d7 100644
--- a/xbmc/drm/CryptoSession.cpp
+++ b/xbmc/media/drm/CryptoSession.cpp
@@ -17,7 +17,7 @@ void CCryptoSession::RegisterInterface(GET_CRYPTO_SESSION_INTERFACE_FN fn)
s_registeredInterfaces.push_back(fn);
}
-CCryptoSession* CCryptoSession::GetCryptoSession(const std::string &UUID, const std::string &cipherAlgo, const std::string &macAlgo)
+CCryptoSession* CCryptoSession::GetCryptoSession(const std::string& UUID, const std::string& cipherAlgo, const std::string& macAlgo)
{
CCryptoSession* retVal = nullptr;
for (auto fn : s_registeredInterfaces)
diff --git a/xbmc/drm/CryptoSession.h b/xbmc/media/drm/CryptoSession.h
index 21ba599f6f..603907df61 100644
--- a/xbmc/drm/CryptoSession.h
+++ b/xbmc/media/drm/CryptoSession.h
@@ -19,28 +19,28 @@ namespace DRM
{
class CCryptoSession;
- typedef CCryptoSession* (*GET_CRYPTO_SESSION_INTERFACE_FN)(const std::string &UUID, const std::string &cipherAlgo, const std::string &hmacAlgo);
+ typedef CCryptoSession* (*GET_CRYPTO_SESSION_INTERFACE_FN)(const std::string& UUID, const std::string& cipherAlgo, const std::string& hmacAlgo);
class CCryptoSession
{
public:
// Interface registration
- static CCryptoSession* GetCryptoSession(const std::string &UUID, const std::string &cipherAlgo, const std::string &macAlgo);
+ static CCryptoSession* GetCryptoSession(const std::string& UUID, const std::string& cipherAlgo, const std::string& macAlgo);
virtual ~CCryptoSession() {};
// Interface methods
- virtual XbmcCommons::Buffer GetKeyRequest(const XbmcCommons::Buffer &init, const std::string &mimeType, bool offlineKey, const std::map<std::string, std::string> &parameters) = 0;
- virtual std::string GetPropertyString(const std::string &name) = 0;
- virtual std::string ProvideKeyResponse(const XbmcCommons::Buffer &response) = 0;
+ virtual XbmcCommons::Buffer GetKeyRequest(const XbmcCommons::Buffer& init, const std::string& mimeType, bool offlineKey, const std::map<std::string, std::string>& parameters) = 0;
+ virtual std::string GetPropertyString(const std::string& name) = 0;
+ virtual std::string ProvideKeyResponse(const XbmcCommons::Buffer& response) = 0;
virtual void RemoveKeys() = 0;
- virtual void RestoreKeys(const std::string &keySetId) = 0;
- virtual void SetPropertyString(const std::string &name, const std::string &value) = 0;
+ virtual void RestoreKeys(const std::string& keySetId) = 0;
+ virtual void SetPropertyString(const std::string& name, const std::string& value) = 0;
// Crypto methods
- virtual XbmcCommons::Buffer Decrypt(const XbmcCommons::Buffer &cipherKeyId, const XbmcCommons::Buffer &input, const XbmcCommons::Buffer &iv) = 0;
- virtual XbmcCommons::Buffer Encrypt(const XbmcCommons::Buffer &cipherKeyId, const XbmcCommons::Buffer &input, const XbmcCommons::Buffer &iv) = 0;
- virtual XbmcCommons::Buffer Sign(const XbmcCommons::Buffer &macKeyId, const XbmcCommons::Buffer &message) = 0;
- virtual bool Verify(const XbmcCommons::Buffer &macKeyId, const XbmcCommons::Buffer &message, const XbmcCommons::Buffer &signature ) = 0;
+ virtual XbmcCommons::Buffer Decrypt(const XbmcCommons::Buffer& cipherKeyId, const XbmcCommons::Buffer& input, const XbmcCommons::Buffer& iv) = 0;
+ virtual XbmcCommons::Buffer Encrypt(const XbmcCommons::Buffer& cipherKeyId, const XbmcCommons::Buffer& input, const XbmcCommons::Buffer& iv) = 0;
+ virtual XbmcCommons::Buffer Sign(const XbmcCommons::Buffer& macKeyId, const XbmcCommons::Buffer& message) = 0;
+ virtual bool Verify(const XbmcCommons::Buffer& macKeyId, const XbmcCommons::Buffer& message, const XbmcCommons::Buffer& signature ) = 0;
protected:
static void RegisterInterface(GET_CRYPTO_SESSION_INTERFACE_FN fn);
diff --git a/xbmc/platform/android/drm/MediaDrmCryptoSession.h b/xbmc/platform/android/drm/MediaDrmCryptoSession.h
deleted file mode 100644
index 4fd0d4cc35..0000000000
--- a/xbmc/platform/android/drm/MediaDrmCryptoSession.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2005-2018 Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#pragma once
-
-#include "drm/CryptoSession.h"
-
-class CJNIMediaDrm;
-class CJNIMediaDrmCryptoSession;
-
-namespace DRM
-{
- class CharVecBuffer : public XbmcCommons::Buffer
- {
- public:
- inline CharVecBuffer(const XbmcCommons::Buffer &buf) : XbmcCommons::Buffer(buf) {};
-
- inline CharVecBuffer(const std::vector<char> &vec)
- : XbmcCommons::Buffer(vec.size())
- {
- memcpy(data(), vec.data(), vec.size());
- }
-
- inline operator std::vector<char>() const
- {
- return std::vector<char>(data(), data() + capacity());
- }
- };
-
- class CharVecBuffer;
-
- class CMediaDrmCryptoSession : public CCryptoSession
- {
- public:
- static void Register();
- CMediaDrmCryptoSession(const std::string &UUID, const std::string &cipherAlgo, const std::string &macAlgo);
- virtual ~CMediaDrmCryptoSession();
-
- // Interface methods
- XbmcCommons::Buffer GetKeyRequest(const XbmcCommons::Buffer &init, const std::string &mimeType, bool offlineKey, const std::map<std::string, std::string> &parameters) override;
- std::string GetPropertyString(const std::string &name) override;
- std::string ProvideKeyResponse(const XbmcCommons::Buffer &response) override;
- void RemoveKeys() override;
- void RestoreKeys(const std::string &keySetId) override;
- void SetPropertyString(const std::string &name, const std::string &value) override;
-
- // Crypto methods
- XbmcCommons::Buffer Decrypt(const XbmcCommons::Buffer &cipherKeyId, const XbmcCommons::Buffer &input, const XbmcCommons::Buffer &iv) override;
- XbmcCommons::Buffer Encrypt(const XbmcCommons::Buffer &cipherKeyId, const XbmcCommons::Buffer &input, const XbmcCommons::Buffer &iv) override;
- XbmcCommons::Buffer Sign(const XbmcCommons::Buffer &macKeyId, const XbmcCommons::Buffer &message) override;
- bool Verify(const XbmcCommons::Buffer &macKeyId, const XbmcCommons::Buffer &message, const XbmcCommons::Buffer &signature ) override;
-
- private:
- static CCryptoSession* Create(const std::string &UUID, const std::string &cipherAlgo, const std::string &hmacAlgo);
- bool OpenSession();
- void CloseSession();
- bool ProvisionRequest();
-
- CJNIMediaDrm *m_mediaDrm;
- CJNIMediaDrmCryptoSession *m_cryptoSession;
-
- std::string m_cipherAlgo;
- std::string m_macAlgo;
- std::string m_keySetId;
-
- bool m_hasKeys;
-
- CharVecBuffer *m_sessionId;
- };
-
-} //namespace
diff --git a/xbmc/platform/android/media/decoderfilter/CMakeLists.txt b/xbmc/platform/android/media/decoderfilter/CMakeLists.txt
new file mode 100644
index 0000000000..0763e456b5
--- /dev/null
+++ b/xbmc/platform/android/media/decoderfilter/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(SOURCES MediaCodecDecoderFilterManager.cpp)
+
+set(HEADERS MediaCodecDecoderFilterManager.h)
+
+core_add_library(mediacodecdecoderfilter)
diff --git a/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.cpp b/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.cpp
new file mode 100644
index 0000000000..376f88043a
--- /dev/null
+++ b/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013-2019 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+
+ /**
+ * \file media\hwdecoder\DecoderFilterManager.cpp
+ * \brief Implements CDecoderFilterManager class.
+ *
+ */
+
+#include "MediaCodecDecoderFilterManager.h"
+#include <androidjni/MediaCodecList.h>
+#include "utils/log.h"
+
+
+CMediaCodecDecoderFilterManager::CMediaCodecDecoderFilterManager()
+{
+ static const char *blacklisted_decoders[] = {
+ // No software decoders
+ "OMX.google",
+ // For Rockchip non-standard components
+ "AVCDecoder",
+ "AVCDecoder_FLASH",
+ "FLVDecoder",
+ "M2VDecoder",
+ "M4vH263Decoder",
+ "RVDecoder",
+ "VC1Decoder",
+ "VPXDecoder",
+ // End of Rockchip
+ NULL
+ };
+
+ unsigned int num_codecs = CJNIMediaCodecList::getCodecCount();
+ for (int i = 0; i < num_codecs; i++)
+ {
+ CJNIMediaCodecInfo codec_info = CJNIMediaCodecList::getCodecInfoAt(i);
+ if (codec_info.isEncoder())
+ continue;
+
+ std::string codecname = codec_info.getName();
+ uint32_t flags = CDecoderFilter::FLAG_GENERAL_ALLOWED | CDecoderFilter::FLAG_DVD_ALLOWED;
+ for (const char **ptr = blacklisted_decoders; *ptr && flags; ptr++)
+ {
+ if (!strnicmp(*ptr, codecname.c_str(), strlen(*ptr)))
+ flags = 0;
+ }
+ add(CDecoderFilter(codecname, flags, 0));
+ CLog::Log(LOGNOTICE, "Mediacodec decoder: %s", codecname.c_str());
+ }
+ Save();
+}
+
diff --git a/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h b/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h
new file mode 100644
index 0000000000..8114651bfe
--- /dev/null
+++ b/xbmc/platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013-2019 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "media/decoderfilter/DecoderFilterManager.h"
+
+
+class CMediaCodecDecoderFilterManager : public CDecoderFilterManager
+{
+public:
+ CMediaCodecDecoderFilterManager();
+};
diff --git a/xbmc/platform/android/drm/CMakeLists.txt b/xbmc/platform/android/media/drm/CMakeLists.txt
index ed49ca12c3..ed49ca12c3 100644
--- a/xbmc/platform/android/drm/CMakeLists.txt
+++ b/xbmc/platform/android/media/drm/CMakeLists.txt
diff --git a/xbmc/platform/android/drm/MediaDrmCryptoSession.cpp b/xbmc/platform/android/media/drm/MediaDrmCryptoSession.cpp
index 72f12a550d..43d4711c74 100644
--- a/xbmc/platform/android/drm/MediaDrmCryptoSession.cpp
+++ b/xbmc/platform/android/media/drm/MediaDrmCryptoSession.cpp
@@ -24,9 +24,9 @@ using namespace XbmcCommons;
class CharVecBuffer : public Buffer
{
public:
- inline CharVecBuffer(const Buffer &buf) : Buffer(buf) {};
+ inline CharVecBuffer(const Buffer& buf) : Buffer(buf) {};
- inline CharVecBuffer(const std::vector<char> &vec)
+ inline CharVecBuffer(const std::vector<char>& vec)
: Buffer(vec.size())
{
memcpy(data(), vec.data(), vec.size());
@@ -44,7 +44,7 @@ void CMediaDrmCryptoSession::Register()
CCryptoSession::RegisterInterface(CMediaDrmCryptoSession::Create);
}
-CMediaDrmCryptoSession::CMediaDrmCryptoSession(const std::string &UUID, const std::string &cipherAlgo, const std::string &macAlgo)
+CMediaDrmCryptoSession::CMediaDrmCryptoSession(const std::string& UUID, const std::string& cipherAlgo, const std::string& macAlgo)
: m_mediaDrm(nullptr)
, m_cryptoSession(nullptr)
, m_cipherAlgo(cipherAlgo)
@@ -91,14 +91,14 @@ CMediaDrmCryptoSession::~CMediaDrmCryptoSession()
delete m_mediaDrm, m_mediaDrm = nullptr;
}
-CCryptoSession* CMediaDrmCryptoSession::Create(const std::string &UUID, const std::string &cipherAlgo, const std::string &macAlgo)
+CCryptoSession* CMediaDrmCryptoSession::Create(const std::string& UUID, const std::string& cipherAlgo, const std::string& macAlgo)
{
CMediaDrmCryptoSession *res = nullptr;;
try
{
res = new CMediaDrmCryptoSession(UUID, cipherAlgo, macAlgo);
}
- catch (std::runtime_error &e)
+ catch (std::runtime_error& e)
{
delete res, res = nullptr;
}
@@ -108,10 +108,10 @@ CCryptoSession* CMediaDrmCryptoSession::Create(const std::string &UUID, const st
/*****************/
// Interface methods
-Buffer CMediaDrmCryptoSession::GetKeyRequest(const Buffer &init,
- const std::string &mimeType,
+Buffer CMediaDrmCryptoSession::GetKeyRequest(const Buffer& init,
+ const std::string& mimeType,
bool offlineKey,
- const std::map<std::string, std::string> &parameters)
+ const std::map<std::string, std::string>& parameters)
{
if (m_mediaDrm && m_sessionId)
{
@@ -124,7 +124,7 @@ Buffer CMediaDrmCryptoSession::GetKeyRequest(const Buffer &init,
}
-std::string CMediaDrmCryptoSession::GetPropertyString(const std::string &name)
+std::string CMediaDrmCryptoSession::GetPropertyString(const std::string& name)
{
if (m_mediaDrm)
return m_mediaDrm->getPropertyString(name);
@@ -133,7 +133,7 @@ std::string CMediaDrmCryptoSession::GetPropertyString(const std::string &name)
}
-std::string CMediaDrmCryptoSession::ProvideKeyResponse(const Buffer &response)
+std::string CMediaDrmCryptoSession::ProvideKeyResponse(const Buffer& response)
{
if (m_mediaDrm)
{
@@ -154,7 +154,7 @@ void CMediaDrmCryptoSession::RemoveKeys()
}
}
-void CMediaDrmCryptoSession::RestoreKeys(const std::string &keySetId)
+void CMediaDrmCryptoSession::RestoreKeys(const std::string& keySetId)
{
if (m_mediaDrm && keySetId != m_keySetId)
{
@@ -164,14 +164,14 @@ void CMediaDrmCryptoSession::RestoreKeys(const std::string &keySetId)
}
}
-void CMediaDrmCryptoSession::SetPropertyString(const std::string &name, const std::string &value)
+void CMediaDrmCryptoSession::SetPropertyString(const std::string& name, const std::string& value)
{
if (m_mediaDrm)
m_mediaDrm->setPropertyString(name, value);
}
// Crypto methods
-Buffer CMediaDrmCryptoSession::Decrypt(const Buffer &cipherKeyId, const Buffer &input, const Buffer &iv)
+Buffer CMediaDrmCryptoSession::Decrypt(const Buffer& cipherKeyId, const Buffer& input, const Buffer& iv)
{
if (m_cryptoSession)
return CharVecBuffer(m_cryptoSession->decrypt(CharVecBuffer(cipherKeyId), CharVecBuffer(input), CharVecBuffer(iv)));
@@ -179,7 +179,7 @@ Buffer CMediaDrmCryptoSession::Decrypt(const Buffer &cipherKeyId, const Buffer &
return Buffer();
}
-Buffer CMediaDrmCryptoSession::Encrypt(const Buffer &cipherKeyId, const Buffer &input, const Buffer &iv)
+Buffer CMediaDrmCryptoSession::Encrypt(const Buffer& cipherKeyId, const Buffer& input, const Buffer& iv)
{
if (m_cryptoSession)
return CharVecBuffer(m_cryptoSession->encrypt(CharVecBuffer(cipherKeyId), CharVecBuffer(input), CharVecBuffer(iv)));
@@ -187,7 +187,7 @@ Buffer CMediaDrmCryptoSession::Encrypt(const Buffer &cipherKeyId, const Buffer &
return Buffer();
}
-Buffer CMediaDrmCryptoSession::Sign(const Buffer &macKeyId, const Buffer &message)
+Buffer CMediaDrmCryptoSession::Sign(const Buffer& macKeyId, const Buffer& message)
{
if (m_cryptoSession)
return CharVecBuffer(m_cryptoSession->sign(CharVecBuffer(macKeyId), CharVecBuffer(message)));
@@ -195,7 +195,7 @@ Buffer CMediaDrmCryptoSession::Sign(const Buffer &macKeyId, const Buffer &messag
return Buffer();
}
-bool CMediaDrmCryptoSession::Verify(const Buffer &macKeyId, const Buffer &message, const Buffer &signature)
+bool CMediaDrmCryptoSession::Verify(const Buffer& macKeyId, const Buffer& message, const Buffer& signature)
{
if (m_cryptoSession)
return m_cryptoSession->verify(CharVecBuffer(macKeyId), CharVecBuffer(message), CharVecBuffer(signature));
diff --git a/xbmc/platform/android/media/drm/MediaDrmCryptoSession.h b/xbmc/platform/android/media/drm/MediaDrmCryptoSession.h
new file mode 100644
index 0000000000..e321bc18bd
--- /dev/null
+++ b/xbmc/platform/android/media/drm/MediaDrmCryptoSession.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "media/drm/CryptoSession.h"
+
+class CJNIMediaDrm;
+class CJNIMediaDrmCryptoSession;
+
+namespace DRM
+{
+ class CharVecBuffer : public XbmcCommons::Buffer
+ {
+ public:
+ inline CharVecBuffer(const XbmcCommons::Buffer& buf) : XbmcCommons::Buffer(buf) {};
+
+ inline CharVecBuffer(const std::vector<char>& vec)
+ : XbmcCommons::Buffer(vec.size())
+ {
+ memcpy(data(), vec.data(), vec.size());
+ }
+
+ inline operator std::vector<char>() const
+ {
+ return std::vector<char>(data(), data() + capacity());
+ }
+ };
+
+ class CharVecBuffer;
+
+ class CMediaDrmCryptoSession : public CCryptoSession
+ {
+ public:
+ static void Register();
+ CMediaDrmCryptoSession(const std::string& UUID, const std::string& cipherAlgo, const std::string& macAlgo);
+ virtual ~CMediaDrmCryptoSession();
+
+ // Interface methods
+ XbmcCommons::Buffer GetKeyRequest(const XbmcCommons::Buffer& init, const std::string& mimeType, bool offlineKey, const std::map<std::string, std::string>& parameters) override;
+ std::string GetPropertyString(const std::string& name) override;
+ std::string ProvideKeyResponse(const XbmcCommons::Buffer& response) override;
+ void RemoveKeys() override;
+ void RestoreKeys(const std::string& keySetId) override;
+ void SetPropertyString(const std::string& name, const std::string& value) override;
+
+ // Crypto methods
+ XbmcCommons::Buffer Decrypt(const XbmcCommons::Buffer& cipherKeyId, const XbmcCommons::Buffer& input, const XbmcCommons::Buffer& iv) override;
+ XbmcCommons::Buffer Encrypt(const XbmcCommons::Buffer& cipherKeyId, const XbmcCommons::Buffer& input, const XbmcCommons::Buffer& iv) override;
+ XbmcCommons::Buffer Sign(const XbmcCommons::Buffer& macKeyId, const XbmcCommons::Buffer& message) override;
+ bool Verify(const XbmcCommons::Buffer& macKeyId, const XbmcCommons::Buffer& message, const XbmcCommons::Buffer& signature ) override;
+
+ private:
+ static CCryptoSession* Create(const std::string& UUID, const std::string& cipherAlgo, const std::string& hmacAlgo);
+ bool OpenSession();
+ void CloseSession();
+ bool ProvisionRequest();
+
+ CJNIMediaDrm* m_mediaDrm;
+ CJNIMediaDrmCryptoSession* m_cryptoSession;
+
+ std::string m_cipherAlgo;
+ std::string m_macAlgo;
+ std::string m_keySetId;
+
+ bool m_hasKeys;
+
+ CharVecBuffer* m_sessionId;
+ };
+
+} //namespace
diff --git a/xbmc/windowing/android/WinSystemAndroid.cpp b/xbmc/windowing/android/WinSystemAndroid.cpp
index 9c7807321b..df4bf99161 100644
--- a/xbmc/windowing/android/WinSystemAndroid.cpp
+++ b/xbmc/windowing/android/WinSystemAndroid.cpp
@@ -11,19 +11,10 @@
#include <string.h>
#include <float.h>
-#include "WinEventsAndroid.h"
-#include "OSScreenSaverAndroid.h"
-#include "ServiceBroker.h"
-#include "windowing/GraphicContext.h"
-#include "windowing/Resolution.h"
-#include "settings/DisplaySettings.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "guilib/DispResource.h"
-#include "utils/log.h"
-#include "threads/SingleLock.h"
-#include "platform/android/activity/XBMCApp.h"
+#include <EGL/egl.h>
+#include <EGL/eglplatform.h>
+#include "addons/interfaces/platform/android/System.h"
#include "cores/RetroPlayer/process/android/RPProcessInfoAndroid.h"
#include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.h"
@@ -31,13 +22,21 @@
#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.h"
#include "cores/VideoPlayer/Process/android/ProcessInfoAndroid.h"
#include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.h"
+#include "guilib/DispResource.h"
+#include "OSScreenSaverAndroid.h"
#include "platform/android/powermanagement/AndroidPowerSyscall.h"
-#include "addons/interfaces/platform/android/System.h"
-#include "platform/android/drm/MediaDrmCryptoSession.h"
-#include <androidjni/MediaCodecList.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglplatform.h>
+#include "platform/android/media/drm/MediaDrmCryptoSession.h"
+#include "platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h"
+#include "platform/android/activity/XBMCApp.h"
+#include "ServiceBroker.h"
+#include "settings/DisplaySettings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "windowing/GraphicContext.h"
+#include "windowing/Resolution.h"
+#include "WinEventsAndroid.h"
using namespace KODI;
@@ -72,6 +71,9 @@ bool CWinSystemAndroid::InitWindowSystem()
m_android = new CAndroidUtils();
+ m_decoderFilterManager = new(CMediaCodecDecoderFilterManager);
+ CServiceBroker::RegisterDecoderFilterManager(m_decoderFilterManager);
+
CDVDVideoCodecAndroidMediaCodec::Register();
CDVDAudioCodecAndroidMediaCodec::Register();
@@ -89,9 +91,14 @@ bool CWinSystemAndroid::InitWindowSystem()
bool CWinSystemAndroid::DestroyWindowSystem()
{
CLog::Log(LOGNOTICE, "CWinSystemAndroid::%s", __FUNCTION__);
+
delete m_android;
m_android = nullptr;
+ CServiceBroker::RegisterDecoderFilterManager(nullptr);
+ delete m_decoderFilterManager;
+ m_decoderFilterManager = nullptr;
+
return true;
}
@@ -182,17 +189,6 @@ void CWinSystemAndroid::UpdateResolutions()
}
res_index = (RESOLUTION)((int)res_index + 1);
}
-
- unsigned int num_codecs = CJNIMediaCodecList::getCodecCount();
- for (int i = 0; i < num_codecs; i++)
- {
- CJNIMediaCodecInfo codec_info = CJNIMediaCodecList::getCodecInfoAt(i);
- if (codec_info.isEncoder())
- continue;
-
- std::string codecname = codec_info.getName();
- CLog::Log(LOGNOTICE, "Mediacodec: %s", codecname.c_str());
- }
}
void CWinSystemAndroid::OnTimeout()
diff --git a/xbmc/windowing/android/WinSystemAndroid.h b/xbmc/windowing/android/WinSystemAndroid.h
index 04a8f4a099..e7f11dbff2 100644
--- a/xbmc/windowing/android/WinSystemAndroid.h
+++ b/xbmc/windowing/android/WinSystemAndroid.h
@@ -16,6 +16,7 @@
#include "threads/Timer.h"
#include "EGL/egl.h"
+class CDecoderFilterManager;
class IDispResource;
class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback
@@ -74,4 +75,5 @@ protected:
CCriticalSection m_resourceSection;
std::vector<IDispResource*> m_resources;
+ CDecoderFilterManager *m_decoderFilterManager;
};