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