xref: /haiku/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
1 /*
2  * ESounD media addon for BeOS
3  *
4  * Copyright (c) 2006 François Revol (revol@free.fr)
5  *
6  * Based on Multi Audio addon for Haiku,
7  * Copyright (c) 2002, 2003 Jerome Duval (jerome.duval@free.fr)
8  *
9  * All rights reserved.
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  *   this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright notice,
16  *   this list of conditions and the following disclaimer in the documentation
17  *   and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31 #ifndef _ESDSINK_NODE_H
32 #define _ESDSINK_NODE_H
33 
34 #include <MediaDefs.h>
35 #include <MediaNode.h>
36 #include <FileInterface.h>
37 #include <BufferConsumer.h>
38 #include <BufferProducer.h>
39 #include <Controllable.h>
40 #include <MediaEventLooper.h>
41 #include <ParameterWeb.h>
42 #include <TimeSource.h>
43 #include <Controllable.h>
44 #include <File.h>
45 #include <Entry.h>
46 #include "ESDEndpoint.h"
47 
48 //#define ENABLE_INPUT 1
49 //#define ENABLE_TS 1
50 
51 /*bool format_is_acceptible(
52 						const media_format & producer_format,
53 						const media_format & consumer_format);*/
54 
55 
56 enum {
57 	PARAM_ENABLED,
58 	PARAM_HOST,
59 	PARAM_PORT
60 };
61 
62 class ESDSinkNode :
63     public BBufferConsumer,
64 #if ENABLE_INPUT
65     public BBufferProducer,
66 #endif
67 #ifdef ENABLE_TS
68     public BTimeSource,
69 #endif
70     public BMediaEventLooper,
71     public BControllable
72 {
73 protected:
74 virtual ~ESDSinkNode(void);
75 
76 public:
77 
78 explicit ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config);
79 
80 virtual status_t InitCheck(void) const;
81 
82 /*************************/
83 /* begin from BMediaNode */
84 public:
85 virtual	BMediaAddOn* AddOn(
86 				int32 * internal_id) const;	/* Who instantiated you -- or NULL for app class */
87 
88 protected:
89 		/* These don't return errors; instead, they use the global error condition reporter. */
90 		/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
91 		/* and is recommended to allow for at least one pending command of each type. */
92 		/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
93 		/* cannot depend on that happening. */
94 virtual	void Preroll(void);
95 
96 public:
97 virtual	status_t HandleMessage(
98 				int32 message,
99 				const void * data,
100 				size_t size);
101 
102 protected:
103 virtual		void NodeRegistered(void);	/* reserved 2 */
104 virtual		status_t RequestCompleted(const media_request_info &info);
105 virtual		void SetTimeSource(BTimeSource *timeSource);
106 
107 /* end from BMediaNode */
108 /***********************/
109 
110 /******************************/
111 /* begin from BBufferConsumer */
112 
113 //included from BMediaAddOn
114 //virtual	status_t HandleMessage(
115 //				int32 message,
116 //				const void * data,
117 //				size_t size);
118 
119 	/* Someone, probably the producer, is asking you about this format. Give */
120 	/* your honest opinion, possibly modifying *format. Do not ask upstream */
121 	/* producer about the format, since he's synchronously waiting for your */
122 	/* reply. */
123 virtual	status_t AcceptFormat(
124 				const media_destination & dest,
125 				media_format * format);
126 virtual	status_t GetNextInput(
127 				int32 * cookie,
128 				media_input * out_input);
129 virtual	void DisposeInputCookie(
130 				int32 cookie);
131 virtual	void BufferReceived(
132 				BBuffer * buffer);
133 virtual	void ProducerDataStatus(
134 				const media_destination & for_whom,
135 				int32 status,
136 				bigtime_t at_performance_time);
137 virtual	status_t GetLatencyFor(
138 				const media_destination & for_whom,
139 				bigtime_t * out_latency,
140 				media_node_id * out_timesource);
141 virtual	status_t Connected(
142 				const media_source & producer,	/* here's a good place to request buffer group usage */
143 				const media_destination & where,
144 				const media_format & with_format,
145 				media_input * out_input);
146 virtual	void Disconnected(
147 				const media_source & producer,
148 				const media_destination & where);
149 	/* The notification comes from the upstream producer, so he's already cool with */
150 	/* the format; you should not ask him about it in here. */
151 virtual	status_t FormatChanged(
152 				const media_source & producer,
153 				const media_destination & consumer,
154 				int32 change_tag,
155 				const media_format & format);
156 
157 	/* Given a performance time of some previous buffer, retrieve the remembered tag */
158 	/* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
159 	/* idea being that flags can be added later, and the understood flags returned in */
160 	/* *out_flags. */
161 virtual	status_t SeekTagRequested(
162 				const media_destination & destination,
163 				bigtime_t in_target_time,
164 				uint32 in_flags,
165 				media_seek_tag * out_seek_tag,
166 				bigtime_t * out_tagged_time,
167 				uint32 * out_flags);
168 
169 /* end from BBufferConsumer */
170 /****************************/
171 
172 /******************************/
173 /* begin from BBufferProducer */
174 #if 0
175 		virtual status_t 	FormatSuggestionRequested(	media_type type,
176 														int32 quality,
177 														media_format* format);
178 
179 		virtual status_t 	FormatProposal(				const media_source& output,
180 														media_format* format);
181 
182 		virtual status_t 	FormatChangeRequested(		const media_source& source,
183 														const media_destination& destination,
184 														media_format* io_format,
185 														int32* _deprecated_);
186 		virtual status_t 	GetNextOutput(				int32* cookie,
187 														media_output* out_output);
188 		virtual status_t 	DisposeOutputCookie(		int32 cookie);
189 
190 		virtual	status_t 	SetBufferGroup(				const media_source& for_source,
191 														BBufferGroup* group);
192 
193 		virtual status_t 	PrepareToConnect(			const media_source& what,
194 														const media_destination& where,
195 														media_format* format,
196 														media_source* out_source,
197 														char* out_name);
198 
199 		virtual void 		Connect(					status_t error,
200 														const media_source& source,
201 														const media_destination& destination,
202 														const media_format& format,
203 														char* io_name);
204 
205 		virtual void 		Disconnect(					const media_source& what,
206 														const media_destination& where);
207 
208 		virtual void 		LateNoticeReceived(			const media_source& what,
209 														bigtime_t how_much,
210 														bigtime_t performance_time);
211 
212 		virtual void 		EnableOutput(				const media_source & what,
213 														bool enabled,
214 														int32* _deprecated_);
215 		virtual void 		AdditionalBufferRequested(	const media_source& source,
216 														media_buffer_id prev_buffer,
217 														bigtime_t prev_time,
218 														const media_seek_tag* prev_tag);
219 #endif
220 /* end from BBufferProducer */
221 /****************************/
222 
223 /*****************/
224 /* BControllable */
225 /*****************/
226 
227 /********************************/
228 /* start from BMediaEventLooper */
229 
230 	protected:
231 		/* you must override to handle your events! */
232 		/* you should not call HandleEvent directly */
233 		virtual void		HandleEvent(	const media_timed_event *event,
234 											bigtime_t lateness,
235 											bool realTimeEvent = false);
236 
237 /* end from BMediaEventLooper */
238 /******************************/
239 
240 /********************************/
241 /* start from BTimeSource */
242 #ifdef ENABLE_TS
243 	protected:
244 		virtual void		SetRunMode(		run_mode mode);
245 		virtual status_t 	TimeSourceOp(	const time_source_op_info &op,
246 											void *_reserved);
247 #endif
248 /* end from BTimeSource */
249 /******************************/
250 
251 /********************************/
252 /* start from BControllable */
253 	protected:
254 		virtual status_t 	GetParameterValue(	int32 id,
255 												bigtime_t* last_change,
256 												void* value,
257 												size_t* ioSize);
258 		virtual void 		SetParameterValue(	int32 id,
259 												bigtime_t when,
260 												const void* value,
261 												size_t size);
262 		virtual BParameterWeb* MakeParameterWeb();
263 
264 /* end from BControllable */
265 /******************************/
266 
267 protected:
268 
269 virtual status_t HandleStart(
270 						const media_timed_event *event,
271 						bigtime_t lateness,
272 						bool realTimeEvent = false);
273 virtual status_t HandleSeek(
274 						const media_timed_event *event,
275 						bigtime_t lateness,
276 						bool realTimeEvent = false);
277 virtual status_t HandleWarp(
278 						const media_timed_event *event,
279 						bigtime_t lateness,
280 						bool realTimeEvent = false);
281 virtual status_t HandleStop(
282 						const media_timed_event *event,
283 						bigtime_t lateness,
284 						bool realTimeEvent = false);
285 virtual status_t HandleBuffer(
286 						const media_timed_event *event,
287 						bigtime_t lateness,
288 						bool realTimeEvent = false);
289 virtual status_t HandleDataStatus(
290 						const media_timed_event *event,
291 						bigtime_t lateness,
292 						bool realTimeEvent = false);
293 virtual status_t HandleParameter(
294 						const media_timed_event *event,
295 						bigtime_t lateness,
296 						bool realTimeEvent = false);
297 
298 public:
299 
300 static void GetFlavor(flavor_info * outInfo, int32 id);
301 static void GetFormat(media_format * outFormat);
302 
303 status_t GetConfigurationFor(BMessage * into_message);
304 
305 
306 private:
307 
308 		ESDSinkNode(	/* private unimplemented */
309 				const ESDSinkNode & clone);
310 		ESDSinkNode & operator=(
311 				const ESDSinkNode & clone);
312 
313 #if 0
314 
315 		void 				AllocateBuffers(node_output &channel);
316 		BBuffer* 			FillNextBuffer(	multi_buffer_info &MBI,
317 										node_output &channel);
318 		void				UpdateTimeSource(multi_buffer_info &MBI,
319 										multi_buffer_info &oldMBI,
320 										node_input &input);
321 #endif
322 //		node_output* 		FindOutput(media_source source);
323 //		node_input* 		FindInput(media_destination dest);
324 //		node_input* 		FindInput(int32 destinationId);
325 
326 //		void 				ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters);
327 //		void 				ProcessMux(BDiscreteParameter *parameter, int32 index);
328 
329 		status_t fInitCheckStatus;
330 
331 		BMediaAddOn 		*fAddOn;
332 		int32				fId;
333 
334 		BList				fInputs;
335 		media_input			fInput;
336 
337 		bigtime_t 			fLatency;
338 		BList				fOutputs;
339 		media_output		fOutput;
340 		media_format 		fPreferredFormat;
341 
342 		bigtime_t fInternalLatency;
343 		// this is computed from the real (negotiated) chunk size and bit rate,
344 		// not the defaults that are in the parameters
345 		bigtime_t fBufferPeriod;
346 
347 
348 		//volatile uint32 	fBufferCycle;
349 		sem_id				fBuffer_free;
350 
351 
352 		thread_id			fThread;
353 
354 		BString				fHostname;
355 		uint16				fPort;
356 		bool				fEnabled;
357 		ESDEndpoint		 	*fDevice;
358 
359 		//multi_description	MD;
360 		//multi_format_info 	MFI;
361 		//multi_buffer_list 	MBL;
362 
363 		//multi_mix_control_info MMCI;
364 		//multi_mix_control	MMC[MAX_CONTROLS];
365 
366 		bool 				fTimeSourceStarted;
367 
368 		BParameterWeb		*fWeb;
369 
370 		BMessage			fConfig;
371 };
372 
373 #endif /* _ESDSINK_NODE_H */
374