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

Revision 714, 9.8 kB (checked in by ppalmers, 15 years ago)

- cleanup of streaming interfaces
- doesn't work yet

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