[Slim-Checkins] r10962 - in /branches/6.5/server/Slim/Player:
Client.pm Source.pm Squeezebox.pm
andy at svn.slimdevices.com
andy at svn.slimdevices.com
Thu Dec 14 12:06:53 PST 2006
Author: andy
Date: Thu Dec 14 12:06:52 2006
New Revision: 10962
URL: http://svn.slimdevices.com?rev=10962&view=rev
Log:
Rebuffering code take 2... this uses a new event STMo which will be part of the next firmware
Modified:
branches/6.5/server/Slim/Player/Client.pm
branches/6.5/server/Slim/Player/Source.pm
branches/6.5/server/Slim/Player/Squeezebox.pm
Modified: branches/6.5/server/Slim/Player/Client.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Player/Client.pm?rev=10962&r1=10961&r2=10962&view=diff
==============================================================================
--- branches/6.5/server/Slim/Player/Client.pm (original)
+++ branches/6.5/server/Slim/Player/Client.pm Thu Dec 14 12:06:52 2006
@@ -175,6 +175,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;
@@ -1686,4 +1687,9 @@
@_ ? ($r->[113] = shift) : $r->[113];
}
+sub bufferStarted {
+ my $r = shift;
+ @_ ? ($r->[114] = shift) : $r->[114];
+}
+
1;
Modified: branches/6.5/server/Slim/Player/Source.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Player/Source.pm?rev=10962&r1=10961&r2=10962&view=diff
==============================================================================
--- branches/6.5/server/Slim/Player/Source.pm (original)
+++ branches/6.5/server/Slim/Player/Source.pm Thu Dec 14 12:06:52 2006
@@ -57,6 +57,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
@@ -632,6 +633,96 @@
$::d_source && msg("Error: Decoder does not support file format, skipping track\n");
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 ( $::d_source ) {
+ my $decoder = $client->bufferFullness();
+ my $output = $client->outputBufferFullness();
+ msg( "Output buffer underrun (decoder: $decoder / output: $output)\n" );
+ }
+
+ 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();
+
+ $::d_source && msg( "Rebuffering: $fullness / $threshold\n" );
+
+ 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: branches/6.5/server/Slim/Player/Squeezebox.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Player/Squeezebox.pm?rev=10962&r1=10961&r2=10962&view=diff
==============================================================================
--- branches/6.5/server/Slim/Player/Squeezebox.pm (original)
+++ branches/6.5/server/Slim/Player/Squeezebox.pm Thu Dec 14 12:06:52 2006
@@ -24,9 +24,6 @@
use Slim::Player::ProtocolHandlers;
use Slim::Utils::Misc;
use Slim::Utils::Network;
-
-# Track when clients begin to buffer streams
-our $buffering = {};
BEGIN {
if ($^O =~ /Win32/) {
@@ -167,7 +164,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,
@@ -192,8 +189,6 @@
#
sub resume {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -208,8 +203,6 @@
sub pause {
my $client = shift;
- delete $buffering->{$client};
-
Slim::Utils::Timers::killTimers($client, \&buffering);
$client->stream('p');
@@ -219,8 +212,6 @@
sub stop {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -233,8 +224,6 @@
sub flush {
my $client = shift;
-
- delete $buffering->{$client};
Slim::Utils::Timers::killTimers($client, \&buffering);
@@ -248,8 +237,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;
}
@@ -310,7 +298,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