From a0703a47ce03792b3981bb6c2f4b8af443dec619 Mon Sep 17 00:00:00 2001 From: beveloper Date: Tue, 3 Jun 2003 21:02:38 +0000 Subject: [PATCH] fixed BSoundPlayer::Stop() bugs exposed by CL-Amp git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3413 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/media/MediaEventLooper.cpp | 5 ++--- src/kits/media/SoundPlayNode.cpp | 12 ++++++++++++ src/kits/media/SoundPlayNode.h | 3 +++ src/kits/media/SoundPlayer.cpp | 20 ++++++++++++++++++-- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/kits/media/MediaEventLooper.cpp b/src/kits/media/MediaEventLooper.cpp index 5c24ed4f60..c9717025be 100644 --- a/src/kits/media/MediaEventLooper.cpp +++ b/src/kits/media/MediaEventLooper.cpp @@ -110,8 +110,7 @@ BMediaEventLooper::Stop(bigtime_t performance_time, if (immediate) { // always be sure to add to the front of the queue so we can make sure it is // handled before any buffers are sent! - performance_time = fEventQueue.FirstEventTime(); - performance_time = (performance_time == B_INFINITE_TIMEOUT) ? 0 : performance_time - 1; + performance_time = 0; } fEventQueue.AddEvent(media_timed_event(performance_time, BTimedEventQueue::B_STOP)); } @@ -372,7 +371,7 @@ void BMediaEventLooper::SetRunState(run_state state) { CALLED(); - + // don't allow run state changes while quitting, // also needed for correct terminating of the ControlLoop() if (fRunState == B_QUITTING && state != B_TERMINATED) diff --git a/src/kits/media/SoundPlayNode.cpp b/src/kits/media/SoundPlayNode.cpp index 7e4a0a6127..9e2fc804dd 100644 --- a/src/kits/media/SoundPlayNode.cpp +++ b/src/kits/media/SoundPlayNode.cpp @@ -68,6 +68,18 @@ _SoundPlayNode::~_SoundPlayNode() Quit(); } +bool +_SoundPlayNode::IsPlaying() +{ + return RunState() == B_STARTED; +} + +bigtime_t +_SoundPlayNode::Latency() +{ + return EventLatency(); +} + media_multi_audio_format _SoundPlayNode::Format() const diff --git a/src/kits/media/SoundPlayNode.h b/src/kits/media/SoundPlayNode.h index ef095a63b3..1cff65cecb 100644 --- a/src/kits/media/SoundPlayNode.h +++ b/src/kits/media/SoundPlayNode.h @@ -22,6 +22,9 @@ public: _SoundPlayNode(const char *name, const media_multi_audio_format *format, BSoundPlayer *player); ~_SoundPlayNode(); + bool IsPlaying(); + bigtime_t Latency(); + /*************************/ /* begin from BMediaNode */ public: diff --git a/src/kits/media/SoundPlayer.cpp b/src/kits/media/SoundPlayer.cpp index 54bdc9cd0f..827301035a 100644 --- a/src/kits/media/SoundPlayer.cpp +++ b/src/kits/media/SoundPlayer.cpp @@ -145,7 +145,7 @@ BSoundPlayer::Start() if (!_m_node) return B_ERROR; - + BMediaRoster *roster = BMediaRoster::Roster(); if (!roster) { TRACE("BSoundPlayer::Start: Couldn't get BMediaRoster\n"); @@ -171,6 +171,10 @@ BSoundPlayer::Stop(bool block, if (!_m_node) return; + + // XXX flush is ignored + + TRACE("BSoundPlayer::Stop: block %d, flush %d\n", (int)block, (int)flush); BMediaRoster *roster = BMediaRoster::Roster(); if (!roster) { @@ -179,7 +183,18 @@ BSoundPlayer::Stop(bool block, } roster->StopNode(_m_node->Node(), 0, true); - + + if (block) { + // wait until the node is stopped + int maxtrys; + for (maxtrys = 250; _m_node->IsPlaying() && maxtrys != 0; maxtrys--) + snooze(2000); + + DEBUG_ONLY(if (maxtrys == 0) printf("BSoundPlayer::Stop: waiting for node stop failed\n")); + + // wait until all buffers on the way to the physical output have been played + snooze(_m_node->Latency() + 2000); + } } BSoundPlayer::BufferPlayerFunc @@ -634,6 +649,7 @@ BSoundPlayer::PlayBuffer(void *buffer, const media_raw_audio_format &format) { // CALLED(); + _m_lock.Lock(); if (_PlayBuffer) (*_PlayBuffer)(_m_cookie,buffer,size,format);