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