[Slim-Checkins] r10963 - in /trunk/server/Slim/Player: Client.pm
Source.pm Squeezebox.pm
andy at svn.slimdevices.com
andy at svn.slimdevices.com
Thu Dec 14 12:11:00 PST 2006
Author: andy
Date: Thu Dec 14 12:11:00 2006
New Revision: 10963
URL: http://svn.slimdevices.com?rev=10963&view=rev
Log:
Rebuffering code take 2... this uses a new event STMo which will be part of the next firmware
Modified:
trunk/server/Slim/Player/Client.pm
trunk/server/Slim/Player/Source.pm
trunk/server/Slim/Player/Squeezebox.pm
Modified: trunk/server/Slim/Player/Client.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Player/Client.pm?rev=10963&r1=10962&r2=10963&view=diff
==============================================================================
--- trunk/server/Slim/Player/Client.pm (original)
+++ trunk/server/Slim/Player/Client.pm Thu Dec 14 12:11:00 2006
@@ -176,6 +176,7 @@
$client->[111] = {}; # pipe sockets used for parent/child communication
$client->[112] = 0; # knobSync
$client->[113] = {}; # pendingPrefChanges
+ $client->[114] = 0; # bufferStarted, tracks when players begin buffering/rebuffering
$clientHash{$id} = $client;
@@ -1704,4 +1705,9 @@
@_ ? ($r->[113] = shift) : $r->[113];
}
+sub bufferStarted {
+ my $r = shift;
+ @_ ? ($r->[114] = shift) : $r->[114];
+}
+
1;
Modified: trunk/server/Slim/Player/Source.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Player/Source.pm?rev=10963&r1=10962&r2=10963&view=diff
==============================================================================
--- trunk/server/Slim/Player/Source.pm (original)
+++ trunk/server/Slim/Player/Source.pm Thu Dec 14 12:11:00 2006
@@ -51,6 +51,7 @@
Slim::Networking::Slimproto::setEventCallback('STMd', \&decoderUnderrun);
Slim::Networking::Slimproto::setEventCallback('STMs', \&trackStartEvent);
Slim::Networking::Slimproto::setEventCallback('STMn', \¬Supported);
+ Slim::Networking::Slimproto::setEventCallback('STMo', \&outputUnderrun);
}
# rate can be negative for rew, zero for pause, 1 for playback and greater than one for ffwd
@@ -634,6 +635,96 @@
logError("Decoder does not support file format, skipping track");
errorOpening($client);
+}
+
+sub outputUnderrun {
+ my $client = shift;
+
+ # STMo is called when the output buffer underruns but the decoder connection is still active.
+ # It signals that we need to pause and rebuffer the live audio stream.
+
+ return unless $client->playmode() =~ /play/;
+
+ if ( $log->is_debug ) {
+ my $decoder = $client->bufferFullness();
+ my $output = $client->outputBufferFullness();
+ $log->debug( "Output buffer underrun (decoder: $decoder / output: $output)" );
+ }
+
+ playmode( $client, 'pause' );
+
+ my ( $line1, $line2 );
+
+ my $string = 'REBUFFERING';
+ $line1 = $client->string('NOW_PLAYING') . ' (' . $client->string($string) . ' 0%)';
+ if ( $client->linesPerScreen() == 1 ) {
+ $line2 = $client->string($string) . ' 0%';
+ }
+ else {
+ my $url = Slim::Player::Playlist::url($client);
+ $line2 = Slim::Music::Info::title($url);
+ }
+
+ $client->showBriefly( $line1, $line2, 2 ) unless $client->display->sbName();
+
+ # Setup a timer to check the buffer and unpause
+ $client->bufferStarted( Time::HiRes::time() ); # track when we started rebuffering
+ Slim::Utils::Timers::setTimer( $client, Time::HiRes::time() + 1, \&rebuffer );
+}
+
+sub rebuffer {
+ my $client = shift;
+
+ # If the user changes something, stop rebuffering
+ return unless $client->playmode() eq 'pause';
+
+ $client->requestStatus();
+
+ my $threshold = 80 * 1024; # 5 seconds of 128k
+
+ my $url = Slim::Player::Playlist::url($client);
+ if ( my $bitrate = Slim::Music::Info::getBitrate($url) ) {
+ $threshold = 5 * ( int($bitrate / 8) );
+ }
+
+ # We restart playback based on the decode buffer,
+ # as the output buffer is not updated in pause mode.
+ my $fullness = $client->bufferFullness();
+
+ $log->debug( "Rebuffering: $fullness / $threshold" );
+
+ if ( $fullness >= $threshold ) {
+ playmode( $client, 'play' );
+
+ $client->update();
+ }
+ else {
+
+ # Only show rebuffering status if no user activity on player or we're on the Now Playing screen
+ my $nowPlaying = Slim::Buttons::Playlist::showingNowPlaying($client);
+ my $lastIR = Slim::Hardware::IR::lastIRTime($client) || 0;
+
+ if ( $nowPlaying || $lastIR < $client->bufferStarted() ) {
+ my ( $line1, $line2 );
+
+ # Bug 1827, display better buffering feedback while we wait for data
+ my $percent = sprintf "%d%%", ( $fullness / $threshold ) * 100;
+
+ my $string = 'REBUFFERING';
+ $line1 = $client->string('NOW_PLAYING') . ' (' . $client->string($string) . " $percent)";
+ if ( $client->linesPerScreen() == 1 ) {
+ $line2 = $client->string($string) . " $percent";
+ }
+ else {
+ my $url = Slim::Player::Playlist::url($client);
+ $line2 = Slim::Music::Info::title($url);
+ }
+
+ $client->showBriefly( $line1, $line2, 2 ) unless $client->display->sbName();
+ }
+
+ Slim::Utils::Timers::setTimer( $client, Time::HiRes::time() + 1, \&rebuffer );
+ }
}
sub skipahead {
Modified: trunk/server/Slim/Player/Squeezebox.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Player/Squeezebox.pm?rev=10963&r1=10962&r2=10963&view=diff
==============================================================================
--- trunk/server/Slim/Player/Squeezebox.pm (original)
+++ trunk/server/Slim/Player/Squeezebox.pm Thu Dec 14 12:11:00 2006
@@ -27,9 +27,6 @@
use Slim::Utils::Misc;
use Slim::Utils::Network;
-# Track when clients begin to buffer streams
-our $buffering = {};
-
# We inherit new() completely from our parent class.
sub init {
@@ -161,7 +158,7 @@
}
# Set a timer for feedback during buffering
- $buffering->{$client} = Time::HiRes::time(); # track when we started buffering
+ $client->bufferStarted( Time::HiRes::time() ); # track when we started buffering
Slim::Utils::Timers::killTimers( $client, \&buffering );
Slim::Utils::Timers::setTimer(
$client,
@@ -186,8 +183,6 @@
#
sub resume {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -202,8 +197,6 @@
sub pause {
my $client = shift;
- delete $buffering->{$client};
-
Slim::Utils::Timers::killTimers($client, \&buffering);
$client->stream('p');
@@ -213,8 +206,6 @@
sub stop {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -227,8 +218,6 @@
sub flush {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -244,8 +233,7 @@
# If the track has started, stop displaying buffering status
# currentPlaylistChangeTime is set to time() after a track start event
- if ( $client->currentPlaylistChangeTime() > $buffering->{$client} ) {
- delete $buffering->{$client};
+ if ( $client->currentPlaylistChangeTime() > $client->bufferStarted() ) {
$client->update();
return;
}
@@ -306,7 +294,7 @@
my $nowPlaying = Slim::Buttons::Playlist::showingNowPlaying($client);
my $lastIR = Slim::Hardware::IR::lastIRTime($client) || 0;
- if ( $nowPlaying || $lastIR < $buffering->{$client} ) {
+ if ( $nowPlaying || $lastIR < $client->bufferStarted() ) {
$client->showBriefly( $line1, $line2, 0.5 ) unless $client->display->sbName();
# Call again unless we've reached the threshold
More information about the checkins
mailing list