From eb91d0058dead0e6f8dc79cc531907fb31012b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 14 Jul 2008 21:58:07 +0000 Subject: [PATCH] * Whether an audio and/or video node is used is now more explicit. The audio node can now also be turned off for videos that don't have audio. * The PlaybackManager currently has the "no audio" support added in a not quite so nice way, will have to think about something, this is just quick and dirty to get it going. There is just two places where the audio time needs to be ignored, because it remains at zero. -> Especially when using OSS, the seeking latency will be much reduced when playing videos that have no sound. * The Controller now maintains the frame it wanted to seek to and does not forward "position changed" to other listeners as long as the seek frame has not been reached. This fixes the slider jumping back to the old position for a bit until jumping back to the seek frame. It also fixes another problem when switching to the next file. Because the total duration is already adopted while the old clip is still playing within the seek latency, the current position jumped to the new relative position, while it is still refering to the position within the old clip. So both seeking and switching clips looks much smoother now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26415 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/Controller.cpp | 33 +++++++++-- src/apps/mediaplayer/Controller.h | 1 + .../media_node_framework/NodeManager.cpp | 56 ++++++++++++------- .../media_node_framework/NodeManager.h | 13 ++++- .../media_node_framework/PlaybackManager.cpp | 11 +++- .../media_node_framework/PlaybackManager.h | 2 + 6 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index 4237f9fa30..e3960a6cc6 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -100,6 +100,7 @@ Controller::Controller() , fPosition(0) , fDuration(0) , fVideoFrameRate(25.0) + , fSeekFrame(-1) , fAutoplay(true) , fPauseAtEndOfStream(false) @@ -164,7 +165,7 @@ Controller::SetTo(const entry_ref &ref) if (fRef == ref) { if (InitCheck() == B_OK) { - SetCurrentFrame(0); + SetPosition(0.0); StartPlaying(); } return B_OK; @@ -269,17 +270,25 @@ Controller::SetTo(const entry_ref &ref) preferredVideoFormat = format.u.raw_video.display.format; } + uint32 enabledNodes; + if (!fVideoTrackSupplier) + enabledNodes = AUDIO_ONLY; + else if (!fAudioTrackSupplier) + enabledNodes = VIDEO_ONLY; + else + enabledNodes = AUDIO_AND_VIDEO; + if (InitCheck() != B_OK) { Init(BRect(0, 0, width - 1, height - 1), fVideoFrameRate, - preferredVideoFormat, LOOPING_ALL, false); + preferredVideoFormat, LOOPING_ALL, false, 1.0, enabledNodes); } else { FormatChanged(BRect(0, 0, width - 1, height - 1), fVideoFrameRate, - preferredVideoFormat); + preferredVideoFormat, enabledNodes); } _NotifyFileChanged(); - SetCurrentFrame(0); + SetPosition(0.0); if (fAutoplay) StartPlaying(true); @@ -420,7 +429,7 @@ Controller::Stop() BAutolock _(this); StopPlaying(); - SetCurrentFrame(0); + SetPosition(0.0); } @@ -559,8 +568,14 @@ Controller::SetPosition(float value) { BAutolock _(this); - SetCurrentFrame(Duration() * value); + fSeekFrame = (int32)(Duration() * value); + int32 currentFrame = CurrentFrame(); + if (fSeekFrame != currentFrame) + SetCurrentFrame(fSeekFrame); + else + fSeekFrame = -1; + // TODO: What was this used for in the old framework? fSeekToStartAfterPause = false; } @@ -891,6 +906,12 @@ Controller::NotifyFPSChanged(float fps) const void Controller::NotifyCurrentFrameChanged(int32 frame) const { + // check if we are still waiting to reach the seekframe, + // don't pass the event on to the listeners in that case + if (fSeekFrame >= 0 && frame != fSeekFrame) + return; + fSeekFrame = -1; + float position = 0.0; double duration = (double)fDuration * fVideoFrameRate / 1000000.0; if (duration > 0) diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index 0ae23c2738..c389edd6c8 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -174,6 +174,7 @@ private: mutable bigtime_t fPosition; bigtime_t fDuration; float fVideoFrameRate; + mutable int32 fSeekFrame; bool fAutoplay; volatile bool fPauseAtEndOfStream; diff --git a/src/apps/mediaplayer/media_node_framework/NodeManager.cpp b/src/apps/mediaplayer/media_node_framework/NodeManager.cpp index cfb4216a05..88032e5dfa 100644 --- a/src/apps/mediaplayer/media_node_framework/NodeManager.cpp +++ b/src/apps/mediaplayer/media_node_framework/NodeManager.cpp @@ -67,7 +67,7 @@ NodeManager::~NodeManager() status_t NodeManager::Init(BRect videoBounds, float videoFrameRate, color_space preferredVideoFormat, int32 loopingMode, - bool loopingEnabled, float speed) + bool loopingEnabled, float speed, uint32 enabledNodes) { // init base class PlaybackManager::Init(videoFrameRate, loopingMode, loopingEnabled, speed); @@ -83,7 +83,7 @@ NodeManager::Init(BRect videoBounds, float videoFrameRate, fAudioSupplier = CreateAudioSupplier(); return FormatChanged(videoBounds, videoFrameRate, preferredVideoFormat, - true); + enabledNodes, true); } // InitCheck @@ -118,13 +118,16 @@ NodeManager::CleanupNodes() // FormatChanged status_t NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, - color_space preferredVideoFormat, bool force) + color_space preferredVideoFormat, uint32 enabledNodes, bool force) { TRACE("NodeManager::FormatChanged()\n"); if (!force && videoBounds == VideoBounds() && videoFrameRate == FramesPerSecond()) { TRACE(" -> reusing existing nodes\n"); + // TODO: if enabledNodes would indicate that audio or video + // is no longer needed, or, worse yet, suddenly needed when + // it wasn't before, then we should not return here! return B_OK; } @@ -139,7 +142,7 @@ NodeManager::FormatChanged(BRect videoBounds, float videoFrameRate, SetVideoBounds(videoBounds); - status_t ret = _SetUpNodes(preferredVideoFormat); + status_t ret = _SetUpNodes(preferredVideoFormat, enabledNodes); if (ret == B_OK) _StartNodes(); else @@ -247,7 +250,7 @@ NodeManager::SetPeakListener(BHandler* handler) // _SetUpNodes status_t -NodeManager::_SetUpNodes(color_space preferredVideoFormat) +NodeManager::_SetUpNodes(color_space preferredVideoFormat, uint32 enabledNodes) { TRACE("NodeManager::_SetUpNodes()\n"); @@ -271,7 +274,7 @@ NodeManager::_SetUpNodes(color_space preferredVideoFormat) } // setup the video nodes - if (fVideoBounds.IsValid()) { + if (enabledNodes != AUDIO_ONLY) { fStatus = _SetUpVideoNodes(preferredVideoFormat); if (fStatus != B_OK) { print_error("Error setting up video nodes", fStatus); @@ -282,11 +285,17 @@ NodeManager::_SetUpNodes(color_space preferredVideoFormat) printf("running without video node\n"); // setup the audio nodes - fStatus = _SetUpAudioNodes(); - if (fStatus != B_OK) { - print_error("Error setting up audio nodes", fStatus); - fMediaRoster->Unlock(); - return fStatus; + if (enabledNodes != VIDEO_ONLY) { + fStatus = _SetUpAudioNodes(); + if (fStatus != B_OK) { + print_error("Error setting up audio nodes", fStatus); + fMediaRoster->Unlock(); + return fStatus; + } +fNoAudio = false; + } else { +fNoAudio = true; + printf("running without audio node\n"); } // we're done mocking with the media roster @@ -589,7 +598,7 @@ status_t NodeManager::_StartNodes() { status_t status = B_NO_INIT; - if (!fMediaRoster || !fAudioProducer) + if (!fMediaRoster) return status; // begin mucking with the media roster if (!fMediaRoster->Lock()) @@ -623,10 +632,13 @@ NodeManager::_StartNodes() } initLatency += estimate_max_scheduling_latency(); - bigtime_t audioLatency = 0; - status = fMediaRoster->GetLatencyFor(fAudioConnection.producer, - &audioLatency); - TRACE("audio latency: %Ld\n", audioLatency); + if (fAudioProducer) { + // TODO: was this supposed to be added to initLatency?!? + bigtime_t audioLatency = 0; + status = fMediaRoster->GetLatencyFor(fAudioConnection.producer, + &audioLatency); + TRACE("audio latency: %Ld\n", audioLatency); + } BTimeSource* timeSource; if (fVideoProducer) { @@ -677,11 +689,13 @@ printf("performance time for %lld: %lld\n", real + latency } } - fAudioProducer->SetRunning(true); - status = fMediaRoster->StartNode(fAudioConnection.producer, perf); - if (status != B_OK) { - print_error("Can't start the audio producer", status); - return status; + if (fAudioProducer) { + fAudioProducer->SetRunning(true); + status = fMediaRoster->StartNode(fAudioConnection.producer, perf); + if (status != B_OK) { + print_error("Can't start the audio producer", status); + return status; + } } fPerformanceTimeBase = perf; diff --git a/src/apps/mediaplayer/media_node_framework/NodeManager.h b/src/apps/mediaplayer/media_node_framework/NodeManager.h index 5bfee3fec7..e36a29e8a7 100644 --- a/src/apps/mediaplayer/media_node_framework/NodeManager.h +++ b/src/apps/mediaplayer/media_node_framework/NodeManager.h @@ -32,11 +32,18 @@ class NodeManager : public PlaybackManager { virtual AudioSupplier* CreateAudioSupplier() = 0; // NodeManager + enum { + AUDIO_AND_VIDEO = 0, + VIDEO_ONLY, + AUDIO_ONLY + }; + status_t Init(BRect videoBounds, float videoFrameRate, color_space preferredVideoFormat, int32 loopingMode = LOOPING_ALL, bool loopingEnabled = true, - float speed = 1.0); + float speed = 1.0, + uint32 enabledNodes = AUDIO_AND_VIDEO); status_t InitCheck(); // only call this if the // media_server has died! @@ -45,6 +52,7 @@ class NodeManager : public PlaybackManager { status_t FormatChanged(BRect videoBounds, float videoFrameRate, color_space preferredVideoFormat, + uint32 enabledNodes = AUDIO_AND_VIDEO, bool force = false); virtual void SetPlayMode(int32 mode, bool continuePlaying = true); @@ -65,7 +73,8 @@ class NodeManager : public PlaybackManager { void SetPeakListener(BHandler* handler); private: - status_t _SetUpNodes(color_space preferredVideoFormat); + status_t _SetUpNodes(color_space preferredVideoFormat, + uint32 enabledNodes); status_t _SetUpVideoNodes( color_space preferredVideoFormat); status_t _SetUpAudioNodes(); diff --git a/src/apps/mediaplayer/media_node_framework/PlaybackManager.cpp b/src/apps/mediaplayer/media_node_framework/PlaybackManager.cpp index 3c969a3c77..e085453302 100644 --- a/src/apps/mediaplayer/media_node_framework/PlaybackManager.cpp +++ b/src/apps/mediaplayer/media_node_framework/PlaybackManager.cpp @@ -67,7 +67,8 @@ PlaybackManager::PlaybackManager() fPerformanceTime(0), fFrameRate(1.0), fStopPlayingFrame(-1), - fListeners() + fListeners(), + fNoAudio(false) { Run(); } @@ -452,8 +453,11 @@ PlaybackManager::SetSpeed(float speed) int64 PlaybackManager::NextFrame() const { + if (fNoAudio) + return FrameForTime(fCurrentVideoTime - 1) + 1; + return FrameForTime(max((bigtime_t)fCurrentAudioTime, - (bigtime_t)fCurrentVideoTime) - 1) + 1; + (bigtime_t)fCurrentVideoTime) - 1) + 1; } @@ -1549,6 +1553,9 @@ PlaybackManager::_UpdateSpeedInfos() bigtime_t PlaybackManager::_TimeForLastFrame() const { + if (fNoAudio) + return TimeForFrame(FrameForTime(fCurrentVideoTime)); + return TimeForFrame(FrameForTime(min((bigtime_t)fCurrentAudioTime, (bigtime_t)fCurrentVideoTime))); } diff --git a/src/apps/mediaplayer/media_node_framework/PlaybackManager.h b/src/apps/mediaplayer/media_node_framework/PlaybackManager.h index adc1133f47..a580abbb67 100644 --- a/src/apps/mediaplayer/media_node_framework/PlaybackManager.h +++ b/src/apps/mediaplayer/media_node_framework/PlaybackManager.h @@ -228,6 +228,8 @@ public: // disabled: -1 BList fListeners; + protected: + bool fNoAudio; };