Don't query the track position and length quite so often. Might reduce CPU usage for issue #246

This commit is contained in:
David Sansome 2010-06-30 20:36:16 +00:00
parent a1fbd65f68
commit b35392d60d
2 changed files with 47 additions and 25 deletions

View File

@ -61,7 +61,8 @@ GstEngine::GstEngine()
rg_preamp_(0.0), rg_preamp_(0.0),
rg_compression_(true), rg_compression_(true),
seek_timer_(new QTimer(this)), seek_timer_(new QTimer(this)),
timer_id_(-1) prune_scope_timer_id_(-1),
about_to_end_timer_id_(-1)
{ {
seek_timer_->setSingleShot(true); seek_timer_->setSingleShot(true);
seek_timer_->setInterval(kSeekDelay); seek_timer_->setInterval(kSeekDelay);
@ -495,9 +496,7 @@ bool GstEngine::Play( uint offset ) {
// If "Resume playback on start" is enabled, we must seek to the last position // If "Resume playback on start" is enabled, we must seek to the last position
if (offset) Seek(offset); if (offset) Seek(offset);
if (timer_id_ != -1) StartTimers();
killTimer(timer_id_);
timer_id_ = startTimer(kTimerInterval);
current_sample_ = 0; current_sample_ = 0;
emit StateChanged(Engine::Playing); emit StateChanged(Engine::Playing);
@ -506,8 +505,7 @@ bool GstEngine::Play( uint offset ) {
void GstEngine::Stop() { void GstEngine::Stop() {
killTimer(timer_id_); StopTimers();
timer_id_ = -1;
url_ = QUrl(); // To ensure we return Empty from state() url_ = QUrl(); // To ensure we return Empty from state()
@ -530,8 +528,7 @@ void GstEngine::Pause() {
current_pipeline_->SetState(GST_STATE_PAUSED); current_pipeline_->SetState(GST_STATE_PAUSED);
emit StateChanged(Engine::Paused); emit StateChanged(Engine::Paused);
killTimer(timer_id_); StopTimers();
timer_id_ = -1;
} }
} }
@ -543,7 +540,7 @@ void GstEngine::Unpause() {
current_pipeline_->SetState(GST_STATE_PLAYING); current_pipeline_->SetState(GST_STATE_PLAYING);
emit StateChanged(Engine::Playing); emit StateChanged(Engine::Playing);
timer_id_ = startTimer(kTimerInterval); StartTimers();
} }
} }
@ -594,23 +591,43 @@ void GstEngine::SetVolumeSW( uint percent ) {
current_pipeline_->SetVolume(percent); current_pipeline_->SetVolume(percent);
} }
void GstEngine::StartTimers() {
StopTimers();
void GstEngine::timerEvent( QTimerEvent* ) { prune_scope_timer_id_ = startTimer(kPruneScopeTimerInterval);
// keep the scope from building while we are not visible about_to_end_timer_id_ = startTimer(kAboutToEndTimerInterval);
// this is why the timer must run as long as we are playing, and not just when }
// we are fading
PruneScope();
// Emit TrackAboutToEnd when we're a few seconds away from finishing void GstEngine::StopTimers() {
if (current_pipeline_) { if (prune_scope_timer_id_ != -1) {
const qint64 nanosec_position = current_pipeline_->position(); killTimer(prune_scope_timer_id_);
const qint64 nanosec_length = current_pipeline_->length(); prune_scope_timer_id_ = -1;
const qint64 remaining = (nanosec_length - nanosec_position) / 1000000; }
const qint64 fudge = 100; // Mmm fudge
const qint64 gap = autocrossfade_enabled_ ? fadeout_duration_ : kPreloadGap;
if (nanosec_length > 0 && remaining < gap + fudge) if (about_to_end_timer_id_ != -1) {
EmitAboutToEnd(); killTimer(about_to_end_timer_id_);
about_to_end_timer_id_ = -1;
}
}
void GstEngine::timerEvent(QTimerEvent* e) {
if (e->timerId() == prune_scope_timer_id_) {
// keep the scope from building while we are not visible
// this is why the timer must run as long as we are playing, and not just when
// we are fading
PruneScope();
} else if (e->timerId() == about_to_end_timer_id_) {
// Emit TrackAboutToEnd when we're a few seconds away from finishing
if (current_pipeline_) {
const qint64 nanosec_position = current_pipeline_->position();
const qint64 nanosec_length = current_pipeline_->length();
const qint64 remaining = (nanosec_length - nanosec_position) / 1000000;
const qint64 fudge = kAboutToEndTimerInterval + 100; // Mmm fudge
const qint64 gap = autocrossfade_enabled_ ? fadeout_duration_ : kPreloadGap;
if (nanosec_length > 0 && remaining < gap + fudge)
EmitAboutToEnd();
}
} }
} }

View File

@ -130,6 +130,9 @@ class GstEngine : public Engine::Base, public BufferConsumer {
void StartFadeout(); void StartFadeout();
void StartTimers();
void StopTimers();
boost::shared_ptr<GstEnginePipeline> CreatePipeline(const QUrl& url); boost::shared_ptr<GstEnginePipeline> CreatePipeline(const QUrl& url);
void UpdateScope(); void UpdateScope();
@ -137,7 +140,8 @@ class GstEngine : public Engine::Base, public BufferConsumer {
private: private:
// Interval of main timer, handles the volume fading // Interval of main timer, handles the volume fading
static const int kTimerInterval = 40; // msec static const int kPruneScopeTimerInterval = 40; // msec
static const int kAboutToEndTimerInterval = 1500; // msec
static const int kPreloadGap = 1000; // msec static const int kPreloadGap = 1000; // msec
static const int kSeekDelay = 100; // msec static const int kSeekDelay = 100; // msec
@ -172,7 +176,8 @@ class GstEngine : public Engine::Base, public BufferConsumer {
bool waiting_to_seek_; bool waiting_to_seek_;
uint seek_pos_; uint seek_pos_;
int timer_id_; int prune_scope_timer_id_;
int about_to_end_timer_id_;
QHash<int, boost::shared_ptr<GstEnginePipeline> > background_streams_; QHash<int, boost::shared_ptr<GstEnginePipeline> > background_streams_;
}; };