1/*
2 * Copyright 2015-2018, Dario Casalinuovo. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#ifndef _MEDIA_CONNECTION_H
7#define _MEDIA_CONNECTION_H
8
9#include <BufferGroup.h>
10#include <MediaDefs.h>
11
12#include <MediaClient.h>
13#include <MediaClientDefs.h>
14
15
16namespace BPrivate { namespace media {
17
18class BMediaClientNode;
19
20
21// The BMediaConnection class is the swiss knife of BMediaClient.
22// It represents a connection between two nodes and allow to create complex
23// nodes without dealing with the unneeded complexity. Two local connections,
24// can be binded, this means that when you will receive a buffer A as input,
25// the BufferReceived function will be called so that you can process the BBuffer,
26// and once the function returns the output will be automatically forwarded
27// to the connection B SendBuffer method.
28// It's not possible to mix a BMediaInput with a BMediaOutput in the same class.
29class BMediaConnection {
30public:
31	const media_connection&			Connection() const;
32	BMediaClient*					Client() const;
33
34	media_connection_id				Id() const;
35	const char*						Name() const;
36
37	bool							HasBinding() const;
38	BMediaConnection*				Binding() const;
39
40	bool							IsConnected() const;
41
42	// If the connection is connected get the other endpoint,
43	// return media_connection::null otherwise.
44	media_connection				Endpoint();
45
46	// Represents the buffer size, implement it to return the buffer size
47	// you decided for this connection.
48	// TODO: Do we want this (and ChainSize) moved on the output side?
49	// Or perhaps provide an implementation based on the buffer group
50	// for the consumer?
51	// Problem is: the consumer has not easy access to the buffer group,
52	// so we way want to add a special messaging between clients after
53	// connection, so that inputs know the buffer size and chain size.
54	virtual size_t					BufferSize() const = 0;
55	// Implement it to specify the size of your chain of buffers.
56	//virtual int32					ChainSize() const = 0;
57
58	// Disconnect this connection. When a connection is disconnected,
59	// it can be reused as brand new.
60	status_t						Disconnect();
61
62	// Once you are done with this connection you release it, it automatically
63	// remove the object from the BMediaClient and free all used resources.
64	// This will make the connection to disappear completely, so if you
65	// want to preserve it for future connections just Disconnect() it.
66	status_t						Release();
67
68protected:
69									BMediaConnection(
70										media_connection_kinds kinds,
71										const char* name = NULL);
72	virtual							~BMediaConnection();
73
74private:
75	// Those callbacks are shared between BMediaInput and BMediaOutput
76	virtual void					Connected(const media_format& format);
77	virtual void					Disconnected();
78
79			void					_ConnectionRegistered(BMediaClient* owner,
80										media_connection_id id);
81
82	const media_source&				_Source() const;
83	const media_destination&		_Destination() const;
84
85	media_connection				fConnection;
86
87	BMediaClient*					fOwner;
88
89	// A connection might be binded so that it will automatically
90	// forward or receive the data from/to a local BMediaConnection,
91	// see BMediaClient::Bind.
92	BMediaConnection*				fBind;
93
94	bool							fConnected;
95
96	virtual	void					_ReservedMediaConnection0();
97	virtual	void					_ReservedMediaConnection1();
98	virtual	void					_ReservedMediaConnection2();
99	virtual	void					_ReservedMediaConnection3();
100	virtual	void					_ReservedMediaConnection4();
101	virtual	void					_ReservedMediaConnection5();
102	virtual	void					_ReservedMediaConnection6();
103	virtual	void					_ReservedMediaConnection7();
104	virtual	void					_ReservedMediaConnection8();
105	virtual	void					_ReservedMediaConnection9();
106	virtual	void					_ReservedMediaConnection10();
107	uint32							fPadding[64];
108
109	friend class BMediaClient;
110	friend class BMediaClientNode;
111
112	friend class BMediaInput;
113	friend class BMediaOutput;
114};
115
116
117class BMediaInput : public virtual BMediaConnection {
118protected:
119									BMediaInput(const char* name = NULL);
120	virtual							~BMediaInput();
121
122	// Callbacks
123	virtual status_t				AcceptFormat(media_format* format) = 0;
124
125	virtual void					HandleBuffer(BBuffer* buffer);
126
127	virtual void					Connected(const media_format& format);
128	virtual void					Disconnected();
129
130private:
131
132	virtual	void					_ReservedMediaInput0();
133	virtual	void					_ReservedMediaInput1();
134	virtual	void					_ReservedMediaInput2();
135	virtual	void					_ReservedMediaInput3();
136	virtual	void					_ReservedMediaInput4();
137	virtual	void					_ReservedMediaInput5();
138	virtual	void					_ReservedMediaInput6();
139	virtual	void					_ReservedMediaInput7();
140	virtual	void					_ReservedMediaInput8();
141	virtual	void					_ReservedMediaInput9();
142	virtual	void					_ReservedMediaInput10();
143	uint32							fPadding[32];
144
145	friend class BMediaClientNode;
146};
147
148
149class BMediaOutput : public virtual BMediaConnection {
150protected:
151									BMediaOutput(const char* name = NULL);
152	virtual							~BMediaOutput();
153
154	// Callbacks
155	virtual status_t				PrepareToConnect(media_format* format) = 0;
156	virtual status_t				FormatProposal(media_format* format) = 0;
157
158	// When a connection is not binded with another, and you really don't want
159	// to use BMediaGraph it's your job to send the buffer to the connection
160	// you want. You might want to ovverride it so that you can track something,
161	// in this case be sure to call the base version. Be sure to know what
162	// you are doing.
163	virtual	status_t				SendBuffer(BBuffer* buffer);
164
165	virtual void					Connected(const media_format& format);
166	virtual void					Disconnected();
167
168private:
169
170	// TODO: possibly unneeded.
171	void							_SetEnabled(bool enabled);
172	bool							_IsEnabled() const;
173
174	bool							fEnabled;
175	size_t							fFramesSent;
176
177	BBufferGroup*					fBufferGroup;
178
179	virtual	void					_ReservedMediaOutput0();
180	virtual	void					_ReservedMediaOutput1();
181	virtual	void					_ReservedMediaOutput2();
182	virtual	void					_ReservedMediaOutput3();
183	virtual	void					_ReservedMediaOutput4();
184	virtual	void					_ReservedMediaOutput5();
185	virtual	void					_ReservedMediaOutput6();
186	virtual	void					_ReservedMediaOutput7();
187	virtual	void					_ReservedMediaOutput8();
188	virtual	void					_ReservedMediaOutput9();
189	virtual	void					_ReservedMediaOutput10();
190	uint32							fPadding[32];
191
192	friend class BMediaClientNode;
193};
194
195
196}
197
198}
199
200using namespace BPrivate::media;
201
202#endif
203