root/branches/streaming-rework/src/libstreaming/StreamProcessor.h

Revision 424, 9.4 kB (checked in by pieterpalmers, 15 years ago)

- The library can now be started in 'slave mode', creating a BounceSlaveDevice?.

On a discovering node, this slave device is discovered as a BounceDevice?.
Streaming does not work yet, something wrong with the timestamps.

- Implemented the 'snoop mode', that allows a client to 'snoop' the streams

between another host and a device. It is only implemented for BeBoB devices.
The channel numbers and stream configuration are automatically detected.
Note that it currently relies on a rather hackish support for reading the
{i,o}PCR plugs by using private functions of libiec61883

- changed jack backend to support these two new features

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