1/*
2 * Copyright 2009-2012, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _MEDIA_NODE_H
6#define _MEDIA_NODE_H
7
8
9#include <MediaDefs.h>
10#include <Point.h>
11
12#include <new>
13
14
15class BBufferConsumer;
16class BBufferProducer;
17class BControllable;
18class BFileInterface;
19class BMediaAddOn;
20class BTimeSource;
21
22
23class media_node {
24public:
25								media_node();
26								~media_node();
27
28			media_node_id		node;
29			port_id				port;
30			uint32				kind;
31
32	static const media_node		null;
33
34private:
35			uint32				_reserved_[3];
36};
37
38
39struct media_input {
40								media_input();
41								~media_input();
42
43			media_node			node;
44			media_source		source;
45			media_destination	destination;
46			media_format		format;
47			char				name[B_MEDIA_NAME_LENGTH];
48
49private:
50			uint32				_reserved_media_input_[4];
51};
52
53
54struct media_output {
55								media_output();
56								~media_output();
57
58			media_node			node;
59			media_source		source;
60			media_destination	destination;
61			media_format		format;
62			char				name[B_MEDIA_NAME_LENGTH];
63
64private:
65			uint32				_reserved_media_output_[4];
66};
67
68
69struct live_node_info {
70								live_node_info();
71								~live_node_info();
72
73			media_node			node;
74			BPoint				hint_point;
75			char				name[B_MEDIA_NAME_LENGTH];
76
77private:
78			char				reserved[160];
79};
80
81
82struct media_request_info {
83			enum what_code {
84				B_SET_VIDEO_CLIPPING_FOR = 1,
85				B_REQUEST_FORMAT_CHANGE,
86				B_SET_OUTPUT_ENABLED,
87				B_SET_OUTPUT_BUFFERS_FOR,
88
89				B_FORMAT_CHANGED = 4097
90			};
91
92			what_code			what;
93			int32				change_tag;
94			status_t			status;
95			void*				cookie;
96			void*				user_data;
97			media_source		source;
98			media_destination	destination;
99			media_format		format;
100
101			uint32				_reserved_[32];
102};
103
104
105struct media_node_attribute {
106			enum {
107				B_R40_COMPILED = 1,
108				B_USER_ATTRIBUTE_NAME = 0x1000000,
109				B_FIRST_USER_ATTRIBUTE
110			};
111
112			uint32				what;
113			uint32				flags;
114			int64				data;
115};
116
117
118namespace BPrivate {
119	namespace media {
120		class TimeSourceObject;
121		class SystemTimeSourceObject;
122		class BMediaRosterEx;
123	}
124} // BPrivate::media
125
126
127/*!	BMediaNode is the indirect base class for all Media Kit participants.
128	However, you should use the more specific BBufferConsumer, BBufferProducer
129	and others rather than BMediaNode directly. It's OK to multiply inherit.
130*/
131class BMediaNode {
132protected:
133	// NOTE: Call Release() to destroy a node.
134	virtual								~BMediaNode();
135
136public:
137			enum run_mode {
138				B_OFFLINE = 1,
139					// This mode has no realtime constraint.
140				B_DECREASE_PRECISION,
141					// When late, try to catch up by reducing quality.
142				B_INCREASE_LATENCY,
143					// When late, increase the presentation time offset.
144				B_DROP_DATA,
145					// When late, try to catch up by dropping buffers.
146				B_RECORDING
147					// For nodes on the receiving end of recording.
148					// Buffers will always be late.
149			};
150
151			BMediaNode*			Acquire();
152			BMediaNode*			Release();
153
154			const char*			Name() const;
155			media_node_id		ID() const;
156			uint64				Kinds() const;
157			media_node			Node() const;
158			run_mode			RunMode() const;
159			BTimeSource*		TimeSource() const;
160
161	// ID of the port used to listen to control messages.
162	virtual	port_id				ControlPort() const;
163
164	// Who instantiated this node or NULL for application internal class.
165	virtual	BMediaAddOn*		AddOn(int32* internalID) const = 0;
166
167	// Message constants which will be sent to anyone watching the
168	// MediaRoster. The message field "be:node_id" will contain the node ID.
169			enum node_error {
170				// Note that these belong with the notifications in
171				// MediaDefs.h! They are here to provide compiler type
172				// checking in ReportError().
173				B_NODE_FAILED_START					= 'TRI0',
174				B_NODE_FAILED_STOP					= 'TRI1',
175				B_NODE_FAILED_SEEK					= 'TRI2',
176				B_NODE_FAILED_SET_RUN_MODE			= 'TRI3',
177				B_NODE_FAILED_TIME_WARP				= 'TRI4',
178				B_NODE_FAILED_PREROLL				= 'TRI5',
179				B_NODE_FAILED_SET_TIME_SOURCE_FOR	= 'TRI6',
180				B_NODE_IN_DISTRESS					= 'TRI7'
181				// What field 'TRIA' and up are used in MediaDefs.h
182			};
183
184protected:
185	// Sends one of the above codes to anybody who's watching. You can
186	// provide an optional message with additional information.
187			status_t			ReportError(node_error what,
188									const BMessage* info = NULL);
189
190	// When you've handled a stop request, call this function. If anyone is
191	// listening for stop information from you, they will be notified.
192	// Especially important for offline capable Nodes.
193			status_t			NodeStopped(bigtime_t performanceTime);
194			void				TimerExpired(bigtime_t notifyPerformanceTime,
195									int32 cookie, status_t error = B_OK);
196
197	// NOTE: Constructor initializes the reference count to 1.
198	explicit					BMediaNode(const char* name);
199
200				status_t		WaitForMessage(bigtime_t waitUntil,
201									uint32 flags = 0, void* _reserved_ = 0);
202
203	// These don't return errors; instead, they use the global error condition
204	// reporter. A node is required to have a queue of at least one pending
205	// command (plus TimeWarp) and is recommended to allow for at least one
206	// pending command of each type. Allowing an arbitrary number of
207	// outstanding commands might be nice, but apps cannot depend on that
208	// happening.
209	virtual	void				Start(bigtime_t atPerformanceTime);
210	virtual	void				Stop(bigtime_t atPerformanceTime,
211									bool immediate);
212	virtual	void				Seek(bigtime_t toMediaTime,
213									bigtime_t atPerformanceTime);
214	virtual	void				SetRunMode(run_mode mode);
215	virtual	void				TimeWarp(bigtime_t atRealTime,
216									bigtime_t toPerformanceTime);
217	virtual	void				Preroll();
218	virtual	void				SetTimeSource(BTimeSource* timeSource);
219
220public:
221	virtual	status_t			HandleMessage(int32 message, const void* data,
222									size_t size);
223
224	// Call this with messages you and your superclasses don't recognize.
225			void				HandleBadMessage(int32 code,
226									const void* buffer, size_t size);
227
228	// Called from derived system classes; you don't need to
229			void				AddNodeKind(uint64 kind);
230
231	// These just call the default global versions for now.
232			void*				operator new(size_t size);
233			void*				operator new(size_t size,
234									const std::nothrow_t&) throw();
235			void				operator delete(void* ptr);
236			void				operator delete(void* ptr,
237									const std::nothrow_t&) throw();
238
239protected:
240	// Hook method which is called when requests have completed, or failed.
241	virtual	status_t			RequestCompleted(
242									const media_request_info & info);
243
244	virtual	status_t			DeleteHook(BMediaNode* node);
245
246	virtual	void				NodeRegistered();
247
248public:
249
250	// Fill out your attributes in the provided array, returning however
251	// many you have.
252	virtual	status_t			GetNodeAttributes(
253									media_node_attribute* _attributes,
254									size_t inMaxCount);
255
256	virtual	status_t			AddTimer(bigtime_t atPerformanceTime,
257									int32 cookie);
258
259private:
260			friend class BTimeSource;
261			friend class BMediaRoster;
262			friend class BBufferProducer;
263			friend class BPrivate::media::TimeSourceObject;
264			friend class BPrivate::media::SystemTimeSourceObject;
265			friend class BPrivate::media::BMediaRosterEx;
266
267			// Deprecated in BeOS R4.1
268			int32				IncrementChangeTag();
269			int32				ChangeTag();
270			int32				MintChangeTag();
271			status_t			ApplyChangeTag(int32 previouslyReserved);
272
273private:
274	// FBC padding and forbidden methods
275			status_t			_Reserved_MediaNode_0(void*);
276				// RequestCompletionHook()
277			status_t			_Reserved_MediaNode_1(void*);
278				// DeleteHook()
279			status_t			_Reserved_MediaNode_2(void*);
280				// NodeRegistered()
281			status_t			_Reserved_MediaNode_3(void*);
282				// GetNodeAttributes()
283			status_t			_Reserved_MediaNode_4(void*);
284				// AddTimer()
285	virtual	status_t			_Reserved_MediaNode_5(void*);
286	virtual	status_t			_Reserved_MediaNode_6(void*);
287	virtual	status_t			_Reserved_MediaNode_7(void*);
288	virtual	status_t			_Reserved_MediaNode_8(void*);
289	virtual	status_t			_Reserved_MediaNode_9(void*);
290	virtual	status_t			_Reserved_MediaNode_10(void*);
291	virtual	status_t			_Reserved_MediaNode_11(void*);
292	virtual	status_t			_Reserved_MediaNode_12(void*);
293	virtual	status_t			_Reserved_MediaNode_13(void*);
294	virtual	status_t			_Reserved_MediaNode_14(void*);
295	virtual	status_t			_Reserved_MediaNode_15(void*);
296
297								BMediaNode();
298								BMediaNode(const BMediaNode& other);
299			BMediaNode&			operator=(const BMediaNode& other);
300
301private:
302								BMediaNode(const char* name,
303									media_node_id id, uint32 kinds);
304
305			void				_InitObject(const char* name,
306									media_node_id id, uint64 kinds);
307
308private:
309			media_node_id		fNodeID;
310			BTimeSource*		fTimeSource;
311			int32				fRefCount;
312			char				fName[B_MEDIA_NAME_LENGTH];
313			run_mode			fRunMode;
314
315			int32				_reserved[2];
316
317			uint64				fKinds;
318			media_node_id		fTimeSourceID;
319
320			BBufferProducer*	fProducerThis;
321			BBufferConsumer*	fConsumerThis;
322			BFileInterface*		fFileInterfaceThis;
323			BControllable*		fControllableThis;
324			BTimeSource*		fTimeSourceThis;
325
326			bool				_reservedBool[4];
327
328	mutable	port_id				fControlPort;
329
330			uint32				_reserved_media_node_[8];
331
332protected:
333	static	int32				NewChangeTag();
334		// for use by BBufferConsumer, mostly
335
336private:
337	// NOTE: Dont' rename this one, it's static and needed for binary
338	// compatibility
339	static	int32 _m_changeTag;
340		// not to be confused with _mChangeCount
341};
342
343
344#endif // _MEDIA_NODE_H
345