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; };