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
56enum {
57	PARAM_ENABLED,
58	PARAM_HOST,
59	PARAM_PORT
60};
61
62class 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{
73protected:
74virtual ~ESDSinkNode(void);
75
76public:
77
78explicit ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config);
79
80virtual status_t InitCheck(void) const;
81
82/*************************/
83/* begin from BMediaNode */
84public:
85virtual	BMediaAddOn* AddOn(
86				int32 * internal_id) const;	/* Who instantiated you -- or NULL for app class */
87
88protected:
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. */
94virtual	void Preroll(void);
95
96public:
97virtual	status_t HandleMessage(
98				int32 message,
99				const void * data,
100				size_t size);
101
102protected:
103virtual		void NodeRegistered(void);	/* reserved 2 */
104virtual		status_t RequestCompleted(const media_request_info &info);
105virtual		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. */
123virtual	status_t AcceptFormat(
124				const media_destination & dest,
125				media_format * format);
126virtual	status_t GetNextInput(
127				int32 * cookie,
128				media_input * out_input);
129virtual	void DisposeInputCookie(
130				int32 cookie);
131virtual	void BufferReceived(
132				BBuffer * buffer);
133virtual	void ProducerDataStatus(
134				const media_destination & for_whom,
135				int32 status,
136				bigtime_t at_performance_time);
137virtual	status_t GetLatencyFor(
138				const media_destination & for_whom,
139				bigtime_t * out_latency,
140				media_node_id * out_timesource);
141virtual	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);
146virtual	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. */
151virtual	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. */
161virtual	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
267protected:
268
269virtual status_t HandleStart(
270						const media_timed_event *event,
271						bigtime_t lateness,
272						bool realTimeEvent = false);
273virtual status_t HandleSeek(
274						const media_timed_event *event,
275						bigtime_t lateness,
276						bool realTimeEvent = false);
277virtual status_t HandleWarp(
278						const media_timed_event *event,
279						bigtime_t lateness,
280						bool realTimeEvent = false);
281virtual status_t HandleStop(
282						const media_timed_event *event,
283						bigtime_t lateness,
284						bool realTimeEvent = false);
285virtual status_t HandleBuffer(
286						const media_timed_event *event,
287						bigtime_t lateness,
288						bool realTimeEvent = false);
289virtual status_t HandleDataStatus(
290						const media_timed_event *event,
291						bigtime_t lateness,
292						bool realTimeEvent = false);
293virtual status_t HandleParameter(
294						const media_timed_event *event,
295						bigtime_t lateness,
296						bool realTimeEvent = false);
297
298public:
299
300static void GetFlavor(flavor_info * outInfo, int32 id);
301static void GetFormat(media_format * outFormat);
302
303status_t GetConfigurationFor(BMessage * into_message);
304
305
306private:
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