1*0fc56ed5SStephan Aßmus /* 2*0fc56ed5SStephan Aßmus * Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@gmx.de>, 3*0fc56ed5SStephan Aßmus * Copyright (c) 2000-2008, Stephan Aßmus <superstippi@gmx.de>, 4*0fc56ed5SStephan Aßmus * All Rights Reserved. Distributed under the terms of the MIT license. 5*0fc56ed5SStephan Aßmus */ 6*0fc56ed5SStephan Aßmus 7*0fc56ed5SStephan Aßmus /*! This class controls our playback 8*0fc56ed5SStephan Aßmus Note: Add/RemoveListener() are the only methods that lock the object 9*0fc56ed5SStephan Aßmus themselves. All other methods need it to be locked before. 10*0fc56ed5SStephan Aßmus */ 11*0fc56ed5SStephan Aßmus #ifndef PLAYBACK_MANAGER_H 12*0fc56ed5SStephan Aßmus #define PLAYBACK_MANAGER_H 13*0fc56ed5SStephan Aßmus 14*0fc56ed5SStephan Aßmus 15*0fc56ed5SStephan Aßmus #include <List.h> 16*0fc56ed5SStephan Aßmus #include <Looper.h> 17*0fc56ed5SStephan Aßmus #include <Rect.h> 18*0fc56ed5SStephan Aßmus 19*0fc56ed5SStephan Aßmus 20*0fc56ed5SStephan Aßmus class PlaybackListener; 21*0fc56ed5SStephan Aßmus 22*0fc56ed5SStephan Aßmus 23*0fc56ed5SStephan Aßmus enum { 24*0fc56ed5SStephan Aßmus MODE_PLAYING_FORWARD = 1, 25*0fc56ed5SStephan Aßmus MODE_PLAYING_BACKWARD = 2, 26*0fc56ed5SStephan Aßmus MODE_PLAYING_PAUSED_FORWARD = -1, 27*0fc56ed5SStephan Aßmus MODE_PLAYING_PAUSED_BACKWARD = -2, 28*0fc56ed5SStephan Aßmus }; 29*0fc56ed5SStephan Aßmus 30*0fc56ed5SStephan Aßmus enum { 31*0fc56ed5SStephan Aßmus LOOPING_ALL = 0, 32*0fc56ed5SStephan Aßmus LOOPING_RANGE = 1, 33*0fc56ed5SStephan Aßmus LOOPING_SELECTION = 2, 34*0fc56ed5SStephan Aßmus LOOPING_VISIBLE = 3, 35*0fc56ed5SStephan Aßmus }; 36*0fc56ed5SStephan Aßmus 37*0fc56ed5SStephan Aßmus enum { 38*0fc56ed5SStephan Aßmus MSG_PLAYBACK_FORCE_UPDATE = 'pbfu', 39*0fc56ed5SStephan Aßmus MSG_PLAYBACK_SET_RANGE = 'pbsr', 40*0fc56ed5SStephan Aßmus MSG_PLAYBACK_SET_VISIBLE = 'pbsv', 41*0fc56ed5SStephan Aßmus MSG_PLAYBACK_SET_LOOP_MODE = 'pbsl', 42*0fc56ed5SStephan Aßmus }; 43*0fc56ed5SStephan Aßmus 44*0fc56ed5SStephan Aßmus 45*0fc56ed5SStephan Aßmus class PlaybackManager : public BLooper { 46*0fc56ed5SStephan Aßmus private: 47*0fc56ed5SStephan Aßmus struct PlayingState; 48*0fc56ed5SStephan Aßmus struct SpeedInfo; 49*0fc56ed5SStephan Aßmus 50*0fc56ed5SStephan Aßmus public: 51*0fc56ed5SStephan Aßmus PlaybackManager(); 52*0fc56ed5SStephan Aßmus virtual ~PlaybackManager(); 53*0fc56ed5SStephan Aßmus 54*0fc56ed5SStephan Aßmus void Init(float frameRate, 55*0fc56ed5SStephan Aßmus int32 loopingMode = LOOPING_ALL, 56*0fc56ed5SStephan Aßmus bool loopingEnabled = true, 57*0fc56ed5SStephan Aßmus float speed = 1.0, 58*0fc56ed5SStephan Aßmus int32 playMode = MODE_PLAYING_PAUSED_FORWARD, 59*0fc56ed5SStephan Aßmus int32 currentFrame = 0); 60*0fc56ed5SStephan Aßmus void Cleanup(); 61*0fc56ed5SStephan Aßmus 62*0fc56ed5SStephan Aßmus // BHandler interface 63*0fc56ed5SStephan Aßmus virtual void MessageReceived(BMessage* message); 64*0fc56ed5SStephan Aßmus 65*0fc56ed5SStephan Aßmus void StartPlaying(bool atBeginning = false); 66*0fc56ed5SStephan Aßmus void StopPlaying(); 67*0fc56ed5SStephan Aßmus void TogglePlaying(bool atBeginning = false); 68*0fc56ed5SStephan Aßmus void PausePlaying(); 69*0fc56ed5SStephan Aßmus bool IsPlaying() const; 70*0fc56ed5SStephan Aßmus 71*0fc56ed5SStephan Aßmus int32 PlayMode() const; 72*0fc56ed5SStephan Aßmus int32 LoopMode() const; 73*0fc56ed5SStephan Aßmus bool IsLoopingEnabled() const; 74*0fc56ed5SStephan Aßmus int32 CurrentFrame() const; 75*0fc56ed5SStephan Aßmus float Speed() const; 76*0fc56ed5SStephan Aßmus 77*0fc56ed5SStephan Aßmus virtual void SetFramesPerSecond(float framesPerSecond); 78*0fc56ed5SStephan Aßmus float FramesPerSecond() const; 79*0fc56ed5SStephan Aßmus 80*0fc56ed5SStephan Aßmus virtual BRect VideoBounds() const = 0; 81*0fc56ed5SStephan Aßmus 82*0fc56ed5SStephan Aßmus virtual void FrameDropped() const; 83*0fc56ed5SStephan Aßmus 84*0fc56ed5SStephan Aßmus void DurationChanged(); 85*0fc56ed5SStephan Aßmus virtual int64 Duration() = 0; 86*0fc56ed5SStephan Aßmus 87*0fc56ed5SStephan Aßmus virtual void SetVolume(float percent) = 0; 88*0fc56ed5SStephan Aßmus 89*0fc56ed5SStephan Aßmus // playing state manipulation 90*0fc56ed5SStephan Aßmus void SetCurrentFrame(int64 frame); 91*0fc56ed5SStephan Aßmus virtual void SetPlayMode(int32 mode, 92*0fc56ed5SStephan Aßmus bool continuePlaying = true); 93*0fc56ed5SStephan Aßmus void SetLoopMode(int32 mode, 94*0fc56ed5SStephan Aßmus bool continuePlaying = true); 95*0fc56ed5SStephan Aßmus void SetLoopingEnabled(bool enabled, 96*0fc56ed5SStephan Aßmus bool continuePlaying = true); 97*0fc56ed5SStephan Aßmus void SetSpeed(float speed); 98*0fc56ed5SStephan Aßmus 99*0fc56ed5SStephan Aßmus // playing state change info 100*0fc56ed5SStephan Aßmus int64 NextFrame() const; 101*0fc56ed5SStephan Aßmus int64 NextPlaylistFrame() const; 102*0fc56ed5SStephan Aßmus 103*0fc56ed5SStephan Aßmus int64 FirstPlaybackRangeFrame(); 104*0fc56ed5SStephan Aßmus int64 LastPlaybackRangeFrame(); 105*0fc56ed5SStephan Aßmus 106*0fc56ed5SStephan Aßmus // playing state access 107*0fc56ed5SStephan Aßmus int64 StartFrameAtFrame(int64 frame); 108*0fc56ed5SStephan Aßmus int64 StartFrameAtTime(bigtime_t time); 109*0fc56ed5SStephan Aßmus int64 EndFrameAtFrame(int64 frame); 110*0fc56ed5SStephan Aßmus int64 EndFrameAtTime(bigtime_t time); 111*0fc56ed5SStephan Aßmus int64 FrameCountAtFrame(int64 frame); 112*0fc56ed5SStephan Aßmus int64 FrameCountAtTime(bigtime_t time); 113*0fc56ed5SStephan Aßmus int32 PlayModeAtFrame(int64 frame); 114*0fc56ed5SStephan Aßmus int32 PlayModeAtTime(bigtime_t time); 115*0fc56ed5SStephan Aßmus int32 LoopModeAtFrame(int64 frame); 116*0fc56ed5SStephan Aßmus int32 LoopModeAtTime(bigtime_t time); 117*0fc56ed5SStephan Aßmus // ... 118*0fc56ed5SStephan Aßmus 119*0fc56ed5SStephan Aßmus // playing frame/time/interval info 120*0fc56ed5SStephan Aßmus int64 PlaylistFrameAtFrame(int64 frame, 121*0fc56ed5SStephan Aßmus int32& playingDirection, 122*0fc56ed5SStephan Aßmus bool& newState) const; 123*0fc56ed5SStephan Aßmus int64 PlaylistFrameAtFrame(int64 frame, 124*0fc56ed5SStephan Aßmus int32& playingDirection) const; 125*0fc56ed5SStephan Aßmus int64 PlaylistFrameAtFrame(int64 frame) const; 126*0fc56ed5SStephan Aßmus int64 NextChangeFrame(int64 startFrame, 127*0fc56ed5SStephan Aßmus int64 endFrame) const; 128*0fc56ed5SStephan Aßmus bigtime_t NextChangeTime(bigtime_t startTime, 129*0fc56ed5SStephan Aßmus bigtime_t endTime) const; 130*0fc56ed5SStephan Aßmus void GetPlaylistFrameInterval( 131*0fc56ed5SStephan Aßmus int64 startFrame, int64& endFrame, 132*0fc56ed5SStephan Aßmus int64& xStartFrame, int64& xEndFrame, 133*0fc56ed5SStephan Aßmus int32& playingDirection) const; 134*0fc56ed5SStephan Aßmus 135*0fc56ed5SStephan Aßmus // PlaybackManagerInterface 136*0fc56ed5SStephan Aßmus virtual void GetPlaylistTimeInterval( 137*0fc56ed5SStephan Aßmus bigtime_t startTime, bigtime_t& endTime, 138*0fc56ed5SStephan Aßmus bigtime_t& xStartTime, bigtime_t& xEndTime, 139*0fc56ed5SStephan Aßmus float& playingSpeed) const; 140*0fc56ed5SStephan Aßmus 141*0fc56ed5SStephan Aßmus // conversion: video frame <-> (performance) time 142*0fc56ed5SStephan Aßmus int64 FrameForTime(bigtime_t time) const; 143*0fc56ed5SStephan Aßmus bigtime_t TimeForFrame(int64 frame) const; 144*0fc56ed5SStephan Aßmus // conversion: (performance) time <-> real time 145*0fc56ed5SStephan Aßmus virtual bigtime_t RealTimeForTime(bigtime_t time) const = 0; 146*0fc56ed5SStephan Aßmus virtual bigtime_t TimeForRealTime(bigtime_t time) const = 0; 147*0fc56ed5SStephan Aßmus // conversion: Playist frame <-> Playlist time 148*0fc56ed5SStephan Aßmus int64 PlaylistFrameForTime(bigtime_t time) const; 149*0fc56ed5SStephan Aßmus bigtime_t PlaylistTimeForFrame(int64 frame) const; 150*0fc56ed5SStephan Aßmus 151*0fc56ed5SStephan Aßmus // to be called by audio/video producers 152*0fc56ed5SStephan Aßmus virtual void SetCurrentAudioTime(bigtime_t time); 153*0fc56ed5SStephan Aßmus void SetCurrentVideoFrame(int64 frame); 154*0fc56ed5SStephan Aßmus void SetCurrentVideoTime(bigtime_t time); 155*0fc56ed5SStephan Aßmus void SetPerformanceFrame(int64 frame); 156*0fc56ed5SStephan Aßmus void SetPerformanceTime(bigtime_t time); 157*0fc56ed5SStephan Aßmus 158*0fc56ed5SStephan Aßmus // listener support 159*0fc56ed5SStephan Aßmus void AddListener(PlaybackListener* listener); 160*0fc56ed5SStephan Aßmus void RemoveListener(PlaybackListener* listener); 161*0fc56ed5SStephan Aßmus 162*0fc56ed5SStephan Aßmus virtual void NotifyPlayModeChanged(int32 mode) const; 163*0fc56ed5SStephan Aßmus virtual void NotifyLoopModeChanged(int32 mode) const; 164*0fc56ed5SStephan Aßmus virtual void NotifyLoopingEnabledChanged( 165*0fc56ed5SStephan Aßmus bool enabled) const; 166*0fc56ed5SStephan Aßmus virtual void NotifyVideoBoundsChanged(BRect bounds) const; 167*0fc56ed5SStephan Aßmus virtual void NotifyFPSChanged(float fps) const; 168*0fc56ed5SStephan Aßmus virtual void NotifyCurrentFrameChanged(int32 frame) const; 169*0fc56ed5SStephan Aßmus virtual void NotifySpeedChanged(float speed) const; 170*0fc56ed5SStephan Aßmus virtual void NotifyFrameDropped() const; 171*0fc56ed5SStephan Aßmus virtual void NotifyStopFrameReached() const; 172*0fc56ed5SStephan Aßmus 173*0fc56ed5SStephan Aßmus // debugging 174*0fc56ed5SStephan Aßmus void PrintState(PlayingState* state); 175*0fc56ed5SStephan Aßmus void PrintStateAtFrame(int64 frame); 176*0fc56ed5SStephan Aßmus 177*0fc56ed5SStephan Aßmus private: 178*0fc56ed5SStephan Aßmus // state management 179*0fc56ed5SStephan Aßmus void _PushState(PlayingState* state, 180*0fc56ed5SStephan Aßmus bool adjustCurrentFrame); 181*0fc56ed5SStephan Aßmus void _UpdateStates(); 182*0fc56ed5SStephan Aßmus int32 _IndexForFrame(int64 frame) const; 183*0fc56ed5SStephan Aßmus int32 _IndexForTime(bigtime_t time) const; 184*0fc56ed5SStephan Aßmus PlayingState* _LastState() const; 185*0fc56ed5SStephan Aßmus PlayingState* _StateAt(int32 index) const; 186*0fc56ed5SStephan Aßmus PlayingState* _StateAtTime(bigtime_t time) const; 187*0fc56ed5SStephan Aßmus PlayingState* _StateAtFrame(int64 frame) const; 188*0fc56ed5SStephan Aßmus 189*0fc56ed5SStephan Aßmus static int32 _PlayingDirectionFor(int32 playingMode); 190*0fc56ed5SStephan Aßmus static int32 _PlayingDirectionFor(PlayingState* state); 191*0fc56ed5SStephan Aßmus static void _GetPlayingBoundsFor(PlayingState* state, 192*0fc56ed5SStephan Aßmus int64& startFrame, 193*0fc56ed5SStephan Aßmus int64& endFrame, 194*0fc56ed5SStephan Aßmus int64& frameCount); 195*0fc56ed5SStephan Aßmus static int64 _PlayingStartFrameFor(PlayingState* state); 196*0fc56ed5SStephan Aßmus static int64 _PlayingEndFrameFor(PlayingState* state); 197*0fc56ed5SStephan Aßmus static int64 _RangeFrameForFrame(PlayingState* state, 198*0fc56ed5SStephan Aßmus int64 frame); 199*0fc56ed5SStephan Aßmus static int64 _FrameForRangeFrame(PlayingState* state, 200*0fc56ed5SStephan Aßmus int64 index); 201*0fc56ed5SStephan Aßmus static int64 _NextFrameInRange(PlayingState* state, 202*0fc56ed5SStephan Aßmus int64 frame); 203*0fc56ed5SStephan Aßmus 204*0fc56ed5SStephan Aßmus // speed management 205*0fc56ed5SStephan Aßmus void _PushSpeedInfo(SpeedInfo* info); 206*0fc56ed5SStephan Aßmus SpeedInfo* _LastSpeedInfo() const; 207*0fc56ed5SStephan Aßmus SpeedInfo* _SpeedInfoAt(int32 index) const; 208*0fc56ed5SStephan Aßmus int32 _SpeedInfoIndexForFrame(int64 frame) const; 209*0fc56ed5SStephan Aßmus int32 _SpeedInfoIndexForTime(bigtime_t time) const; 210*0fc56ed5SStephan Aßmus SpeedInfo* _SpeedInfoForFrame(int64 frame) const; 211*0fc56ed5SStephan Aßmus SpeedInfo* _SpeedInfoForTime(bigtime_t time) const; 212*0fc56ed5SStephan Aßmus void _UpdateSpeedInfos(); 213*0fc56ed5SStephan Aßmus 214*0fc56ed5SStephan Aßmus bigtime_t _TimeForLastFrame() const; 215*0fc56ed5SStephan Aßmus bigtime_t _TimeForNextFrame() const; 216*0fc56ed5SStephan Aßmus 217*0fc56ed5SStephan Aßmus void _CheckStopPlaying(); 218*0fc56ed5SStephan Aßmus 219*0fc56ed5SStephan Aßmus private: 220*0fc56ed5SStephan Aßmus BList fStates; 221*0fc56ed5SStephan Aßmus BList fSpeeds; 222*0fc56ed5SStephan Aßmus volatile bigtime_t fCurrentAudioTime; 223*0fc56ed5SStephan Aßmus volatile bigtime_t fCurrentVideoTime; 224*0fc56ed5SStephan Aßmus volatile bigtime_t fPerformanceTime; 225*0fc56ed5SStephan Aßmus volatile float fFrameRate; // video frame rate 226*0fc56ed5SStephan Aßmus volatile bigtime_t fStopPlayingFrame; // frame at which playing 227*0fc56ed5SStephan Aßmus // shall be stopped, 228*0fc56ed5SStephan Aßmus // disabled: -1 229*0fc56ed5SStephan Aßmus 230*0fc56ed5SStephan Aßmus BList fListeners; 231*0fc56ed5SStephan Aßmus }; 232*0fc56ed5SStephan Aßmus 233*0fc56ed5SStephan Aßmus 234*0fc56ed5SStephan Aßmus #endif // PLAYBACK_MANAGER_H 235