Skip to content

Commit

Permalink
[video_player_avplay] Resolve drm manager proxy doesn't support multi…
Browse files Browse the repository at this point in the history
…ple instances issue. (#660)
  • Loading branch information
xiaowei-guan authored Jan 30, 2024
1 parent d10b7e2 commit cf47694
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 91 deletions.
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.");
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

0 comments on commit cf47694

Please sign in to comment.