source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_decoder.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 95.8 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bape_decoder.c $
11 * $brcm_Revision: Hydra_Software_Devel/87 $
12 * $brcm_Date: 3/8/12 5:08p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_decoder.c $
19 *
20 * Hydra_Software_Devel/87   3/8/12 5:08p gskerl
21 * SW7429-18: Rearranged code so that BAPE_InputPort_P_AttachConsumer() is
22 * called before accessing the InputPort format fields.
23 *
24 * Hydra_Software_Devel/86   3/8/12 10:56a jgarrett
25 * SW7435-24: Adding DSP index for decode and dsp mixer
26 *
27 * Hydra_Software_Devel/85   3/7/12 4:35p jgarrett
28 * SW7435-24: Adding DSP index for decode and dsp mixer
29 *
30 * Hydra_Software_Devel/84   2/23/12 4:26p gskerl
31 * SW7429-18: Added 7429 SPDIF input support. Use saved audio format from
32 * handle instead of from PathConnector.
33 *
34 * Hydra_Software_Devel/84   2/23/12 4:21p gskerl
35 * SW7429-18: Added 7429 SPDIF input support. Use saved audio format from
36 * handle instead of from PathConnector.
37 *
38 * Hydra_Software_Devel/83   2/21/12 6:41p jgarrett
39 * SW7231-363: Correctly recovering if StartTask fails.  Propagating
40 * compressed connector format properly
41 *
42 * Hydra_Software_Devel/82   2/17/12 4:13p jgarrett
43 * SW7425-2262: Adding API to enter Non-Realtime Gap Fill mode
44 *
45 * Hydra_Software_Devel/81   2/9/12 5:44p jgarrett
46 * SW7425-2074: Failing gracefully if PCM 5.1/7.1 is requested as input
47 * for HDMI
48 *
49 * Hydra_Software_Devel/80   2/9/12 11:21a jgarrett
50 * SW7425-2074: Enabling input halt and revising MAI shutown for
51 * multichannel PCM
52 *
53 * Hydra_Software_Devel/79   2/3/12 4:29p jgarrett
54 * SW7425-2268: Initial bringup of voice conferencing support
55 *
56 * Hydra_Software_Devel/78   2/2/12 12:14p gskerl
57 * SW7429-18: Added BAPE_Decoder_P_InputFormatChange_isr() callback to
58 * stop decoding when the input port detects a format change.
59 *
60 * Hydra_Software_Devel/77   1/31/12 6:17p jgarrett
61 * SW7425-2268: Adding initial voice conferencing support
62 *
63 * Hydra_Software_Devel/76   1/13/12 3:12p gskerl
64 * SW7429-18: Added 7429 support for MAI input.
65 *
66 * Hydra_Software_Devel/75   12/29/11 1:14p jgarrett
67 * SW7231-500: Adding IEEE-1394 LPCM
68 *
69 * Hydra_Software_Devel/74   12/19/11 4:27p jgarrett
70 * SW7425-1018: Adding initial A/85 implementation
71 *
72 * Hydra_Software_Devel/73   12/15/11 3:29p jgarrett
73 * SW7425-1756: Disabling status ready interrupt after it fires once.
74 *
75 * Hydra_Software_Devel/72   12/15/11 3:22p jgarrett
76 * SW7231-500: Converting framesync settings from struct to union
77 *
78 * Hydra_Software_Devel/71   12/9/11 5:50p jgarrett
79 * SW7425-1756: Adding debug and correcting some ISR callbacks
80 *
81 * Hydra_Software_Devel/70   11/21/11 11:44a jgarrett
82 * SW7425-1756: Adding overflow and status ready interrupts
83 *
84 * Hydra_Software_Devel/69   11/14/11 3:40p gskerl
85 * SW7429-18: Merging 7429 changes back to main branch.
86 *
87 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
88 * SW7429-18: Initial compileable version for 7429
89 *
90 * Hydra_Software_Devel/68   9/27/11 5:36p jgarrett
91 * SW7425-1352: Adding STCValid debug prints
92 *
93 * Hydra_Software_Devel/67   9/15/11 9:24a jgarrett
94 * SW7425-1285: Sending lower 32-bits of STC to DSP on systems with 42-bit
95 * STC support
96 *
97 * Hydra_Software_Devel/66   9/14/11 6:58p jgarrett
98 * SW7425-1045: Adding unmapped settings and status values for some
99 * decoder algorithms
100 *
101 * Hydra_Software_Devel/65   9/8/11 10:42a jgarrett
102 * SWDTV-6627: Adding BAPE_Equalizer_GetDefaultSettings stub for chips
103 * w/out EQ support
104 *
105 * Hydra_Software_Devel/64   8/25/11 12:20p jgarrett
106 * SW7231-295: Propagating PPM correction setting to DSP Task
107 *
108 * Hydra_Software_Devel/63   8/22/11 7:03p jgarrett
109 * SWDTV-8271: Adding low delay mode support
110 *
111 * Hydra_Software_Devel/61   8/12/11 7:05p sgadara
112 * SWDTV-6584: [35233] Reorganize Input port FCI id extraction
113 *
114 * Hydra_Software_Devel/60   8/12/11 4:19p venkatr
115 * SWDTV-6584 : [35233] ADC input code cleanup
116 *
117 * Hydra_Software_Devel/59   8/11/11 6:24p jgarrett
118 * SWDTV-6305: Setting RF I2S input as I2S 1
119 *
120 * Hydra_Software_Devel/58   8/10/11 9:29a venkatr
121 * SWDTV-6584 : [35233] Add ADC Input for APE
122 *
123 * Hydra_Software_Devel/57   8/8/11 6:01p jgarrett
124 * SW7346-412: Marking PTS as invalid if DSP is not ready
125 *
126 * Hydra_Software_Devel/56   7/18/11 4:13p jgarrett
127 * SW7425-910: Correcting passthrough FMM programming for LSF/QSF sources
128 *
129 * Hydra_Software_Devel/55   7/11/11 6:57p jgarrett
130 * SW7425-64: Updating sample rate handling for new callback
131 *
132 * Hydra_Software_Devel/54   7/8/11 4:52p gskerl
133 * SW7425-321: Added printing of downstream nodes when an audio path is
134 * started (if bape_startprint is enabled)
135 *
136 * Hydra_Software_Devel/53   7/6/11 4:55p jgarrett
137 * SW7358-62: Storing a local copy of the XptContextMap structure
138 *
139 * Hydra_Software_Devel/52   7/1/11 9:59a jgarrett
140 * SW7405-5072: Adding WMA TS Support
141 *
142 * Hydra_Software_Devel/51   6/29/11 5:00p jgarrett
143 * SW7425-620: Allowing multichannel/compressed outputs from a decoder to
144 * override to PCM if the codec does not support multichannel/compressed
145 * output
146 *
147 * Hydra_Software_Devel/50   6/28/11 11:08a jgarrett
148 * SW7425-654: Adding AAC passthrough remux configuration
149 *
150 * Hydra_Software_Devel/49   6/27/11 5:41p jgarrett
151 * SW7231-97: Refactoring SPDIF/HDMI enable mechanisms to handle older
152 * Onkyo receiver DTS->PCM switching requirements
153 *
154 * Hydra_Software_Devel/48   6/27/11 8:27a jgarrett
155 * SW7425-654: Merging NRT to main line
156 *
157 * Hydra_Software_Devel/NRT_XCODE_DEVEL/1   6/21/11 5:54p jgarrett
158 * SW7425-654: Adding NRT hooks
159 *
160 * Hydra_Software_Devel/47   6/21/11 3:50p jgarrett
161 * SW7425-654: Adding NRT APIs to decoder and mux
162 *
163 * Hydra_Software_Devel/46   6/20/11 3:58p jgarrett
164 * SW7425-408: Adding MS usage case restriction regarding AAC-HE simul
165 * passthrough due to sample rate conversion in the decoder
166 *
167 * Hydra_Software_Devel/45   6/16/11 6:40p jgarrett
168 * SW7422-456: Always applying TSM settings even if task is not started
169 * yet.
170 *
171 * Hydra_Software_Devel/44   6/16/11 11:01a gskerl
172 * SW7425-321: Added call to BAPE_Mixer_P_PrintMixers() just before
173 * starting paths
174 *
175 * Hydra_Software_Devel/43   5/27/11 4:56p jgarrett
176 * SW7425-408: Propagating decoder settings for AAC/AC3 to DDRE in MS11
177 * usage modes
178 *
179 * Hydra_Software_Devel/42   5/26/11 6:10p jgarrett
180 * SW7425-408: Making generic passthru optional
181 *
182 * Hydra_Software_Devel/41   5/5/11 5:52p jgarrett
183 * SW7425-522: Returning error on unsupported trick rates
184 *
185 * Hydra_Software_Devel/40   4/27/11 6:10p jgarrett
186 * SW7344-48: Flipping CDB LittleEndian flag in Big Endian
187 *
188 * Hydra_Software_Devel/39   4/19/11 5:33p jgarrett
189 * SW7422-408: Adding additional codecs
190 *
191 * Hydra_Software_Devel/38   4/19/11 11:05a jgarrett
192 * SW7344-46: Fixing multichannel support test
193 *
194 * Hydra_Software_Devel/37   4/18/11 10:09p jgarrett
195 * SW7425-361: Refactoring DSP branch decisions
196 *
197 * Hydra_Software_Devel/36   4/17/11 1:55p jgarrett
198 * SW7425-288: Adding audio codec to metadata
199 *
200 * Hydra_Software_Devel/35   4/17/11 12:28p jgarrett
201 * SW7344-46: Adding error checking for license issues and attempts to
202 * enable unsupported features
203 *
204 * Hydra_Software_Devel/34   4/16/11 12:15p jgarrett
205 * SW7425-371: Removing tab characters
206 *
207 * Hydra_Software_Devel/33   4/6/11 1:23a jgarrett
208 * SW35330-35: Merge to main branch
209 *
210 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:49p jgarrett
211 * SW35330-35: FMM Abstraction refactoring to support DTV
212 *
213 * Hydra_Software_Devel/32   3/27/11 12:19p piyushg
214 * SW7422-364: Reading the correct MAI FORMAT register.
215 *
216 * Hydra_Software_Devel/31   3/24/11 5:25p jgarrett
217 * SW7422-146: Fixes for kernel mode and big endian
218 *
219 * Hydra_Software_Devel/30   3/23/11 4:29p jgarrett
220 * SW7422-403: Removing error return when dsola is requested with
221 * compressed/multichannel outputs
222 *
223 * Hydra_Software_Devel/30   3/23/11 3:48p jgarrett
224 * SW7422-403: Not failing for DSOLA request with Compressed/Multichannel
225 * out
226 *
227 * Hydra_Software_Devel/29   3/23/11 11:04a piyushg
228 * SW7422-146: Fixing compilation errors.
229 *
230 * Hydra_Software_Devel/28   3/22/11 6:27p jgarrett
231 * SW7422-401: Fixing implementation of DisableForFlush and Flush
232 *
233 * Hydra_Software_Devel/27   3/21/11 7:08p jgarrett
234 * SW7422-356: Adding MuxOutput
235 *
236 * Hydra_Software_Devel/26   3/18/11 6:12p gskerl
237 * SW7422-146: Changed audio input connector callbacks to take the connect
238 * handle as an argument
239 *
240 * Hydra_Software_Devel/26   3/18/11 6:04p gskerl
241 * SW7422-146: Changed audio input connector callbacks to take the connect
242 * handle as an argument
243 *
244 * Hydra_Software_Devel/25   3/14/11 6:03p jgarrett
245 * SW7422-146: Disabling PPM correction for external input sources
246 *
247 * Hydra_Software_Devel/24   3/11/11 6:02p jgarrett
248 * SW7422-146: Decoder supports external inputs
249 *
250 * Hydra_Software_Devel/23   3/11/11 12:20p jgarrett
251 * SW7422-146: Enabling PPM Correction
252 *
253 * Hydra_Software_Devel/22   3/9/11 2:54p jgarrett
254 * SW7422-146: Fixing SRC lockup with decode stop/start
255 *
256 * Hydra_Software_Devel/21   3/3/11 6:31p jgarrett
257 * SW7422-146: Adding SRC and DSOLA and path review feedback
258 *
259 * Hydra_Software_Devel/20   3/1/11 5:13p jgarrett
260 * SW7422-146: Fixing post-processing output modes
261 *
262 * Hydra_Software_Devel/19   2/28/11 5:15p jgarrett
263 * SW7422-146: Fixing passthrough config for DDP
264 *
265 * Hydra_Software_Devel/18   2/28/11 1:28p jgarrett
266 * SW7422-146: Filter graph reworked to remove mixer dependencies
267 *
268 * Hydra_Software_Devel/17   2/22/11 5:43p jgarrett
269 * SW7422-146: Implemented type renaming based on filter graph review
270 * comments
271 *
272 * Hydra_Software_Devel/16   2/16/11 3:04p jgarrett
273 * SW7422-146: Coverity CID 255
274 *
275 * Hydra_Software_Devel/15   2/15/11 4:07p jgarrett
276 * SW7422-146: Adding additional codec settings and types
277 *
278 * Hydra_Software_Devel/14   2/7/11 11:30a jgarrett
279 * SW7422-146: Implementing DDP -> AC3 conversion and status for
280 * MPEG/AAC/AC3
281 *
282 * Hydra_Software_Devel/13   2/2/11 6:06p jgarrett
283 * SW7422-146: Fixing arguments to simul branches
284 *
285 * Hydra_Software_Devel/12   2/2/11 4:01p jgarrett
286 * SW7422-146: Switching converter data type to auxiliary
287 *
288 * Hydra_Software_Devel/11   2/2/11 2:17p jgarrett
289 * SW7422-146: Adding decoder status placeholder
290 *
291 * Hydra_Software_Devel/10   2/1/11 5:41p jgarrett
292 * SW7422-146: Added MPEG support
293 *
294 * Hydra_Software_Devel/9   2/1/11 5:01p jgarrett
295 * SW7422-146: Adding AAC and Generic Passthrough
296 *
297 * Hydra_Software_Devel/8   1/28/11 3:38p jgarrett
298 * SW7422-146: Adding support for simul handling of DDP/WMA-Pro/Generic
299 *
300 * Hydra_Software_Devel/7   1/27/11 5:47p jgarrett
301 * SW7422-146: Adding support for multichannel and ac3 user parameters
302 *
303 * Hydra_Software_Devel/6   1/19/11 6:50p jgarrett
304 * SW7422-146: Fixing computation of number of source paths
305 *
306 * Hydra_Software_Devel/5   1/19/11 6:13p jgarrett
307 * SW7422-146: Enabling TSM
308 *
309 * Hydra_Software_Devel/4   1/19/11 2:58p jgarrett
310 * SW7422-146: Initial decode/passthrough of ac3
311 *
312 * Hydra_Software_Devel/3   1/12/11 4:24p jgarrett
313 * SW7422-146: Adding additional APIs
314 *
315 * Hydra_Software_Devel/2   12/17/10 3:58p jgarrett
316 * SW7422-146: Nexus APE integration on 7422
317 *
318 * Hydra_Software_Devel/1   12/16/10 4:04p jgarrett
319 * SW7422-146: Initial compilable APE for 7422
320 *
321 ***************************************************************************/
322
323#include "bstd.h"
324#include "bkni.h"
325#include "bape.h"
326#include "bape_priv.h"
327#include "bchp_aud_fmm_bf_ctrl.h"
328#include "bdsp_raaga.h"
329
330BDBG_MODULE(bape_decoder);
331
332BDBG_OBJECT_ID(BAPE_Decoder);
333
334#define BAPE_DISABLE_DSP 0  /* Enable this to check for CIT errors and avoid starting the DSP */
335
336static void BAPE_Decoder_P_SetupDefaults(BAPE_DecoderHandle handle);
337static void BAPE_Decoder_P_ConvertTsmStatus_isr(BAPE_DecoderTsmStatus *pStatus, const BDSP_AudioTaskTsmStatus *pDspStatus);
338static void BAPE_Decoder_P_FirstPts_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus);
339static void BAPE_Decoder_P_TsmFail_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus);
340static void BAPE_Decoder_P_TsmPass_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus);
341static void BAPE_Decoder_P_SampleRateChange_isr(void *pParam1, int param2, unsigned streamSampleRate, unsigned baseSampleRate);
342static void BAPE_Decoder_P_ModeChange_isr(void *pParam1, int param2, unsigned mode);
343static void BAPE_Decoder_P_BitrateChange_isr(void *pParam1, int param2, const BDSP_AudioBitRateChangeInfo *pInfo);
344static void BAPE_Decoder_P_Overflow_isr(void *pParam1, int param2);
345static void BAPE_Decoder_P_StatusReady_isr(void *pParam1, int param2);
346static BERR_Code BAPE_Decoder_P_InputFormatChange_isr(BAPE_PathNode *pNode,BAPE_InputPort inputPort);
347static void BAPE_Decoder_P_CleanupTaskCreateSetings(BAPE_DecoderHandle handle);
348static BERR_Code BAPE_Decoder_P_ApplyDsolaSettings(BAPE_DecoderHandle handle);
349static BERR_Code BAPE_Decoder_P_ApplyFramesyncSettings(BAPE_DecoderHandle handle);
350static BERR_Code BAPE_Decoder_P_Start(BAPE_DecoderHandle handle);
351static void BAPE_Decoder_P_Stop(BAPE_DecoderHandle handle);
352static bool BAPE_Decoder_P_TaskValid_isr(BAPE_DecoderHandle handle);
353static BERR_Code BAPE_Decoder_P_DeriveMultistreamLinkage(BAPE_DecoderHandle handle);
354
355void BAPE_Decoder_GetDefaultOpenSettings(
356    BAPE_DecoderOpenSettings *pSettings     /* [out] */
357    )
358{
359    BDBG_ASSERT(NULL != pSettings);
360    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
361}
362
363BERR_Code BAPE_Decoder_Open(
364    BAPE_Handle deviceHandle,
365    unsigned index,
366    const BAPE_DecoderOpenSettings *pSettings, 
367    BAPE_DecoderHandle *pHandle                 /* [out] */
368    )
369{
370    BAPE_DecoderOpenSettings defaults;
371    BAPE_DecoderHandle handle;
372
373    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
374
375    if ( NULL == pSettings )
376    {
377        BAPE_Decoder_GetDefaultOpenSettings(&defaults);
378        pSettings = &defaults;
379    }
380
381    if ( index >= BAPE_CHIP_MAX_DECODERS )
382    {
383        BDBG_ERR(("This chip only supports %u decoders.  Cannot open decoder %u", BAPE_CHIP_MAX_DECODERS, index));
384        return BERR_TRACE(BERR_INVALID_PARAMETER);
385    }
386
387    if ( deviceHandle->decoders[index] )
388    {
389        BDBG_ERR(("Decoder %d already open", index));
390        return BERR_TRACE(BERR_INVALID_PARAMETER);
391    }
392
393    if ( pSettings->dspIndex >= deviceHandle->numDsps )
394    {
395        BDBG_ERR(("DSP %u is not available.  This system has %u DSPs.", pSettings->dspIndex, deviceHandle->numDsps));
396        return BERR_TRACE(BERR_INVALID_PARAMETER);
397    }
398
399    handle = BKNI_Malloc(sizeof(BAPE_Decoder));
400    if ( NULL == handle )
401    {
402        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
403    }
404    BKNI_Memset(handle, 0, sizeof(BAPE_Decoder));
405    handle->deviceHandle = deviceHandle;
406    handle->index = index;
407    handle->dspIndex = pSettings->dspIndex;
408    BKNI_Snprintf(handle->name, sizeof(handle->name), "Decoder %u", index);
409    BAPE_P_InitPathNode(&handle->node, BAPE_PathNodeType_eDecoder, 0, 4, deviceHandle, handle);
410    handle->node.pName = handle->name;
411    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.dataSource = BAPE_DataSource_eDspBuffer;
412    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.numChannelPairs = 1;
413    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.useBufferPool = true;
414    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.pName = "stereo";
415    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.dataSource = BAPE_DataSource_eDspBuffer;
416    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 3;
417    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.useBufferPool = true;
418    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.pName = "multichannel";
419    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.dataSource = BAPE_DataSource_eDspBuffer;
420    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.numChannelPairs = 1;
421    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.compressed = true;
422    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.useBufferPool = true;
423    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.pName = "compressed";
424    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.dataSource = BAPE_DataSource_eDspBuffer;
425    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.numChannelPairs = 1;
426    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.mono = true;
427    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.useBufferPool = true;
428    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.pName = "mono";
429    /* Setup node callbacks */
430    handle->node.allocatePathToOutput = BAPE_DSP_P_AllocatePathToOutput;
431    handle->node.configPathToOutput = BAPE_DSP_P_ConfigPathToOutput;
432    handle->node.startPathToOutput = BAPE_DSP_P_StartPathToOutput;
433    handle->node.stopPathToOutput = BAPE_DSP_P_StopPathToOutput;
434    handle->node.inputPortFormatChange_isr = BAPE_Decoder_P_InputFormatChange_isr;
435    handle->state = BAPE_DecoderState_eStopped;
436    handle->settings.multichannelFormat = BAPE_MultichannelFormat_e5_1;
437    handle->settings.dualMonoMode = BAPE_DualMonoMode_eStereo;
438    handle->settings.outputMode = BAPE_ChannelMode_e3_2;
439    handle->settings.outputLfe = true;
440    handle->settings.decodeRate = BAPE_NORMAL_DECODE_RATE;
441    handle->settings.loudnessEquivalenceEnabled = true;
442    BAPE_Decoder_GetDefaultStartSettings(&handle->startSettings);
443    BDBG_OBJECT_SET(handle, BAPE_Decoder);
444    BAPE_Decoder_P_SetupDefaults(handle);
445
446    /* Success */
447    *pHandle = handle;
448    deviceHandle->decoders[index] = handle;
449    return BERR_SUCCESS;
450}
451
452void BAPE_Decoder_Close(
453    BAPE_DecoderHandle handle
454    )
455{
456    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
457
458    if ( handle->state != BAPE_DecoderState_eStopped )
459    {
460        BDBG_WRN(("Implicitly stopping decoder %u on shutdown.", handle->index));
461        BAPE_Decoder_Stop(handle);
462    }
463
464    /* Disconnect from all mixers, post-processors */
465    BAPE_Connector_P_RemoveAllConnections(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector);
466    BAPE_Connector_P_RemoveAllConnections(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector);
467    BAPE_Connector_P_RemoveAllConnections(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector);
468    BAPE_Connector_P_RemoveAllConnections(&handle->node.paths[BAPE_ConnectorFormat_eMono].connector);
469
470    /* Cleanup */
471    handle->deviceHandle->decoders[handle->index] = NULL;
472    BDBG_OBJECT_DESTROY(handle, BAPE_Decoder);
473    BKNI_Free(handle);
474}
475
476void BAPE_Decoder_GetDefaultStartSettings(
477    BAPE_DecoderStartSettings *pSettings    /* [out] */
478    )
479{
480    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
481    pSettings->codec = BAVC_AudioCompressionStd_eMax;
482    pSettings->streamType = BAVC_StreamType_eTsMpeg;
483    pSettings->ppmCorrection = true;
484}
485
486static BERR_Code BAPE_Decoder_P_ApplyDsolaSettings(
487    BAPE_DecoderHandle handle
488    )
489{
490    BDSP_Raaga_Audio_DsolaConfigParams userConfig;
491    BERR_Code errCode;
492    unsigned branch,stage;
493
494    if ( handle->startSettings.decodeRateControl && handle->task )
495    {
496        branch = handle->dsolaBranch;
497        stage = handle->dsolaStage;
498
499        errCode = BDSP_Task_GetStageSettings(handle->task, branch, stage, &userConfig, sizeof(userConfig));
500        if ( errCode )
501        {
502            return BERR_TRACE(errCode);
503        }
504
505        userConfig.ui32InputPcmFrameSize = (512 * handle->settings.decodeRate)/BAPE_NORMAL_DECODE_RATE;
506
507        errCode = BDSP_Task_SetStageSettings(handle->task, branch, stage, &userConfig, sizeof(userConfig));
508        if ( errCode )
509        {
510            return BERR_TRACE(errCode);
511        }
512    }
513
514    return BERR_SUCCESS;   
515}
516
517static BERR_Code BAPE_Decoder_P_SetupPassthrough(
518    BAPE_DecoderHandle handle
519    )
520{
521    BDSP_Raaga_Audio_PassthruConfigParams userConfig;
522    BERR_Code errCode;
523    unsigned branch,stage,type;
524
525    branch = handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.branchId;
526    stage = handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.stageId;
527
528    if ( handle->simul )
529    {
530        if ( BAPE_P_CodecRequiresGenericPassthru(handle->startSettings.codec) )
531        {
532            type=BDSP_Raaga_ePassthruType_Simul;
533        }
534        else
535        {
536            return BERR_SUCCESS;
537        }
538    }
539    else if ( handle->passthrough )
540    {
541        if ( handle->startSettings.codec == BAVC_AudioCompressionStd_ePcm )
542        {
543            type = BDSP_Raaga_ePassthruType_PCM;
544        }
545        else
546        {
547            type = BDSP_Raaga_ePassthruType_SPDIF;
548        }
549    }
550    else
551    {
552        return BERR_SUCCESS;
553    }
554
555    errCode = BDSP_Task_GetStageSettings(handle->task, branch, stage, &userConfig, sizeof(userConfig));
556    if ( errCode )
557    {
558        return BERR_TRACE(errCode);
559    }
560
561    userConfig.ui32PassthruType = type;
562    switch ( handle->startSettings.codec )
563    {
564    case BAVC_AudioCompressionStd_eAacAdts:
565    case BAVC_AudioCompressionStd_eAacPlusAdts:
566        userConfig.eAacHeaderType = BDSP_Raaga_eAacHeaderType_Adts;
567        break;
568    case BAVC_AudioCompressionStd_eAacLoas:
569    case BAVC_AudioCompressionStd_eAacPlusLoas:
570        userConfig.eAacHeaderType = BDSP_Raaga_eAacHeaderType_Loas;
571        break;
572    default:
573        break;
574    }
575
576    errCode = BDSP_Task_SetStageSettings(handle->task, branch, stage, &userConfig, sizeof(userConfig));
577    if ( errCode )
578    {
579        return BERR_TRACE(errCode);
580    }
581
582    return BERR_SUCCESS;
583}
584
585static BERR_Code BAPE_Decoder_P_ValidateDecodeSettings(
586    BAPE_DecoderHandle handle,
587    const BAPE_DecoderStartSettings *pSettings,
588    BAPE_DecoderStartSettings *pOutputSettings
589    )
590{
591    BDSP_AudioType audioType;
592    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
593    BDBG_ASSERT(NULL != pSettings);
594    BDBG_ASSERT(NULL != pOutputSettings);
595    /* Start by copying the existing settings */
596    BKNI_Memcpy(pOutputSettings, pSettings, sizeof(BAPE_DecoderStartSettings));
597    /* Check for valid input */
598    if ( NULL == pSettings->pContextMap && NULL == pSettings->inputPort )
599    {
600        BDBG_ERR(("Must specify an input to decode"));
601        return BERR_TRACE(BERR_INVALID_PARAMETER);
602    }
603    /* Store local copy of the RAVE context map in case it goes out of scope after start. */
604    if ( pSettings->pContextMap )
605    {
606        BKNI_Memcpy(&handle->contextMap, pSettings->pContextMap, sizeof(BAVC_XptContextMap));
607        pOutputSettings->pContextMap = &handle->contextMap;
608    }
609    /* Check for valid STC */
610    if ( pSettings->stcIndex > BAPE_CHIP_MAX_STCS )
611    {
612        BDBG_ERR(("STC Index %u out of range.  Supported values are 0..%u", BAPE_CHIP_MAX_STCS));
613        return BERR_TRACE(BERR_INVALID_PARAMETER);
614    }
615    audioType = BAPE_P_GetCodecAudioType(pSettings->codec);
616    if ( audioType == BDSP_AudioType_eMax )
617    {
618        return BERR_TRACE(BERR_NOT_SUPPORTED);
619    }
620    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMono].totalConnections > 0 )
621    {
622        /* Check two things.  One, you can only have mono on certain codecs.  Two, you can only have
623           two active PCM paths per node.  */
624        if ( !BAPE_P_CodecSupportsMono(pSettings->codec) )
625        {
626            BDBG_ERR(("Codec %u does not support mono output.  Please remove all mono outputs.", BAPE_P_GetCodecName(pSettings->codec)));
627            return BERR_TRACE(BERR_NOT_SUPPORTED);
628        }
629        if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].totalConnections > 0 &&
630             handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].totalConnections > 0 )
631        {
632            BDBG_ERR(("You can only have two types of PCM data from a single decoder.  Please remove outputs from either the stereo, multichannel, or mono connectors."));
633            return BERR_TRACE(BERR_NOT_SUPPORTED);
634        }
635    }
636    if ( handle->passthrough )
637    {
638        /* Determine if passthrough is valid for this codec */
639        if ( !BAPE_P_CodecSupportsPassthrough(pSettings->codec) )
640        {
641            BDBG_WRN(("Codec %s (%u) does not support compressed passthrough -- Compressed output will be PCM", 
642                      BAPE_P_GetCodecName(pSettings->codec), pSettings->codec));
643            handle->stereoOnCompressed = true;
644            handle->passthrough = false;    /* We're really doing a decode now */
645        }
646        else
647        {
648            handle->stereoOnCompressed = false;
649        }
650    }
651    /* Determine if we're trying to decode */
652    if ( !handle->passthrough )
653    {
654        /* Check for License */
655        if ( !BDSP_Raaga_IsAudioTypeSupported(audioType) )
656        {
657            BDBG_ERR(("Codec %s (%u) is not supported on this platform", 
658                      BAPE_P_GetCodecName(pSettings->codec), pSettings->codec));
659            return BERR_TRACE(BERR_NOT_SUPPORTED);
660        }
661        /* If we're trying simul mode, make sure that's valid */
662        if ( handle->simul )
663        {
664            if ( !BAPE_P_CodecSupportsSimulMode(pSettings->codec) )
665            {
666                BDBG_WRN(("Codec %s (%u) does not support simultaneous PCM and compressed output - compressed output will be stereo PCM", 
667                          BAPE_P_GetCodecName(pSettings->codec), pSettings->codec));
668                handle->stereoOnCompressed = true;
669            }
670            else
671            {
672                handle->stereoOnCompressed = false;
673            }
674        }
675    }   
676    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].totalConnections > 0 )
677    {
678        /* Determine if multichannel is valid */
679        if ( BAPE_P_GetCodecMultichannelFormat(pSettings->codec) == BAPE_MultichannelFormat_e2_0 )
680        {
681            BDBG_WRN(("Codec %s (%u) does not support multichannel output - multichannel output will be stereo", 
682                      BAPE_P_GetCodecName(pSettings->codec), pSettings->codec));
683            handle->stereoOnMultichannel = true;
684        }
685        else
686        {
687            handle->stereoOnMultichannel = false;
688        }
689    }
690    /* Determine if PPM Correction is possible */
691    if ( pSettings->decodeRateControl )
692    {
693        if ( !BDSP_Raaga_IsAudioProcessingSupported(BDSP_AudioProcessing_eDsola) )
694        {
695            BDBG_WRN(("This platform does not support DSOLA for audio decoder rate control.  Disabling rate control."));
696            pOutputSettings->decodeRateControl = false;
697        }
698        if ( handle->outputStatus.totalMultichannelOutputs > 0 ||
699             handle->outputStatus.totalCompressedOutputs > 0 ||
700             handle->outputStatus.totalMonoOutputs > 0 )
701        {
702            BDBG_WRN(("Can not perform audio trick modes with multichannel, compressed, or mono outputs connected.  Diabling rate control."));
703            pOutputSettings->decodeRateControl = false;
704        }
705        if ( pSettings->ppmCorrection )
706        {
707            BDBG_MSG(("PPM Correction is not permitted at non-standard decode rates.  Disabling PPM correction."));
708        }
709        pOutputSettings->ppmCorrection = false;
710    }
711    else if ( pSettings->ppmCorrection )
712    {
713        if ( handle->outputStatus.totalMultichannelOutputs > 0 ||
714             handle->outputStatus.totalCompressedOutputs > 0 )
715        {
716            BDBG_MSG(("PPM Correction is not permitted with multichannel or compressed outptus.  Disabling PPM correction."));
717            pOutputSettings->ppmCorrection = false;
718        }
719        else if ( pSettings->inputPort )
720        {
721            BDBG_MSG(("PPM Correction is not permitted with external inputs.  Disabling PPM correction."));
722            pOutputSettings->ppmCorrection = false;
723        }
724    }
725    return BERR_SUCCESS;
726}
727
728static BERR_Code BAPE_Decoder_P_Start(
729    BAPE_DecoderHandle handle
730    )
731{
732    BERR_Code errCode;
733    unsigned branch, stage, i, stereoBranch, stereoStage;
734    const BAPE_DecoderStartSettings *pSettings;
735    BAVC_AudioCompressionStd previousCodec;
736
737    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
738    pSettings = &handle->startSettings;
739
740    BDBG_MSG(("BAPE_Decoder_P_Start(%#x) [index %u]", handle, handle->index));
741
742    /* Do we have compressed outputs directly connected? */
743    BDBG_MSG(("%s: %u stereo consumers", handle->node.pName, handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].directConnections));
744    BDBG_MSG(("%s: %u multichannel consumers", handle->node.pName, handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].directConnections));
745    BDBG_MSG(("%s: %u compressed consumers", handle->node.pName, handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eCompressed].directConnections));
746    BDBG_MSG(("%s: %u mono consumers", handle->node.pName, handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMono].directConnections));
747
748    /* Setup DSP Task First */
749    BDSP_Task_GetDefaultCreateSettings(handle->deviceHandle->dspContext, &handle->taskCreateSettings);
750    /* Select appropriate dsp */
751    handle->taskCreateSettings.dspIndex = handle->dspIndex;
752    /* Setup default branch (not malloc'ed - others are) */
753    handle->taskCreateSettings.numBranches = 1;
754    handle->taskCreateSettings.ppmCorrection = pSettings->ppmCorrection;
755    handle->taskCreateSettings.pBranchInfo[0] = &handle->primaryBranch;
756    switch ( pSettings->streamType )
757    {
758    case BAVC_StreamType_eDssEs:
759    case BAVC_StreamType_eDssPes:
760           handle->taskCreateSettings.timeBaseType = BDSP_AF_P_TimeBaseType_e27Mhz;
761           break;
762    default:
763           handle->taskCreateSettings.timeBaseType = BDSP_AF_P_TimeBaseType_e45Khz;
764           break;
765    }
766    handle->taskCreateSettings.audioTaskDelayMode = (pSettings->delayMode == BAPE_DspDelayMode_eLow)?BDSP_AudioTaskDelayMode_eLow:BDSP_AudioTaskDelayMode_eDefault;
767    BAPE_DSP_P_InitBranch(&handle->primaryBranch);
768    handle->primaryBranch.ui32NumStages = 1;
769    /* Setup Decode/Passthru Stage */
770    handle->primaryBranch.sFwStgInfo[0].ui32BranchId = 0;
771    handle->primaryBranch.sFwStgInfo[0].ui32StageId = 0;
772    handle->primaryBranch.sFwStgInfo[0].eStageType = BDSP_CIT_P_StageType_eDecode;
773    handle->primaryBranch.sFwStgInfo[0].uAlgorithm.eDecAudioAlgo = BAPE_P_GetCodecAudioType(handle->startSettings.codec);
774    handle->primaryBranch.sFwStgInfo[0].uAudioMode.eDecAudioMode = (handle->passthrough)?BDSP_DecodeMode_ePassThru:BDSP_DecodeMode_eDecode;
775    handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.ui32NumSrc = 1; 
776    BKNI_Memset(&handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0], 0, 
777                sizeof(handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0]));
778    if ( pSettings->pContextMap )
779    {
780        /* Input Hardcoded to RAVE for now (checked above) */
781        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].eType = BDSP_CIT_P_FwStgSrcDstType_eRaveBuf;
782        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.ui32NumBuffers = 2;
783        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.eBufferType = BDSP_AF_P_BufferType_eRAVE;
784        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[0].ui32BaseAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->CDB_Base;
785        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[0].ui32EndAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->CDB_End;
786        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[0].ui32ReadAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->CDB_Read;
787        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[0].ui32WriteAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->CDB_Valid;
788        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[0].ui32WrapAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->CDB_Wrap;
789        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[1].ui32BaseAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->ITB_Base;
790        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[1].ui32EndAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->ITB_End;
791        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[1].ui32ReadAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->ITB_Read;
792        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[1].ui32WriteAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->ITB_Valid;
793        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.sCircBuffer[1].ui32WrapAddr = BCHP_PHYSICAL_OFFSET + pSettings->pContextMap->ITB_Wrap; 
794    }
795    else
796    {
797        BAPE_BufferType bufferType;       
798        BAPE_DfifoGroupCreateSettings dfifoCreateSettings;
799        BAPE_DfifoGroupSettings dfifoSettings;
800
801        /* DFIFO Input */
802        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].eType = BDSP_CIT_P_FwStgSrcDstType_eFMMBuf;
803        handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.eBufferType = BDSP_AF_P_BufferType_eFMM;
804
805        /* Make sure the input is usable.  Don't reference InputPort fields until after this.  */
806        errCode = BAPE_InputPort_P_AttachConsumer(pSettings->inputPort, &handle->node);
807        if ( errCode )
808        {
809            errCode = BERR_TRACE(errCode);
810            goto err_attach_input_port;
811        }
812
813        handle->inputCompressed = pSettings->inputPort->compressed;
814        handle->inputChannelPairs = pSettings->inputPort->numChannelPairs;
815       
816        if ( handle->inputChannelPairs > 1 )
817        {
818            BDBG_ERR(("Multichannel PCM is not currently supported from an external input."));
819            errCode = BERR_TRACE(BERR_NOT_SUPPORTED);
820            goto err_input_format;
821        }
822
823        BAPE_DfifoGroup_P_GetDefaultCreateSettings(&dfifoCreateSettings);
824        dfifoCreateSettings.numChannelPairs = handle->inputChannelPairs;
825        errCode = BAPE_DfifoGroup_P_Create(handle->deviceHandle, &dfifoCreateSettings, &handle->inputDfifoGroup);
826        if ( errCode )
827        {
828            errCode = BERR_TRACE(errCode);
829            goto err_dfifo_alloc;
830        }
831       
832        BAPE_DfifoGroup_P_GetSettings(handle->inputDfifoGroup, &dfifoSettings);
833        BAPE_FciIdGroup_Init(&dfifoSettings.input);
834       
835        BAPE_InputPort_P_GetOutputFciIds(handle, &dfifoSettings.input);
836       
837        dfifoSettings.highPriority = (pSettings->inputPort->sampleRate >= 96000) ? true : false;
838
839
840        if ( handle->inputCompressed )
841        {
842            handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.ui32NumBuffers = 1;
843            bufferType = BAPE_BufferType_eCompressed;
844            dfifoSettings.interleaveData = true;
845            dfifoSettings.dataWidth = 16;
846        }
847        else
848        {
849            handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffer.ui32NumBuffers = 2*handle->inputChannelPairs;
850            bufferType = BAPE_BufferType_ePcm;
851            dfifoSettings.interleaveData = false;
852            dfifoSettings.dataWidth = 32;
853        }
854        for ( i = 0; i < handle->inputChannelPairs; i++ )
855        {
856            uint32_t rbufId;
857            handle->pInputBuffers[i] = BAPE_P_AllocateBuffer(handle->deviceHandle, bufferType);
858            if ( NULL == handle->pInputBuffers[i] )
859            {
860                errCode = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
861                goto err_input_buffers;
862            }
863            /* Setup CIT to have correct ringbuffer ID for each DFIFO -- TODO: There should be a routine in dsp_utils_priv that takes a DFIFO Group handle instead */
864            rbufId = BAPE_P_DFIFO_TO_RINBGUFFER(BAPE_DfifoGroup_P_GetHwIndex(handle->inputDfifoGroup, i));
865            handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffId.ui32BufferId[2*i] = rbufId;
866            handle->primaryBranch.sFwStgInfo[0].sStgConnectivity.sSrcDetails[0].uDetails.sIoBuf.uIoBuffer.sIoBuffId.ui32BufferId[(2*i)+1] = rbufId+1;
867            dfifoSettings.bufferInfo[2*i].base = handle->pInputBuffers[i]->offset;
868            if ( handle->inputCompressed )
869            {
870                dfifoSettings.bufferInfo[2*i].length = handle->pInputBuffers[i]->bufferSize;
871            }
872            else
873            {
874                unsigned length = handle->pInputBuffers[i]->bufferSize/2;
875                dfifoSettings.bufferInfo[2*i].length = dfifoSettings.bufferInfo[(2*i)+1].length = length;
876                dfifoSettings.bufferInfo[(2*i)+1].base = handle->pInputBuffers[i]->offset + length;
877            }
878        }
879        errCode = BAPE_DfifoGroup_P_SetSettings(handle->inputDfifoGroup, &dfifoSettings);
880        if ( errCode )
881        {
882            (void)BERR_TRACE(errCode);
883            goto err_set_dfifo_settings;
884        }
885    }
886
887    /* Determine branch/stage outputting data to stereo PCM path  */   
888    branch=stage=0;
889    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].directConnections > 0 )
890    {       
891        /* Add SRC if required */
892        if ( !handle->passthrough && BAPE_P_CodecRequiresSrc(handle->startSettings.codec) && BDSP_Raaga_IsAudioProcessingSupported(BDSP_AudioProcessing_eSrc) )
893        {
894            errCode = BAPE_DSP_P_AddProcessingStage(&handle->taskCreateSettings, 0, 0, BDSP_AF_P_DistinctOpType_eStereo_PCM, BDSP_AudioProcessing_eSrc, false, &branch, &stage);
895            if ( errCode )
896            {
897                errCode = BERR_TRACE(errCode);
898                goto err_add_decode_pp;
899            }
900        }
901        /* Add DSOLA if required */
902        if ( pSettings->decodeRateControl )
903        {
904            errCode = BAPE_DSP_P_AddProcessingStage(&handle->taskCreateSettings, branch, stage, BDSP_AF_P_DistinctOpType_eStereo_PCM, BDSP_AudioProcessing_eDsola, false, &branch, &stage);
905            if ( errCode )
906            {
907                errCode = BERR_TRACE(errCode);
908                goto err_add_decode_pp;
909            }
910            handle->dsolaBranch=branch;
911            handle->dsolaStage=stage;
912        }
913        else
914        {
915            handle->dsolaBranch=BAPE_BRANCH_ID_INVALID;
916            handle->dsolaStage=BAPE_STAGE_ID_INVALID;
917        }
918    }
919    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.pTaskCreateSettings = &handle->taskCreateSettings;
920    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.branchId = branch;
921    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.stageId = stage;
922    stereoBranch = branch;
923    stereoStage = stage;
924
925    if ( !handle->stereoOnMultichannel )
926    {
927    /* Determine branch/stage outputting data to multichannel PCM path  */   
928    branch=stage=0;
929    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].directConnections > 0 )
930    {       
931        BDSP_AF_P_DistinctOpType opType = BAPE_DSP_P_GetDataTypeFromConnector(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector);
932        /* Add SRC if required */
933        if ( !handle->passthrough && BAPE_P_CodecRequiresSrc(handle->startSettings.codec) && BDSP_Raaga_IsAudioProcessingSupported(BDSP_AudioProcessing_eSrc) )
934        {
935            errCode = BAPE_DSP_P_AddProcessingStage(&handle->taskCreateSettings, 0, 0, opType, BDSP_AudioProcessing_eSrc, false, &branch, &stage);
936            if ( errCode )
937            {
938                errCode = BERR_TRACE(errCode);
939                goto err_add_decode_pp;
940            }
941        }
942    }
943    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.pTaskCreateSettings = &handle->taskCreateSettings;
944    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.branchId = branch;
945    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.stageId = stage;
946    }
947    else
948    {
949        handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.pTaskCreateSettings = &handle->taskCreateSettings;
950        handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.branchId = stereoBranch;
951        handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.stageId = stereoStage;
952    }
953
954    /* Determine if we need to add passthrough */
955    if ( !handle->stereoOnCompressed )
956    {
957    branch=stage=0;
958    if ( handle->simul && BAPE_P_CodecRequiresGenericPassthru(handle->startSettings.codec) )
959    {
960        /* This should always branch in simul mode */
961        errCode = BAPE_DSP_P_AddProcessingStage(&handle->taskCreateSettings, 0, 0, BDSP_AF_P_DistinctOpType_eAuxilaryDataOut, BDSP_AudioProcessing_eGenericPassThru, true, &branch, &stage);
962        if ( errCode )
963        {
964            errCode = BERR_TRACE(errCode);
965            goto err_add_passthrough;
966        }
967    }
968    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.pTaskCreateSettings = &handle->taskCreateSettings;
969    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.branchId = branch;
970    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.stageId = stage;
971    }
972    else
973    {
974        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.pTaskCreateSettings = &handle->taskCreateSettings;
975        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.branchId = stereoBranch;
976        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.stageId = stereoStage;
977    }
978
979    /* Set output codec correctly per input codec */
980    previousCodec = handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.codec;
981    if ( handle->startSettings.codec == BAVC_AudioCompressionStd_eAc3Plus &&
982         (handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].directConnections > 0 ||
983          handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].directConnections > 0) )
984    {
985        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.codec = BAVC_AudioCompressionStd_eAc3;
986    }
987    else if ( handle->stereoOnCompressed )
988    {
989        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.codec = BAVC_AudioCompressionStd_ePcm;
990    }
991    else
992    {
993        handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.codec = handle->startSettings.codec;
994    }
995
996    /* Prepare all branches to start */
997    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].directConnections )
998    {
999        if ( pSettings->ppmCorrection != handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.ppmCorrection )
1000        {
1001            handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.ppmCorrection = pSettings->ppmCorrection;
1002            errCode = BAPE_Connector_P_FormatChange(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector);
1003            if ( errCode )
1004            {
1005                errCode = BERR_TRACE(errCode);
1006                goto err_format_change;
1007            }
1008        }
1009    }
1010    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].directConnections )
1011    {
1012        bool multichannelWasStereo = (handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs == 1)?true:false;
1013        if ( multichannelWasStereo != handle->stereoOnMultichannel && handle->settings.multichannelFormat != BAPE_MultichannelFormat_e2_0 )
1014        {
1015            if ( handle->stereoOnMultichannel )
1016            {
1017                handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 1;
1018            }
1019            else
1020            {
1021                switch ( handle->settings.multichannelFormat )
1022                {
1023                case BAPE_MultichannelFormat_e5_1:
1024                    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 3;
1025                    break;
1026                case BAPE_MultichannelFormat_e7_1:
1027                    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 4;
1028                    break;
1029                default:
1030                    /* Should never get here */
1031                    break;
1032                }
1033            }
1034            errCode = BAPE_Connector_P_FormatChange(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector);
1035            if ( errCode )
1036            {
1037                errCode = BERR_TRACE(errCode);
1038                goto err_format_change;
1039            }
1040        }
1041    }
1042    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eCompressed].directConnections )
1043    {
1044        bool formatChanged=false;
1045        /* This check seems weird, but will be true if we need to switch the compressed output format from stereo<->compressed */
1046        if ( handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.compressed == 
1047             handle->stereoOnCompressed )
1048        {
1049            handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.compressed = !handle->stereoOnCompressed;
1050            formatChanged = true;
1051        }
1052        if ( previousCodec != handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.codec )
1053        {
1054            formatChanged = true;
1055        }
1056        if ( formatChanged )
1057        {
1058            BDBG_MSG(("Compressed Format Changed"));
1059            errCode = BAPE_Connector_P_FormatChange(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector);
1060            if ( errCode )
1061            {
1062                errCode = BERR_TRACE(errCode);
1063                goto err_format_change;
1064            }
1065        }
1066    }
1067    /* Mono outputs will always start from branch/stage 0 - no SRC or DSOLA. */
1068    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.pTaskCreateSettings = &handle->taskCreateSettings;
1069    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.branchId = 0;
1070    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.stageId = 0;
1071
1072    errCode = BAPE_PathNode_P_AcquirePathResources(&handle->node);
1073    if ( errCode )
1074    {
1075        errCode = BERR_TRACE(errCode);
1076        goto err_build_paths;
1077    }
1078
1079    /* Ready */
1080    handle->sampleRate = 0;
1081    handle->mode = 0;
1082    BKNI_Memset(&handle->bitRateInfo, 0, sizeof(handle->bitRateInfo));
1083    errCode = BDSP_Task_Create(handle->deviceHandle->dspContext, &handle->taskCreateSettings, &handle->task);
1084    if ( errCode )
1085    {
1086        errCode = BERR_TRACE(errCode);
1087        goto err_task_create;
1088    }
1089    errCode = BAPE_Decoder_SetInterruptHandlers(handle, &handle->interrupts);
1090    if ( errCode )
1091    {
1092        (void)BERR_TRACE(errCode);
1093        goto err_codec_settings;
1094    }
1095    errCode = BAPE_Decoder_P_ApplyFramesyncSettings(handle);
1096    if ( errCode )
1097    {
1098        (void)BERR_TRACE(errCode);
1099        goto err_codec_settings;
1100    }
1101    errCode = BAPE_Decoder_SetTsmSettings(handle, &handle->tsmSettings);
1102    if ( errCode )
1103    {
1104        (void)BERR_TRACE(errCode);
1105        goto err_codec_settings;
1106    }
1107
1108    /* Apply codec settings */
1109    errCode = BAPE_Decoder_P_ApplyCodecSettings(handle);
1110    if ( errCode )
1111    {
1112        (void)BERR_TRACE(errCode);
1113        goto err_codec_settings;
1114    }
1115
1116    /* Configure DSOLA */
1117    if ( pSettings->decodeRateControl )
1118    {
1119        errCode = BAPE_Decoder_P_ApplyDsolaSettings(handle);
1120        if ( errCode )
1121        {
1122            errCode = BERR_TRACE(errCode);
1123            goto err_codec_settings;
1124        }
1125    }
1126
1127    /* Configure passthrough if used */
1128    errCode = BAPE_Decoder_P_SetupPassthrough(handle);
1129    if ( errCode )
1130    {
1131        (void)BERR_TRACE(errCode);
1132        goto err_codec_settings;
1133    }
1134
1135    /* Initialize connectors */
1136    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.sampleRate = 0;
1137    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.task = handle->task;
1138    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.sampleRate = 0;
1139    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.task = handle->task;
1140    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.sampleRate = 0;
1141    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.task = handle->task;
1142    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.sampleRate = 0;
1143    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.task = handle->task;
1144
1145    /* Link the path resources */
1146    errCode = BAPE_PathNode_P_ConfigurePathResources(&handle->node);
1147    if ( errCode )
1148    {
1149        errCode = BERR_TRACE(errCode);
1150        goto err_config_path_resources;
1151    }
1152
1153    #if BDBG_DEBUG_BUILD
1154        BAPE_Mixer_P_PrintMixers(handle->deviceHandle);
1155    #endif
1156
1157    /* Start the consumers */
1158    errCode = BAPE_PathNode_P_StartPaths(&handle->node);
1159    if ( errCode )
1160    {
1161        goto err_start_path;
1162    }
1163   
1164    #if BDBG_DEBUG_BUILD
1165        BAPE_Mixer_P_PrintDownstreamNodes(&handle->node);
1166    #endif
1167   
1168#if BAPE_DISABLE_DSP
1169    #warning Task Start is Disabled!
1170    BDBG_ERR(("NOT STARTING"));
1171#else
1172    errCode = BDSP_Task_Start(handle->task);
1173    if ( errCode )
1174    {
1175        (void)BERR_TRACE(errCode);
1176        goto err_start_task;
1177    }
1178#endif
1179
1180    /* Start the DFIFOs */
1181    if ( pSettings->inputPort )
1182    {
1183        errCode = BAPE_DfifoGroup_P_Start(handle->inputDfifoGroup, false);
1184        if ( errCode )
1185        {
1186            errCode = BERR_TRACE(errCode);
1187            goto err_dfifo_start;
1188        }
1189        BDBG_ASSERT(NULL != pSettings->inputPort->enable);
1190        pSettings->inputPort->enable(pSettings->inputPort);
1191    }
1192
1193    handle->state = BAPE_DecoderState_eStarted;
1194    return BERR_SUCCESS;
1195
1196err_dfifo_start:
1197    BDSP_Task_Stop(handle->task);
1198err_start_task:
1199    BAPE_PathNode_P_StopPaths(&handle->node);
1200err_start_path:
1201err_config_path_resources:
1202err_codec_settings:
1203    BDSP_Task_Destroy(handle->task);
1204    handle->task = NULL;
1205err_task_create:
1206    BAPE_PathNode_P_ReleasePathResources(&handle->node);
1207err_build_paths:
1208err_format_change:
1209err_add_passthrough:
1210err_add_decode_pp:
1211    BAPE_Decoder_P_CleanupTaskCreateSetings(handle);   
1212err_input_buffers:
1213err_set_dfifo_settings:
1214    if ( pSettings->inputPort )
1215    {
1216        for ( i = 0; i < handle->inputChannelPairs; i++ )
1217        {
1218            if ( handle->pInputBuffers[i] )
1219            {
1220                BAPE_P_FreeBuffer(handle->deviceHandle, handle->pInputBuffers[i]);
1221                handle->pInputBuffers[i] = NULL;
1222            }
1223        }
1224        BAPE_DfifoGroup_P_Destroy(handle->inputDfifoGroup);
1225        handle->inputDfifoGroup = NULL;
1226    }
1227err_dfifo_alloc:
1228err_input_format:
1229    if ( pSettings->inputPort )
1230    {
1231        BAPE_InputPort_P_DetachConsumer(pSettings->inputPort, &handle->node);
1232    }
1233err_attach_input_port:
1234    return errCode;
1235}
1236
1237BERR_Code BAPE_Decoder_Start(
1238    BAPE_DecoderHandle handle,
1239    const BAPE_DecoderStartSettings *pSettings
1240    )
1241{
1242    BERR_Code errCode;
1243    BAPE_PathNode *pNode;
1244    unsigned numFound;
1245
1246    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1247    BDBG_ASSERT(NULL != pSettings);
1248
1249    BDBG_MSG(("BAPE_Decoder_Start(%#x) [index %u]", handle, handle->index));
1250
1251    if ( NULL == handle->deviceHandle->dspContext )
1252    {
1253        BDBG_ERR(("DSP Not avaliable"));
1254        return BERR_TRACE(BERR_NOT_SUPPORTED);
1255    }
1256
1257    if ( handle->state != BAPE_DecoderState_eStopped )
1258    {
1259        BDBG_ERR(("Already running, cannot start"));
1260        return BERR_TRACE(BERR_INVALID_PARAMETER);
1261    }
1262
1263    /* Get output status */
1264    BAPE_PathNode_P_GetOutputStatus(&handle->node, &handle->outputStatus);
1265
1266    /* Validate we either have real-time outputs or don't depending on system requirements */
1267    BAPE_PathNode_P_FindConsumersBySubtype(&handle->node, BAPE_PathNodeType_eMixer, BAPE_MixerType_eStandard, 1, &numFound, &pNode);
1268    if ( pSettings->nonRealTime )
1269    {
1270        if ( numFound != 0 )
1271        {
1272            BDBG_ERR(("No outputs should be connected to a decoder in non-realtime mode."));
1273            return BERR_TRACE(BERR_NOT_SUPPORTED);
1274        }
1275    }
1276    else
1277    {
1278        if ( numFound == 0 )
1279        {
1280            BDBG_ERR(("No outputs are connected.  Cannot start."));
1281            return BERR_TRACE(BERR_INVALID_PARAMETER);
1282        }
1283    }
1284
1285    /* Determine decoder "mode" based on connections first */
1286    if ( handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eCompressed].directConnections > 0 )
1287    {
1288        /* Do we have any stereo or multichannel outputs connected directly? */
1289        if ( 0 == (handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eStereo].directConnections + 
1290                   handle->outputStatus.pathStatus[BAPE_ConnectorFormat_eMultichannel].directConnections) )
1291        {
1292            /* No.  This is a passthrough operation. */
1293            handle->passthrough = true;
1294            handle->simul = false;
1295        }
1296        else
1297        {
1298            /* Yes.  This is "simul", decode + passthrough */
1299            handle->passthrough = false;
1300            handle->simul = true;
1301        }
1302    }
1303    else
1304    {
1305        /* No compressed outputs.  This is a decode operation. */
1306        handle->passthrough = false;
1307        handle->simul = false;
1308    }
1309
1310    /* Sanity check settings */
1311    errCode = BAPE_Decoder_P_ValidateDecodeSettings(handle, pSettings, &handle->startSettings);
1312    if ( errCode )
1313    {
1314        return BERR_TRACE(errCode);
1315    }
1316    pSettings = &handle->startSettings;
1317
1318    /* Determine multistream linkage */
1319    errCode = BAPE_Decoder_P_DeriveMultistreamLinkage(handle);
1320    if ( errCode )
1321    {
1322        return BERR_TRACE(errCode);
1323    }
1324
1325    /* Trigger task and path startup */
1326    errCode = BAPE_Decoder_P_Start(handle);
1327    if ( errCode )
1328    {
1329        return BERR_TRACE(errCode);
1330    }
1331
1332    /* Success */
1333    return BERR_SUCCESS;
1334}
1335
1336static void BAPE_Decoder_P_Stop(
1337    BAPE_DecoderHandle handle
1338    )
1339{
1340    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1341
1342    if ( NULL == handle->task )
1343    {
1344        BDBG_MSG(("BAPE_Decoder_P_Stop: Decoder %u already stopped.", handle->index));
1345        return;
1346    }
1347
1348    /* Stop DFIFO if needed*/
1349    if ( handle->startSettings.inputPort )
1350    {
1351        BDBG_ASSERT(NULL != handle->startSettings.inputPort->disable);
1352        handle->startSettings.inputPort->disable(handle->startSettings.inputPort);
1353        BAPE_DfifoGroup_P_Stop(handle->inputDfifoGroup);
1354    }
1355
1356#if BAPE_DISABLE_DSP
1357    #warning Task Start is Disabled!
1358    BDBG_ERR(("NOT STOPPING DSP"));
1359#else
1360    BDSP_Task_Stop(handle->task);
1361#endif
1362
1363    BAPE_PathNode_P_StopPaths(&handle->node);
1364
1365    if ( handle->startSettings.inputPort  )
1366    {
1367        unsigned i;
1368        for ( i = 0; i < handle->inputChannelPairs; i++ )
1369        {
1370            BAPE_P_FreeBuffer(handle->deviceHandle, handle->pInputBuffers[i]);
1371            handle->pInputBuffers[i] = NULL;
1372        }
1373        BAPE_DfifoGroup_P_Destroy(handle->inputDfifoGroup);
1374        handle->inputDfifoGroup = NULL;
1375        BAPE_InputPort_P_DetachConsumer(handle->startSettings.inputPort, &handle->node);
1376    }
1377
1378    BDSP_Task_Destroy(handle->task);
1379    handle->task = NULL;
1380    BAPE_Decoder_P_CleanupTaskCreateSetings(handle);   
1381}
1382
1383void BAPE_Decoder_Stop(
1384    BAPE_DecoderHandle handle
1385    )
1386{
1387    bool unmute = false;
1388
1389    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1390
1391    BDBG_MSG(("BAPE_Decoder_Stop(%#x) [index %u]", handle, handle->index));
1392
1393    switch ( handle->state )
1394    {
1395    case BAPE_DecoderState_eStopped:
1396        BDBG_WRN(("Decoder %u Already Stopped.", handle->index));
1397        return;
1398    case BAPE_DecoderState_ePaused:
1399    case BAPE_DecoderState_eDisabledPaused:
1400        unmute = true;
1401        break;
1402    default:
1403        break;
1404    }
1405
1406    /* Stop the task first */
1407    handle->state = BAPE_DecoderState_eStopped;
1408    /* Serialize with critical section prior to stopping the task, guarantees isrs are not updating while we stop (they check the state first) */
1409    BKNI_EnterCriticalSection();
1410    BKNI_LeaveCriticalSection();
1411
1412    BAPE_Decoder_P_Stop(handle);
1413
1414    /* Reset multistream state */
1415    handle->ddre = NULL;
1416    handle->fwMixer = NULL;
1417    handle->fwMixerMaster = true;
1418
1419    if ( unmute )
1420    {
1421        BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector, false);
1422        BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector, false);
1423        BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector, false);
1424        BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMono].connector, false);
1425    }
1426}
1427
1428BERR_Code BAPE_Decoder_Pause(
1429    BAPE_DecoderHandle handle
1430    )
1431{
1432    BERR_Code errCode = BERR_SUCCESS;
1433
1434    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1435
1436    BDBG_MSG(("BAPE_Decoder_Pause(%#x) [index %u]", handle, handle->index));
1437
1438    /* Make sure we're performing a valid state transition */
1439    switch ( handle->state )
1440    {
1441    case BAPE_DecoderState_eStopped:
1442        BDBG_ERR(("Decoder %u is not started, cannot pause.", handle->index));
1443        return BERR_TRACE(BERR_NOT_SUPPORTED);
1444    case BAPE_DecoderState_eStarted:
1445        break;
1446    case BAPE_DecoderState_ePaused:
1447        BDBG_WRN(("Decoder %u already paused.", handle->index));
1448        return BERR_SUCCESS;
1449    case BAPE_DecoderState_eDisabled:
1450    case BAPE_DecoderState_eDisabledPaused:
1451        BDBG_ERR(("Decoder %u is disabled for flush.  Must complete flush prior to calling Pause.", handle->index));
1452        return BERR_TRACE(BERR_NOT_SUPPORTED);
1453    default:
1454        BDBG_ERR(("Unexpected decoder state %u", handle->state));
1455        BDBG_ASSERT(0);
1456        return BERR_TRACE(BERR_NOT_SUPPORTED);
1457    }
1458
1459    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector, true);
1460    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector, true);
1461    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector, true);
1462    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMono].connector, true);
1463
1464    errCode = BDSP_AudioTask_Pause(handle->task);
1465    if ( errCode )
1466    {
1467        return BERR_TRACE(errCode);
1468    }
1469
1470    handle->state = BAPE_DecoderState_ePaused;
1471    return BERR_SUCCESS;
1472}
1473
1474BERR_Code BAPE_Decoder_Resume(
1475    BAPE_DecoderHandle handle
1476    )
1477{
1478    BERR_Code errCode = BERR_SUCCESS;
1479
1480    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1481
1482    BDBG_MSG(("BAPE_Decoder_Resume(%#x) [index %u]", handle, handle->index));
1483
1484    /* Make sure we're performing a valid state transition */
1485    switch ( handle->state )
1486    {
1487    case BAPE_DecoderState_eStopped:
1488        BDBG_ERR(("Decoder %u is not started, cannot resume.", handle->index));
1489        return BERR_TRACE(BERR_NOT_SUPPORTED);
1490    case BAPE_DecoderState_eStarted:
1491        BDBG_WRN(("Decoder %u already running.", handle->index));
1492        return BERR_SUCCESS;
1493    case BAPE_DecoderState_ePaused:
1494        break;
1495    case BAPE_DecoderState_eDisabled:
1496    case BAPE_DecoderState_eDisabledPaused:
1497        BDBG_ERR(("Decoder %u is disabled for flush.  Must complete flush prior to calling Resume.", handle->index));
1498        return BERR_TRACE(BERR_NOT_SUPPORTED);
1499    default:
1500        BDBG_ERR(("Unexpected decoder state %u", handle->state));
1501        BDBG_ASSERT(0);
1502        return BERR_TRACE(BERR_NOT_SUPPORTED);
1503    }
1504
1505    errCode = BDSP_AudioTask_Resume(handle->task);
1506    if ( errCode )
1507    {
1508        return BERR_TRACE(errCode);
1509    }
1510
1511    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector, false);
1512    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector, false);
1513    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector, false);
1514    BAPE_Connector_P_SetMute(&handle->node.paths[BAPE_ConnectorFormat_eMono].connector, false);
1515
1516    handle->state = BAPE_DecoderState_eStarted;
1517    return BERR_SUCCESS;
1518}
1519
1520BERR_Code BAPE_Decoder_Advance(
1521    BAPE_DecoderHandle handle,
1522    unsigned milliseconds           /* Milliseconds to advance */
1523    )
1524{
1525    BERR_Code errCode = BERR_SUCCESS;
1526
1527    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1528
1529    BDBG_MSG(("BAPE_Decoder_Advance(%#x, %u) [index %u]", handle, milliseconds, handle->index));
1530
1531    /* Make sure we're performing a valid state transition */
1532    switch ( handle->state )
1533    {
1534    case BAPE_DecoderState_eStopped:
1535        BDBG_ERR(("Decoder %u is not started, cannot advance.", handle->index));
1536        return BERR_TRACE(BERR_NOT_SUPPORTED);
1537    case BAPE_DecoderState_eStarted:
1538        BDBG_WRN(("Decoder %u running, can't advance.", handle->index));
1539        return BERR_TRACE(BERR_NOT_SUPPORTED);
1540    case BAPE_DecoderState_ePaused:
1541        break;
1542    case BAPE_DecoderState_eDisabled:
1543    case BAPE_DecoderState_eDisabledPaused:
1544        BDBG_ERR(("Decoder %u is disabled for flush.  Must complete flush prior to calling Advance.", handle->index));
1545        return BERR_TRACE(BERR_NOT_SUPPORTED);
1546    default:
1547        BDBG_ERR(("Unexpected decoder state %u", handle->state));
1548        BDBG_ASSERT(0);
1549        return BERR_TRACE(BERR_NOT_SUPPORTED);
1550    }
1551
1552    errCode = BDSP_AudioTask_Advance(handle->task, milliseconds);
1553    if ( errCode )
1554    {
1555        return BERR_TRACE(errCode);
1556    }
1557
1558    return BERR_SUCCESS;
1559}
1560
1561BERR_Code BAPE_Decoder_DisableForFlush(
1562    BAPE_DecoderHandle handle
1563    )
1564{
1565    BAPE_DecoderState newState = BAPE_DecoderState_eMax;
1566
1567    BDBG_MSG(("BAPE_Decoder_DisableForFlush(%#x) [index %u]", handle, handle->index));
1568
1569    /* Make sure we're performing a valid state transition */
1570    switch ( handle->state )
1571    {
1572    case BAPE_DecoderState_eStopped:
1573        BDBG_ERR(("Decoder %u is not started, cannot disable for flush.", handle->index));
1574        return BERR_TRACE(BERR_NOT_SUPPORTED);
1575    case BAPE_DecoderState_eStarted:
1576        newState = BAPE_DecoderState_eDisabled;
1577        break;
1578    case BAPE_DecoderState_ePaused:
1579        newState = BAPE_DecoderState_eDisabledPaused;
1580        break;
1581    case BAPE_DecoderState_eDisabled:
1582    case BAPE_DecoderState_eDisabledPaused:
1583        /* No change */
1584        return BERR_SUCCESS;
1585    default:
1586        BDBG_ERR(("Unexpected decoder state %u", handle->state));
1587        BDBG_ASSERT(0);
1588        return BERR_TRACE(BERR_NOT_SUPPORTED);
1589    }
1590
1591    /* Transition State */
1592    handle->state = newState;
1593    BKNI_EnterCriticalSection();
1594    BKNI_LeaveCriticalSection();
1595    BAPE_Decoder_P_Stop(handle);
1596
1597    return BERR_SUCCESS;
1598}
1599
1600BERR_Code BAPE_Decoder_Flush(
1601    BAPE_DecoderHandle handle
1602    )
1603{
1604    BERR_Code errCode;
1605    bool paused = false;
1606
1607    BDBG_MSG(("BAPE_Decoder_Flush(%#x) [index %u]", handle, handle->index));
1608
1609    /* Make sure we're performing a valid state transition */
1610    switch ( handle->state )
1611    {
1612    case BAPE_DecoderState_eStopped:
1613        BDBG_ERR(("Decoder %u is not started, cannot flush.", handle->index));
1614        return BERR_TRACE(BERR_NOT_SUPPORTED);
1615    case BAPE_DecoderState_eStarted:
1616    case BAPE_DecoderState_ePaused:
1617        BDBG_ERR(("Decoder %u is not disabled, cannot flush.", handle->index));
1618        return BERR_TRACE(BERR_NOT_SUPPORTED);
1619    case BAPE_DecoderState_eDisabled:
1620        break;
1621    case BAPE_DecoderState_eDisabledPaused:
1622        paused = true;
1623        break;
1624    default:
1625        BDBG_ERR(("Unexpected decoder state %u", handle->state));
1626        BDBG_ASSERT(0);
1627        return BERR_TRACE(BERR_NOT_SUPPORTED);
1628    }
1629
1630    errCode = BAPE_Decoder_P_Start(handle);
1631    if ( errCode )
1632    {
1633        return BERR_TRACE(errCode);
1634    }
1635
1636    if ( paused )
1637    {
1638        errCode = BAPE_Decoder_Pause(handle);
1639        if ( errCode )
1640        {
1641            /* Should never happen, but just for completeness */
1642            return BERR_TRACE(errCode);
1643        }
1644    }
1645
1646    return BERR_SUCCESS;
1647}
1648
1649void BAPE_Decoder_GetTsmSettings(
1650    BAPE_DecoderHandle handle,
1651    BAPE_DecoderTsmSettings *pSettings  /* [out] */
1652    )
1653{
1654    BKNI_EnterCriticalSection();
1655    BAPE_Decoder_GetTsmSettings_isr(handle, pSettings);
1656    BKNI_LeaveCriticalSection();
1657}
1658
1659void BAPE_Decoder_GetTsmSettings_isr(
1660    BAPE_DecoderHandle handle,
1661    BAPE_DecoderTsmSettings *pSettings  /* [out] */
1662    )
1663{
1664    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1665    BDBG_ASSERT(NULL != pSettings);
1666    *pSettings = handle->tsmSettings;
1667}
1668
1669BERR_Code BAPE_Decoder_SetTsmSettings(
1670    BAPE_DecoderHandle handle,
1671    const BAPE_DecoderTsmSettings *pSettings
1672    )
1673{
1674    BERR_Code errCode;
1675    BKNI_EnterCriticalSection();
1676    errCode = BAPE_Decoder_SetTsmSettings_isr(handle, pSettings);
1677    BKNI_LeaveCriticalSection();
1678    if ( errCode )
1679    {
1680        return BERR_TRACE(errCode);
1681    }
1682    return BERR_SUCCESS;
1683}
1684
1685/***************************************************************************
1686Summary:
1687Set Audio Decoder TSM Settings in isr context
1688***************************************************************************/
1689BERR_Code BAPE_Decoder_SetTsmSettings_isr(
1690    BAPE_DecoderHandle handle,
1691    const BAPE_DecoderTsmSettings *pSettings
1692    )
1693{
1694    BERR_Code errCode = BERR_SUCCESS;
1695
1696    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1697    BDBG_ASSERT(NULL != pSettings);
1698
1699    if ( BAPE_Decoder_P_TaskValid_isr(handle) )
1700    {
1701        BDSP_AudioTaskTsmSettings tsmSettings;
1702        BDSP_AudioTask_GetTsmSettings_isr(handle->task, 0, 0, &tsmSettings);
1703        BAPE_DSP_P_SET_VARIABLE(tsmSettings, ui32STCAddr, BCHP_PHYSICAL_OFFSET + BAPE_CHIP_GET_STC_ADDRESS(handle->startSettings.stcIndex));
1704        BAPE_DSP_P_SET_VARIABLE(tsmSettings, eTsmEnable, pSettings->tsmEnabled?BDSP_Raaga_eTsmBool_True:BDSP_Raaga_eTsmBool_False);
1705        BAPE_DSP_P_SET_VARIABLE(tsmSettings, eAstmEnable, pSettings->astmEnabled?BDSP_Raaga_eTsmBool_True:BDSP_Raaga_eTsmBool_False);
1706        BAPE_DSP_P_SET_VARIABLE(tsmSettings, ePlayBackOn, pSettings->playback?BDSP_Raaga_eTsmBool_True:BDSP_Raaga_eTsmBool_False);
1707        BAPE_DSP_P_SET_VARIABLE(tsmSettings, ui32AVOffset, pSettings->ptsOffset);
1708        BAPE_DSP_P_SET_VARIABLE(tsmSettings, i32TSMDiscardThreshold, pSettings->thresholds.discard*45);
1709        BAPE_DSP_P_SET_VARIABLE(tsmSettings, i32TSMGrossThreshold, pSettings->thresholds.grossAdjustment*45);
1710        BAPE_DSP_P_SET_VARIABLE(tsmSettings, i32TSMSmoothThreshold, pSettings->thresholds.smoothTrack*45);
1711        BAPE_DSP_P_SET_VARIABLE(tsmSettings, i32TSMSyncLimitThreshold, pSettings->thresholds.syncLimit*45);
1712        BDBG_MSG(("BAPE_Decoder_SetTsmSettings_isr: eSTCValid = %u", tsmSettings.eSTCValid));
1713        if ( handle->startSettings.nonRealTime )
1714        {
1715            BAPE_DSP_P_SET_VARIABLE(tsmSettings, ui32SwSTCOffset, pSettings->stcOffset);
1716        }
1717        errCode = BDSP_AudioTask_SetTsmSettings_isr(handle->task, 0, 0, &tsmSettings);
1718        if ( errCode )
1719        {
1720            return BERR_TRACE(errCode);
1721        }
1722    }
1723
1724    handle->tsmSettings = *pSettings;
1725
1726    return BERR_SUCCESS;
1727}
1728
1729BERR_Code BAPE_Decoder_GetTsmStatus(
1730    BAPE_DecoderHandle handle,
1731    BAPE_DecoderTsmStatus *pStatus  /* [out] */
1732    )
1733{
1734    BERR_Code errCode;
1735    BKNI_EnterCriticalSection();
1736    errCode = BAPE_Decoder_GetTsmStatus_isr(handle, pStatus);
1737    BKNI_LeaveCriticalSection();
1738    if ( errCode )
1739    {
1740        return errCode;     /* BERR_TRACE intentionally omitted */
1741    }
1742    return BERR_SUCCESS;
1743}
1744
1745BERR_Code BAPE_Decoder_GetTsmStatus_isr(
1746    BAPE_DecoderHandle handle,
1747    BAPE_DecoderTsmStatus *pStatus  /* [out] */
1748    )
1749{
1750    BERR_Code errCode;
1751    BDSP_AudioTaskTsmStatus tsmStatus;
1752
1753    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1754    BDBG_ASSERT(NULL != pStatus);
1755
1756    if ( BAPE_Decoder_P_TaskValid_isr(handle) )
1757    {
1758        errCode = BDSP_AudioTask_GetTsmStatus_isr(handle->task, 0, 0, &tsmStatus);
1759        if ( errCode )
1760        {
1761            BKNI_Memset(pStatus, 0, sizeof(*pStatus));
1762            pStatus->ptsInfo.ePTSType = BAVC_PTSType_eInterpolatedFromInvalidPTS; /* Mark PTS as invalid */
1763            return errCode;     /* BERR_TRACE intentionally omitted */
1764        }
1765        BAPE_Decoder_P_ConvertTsmStatus_isr(pStatus, &tsmStatus);
1766    }
1767
1768    return BERR_SUCCESS;
1769}
1770
1771void BAPE_Decoder_GetSettings(
1772    BAPE_DecoderHandle handle,
1773    BAPE_DecoderSettings *pSettings     /* [out] */
1774    )
1775{
1776    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1777    BDBG_ASSERT(NULL != pSettings);
1778
1779    *pSettings = handle->settings;
1780}
1781
1782BERR_Code BAPE_Decoder_SetSettings(
1783    BAPE_DecoderHandle handle,
1784    const BAPE_DecoderSettings *pSettings
1785    )
1786{
1787    BERR_Code errCode = BERR_SUCCESS;
1788
1789    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1790    BDBG_ASSERT(NULL != pSettings);
1791
1792    if ( pSettings->decodeRate < (BAPE_NORMAL_DECODE_RATE/2) || pSettings->decodeRate > (2*BAPE_NORMAL_DECODE_RATE) )
1793    {
1794        BDBG_ERR(("Audio trick play is supported for 0.5x to 2x playback only. (rate=%u)", pSettings->decodeRate));
1795        return BERR_TRACE(BERR_INVALID_PARAMETER);
1796    }
1797
1798    if ( handle->settings.multichannelFormat != pSettings->multichannelFormat )
1799    {
1800        if ( handle->task )
1801        {
1802            BDBG_ERR(("Cannot change multichannel format while decoder is running."));
1803        }
1804        else
1805        {
1806            /* Release multichannel path resources and update number of channels accordingly */
1807            BAPE_Connector_P_RemoveAllConnections(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector);
1808            switch ( pSettings->multichannelFormat )
1809            {
1810            case BAPE_MultichannelFormat_e2_0:
1811                handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 1;
1812                break;
1813            case BAPE_MultichannelFormat_e5_1:
1814                handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 3;
1815                break;
1816            case BAPE_MultichannelFormat_e7_1:
1817                handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.numChannelPairs = 4;
1818                break;
1819            default:
1820                return BERR_TRACE(BERR_INVALID_PARAMETER);
1821            }
1822        }
1823    }
1824
1825    handle->settings = *pSettings;
1826
1827    if ( handle->task )
1828    {
1829        errCode = BAPE_Decoder_P_ApplyCodecSettings(handle);
1830        if ( errCode )
1831        {
1832            return BERR_TRACE(errCode);
1833        }
1834        if ( handle->startSettings.decodeRateControl )
1835        {
1836            errCode = BAPE_Decoder_P_ApplyDsolaSettings(handle);
1837            if ( errCode )
1838            {
1839                return BERR_TRACE(errCode);
1840            }
1841        }
1842    }
1843
1844    return BERR_SUCCESS;
1845}
1846
1847void BAPE_Decoder_GetStatus(
1848    BAPE_DecoderHandle handle,
1849    BAPE_DecoderStatus *pStatus     /* [out] */
1850    )
1851{
1852    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1853    BDBG_ASSERT(NULL != pStatus);
1854
1855    BKNI_Memset(pStatus, 0, sizeof(BAPE_DecoderStatus));
1856    if ( handle->state == BAPE_DecoderState_eStopped )
1857    {
1858        pStatus->codec = BAVC_AudioCompressionStd_eMax;
1859        pStatus->sampleRate = 0;
1860    }
1861    else
1862    {
1863        pStatus->codec = handle->startSettings.codec;
1864        BAPE_Decoder_GetTsmStatus(handle, &pStatus->tsmStatus);
1865        pStatus->sampleRate = handle->sampleRate;
1866        BAPE_Decoder_P_GetCodecStatus(handle, pStatus);
1867    }
1868}
1869
1870void BAPE_Decoder_GetCodecSettings(
1871    BAPE_DecoderHandle handle,
1872    BAVC_AudioCompressionStd codec,
1873    BAPE_DecoderCodecSettings *pSettings     /* [out] */
1874    )
1875{
1876    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1877    BDBG_ASSERT(NULL != pSettings);
1878    switch ( codec )
1879    {
1880    case BAVC_AudioCompressionStd_eAc3:
1881        *pSettings = handle->ac3Settings;
1882        break;
1883    case BAVC_AudioCompressionStd_eAc3Plus:
1884        *pSettings = handle->ac3PlusSettings;
1885        break;
1886    case BAVC_AudioCompressionStd_eAacAdts:
1887    case BAVC_AudioCompressionStd_eAacLoas:
1888        *pSettings = handle->aacSettings;
1889        break;
1890    case BAVC_AudioCompressionStd_eAacPlusAdts:
1891    case BAVC_AudioCompressionStd_eAacPlusLoas:
1892        *pSettings = handle->aacPlusSettings;
1893        break;
1894    case BAVC_AudioCompressionStd_eDts:
1895    case BAVC_AudioCompressionStd_eDtshd:
1896    case BAVC_AudioCompressionStd_eDtsLegacy:
1897        *pSettings = handle->dtsSettings;
1898        break;
1899    case BAVC_AudioCompressionStd_eAdpcm:
1900        *pSettings = handle->adpcmSettings;
1901        break;
1902    default:
1903        break;
1904    }
1905    pSettings->codec = codec;
1906}
1907
1908BERR_Code BAPE_Decoder_SetCodecSettings(
1909    BAPE_DecoderHandle handle,
1910    const BAPE_DecoderCodecSettings *pSettings
1911    )
1912{
1913    BERR_Code errCode = BERR_SUCCESS;
1914    bool updateTask=false;
1915
1916    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1917    BDBG_ASSERT(NULL != pSettings);
1918   
1919    /* Passthrough params are not user-changeable, so no need to set them.
1920       Default to update task if the codec matches for decode/simul cases. */
1921    if ( handle->startSettings.codec == pSettings->codec &&
1922         !handle->passthrough )
1923    {
1924        updateTask = true;
1925    }
1926
1927    switch ( pSettings->codec )
1928    {
1929    case BAVC_AudioCompressionStd_eAc3:
1930        handle->ac3Settings = *pSettings;
1931        break;
1932    case BAVC_AudioCompressionStd_eAc3Plus:
1933        handle->ac3PlusSettings = *pSettings;
1934        break;
1935    case BAVC_AudioCompressionStd_eAacAdts:
1936    case BAVC_AudioCompressionStd_eAacLoas:
1937        handle->aacSettings = *pSettings;
1938        if ( handle->startSettings.codec == BAVC_AudioCompressionStd_eAacLoas ||
1939             handle->startSettings.codec == BAVC_AudioCompressionStd_eAacAdts )
1940        {
1941            /* We don't manage AAC ADTS/LOAS as separate configs */
1942            updateTask = true;
1943        }
1944        break;
1945    case BAVC_AudioCompressionStd_eAacPlusLoas:
1946    case BAVC_AudioCompressionStd_eAacPlusAdts:
1947        handle->aacPlusSettings = *pSettings;
1948        if ( handle->startSettings.codec == BAVC_AudioCompressionStd_eAacPlusLoas ||
1949             handle->startSettings.codec == BAVC_AudioCompressionStd_eAacPlusAdts )
1950        {
1951            /* We don't manage AAC ADTS/LOAS as separate configs */
1952            updateTask = true;
1953        }
1954        break;
1955    case BAVC_AudioCompressionStd_eDts:
1956    case BAVC_AudioCompressionStd_eDtshd:
1957    case BAVC_AudioCompressionStd_eDtsLegacy:
1958        handle->dtsSettings = *pSettings;
1959        if ( handle->startSettings.codec == BAVC_AudioCompressionStd_eDts ||
1960             handle->startSettings.codec == BAVC_AudioCompressionStd_eDtshd ||
1961             handle->startSettings.codec == BAVC_AudioCompressionStd_eDtsLegacy )
1962        {
1963            /* We don't manage the multitude of DTS variants as separate configs */
1964            updateTask = true;
1965        }
1966        break;
1967    case BAVC_AudioCompressionStd_eAdpcm:
1968        handle->adpcmSettings = *pSettings;
1969        break;
1970    default:
1971        updateTask = false;
1972        break;
1973    }
1974
1975    if ( handle->task && updateTask )
1976    {
1977        errCode = BAPE_Decoder_P_ApplyCodecSettings(handle);
1978        if ( errCode )
1979        {
1980            return BERR_TRACE(errCode);
1981        }
1982    }
1983
1984    return BERR_SUCCESS;
1985}
1986
1987void BAPE_Decoder_GetConnector(
1988    BAPE_DecoderHandle handle,
1989    BAPE_ConnectorFormat format,
1990    BAPE_Connector *pConnector /* [out] */
1991    )
1992{
1993    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
1994    BDBG_ASSERT(NULL != pConnector);
1995
1996    switch ( format )
1997    {
1998    case BAPE_ConnectorFormat_eStereo:
1999    case BAPE_ConnectorFormat_eMultichannel:
2000    case BAPE_ConnectorFormat_eCompressed:
2001    case BAPE_ConnectorFormat_eMono:
2002        *pConnector = &handle->node.paths[format].connector;
2003        break;
2004    default:
2005        BDBG_ERR(("Unsupported data path format %u", format));
2006        *pConnector = NULL;
2007        break;
2008    }
2009}
2010
2011void BAPE_Decoder_GetInterruptHandlers(
2012    BAPE_DecoderHandle handle,
2013    BAPE_DecoderInterruptHandlers *pInterrupts     /* [out] */
2014    )
2015{
2016    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2017    BDBG_ASSERT(NULL != pInterrupts);
2018    *pInterrupts = handle->interrupts;
2019}
2020
2021BERR_Code BAPE_Decoder_SetInterruptHandlers(
2022    BAPE_DecoderHandle handle,
2023    const BAPE_DecoderInterruptHandlers *pInterrupts
2024    )
2025{
2026    BERR_Code errCode;
2027    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2028    BDBG_ASSERT(NULL != pInterrupts);
2029    BKNI_EnterCriticalSection();
2030    if ( handle->task )
2031    {
2032        BDSP_AudioInterruptHandlers interrupts;
2033        BDSP_AudioTask_GetInterruptHandlers_isr(handle->task, &interrupts);
2034        interrupts.firstPts.pCallback_isr = BAPE_Decoder_P_FirstPts_isr;
2035        interrupts.firstPts.pParam1 = handle;
2036        interrupts.tsmFail.pCallback_isr = BAPE_Decoder_P_TsmFail_isr;
2037        interrupts.tsmFail.pParam1 = handle;
2038        interrupts.tsmPass.pCallback_isr = BAPE_Decoder_P_TsmPass_isr;
2039        interrupts.tsmPass.pParam1 = handle;
2040        interrupts.sampleRateChange.pCallback_isr = BAPE_Decoder_P_SampleRateChange_isr;
2041        interrupts.sampleRateChange.pParam1 = handle;
2042        interrupts.lock.pCallback_isr = pInterrupts->lock.pCallback_isr;
2043        interrupts.lock.pParam1 = pInterrupts->lock.pParam1;
2044        interrupts.lock.param2 = pInterrupts->lock.param2;
2045        interrupts.unlock.pCallback_isr = pInterrupts->unlock.pCallback_isr;
2046        interrupts.unlock.pParam1 = pInterrupts->unlock.pParam1;
2047        interrupts.unlock.param2 = pInterrupts->unlock.param2;               
2048        interrupts.modeChange.pCallback_isr = BAPE_Decoder_P_ModeChange_isr;
2049        interrupts.modeChange.pParam1 = handle;
2050        interrupts.bitrateChange.pCallback_isr = BAPE_Decoder_P_BitrateChange_isr;
2051        interrupts.bitrateChange.pParam1 = handle;
2052        interrupts.cdbItbOverflow.pCallback_isr = BAPE_Decoder_P_Overflow_isr;
2053        interrupts.cdbItbOverflow.pParam1 = handle;
2054        interrupts.statusReady.pCallback_isr = BAPE_Decoder_P_StatusReady_isr;
2055        interrupts.statusReady.pParam1 = handle;
2056        errCode = BDSP_AudioTask_SetInterruptHandlers_isr(handle->task, &interrupts);
2057        if ( errCode )
2058        {
2059            BKNI_LeaveCriticalSection();
2060            return BERR_TRACE(errCode);
2061        }
2062    }
2063    handle->interrupts = *pInterrupts;
2064    BKNI_LeaveCriticalSection();
2065    return BERR_SUCCESS;
2066}
2067
2068void BAPE_Decoder_P_SetSampleRate_isr(BAPE_DecoderHandle handle, unsigned sampleRate)
2069{
2070    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2071
2072    handle->node.paths[BAPE_ConnectorFormat_eStereo].connector.sampleRate = sampleRate;
2073    BAPE_Connector_P_SampleRateChange_isr(&handle->node.paths[BAPE_ConnectorFormat_eStereo].connector);
2074
2075    handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector.sampleRate = sampleRate;
2076    BAPE_Connector_P_SampleRateChange_isr(&handle->node.paths[BAPE_ConnectorFormat_eMultichannel].connector);
2077
2078    handle->node.paths[BAPE_ConnectorFormat_eMono].connector.sampleRate = sampleRate;
2079    BAPE_Connector_P_SampleRateChange_isr(&handle->node.paths[BAPE_ConnectorFormat_eMono].connector);
2080
2081    /* AC3+ Passthrough is 4x the sample rate */
2082    if ( handle->startSettings.codec == BAVC_AudioCompressionStd_eAc3Plus &&
2083         handle->passthrough == true )
2084    {
2085        if ( sampleRate == 32000 )
2086        {
2087            BDBG_WRN(("AC3 Plus compressed passthrough is not supported at 32kHz sampling rates."));
2088        }       
2089        sampleRate *= 4;
2090    }
2091    handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector.sampleRate = sampleRate;
2092    BAPE_Connector_P_SampleRateChange_isr(&handle->node.paths[BAPE_ConnectorFormat_eCompressed].connector);
2093}
2094
2095void BAPE_Decoder_GetDefaultCdbItbConfig(
2096    BAPE_DecoderHandle handle,
2097    BAVC_CdbItbConfig *pConfig  /* [out] */
2098    )
2099{
2100    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2101    BSTD_UNUSED(handle);
2102    BKNI_Memset(pConfig, 0, sizeof(BAVC_CdbItbConfig));
2103    pConfig->Cdb.Length = 256*1024;
2104    pConfig->Cdb.Alignment = 6; /* cache line on 4380 */
2105    pConfig->Itb.Length = 128*1024;
2106    pConfig->Itb.Alignment = 6; /* cache line on 4380 */
2107#if BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE
2108    pConfig->Cdb.LittleEndian = true;
2109#else
2110    pConfig->Cdb.LittleEndian = false;
2111#endif
2112}
2113
2114BERR_Code BAPE_Decoder_SetStcValid_isr(
2115    BAPE_DecoderHandle handle
2116    )
2117{
2118    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2119    if ( BAPE_Decoder_P_TaskValid_isr(handle) )
2120    {
2121        BDSP_AudioTaskTsmSettings tsmSettings;
2122        BERR_Code errCode;
2123        BDSP_AudioTask_GetTsmSettings_isr(handle->task, 0, 0, &tsmSettings);
2124        BAPE_DSP_P_SET_VARIABLE(tsmSettings, eSTCValid, BDSP_Raaga_eTsmBool_True);
2125        errCode = BDSP_AudioTask_SetTsmSettings_isr(handle->task, 0, 0, &tsmSettings);
2126        if ( errCode )
2127        {
2128            return BERR_TRACE(errCode);
2129        }
2130    }
2131    return BERR_SUCCESS;
2132}
2133
2134static void BAPE_Decoder_P_SetupDefaults(BAPE_DecoderHandle handle)
2135{
2136    BDSP_AudioTaskTsmSettings tsmSettings;
2137
2138    BDSP_AudioTask_GetDefaultTsmSettings(&tsmSettings, sizeof(tsmSettings));
2139    handle->tsmSettings.tsmEnabled = tsmSettings.eTsmEnable == BDSP_Raaga_eTsmBool_True?true:false;
2140    handle->tsmSettings.astmEnabled = tsmSettings.eAstmEnable == BDSP_Raaga_eTsmBool_True?true:false;
2141    handle->tsmSettings.playback = tsmSettings.ePlayBackOn == BDSP_Raaga_eTsmBool_True?true:false;
2142    handle->tsmSettings.ptsOffset = tsmSettings.ui32AVOffset/45;
2143    handle->tsmSettings.thresholds.discard = tsmSettings.i32TSMDiscardThreshold/45;
2144    handle->tsmSettings.thresholds.grossAdjustment = tsmSettings.i32TSMGrossThreshold/45;
2145    handle->tsmSettings.thresholds.smoothTrack = tsmSettings.i32TSMSmoothThreshold/45;
2146    handle->tsmSettings.thresholds.syncLimit = tsmSettings.i32TSMSyncLimitThreshold/45;
2147
2148    BAPE_Decoder_P_GetDefaultCodecSettings(handle);
2149}
2150
2151static void BAPE_Decoder_P_ConvertTsmStatus_isr(BAPE_DecoderTsmStatus *pStatus, const BDSP_AudioTaskTsmStatus *pDspStatus)
2152{
2153    BKNI_Memset(&pStatus->ptsInfo, 0, sizeof(BAVC_PTSInfo));
2154    pStatus->ptsInfo.ui32CurrentPTS = pDspStatus->ui32RunningPts;
2155    switch ( pDspStatus->ePtsType )
2156    {
2157    case BDSP_PtsType_eCoded:
2158        pStatus->ptsInfo.ePTSType = BAVC_PTSType_eCoded;
2159        break;
2160    case BDSP_PtsType_eInterpolatedFromValidPTS:
2161        pStatus->ptsInfo.ePTSType = BAVC_PTSType_eInterpolatedFromValidPTS;
2162        break;
2163    default:
2164        BDBG_WRN(("Invalid DSP PTS type %u", pDspStatus->ePtsType));
2165        /* Fall through */
2166    case BDSP_PtsType_eInterpolatedFromInvalidPTS:
2167        pStatus->ptsInfo.ePTSType = BAVC_PTSType_eInterpolatedFromInvalidPTS;
2168        break;
2169    }
2170    pStatus->ptsStcDifference = pDspStatus->i32PtsToStcPhase;
2171    pStatus->lastFrameLength = pDspStatus->i32TSMUpperThreshold;
2172}
2173
2174static void BAPE_Decoder_P_FirstPts_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus)
2175{
2176    BAPE_DecoderHandle handle = pParam1;
2177
2178    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2179    BSTD_UNUSED(param2);
2180
2181    if ( handle->interrupts.firstPts.pCallback_isr )
2182    {
2183        BAPE_DecoderTsmStatus tsmStatus;
2184        BAPE_Decoder_P_ConvertTsmStatus_isr(&tsmStatus, pTsmStatus);
2185        handle->interrupts.firstPts.pCallback_isr(handle->interrupts.firstPts.pParam1, handle->interrupts.firstPts.param2, &tsmStatus);
2186    }
2187}
2188
2189static void BAPE_Decoder_P_TsmFail_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus)
2190{
2191    BAPE_DecoderHandle handle = pParam1;
2192
2193    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2194    BSTD_UNUSED(param2);
2195
2196    if ( handle->interrupts.tsmFail.pCallback_isr )
2197    {
2198        BAPE_DecoderTsmStatus tsmStatus;
2199        BAPE_Decoder_P_ConvertTsmStatus_isr(&tsmStatus, pTsmStatus);
2200        handle->interrupts.tsmFail.pCallback_isr(handle->interrupts.tsmFail.pParam1, handle->interrupts.tsmFail.param2, &tsmStatus);
2201    }
2202}
2203
2204static void BAPE_Decoder_P_TsmPass_isr(void *pParam1, int param2, const BDSP_AudioTaskTsmStatus *pTsmStatus)
2205{
2206    BAPE_DecoderHandle handle = pParam1;
2207
2208    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2209    BSTD_UNUSED(param2);
2210
2211    if ( handle->interrupts.tsmPass.pCallback_isr )
2212    {
2213        BAPE_DecoderTsmStatus tsmStatus;
2214        BAPE_Decoder_P_ConvertTsmStatus_isr(&tsmStatus, pTsmStatus);
2215        handle->interrupts.tsmPass.pCallback_isr(handle->interrupts.tsmPass.pParam1, handle->interrupts.tsmPass.param2, &tsmStatus);
2216    }
2217}
2218
2219static void BAPE_Decoder_P_SampleRateChange_isr(void *pParam1, int param2, unsigned streamSampleRate, unsigned baseSampleRate)
2220{
2221    BAPE_DecoderHandle handle = pParam1;
2222    unsigned fmmSampleRate=0;
2223
2224    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2225    BSTD_UNUSED(param2);
2226
2227    /* Store stream sample rate for user status */
2228    handle->sampleRate = streamSampleRate;
2229
2230    /* Determine FMM sample rate */
2231    if ( handle->passthrough )
2232    {
2233        switch ( streamSampleRate )
2234        {
2235        default:
2236        case 48000:
2237        case 44100:
2238        case 32000:
2239            fmmSampleRate = streamSampleRate;
2240            break;
2241        case 24000:
2242        case 22050:
2243        case 16000:
2244            fmmSampleRate = streamSampleRate*2; /* LSF */
2245            break;
2246        case 12000:
2247        case 11025:
2248        case  8000:
2249            fmmSampleRate = streamSampleRate*4; /* QSF */
2250            break;
2251        }
2252    }
2253    else
2254    {
2255        fmmSampleRate = baseSampleRate;
2256    }
2257
2258    BDBG_MSG(("Sample Rate Interrupt Received [decoder %u] Stream %u FMM %u", handle->index, streamSampleRate, fmmSampleRate));
2259    /* Apply sample rate downstream - passthrough is at the stream rate and decode is the base rate */
2260    BAPE_Decoder_P_SetSampleRate_isr(handle, fmmSampleRate);
2261    if ( handle->interrupts.sampleRateChange.pCallback_isr )
2262    {
2263        /* Send stream rate to the application */
2264        handle->interrupts.sampleRateChange.pCallback_isr(handle->interrupts.sampleRateChange.pParam1, handle->interrupts.sampleRateChange.param2, streamSampleRate);
2265    }
2266}
2267
2268static void BAPE_Decoder_P_ModeChange_isr(void *pParam1, int param2, unsigned mode)
2269{
2270    BAPE_DecoderHandle handle = pParam1;
2271
2272    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2273    BSTD_UNUSED(param2);
2274    handle->mode = mode;
2275    BDBG_MSG(("Mode Change Received [decoder %u] acmod now %u", handle->index, mode));
2276    if ( handle->interrupts.modeChange.pCallback_isr )
2277    {
2278        handle->interrupts.modeChange.pCallback_isr(handle->interrupts.modeChange.pParam1, handle->interrupts.modeChange.param2);
2279    }
2280}
2281
2282static void BAPE_Decoder_P_BitrateChange_isr(void *pParam1, int param2, const BDSP_AudioBitRateChangeInfo *pInfo)
2283{
2284    BAPE_DecoderHandle handle = pParam1;
2285
2286    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2287    BSTD_UNUSED(param2);
2288    BKNI_Memcpy(&handle->bitRateInfo, pInfo, sizeof(*pInfo));
2289#if 0
2290    BDBG_MSG(("Bitrate Interrupt Received [decoder %u]", handle->index));
2291#endif
2292    if ( handle->interrupts.bitrateChange.pCallback_isr )
2293    {
2294        handle->interrupts.bitrateChange.pCallback_isr(handle->interrupts.bitrateChange.pParam1, handle->interrupts.bitrateChange.param2);
2295    }
2296}
2297
2298static void BAPE_Decoder_P_Overflow_isr(void *pParam1, int param2)
2299{
2300    BAPE_DecoderHandle handle = pParam1;
2301
2302    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2303    BSTD_UNUSED(param2);
2304    BDBG_MSG(("CDB/ITB Overflow Interrupt Received [decoder %u]", handle->index));
2305    if ( handle->interrupts.cdbItbOverflow.pCallback_isr )
2306    {
2307        handle->interrupts.cdbItbOverflow.pCallback_isr(handle->interrupts.cdbItbOverflow.pParam1, handle->interrupts.cdbItbOverflow.param2);
2308    }
2309}
2310
2311static void BAPE_Decoder_P_StatusReady_isr(void *pParam1, int param2)
2312{
2313    BAPE_DecoderHandle handle = pParam1;
2314    BDSP_AudioInterruptHandlers interrupts;
2315
2316    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2317    BSTD_UNUSED(param2);
2318    BDBG_MSG(("Status Ready Interrupt Received [decoder %u]", handle->index));
2319    if ( handle->interrupts.statusReady.pCallback_isr )
2320    {
2321        handle->interrupts.statusReady.pCallback_isr(handle->interrupts.statusReady.pParam1, handle->interrupts.statusReady.param2);
2322    }
2323
2324    /* This interrupt will fire each frame, but we only want the first one.  Disable the interrupt after it fires. */
2325    BDSP_AudioTask_GetInterruptHandlers_isr(handle->task, &interrupts);
2326    interrupts.statusReady.pCallback_isr = NULL;
2327    interrupts.statusReady.pParam1 = handle;
2328    (void)BDSP_AudioTask_SetInterruptHandlers_isr(handle->task, &interrupts);
2329}
2330
2331static BERR_Code BAPE_Decoder_P_InputFormatChange_isr(
2332    BAPE_PathNode *pNode,
2333    BAPE_InputPort inputPort
2334    )
2335{
2336    BAPE_DecoderHandle handle;   
2337    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
2338    BDBG_OBJECT_ASSERT(inputPort, BAPE_InputPort);
2339    BKNI_ASSERT_ISR_CONTEXT();
2340    handle = pNode->pHandle;
2341    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2342    /* On the fly format changes are not possible */
2343    if ( (inputPort->compressed      != handle->inputCompressed) ||
2344         (inputPort->numChannelPairs != handle->inputChannelPairs) )
2345    {
2346        BDBG_MSG(("Input data format has changed.  Halting capture."));
2347       if ( handle->interrupts.inputHalted.pCallback_isr )
2348       {
2349           handle->interrupts.inputHalted.pCallback_isr(handle->interrupts.inputHalted.pParam1, handle->interrupts.inputHalted.param2);
2350       }
2351       /* Intentionally omitted BERR_TRACE */
2352       return BERR_NOT_SUPPORTED;
2353    }
2354    return BERR_SUCCESS;
2355}
2356
2357static void BAPE_Decoder_P_CleanupTaskCreateSetings(BAPE_DecoderHandle handle)
2358{
2359    unsigned i;
2360
2361    /* The first branch is always static.  Others need to be BKNI_Free()'d. */
2362    /* This is not an ideal programming model, but workable */
2363    for ( i = 1; i < handle->taskCreateSettings.numBranches; i++ )
2364    {
2365        BDBG_ASSERT(NULL != handle->taskCreateSettings.pBranchInfo[i]);
2366        BKNI_Free(handle->taskCreateSettings.pBranchInfo[i]);
2367    }
2368    /* Reset structure to defaults */
2369    BDSP_Task_GetDefaultCreateSettings(handle->deviceHandle->dspContext, &handle->taskCreateSettings);
2370}
2371
2372static BERR_Code BAPE_Decoder_P_ApplyFramesyncSettings(BAPE_DecoderHandle handle)
2373{
2374    BDSP_AudioTaskDatasyncSettings datasyncSettings;
2375    BERR_Code errCode;
2376   
2377    errCode = BDSP_AudioTask_GetDatasyncSettings(handle->task, 0, 0, 
2378                                                 &datasyncSettings);
2379    if ( errCode )
2380    {
2381        return BERR_TRACE(errCode);
2382    }
2383
2384    datasyncSettings.eEnableTargetSync = handle->startSettings.targetSyncEnabled?BDSP_AF_P_eEnable:BDSP_AF_P_eDisable;
2385    if ( handle->startSettings.inputPort )
2386    {
2387        /* Setup input port specifics */
2388        datasyncSettings.eEnablePESBasedFrameSync = BDSP_AF_P_eEnable;
2389        switch ( handle->startSettings.inputPort->type )
2390        {
2391        case BAPE_InputPortType_eI2s:           
2392            BDBG_ASSERT(0 == handle->startSettings.inputPort->index || 1 == handle->startSettings.inputPort->index);
2393            datasyncSettings.eAudioIpSourceType = (handle->startSettings.inputPort->index == 0) ? BDSP_Raaga_Audio_AudioInputSource_eExtI2s0 : BDSP_Raaga_Audio_AudioInputSource_eCapPortRfI2s;
2394            datasyncSettings.uAudioIpSourceDetail.ui32SamplingFrequency = handle->startSettings.inputPort->sampleRate;
2395            break;
2396        case BAPE_InputPortType_eRf:
2397            BDBG_ASSERT(0 == handle->startSettings.inputPort->index);
2398            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortRfI2s;
2399            datasyncSettings.uAudioIpSourceDetail.ui32SamplingFrequency = handle->startSettings.inputPort->sampleRate;
2400            break;
2401        case BAPE_InputPortType_eAdc:
2402            BDBG_ASSERT(0 == handle->startSettings.inputPort->index);
2403            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortAdc;
2404            datasyncSettings.uAudioIpSourceDetail.ui32SamplingFrequency = handle->startSettings.inputPort->sampleRate;
2405            break;
2406#if defined BCHP_SPDIF_RCVR_CTRL_STATUS
2407        case BAPE_InputPortType_eSpdif:
2408            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortSpdif;
2409            datasyncSettings.uAudioIpSourceDetail.ui32MaiCtrlStatusRegAddr = BCHP_PHYSICAL_OFFSET + BCHP_SPDIF_RCVR_CTRL_STATUS;
2410            break;
2411#endif
2412#if defined BCHP_AUD_FMM_IOP_IN_SPDIF_0_STATUS
2413        case BAPE_InputPortType_eSpdif:
2414            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortSpdif;
2415            datasyncSettings.uAudioIpSourceDetail.ui32MaiCtrlStatusRegAddr = BCHP_PHYSICAL_OFFSET + BCHP_AUD_FMM_IOP_IN_SPDIF_0_STATUS;
2416            break;
2417#endif
2418#if defined BCHP_HDMI_RCVR_CTRL_MAI_FORMAT
2419        case BAPE_InputPortType_eMai:
2420            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortHdmi;
2421            datasyncSettings.uAudioIpSourceDetail.ui32MaiCtrlStatusRegAddr = BCHP_PHYSICAL_OFFSET + BCHP_HDMI_RCVR_CTRL_MAI_FORMAT;
2422            break;
2423#endif
2424#if defined BCHP_AUD_FMM_IOP_IN_HDMI_0_MAI_FORMAT
2425        case BAPE_InputPortType_eMai:
2426            datasyncSettings.eAudioIpSourceType = BDSP_Raaga_Audio_AudioInputSource_eCapPortHdmi;
2427            datasyncSettings.uAudioIpSourceDetail.ui32MaiCtrlStatusRegAddr = BCHP_PHYSICAL_OFFSET + BCHP_AUD_FMM_IOP_IN_HDMI_0_MAI_FORMAT;
2428            break;
2429#endif
2430        default:
2431            BDBG_ERR(("Input %s is not supported.", handle->startSettings.inputPort->pName));
2432            return BERR_TRACE(BERR_NOT_SUPPORTED);
2433        }
2434    }
2435
2436    /* Codec-Specific Settings (currently only for WMA) */
2437    switch ( handle->startSettings.codec )
2438    {
2439    case BAVC_AudioCompressionStd_eWmaStd:
2440    case BAVC_AudioCompressionStd_eWmaPro:
2441        datasyncSettings.uAlgoSpecConfigStruct.sWmaConfig.eWMAIpType = BDSP_Raaga_Audio_WMAIpType_eASF;
2442        break;
2443    case BAVC_AudioCompressionStd_eWmaStdTs:
2444        datasyncSettings.uAlgoSpecConfigStruct.sWmaConfig.eWMAIpType = BDSP_Raaga_Audio_WMAIpType_eTS;
2445        break;
2446    case BAVC_AudioCompressionStd_eLpcmDvd:
2447        datasyncSettings.uAlgoSpecConfigStruct.sLpcmConfig.eLpcmType = BDSP_Raaga_Audio_LpcmAlgoType_eDvd;
2448        break;
2449    case BAVC_AudioCompressionStd_eLpcm1394:
2450        datasyncSettings.uAlgoSpecConfigStruct.sLpcmConfig.eLpcmType = BDSP_Raaga_Audio_LpcmAlgoType_eIeee1394;
2451        break;
2452    default:
2453        /* Value doesn't matter */
2454        break;
2455    }
2456
2457    errCode = BDSP_AudioTask_SetDatasyncSettings(handle->task, 0, 0, 
2458                                                 &datasyncSettings);
2459    if ( errCode )
2460    {
2461        return BERR_TRACE(errCode);
2462    }
2463
2464    return BERR_SUCCESS;
2465}
2466
2467/* Used to synchronize interrupts so they don't try to operate on a stopping task */
2468static bool BAPE_Decoder_P_TaskValid_isr(BAPE_DecoderHandle handle)
2469{
2470#if 0
2471    switch ( handle->state )
2472    {
2473    case BAPE_DecoderState_eStarted:
2474    case BAPE_DecoderState_ePaused:
2475        return (handle->task != NULL)?true:false;
2476    default:
2477        return false;
2478    }
2479#endif
2480    return (handle->task != NULL)?true:false;
2481}
2482
2483static BERR_Code BAPE_Decoder_P_DeriveMultistreamLinkage(BAPE_DecoderHandle handle)
2484{
2485    BAPE_PathNode *pNode;
2486    BAPE_DolbyDigitalReencodeHandle ddre=NULL;
2487    BAPE_MixerHandle fwMixer=NULL;
2488    unsigned numFound;
2489    bool master=true;
2490
2491    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2492
2493    /* Find DDRE and FW Mixer.  Need to determine usage modes based on these. */
2494    BAPE_PathNode_P_FindConsumersBySubtype(&handle->node, BAPE_PathNodeType_ePostProcessor, BAPE_PostProcessorType_eDdre, 1, &numFound, &pNode);
2495    switch ( numFound )
2496    {
2497    case 0:
2498        break;
2499    case 1:
2500        ddre = pNode->pHandle;
2501        break;
2502    default:
2503        BDBG_ERR(("Multiple DDRE consumers found downstream from decoder %u.  This is not supported.", handle->index));
2504        return BERR_TRACE(BERR_NOT_SUPPORTED);
2505    }
2506    BAPE_PathNode_P_FindConsumersBySubtype(&handle->node, BAPE_PathNodeType_eMixer, BAPE_MixerType_eDsp, 1, &numFound, &pNode);
2507    switch ( numFound )
2508    {
2509    case 0:
2510        break;
2511    case 1:
2512        fwMixer = pNode->pHandle;
2513        break;
2514    default:
2515        BDBG_ERR(("Multiple DSP mixer consumers found downstream from decoder %u.  This is not supported.", handle->index));
2516        return BERR_TRACE(BERR_NOT_SUPPORTED);
2517    }
2518    if ( fwMixer )
2519    {
2520        BAPE_PathConnector *pMaster = fwMixer->master;
2521        if ( NULL == pMaster )
2522        {
2523            BDBG_ERR(("A DSP mixer was found downstream from decoder %u but it does not have a master input designated.  This is not supported.", handle->index));
2524            return BERR_TRACE(BERR_NOT_SUPPORTED);
2525        }
2526        pNode = pMaster->pParent;
2527        if ( pNode == &handle->node )
2528        {
2529            /* I am the master directly */
2530            master = true;
2531        }
2532        else
2533        {
2534            /* Possibly another post-processing node is between the decoder and FW mixer.  Test if the master between this node and the mixer. */
2535            master = BAPE_PathNode_P_NodeIsConsumer(&handle->node, pNode);
2536        }
2537    }
2538
2539    /* Success.  Store results */
2540    handle->ddre = ddre;
2541    handle->fwMixer = fwMixer;
2542    handle->fwMixerMaster = master;
2543
2544    return BERR_SUCCESS;
2545}
2546
2547BERR_Code BAPE_Decoder_EnterUnderflowMode(
2548    BAPE_DecoderHandle handle
2549    )
2550{
2551    BERR_Code errCode;
2552    BDBG_OBJECT_ASSERT(handle, BAPE_Decoder);
2553
2554    if ( handle->state == BAPE_DecoderState_eStarted &&
2555         handle->startSettings.nonRealTime )
2556    {
2557        errCode = BDSP_AudioTask_AudioGapFill(handle->task);
2558        if ( errCode )
2559        {
2560            return BERR_TRACE(errCode);
2561        }
2562
2563        return BERR_SUCCESS;
2564    }
2565
2566    BDBG_ERR(("Decoder must be started in non-realtime mode to enter underflow mode"));
2567    return BERR_TRACE(BERR_NOT_SUPPORTED);
2568}
2569
Note: See TracBrowser for help on using the repository browser.