1// MediaReader.h
2//
3// Andrew Bachmann, 2002
4//
5// A MediaReader is a node that
6// implements FileInterface and BBufferProducer.
7// It reads any file and produces one output,
8// which is a multistream.  It has a rather
9// unique interpretation of time.  Time is
10// distance in the file.  So the duration is the
11// file length. (in bytes)
12
13#if !defined(_MEDIA_READER_H)
14#define _MEDIA_READER_H
15
16#include <MediaDefs.h>
17#include <MediaNode.h>
18#include <FileInterface.h>
19#include <BufferProducer.h>
20#include <Controllable.h>
21#include <MediaEventLooper.h>
22#include <File.h>
23#include <Entry.h>
24#include <BufferGroup.h>
25
26#include "../AbstractFileInterfaceNode.h"
27
28class MediaReader :
29    public BBufferProducer,
30    public AbstractFileInterfaceNode
31{
32protected:
33virtual ~MediaReader(void);
34
35public:
36
37explicit MediaReader(
38				size_t defaultChunkSize = 8192, // chunk size = 8 KB
39				float defaultBitRate = 800000,  // bit rate = 100.000 KB/sec = 5.85 MB/minute
40				const flavor_info * info = 0,   // buffer period = 80 milliseconds
41				BMessage * config = 0,
42				BMediaAddOn * addOn = 0);
43
44/*************************/
45/* begin from BMediaNode */
46protected:
47		/* These don't return errors; instead, they use the global error condition reporter. */
48		/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
49		/* and is recommended to allow for at least one pending command of each type. */
50		/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
51		/* cannot depend on that happening. */
52virtual	void Preroll(void);
53
54public:
55virtual	status_t HandleMessage(
56				int32 message,
57				const void * data,
58				size_t size);
59
60protected:
61virtual		void NodeRegistered(void);	/* reserved 2 */
62
63/* end from BMediaNode */
64/***********************/
65
66/*****************************/
67/* begin from BFileInterface */
68protected:
69
70using AbstractFileInterfaceNode::SetRef;
71
72virtual	status_t SetRef(
73				const entry_ref & file,
74				bool create,
75				bigtime_t * out_time);
76
77/* end from BFileInterface */
78/***************************/
79
80// provided for BMediaReaderAddOn
81public:
82static status_t StaticSniffRef(
83				const entry_ref & file,
84				char * out_mime_type,	/* 256 bytes */
85				float * out_quality);
86
87/******************************/
88/* begin from BBufferProducer */
89protected:
90	/* functionality of BBufferProducer */
91virtual	status_t FormatSuggestionRequested(
92				media_type type,
93				int32 quality,
94				media_format * format);
95virtual	status_t FormatProposal(
96				const media_source & output,
97				media_format * format);
98	/* If the format isn't good, put a good format into *io_format and return error */
99	/* If format has wildcard, specialize to what you can do (and change). */
100	/* If you can change the format, return OK. */
101	/* The request comes from your destination sychronously, so you cannot ask it */
102	/* whether it likes it -- you should assume it will since it asked. */
103virtual	status_t FormatChangeRequested(
104				const media_source & source,
105				const media_destination & destination,
106				media_format * io_format,
107				int32 * _deprecated_);
108virtual	status_t GetNextOutput(	/* cookie starts as 0 */
109				int32 * cookie,
110				media_output * out_output);
111virtual	status_t DisposeOutputCookie(
112				int32 cookie);
113	/* In this function, you should either pass on the group to your upstream guy, */
114	/* or delete your current group and hang on to this group. Deleting the previous */
115	/* group (unless you passed it on with the reclaim flag set to false) is very */
116	/* important, else you will 1) leak memory and 2) block someone who may want */
117	/* to reclaim the buffers living in that group. */
118virtual	status_t SetBufferGroup(
119				const media_source & for_source,
120				BBufferGroup * group);
121	/* Format of clipping is (as int16-s): <from line> <npairs> <startclip> <endclip>. */
122	/* Repeat for each line where the clipping is different from the previous line. */
123	/* If <npairs> is negative, use the data from line -<npairs> (there are 0 pairs after */
124	/* a negative <npairs>. Yes, we only support 32k*32k frame buffers for clipping. */
125	/* Any non-0 field of 'display' means that that field changed, and if you don't support */
126	/* that change, you should return an error and ignore the request. Note that the buffer */
127	/* offset values do not have wildcards; 0 (or -1, or whatever) are real values and must */
128	/* be adhered to. */
129virtual	status_t VideoClippingChanged(
130				const media_source & for_source,
131				int16 num_shorts,
132				int16 * clip_data,
133				const media_video_display_info & display,
134				int32 * _deprecated_);
135	/* Iterates over all outputs and maxes the latency found */
136virtual	status_t GetLatency(
137				bigtime_t * out_latency);
138virtual	status_t PrepareToConnect(
139				const media_source & what,
140				const media_destination & where,
141				media_format * format,
142				media_source * out_source,
143				char * out_name);
144virtual	void Connect(
145				status_t error,
146				const media_source & source,
147				const media_destination & destination,
148				const media_format & format,
149				char * io_name);
150virtual	void Disconnect(
151				const media_source & what,
152				const media_destination & where);
153virtual	void LateNoticeReceived(
154				const media_source & what,
155				bigtime_t how_much,
156				bigtime_t performance_time);
157virtual	void EnableOutput(
158				const media_source & what,
159				bool enabled,
160				int32 * _deprecated_);
161virtual	status_t SetPlayRate(
162				int32 numer,
163				int32 denom);
164
165//included from BMediaNode
166//virtual	status_t HandleMessage(	/* call this from the thread that listens to the port */
167//				int32 message,
168//				const void * data,
169//				size_t size);
170
171virtual	void AdditionalBufferRequested(			//	used to be Reserved 0
172				const media_source & source,
173				media_buffer_id prev_buffer,
174				bigtime_t prev_time,
175				const media_seek_tag * prev_tag);	//	may be NULL
176
177virtual	void LatencyChanged(					//	used to be Reserved 1
178				const media_source & source,
179				const media_destination & destination,
180				bigtime_t new_latency,
181				uint32 flags);
182
183/* end from BBufferProducer */
184/****************************/
185
186/*****************/
187/* BControllable */
188/*****************/
189
190/*********************/
191/* BMediaEventLooper */
192/*********************/
193
194protected:
195
196virtual status_t HandleBuffer(
197						const media_timed_event *event,
198						bigtime_t lateness,
199						bool realTimeEvent = false);
200virtual status_t HandleDataStatus(
201						const media_timed_event *event,
202						bigtime_t lateness,
203						bool realTimeEvent = false);
204
205public:
206
207static void GetFlavor(flavor_info * outInfo, int32 id);
208static void GetFormat(media_format * outFormat);
209static void GetFileFormat(media_file_format * outFileFormat);
210
211protected:
212
213virtual status_t GetFilledBuffer(BBuffer ** outBuffer);
214virtual status_t FillFileBuffer(BBuffer * buffer);
215
216private:
217
218		MediaReader(	/* private unimplemented */
219				const MediaReader & clone);
220		MediaReader & operator=(
221				const MediaReader & clone);
222
223		media_output output;
224
225		bool fOutputEnabled;
226
227		BBufferGroup * fBufferGroup;
228		bigtime_t fDownstreamLatency;
229		bigtime_t fInternalLatency;
230		// this is computed from the real (negotiated) chunk size and bit rate,
231		// not the defaults that are in the parameters
232		bigtime_t fBufferPeriod;
233
234		/* Mmmh, stuffing! */
235virtual		status_t _Reserved_MediaReader_0(void *);
236virtual		status_t _Reserved_MediaReader_1(void *);
237virtual		status_t _Reserved_MediaReader_2(void *);
238virtual		status_t _Reserved_MediaReader_3(void *);
239virtual		status_t _Reserved_MediaReader_4(void *);
240virtual		status_t _Reserved_MediaReader_5(void *);
241virtual		status_t _Reserved_MediaReader_6(void *);
242virtual		status_t _Reserved_MediaReader_7(void *);
243virtual		status_t _Reserved_MediaReader_8(void *);
244virtual		status_t _Reserved_MediaReader_9(void *);
245virtual		status_t _Reserved_MediaReader_10(void *);
246virtual		status_t _Reserved_MediaReader_11(void *);
247virtual		status_t _Reserved_MediaReader_12(void *);
248virtual		status_t _Reserved_MediaReader_13(void *);
249virtual		status_t _Reserved_MediaReader_14(void *);
250virtual		status_t _Reserved_MediaReader_15(void *);
251
252		uint32 _reserved_media_reader_[16];
253
254};
255
256#endif /* _MEDIA_READER_H */
257