xref: /haiku/headers/private/media/experimental/MediaClient.h (revision 78fea9cd2df1bf223498d258bd7e09f1a351bc5e)
1 /*
2  * Copyright 2015-2018, Dario Casalinuovo. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #ifndef _MEDIA_CLIENT_H
7 #define _MEDIA_CLIENT_H
8 
9 #include <Buffer.h>
10 #include <MediaAddOn.h>
11 #include <MediaClientDefs.h>
12 #include <MediaDefs.h>
13 #include <ObjectList.h>
14 
15 
16 namespace BPrivate { namespace media {
17 
18 
19 class BMediaClientNode;
20 class BMediaConnection;
21 class BMediaInput;
22 class BMediaOutput;
23 
24 // Private stuff
25 class InputReleaser;
26 class OutputReleaser;
27 
28 
29 // BMediaClient is a general purpose class allowing to create any kind
30 // of media_node. It automatically manage the expected behavior under
31 // different run modes, and allow to specify the different capabilities needed.
32 // BMediaClient is not using any of the coding patterns you might be used to.
33 // There are no events to care, and threading is managed internally using
34 // the data processing specified by the BMediaGraph class.
35 class BMediaClient {
36 public:
37 									BMediaClient(const char* name,
38 										media_type type
39 											= B_MEDIA_UNKNOWN_TYPE,
40 										media_client_kinds
41 											kind = B_MEDIA_PLAYER
42 												& B_MEDIA_RECORDER);
43 
44 	virtual							~BMediaClient();
45 
46 			const media_client&		Client() const;
47 
48 			media_client_id			Id() const;
49 			const char*				Name() const;
50 	// Return the capabilities of this BMediaClient instance.
51 			media_client_kinds		Kinds() const;
52 			media_type				MediaType() const;
53 
54 			status_t				InitCheck() const;
55 
56 	// TODO: Should allow BControllable capabilities
57 
58 	// When those functions return, the BMediaConnection is added to the
59 	// list and is visible to other nodes as not connected. Any input/output
60 	// should be registered to a BMediaClient to become visible in the system.
61 	virtual status_t				RegisterInput(BMediaInput* input);
62 	virtual status_t				RegisterOutput(BMediaOutput* output);
63 
64 	// Bind internally two connections of the same BMediaClient, so that the
65 	// input will be automatically forwarded to the output just after the
66 	// ProcessFunc is called. The buffer is automatically recycled too.
67 	// Beware that the binding operation is valid only for local connections
68 	// which belong to this node, otherwise return B_ERROR.
69 	virtual status_t				Bind(BMediaInput* input,
70 										BMediaOutput* output);
71 
72 	virtual status_t				Unbind(BMediaInput* input,
73 										BMediaOutput* output);
74 
75 	// If the user want a particular format for a connection it should
76 	// use BMediaConnection::SetAcceptedFormat(), if it's not specified
77 	// BMediaClient::Format() will be used, in case both aren't specified
78 	// an error is returned. The first parameter should always belong to
79 	// this node, the second will be a connection obtained from another
80 	// BMediaClient. Unregistered connections will be registered automatically.
81 	virtual status_t				Connect(BMediaConnection* ourConnection,
82 										BMediaConnection* theirConnection);
83 
84 	virtual status_t				Connect(BMediaConnection* ourConnection,
85 										const media_connection& theirConnection);
86 
87 	// Find a free input/output and try to connect to the media_client,
88 	// return meaningful error otherwise.
89 	virtual status_t				Connect(BMediaConnection* ourConnection,
90 										const media_client& client);
91 
92 	// Disconnect any connection belonging to this object, to disconnect
93 	// a single connection use BMediaConnection::Disconnect().
94 	virtual status_t				Disconnect();
95 
96 			int32					CountInputs() const;
97 			int32					CountOutputs() const;
98 
99 			BMediaInput*			InputAt(int32 index) const;
100 			BMediaOutput*			OutputAt(int32 index) const;
101 
102 			BMediaInput*			FindInput(
103 										const media_connection& input) const;
104 			BMediaOutput*			FindOutput(
105 										const media_connection& output) const;
106 
107 			bool					IsRunning() const;
108 
109 	// NOTE: The following functions aren't provided to be inherited,
110 	// always use the protected HandleSomething version. This is because
111 	// otherwise you could break the connection mechanism and mine interoperability
112 	// from remote nodes.
113 			status_t				Start();
114 			status_t				Stop();
115 			status_t				Seek(bigtime_t mediaTime,
116 										bigtime_t performanceTime);
117 			status_t				Roll(bigtime_t start, bigtime_t stop,
118 										bigtime_t seek);
119 
120 	// Preroll the client to buffer startup latency
121 			status_t				Preroll();
122 
123 	// This function return when the client reach the specified performanceTime
124 			status_t				SyncTo(bigtime_t performanceTime,
125 										bigtime_t timeout = -1);
126 
127 	// Return the current performance time handled by the object when
128 	// run_mode != B_OFFLINE. Otherwise returns the current offline time.
129 			bigtime_t				CurrentTime() const;
130 
131 	// This is supplied to support using this class in a BMediaAddOn.
132 	// Default version just return NULL.
133 	virtual	BMediaAddOn*			AddOn(int32* id) const;
134 
135 protected:
136 	virtual void					HandleStart(bigtime_t performanceTime);
137 	virtual void					HandleStop(bigtime_t performanceTime);
138 
139 	virtual void					HandleSeek(bigtime_t mediaTime,
140 										bigtime_t performanceTime);
141 
142 	virtual status_t				FormatSuggestion(media_type type,
143 										int32 quality, media_format* format);
144 
145 private:
146 			void					_Init();
147 			void					_Deinit();
148 
149 			void					_AddInput(BMediaInput* input);
150 			void					_AddOutput(BMediaOutput* output);
151 
152 			BMediaInput*			_FindInput(
153 										const media_destination& dest) const;
154 			BMediaOutput*			_FindOutput(
155 										const media_source& source) const;
156 
157 			status_t				_ConnectInput(BMediaOutput* output,
158 										const media_connection& input);
159 			status_t				_ConnectOutput(BMediaInput* input,
160 										const media_connection& output);
161 
162 			status_t				_DisconnectConnection(BMediaConnection* conn);
163 			status_t				_ReleaseConnection(BMediaConnection* conn);
164 
165 			status_t				fInitErr;
166 
167 			media_client			fClient;
168 
169 			bool					fRunning;
170 			BMediaClientNode*		fNode;
171 
172 			bigtime_t				fCurrentTime;
173 
174 			BObjectList<InputReleaser>	fInputs;
175 			BObjectList<OutputReleaser>	fOutputs;
176 
177 			media_connection_id		fLastID;
178 
179 	virtual	void					_ReservedMediaClient0();
180 	virtual	void					_ReservedMediaClient1();
181 	virtual	void					_ReservedMediaClient2();
182 	virtual	void					_ReservedMediaClient3();
183 	virtual	void					_ReservedMediaClient4();
184 	virtual	void					_ReservedMediaClient5();
185 	virtual	void					_ReservedMediaClient6();
186 	virtual	void					_ReservedMediaClient7();
187 	virtual	void					_ReservedMediaClient8();
188 	virtual	void					_ReservedMediaClient9();
189 	virtual	void					_ReservedMediaClient10();
190 			uint32					fPadding[64];
191 
192 	friend class BMediaClientNode;
193 	friend class BMediaConnection;
194 	friend class BMediaInput;
195 	friend class BMediaOutput;
196 };
197 
198 
199 }
200 
201 }
202 
203 using namespace BPrivate::media;
204 
205 #endif
206