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
20class MessageEvent;
21class PlaybackListener;
22
23
24enum {
25	MODE_PLAYING_FORWARD			= 1,
26	MODE_PLAYING_BACKWARD			= 2,
27	MODE_PLAYING_PAUSED_FORWARD		= -1,
28	MODE_PLAYING_PAUSED_BACKWARD	= -2,
29};
30
31enum {
32	LOOPING_ALL						= 0,
33	LOOPING_RANGE					= 1,
34	LOOPING_SELECTION				= 2,
35	LOOPING_VISIBLE					= 3,
36};
37
38enum {
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
46class PlaybackManager : public BLooper {
47private:
48			struct PlayingState;
49			struct SpeedInfo;
50
51public:
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
224private:
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;
239protected:
240 			bool				fNoAudio;
241};
242
243
244#endif	// PLAYBACK_MANAGER_H
245