Skip to content

Commit

Permalink
Properly compiles
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDaChicken committed Oct 19, 2023
1 parent 54b3f50 commit 6168bb2
Show file tree
Hide file tree
Showing 22 changed files with 2,056 additions and 2 deletions.
15 changes: 15 additions & 0 deletions lib/mfcdm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.10)
project(mfcdm_library)

add_library(mfcdm_library STATIC
mfcdm/MediaFoundationCdm.h
mfcdm/MediaFoundationCdm.cpp
mfcdm/MediaFoundationCdmFactory.cpp
mfcdm/MediaFoundationCdmSession.cpp
mfcdm/MediaFoundationSession.cpp
mfcdm/Log.cpp
)

target_include_directories(mfcdm_library PUBLIC ${PROJECT_SOURCE_DIR})
target_link_libraries(mfcdm_library PRIVATE cdm_library propsys mf mfplat mfplay mfreadwrite mfuuid wmcodecdspuuid)
set_target_properties(mfcdm_library PROPERTIES POSITION_INDEPENDENT_CODE True)
47 changes: 47 additions & 0 deletions lib/mfcdm/mfcdm/Log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "Log.h"

#include <cstdarg>
#include <cstdio>

typedef struct
{
const char* name;
int cur_level;
void (*msg_callback)(int level, char* msg);
} debug_ctx_t;

static debug_ctx_t debug_ctx = {"MF", MFCDM::MFLOG_NONE, NULL};


static inline void __dbg(debug_ctx_t* ctx, int level, const char* fmt, va_list ap)
{
if (ctx != NULL && level <= ctx->cur_level)
{
char msg[4096];
int len = snprintf(msg, sizeof(msg), "[%s] ", ctx->name);
vsnprintf(msg + len, sizeof(msg) - len, fmt, ap);
if (ctx->msg_callback)
{
ctx->msg_callback(level, msg);
}
}
}

void MFCDM::LogAll()
{
debug_ctx.cur_level = MFLOG_ALL;
}

void MFCDM::Log(LogLevel level, const char* fmt, ...)
{
va_list ap;

va_start(ap, fmt);
__dbg(&debug_ctx, level, fmt, ap);
va_end(ap);
}

void MFCDM::SetMFMsgCallback(void (*msgcb)(int level, char*))
{
debug_ctx.msg_callback = msgcb;
}
17 changes: 17 additions & 0 deletions lib/mfcdm/mfcdm/Log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace MFCDM
{
enum LogLevel
{
MFLOG_NONE = -1,
MFLOG_ERROR,
MFLOG_WARN,
MFLOG_INFO,
MFLOG_DEBUG,
MFLOG_ALL = 100
};

void LogAll();
void Log(LogLevel level, const char* fmt, ...);
void SetMFMsgCallback(void (*msgcb)(int level, char*));

} // namespace MFCDM
123 changes: 123 additions & 0 deletions lib/mfcdm/mfcdm/MediaFoundationCdm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2023 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.
*/

#include "MediaFoundationCdm.h"

#include "Log.h"
#include "MediaFoundationCdmFactory.h"
#include "MediaFoundationCdmModule.h"
#include "MediaFoundationCdmSession.h"

#include "utils/PMPHostWrapper.h"

MediaFoundationCdm::~MediaFoundationCdm() = default;

bool MediaFoundationCdm::Initialize(const std::string &keySystem,
const std::string &basePath,
const media::CdmConfig &cdmConfig,
media::CdmAdapterClient* client)
{
bool ret = true;

m_session.Startup();

ret = m_session.HasMediaFoundation();
if (!ret)
{
Log(MFCDM::MFLOG_ERROR, "MF doesn't exist on current system");
return false;
}

const auto m_factory = std::make_unique<MediaFoundationCdmFactory>(keySystem);

ret = m_factory->Initialize();
if (!ret)
{
Log(MFCDM::MFLOG_ERROR, "MFFactory failed to initialize.");
return false;
}

ret = m_factory->CreateMfCdm(cdmConfig, basePath, m_module);
if (!ret)
{
Log(MFCDM::MFLOG_ERROR, "MFFactory failed to create MF CDM.");
return false;
}

Log(MFCDM::MFLOG_DEBUG, "MF CDM created.");

SetupPMPServer();

m_client = client;
return true;
}

