1/*
2 * Copyright 2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _BUFFER_PRODUCER_H
6#define _BUFFER_PRODUCER_H
7
8
9#include <MediaNode.h>
10
11
12class BBuffer;
13class BBufferGroup;
14class BRegion;
15
16
17namespace BPrivate {
18	namespace media {
19		class BMediaRosterEx;
20	}
21}
22
23
24class BBufferProducer : public virtual BMediaNode {
25protected:
26	// NOTE: This has to be at the top to force a vtable.
27	virtual						~BBufferProducer();
28
29public:
30
31	// Supported formats for low-level clipping data
32	enum {
33		B_CLIP_SHORT_RUNS = 1
34	};
35
36	// Handy conversion function for dealing with clip information.
37	static	status_t			ClipDataToRegion(int32 format, int32 size,
38									const void* data,  BRegion* region);
39
40			media_type			ProducerType();
41
42protected:
43	explicit					BBufferProducer(media_type producer_type
44									/* = B_MEDIA_UNKNOWN_TYPE */);
45
46	enum suggestion_quality {
47		B_ANY_QUALITY		= 0,
48		B_LOW_QUALITY		= 10,
49		B_MEDIUM_QUALITY	= 50,
50		B_HIGH_QUALITY		= 100
51	};
52
53	// BBufferProducer interface
54	virtual	status_t			FormatSuggestionRequested(media_type type,
55									int32 quality, media_format* format) = 0;
56	virtual	status_t			FormatProposal(const media_source& output,
57									media_format* ioFormat) = 0;
58
59	// If the format isn't good, put a good format into ioFormat and
60	// return error.
61	// If format has wildcard, specialize to what you can do (and change).
62	// If you can change the format, return OK.
63	// The request comes from your destination sychronously, so you cannot ask
64	// it whether it likes it -- you should assume it will since it asked.
65	virtual	status_t			FormatChangeRequested(
66									const media_source& source,
67									const media_destination& destination,
68									media_format* ioFormat,
69									int32* _deprecated_) = 0;
70	virtual	status_t			GetNextOutput(
71									int32* ioCookie,
72									media_output* _output) = 0;
73	virtual	status_t			DisposeOutputCookie(int32 cookie) = 0;
74
75	// In this function, you should either pass on the group to your upstream
76	// guy, or delete your current group and hang on to this group. Deleting
77	// the previous group (unless you passed it on with the reclaim flag set
78	// to false) is very important, else you will 1) leak memory and 2) block
79	// someone who may want to reclaim the buffers living in that group.
80	virtual	status_t			SetBufferGroup(const media_source& forSource,
81									BBufferGroup* group) = 0;
82
83	// Format of clipping is (as int16-s): <from line> <npairs> <startclip>
84	// <endclip>. Repeat for each line where the clipping is different from
85	// the previous line. If <npairs> is negative, use the data from line
86	// -<npairs> (there are 0 pairs after a negative <npairs>. Yes, we only
87	// support 32k*32k frame buffers for clipping. Any non-0 field of
88	// 'display' means that that field changed, and if you don't support that
89	// change, you should return an error and ignore the request. Note that
90	// the buffer offset values do not have wildcards; 0 (or -1, or whatever)
91	// are real values and must be adhered to.
92	virtual	status_t			VideoClippingChanged(
93									const media_source& forSource,
94									int16 numShorts,
95									int16* clipData,
96									const media_video_display_info& display,
97									int32 * _deprecated_);
98
99	// Iterates over all outputs and maxes the latency found
100	virtual	status_t			GetLatency(bigtime_t* _lantency);
101
102	virtual	status_t			PrepareToConnect(const media_source& what,
103									const media_destination& where,
104									media_format* format,
105									media_source* _source,
106									char* _name) = 0;
107	virtual	void				Connect(status_t error,
108									const media_source& source,
109									const media_destination& destination,
110									const media_format& format,
111									char* ioName) = 0;
112	virtual	void				Disconnect(const media_source& what,
113									const media_destination& where) = 0;
114
115	virtual	void				LateNoticeReceived(const media_source& what,
116									bigtime_t howMuch,
117									bigtime_t performanceTime) = 0;
118
119	virtual	void				EnableOutput(const media_source& what,
120									bool enabled, int32* _deprecated_) = 0;
121
122	virtual	status_t			SetPlayRate(int32 numer, int32 denom);
123
124	// NOTE: Call this from the thread that listens to the port!
125	virtual	status_t			HandleMessage(int32 message, const void* data,
126									size_t size);
127
128	virtual	void				AdditionalBufferRequested(
129									const media_source& source,
130									media_buffer_id previousBuffer,
131									bigtime_t previousTime,
132									const media_seek_tag* previousTag
133										/* = NULL */);
134
135	virtual	void				LatencyChanged(const media_source& source,
136									const media_destination& destination,
137									bigtime_t newLatency, uint32 flags);
138
139	// NOTE: Use this function to pass on the buffer on to the BBufferConsumer.
140			status_t			SendBuffer(BBuffer* buffer,
141									const media_source& source,
142									const media_destination& destination);
143
144			status_t			SendDataStatus(int32 status,
145									const media_destination& destination,
146									bigtime_t atTime);
147
148	// Check in advance if a target is prepared to accept a format. You may
149	// want to call this from Connect(), although that's not required.
150			status_t			ProposeFormatChange(media_format* format,
151									const media_destination& forDestination);
152
153	// Tell consumer to accept a proposed format change
154	// NOTE: You must not call SendBuffer while this call is pending!
155			status_t			ChangeFormat(const media_source& forSource,
156									const media_destination& forDestination,
157									media_format* format);
158
159	// Check how much latency the down-stream graph introduces.
160			status_t			FindLatencyFor(
161									const media_destination& forDestination,
162									bigtime_t* _latency,
163									media_node_id* _timesource);
164
165	// Find the tag of a previously seen buffer to expedite seeking
166			status_t			FindSeekTag(
167									const media_destination& forDestination,
168									bigtime_t inTargetTime,
169									media_seek_tag* _tag,
170									bigtime_t* _taggedTime, uint32* _flags = 0,
171									uint32 flags = 0);
172
173	// Set the initial latency, which is the maximum additional latency
174	// that will be imposed while starting/syncing to a signal (such as
175	// starting a TV capture card in the middle of a field). Most nodes
176	// have this at 0 (the default); only TV input Nodes need it currently
177	// because they slave to a low-resolution (59.94 Hz) clock that arrives
178	// from the outside world. Call this from the constructor if you need it.
179			void				SetInitialLatency(bigtime_t inInitialLatency,
180									uint32 flags = 0);
181
182	// TODO: Needs a Perform() virtual method!
183
184private:
185	// FBC padding and forbidden methods
186								BBufferProducer();
187								BBufferProducer(const BBufferProducer& other);
188			BBufferProducer&	operator=(const BBufferProducer& other);
189
190			status_t			_Reserved_BufferProducer_0(void*);
191				// was AdditionalBufferRequested()
192			status_t			_Reserved_BufferProducer_1(void*);
193				// was LatencyChanged()
194	virtual	status_t			_Reserved_BufferProducer_2(void*);
195	virtual	status_t			_Reserved_BufferProducer_3(void*);
196	virtual	status_t			_Reserved_BufferProducer_4(void*);
197	virtual	status_t			_Reserved_BufferProducer_5(void*);
198	virtual	status_t			_Reserved_BufferProducer_6(void*);
199	virtual	status_t			_Reserved_BufferProducer_7(void*);
200	virtual	status_t			_Reserved_BufferProducer_8(void*);
201	virtual	status_t			_Reserved_BufferProducer_9(void*);
202	virtual	status_t			_Reserved_BufferProducer_10(void*);
203	virtual	status_t			_Reserved_BufferProducer_11(void*);
204	virtual	status_t			_Reserved_BufferProducer_12(void*);
205	virtual	status_t			_Reserved_BufferProducer_13(void*);
206	virtual	status_t			_Reserved_BufferProducer_14(void*);
207	virtual	status_t			_Reserved_BufferProducer_15(void*);
208
209	// deprecated calls
210			status_t			SendBuffer(BBuffer* buffer,
211									const media_destination& destination);
212
213private:
214			friend class BBufferConsumer;
215			friend class BMediaNode;
216			friend class BMediaRoster;
217			friend class BPrivate::media::BMediaRosterEx;
218
219	static	status_t			clip_shorts_to_region(const int16* data,
220									int count, BRegion* output);
221	static	status_t			clip_region_to_shorts(const BRegion* input,
222									int16* data, int maxCount, int* _count);
223
224private:
225			media_type			fProducerType;
226			bigtime_t			fInitialLatency;
227			uint32				fInitialFlags;
228			bigtime_t			fDelay;
229
230			uint32				_reserved_buffer_producer_[12];
231};
232
233#endif // _BUFFER_PRODUCER_H
234
235