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

Revision 715, 9.6 kB (checked in by ppalmers, 15 years ago)

some more cleaning

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 \brief Class providing a generic interface for Stream Processors
43
44  A stream processor multiplexes or demultiplexes an ISO stream into a
45  collection of ports. This class should be subclassed, and the relevant
46  functions should be overloaded.
47
48 */
49 class StreamProcessor : public IsoStream,
50                         public PortManager,
51                         public Util::TimestampedBufferClient,
52                         public Util::OptionContainer {
53
54     friend class StreamProcessorManager; // FIXME: get rid of this
55
56 public:
57     ///> the streamprocessor type
58     enum eProcessorType {
59         ePT_Receive,
60         ePT_Transmit
61     };
62     ///> returns the type of the streamprocessor
63     virtual enum eProcessorType getType() { return m_processor_type; };
64 private:
65     // this can only be set by the constructor
66     enum eProcessorType m_processor_type;
67
68 protected:
69     ///> the state the streamprocessor is in
70     enum eProcessorState {
71         ePS_Created,
72         ePS_Initialized,
73         ePS_WaitingForRunningStream,
74         ePS_DryRunning,
75         ePS_WaitingForEnabledStream,
76         ePS_StreamEnabled,
77         ePS_WaitingForDisabledStream,
78     };
79    
80     ///> set the SP state to a specific value
81     void setState(enum eProcessorState);
82     ///> get the SP state
83     enum eProcessorState getState() {return m_state;};
84 private:
85     enum eProcessorState m_state;
86     const char *ePSToString(enum eProcessorState);
87
88 // constructor/destructor
89 public:
90     StreamProcessor(enum eProcessorType type, int port);
91     virtual ~StreamProcessor();
92
93 // the receive/transmit functions
94 public:
95     // the transmit interface accepts frames and provides packets
96     // implement these for a transmit SP
97     // leave default for a receive SP
98     virtual enum raw1394_iso_disposition
99     getPacket(unsigned char *data, unsigned int *length,
100                 unsigned char *tag, unsigned char *sy,
101                 int cycle, unsigned int dropped, unsigned int max_length)
102         {debugWarning("call not allowed\n"); return RAW1394_ISO_STOP;};
103     virtual bool putFrames(unsigned int nbframes, int64_t ts)
104         {debugWarning("call not allowed\n"); return false;};
105     virtual bool putFramesDry(unsigned int nbframes, int64_t ts)
106         {debugWarning("call not allowed\n"); return false;};
107     virtual bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset)
108         {debugWarning("call not allowed\n"); return false;};
109
110     // the receive interface accepts packets and provides frames
111     // implement these for a receive SP
112     // leave default for a transmit SP
113     virtual enum raw1394_iso_disposition
114         putPacket(unsigned char *data, unsigned int length,
115                   unsigned char channel, unsigned char tag, unsigned char sy,
116                   unsigned int cycle, unsigned int dropped)
117         {debugWarning("call not allowed\n"); return RAW1394_ISO_STOP;};
118     virtual bool getFrames(unsigned int nbframes, int64_t ts)
119         {debugWarning("call not allowed\n"); return false;};
120     virtual bool getFramesDry(unsigned int nbframes, int64_t ts)
121         {debugWarning("call not allowed\n"); return false;};
122     virtual bool processReadBlock(char *data, unsigned int nevents, unsigned int offset)
123         {debugWarning("call not allowed\n"); return false;};
124
125
126 //--- state stuff (TODO: cleanup)
127     bool xrunOccurred() { return (m_xruns>0); };
128     bool isRunning(); ///< returns true if there is some stream data processed
129     virtual bool prepareForEnable(uint64_t time_to_enable_at);
130     virtual bool prepareForDisable();
131
132     bool enable(uint64_t time_to_enable_at); ///< enable the stream processing
133     bool disable(); ///< disable the stream processing
134     bool isEnabled() {return !m_is_disabled;};
135
136     virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun)
137
138     virtual bool prepare(); ///< prepare the streams & buffers (e.g. prefill)
139     virtual bool init();
140     virtual bool prepareForStop() {return true;};
141     virtual bool prepareForStart() {return true;};
142
143     // move to private?
144     void resetXrunCounter();
145 protected:
146     bool m_running;
147     bool m_disabled;
148     bool m_is_disabled;
149     unsigned int m_cycle_to_enable_at;
150
151 //--- data buffering and accounting
152 public: // FIXME: should be private
153     Util::TimestampedBuffer *m_data_buffer;
154
155 protected:
156     unsigned int m_xruns;
157
158     StreamProcessorManager *m_manager;
159
160     // frame counter & sync stuff
161     public:
162         /**
163          * @brief Can this StreamProcessor handle a transfer of nframes frames?
164          *
165          * this function indicates if the streamprocessor can handle a transfer of
166          * nframes frames. It is used to detect underruns-to-be.
167          *
168          * @param nframes number of frames
169          * @return true if the StreamProcessor can handle this amount of frames
170          *         false if it can't
171          */
172         virtual bool canClientTransferFrames(unsigned int nframes);
173
174         /**
175          * @brief drop nframes from the internal buffer
176          *
177          * this function drops nframes from the internal buffers, without any
178          * specification on what frames are dropped. Timestamps are not updated.
179          *
180          * @param nframes number of frames
181          * @return true if the operation was successful
182          */
183         virtual bool dropFrames(unsigned int nframes);
184
185         /**
186          * \brief return the time until the next period boundary should be signaled (in microseconds)
187          *
188          * Return the time until the next period boundary signal. If this StreamProcessor
189          * is the current synchronization source, this function is called to
190          * determine when a buffer transfer can be made. When this value is
191          * smaller than 0, a period boundary is assumed to be crossed, hence a
192          * transfer can be made.
193          *
194          * \return the time in usecs
195          */
196         int64_t getTimeUntilNextPeriodSignalUsecs();
197         /**
198          * \brief return the time of the next period boundary (in microseconds)
199          *
200          * Returns the time of the next period boundary, in microseconds. The
201          * goal of this function is to determine the exact point of the period
202          * boundary. This is assumed to be the point at which the buffer transfer should
203          * take place, meaning that it can be used as a reference timestamp for transmitting
204          * StreamProcessors
205          *
206          * \return the time in usecs
207          */
208         uint64_t getTimeAtPeriodUsecs();
209
210         /**
211          * \brief return the time of the next period boundary (in internal units)
212          *
213          * The same as getTimeAtPeriodUsecs() but in internal units.
214          *
215          * @return the time in internal units
216          */
217         virtual uint64_t getTimeAtPeriod();
218
219         uint64_t getTimeNow();
220
221
222         /**
223          * Returns the sync delay. This is the time a syncsource
224          * delays a period signal, e.g. to cope with buffering.
225          * @return the sync delay
226          */
227         int getSyncDelay() {return m_sync_delay;};
228         /**
229          * sets the sync delay
230          * @param d sync delay
231          */
232         void setSyncDelay(int d) {m_sync_delay=d;};
233
234         /**
235          * @brief get the maximal frame latency
236          *
237          * The maximum frame latency is the maximum time that will elapse
238          * between the frame being received by the 1394 stack, and the moment this
239          * frame is presented to the StreamProcessor.
240          *
241          * For transmit SP's this is the maximum time that a frame is requested by
242          * the handler ahead of the time the frame is intended to be transmitted.
243          *
244          * This is useful to figure out how longer than the actual reception time
245          * we have to wait before trying to read the frame from the SP.
246          *
247          * @return maximal frame latency
248          */
249         virtual int getMaxFrameLatency();
250
251         StreamProcessor& getSyncSource();
252
253         float getTicksPerFrame();
254
255         int getLastCycle() {return m_last_cycle;};
256
257         int getBufferFill();
258
259     protected:
260         float m_ticks_per_frame;
261         int m_last_cycle;
262         int m_sync_delay;
263
264 protected: // SPM related
265     void setManager(StreamProcessorManager *manager) {m_manager=manager;};
266     void clearManager() {m_manager=NULL;};
267
268 public:
269     // debug stuff
270     virtual void dumpInfo();
271     virtual void setVerboseLevel(int l);
272     StreamStatistics m_PacketStat;
273     StreamStatistics m_PeriodStat;
274     StreamStatistics m_WakeupStat;
275     DECLARE_DEBUG_MODULE;
276
277 };
278
279 }
280
281 #endif /* __FFADO_STREAMPROCESSOR__ */
282
283
Note: See TracBrowser for help on using the browser.