Initial support for instant rate change
Custom implementation for Amlogic
Change-Id: Ie76cc8921a9ad05de44d75b399a5640f6487619d
Signed-off-by: Eugene Mutavchi <Ievgen_Mutavchi@comcast.com>
diff --git a/src/third_party/starboard/rdk/shared/player/player_internal.cc b/src/third_party/starboard/rdk/shared/player/player_internal.cc
index 190e196..047f9b5 100644
--- a/src/third_party/starboard/rdk/shared/player/player_internal.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_internal.cc
@@ -1146,7 +1146,6 @@
MediaType min_sample_timestamp_origin_{MediaType::kNone};
bool is_seek_pending_{false};
double pending_rate_{.0};
- bool is_rate_being_changed_{false};
int has_enough_data_{static_cast<int>(MediaType::kBoth)};
mutable int decoder_state_data_{static_cast<int>(MediaType::kNone)};
int eos_data_{static_cast<int>(MediaType::kNone)};
@@ -1170,6 +1169,7 @@
GstCaps* audio_caps_ { nullptr };
GstCaps* video_caps_ { nullptr };
SbTime buf_target_min_ts_ { kSbTimeMax };
+ bool did_instant_rate_change_ { false };
};
struct PlayerRegistry
@@ -1491,7 +1491,7 @@
}
if (self->state_ == State::kPrerollAfterSeek ||
self->state_ == State::kInitialPreroll) {
- self->has_oob_write_pending_ |= (is_seek_pending || is_rate_pending);
+ self->has_oob_write_pending_ |= is_seek_pending;
}
}
@@ -1521,15 +1521,13 @@
::starboard::Mutex &mutex = self->mutex_;
::starboard::ScopedLock lock(mutex);
- self->is_rate_being_changed_ = false;
if (self->state_ == State::kPrerollAfterSeek ||
self->state_ == State::kInitialPreroll) {
bool is_seek_pending = self->is_seek_pending_;
- bool is_rate_pending = self->pending_rate_ != 0.;
bool has_pending_samples = (self->pending_samples_.empty() == false) || self->has_oob_write_pending_;
- if (!is_seek_pending && !is_rate_pending && has_pending_samples) {
+ if (!is_seek_pending && has_pending_samples) {
int prev_has_data = static_cast<int>(self->has_enough_data_);
self->has_enough_data_ = static_cast<int>(MediaType::kBoth);
@@ -2001,7 +1999,7 @@
bool keep_samples = false;
{
::starboard::ScopedLock lock(mutex_);
- keep_samples = is_seek_pending_ || pending_rate_ != .0;
+ keep_samples = is_seek_pending_;
serial = samples_serial_[ (sample_type == kSbMediaTypeVideo ? kVideoIndex : kAudioIndex) ]++;
if (sample_type == kSbMediaTypeVideo)
++total_video_frames_;
@@ -2180,48 +2178,52 @@
bool PlayerImpl::SetRate(double rate) {
GST_DEBUG_OBJECT(pipeline_, "===> rate %lf (rate_ %lf), TID: %d", rate, rate_,
SbThreadGetId());
+
bool success = true;
- double current_rate = 1.;
{
::starboard::ScopedLock lock(mutex_);
- current_rate = rate_;
decoder_state_data_ = 0;
eos_data_ = 0;
}
+
if (rate == .0) {
ChangePipelineState(GST_STATE_PAUSED);
- } else if (rate == 1. && (current_rate == 1. || current_rate == .0)) {
- ChangePipelineState(GST_STATE_PLAYING);
} else {
ChangePipelineState(GST_STATE_PLAYING);
+ }
+
+ if (rate != .0 && (rate != 1. || did_instant_rate_change_)) {
{
::starboard::ScopedLock lock(mutex_);
if (is_seek_pending_) {
- GST_DEBUG("Rate will be set when doing seek");
+ GST_DEBUG_OBJECT(pipeline_, "Rate will be set when doing seek");
rate_ = rate;
return true;
}
- }
- if (GST_STATE(pipeline_) < GST_STATE_PAUSED) {
- GST_DEBUG_OBJECT(pipeline_, "===> Set rate postponed");
- ::starboard::ScopedLock lock(mutex_);
- pending_rate_ = rate;
- return true;
- } else {
- {
- ::starboard::ScopedLock lock(mutex_);
- is_rate_being_changed_ = true;
- pending_rate_ = .0;
+ if (GST_STATE(pipeline_) < GST_STATE_PLAYING) {
+ GST_DEBUG_OBJECT(pipeline_, "===> Set rate postponed");
+ pending_rate_ = rate;
+ return true;
}
+ pending_rate_ = .0;
+ }
- GST_DEBUG("Calling seek (set rate)");
- success =
- gst_element_seek(pipeline_, rate, GST_FORMAT_TIME,
- static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH |
- GST_SEEK_FLAG_ACCURATE),
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
- GST_DEBUG("Seek called (set rate)");
+ // TODO: instant rate change support
+ GstElement* sink = nullptr;
+ g_object_get(pipeline_, "audio-sink", &sink, nullptr);
+ if (sink && g_str_has_prefix(GST_ELEMENT_NAME(sink), "amlhalasink")) {
+ GstSegment* segment = gst_segment_new();
+ gst_segment_init(segment, GST_FORMAT_TIME);
+ segment->rate = rate;
+ segment->start = GST_CLOCK_TIME_NONE;
+ segment->position = GST_CLOCK_TIME_NONE;
+ GST_DEBUG_OBJECT(pipeline_, "===> Sending new segment %" GST_SEGMENT_FORMAT, segment);
+ success = gst_pad_send_event (GST_BASE_SINK_PAD(sink), gst_event_new_segment(segment));
+ GST_DEBUG_OBJECT(pipeline_, "===> Sent new segment, success = %s", success ? "true" : "false");
+ gst_segment_free(segment);
+ g_object_unref(sink);
+
+ did_instant_rate_change_ |= success;
}
}
@@ -2409,11 +2411,6 @@
cached_position_ns_ = seek_pos_ns;
seek_position_ = kSbTimeMax;
}
-
- if (is_rate_being_changed_ && audio_codec_ != kSbMediaAudioCodecNone) {
- GST_WARNING("Set rate workaround kicking in.");
- return max_sample_timestamps_[kAudioIndex];
- }
}
if (GST_CLOCK_TIME_IS_VALID(cached_position_ns_) &&
@@ -2435,7 +2432,7 @@
int ticket = -1;
{
::starboard::ScopedLock lock(mutex_);
- keep_samples = is_seek_pending_ || pending_rate_ != 0.;
+ keep_samples = is_seek_pending_;
ticket = ticket_;
local_samples.swap(pending_samples_);
}
diff --git a/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc b/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
index d892b71..e5d2083 100644
--- a/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
+++ b/src/third_party/starboard/rdk/shared/player/player_set_playback_rate.cc
@@ -34,11 +34,5 @@
#include "third_party/starboard/rdk/shared/player/player_internal.h"
bool SbPlayerSetPlaybackRate(SbPlayer player, double playback_rate) {
- // FIXME: remove after seemless rate change is supported
- if (playback_rate > 0.0 && playback_rate != 1.0)
- playback_rate = 1.0;
- else if (playback_rate < 0.0)
- playback_rate = 0.0;
-
return player->player_->SetRate(playback_rate);
}