root/branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h

Revision 709, 10.4 kB (checked in by ppalmers, 16 years ago)

some more streaming system updates.
this works with the saffire up till -n2 -p256

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #ifndef __FFADO_STREAMPROCESSOR__
25 #define __FFADO_STREAMPROCESSOR__
26
27 #include "IsoStream.h"
28 #include "PortManager.h"
29
30 #include "libutil/StreamStatistics.h"
31 #include "libutil/TimestampedBuffer.h"
32 #include "libutil/OptionContainer.h"
33
34 #include "debugmodule/debugmodule.h"
35
36 #include <pthread.h>
37
38 namespace Streaming {
39
40 class StreamProcessorManager;
41
42 /*!
43 \brief Class providing a generic interface for Stream Processors
44
45  A stream processor multiplexes or demultiplexes an ISO stream into a
46  collection of ports. This class should be subclassed, and the relevant
47  functions should be overloaded.
48
49 */
50 class StreamProcessor : public IsoStream,
51                         public PortManager,
52                         public Util::TimestampedBufferClient,
53                         public Util::OptionContainer {
54
55     friend class StreamProcessorManager;
56
57 public:
58     enum EProcessorType {
59             E_Receive,
60             E_Transmit
61     };
62
63     StreamProcessor(enum IsoStream::EStreamType type, int port, int framerate);
64     virtual ~StreamProcessor();
65
66     virtual enum raw1394_iso_disposition
67             putPacket(unsigned char *data, unsigned int length,
68                     unsigned char channel, unsigned char tag, unsigned char sy,
69                         unsigned int cycle, unsigned int dropped) = 0;
70     virtual enum raw1394_iso_disposition
71             getPacket(unsigned char *data, unsigned int *length,
72                     unsigned char *tag, unsigned char *sy,
73                     int cycle, unsigned int dropped, unsigned int max_length) = 0;
74
75     virtual enum EProcessorType getType() =0;
76
77     bool xrunOccurred() { return (m_xruns>0);};
78
79     // move to private?
80     void resetXrunCounter();
81
82     bool isRunning(); ///< returns true if there is some stream data processed
83
84     virtual bool prepareForEnable(uint64_t time_to_enable_at);
85     virtual bool prepareForDisable();
86
87     bool enable(uint64_t time_to_enable_at); ///< enable the stream processing
88     bool disable(); ///< disable the stream processing
89     bool isEnabled() {return !m_is_disabled;};
90
91     virtual bool putFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents from client
92     virtual bool getFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents to the client
93     virtual bool putFramesDry(unsigned int nbframes, int64_t ts) = 0; ///< dry-process the buffer contents
94     virtual bool getFramesDry(unsigned int nbframes, int64_t ts) = 0; ///< dry-process the buffer contents
95
96     virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun)
97
98     virtual bool prepare(); ///< prepare the streams & buffers (e.g. prefill)
99
100     virtual void dumpInfo();
101
102     virtual bool init();
103
104     virtual void setVerboseLevel(int l);
105
106     virtual bool prepareForStop() {return true;};
107     virtual bool prepareForStart() {return true;};
108
109
110 public:
111     Util::TimestampedBuffer *m_data_buffer;
112
113     StreamStatistics m_PacketStat;
114     StreamStatistics m_PeriodStat;
115
116     StreamStatistics m_WakeupStat;
117
118 protected: // SPM related
119     void setManager(StreamProcessorManager *manager) {m_manager=manager;};
120     void clearManager() {m_manager=0;};
121
122 protected:
123     unsigned int m_nb_buffers; ///< cached from manager->getNbBuffers(), the number of periods to buffer
124     unsigned int m_period; ///< cached from manager->getPeriod(), the period size
125
126     unsigned int m_xruns;
127
128     unsigned int m_framerate;
129
130     StreamProcessorManager *m_manager;
131
132     bool m_running;
133     bool m_disabled;
134     bool m_is_disabled;
135     unsigned int m_cycle_to_enable_at;
136
137
138
139     DECLARE_DEBUG_MODULE;
140
141     // frame counter & sync stuff
142     public:
143         /**
144          * @brief Can this StreamProcessor handle a transfer of nframes frames?
145          *
146          * this function indicates if the streamprocessor can handle a transfer of
147          * nframes frames. It is used to detect underruns-to-be.
148          *
149          * @param nframes number of frames
150          * @return true if the StreamProcessor can handle this amount of frames
151          *         false if it can't
152          */
153         virtual bool canClientTransferFrames(unsigned int nframes) = 0;
154
155         /**
156          * @brief drop nframes from the internal buffer
157          *
158          * this function drops nframes from the internal buffers, without any
159          * specification on what frames are dropped. Timestamps are not updated.
160          *
161          * @param nframes number of frames
162          * @return true if the operation was successful
163          */
164         virtual bool dropFrames(unsigned int nframes);
165
166         /**
167          * \brief return the time until the next period boundary should be signaled (in microseconds)
168          *
169          * Return the time until the next period boundary signal. If this StreamProcessor
170          * is the current synchronization source, this function is called to
171          * determine when a buffer transfer can be made. When this value is
172          * smaller than 0, a period boundary is assumed to be crossed, hence a
173          * transfer can be made.
174          *
175          * \return the time in usecs
176          */
177         int64_t getTimeUntilNextPeriodSignalUsecs();
178         /**
179          * \brief return the time of the next period boundary (in microseconds)
180          *
181          * Returns the time of the next period boundary, in microseconds. The
182          * goal of this function is to determine the exact point of the period
183          * boundary. This is assumed to be the point at which the buffer transfer should
184          * take place, meaning that it can be used as a reference timestamp for transmitting
185          * StreamProcessors
186          *
187          * \return the time in usecs
188          */
189         uint64_t getTimeAtPeriodUsecs();
190
191         /**
192          * \brief return the time of the next period boundary (in internal units)
193          *
194          * The same as getTimeAtPeriodUsecs() but in internal units.
195          *
196          * @return the time in internal units
197          */
198         virtual uint64_t getTimeAtPeriod() = 0;
199
200         uint64_t getTimeNow();
201
202
203         /**
204          * Returns the sync delay. This is the time a syncsource
205          * delays a period signal, e.g. to cope with buffering.
206          * @return the sync delay
207          */
208         int getSyncDelay() {return m_sync_delay;};
209         /**
210          * sets the sync delay
211          * @param d sync delay
212          */
213         void setSyncDelay(int d) {m_sync_delay=d;};
214
215         /**
216          * @brief get the maximal frame latency
217          *
218          * The maximum frame latency is the maximum time that will elapse
219          * between the frame being received by the 1394 stack, and the moment this
220          * frame is presented to the StreamProcessor.
221          *
222          * For transmit SP's this is the maximum time that a frame is requested by
223          * the handler ahead of the time the frame is intended to be transmitted.
224          *
225          * This is useful to figure out how longer than the actual reception time
226          * we have to wait before trying to read the frame from the SP.
227          *
228          * @return maximal frame latency
229          */
230         virtual int getMaxFrameLatency();
231
232         bool setSyncSource(StreamProcessor *s);
233         float getTicksPerFrame();
234
235         int getLastCycle() {return m_last_cycle;};
236
237         int getBufferFill();
238
239     protected:
240         StreamProcessor *m_SyncSource;
241
242         float m_ticks_per_frame;
243
244         int m_last_cycle;
245         int m_sync_delay;
246
247 };
248
249 /*!
250 \brief Class providing a generic interface for receive Stream Processors
251
252 */
253 class ReceiveStreamProcessor : public StreamProcessor {
254
255 public:
256     ReceiveStreamProcessor(int port, int framerate)
257         : StreamProcessor(IsoStream::EST_Receive, port, framerate) {};
258     virtual ~ReceiveStreamProcessor(){};
259
260
261     virtual enum EProcessorType getType() {return E_Receive;};
262
263     virtual enum raw1394_iso_disposition
264         getPacket(unsigned char *data, unsigned int *length,
265                   unsigned char *tag, unsigned char *sy,
266                   int cycle, unsigned int dropped, unsigned int max_length)
267                   {return RAW1394_ISO_STOP;};
268         virtual bool putFrames(unsigned int nbframes, int64_t ts) {return false;};
269         virtual bool putFramesDry(unsigned int nbframes, int64_t ts) {return false;};
270
271         virtual enum raw1394_iso_disposition putPacket(unsigned char *data, unsigned int length,
272                   unsigned char channel, unsigned char tag, unsigned char sy,
273                   unsigned int cycle, unsigned int dropped) = 0;
274
275     uint64_t getTimeAtPeriod();
276     bool canClientTransferFrames(unsigned int nframes);
277
278 protected:
279     bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset) {return true;};
280 };
281
282 /*!
283 \brief Class providing a generic interface for receive Stream Processors
284
285 */
286 class TransmitStreamProcessor : public StreamProcessor {
287
288 public:
289     TransmitStreamProcessor(int port, int framerate)
290         : StreamProcessor(IsoStream::EST_Transmit, port, framerate) {};
291     virtual ~TransmitStreamProcessor() {};
292
293     virtual enum EProcessorType getType() {return E_Transmit;};
294
295     virtual enum raw1394_iso_disposition
296         putPacket(unsigned char *data, unsigned int length,
297                   unsigned char channel, unsigned char tag, unsigned char sy,
298                   unsigned int cycle, unsigned int dropped) {return RAW1394_ISO_STOP;};
299         virtual bool getFrames(unsigned int nbframes, int64_t ts) {return false;};
300         virtual bool getFramesDry(unsigned int nbframes, int64_t ts) {return false;};
301
302     uint64_t getTimeAtPeriod();
303     bool canClientTransferFrames(unsigned int nframes);
304
305 protected:
306     bool processReadBlock(char *data, unsigned int nevents, unsigned int offset) {return true;};
307 };
308
309 }
310
311 #endif /* __FFADO_STREAMPROCESSOR__ */
312
313
Note: See TracBrowser for help on using the browser.