Skip to content

Commit

Permalink
[video_player_avplay] Replace g_idle_add with ecore_pipe (flutter-tiz…
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaowei-guan authored Jan 10, 2024
1 parent 0812a8f commit 00d1524
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 98 deletions.
5 changes: 5 additions & 0 deletions packages/video_player_avplay/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
## 0.2.1

* Replace g_idle_add with ecore_pipe

## 0.2.0

* Add get duration API for live stream.

## 0.1.3
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.2.0
video_player_avplay: ^0.2.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.2.0
version: 0.2.1

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
115 changes: 64 additions & 51 deletions packages/video_player_avplay/tizen/src/drm_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,20 @@ DrmManager::DrmManager() : drm_type_(DM_TYPE_NONE) {
} 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);
self->ExecuteRequest();
},
this);
}

DrmManager::~DrmManager() {
ReleaseDrmSession();

if (license_request_pipe_) {
ecore_pipe_del(license_request_pipe_);
license_request_pipe_ = nullptr;
}
if (drm_manager_proxy_) {
CloseDrmManagerProxy(drm_manager_proxy_);
drm_manager_proxy_ = nullptr;
Expand Down Expand Up @@ -97,30 +106,34 @@ bool DrmManager::SetChallenge(const std::string &media_url,
}

void DrmManager::ReleaseDrmSession() {
if (source_id_ > 0) {
g_source_remove(source_id_);
if (drm_session_ == nullptr) {
LOG_ERROR("[DrmManager] Already released.");
return;
}
source_id_ = 0;

if (drm_session_) {
int ret = 0;
if (initialized_) {
ret = DMGRSetData(drm_session_, "Finalize", nullptr);
if (ret == DM_ERROR_NONE) {
initialized_ = false;
} else {
LOG_ERROR("[DrmManager] Fail to set finalize to drm session: %s",
get_error_message(ret));
}
}
ret = DMGRReleaseDRMSession(drm_session_);
if (ret == DM_ERROR_NONE) {
drm_session_ = nullptr;
} else {
LOG_ERROR("[DrmManager] Fail to release drm session: %s",
get_error_message(ret));
}
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);
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);

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

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

bool DrmManager::GetDrmHandle(int *handle) {
Expand Down Expand Up @@ -216,19 +229,11 @@ int DrmManager::OnChallengeData(void *session_id, int message_type,
void *user_data) {
LOG_INFO("[DrmManager] challenge data: %s, challenge length: %d", message,
message_length);

DrmManager *self = static_cast<DrmManager *>(user_data);
LOG_INFO("[DrmManager] drm_type: %d, license server: %s", self->drm_type_,
self->license_server_url_.c_str());
DataForLicenseProcess *data =
new DataForLicenseProcess(session_id, message, message_length);
data->user_data = self;
self->source_id_ = g_idle_add(ProcessLicense, data);
if (self->source_id_ <= 0) {
LOG_ERROR("[DrmManager] Fail to add g_idle.");
delete data;
return DM_ERROR_INTERNAL_ERROR;
}
DataForLicenseProcess process_message(session_id, message, message_length);
self->PushLicenseRequestData(process_message);
return DM_ERROR_NONE;
}

Expand All @@ -238,40 +243,33 @@ void DrmManager::OnDrmManagerError(long error_code, char *error_message,
error_message);
}

gboolean DrmManager::ProcessLicense(void *user_data) {
bool DrmManager::ProcessLicense(DataForLicenseProcess &data) {
LOG_INFO("[DrmManager] Start process license.");

DataForLicenseProcess *data = static_cast<DataForLicenseProcess *>(user_data);
DrmManager *self = static_cast<DrmManager *>(data->user_data);

if (!self->license_server_url_.empty()) {
if (!license_server_url_.empty()) {
// Get license via the license server.
unsigned char *response_data = nullptr;
unsigned long response_len = 0;
DRM_RESULT ret = DrmLicenseHelper::DoTransactionTZ(
self->license_server_url_.c_str(), data->message.c_str(),
data->message.size(), &response_data, &response_len,
static_cast<DrmLicenseHelper::DrmType>(self->drm_type_), nullptr,
nullptr);
license_server_url_.c_str(), data.message.c_str(), data.message.size(),
&response_data, &response_len,
static_cast<DrmLicenseHelper::DrmType>(drm_type_), nullptr, nullptr);
if (DRM_SUCCESS != ret || nullptr == response_data || 0 == response_len) {
LOG_ERROR("[DrmManager] Fail to get respone by license server url.");
delete data;
return false;
}
LOG_INFO("[DrmManager] Response length : %d", response_len);
self->InstallKey(const_cast<void *>(reinterpret_cast<const void *>(
data->session_id.c_str())),
static_cast<void *>(response_data),
reinterpret_cast<void *>(response_len));
LOG_INFO("[DrmManager] Response length : %lu", response_len);
InstallKey(const_cast<void *>(
reinterpret_cast<const void *>(data.session_id.c_str())),
static_cast<void *>(response_data),
reinterpret_cast<void *>(response_len));
free(response_data);
} else if (self->request_license_channel_) {
} else if (request_license_channel_) {
// Get license via the Dart callback.
self->RequestLicense(data->session_id, data->message);
RequestLicense(data.session_id, data.message);
} else {
LOG_ERROR("[DrmManager] No way to request license.");
}

delete data;
return false;
}

Expand Down Expand Up @@ -327,3 +325,18 @@ void DrmManager::RequestLicense(std::string &session_id, std::string &message) {
flutter::EncodableValue(args_map)),
std::move(result_handler));
}

void DrmManager::PushLicenseRequestData(DataForLicenseProcess &data) {
std::lock_guard<std::mutex> lock(queue_mutex_);
license_request_queue_.push(data);
ecore_pipe_write(license_request_pipe_, nullptr, 0);
}

void DrmManager::ExecuteRequest() {
std::lock_guard<std::mutex> lock(queue_mutex_);
while (!license_request_queue_.empty()) {
DataForLicenseProcess data = license_request_queue_.front();
ProcessLicense(data);
license_request_queue_.pop();
}
}
14 changes: 10 additions & 4 deletions packages/video_player_avplay/tizen/src/drm_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
#ifndef FLUTTER_PLUGIN_DRM_MANAGER_H_
#define FLUTTER_PLUGIN_DRM_MANAGER_H_

#include <Ecore.h>
#include <flutter/method_channel.h>
#include <glib.h>

#include <mutex>
#include <queue>

#include "drm_manager_proxy.h"

Expand Down Expand Up @@ -39,7 +42,6 @@ class DrmManager {
message(static_cast<char *>(message), message_length) {}
std::string session_id;
std::string message;
void *user_data;
};

void RequestLicense(std::string &session_id, std::string &message);
Expand All @@ -50,7 +52,9 @@ class DrmManager {
int message_length, void *user_data);
static void OnDrmManagerError(long error_code, char *error_message,
void *user_data);
static gboolean ProcessLicense(void *user_data);
bool ProcessLicense(DataForLicenseProcess &data);
void PushLicenseRequestData(DataForLicenseProcess &data);
void ExecuteRequest();

std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>>
request_license_channel_;
Expand All @@ -60,8 +64,10 @@ class DrmManager {

int drm_type_;
std::string license_server_url_;
unsigned int source_id_ = 0;
bool initialized_ = false;
std::mutex queue_mutex_;
Ecore_Pipe *license_request_pipe_ = nullptr;
std::queue<DataForLicenseProcess> license_request_queue_;
};

#endif // FLUTTER_PLUGIN_DRM_MANAGER_H_
35 changes: 19 additions & 16 deletions packages/video_player_avplay/tizen/src/media_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static player_stream_type_e ConvertTrackType(std::string track_type) {
if (track_type == "text") {
return PLAYER_STREAM_TYPE_TEXT;
}
return PLAYER_STREAM_TYPE_DEFAULT;
}

MediaPlayer::MediaPlayer(flutter::BinaryMessenger *messenger,
Expand All @@ -52,7 +53,22 @@ MediaPlayer::MediaPlayer(flutter::BinaryMessenger *messenger,
media_player_proxy_ = std::make_unique<MediaPlayerProxy>();
}

MediaPlayer::~MediaPlayer() { Dispose(); }
MediaPlayer::~MediaPlayer() {
if (player_) {
player_stop(player_);
player_unprepare(player_);
player_unset_buffering_cb(player_);
player_unset_completed_cb(player_);
player_unset_interrupted_cb(player_);
player_unset_error_cb(player_);
player_unset_subtitle_updated_cb(player_);
player_destroy(player_);
player_ = nullptr;
}
if (drm_manager_) {
drm_manager_->ReleaseDrmSession();
}
}

int64_t MediaPlayer::Create(const std::string &uri, int drm_type,
const std::string &license_server_url,
Expand Down Expand Up @@ -175,20 +191,7 @@ int64_t MediaPlayer::Create(const std::string &uri, int drm_type,

void MediaPlayer::Dispose() {
LOG_INFO("[MediaPlayer] Disposing.");

if (player_) {
if (is_initialized_) {
player_unprepare(player_);
is_initialized_ = false;
}
player_destroy(player_);
player_ = nullptr;
}

// drm should be released after destroy of player
if (drm_manager_) {
drm_manager_->ReleaseDrmSession();
}
ClearUpEventChannel();
}

void MediaPlayer::SetDisplayRoi(int32_t x, int32_t y, int32_t width,
Expand Down Expand Up @@ -285,7 +288,7 @@ bool MediaPlayer::SetPlaybackSpeed(double speed) {
}

bool MediaPlayer::SeekTo(int64_t position, SeekCompletedCallback callback) {
LOG_INFO("[MediaPlayer] position: %d.", position);
LOG_INFO("[MediaPlayer] position: %lld.", position);

on_seek_completed_ = std::move(callback);
int ret =
Expand Down
39 changes: 14 additions & 25 deletions packages/video_player_avplay/tizen/src/plus_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,19 @@ PlusPlayer::PlusPlayer(flutter::BinaryMessenger *messenger,
std::string &video_format)
: VideoPlayer(messenger, flutter_view), video_format_(video_format) {}

PlusPlayer::~PlusPlayer() { Dispose(); }
PlusPlayer::~PlusPlayer() {
if (player_) {
Stop(player_);
Close(player_);
UnregisterListener(player_);
DestroyPlayer(player_);
player_ = nullptr;
}

if (drm_manager_) {
drm_manager_->ReleaseDrmSession();
}
}

void PlusPlayer::RegisterListener() {
listener_.buffering_callback = OnBufferStatus;
Expand Down Expand Up @@ -134,30 +146,7 @@ int64_t PlusPlayer::Create(const std::string &uri, int drm_type,

void PlusPlayer::Dispose() {
LOG_INFO("[PlusPlayer] Player disposing.");

if (!player_) {
LOG_ERROR("[PlusPlayer] Player not created.");
return;
}
if (!Stop(player_)) {
LOG_INFO("[PlusPlayer] Player fail to stop.");
return;
}

plusplayer::State state = GetState(player_);
if (state == plusplayer::State::kIdle || state == plusplayer::State::kNone) {
if (!Close(player_)) {
LOG_INFO("[PlusPlayer] Player fail to close.");
return;
}
}
UnregisterListener(player_);
DestroyPlayer(player_);
player_ = nullptr;

if (drm_manager_) {
drm_manager_->ReleaseDrmSession();
}
ClearUpEventChannel();
}

void PlusPlayer::SetDisplayRoi(int32_t x, int32_t y, int32_t width,
Expand Down
5 changes: 5 additions & 0 deletions packages/video_player_avplay/tizen/src/video_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ VideoPlayer::VideoPlayer(flutter::BinaryMessenger *messenger,
VideoPlayer::~VideoPlayer() {
if (sink_event_pipe_) {
ecore_pipe_del(sink_event_pipe_);
sink_event_pipe_ = nullptr;
}
}

void VideoPlayer::ClearUpEventChannel() {
is_initialized_ = false;
event_sink_ = nullptr;
if (event_channel_) {
event_channel_->SetStreamHandler(nullptr);
Expand Down
1 change: 1 addition & 0 deletions packages/video_player_avplay/tizen/src/video_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class VideoPlayer {
virtual void GetVideoSize(int32_t *width, int32_t *height) = 0;
void *GetWindowHandle();
int64_t SetUpEventChannel();
void ClearUpEventChannel();
void SendInitialized();
void SendBufferingStart();
void SendBufferingUpdate(int32_t value);
Expand Down

0 comments on commit 00d1524

Please sign in to comment.