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

Revision 390, 9.3 kB (checked in by pieterpalmers, 16 years ago)

* working version of SYT based AMDTP receive and transmit.

Still has to be tuned to work with low buffer sizes.

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
40 namespace FreebobStreaming {
41
42 class StreamProcessorManager;
43
44 /*!
45 \brief Class providing a generic interface for Stream Processors
46
47  A stream processor multiplexes or demultiplexes an ISO stream into a
48  collection of ports. This class should be subclassed, and the relevant
49  functions should be overloaded.
50  
51 */
52 class StreamProcessor : public IsoStream,
53                         public PortManager {
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     bool enable(uint64_t time_to_enable_at); ///< enable the stream processing
84     bool disable(); ///< disable the stream processing
85     bool isEnabled() {return !m_is_disabled;};
86
87     virtual bool putFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents from client
88     virtual bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client
89
90     virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun)
91
92     virtual bool prepare(); ///< prepare the streams & buffers (e.g. prefill)
93
94     virtual void dumpInfo();
95
96     virtual bool init();
97
98     virtual void setVerboseLevel(int l);
99
100     virtual bool prepareForStop() {return true;};
101     virtual bool prepareForStart() {return true;};
102    
103     virtual bool prepareForEnable();
104     virtual bool prepareForDisable();
105
106 protected:
107        
108
109     void setManager(StreamProcessorManager *manager) {m_manager=manager;};
110     void clearManager() {m_manager=0;};
111
112     unsigned int m_nb_buffers; ///< cached from manager->getNbBuffers(), the number of periods to buffer
113     unsigned int m_period; ///< cached from manager->getPeriod(), the period size
114
115     unsigned int m_xruns;
116
117     unsigned int m_framerate;
118
119     StreamProcessorManager *m_manager;
120    
121     bool m_running;
122     bool m_disabled;
123     bool m_is_disabled;
124     unsigned int m_cycle_to_enable_at;
125    
126     StreamStatistics m_PacketStat;
127     StreamStatistics m_PeriodStat;
128    
129     StreamStatistics m_WakeupStat;
130    
131
132     DECLARE_DEBUG_MODULE;
133    
134     // frame counter & sync stuff
135     public:
136         /**
137          * @brief Can this StreamProcessor handle a nframes of frames?
138          *
139          * this function indicates if the streamprocessor can handle nframes
140          * of frames. It is used to detect underruns-to-be.
141          *
142          * @param nframes number of frames
143          * @return true if the StreamProcessor can handle this amount of frames
144          *         false if it can't
145          */
146         virtual bool canClientTransferFrames(unsigned int nframes) {return true;};
147        
148         int getFrameCounter() {return m_framecounter;};
149    
150         void decrementFrameCounter(int nbframes, uint64_t new_timestamp);
151         void incrementFrameCounter(int nbframes, uint64_t new_timestamp);
152         void resetFrameCounter();
153        
154         /**
155          * \brief return the time until the next period boundary (in microseconds)
156          *
157          * Return the time until the next period boundary. If this StreamProcessor
158          * is the current synchronization source, this function is called to
159          * determine when a buffer transfer can be made. When this value is
160          * smaller than 0, a period boundary is assumed to be crossed, hence a
161          * transfer can be made.
162          *
163          * \return the time in usecs
164          */
165         virtual int64_t getTimeUntilNextPeriodUsecs() = 0;
166         /**
167          * \brief return the time of the next period boundary (in microseconds)
168          *
169          * Returns the time of the next period boundary, in microseconds. The
170          * goal of this function is to determine the exact point of the period
171          * boundary. This is assumed to be the point at which the buffer transfer should
172          * take place, meaning that it can be used as a reference timestamp for transmitting
173          * StreamProcessors
174          *
175          * \return the time in usecs
176          */
177         virtual uint64_t getTimeAtPeriodUsecs() = 0;
178        
179         /**
180          * \brief return the time of the next period boundary (in internal units)
181          *
182          * The same as getTimeUntilNextPeriodUsecs() but in internal units.
183          *
184          * @return the time in internal units
185          */
186         virtual uint64_t getTimeAtPeriod() = 0;
187        
188         uint64_t getTimeNow();
189        
190         void getBufferHeadTimestamp(uint64_t *ts, uint64_t *fc);
191         void getBufferTailTimestamp(uint64_t *ts, uint64_t *fc);
192        
193         void setBufferTailTimestamp(uint64_t new_timestamp);
194         void setBufferHeadTimestamp(uint64_t new_timestamp);
195         void setBufferTimestamps(uint64_t new_head, uint64_t new_tail);
196        
197         bool setSyncSource(StreamProcessor *s);
198         float getTicksPerFrame() {return m_ticks_per_frame;};
199        
200         unsigned int getLastCycle() {return m_last_cycle;};
201    
202     private:
203         // the framecounter gives the number of frames in the buffer
204         signed int m_framecounter;
205        
206         // the buffer tail timestamp gives the timestamp of the last frame
207         // that was put into the buffer
208         uint64_t   m_buffer_tail_timestamp;
209        
210         // the buffer head timestamp gives the timestamp of the first frame
211         // that was put into the buffer
212         uint64_t   m_buffer_head_timestamp;
213        
214     protected:
215         StreamProcessor *m_SyncSource;
216        
217         float m_ticks_per_frame;
218        
219         unsigned int m_last_cycle;
220
221     private:
222         // this mutex protects the access to the framecounter
223         // and the buffer head timestamp.
224         pthread_mutex_t m_framecounter_lock;
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                      
248         virtual enum raw1394_iso_disposition putPacket(unsigned char *data, unsigned int length,
249                       unsigned char channel, unsigned char tag, unsigned char sy,
250                           unsigned int cycle, unsigned int dropped) = 0;
251         virtual void setVerboseLevel(int l);
252
253 protected:
254
255      DECLARE_DEBUG_MODULE;
256
257 };
258
259 /*!
260 \brief Class providing a generic interface for receive Stream Processors
261
262 */
263 class TransmitStreamProcessor : public StreamProcessor {
264
265 public:
266         TransmitStreamProcessor(int port, int framerate);
267
268         virtual ~TransmitStreamProcessor();
269
270         virtual enum EProcessorType getType() {return E_Transmit;};
271
272         virtual enum raw1394_iso_disposition
273                 putPacket(unsigned char *data, unsigned int length,
274                       unsigned char channel, unsigned char tag, unsigned char sy,
275                           unsigned int cycle, unsigned int dropped) {return RAW1394_ISO_STOP;};
276                          
277         virtual enum raw1394_iso_disposition
278                 getPacket(unsigned char *data, unsigned int *length,
279                       unsigned char *tag, unsigned char *sy,
280                       int cycle, unsigned int dropped, unsigned int max_length) = 0;
281         virtual void setVerboseLevel(int l);
282
283 protected:
284
285      DECLARE_DEBUG_MODULE;
286
287
288 };
289
290 }
291
292 #endif /* __FREEBOB_STREAMPROCESSOR__ */
293
294
Note: See TracBrowser for help on using the browser.