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