#include "base/command_line.h"
#include "base/no_destructor.h"
#include "base/strings/string_split.h"
+#include "base/time/time.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ewk/efl_integration/common/content_switches_efl.h"
#include "media/base/efl/media_player_util_efl.h"
}
void MediaPlayerBridgeCapiTV::Release() {
+ was_paused_before_.reset();
is_preloaded_ = false;
player_prepared_ = false;
if (player_released_) {
}
}
+void MediaPlayerBridgeCapiTV::TrackDoubleSeek(base::TimeDelta pts) {
+ if (!blink::IsHbbTV()) {
+ return;
+ }
+
+ const bool is_paused = is_paused_;
+ switch (seek_state_) {
+ case SeekState::kNone:
+ case SeekState::kSecondSeekComplete:
+ Pause(false);
+ was_paused_before_ = is_paused;
+ seek_state_pts_ = pts;
+ seek_state_ = SeekState::kFirstSeek;
+ break;
+ case SeekState::kFirstSeekComplete:
+ if (seek_state_pts_.has_value() && seek_state_pts_.value() == pts) {
+ seek_state_ = SeekState::kSecondSeek;
+ break;
+ }
+ LOG_ID(ERROR, player_id_)
+ << "Unexpected flow for double seek, wrong pts=" << pts;
+ RestorePlaybackSeekState();
+ seek_state_ = SeekState::kNone;
+ break;
+ case SeekState::kFirstSeek:
+ case SeekState::kSecondSeek:
+ LOG_ID(ERROR, player_id_) << "Unexpected flow for double seek";
+ RestorePlaybackSeekState();
+ seek_state_ = SeekState::kNone;
+ break;
+ }
+}
+
+void MediaPlayerBridgeCapiTV::TrackDoubleSeekCompleted() {
+ if (!blink::IsHbbTV()) {
+ return;
+ }
+
+ switch (seek_state_) {
+ case SeekState::kNone:
+ case SeekState::kSecondSeekComplete:
+ case SeekState::kFirstSeekComplete:
+ LOG_ID(ERROR, player_id_) << "Unexpected flow for double seek";
+ RestorePlaybackSeekState();
+ seek_state_ = SeekState::kNone;
+ break;
+ case SeekState::kFirstSeek:
+ seek_state_ = SeekState::kFirstSeekComplete;
+ break;
+ case SeekState::kSecondSeek:
+ RestorePlaybackSeekState();
+ seek_state_ = SeekState::kSecondSeekComplete;
+ break;
+ }
+}
+
+void MediaPlayerBridgeCapiTV::RestorePlaybackSeekState() {
+ if (!blink::IsHbbTV()) {
+ return;
+ }
+
+ if (!was_paused_before_.value_or(true)) {
+ Play();
+ }
+ seek_state_pts_.reset();
+ was_paused_before_.reset();
+}
+
+void MediaPlayerBridgeCapiTV::SeekInternal(base::TimeDelta time) {
+ TrackDoubleSeek(time);
+ MediaPlayerBridgeCapi::SeekInternal(time);
+}
+
bool MediaPlayerBridgeCapiTV::Play() {
LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
<< __func__
<< ",current_time:" << GetCurrentTime().InSecondsF();
-
+ was_paused_before_.reset();
if (IsPlayerSuspended()) {
is_play_pending_ = true;
LOG_ID(INFO, GetPlayerId()) << "Player is suspended";
}
void MediaPlayerBridgeCapiTV::Pause(bool is_media_related_action) {
+ was_paused_before_.reset();
if (!player_prepared_ || is_resuming_) {
delayed_player_state_ = PLAYER_STATE_DELAYED_PAUSE;
return;
return;
}
+ RestorePlaybackSeekState();
if (GetMediaPlayerClient())
GetMediaPlayerClient()->OnRequestSuspend(resource_conflicted);
MediaPlayerBridgeCapi::Suspend();
<< "(" << static_cast<void*>(this) << ") "
<< " stashing pending seek - " << time.InSecondsF() << "s";
+ // NOTE: Stashing seek prevents double seek. This would require to use
+ // a queue to store seeks and handle them one after another.
+ RestorePlaybackSeekState();
+
if(delayed_player_state_ == PLAYER_STATE_DELAYED_PLAY ||
delayed_player_state_ == PLAYER_STATE_DELAYED_SEEK_THEN_PLAY)
delayed_player_state_ = PLAYER_STATE_DELAYED_SEEK_THEN_PLAY;
}
LOG_ID(INFO, player_id_) << "SeekInternal";
- MediaPlayerBridgeCapi::SeekInternal(time);
+ SeekInternal(time);
LOG_ID(INFO, player_id_) << "NotifySubtitleState seek start";
NotifySubtitleState(blink::WebMediaPlayer::kSubtitleSeekStart,
}
void MediaPlayerBridgeCapiTV::SeekCompleteUpdate() {
+ TrackDoubleSeekCompleted();
MediaPlayerBridgeCapi::SeekCompleteUpdate();
NotifySubtitleState(blink::WebMediaPlayer::kSubtitleSeekComplete);
waiting_for_drm_init_complete_ = false;
return (decryptor_ != 0);
}
+
#endif
} // namespace media
#include <emeCDM/IEME.h>
#include <player_product.h>
+#include <string>
#include "base/synchronization/condition_variable.h"
+#include "base/time/time.h"
#include "media/filters/hardware_resource_helper.h"
#include "media/filters/media_player_bridge_capi.h"
#include "tizen_src/chromium_impl/build/tizen_version.h"
DEL_INBAND_TEXT_TRACK,
};
+enum class SeekState {
+ kNone,
+ kFirstSeek,
+ kFirstSeekComplete,
+ kSecondSeek,
+ kSecondSeekComplete
+};
+
#if defined(TIZEN_VD_NGA)
struct AudioPreselectionInfos {
std::string id;
return is_player_reload_by_mixer_;
};
+ void TrackDoubleSeek(base::TimeDelta pts);
+ void TrackDoubleSeekCompleted();
+ void RestorePlaybackSeekState();
+
+ void SeekInternal(base::TimeDelta time) override;
bool ActivateAudioStreamIfNeeded();
bool DeactivateAudioStreamIfNeeded();
bool ActivateAudioStream();
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<MediaPlayerBridgeCapiTV> weak_factory_;
+ SeekState seek_state_ = SeekState::kNone;
+ absl::optional<bool> was_paused_before_;
+ absl::optional<base::TimeDelta> seek_state_pts_;
+
bool has_encrypted_listener_or_cdm_{false};
// Flag indicating that has_encrypted_listener_or_cdm_ has been changed.
bool encrypted_listener_or_cdm_has_changed_{false};