/*!
* \brief Setup PMPHostApp
* IMFContentDecryptionModule->SetPMPHostApp
* needs to be set if not under UWP or else GenerateChallenge will fail
* \link https://github.com/microsoft/media-foundation/issues/37#issuecomment-1194534228
*/
void MediaFoundationCdm::SetupPMPServer() const
{
if (!m_module)
return;

const winrt::com_ptr<IMFGetService> spIMFGetService = m_module->As<IMFGetService>();
winrt::com_ptr<IMFPMPHost> pmpHostApp;

if(FAILED(spIMFGetService->GetService(
MF_CONTENTDECRYPTIONMODULE_SERVICE, IID_PPV_ARGS(pmpHostApp.put()))))
{
Log(MFCDM::MFLOG_ERROR, "Failed to get MF CDM service.");
return;
}

winrt::com_ptr<PMPHostWrapper> spIMFPMPHostApp = winrt::make_self<PMPHostWrapper>(pmpHostApp);
m_module->SetPMPHostApp(spIMFPMPHostApp.get());
}

void MediaFoundationCdm::SetServerCertificate(uint32_t promise_id,
const uint8_t* serverCertificateData,
uint32_t serverCertificateDataSize) const
{
m_module->SetServerCertificate(serverCertificateData, serverCertificateDataSize);
}

void MediaFoundationCdm::CreateSessionAndGenerateRequest(uint32_t promise_id, cdm::SessionType sessionType,
cdm::InitDataType initDataType, const uint8_t *init_data,
uint32_t init_data_size)
{
auto session = std::make_unique<MediaFoundationCdmSession>();

if (!session->Initialize(sessionType, m_module.get()))
{
Log(MFCDM::MFLOG_ERROR, "Failed to create session.");
return;
}

int session_token = next_session_token_++;
session->GenerateRequest(initDataType, init_data, init_data_size);

m_cdm_sessions.emplace(session_token, std::move(session));
}

void MediaFoundationCdm::LoadSession(cdm::SessionType session_type,
const std::string &session_id)
{

}

void MediaFoundationCdm::UpdateSession(const std::string &session_id)
{

}




60 changes: 60 additions & 0 deletions lib/mfcdm/mfcdm/MediaFoundationCdm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2023 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 "MediaFoundationSession.h"

#include <string>
#include <map>
#include <memory>

#include "cdm/media/base/cdm_config.h"
#include "cdm/media/cdm/api/content_decryption_module.h"
#include "cdm/media/cdm/cdm_adapter.h"

class MediaFoundationCdmSession;
class MediaFoundationCdmFactory;
class MediaFoundationCdmModule;

class MediaFoundationCdm {
public:
~MediaFoundationCdm();

bool IsInitialized() const { return m_module != nullptr; }

bool Initialize(const std::string& keySystem,
const std::string &basePath,
const media::CdmConfig &cdmConfig,
media::CdmAdapterClient* client);

void SetServerCertificate(uint32_t promise_id,
const uint8_t* serverCertificateData,
uint32_t serverCertificateDataSize) const;

void CreateSessionAndGenerateRequest(uint32_t promise_id,
cdm::SessionType sessionType,
cdm::InitDataType initDataType,
const uint8_t* init_data,
uint32_t init_data_size);

void LoadSession(cdm::SessionType session_type, const std::string& session_id);

void UpdateSession(const std::string& session_id);
private:
void SetupPMPServer() const;

MediaFoundationSession m_session;

std::unique_ptr<MediaFoundationCdmModule> m_module{nullptr};

int next_session_token_{0};
std::map<int, std::unique_ptr<MediaFoundationCdmSession>> m_cdm_sessions;

media::CdmAdapterClient* m_client{nullptr};
};
32 changes: 32 additions & 0 deletions lib/mfcdm/mfcdm/MediaFoundationCdmConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023 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

/*!
* \brief The runtime configuration for the CDM instance
*/
struct MediaFoundationCdmConfig
{
MediaFoundationCdmConfig(bool distinctive_identifier = false, bool persistent_state = false)
: allow_distinctive_identifier(distinctive_identifier),
allow_persistent_state(persistent_state),
use_hw_secure_codecs(false)
{

}

// Allow access to a distinctive identifier.
bool allow_distinctive_identifier;

// Allow access to persistent state.
bool allow_persistent_state;

// Use hardware-secure codecs.
bool use_hw_secure_codecs;
};
Loading

0 comments on commit 6168bb2

Please sign in to comment.