this repo has no description
1/* Copyright: � Copyright 2005 Apple Computer, Inc. All rights reserved.
2
3 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
4 ("Apple") in consideration of your agreement to the following terms, and your
5 use, installation, modification or redistribution of this Apple software
6 constitutes acceptance of these terms. If you do not agree with these terms,
7 please do not use, install, modify or redistribute this Apple software.
8
9 In consideration of your agreement to abide by the following terms, and subject
10 to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
11 copyrights in this original Apple software (the "Apple Software"), to use,
12 reproduce, modify and redistribute the Apple Software, with or without
13 modifications, in source and/or binary forms; provided that if you redistribute
14 the Apple Software in its entirety and without modifications, you must retain
15 this notice and the following text and disclaimers in all such redistributions of
16 the Apple Software. Neither the name, trademarks, service marks or logos of
17 Apple Computer, Inc. may be used to endorse or promote products derived from the
18 Apple Software without specific prior written permission from Apple. Except as
19 expressly stated in this notice, no other rights or licenses, express or implied,
20 are granted by Apple herein, including but not limited to any patent rights that
21 may be infringed by your derivative works or by other works in which the Apple
22 Software may be incorporated.
23
24 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
25 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
26 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
28 COMBINATION WITH YOUR PRODUCTS.
29
30 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
32 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
34 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
35 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
36 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37*/
38/*=============================================================================
39 CABufferQueue.h
40
41=============================================================================*/
42
43#ifndef __CABufferQueue_h__
44#define __CABufferQueue_h__
45
46#include "CAPThread.h"
47#include "CAGuard.h"
48#include "CAStreamBasicDescription.h"
49#include "CABufferList.h"
50#include <list>
51#include "CAAtomicStack.h"
52
53// ____________________________________________________________________________
54
55// Abstraction for moving audio buffers between threads.
56// Has abstract subclasses for push and pull.
57class CABufferQueue {
58 friend class CAPushBufferQueue;
59 friend class CAPullBufferQueue;
60public:
61 CABufferQueue(int nBuffers, UInt32 bufferSizeFrames);
62 virtual ~CABufferQueue();
63
64 void SetFormat(const CAStreamBasicDescription &fmt);
65 UInt32 GetBufferSizeFrames() const { return mBufferSizeFrames; }
66 int ErrorCount() const { return mErrorCount; }
67
68 // -----
69 class Buffer {
70 public:
71 Buffer(CABufferQueue *owner, const CAStreamBasicDescription &fmt, UInt32 nBytes);
72
73 ~Buffer() { delete mMemory; }
74
75 CABufferQueue * Queue() { return mQueue; }
76 CABufferList * GetBufferList() { return mMemory; }
77 UInt32 FrameCount() { return mEndFrame - mStartFrame; }
78 void SetEmpty() { mStartFrame = mEndFrame = 0; }
79
80 void SetInProgress(bool b) { mInProgress = b; }
81 bool InProgress() const { return mInProgress; }
82 bool ReachedEndOfStream() const { return mEndOfStream; }
83
84 bool CopyInto(AudioBufferList *destBufferList, int bytesPerFrame, UInt32 &framesProduced, UInt32 &framesRequired); // return true if buffer emptied
85
86 bool CopyFrom(const AudioBufferList *srcBufferList, int bytesPerFrame, UInt32 &framesProduced, UInt32 &framesRequired); // return true if buffer filled and not end-of-stream
87
88 Buffer * get_next() { return mNext; }
89 void set_next(Buffer *b) { mNext = b; }
90 Buffer *& next() { return mNext; }
91
92#if DEBUG
93 void print() {
94 printf("Buffer %p:\n inProgress %d, endOfStream %d, frames %ld-%ld\n", this, mInProgress, mEndOfStream, mStartFrame, mEndFrame);
95 }
96#endif
97
98 protected:
99 Buffer * mNext;
100 CABufferQueue * mQueue;
101 CABufferList * mMemory;
102 UInt32 mByteSize;
103
104 bool mInProgress; // true if in the work queue
105 bool mEndOfStream; // true if the operation resulted in end-of-stream
106 UInt32 mStartFrame, mEndFrame; // produce/consume pointers within the buffer
107 };
108
109#if DEBUG
110 void print() {
111 printf("BufferQueue %p\n mCurrentBuffer=%d\n", this, mCurrentBuffer);
112 if (mBuffers)
113 for (int i = 0; i < mNumberBuffers; ++i) {
114 Buffer *b = mBuffers[i];
115 printf(" buffer[%d]: ", i);
116 if (b)
117 b->print();
118 else printf("NULL\n");
119 }
120 }
121#endif
122
123protected:
124 virtual Buffer * CreateBuffer(const CAStreamBasicDescription &fmt, UInt32 nBytes) = 0;
125 virtual void ProcessBuffer(Buffer *b) = 0;
126 void CancelBuffers();
127 void CancelAndDisposeBuffers();
128
129 CABufferList * GetBufferList() { return mBufferList; }
130 const Buffer * GetCurrentBuffer() const { return mBuffers[mCurrentBuffer]; }
131 UInt32 GetBytesPerFrame() const { return mBytesPerFrame; }
132
133private:
134
135 // -----
136 class WorkThread : public CAPThread {
137 public:
138 WorkThread();
139
140 static void * ThreadEntry(void *param)
141 {
142 static_cast<WorkThread *>(param)->Run();
143 return NULL;
144 }
145 void Run();
146 void Stop();
147
148 void AddBuffer(Buffer *buffer);
149 void RemoveBuffers(CABufferQueue *owner);
150
151 private:
152 typedef std::list<Buffer *> WorkQueue;
153
154 bool mStopped;
155 WorkQueue mWorkQueue;
156 CAGuard mRunGuard;
157 TAtomicStack<Buffer> mBuffersToAdd;
158 };
159
160 static WorkThread * sWorkThread;
161
162 // -----
163private:
164 WorkThread * mWorkThread;
165
166 int mCurrentBuffer;
167 int mNumberBuffers;
168 Buffer ** mBuffers; // array of pointers
169 UInt32 mBufferSizeFrames;
170 UInt32 mBytesPerFrame; // function of client format
171 CABufferList * mBufferList; // maintained in SetFormat
172protected:
173 int mErrorCount;
174};
175
176// ____________________________________________________________________________
177
178// Abstract class.
179// The client pushes buffers in; they are consumed (via ProcessBuffer) on the work thread.
180// (ex: file recorder)
181class CAPushBufferQueue : public CABufferQueue {
182public:
183 CAPushBufferQueue(int nBuffers, UInt32 bufferSizeFrames) :
184 CABufferQueue(nBuffers, bufferSizeFrames) { }
185
186 void PushBuffer(UInt32 inNumberFrames, const AudioBufferList *inBufferList);
187 // push a buffer in
188 void Flush();
189 // emit a possibly incomplete final buffer
190};
191
192// ____________________________________________________________________________
193
194// Abstract class.
195// The client pulls buffers out; they are produced (via ProcessBuffer) on the work thread.
196// (ex: file player)
197class CAPullBufferQueue : public CABufferQueue {
198public:
199 CAPullBufferQueue(int nBuffers, UInt32 bufferSizeFrames) :
200 CABufferQueue(nBuffers, bufferSizeFrames),
201 mEndOfStream(false) { }
202
203 void Prime();
204 // produce initial buffers
205 void PullBuffer(UInt32 &ioFrames, AudioBufferList *outBufferList);
206 // pull a buffer out
207 bool ReachedEndOfStream() const { return mEndOfStream; }
208
209protected:
210 bool mEndOfStream;
211};
212
213#endif // __CABufferQueue_h__