1d5525d8cSshatty// MediaDemultiplexerNode.h
2d5525d8cSshatty//
3d5525d8cSshatty// Andrew Bachmann, 2002
4d5525d8cSshatty//
5d5525d8cSshatty// The MediaDemultiplexerNode class
6d5525d8cSshatty// takes a multistream input and supplies
7d5525d8cSshatty// the individual constituent streams as
8d5525d8cSshatty// the output.
9d5525d8cSshatty
10d5525d8cSshatty#if !defined(_MEDIA_DEMULTIPLEXER_NODE_H)
11d5525d8cSshatty#define _MEDIA_DEMULTIPLEXER_NODE_H
12d5525d8cSshatty
13d5525d8cSshatty#include <MediaDefs.h>
14d5525d8cSshatty#include <MediaNode.h>
15d5525d8cSshatty#include <BufferConsumer.h>
16d5525d8cSshatty#include <BufferProducer.h>
17d5525d8cSshatty#include <MediaEventLooper.h>
18d5525d8cSshatty#include <BufferGroup.h>
19d5525d8cSshatty#include <vector>
20d5525d8cSshatty#include "MediaOutputInfo.h"
21d5525d8cSshatty
22d5525d8cSshattyclass MediaDemultiplexerNode :
23d5525d8cSshatty	public BBufferConsumer,
24d5525d8cSshatty	public BBufferProducer,
25d5525d8cSshatty    public BMediaEventLooper
26d5525d8cSshatty{
27d5525d8cSshattyprotected:
28d5525d8cSshattyvirtual ~MediaDemultiplexerNode(void);
29d5525d8cSshatty
30d5525d8cSshattypublic:
31d5525d8cSshatty
32d5525d8cSshattyexplicit MediaDemultiplexerNode(
33d5525d8cSshatty				const flavor_info * info = 0,
34d5525d8cSshatty				BMessage * config = 0,
35d5525d8cSshatty				BMediaAddOn * addOn = 0);
36d5525d8cSshatty
37d5525d8cSshattyvirtual status_t InitCheck(void) const;
38d5525d8cSshatty
39d5525d8cSshatty// see BMediaAddOn::GetConfigurationFor
40d5525d8cSshattyvirtual	status_t GetConfigurationFor(
41d5525d8cSshatty				BMessage * into_message);
42d5525d8cSshatty
43d5525d8cSshatty/*************************/
44d5525d8cSshatty/* begin from BMediaNode */
45d5525d8cSshattypublic:
46d5525d8cSshatty//	/* this port is what a media node listens to for commands */
47d5525d8cSshatty// virtual port_id ControlPort(void) const;
48d5525d8cSshatty
49d5525d8cSshattyvirtual	BMediaAddOn* AddOn(
50d5525d8cSshatty				int32 * internal_id) const;	/* Who instantiated you -- or NULL for app class */
51d5525d8cSshatty
52d5525d8cSshattyprotected:
53d5525d8cSshatty		/* These don't return errors; instead, they use the global error condition reporter. */
54d5525d8cSshatty		/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
55d5525d8cSshatty		/* and is recommended to allow for at least one pending command of each type. */
56d5525d8cSshatty		/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
57d5525d8cSshatty		/* cannot depend on that happening. */
58d5525d8cSshattyvirtual	void Start(
59d5525d8cSshatty				bigtime_t performance_time);
60d5525d8cSshattyvirtual	void Stop(
61d5525d8cSshatty				bigtime_t performance_time,
62d5525d8cSshatty				bool immediate);
63d5525d8cSshattyvirtual	void Seek(
64d5525d8cSshatty				bigtime_t media_time,
65d5525d8cSshatty				bigtime_t performance_time);
66d5525d8cSshattyvirtual	void SetRunMode(
67d5525d8cSshatty				run_mode mode);
68d5525d8cSshattyvirtual	void TimeWarp(
69d5525d8cSshatty				bigtime_t at_real_time,
70d5525d8cSshatty				bigtime_t to_performance_time);
71d5525d8cSshattyvirtual	void Preroll(void);
72d5525d8cSshattyvirtual	void SetTimeSource(
73d5525d8cSshatty				BTimeSource * time_source);
74d5525d8cSshatty
75d5525d8cSshattypublic:
76d5525d8cSshattyvirtual	status_t HandleMessage(
77d5525d8cSshatty				int32 message,
78d5525d8cSshatty				const void * data,
79d5525d8cSshatty				size_t size);
80d5525d8cSshatty
81d5525d8cSshattyprotected:
82d5525d8cSshatty		/* Called when requests have completed, or failed. */
83d5525d8cSshattyvirtual	status_t RequestCompleted(	/* reserved 0 */
84d5525d8cSshatty				const media_request_info & info);
85d5525d8cSshatty
86d5525d8cSshattyprotected:
87d5525d8cSshattyvirtual		status_t DeleteHook(BMediaNode * node);		/* reserved 1 */
88d5525d8cSshatty
89d5525d8cSshattyvirtual		void NodeRegistered(void);	/* reserved 2 */
90d5525d8cSshatty
91d5525d8cSshattypublic:
92d5525d8cSshatty
93d5525d8cSshatty		/* fill out your attributes in the provided array, returning however many you have. */
94d5525d8cSshattyvirtual		status_t GetNodeAttributes(	/* reserved 3 */
95d5525d8cSshatty					media_node_attribute * outAttributes,
96d5525d8cSshatty					size_t inMaxCount);
97d5525d8cSshatty
98d5525d8cSshattyvirtual		status_t AddTimer(
99d5525d8cSshatty					bigtime_t at_performance_time,
100d5525d8cSshatty					int32 cookie);
101d5525d8cSshatty
102d5525d8cSshatty/* end from BMediaNode */
103d5525d8cSshatty/***********************/
104d5525d8cSshatty
105d5525d8cSshatty/******************************/
106d5525d8cSshatty/* begin from BBufferConsumer */
107d5525d8cSshatty
108d5525d8cSshatty//included from BMediaAddOn
109d5525d8cSshatty//virtual	status_t HandleMessage(
110d5525d8cSshatty//				int32 message,
111d5525d8cSshatty//				const void * data,
112d5525d8cSshatty//				size_t size);
113d5525d8cSshatty
114d5525d8cSshatty	/* Someone, probably the producer, is asking you about this format. Give */
115d5525d8cSshatty	/* your honest opinion, possibly modifying *format. Do not ask upstream */
116d5525d8cSshatty	/* producer about the format, since he's synchronously waiting for your */
117d5525d8cSshatty	/* reply. */
118d5525d8cSshattyvirtual	status_t AcceptFormat(
119d5525d8cSshatty				const media_destination & dest,
120d5525d8cSshatty				media_format * format);
121d5525d8cSshattyvirtual	status_t GetNextInput(
122d5525d8cSshatty				int32 * cookie,
123d5525d8cSshatty				media_input * out_input);
124d5525d8cSshattyvirtual	void DisposeInputCookie(
125d5525d8cSshatty				int32 cookie);
126d5525d8cSshattyvirtual	void BufferReceived(
127d5525d8cSshatty				BBuffer * buffer);
128d5525d8cSshattyvirtual	void ProducerDataStatus(
129d5525d8cSshatty				const media_destination & for_whom,
130d5525d8cSshatty				int32 status,
131d5525d8cSshatty				bigtime_t at_performance_time);
132d5525d8cSshattyvirtual	status_t GetLatencyFor(
133d5525d8cSshatty				const media_destination & for_whom,
134d5525d8cSshatty				bigtime_t * out_latency,
135d5525d8cSshatty				media_node_id * out_timesource);
136d5525d8cSshattyvirtual	status_t Connected(
137d5525d8cSshatty				const media_source & producer,	/* here's a good place to request buffer group usage */
138d5525d8cSshatty				const media_destination & where,
139d5525d8cSshatty				const media_format & with_format,
140d5525d8cSshatty				media_input * out_input);
141d5525d8cSshattyvirtual	void Disconnected(
142d5525d8cSshatty				const media_source & producer,
143d5525d8cSshatty				const media_destination & where);
144d5525d8cSshatty	/* The notification comes from the upstream producer, so he's already cool with */
145d5525d8cSshatty	/* the format; you should not ask him about it in here. */
146d5525d8cSshattyvirtual	status_t FormatChanged(
147d5525d8cSshatty				const media_source & producer,
148d5525d8cSshatty				const media_destination & consumer,
149d5525d8cSshatty				int32 change_tag,
150d5525d8cSshatty				const media_format & format);
151d5525d8cSshatty
152d5525d8cSshatty	/* Given a performance time of some previous buffer, retrieve the remembered tag */
153d5525d8cSshatty	/* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
154d5525d8cSshatty	/* idea being that flags can be added later, and the understood flags returned in */
155d5525d8cSshatty	/* *out_flags. */
156d5525d8cSshattyvirtual	status_t SeekTagRequested(
157d5525d8cSshatty				const media_destination & destination,
158d5525d8cSshatty				bigtime_t in_target_time,
159d5525d8cSshatty				uint32 in_flags,
160d5525d8cSshatty				media_seek_tag * out_seek_tag,
161d5525d8cSshatty				bigtime_t * out_tagged_time,
162d5525d8cSshatty				uint32 * out_flags);
163d5525d8cSshatty
164d5525d8cSshatty/* end from BBufferConsumer */
165d5525d8cSshatty/****************************/
166d5525d8cSshatty
167d5525d8cSshatty/******************************/
168d5525d8cSshatty/* begin from BBufferProducer */
169d5525d8cSshattyprotected:
170d5525d8cSshatty	/* functionality of BBufferProducer */
171d5525d8cSshattyvirtual	status_t FormatSuggestionRequested(
172d5525d8cSshatty				media_type type,
173d5525d8cSshatty				int32 quality,
174d5525d8cSshatty				media_format * format);
175d5525d8cSshattyvirtual	status_t FormatProposal(
176d5525d8cSshatty				const media_source & output,
177d5525d8cSshatty				media_format * format);
178d5525d8cSshatty	/* If the format isn't good, put a good format into *io_format and return error */
179d5525d8cSshatty	/* If format has wildcard, specialize to what you can do (and change). */
180d5525d8cSshatty	/* If you can change the format, return OK. */
181d5525d8cSshatty	/* The request comes from your destination sychronously, so you cannot ask it */
182d5525d8cSshatty	/* whether it likes it -- you should assume it will since it asked. */
183d5525d8cSshattyvirtual	status_t FormatChangeRequested(
184d5525d8cSshatty				const media_source & source,
185d5525d8cSshatty				const media_destination & destination,
186d5525d8cSshatty				media_format * io_format,
187d5525d8cSshatty				int32 * _deprecated_);
188d5525d8cSshattyvirtual	status_t GetNextOutput(	/* cookie starts as 0 */
189d5525d8cSshatty				int32 * cookie,
190d5525d8cSshatty				media_output * out_output);
191d5525d8cSshattyvirtual	status_t DisposeOutputCookie(
192d5525d8cSshatty				int32 cookie);
193d5525d8cSshatty	/* In this function, you should either pass on the group to your upstream guy, */
194d5525d8cSshatty	/* or delete your current group and hang on to this group. Deleting the previous */
195d5525d8cSshatty	/* group (unless you passed it on with the reclaim flag set to false) is very */
196d5525d8cSshatty	/* important, else you will 1) leak memory and 2) block someone who may want */
197d5525d8cSshatty	/* to reclaim the buffers living in that group. */
198d5525d8cSshattyvirtual	status_t SetBufferGroup(
199d5525d8cSshatty				const media_source & for_source,
200d5525d8cSshatty				BBufferGroup * group);
201d5525d8cSshatty	/* Format of clipping is (as int16-s): <from line> <npairs> <startclip> <endclip>. */
202d5525d8cSshatty	/* Repeat for each line where the clipping is different from the previous line. */
203d5525d8cSshatty	/* If <npairs> is negative, use the data from line -<npairs> (there are 0 pairs after */
204d5525d8cSshatty	/* a negative <npairs>. Yes, we only support 32k*32k frame buffers for clipping. */
205d5525d8cSshatty	/* Any non-0 field of 'display' means that that field changed, and if you don't support */
206d5525d8cSshatty	/* that change, you should return an error and ignore the request. Note that the buffer */
207d5525d8cSshatty	/* offset values do not have wildcards; 0 (or -1, or whatever) are real values and must */
208d5525d8cSshatty	/* be adhered to. */
209d5525d8cSshattyvirtual	status_t VideoClippingChanged(
210d5525d8cSshatty				const media_source & for_source,
211d5525d8cSshatty				int16 num_shorts,
212d5525d8cSshatty				int16 * clip_data,
213d5525d8cSshatty				const media_video_display_info & display,
214d5525d8cSshatty				int32 * _deprecated_);
215d5525d8cSshatty	/* Iterates over all outputs and maxes the latency found */
216d5525d8cSshattyvirtual	status_t GetLatency(
217d5525d8cSshatty				bigtime_t * out_latency);
218d5525d8cSshattyvirtual	status_t PrepareToConnect(
219d5525d8cSshatty				const media_source & what,
220d5525d8cSshatty				const media_destination & where,
221d5525d8cSshatty				media_format * format,
222d5525d8cSshatty				media_source * out_source,
223d5525d8cSshatty				char * out_name);
224d5525d8cSshattyvirtual	void Connect(
225d5525d8cSshatty				status_t error,
226d5525d8cSshatty				const media_source & source,
227d5525d8cSshatty				const media_destination & destination,
228d5525d8cSshatty				const media_format & format,
229d5525d8cSshatty				char * io_name);
230d5525d8cSshattyvirtual	void Disconnect(
231d5525d8cSshatty				const media_source & what,
232d5525d8cSshatty				const media_destination & where);
233d5525d8cSshattyvirtual	void LateNoticeReceived(
234d5525d8cSshatty				const media_source & what,
235d5525d8cSshatty				bigtime_t how_much,
236d5525d8cSshatty				bigtime_t performance_time);
237d5525d8cSshattyvirtual	void EnableOutput(
238d5525d8cSshatty				const media_source & what,
239d5525d8cSshatty				bool enabled,
240d5525d8cSshatty				int32 * _deprecated_);
241d5525d8cSshattyvirtual	status_t SetPlayRate(
242d5525d8cSshatty				int32 numer,
243d5525d8cSshatty				int32 denom);
244d5525d8cSshatty
245d5525d8cSshatty//included from BMediaNode
246d5525d8cSshatty//virtual	status_t HandleMessage(	/* call this from the thread that listens to the port */
247d5525d8cSshatty//				int32 message,
248d5525d8cSshatty//				const void * data,
249d5525d8cSshatty//				size_t size);
250d5525d8cSshatty
251d5525d8cSshattyvirtual	void AdditionalBufferRequested(			//	used to be Reserved 0
252d5525d8cSshatty				const media_source & source,
253d5525d8cSshatty				media_buffer_id prev_buffer,
254d5525d8cSshatty				bigtime_t prev_time,
255d5525d8cSshatty				const media_seek_tag * prev_tag);	//	may be NULL
256d5525d8cSshatty
257d5525d8cSshattyvirtual	void LatencyChanged(					//	used to be Reserved 1
258d5525d8cSshatty				const media_source & source,
259d5525d8cSshatty				const media_destination & destination,
260d5525d8cSshatty				bigtime_t new_latency,
261d5525d8cSshatty				uint32 flags);
262d5525d8cSshatty
263d5525d8cSshatty/* end from BBufferProducer */
264d5525d8cSshatty/****************************/
265d5525d8cSshatty
266d5525d8cSshatty/********************************/
267d5525d8cSshatty/* start from BMediaEventLooper */
268d5525d8cSshatty
269d5525d8cSshatty	protected:
270d5525d8cSshatty		/* you must override to handle your events! */
271d5525d8cSshatty		/* you should not call HandleEvent directly */
272d5525d8cSshatty		virtual void		HandleEvent(	const media_timed_event *event,
273d5525d8cSshatty											bigtime_t lateness,
274d5525d8cSshatty											bool realTimeEvent = false);
275d5525d8cSshatty
276d5525d8cSshatty		/* override to clean up custom events you have added to your queue */
277d5525d8cSshatty		virtual void		CleanUpEvent(const media_timed_event *event);
278d5525d8cSshatty
279d5525d8cSshatty		/* called from Offline mode to determine the current time of the node */
280d5525d8cSshatty		/* update your internal information whenever it changes */
281d5525d8cSshatty		virtual	bigtime_t	OfflineTime();
282d5525d8cSshatty
283d5525d8cSshatty		/* override only if you know what you are doing! */
284d5525d8cSshatty		/* otherwise much badness could occur */
285d5525d8cSshatty		/* the actual control loop function: */
286d5525d8cSshatty		/* 	waits for messages, Pops events off the queue and calls DispatchEvent */
287d5525d8cSshatty		virtual void		ControlLoop();
288d5525d8cSshatty
289d5525d8cSshatty/* end from BMediaEventLooper */
290d5525d8cSshatty/******************************/
291d5525d8cSshatty
292d5525d8cSshattyprotected:
293d5525d8cSshatty
294d5525d8cSshattyvirtual status_t HandleStart(
295d5525d8cSshatty						const media_timed_event *event,
296d5525d8cSshatty						bigtime_t lateness,
297d5525d8cSshatty						bool realTimeEvent = false);
298d5525d8cSshattyvirtual status_t HandleSeek(
299d5525d8cSshatty						const media_timed_event *event,
300d5525d8cSshatty						bigtime_t lateness,
301d5525d8cSshatty						bool realTimeEvent = false);
302d5525d8cSshattyvirtual status_t HandleWarp(
303d5525d8cSshatty						const media_timed_event *event,
304d5525d8cSshatty						bigtime_t lateness,
305d5525d8cSshatty						bool realTimeEvent = false);
306d5525d8cSshattyvirtual status_t HandleStop(
307d5525d8cSshatty						const media_timed_event *event,
308d5525d8cSshatty						bigtime_t lateness,
309d5525d8cSshatty						bool realTimeEvent = false);
310d5525d8cSshattyvirtual status_t HandleBuffer(
311d5525d8cSshatty						const media_timed_event *event,
312d5525d8cSshatty						bigtime_t lateness,
313d5525d8cSshatty						bool realTimeEvent = false);
314d5525d8cSshattyvirtual status_t HandleDataStatus(
315d5525d8cSshatty						const media_timed_event *event,
316d5525d8cSshatty						bigtime_t lateness,
317d5525d8cSshatty						bool realTimeEvent = false);
318d5525d8cSshattyvirtual status_t HandleParameter(
319d5525d8cSshatty						const media_timed_event *event,
320d5525d8cSshatty						bigtime_t lateness,
321d5525d8cSshatty						bool realTimeEvent = false);
322d5525d8cSshatty
323728a8c74Sshattyprotected:
324728a8c74Sshatty
325728a8c74Sshattyvoid CreateBufferGroup(MediaOutputInfo * output_info);
326728a8c74Sshattyvoid ComputeInternalLatency();
327728a8c74Sshatty
328d5525d8cSshattypublic:
329d5525d8cSshatty
330d5525d8cSshattystatic void GetFlavor(flavor_info * outInfo, int32 id);
331d5525d8cSshatty
332d5525d8cSshattyprivate:
333d5525d8cSshatty
334d5525d8cSshattystatic void GetInputFormat(media_format * outFormat);
335d5525d8cSshattystatic void GetOutputFormat(media_format * outFormat);
336d5525d8cSshatty
337d5525d8cSshattyprotected:
338d5525d8cSshatty
339d5525d8cSshattyvirtual status_t AddRequirements(media_format * format);
340d5525d8cSshatty
341d5525d8cSshattyprivate:
342d5525d8cSshatty
343d5525d8cSshatty		MediaDemultiplexerNode(	/* private unimplemented */
344d5525d8cSshatty				const MediaDemultiplexerNode & clone);
345d5525d8cSshatty		MediaDemultiplexerNode & operator=(
346d5525d8cSshatty				const MediaDemultiplexerNode & clone);
347d5525d8cSshatty
348d5525d8cSshatty		status_t fInitCheckStatus;
349d5525d8cSshatty
350d5525d8cSshatty		BMediaAddOn * fAddOn;
351d5525d8cSshatty
352d5525d8cSshatty		media_input input;
353d5525d8cSshatty		vector<MediaOutputInfo> outputs;
354d5525d8cSshatty
355d5525d8cSshatty		bigtime_t fDownstreamLatency;
356d5525d8cSshatty		bigtime_t fInternalLatency;
357d5525d8cSshatty
358d5525d8cSshatty		/* Mmmh, stuffing! */
359d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_0(void *);
360d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_1(void *);
361d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_2(void *);
362d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_3(void *);
363d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_4(void *);
364d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_5(void *);
365d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_6(void *);
366d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_7(void *);
367d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_8(void *);
368d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_9(void *);
369d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_10(void *);
370d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_11(void *);
371d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_12(void *);
372d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_13(void *);
373d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_14(void *);
374d5525d8cSshattyvirtual		status_t _Reserved_MediaDemultiplexerNode_15(void *);
375d5525d8cSshatty
376d5525d8cSshatty		uint32 _reserved_media_demultiplexer_node_[16];
377d5525d8cSshatty
378d5525d8cSshatty};
379d5525d8cSshatty
380d5525d8cSshatty#endif /* _MEDIA_DEMULTIPLEXER_NODE_H */
381