xref: /haiku/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
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 class ESDSinkNode :
56     public BBufferConsumer,
57 #if ENABLE_INPUT
58     public BBufferProducer,
59 #endif
60 #ifdef ENABLE_TS
61     public BTimeSource,
62 #endif
63     public BMediaEventLooper,
64     public BControllable
65 {
66 protected:
67 virtual ~ESDSinkNode(void);
68 
69 public:
70 
71 explicit ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config);
72 
73 virtual status_t InitCheck(void) const;
74 
75 /*************************/
76 /* begin from BMediaNode */
77 public:
78 virtual	BMediaAddOn* AddOn(
79 				int32 * internal_id) const;	/* Who instantiated you -- or NULL for app class */
80 
81 protected:
82 		/* These don't return errors; instead, they use the global error condition reporter. */
83 		/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
84 		/* and is recommended to allow for at least one pending command of each type. */
85 		/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
86 		/* cannot depend on that happening. */
87 virtual	void Preroll(void);
88 
89 public:
90 virtual	status_t HandleMessage(
91 				int32 message,
92 				const void * data,
93 				size_t size);
94 
95 protected:
96 virtual		void NodeRegistered(void);	/* reserved 2 */
97 virtual		status_t RequestCompleted(const media_request_info &info);
98 virtual		void SetTimeSource(BTimeSource *timeSource);
99 
100 /* end from BMediaNode */
101 /***********************/
102 
103 /******************************/
104 /* begin from BBufferConsumer */
105 
106 //included from BMediaAddOn
107 //virtual	status_t HandleMessage(
108 //				int32 message,
109 //				const void * data,
110 //				size_t size);
111 
112 	/* Someone, probably the producer, is asking you about this format. Give */
113 	/* your honest opinion, possibly modifying *format. Do not ask upstream */
114 	/* producer about the format, since he's synchronously waiting for your */
115 	/* reply. */
116 virtual	status_t AcceptFormat(
117 				const media_destination & dest,
118 				media_format * format);
119 virtual	status_t GetNextInput(
120 				int32 * cookie,
121 				media_input * out_input);
122 virtual	void DisposeInputCookie(
123 				int32 cookie);
124 virtual	void BufferReceived(
125 				BBuffer * buffer);
126 virtual	void ProducerDataStatus(
127 				const media_destination & for_whom,
128 				int32 status,
129 				bigtime_t at_performance_time);
130 virtual	status_t GetLatencyFor(
131 				const media_destination & for_whom,
132 				bigtime_t * out_latency,
133 				media_node_id * out_timesource);
134 virtual	status_t Connected(
135 				const media_source & producer,	/* here's a good place to request buffer group usage */
136 				const media_destination & where,
137 				const media_format & with_format,
138 				media_input * out_input);
139 virtual	void Disconnected(
140 				const media_source & producer,
141 				const media_destination & where);
142 	/* The notification comes from the upstream producer, so he's already cool with */
143 	/* the format; you should not ask him about it in here. */
144 virtual	status_t FormatChanged(
145 				const media_source & producer,
146 				const media_destination & consumer,
147 				int32 change_tag,
148 				const media_format & format);
149 
150 	/* Given a performance time of some previous buffer, retrieve the remembered tag */
151 	/* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
152 	/* idea being that flags can be added later, and the understood flags returned in */
153 	/* *out_flags. */
154 virtual	status_t SeekTagRequested(
155 				const media_destination & destination,
156 				bigtime_t in_target_time,
157 				uint32 in_flags,
158 				media_seek_tag * out_seek_tag,
159 				bigtime_t * out_tagged_time,
160 				uint32 * out_flags);
161 
162 /* end from BBufferConsumer */
163 /****************************/
164 
165 /******************************/
166 /* begin from BBufferProducer */
167 #if 0
168 		virtual status_t 	FormatSuggestionRequested(	media_type type,
169 														int32 quality,
170 														media_format* format);
171 
172 		virtual status_t 	FormatProposal(				const media_source& output,
173 														media_format* format);
174 
175 		virtual status_t 	FormatChangeRequested(		const media_source& source,
176 														const media_destination& destination,
177 														media_format* io_format,
178 														int32* _deprecated_);
179 		virtual status_t 	GetNextOutput(				int32* cookie,
180 														media_output* out_output);
181 		virtual status_t 	DisposeOutputCookie(		int32 cookie);
182 
183 		virtual	status_t 	SetBufferGroup(				const media_source& for_source,
184 														BBufferGroup* group);
185 
186 		virtual status_t 	PrepareToConnect(			const media_source& what,
187 														const media_destination& where,
188 														media_format* format,
189 														media_source* out_source,
190 														char* out_name);
191 
192 		virtual void 		Connect(					status_t error,
193 														const media_source& source,
194 														const media_destination& destination,
195 														const media_format& format,
196 														char* io_name);
197 
198 		virtual void 		Disconnect(					const media_source& what,
199 														const media_destination& where);
200 
201 		virtual void 		LateNoticeReceived(			const media_source& what,
202 														bigtime_t how_much,
203 														bigtime_t performance_time);
204 
205 		virtual void 		EnableOutput(				const media_source & what,
206 														bool enabled,
207 														int32* _deprecated_);
208 		virtual void 		AdditionalBufferRequested(	const media_source& source,
209 														media_buffer_id prev_buffer,
210 														bigtime_t prev_time,
211 														const media_seek_tag* prev_tag);
212 #endif
213 /* end from BBufferProducer */
214 /****************************/
215 
216 /*****************/
217 /* BControllable */
218 /*****************/
219 
220 /********************************/
221 /* start from BMediaEventLooper */
222 
223 	protected:
224 		/* you must override to handle your events! */
225 		/* you should not call HandleEvent directly */
226 		virtual void		HandleEvent(	const media_timed_event *event,
227 											bigtime_t lateness,
228 											bool realTimeEvent = false);
229 
230 /* end from BMediaEventLooper */
231 /******************************/
232 
233 /********************************/
234 /* start from BTimeSource */
235 #ifdef ENABLE_TS
236 	protected:
237 		virtual void		SetRunMode(		run_mode mode);
238 		virtual status_t 	TimeSourceOp(	const time_source_op_info &op,
239 											void *_reserved);
240 #endif
241 /* end from BTimeSource */
242 /******************************/
243 
244 /********************************/
245 /* start from BControllable */
246 	protected:
247 		virtual status_t 	GetParameterValue(	int32 id,
248 												bigtime_t* last_change,
249 												void* value,
250 												size_t* ioSize);
251 		virtual void 		SetParameterValue(	int32 id,
252 												bigtime_t when,
253 												const void* value,
254 												size_t size);
255 		virtual BParameterWeb* MakeParameterWeb();
256 
257 /* end from BControllable */
258 /******************************/
259 
260 protected:
261 
262 virtual status_t HandleStart(
263 						const media_timed_event *event,
264 						bigtime_t lateness,
265 						bool realTimeEvent = false);
266 virtual status_t HandleSeek(
267 						const media_timed_event *event,
268 						bigtime_t lateness,
269 						bool realTimeEvent = false);
270 virtual status_t HandleWarp(
271 						const media_timed_event *event,
272 						bigtime_t lateness,
273 						bool realTimeEvent = false);
274 virtual status_t HandleStop(
275 						const media_timed_event *event,
276 						bigtime_t lateness,
277 						bool realTimeEvent = false);
278 virtual status_t HandleBuffer(
279 						const media_timed_event *event,
280 						bigtime_t lateness,
281 						bool realTimeEvent = false);
282 virtual status_t HandleDataStatus(
283 						const media_timed_event *event,
284 						bigtime_t lateness,
285 						bool realTimeEvent = false);
286 virtual status_t HandleParameter(
287 						const media_timed_event *event,
288 						bigtime_t lateness,
289 						bool realTimeEvent = false);
290 
291 public:
292 
293 static void GetFlavor(flavor_info * outInfo, int32 id);
294 static void GetFormat(media_format * outFormat);
295 
296 status_t GetConfigurationFor(BMessage * into_message);
297 
298 
299 private:
300 
301 		ESDSinkNode(	/* private unimplemented */
302 				const ESDSinkNode & clone);
303 		ESDSinkNode & operator=(
304 				const ESDSinkNode & clone);
305 
306 #if 0
307 
308 		void 				AllocateBuffers(node_output &channel);
309 		BBuffer* 			FillNextBuffer(	multi_buffer_info &MBI,
310 										node_output &channel);
311 		void				UpdateTimeSource(multi_buffer_info &MBI,
312 										multi_buffer_info &oldMBI,
313 										node_input &input);
314 #endif
315 //		node_output* 		FindOutput(media_source source);
316 //		node_input* 		FindInput(media_destination dest);
317 //		node_input* 		FindInput(int32 destinationId);
318 
319 //		void 				ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters);
320 //		void 				ProcessMux(BDiscreteParameter *parameter, int32 index);
321 
322 		status_t fInitCheckStatus;
323 
324 		BMediaAddOn 		*fAddOn;
325 		int32				fId;
326 
327 		BList				fInputs;
328 		media_input			fInput;
329 
330 		bigtime_t 			fLatency;
331 		BList				fOutputs;
332 		media_output		fOutput;
333 		media_format 		fPreferredFormat;
334 
335 		bigtime_t fInternalLatency;
336 		// this is computed from the real (negotiated) chunk size and bit rate,
337 		// not the defaults that are in the parameters
338 		bigtime_t fBufferPeriod;
339 
340 
341 		//volatile uint32 	fBufferCycle;
342 		sem_id				fBuffer_free;
343 
344 
345 		thread_id			fThread;
346 
347 		BString				fHostname;
348 		ESDEndpoint		 	*fDevice;
349 
350 		//multi_description	MD;
351 		//multi_format_info 	MFI;
352 		//multi_buffer_list 	MBL;
353 
354 		//multi_mix_control_info MMCI;
355 		//multi_mix_control	MMC[MAX_CONTROLS];
356 
357 		bool 				fTimeSourceStarted;
358 
359 		BParameterWeb		*fWeb;
360 		int32				fWebHostId;
361 		int32				fWebPortId;
362 
363 		BMessage			fConfig;
364 };
365 
366 #endif /* _ESDSINK_NODE_H */
367