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