aboutsummaryrefslogtreecommitdiffstats
path: root/src/PlayerThread.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-01-07 21:39:47 +0100
committerMax Kellermann <max@duempel.org>2014-01-09 09:05:58 +0100
commit322b0616322760dc162447563d8f4da7e024ca90 (patch)
tree2f87cb3ce061556161797aba9f57ee08de5b9e21 /src/PlayerThread.cxx
parent43847f2244a34064af24704aac4cfad4a3c76f7d (diff)
downloadmpd-322b0616322760dc162447563d8f4da7e024ca90.tar.gz
mpd-322b0616322760dc162447563d8f4da7e024ca90.tar.xz
mpd-322b0616322760dc162447563d8f4da7e024ca90.zip
DetachedSong: fork of struct Song
From now on, struct Song will be used by the database only, and DetachedSong will be used by everybody else. DetachedSong is easier to use, but Song has lower overhead.
Diffstat (limited to '')
-rw-r--r--src/PlayerThread.cxx70
1 files changed, 30 insertions, 40 deletions
diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx
index 84d248d7b..814269b50 100644
--- a/src/PlayerThread.cxx
+++ b/src/PlayerThread.cxx
@@ -24,7 +24,7 @@
#include "MusicPipe.hxx"
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
-#include "Song.hxx"
+#include "DetachedSong.hxx"
#include "system/FatalError.hxx"
#include "CrossFade.hxx"
#include "PlayerControl.hxx"
@@ -92,7 +92,7 @@ class Player {
/**
* the song currently being played
*/
- Song *song;
+ DetachedSong *song;
/**
* is cross fading enabled?
@@ -290,12 +290,12 @@ Player::StartDecoder(MusicPipe &_pipe)
assert(queued || pc.command == PlayerCommand::SEEK);
assert(pc.next_song != nullptr);
- unsigned start_ms = pc.next_song->start_ms;
+ unsigned start_ms = pc.next_song->GetStartMS();
if (pc.command == PlayerCommand::SEEK)
start_ms += (unsigned)(pc.seek_where * 1000);
- dc.Start(pc.next_song->DupDetached(),
- start_ms, pc.next_song->end_ms,
+ dc.Start(new DetachedSong(*pc.next_song),
+ start_ms, pc.next_song->GetEndMS(),
buffer, _pipe);
}
@@ -329,7 +329,7 @@ Player::WaitForDecoder()
if (error.IsDefined()) {
pc.SetError(PlayerError::DECODER, std::move(error));
- pc.next_song->Free();
+ delete pc.next_song;
pc.next_song = nullptr;
pc.Unlock();
@@ -339,9 +339,7 @@ Player::WaitForDecoder()
pc.ClearTaggedSong();
- if (song != nullptr)
- song->Free();
-
+ delete song;
song = pc.next_song;
elapsed_time = 0.0;
@@ -370,17 +368,20 @@ Player::WaitForDecoder()
* indicated by the decoder plugin.
*/
static double
-real_song_duration(const Song &song, double decoder_duration)
+real_song_duration(const DetachedSong &song, double decoder_duration)
{
if (decoder_duration <= 0.0)
/* the decoder plugin didn't provide information; fall
back to Song::GetDuration() */
return song.GetDuration();
- if (song.end_ms > 0 && song.end_ms / 1000.0 < decoder_duration)
- return (song.end_ms - song.start_ms) / 1000.0;
+ const unsigned start_ms = song.GetStartMS();
+ const unsigned end_ms = song.GetEndMS();
+
+ if (end_ms > 0 && end_ms / 1000.0 < decoder_duration)
+ return (end_ms - start_ms) / 1000.0;
- return decoder_duration - song.start_ms / 1000.0;
+ return decoder_duration - start_ms / 1000.0;
}
bool
@@ -458,10 +459,10 @@ Player::CheckDecoderStartup()
decoder_starting = false;
if (!paused && !OpenOutput()) {
- const auto uri = dc.song->GetURI();
FormatError(player_domain,
"problems opening audio device "
- "while playing \"%s\"", uri.c_str());
+ "while playing \"%s\"",
+ dc.song->GetURI());
return true;
}
@@ -516,7 +517,7 @@ Player::SeekDecoder()
{
assert(pc.next_song != nullptr);
- const unsigned start_ms = pc.next_song->start_ms;
+ const unsigned start_ms = pc.next_song->GetStartMS();
if (!dc.LockIsCurrentSong(*pc.next_song)) {
/* the decoder is already decoding the "next" song -
@@ -542,7 +543,7 @@ Player::SeekDecoder()
ClearAndReplacePipe(dc.pipe);
}
- pc.next_song->Free();
+ delete pc.next_song;
pc.next_song = nullptr;
queued = false;
}
@@ -658,7 +659,7 @@ Player::ProcessCommand()
pc.Lock();
}
- pc.next_song->Free();
+ delete pc.next_song;
pc.next_song = nullptr;
queued = false;
pc.CommandFinished();
@@ -681,17 +682,14 @@ Player::ProcessCommand()
}
static void
-update_song_tag(PlayerControl &pc, Song &song, const Tag &new_tag)
+update_song_tag(PlayerControl &pc, DetachedSong &song, const Tag &new_tag)
{
if (song.IsFile())
/* don't update tags of local files, only remote
streams may change tags dynamically */
return;
- Tag *old_tag = song.tag;
- song.tag = new Tag(new_tag);
-
- delete old_tag;
+ song.SetTag(new_tag);
pc.LockSetTaggedSong(song);
@@ -713,7 +711,7 @@ update_song_tag(PlayerControl &pc, Song &song, const Tag &new_tag)
*/
static bool
play_chunk(PlayerControl &pc,
- Song &song, struct music_chunk *chunk,
+ DetachedSong &song, struct music_chunk *chunk,
MusicBuffer &buffer,
const AudioFormat format,
Error &error)
@@ -880,10 +878,7 @@ Player::SongBorder()
{
xfade_state = CrossFadeState::UNKNOWN;
- {
- const auto uri = song->GetURI();
- FormatDefault(player_domain, "played \"%s\"", uri.c_str());
- }
+ FormatDefault(player_domain, "played \"%s\"", song->GetURI());
ReplacePipe(dc.pipe);
@@ -1079,9 +1074,8 @@ Player::Run()
delete cross_fade_tag;
if (song != nullptr) {
- const auto uri = song->GetURI();
- FormatDefault(player_domain, "played \"%s\"", uri.c_str());
- song->Free();
+ FormatDefault(player_domain, "played \"%s\"", song->GetURI());
+ delete song;
}
pc.Lock();
@@ -1090,7 +1084,7 @@ Player::Run()
if (queued) {
assert(pc.next_song != nullptr);
- pc.next_song->Free();
+ delete pc.next_song;
pc.next_song = nullptr;
}
@@ -1139,10 +1133,8 @@ player_task(void *arg)
/* fall through */
case PlayerCommand::PAUSE:
- if (pc.next_song != nullptr) {
- pc.next_song->Free();
- pc.next_song = nullptr;
- }
+ delete pc.next_song;
+ pc.next_song = nullptr;
pc.CommandFinished();
break;
@@ -1177,10 +1169,8 @@ player_task(void *arg)
return;
case PlayerCommand::CANCEL:
- if (pc.next_song != nullptr) {
- pc.next_song->Free();
- pc.next_song = nullptr;
- }
+ delete pc.next_song;
+ pc.next_song = nullptr;
pc.CommandFinished();
break;