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
16namespace BPrivate { namespace media {
17
18
19class BMediaClientNode;
20class BMediaConnection;
21class BMediaInput;
22class BMediaOutput;
23
24// Private stuff
25class InputReleaser;
26class 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.
35class BMediaClient {
36public:
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	// Called when the node is correctly registered to the media services.
57	virtual void					ClientRegistered();
58
59	// TODO: Should allow BControllable capabilities
60
61	// When those functions return, the BMediaConnection is added to the
62	// list and is visible to other nodes as not connected. Any input/output
63	// should be registered to a BMediaClient to become visible in the system.
64	virtual status_t				RegisterInput(BMediaInput* input);
65	virtual status_t				RegisterOutput(BMediaOutput* output);
66
67	// Bind internally two connections of the same BMediaClient, so that the
68	// input will be automatically forwarded to the output just after the
69	// ProcessFunc is called. The buffer is automatically recycled too.
70	// Beware that the binding operation is valid only for local connections
71	// which belong to this node, otherwise return B_ERROR.
72	virtual status_t				Bind(BMediaInput* input,
73										BMediaOutput* output);
74
75	virtual status_t				Unbind(BMediaInput* input,
76										BMediaOutput* output);
77
78	// If the user want a particular format for a connection it should
79	// use BMediaConnection::SetAcceptedFormat(), if it's not specified
80	// BMediaClient::Format() will be used, in case both aren't specified
81	// an error is returned. The first parameter should always belong to
82	// this node, the second will be a connection obtained from another
83	// BMediaClient. Unregistered connections will be registered automatically.
84	virtual status_t				Connect(BMediaConnection* ourConnection,
85										BMediaConnection* theirConnection);
86
87	virtual status_t				Connect(BMediaConnection* ourConnection,
88										const media_connection& theirConnection);
89
90	// Find a free input/output and try to connect to the media_client,
91	// return meaningful error otherwise.
92	virtual status_t				Connect(BMediaConnection* ourConnection,
93										const media_client& client);
94
95	// Disconnect any connection belonging to this object, to disconnect
96	// a single connection use BMediaConnection::Disconnect().
97	virtual status_t				Disconnect();
98
99			int32					CountInputs() const;
100			int32					CountOutputs() const;
101
102			BMediaInput*			InputAt(int32 index) const;
103			BMediaOutput*			OutputAt(int32 index) const;
104
105			BMediaInput*			FindInput(
106										const media_connection& input) const;
107			BMediaOutput*			FindOutput(
108										const media_connection& output) const;
109
110			bool					IsStarted() const;
111
112	// NOTE: The following functions aren't provided to be inherited,
113	// always use the protected HandleSomething version. This is because
114	// otherwise you could break the connection mechanism and mine interoperability
115	// from remote nodes.
116			status_t				Start();
117			status_t				Stop();
118			status_t				Seek(bigtime_t mediaTime,
119										bigtime_t performanceTime);
120			status_t				Roll(bigtime_t start, bigtime_t stop,
121										bigtime_t seek);
122
123	// Return the current performance time handled by the client.
124			bigtime_t				CurrentTime() const;
125
126	// This is supplied to support using this class in a BMediaAddOn.
127	// Default version just return NULL.
128	virtual	BMediaAddOn*			AddOn(int32* id) const;
129
130protected:
131	virtual void					HandleStart(bigtime_t performanceTime);
132	virtual void					HandleStop(bigtime_t performanceTime);
133
134	virtual void					HandleSeek(bigtime_t mediaTime,
135										bigtime_t performanceTime);
136
137	virtual status_t				FormatSuggestion(media_type type,
138										int32 quality, media_format* format);
139
140private:
141			void					_Init();
142			void					_Deinit();
143
144			void					_AddInput(BMediaInput* input);
145			void					_AddOutput(BMediaOutput* output);
146
147			BMediaInput*			_FindInput(
148										const media_destination& dest) const;
149			BMediaOutput*			_FindOutput(
150										const media_source& source) const;
151
152			status_t				_ConnectInput(BMediaOutput* output,
153										const media_connection& input);
154			status_t				_ConnectOutput(BMediaInput* input,
155										const media_connection& output);
156
157			status_t				_DisconnectConnection(BMediaConnection* conn);
158			status_t				_ReleaseConnection(BMediaConnection* conn);
159
160			status_t				fInitErr;
161
162			media_client			fClient;
163
164			bool					fRunning;
165			BMediaClientNode*		fNode;
166
167			bigtime_t				fCurrentTime;
168
169			BObjectList<InputReleaser>	fInputs;
170			BObjectList<OutputReleaser>	fOutputs;
171
172			media_connection_id		fLastID;
173
174	virtual	void					_ReservedMediaClient0();
175	virtual	void					_ReservedMediaClient1();
176	virtual	void					_ReservedMediaClient2();
177	virtual	void					_ReservedMediaClient3();
178	virtual	void					_ReservedMediaClient4();
179	virtual	void					_ReservedMediaClient5();
180	virtual	void					_ReservedMediaClient6();
181	virtual	void					_ReservedMediaClient7();
182	virtual	void					_ReservedMediaClient8();
183	virtual	void					_ReservedMediaClient9();
184	virtual	void					_ReservedMediaClient10();
185			uint32					fPadding[64];
186
187	friend class BMediaClientNode;
188	friend class BMediaConnection;
189	friend class BMediaInput;
190	friend class BMediaOutput;
191};
192
193
194}
195
196}
197
198using namespace BPrivate::media;
199
200#endif
201