1 /*
2 File: ACCodec.cpp
3 Abstract: ACCodec.h
4 Version: 1.1
5
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
7 Inc. ("Apple") in consideration of your agreement to the following
8 terms, and your use, installation, modification or redistribution of
9 this Apple software constitutes acceptance of these terms. If you do
10 not agree with these terms, please do not use, install, modify or
11 redistribute this Apple software.
12
13 In consideration of your agreement to abide by the following terms, and
14 subject to these terms, Apple grants you a personal, non-exclusive
15 license, under Apple's copyrights in this original Apple software (the
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple
17 Software, with or without modifications, in source and/or binary forms;
18 provided that if you redistribute the Apple Software in its entirety and
19 without modifications, you must retain this notice and the following
20 text and disclaimers in all such redistributions of the Apple Software.
21 Neither the name, trademarks, service marks or logos of Apple Inc. may
22 be used to endorse or promote products derived from the Apple Software
23 without specific prior written permission from Apple. Except as
24 expressly stated in this notice, no other rights or licenses, express or
25 implied, are granted by Apple herein, including but not limited to any
26 patent rights that may be infringed by your derivative works or by other
27 works in which the Apple Software may be incorporated.
28
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42 POSSIBILITY OF SUCH DAMAGE.
43
44 Copyright (C) 2014 Apple Inc. All Rights Reserved.
45
46 */
47 //=============================================================================
48 // Includes
49 //=============================================================================
50
51 #include "ACCodec.h"
52
53 //=============================================================================
54 // ACCodec
55 //=============================================================================
56
ACCodec(AudioComponentInstance inInstance)57 ACCodec::ACCodec(AudioComponentInstance inInstance) : ComponentBase(inInstance)
58 {
59 }
60
~ACCodec()61 ACCodec::~ACCodec()
62 {
63 }
64
65 #if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_IPHONE
66
67 #if TARGET_OS_MAC
68 #if __LP64__
69 // comp instance, parameters in forward order
70 #define PARAM(_typ, _name, _index, _nparams) \
71 _typ _name = *(_typ *)((void*)&inParameters->params[_index + 1]);
72 #else
73 // parameters in reverse order, then comp instance
74 #define PARAM(_typ, _name, _index, _nparams) \
75 _typ _name = *(_typ *)((void*)&inParameters->params[_nparams - 1 - _index]);
76 #endif
77 #elif TARGET_OS_WIN32
78 // (no comp instance), parameters in forward order
79 #define PARAM(_typ, _name, _index, _nparams) \
80 _typ _name = *(_typ *)&inParameters->params[_index];
81 #endif
82
ComponentEntryDispatch(ComponentParameters * inParameters,ACCodec * inThis)83 OSStatus ACCodec::ComponentEntryDispatch(ComponentParameters *inParameters, ACCodec *inThis)
84 {
85 OSStatus theError = kAudioCodecNoError;
86
87 try
88 {
89 switch (inParameters->what)
90 {
91 // these selectors don't use the object pointer
92
93 case kComponentOpenSelect:
94 case kComponentCloseSelect:
95 theError = ComponentBase::ComponentEntryDispatch(inParameters, inThis);
96 break;
97
98 case kComponentCanDoSelect:
99 {
100 switch (GetSelectorForCanDo(inParameters))
101 {
102 case kAudioCodecGetPropertyInfoSelect:
103 case kAudioCodecGetPropertySelect:
104 case kAudioCodecSetPropertySelect:
105 case kAudioCodecInitializeSelect:
106 case kAudioCodecUninitializeSelect: // was missing -- why?
107 case kAudioCodecAppendInputDataSelect:
108 case kAudioCodecProduceOutputDataSelect:
109 case kAudioCodecResetSelect:
110 theError = 1;
111 break;
112 default:
113 theError = ComponentBase::ComponentEntryDispatch(inParameters, inThis);
114 break;
115 }
116 }
117 break;
118
119 default:
120 // these selectors use the object pointer
121 if(inThis != NULL)
122 {
123 switch (inParameters->what)
124 {
125 case kComponentVersionSelect:
126 theError = inThis->Version();
127 break;
128
129 case kAudioCodecGetPropertyInfoSelect:
130 {
131 PARAM(AudioCodecPropertyID, inPropertyID, 0, 3);
132 PARAM(UInt32 *, outSize, 1, 3);
133 PARAM(Boolean *, outWritable, 2, 3);
134
135 UInt32 theSize = 0;
136 Boolean isWritable = false;
137
138 inThis->GetPropertyInfo(inPropertyID, theSize, isWritable);
139 if(outSize != NULL)
140 {
141 *outSize = theSize;
142 }
143 if(outWritable != NULL)
144 {
145 *outWritable = isWritable ? 1 : 0;
146 }
147 }
148 break;
149
150 case kAudioCodecGetPropertySelect:
151 {
152 PARAM(AudioCodecPropertyID, inPropertyID, 0, 3);
153 PARAM(UInt32 *, ioPropertyDataSize, 1, 3);
154 PARAM(void *, outPropertyData, 2, 3);
155
156 if((ioPropertyDataSize != NULL) && (outPropertyData != NULL))
157 {
158 inThis->GetProperty(inPropertyID, *ioPropertyDataSize, outPropertyData);
159 }
160 else
161 {
162 theError = kAudio_ParamError;
163 }
164 }
165 break;
166
167 case kAudioCodecSetPropertySelect:
168 {
169 PARAM(AudioCodecPropertyID, inPropertyID, 0, 3);
170 PARAM(UInt32, inPropertyDataSize, 1, 3);
171 PARAM(const void *, inPropertyData, 2, 3);
172
173 if(inPropertyData != NULL)
174 {
175 inThis->SetProperty(inPropertyID, inPropertyDataSize, inPropertyData);
176 }
177 else
178 {
179 theError = kAudio_ParamError;
180 }
181 }
182 break;
183
184 case kAudioCodecInitializeSelect:
185 {
186 PARAM(const AudioStreamBasicDescription *, inInputFormat, 0, 4);
187 PARAM(const AudioStreamBasicDescription *, inOutputFormat, 1, 4);
188 PARAM(const void *, inMagicCookie, 2, 4);
189 PARAM(UInt32, inMagicCookieByteSize, 3, 4);
190
191 inThis->Initialize(inInputFormat, inOutputFormat, inMagicCookie, inMagicCookieByteSize);
192 }
193 break;
194
195 case kAudioCodecUninitializeSelect:
196 {
197 inThis->Uninitialize();
198 }
199 break;
200
201 case kAudioCodecAppendInputDataSelect:
202 {
203 PARAM(const void *, inInputData, 0, 4);
204 PARAM(UInt32 *, ioInputDataByteSize, 1, 4);
205 PARAM(UInt32 *, ioNumberPackets, 2, 4);
206 PARAM(const AudioStreamPacketDescription *, inPacketDescription, 3, 4);
207
208 if((inInputData != NULL) && (ioInputDataByteSize != NULL))
209 {
210 if(ioNumberPackets != NULL)
211 {
212 inThis->AppendInputData(inInputData, *ioInputDataByteSize, *ioNumberPackets, inPacketDescription);
213 }
214 else
215 {
216 UInt32 theNumberPackets = 0;
217 inThis->AppendInputData(inInputData, *ioInputDataByteSize, theNumberPackets, inPacketDescription);
218 }
219 }
220 else
221 {
222 theError = kAudio_ParamError;
223 }
224 }
225 break;
226
227 case kAudioCodecProduceOutputDataSelect:
228 {
229 PARAM(void *, outOutputData, 0, 5);
230 PARAM(UInt32 *, ioOutputDataByteSize, 1, 5);
231 PARAM(UInt32 *, ioNumberPackets, 2, 5);
232 PARAM(AudioStreamPacketDescription *, outPacketDescription, 3, 5);
233 PARAM(UInt32 *, outStatus, 4, 5);
234
235 if((outOutputData != NULL) && (ioOutputDataByteSize != NULL) && (ioNumberPackets != NULL) && (outStatus != NULL))
236 {
237 *outStatus = inThis->ProduceOutputPackets(outOutputData, *ioOutputDataByteSize, *ioNumberPackets, outPacketDescription);
238 if(kAudioCodecProduceOutputPacketFailure == *outStatus)
239 {
240 theError = kAudio_ParamError;
241 }
242 }
243 else
244 {
245 theError = kAudio_ParamError;
246 }
247 }
248 break;
249
250 #if AC_NON_INTERLEAVED_SUPPORT
251 case kAudioCodecAppendInputBufferListSelect:
252 {
253 PARAM(const AudioBufferList *, inBufferList, 0, 4);
254 PARAM(UInt32 *, ioNumberPackets, 1, 4);
255 PARAM(const AudioStreamPacketDescription *, inPacketDescription, 2, 4);
256 PARAM(UInt32 *, outBytesConsumed, 3, 4);
257
258 if((inBufferList != NULL) && (outBytesConsumed != NULL))
259 {
260 if(ioNumberPackets != NULL)
261 {
262 inThis->AppendInputBufferList(inBufferList, *ioNumberPackets, inPacketDescription, outBytesConsumed);
263 }
264 else
265 {
266 UInt32 theNumberPackets = 0;
267 inThis->AppendInputBufferList(inBufferList, theNumberPackets, inPacketDescription, outBytesConsumed);
268 }
269 }
270 else
271 {
272 theError = kAudio_ParamError;
273 }
274 }
275 break;
276
277 case kAudioCodecProduceOutputBufferListSelect:
278 {
279 PARAM(AudioBufferList *, ioBufferList, 0, 4);
280 PARAM(UInt32 *, ioNumberPackets, 1, 4);
281 PARAM(AudioStreamPacketDescription *, outPacketDescription, 2, 4);
282 PARAM(UInt32 *, outStatus, 3, 4);
283
284 if((ioBufferList != NULL) && (ioNumberPackets != NULL) && (outStatus != NULL))
285 {
286 *outStatus = inThis->ProduceOutputBufferList(ioBufferList, *ioNumberPackets, outPacketDescription);
287 if(kAudioCodecProduceOutputPacketFailure == *outStatus)
288 {
289 theError = kAudio_ParamError;
290 }
291 }
292 else
293 {
294 theError = kAudio_ParamError;
295 }
296 }
297 break;
298 #endif // AC_NON_INTERLEAVED_SUPPORT
299
300 case kAudioCodecResetSelect:
301 {
302 inThis->Reset();
303 }
304 break;
305
306 default:
307 theError = badComponentSelector;
308 break;
309 };
310 }
311 else
312 {
313 theError = kAudio_ParamError;
314 }
315 break;
316 };
317 }
318 catch(OSStatus inErrorCode)
319 {
320 theError = inErrorCode;
321 }
322 catch(...)
323 {
324 theError = kAudioCodecUnspecifiedError;
325 }
326
327 return theError;
328 }
329 #endif // !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_IPHONE
330