xref: /haiku/headers/private/media/experimental/MediaClient.h (revision 7de0fd45cd01d32785b29bc882ebc9d935de5632)
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 	// Called when the node is correctly registered to the media services.
109 	//virtual void					ReadyToRun() const;
110 
111 	// NOTE: The following functions aren't provided to be inherited,
112 	// always use the protected HandleSomething version. This is because
113 	// otherwise you could break the connection mechanism and mine interoperability
114 	// from remote nodes.
115 			status_t				Start();
116 			status_t				Stop();
117 			status_t				Seek(bigtime_t mediaTime,
118 										bigtime_t performanceTime);
119 			status_t				Roll(bigtime_t start, bigtime_t stop,
120 										bigtime_t seek);
121 
122 	// TODO: We really want to expose Preroll and SyncTo?
123 	// Preroll the client to buffer startup latency
124 			status_t				Preroll();
125 
126 	// This function return when the client reach the specified performanceTime
127 			status_t				SyncTo(bigtime_t performanceTime,
128 										bigtime_t timeout = -1);
129 
130 	// Return the current performance time handled by the client.
131 			bigtime_t				CurrentTime() const;
132 
133 	// This is supplied to support using this class in a BMediaAddOn.
134 	// Default version just return NULL.
135 	virtual	BMediaAddOn*			AddOn(int32* id) const;
136 
137 protected:
138 	virtual void					HandleStart(bigtime_t performanceTime);
139 	virtual void					HandleStop(bigtime_t performanceTime);
140 
141 	virtual void					HandleSeek(bigtime_t mediaTime,
142 										bigtime_t performanceTime);
143 
144 	virtual status_t				FormatSuggestion(media_type type,
145 										int32 quality, media_format* format);
146 
147 private:
148 			void					_Init();
149 			void					_Deinit();
150 
151 			void					_AddInput(BMediaInput* input);
152 			void					_AddOutput(BMediaOutput* output);
153 
154 			BMediaInput*			_FindInput(
155 										const media_destination& dest) const;
156 			BMediaOutput*			_FindOutput(
157 										const media_source& source) const;
158 
159 			status_t				_ConnectInput(BMediaOutput* output,
160 										const media_connection& input);
161 			status_t				_ConnectOutput(BMediaInput* input,
162 										const media_connection& output);
163 
164 			status_t				_DisconnectConnection(BMediaConnection* conn);
165 			status_t				_ReleaseConnection(BMediaConnection* conn);
166 
167 			status_t				fInitErr;
168 
169 			media_client			fClient;
170 
171 			bool					fRunning;
172 			BMediaClientNode*		fNode;
173 
174 			bigtime_t				fCurrentTime;
175 
176 			BObjectList<InputReleaser>	fInputs;
177 			BObjectList<OutputReleaser>	fOutputs;
178 
179 			media_connection_id		fLastID;
180 
181 	virtual	void					_ReservedMediaClient0();
182 	virtual	void					_ReservedMediaClient1();
183 	virtual	void					_ReservedMediaClient2();
184 	virtual	void					_ReservedMediaClient3();
185 	virtual	void					_ReservedMediaClient4();
186 	virtual	void					_ReservedMediaClient5();
187 	virtual	void					_ReservedMediaClient6();
188 	virtual	void					_ReservedMediaClient7();
189 	virtual	void					_ReservedMediaClient8();
190 	virtual	void					_ReservedMediaClient9();
191 	virtual	void					_ReservedMediaClient10();
192 			uint32					fPadding[64];
193 
194 	friend class BMediaClientNode;
195 	friend class BMediaConnection;
196 	friend class BMediaInput;
197 	friend class BMediaOutput;
198 };
199 
200 
201 }
202 
203 }
204 
205 using namespace BPrivate::media;
206 
207 #endif
208