Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[video_player_avplay] Resolve drm manager proxy doesn't support multiple instances issue. #660

Merged
merged 10 commits into from
Jan 30, 2024
4 changes: 4 additions & 0 deletions packages/video_player_avplay/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.3.1

* Resolve drm manager proxy doesn't support multiple instances issue.

## 0.3.0

* Support ADAPTIVE_INFO property.
Expand Down
2 changes: 1 addition & 1 deletion packages/video_player_avplay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec.

```yaml
dependencies:
video_player_avplay: ^0.3.0
video_player_avplay: ^0.3.1
```
Then you can import `video_player_avplay` in your Dart code:
Expand Down
2 changes: 1 addition & 1 deletion packages/video_player_avplay/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: video_player_avplay
description: Flutter plugin for displaying inline video on Tizen TV devices.
homepage: https://github.com/flutter-tizen/plugins
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player_avplay
version: 0.3.0
version: 0.3.1

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
64 changes: 25 additions & 39 deletions packages/video_player_avplay/tizen/src/drm_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,6 @@ static std::string GetDrmSubType(int drm_type) {
}

DrmManager::DrmManager() : drm_type_(DM_TYPE_NONE) {
drm_manager_proxy_ = OpenDrmManagerProxy();
if (drm_manager_proxy_) {
int ret = InitDrmManagerProxy(drm_manager_proxy_);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to initialize DRM manager: %s",
get_error_message(ret));
CloseDrmManagerProxy(drm_manager_proxy_);
drm_manager_proxy_ = nullptr;
}
} else {
LOG_ERROR("[DrmManager] Fail to dlopen libdrmmanager.");
}
license_request_pipe_ = ecore_pipe_add(
[](void *data, void *buffer, unsigned int nbyte) -> void {
auto *self = static_cast<DrmManager *>(data);
Expand All @@ -48,26 +36,18 @@ DrmManager::~DrmManager() {
ecore_pipe_del(license_request_pipe_);
license_request_pipe_ = nullptr;
}
if (drm_manager_proxy_) {
CloseDrmManagerProxy(drm_manager_proxy_);
drm_manager_proxy_ = nullptr;
}
}

bool DrmManager::CreateDrmSession(int drm_type, bool local_mode) {
if (!drm_manager_proxy_) {
LOG_ERROR("[DrmManager] Invalid handle of libdrmmanager.");
return false;
}

if (local_mode) {
DMGRSetDRMLocalMode();
DrmManagerProxy::GetInstance().DMGRSetDRMLocalMode();
}

drm_type_ = drm_type;
std::string sub_type = GetDrmSubType(drm_type);
LOG_INFO("[DrmManager] drm type is %s", sub_type.c_str());
drm_session_ = DMGRCreateDRMSession(DM_TYPE_EME, sub_type.c_str());
drm_session_ = DrmManagerProxy::GetInstance().DMGRCreateDRMSession(
DM_TYPE_EME, sub_type.c_str());
if (!drm_session_) {
LOG_ERROR("[DrmManager] Fail to create drm session.");
return false;
Expand All @@ -78,7 +58,8 @@ bool DrmManager::CreateDrmSession(int drm_type, bool local_mode) {
SetDataParam_t configure_param = {};
configure_param.param1 = reinterpret_cast<void *>(OnDrmManagerError);
configure_param.param2 = drm_session_;
int ret = DMGRSetData(drm_session_, "error_event_callback", &configure_param);
int ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "error_event_callback", &configure_param);
if (ret != DM_ERROR_NONE) {
LOG_ERROR(
"[DrmManager] Fail to set error_event_callback to drm session: %s",
Expand Down Expand Up @@ -114,21 +95,22 @@ void DrmManager::ReleaseDrmSession() {
SetDataParam_t challenge_data_param = {};
challenge_data_param.param1 = nullptr;
challenge_data_param.param2 = nullptr;
int ret = DMGRSetData(drm_session_, "eme_request_key_callback",
&challenge_data_param);
int ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "eme_request_key_callback", &challenge_data_param);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to unset eme_request_key_callback: %s",
get_error_message(ret));
}

ret = DMGRSetData(drm_session_, "Finalize", nullptr);
ret = DrmManagerProxy::GetInstance().DMGRSetData(drm_session_, "Finalize",
nullptr);

if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to set finalize to drm session: %s",
get_error_message(ret));
}

ret = DMGRReleaseDRMSession(drm_session_);
ret = DrmManagerProxy::GetInstance().DMGRReleaseDRMSession(drm_session_);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to release drm session: %s",
get_error_message(ret));
Expand All @@ -139,7 +121,8 @@ void DrmManager::ReleaseDrmSession() {
bool DrmManager::GetDrmHandle(int *handle) {
if (drm_session_) {
*handle = 0;
int ret = DMGRGetData(drm_session_, "drm_handle", handle);
int ret = DrmManagerProxy::GetInstance().DMGRGetData(drm_session_,
"drm_handle", handle);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to get drm_handle from drm session: %s",
get_error_message(ret));
Expand All @@ -162,7 +145,8 @@ int DrmManager::UpdatePsshData(const void *data, int length) {
SetDataParam_t pssh_data_param = {};
pssh_data_param.param1 = const_cast<void *>(data);
pssh_data_param.param2 = reinterpret_cast<void *>(length);
int ret = DMGRSetData(drm_session_, "update_pssh_data", &pssh_data_param);
int ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "update_pssh_data", &pssh_data_param);
if (DM_ERROR_NONE != ret) {
LOG_ERROR("[DrmManager] Fail to set update_pssh_data to drm session: %s",
get_error_message(ret));
Expand All @@ -182,8 +166,8 @@ bool DrmManager::SecurityInitCompleteCB(int *drm_handle, unsigned int len,
}
security_param.param2 = drm_session_;

return DMGRSecurityInitCompleteCB(drm_handle, len, pssh_data,
&security_param);
return DrmManagerProxy::GetInstance().DMGRSecurityInitCompleteCB(
drm_handle, len, pssh_data, &security_param);
}

int DrmManager::SetChallenge(const std::string &media_url) {
Expand All @@ -195,8 +179,8 @@ int DrmManager::SetChallenge(const std::string &media_url) {
SetDataParam_t challenge_data_param = {};
challenge_data_param.param1 = reinterpret_cast<void *>(OnChallengeData);
challenge_data_param.param2 = this;
int ret = DMGRSetData(drm_session_, "eme_request_key_callback",
&challenge_data_param);
int ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "eme_request_key_callback", &challenge_data_param);
if (ret != DM_ERROR_NONE) {
LOG_ERROR(
"[DrmManager] Fail to set eme_request_key_callback to drm session: "
Expand All @@ -205,22 +189,23 @@ int DrmManager::SetChallenge(const std::string &media_url) {
return ret;
}

ret = DMGRSetData(drm_session_, "set_playready_manifest",
static_cast<void *>(const_cast<char *>(media_url.c_str())));
ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "set_playready_manifest",
static_cast<void *>(const_cast<char *>(media_url.c_str())));
if (ret != DM_ERROR_NONE) {
LOG_ERROR(
"[DrmManager] Fail to set set_playready_manifest to drm session: %s",
get_error_message(ret));
return ret;
}

ret = DMGRSetData(drm_session_, "Initialize", nullptr);
ret = DrmManagerProxy::GetInstance().DMGRSetData(drm_session_, "Initialize",
nullptr);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to set initialize to drm session: %s",
get_error_message(ret));
return ret;
}
initialized_ = true;
return ret;
}

Expand Down Expand Up @@ -281,7 +266,8 @@ void DrmManager::InstallKey(void *session_id, void *response_data,
license_param.param1 = session_id;
license_param.param2 = response_data;
license_param.param3 = response_len;
int ret = DMGRSetData(drm_session_, "install_eme_key", &license_param);
int ret = DrmManagerProxy::GetInstance().DMGRSetData(
drm_session_, "install_eme_key", &license_param);
if (ret != DM_ERROR_NONE) {
LOG_ERROR("[DrmManager] Fail to install eme key: %s",
get_error_message(ret));
Expand Down
4 changes: 0 additions & 4 deletions packages/video_player_avplay/tizen/src/drm_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include <mutex>
#include <queue>

#include "drm_manager_proxy.h"

class DrmManager {
public:
typedef enum {
Expand Down Expand Up @@ -60,11 +58,9 @@ class DrmManager {
request_license_channel_;

void *drm_session_ = nullptr;
void *drm_manager_proxy_ = nullptr;

int drm_type_;
std::string license_server_url_;
bool initialized_ = false;
std::mutex queue_mutex_;
Ecore_Pipe *license_request_pipe_ = nullptr;
std::queue<DataForLicenseProcess> license_request_queue_;
Expand Down
134 changes: 98 additions & 36 deletions packages/video_player_avplay/tizen/src/drm_manager_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,121 @@

#include <dlfcn.h>

FuncDMGRSetData DMGRSetData = nullptr;
FuncDMGRGetData DMGRGetData = nullptr;
FuncDMGRSetDRMLocalMode DMGRSetDRMLocalMode = nullptr;
FuncDMGRCreateDRMSession DMGRCreateDRMSession = nullptr;
FuncDMGRSecurityInitCompleteCB DMGRSecurityInitCompleteCB = nullptr;
FuncDMGRReleaseDRMSession DMGRReleaseDRMSession = nullptr;

void* OpenDrmManagerProxy() { return dlopen("libdrmmanager.so.0", RTLD_LAZY); }

int InitDrmManagerProxy(void* handle) {
if (!handle) {
return DM_ERROR_INVALID_PARAM;
#include "log.h"

DrmManagerProxy::DrmManagerProxy()
: drm_manager_handle_(dlopen("libdrmmanager.so.0", RTLD_LAZY)) {
is_valid_ = Initialize();
}

bool DrmManagerProxy::Initialize() {
if (drm_manager_handle_ == nullptr) {
LOG_ERROR("Fail to open drm manager.");
return false;
}

DMGRSetData = reinterpret_cast<FuncDMGRSetData>(dlsym(handle, "DMGRSetData"));
if (!DMGRSetData) {
return DM_ERROR_DL;
dmgr_set_data_ = reinterpret_cast<FuncDMGRSetData>(
dlsym(drm_manager_handle_, "DMGRSetData"));
if (dmgr_set_data_ == nullptr) {
LOG_ERROR("Fail to find DMGRSetData.");
return false;
}

DMGRGetData = reinterpret_cast<FuncDMGRGetData>(dlsym(handle, "DMGRGetData"));
if (!DMGRGetData) {
return DM_ERROR_DL;
dmgr_get_data_ = reinterpret_cast<FuncDMGRGetData>(
dlsym(drm_manager_handle_, "DMGRGetData"));
if (dmgr_get_data_ == nullptr) {
LOG_ERROR("Fail to find DMGRGetData.");
return false;
}

DMGRSetDRMLocalMode = reinterpret_cast<FuncDMGRSetDRMLocalMode>(
dlsym(handle, "DMGRSetDRMLocalMode"));
if (!DMGRSetDRMLocalMode) {
return DM_ERROR_DL;
dmgr_set_drm_local_mode_ = reinterpret_cast<FuncDMGRSetDRMLocalMode>(
dlsym(drm_manager_handle_, "DMGRSetDRMLocalMode"));
if (dmgr_set_drm_local_mode_ == nullptr) {
LOG_ERROR("Fail to find DMGRSetDRMLocalMode.");
JSUYA marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

DMGRCreateDRMSession = reinterpret_cast<FuncDMGRCreateDRMSession>(
dlsym(handle, "DMGRCreateDRMSession"));
if (!DMGRCreateDRMSession) {
return DM_ERROR_DL;
dmgr_create_drm_session_ = reinterpret_cast<FuncDMGRCreateDRMSession>(
dlsym(drm_manager_handle_, "DMGRCreateDRMSession"));
if (dmgr_create_drm_session_ == nullptr) {
LOG_ERROR("Fail to find DMGRCreateDRMSession.");
return false;
}

DMGRSecurityInitCompleteCB = reinterpret_cast<FuncDMGRSecurityInitCompleteCB>(
dlsym(handle, "DMGRSecurityInitCompleteCB"));
if (!DMGRSecurityInitCompleteCB) {
dmgr_security_init_complete_cb_ =
reinterpret_cast<FuncDMGRSecurityInitCompleteCB>(
dlsym(drm_manager_handle_, "DMGRSecurityInitCompleteCB"));
if (dmgr_security_init_complete_cb_ == nullptr) {
LOG_ERROR("Fail to find DMGRSecurityInitCompleteCB.");
return false;
}

dmgr_release_drm_session_ = reinterpret_cast<FuncDMGRReleaseDRMSession>(
dlsym(drm_manager_handle_, "DMGRReleaseDRMSession"));
if (dmgr_release_drm_session_ == nullptr) {
LOG_ERROR("Fail to find DMGRReleaseDRMSession.");
return false;
}
return true;
}

int DrmManagerProxy::DMGRSetData(DRMSessionHandle_t drm_session,
const char* data_type, void* input_data) {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRSetData.");
return DM_ERROR_DL;
}
return dmgr_set_data_(drm_session, data_type, input_data);
}

DMGRReleaseDRMSession = reinterpret_cast<FuncDMGRReleaseDRMSession>(
dlsym(handle, "DMGRReleaseDRMSession"));
if (!DMGRReleaseDRMSession) {
int DrmManagerProxy::DMGRGetData(DRMSessionHandle_t drm_session,
const char* data_type, void* output_data) {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRGetData.");
return DM_ERROR_DL;
}
return dmgr_get_data_(drm_session, data_type, output_data);
}

void DrmManagerProxy::DMGRSetDRMLocalMode() {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRSetDRMLocalMode.");
return;
}
dmgr_set_drm_local_mode_();
}

DRMSessionHandle_t DrmManagerProxy::DMGRCreateDRMSession(
dm_type_e type, const char* drm_sub_type) {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRCreateDRMSession.");
return nullptr;
}
return dmgr_create_drm_session_(type, drm_sub_type);
}

bool DrmManagerProxy::DMGRSecurityInitCompleteCB(int* drm_handle,
unsigned int len,
unsigned char* pssh_data,
void* user_data) {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRSecurityInitCompleteCB.");
return false;
}
return dmgr_security_init_complete_cb_(drm_handle, len, pssh_data, user_data);
}

return DM_ERROR_NONE;
int DrmManagerProxy::DMGRReleaseDRMSession(DRMSessionHandle_t drm_session) {
if (!is_valid_) {
LOG_ERROR("Fail to obtain address of DMGRReleaseDRMSession.");
return DM_ERROR_DL;
}
return dmgr_release_drm_session_(drm_session);
}

void CloseDrmManagerProxy(void* handle) {
if (handle) {
dlclose(handle);
DrmManagerProxy::~DrmManagerProxy() {
if (drm_manager_handle_) {
dlclose(drm_manager_handle_);
drm_manager_handle_ = nullptr;
}
}
Loading
Loading