| 1 | /*************************************************************************** |
|---|
| 2 | * (c)2004-2011 Broadcom Corporation |
|---|
| 3 | * |
|---|
| 4 | * This program is the proprietary software of Broadcom Corporation and/or its licensors, |
|---|
| 5 | * and may only be used, duplicated, modified or distributed pursuant to the terms and |
|---|
| 6 | * conditions of a separate, written license agreement executed between you and Broadcom |
|---|
| 7 | * (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants |
|---|
| 8 | * no license (express or implied), right to use, or waiver of any kind with respect to the |
|---|
| 9 | * Software, and Broadcom expressly reserves all rights in and to the Software and all |
|---|
| 10 | * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU |
|---|
| 11 | * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY |
|---|
| 12 | * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. |
|---|
| 13 | * |
|---|
| 14 | * Except as expressly set forth in the Authorized License, |
|---|
| 15 | * |
|---|
| 16 | * 1. This program, including its structure, sequence and organization, constitutes the valuable trade |
|---|
| 17 | * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, |
|---|
| 18 | * and to use this information only in connection with your use of Broadcom integrated circuit products. |
|---|
| 19 | * |
|---|
| 20 | * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" |
|---|
| 21 | * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR |
|---|
| 22 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO |
|---|
| 23 | * THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES |
|---|
| 24 | * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, |
|---|
| 25 | * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION |
|---|
| 26 | * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF |
|---|
| 27 | * USE OR PERFORMANCE OF THE SOFTWARE. |
|---|
| 28 | * |
|---|
| 29 | * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS |
|---|
| 30 | * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR |
|---|
| 31 | * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR |
|---|
| 32 | * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF |
|---|
| 33 | * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT |
|---|
| 34 | * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE |
|---|
| 35 | * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF |
|---|
| 36 | * ANY LIMITED REMEDY. |
|---|
| 37 | * |
|---|
| 38 | * $brcm_Workfile: nexus_audio_decoder.c $ |
|---|
| 39 | * $brcm_Revision: 47 $ |
|---|
| 40 | * $brcm_Date: 12/21/11 4:52p $ |
|---|
| 41 | * |
|---|
| 42 | * API Description: |
|---|
| 43 | * API name: AudioDecoder |
|---|
| 44 | * API for audio decoder management. |
|---|
| 45 | * |
|---|
| 46 | * Revision History: |
|---|
| 47 | * |
|---|
| 48 | * $brcm_Log: /nexus/modules/audio/7422/src/nexus_audio_decoder.c $ |
|---|
| 49 | * |
|---|
| 50 | * 47 12/21/11 4:52p jgarrett |
|---|
| 51 | * SW7425-2042: Audio decoder will only report running when actually |
|---|
| 52 | * started. This resolves issues with attaching a mixer to HDMI/SPDIF |
|---|
| 53 | * inputs |
|---|
| 54 | * |
|---|
| 55 | * 46 12/21/11 12:45p jgarrett |
|---|
| 56 | * SW7425-1756: Bitrate changes should not fire sourceChagned callback |
|---|
| 57 | * |
|---|
| 58 | * 45 12/21/11 12:21p jgarrett |
|---|
| 59 | * SW7425-2000: Disabling TSM for OGG source material |
|---|
| 60 | * |
|---|
| 61 | * 44 12/20/11 4:18p jgarrett |
|---|
| 62 | * SW7425-1018: Propagating loudness equivalence setting to APE |
|---|
| 63 | * |
|---|
| 64 | * 43 12/20/11 4:13p jgarrett |
|---|
| 65 | * SW7425-1018: Adding initial A/85 implementation |
|---|
| 66 | * |
|---|
| 67 | * 42 12/13/11 9:44p bandrews |
|---|
| 68 | * SW7425-1772: merge to main |
|---|
| 69 | * |
|---|
| 70 | * SW7425-1772/4 12/12/11 10:18p bandrews |
|---|
| 71 | * SW7425-1772: merge from main |
|---|
| 72 | * |
|---|
| 73 | * 41 12/9/11 5:51p jgarrett |
|---|
| 74 | * SW7425-1756: Adding stream status callback and bitrate/mode change |
|---|
| 75 | * handling |
|---|
| 76 | * |
|---|
| 77 | * 40 12/7/11 5:36p jgarrett |
|---|
| 78 | * SW7425-1893: Adding MPEG Conformance mode |
|---|
| 79 | * |
|---|
| 80 | * 39 11/21/11 11:30a jgarrett |
|---|
| 81 | * SW7425-1756: Adding overflow callback |
|---|
| 82 | * |
|---|
| 83 | * 38 11/18/11 3:04p jgarrett |
|---|
| 84 | * SW7425-1756: Adding PTS callbacks and overflow callback |
|---|
| 85 | * |
|---|
| 86 | * 37 11/18/11 2:57p jgarrett |
|---|
| 87 | * SW7425-1519: Adding decoder mixing mode settings |
|---|
| 88 | * |
|---|
| 89 | * SW7425-1772/3 12/12/11 10:02p bandrews |
|---|
| 90 | * SW7425-1772: add priority scheme to stc channel |
|---|
| 91 | * |
|---|
| 92 | * SW7425-1772/2 11/17/11 9:19p bandrews |
|---|
| 93 | * SW7425-1772: make decoders id themselves to stc channel as index, |
|---|
| 94 | * instead of funky way based on compressed / pcm / input |
|---|
| 95 | * |
|---|
| 96 | * SW7425-1772/1 11/17/11 6:31p bandrews |
|---|
| 97 | * SW7425-1772: 6 channel support to stc channel |
|---|
| 98 | * |
|---|
| 99 | * 36 11/8/11 6:06p jgarrett |
|---|
| 100 | * SW7422-400: Adding audio debug log support in kernel mode |
|---|
| 101 | * |
|---|
| 102 | * 35 11/3/11 6:53p jgarrett |
|---|
| 103 | * SW7422-400: Enabling audio debug logs on 40nm APE chips |
|---|
| 104 | * |
|---|
| 105 | * 34 11/2/11 6:26p jgarrett |
|---|
| 106 | * SW7422-400: Adding routines for audio DSP debug |
|---|
| 107 | * |
|---|
| 108 | * 33 10/25/11 2:50p gskerl |
|---|
| 109 | * SW7231-129: Removed call to NEXUS_AudioInput_P_RemoveInput() from |
|---|
| 110 | * NEXUS_AudioDecoder_Start() |
|---|
| 111 | * |
|---|
| 112 | * 32 10/10/11 1:42p jgarrett |
|---|
| 113 | * SW7425-1457: Ensuring PidChannel is only refernced after |
|---|
| 114 | * NEXUS_AudioDecoder_Start() during ApplySettings() |
|---|
| 115 | * |
|---|
| 116 | * 31 10/6/11 6:20p jgarrett |
|---|
| 117 | * SW7425-1428: Fixing pause handling |
|---|
| 118 | * |
|---|
| 119 | * 30 9/30/11 5:31p jgarrett |
|---|
| 120 | * SW7425-1297: Changes for 0.5x..2.0x audio trick modes and automatic |
|---|
| 121 | * muting on unsupported rates |
|---|
| 122 | * |
|---|
| 123 | * SW7425-1297/1 9/28/11 6:29p jgarrett |
|---|
| 124 | * SW7425-1297: Adding automatic mute on unsupported trick rates |
|---|
| 125 | * |
|---|
| 126 | * 29 9/20/11 5:10p jgarrett |
|---|
| 127 | * SW7425-1045: Mapping additional settings and status between nexus and |
|---|
| 128 | * the audio FW |
|---|
| 129 | * |
|---|
| 130 | * 28 9/9/11 3:20p jgarrett |
|---|
| 131 | * SW7552-113: Merge to main branch (original branch was inadvertent) |
|---|
| 132 | * |
|---|
| 133 | * 27 9/9/11 10:08a ialauder |
|---|
| 134 | * SWDTV-8364: Added call to convert the decoder codec to the nexus codec |
|---|
| 135 | * when callling NEXUS_AudioDecoder_GetStatus(). |
|---|
| 136 | * |
|---|
| 137 | * SW7425-1212/1 9/9/11 3:12p jgarrett |
|---|
| 138 | * SW7552-113: Adding ASTM hooks |
|---|
| 139 | * |
|---|
| 140 | * 24 8/15/11 5:01p jgarrett |
|---|
| 141 | * SW7346-438: Coverity CID 34705,32711 |
|---|
| 142 | * |
|---|
| 143 | * 23 8/8/11 6:01p jgarrett |
|---|
| 144 | * SW7346-412: Propagating errors from BAPE_GetTsmStatus |
|---|
| 145 | * |
|---|
| 146 | * 22 7/29/11 5:34p jgarrett |
|---|
| 147 | * SW7346-358: coverity cid 33739 |
|---|
| 148 | * |
|---|
| 149 | * 21 7/14/11 1:02p jgarrett |
|---|
| 150 | * SW7425-406: Fixing TSM Playback setting with no STC channel |
|---|
| 151 | * |
|---|
| 152 | * 20 7/1/11 10:54a jgarrett |
|---|
| 153 | * SW7405-5072: Adding numWatchdogs and raveIndex status |
|---|
| 154 | * |
|---|
| 155 | * 19 6/22/11 11:36a jgarrett |
|---|
| 156 | * SW7425-654: Adding NRT hooks |
|---|
| 157 | * |
|---|
| 158 | * 18 6/21/11 5:03p jgarrett |
|---|
| 159 | * SW7425-654: Adding Audio NRT APIs |
|---|
| 160 | * |
|---|
| 161 | * 17 6/9/11 2:56p jgarrett |
|---|
| 162 | * SW7425-406: Adding secondary decoder support |
|---|
| 163 | * |
|---|
| 164 | * 16 5/25/11 5:16p jgarrett |
|---|
| 165 | * SW7425-408: Adding BDBG_OBJECT to input/output types and MS11 features |
|---|
| 166 | * |
|---|
| 167 | * 15 5/20/11 11:32a jgarrett |
|---|
| 168 | * SW7405-5335: Adding numBytesDecoded to NEXUS_AudioDecoderStatus |
|---|
| 169 | * |
|---|
| 170 | * 14 5/5/11 6:07p jgarrett |
|---|
| 171 | * SW7425-524: Muting decoder on invalid trick modes |
|---|
| 172 | * |
|---|
| 173 | * 13 5/4/11 4:04p jgarrett |
|---|
| 174 | * SW7425-469: Adding no_watchdog environment variable to disable audio |
|---|
| 175 | * watchdog |
|---|
| 176 | * |
|---|
| 177 | * 12 4/26/11 4:23p jgarrett |
|---|
| 178 | * SW7425-437: Not allowing dead nodes in the filter graph |
|---|
| 179 | * |
|---|
| 180 | * 11 4/20/11 6:16p jtna |
|---|
| 181 | * SW7425-365: fix build warnings for 2.6.37 kernel |
|---|
| 182 | * |
|---|
| 183 | * 10 4/18/11 10:29p jgarrett |
|---|
| 184 | * SW7425-361: Not implicitly forcing audio connection memory to be |
|---|
| 185 | * allocated with sync mute |
|---|
| 186 | * |
|---|
| 187 | * 9 3/23/11 6:28p jgarrett |
|---|
| 188 | * SW7422-352: adding HDMI input support to nexus |
|---|
| 189 | * |
|---|
| 190 | * 8 3/23/11 4:29p jgarrett |
|---|
| 191 | * SW7422-403: Fixing sync mute and DSOLA |
|---|
| 192 | * |
|---|
| 193 | * 7 3/21/11 6:59p jgarrett |
|---|
| 194 | * SW7422-146: Fixing crash on stop with external inputs |
|---|
| 195 | * |
|---|
| 196 | * 6 3/11/11 6:02p jgarrett |
|---|
| 197 | * SW7422-146: Decoder supports external inputs |
|---|
| 198 | * |
|---|
| 199 | * 5 2/22/11 5:44p jgarrett |
|---|
| 200 | * SW7422-146: Implemented type renaming based on filter graph review |
|---|
| 201 | * comments |
|---|
| 202 | * |
|---|
| 203 | * 4 2/7/11 11:30a jgarrett |
|---|
| 204 | * SW7422-146: Implementing DDP -> AC3 conversion and status for |
|---|
| 205 | * MPEG/AAC/AC3 |
|---|
| 206 | * |
|---|
| 207 | * 3 1/13/11 5:25p jgarrett |
|---|
| 208 | * SW7422-146: Adding encoder hooks |
|---|
| 209 | * |
|---|
| 210 | * 2 1/12/11 4:25p jgarrett |
|---|
| 211 | * SW7422-146: Refactoring data path from decoder |
|---|
| 212 | * |
|---|
| 213 | * 1 12/17/10 3:56p jgarrett |
|---|
| 214 | * SW7422-146: Adding initial nexus on APE for 7422 |
|---|
| 215 | * |
|---|
| 216 | ***************************************************************************/ |
|---|
| 217 | |
|---|
| 218 | #include "nexus_audio_module.h" |
|---|
| 219 | #include "priv/nexus_audio_decoder_priv.h" |
|---|
| 220 | |
|---|
| 221 | #define RAAGA_DEBUG_LOG_CHANGES 1 |
|---|
| 222 | #include "bdsp_raaga.h" |
|---|
| 223 | |
|---|
| 224 | BDBG_MODULE(nexus_audio_decoder); |
|---|
| 225 | |
|---|
| 226 | BDBG_OBJECT_ID(NEXUS_AudioDecoder); |
|---|
| 227 | static NEXUS_AudioDecoder g_decoders[NEXUS_NUM_AUDIO_DECODERS]; |
|---|
| 228 | |
|---|
| 229 | static void NEXUS_AudioDecoder_P_Watchdog(void *pParam); |
|---|
| 230 | static void NEXUS_AudioDecoder_P_SampleRate(void *pParam); |
|---|
| 231 | static void NEXUS_AudioDecoder_P_ChannelChangeReport(void * context); |
|---|
| 232 | static void NEXUS_AudioDecoder_P_FirstPts_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus); |
|---|
| 233 | static void NEXUS_AudioDecoder_P_AudioTsmFail_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus); |
|---|
| 234 | static void NEXUS_AudioDecoder_P_AudioTsmPass_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus); |
|---|
| 235 | static void NEXUS_AudioDecoder_P_SampleRateChange_isr(void *pParam1, int param2, unsigned sampleRate); |
|---|
| 236 | static void NEXUS_AudioDecoder_P_Lock_isr(void *pParam1, int param2); |
|---|
| 237 | static void NEXUS_AudioDecoder_P_StreamStatusAvailable_isr(void *pParam1, int param2); |
|---|
| 238 | static void NEXUS_AudioDecoder_P_StreamParameterChanged_isr(void *pParam1, int param2); |
|---|
| 239 | static BERR_Code NEXUS_AudioDecoder_P_GetPtsCallback_isr(void *pContext, BAVC_PTSInfo *pPTSInfo); |
|---|
| 240 | static BERR_Code NEXUS_AudioDecoder_P_GetCdbLevelCallback_isr(void *pContext, unsigned *pCdbLevel); |
|---|
| 241 | static BERR_Code NEXUS_AudioDecoder_P_StcValidCallback_isr(void *pContext); |
|---|
| 242 | static void NEXUS_AudioDecoder_P_FifoWatchdog(void *context); |
|---|
| 243 | static void NEXUS_AudioDecoder_P_Watchdog_isr(void *pParam1, int param2); |
|---|
| 244 | static void NEXUS_AudioDecoder_P_InputFormatChange_isr(void *pParam1, int param2); |
|---|
| 245 | static void NEXUS_AudioDecoder_P_InputFormatChange(void *pContext); |
|---|
| 246 | static BERR_Code NEXUS_AudioDecoder_P_SetPcrOffset_isr(void *pContext, uint32_t pcrOffset); |
|---|
| 247 | static BERR_Code NEXUS_AudioDecoder_P_GetPcrOffset_isr(void *pContext, uint32_t *pPcrOffset); |
|---|
| 248 | |
|---|
| 249 | #define LOCK_TRANSPORT() NEXUS_Module_Lock(g_NEXUS_audioModuleData.settings.modules.transport) |
|---|
| 250 | #define UNLOCK_TRANSPORT() NEXUS_Module_Unlock(g_NEXUS_audioModuleData.settings.modules.transport) |
|---|
| 251 | |
|---|
| 252 | static BKNI_EventHandle g_watchdogEvent; |
|---|
| 253 | static NEXUS_EventCallbackHandle g_watchdogCallback; |
|---|
| 254 | static unsigned g_numWatchdogs; |
|---|
| 255 | |
|---|
| 256 | static void NEXUS_AudioDecoder_P_Watchdog_isr(void *pParam1, int param2) |
|---|
| 257 | { |
|---|
| 258 | BSTD_UNUSED(pParam1); |
|---|
| 259 | BSTD_UNUSED(param2); |
|---|
| 260 | BDBG_ERR(("Audio Watchdog Interrupt Received")); |
|---|
| 261 | BKNI_SetEvent_isr(g_watchdogEvent); |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | NEXUS_Error NEXUS_AudioDecoder_P_Init(void) |
|---|
| 265 | { |
|---|
| 266 | BERR_Code errCode; |
|---|
| 267 | BAPE_InterruptHandlers interrupts; |
|---|
| 268 | |
|---|
| 269 | g_numWatchdogs = 0; |
|---|
| 270 | errCode = BKNI_CreateEvent(&g_watchdogEvent); |
|---|
| 271 | if ( errCode ) |
|---|
| 272 | { |
|---|
| 273 | return BERR_TRACE(errCode); |
|---|
| 274 | } |
|---|
| 275 | g_watchdogCallback = NEXUS_RegisterEvent(g_watchdogEvent, NEXUS_AudioDecoder_P_Watchdog, NULL); |
|---|
| 276 | if ( NULL == g_watchdogCallback ) |
|---|
| 277 | { |
|---|
| 278 | BKNI_DestroyEvent(g_watchdogEvent); |
|---|
| 279 | g_watchdogEvent = NULL; |
|---|
| 280 | return BERR_TRACE(BERR_OS_ERROR); |
|---|
| 281 | } |
|---|
| 282 | |
|---|
| 283 | /* Allow watchdog to be disabled for debugging */ |
|---|
| 284 | if ( !NEXUS_GetEnv("no_watchdog") && g_NEXUS_audioModuleData.settings.watchdogEnabled ) |
|---|
| 285 | { |
|---|
| 286 | BAPE_GetInterruptHandlers(NEXUS_AUDIO_DEVICE_HANDLE, &interrupts); |
|---|
| 287 | interrupts.watchdog.pCallback_isr = NEXUS_AudioDecoder_P_Watchdog_isr; |
|---|
| 288 | errCode = BAPE_SetInterruptHandlers(NEXUS_AUDIO_DEVICE_HANDLE, &interrupts); |
|---|
| 289 | if ( errCode ) |
|---|
| 290 | { |
|---|
| 291 | NEXUS_UnregisterEvent(g_watchdogCallback); |
|---|
| 292 | g_watchdogCallback = NULL; |
|---|
| 293 | BKNI_DestroyEvent(g_watchdogEvent); |
|---|
| 294 | g_watchdogEvent = NULL; |
|---|
| 295 | return BERR_TRACE(errCode); |
|---|
| 296 | } |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | return BERR_SUCCESS; |
|---|
| 300 | } |
|---|
| 301 | |
|---|
| 302 | void NEXUS_AudioDecoder_P_Uninit(void) |
|---|
| 303 | { |
|---|
| 304 | BAPE_InterruptHandlers interrupts; |
|---|
| 305 | |
|---|
| 306 | BAPE_GetInterruptHandlers(NEXUS_AUDIO_DEVICE_HANDLE, &interrupts); |
|---|
| 307 | interrupts.watchdog.pCallback_isr = NULL; |
|---|
| 308 | BAPE_SetInterruptHandlers(NEXUS_AUDIO_DEVICE_HANDLE, &interrupts); |
|---|
| 309 | |
|---|
| 310 | NEXUS_UnregisterEvent(g_watchdogCallback); |
|---|
| 311 | g_watchdogCallback = NULL; |
|---|
| 312 | BKNI_DestroyEvent(g_watchdogEvent); |
|---|
| 313 | g_watchdogEvent = NULL; |
|---|
| 314 | } |
|---|
| 315 | |
|---|
| 316 | /*************************************************************************** |
|---|
| 317 | Summary: |
|---|
| 318 | Get default open settings for an audio decoder |
|---|
| 319 | ***************************************************************************/ |
|---|
| 320 | void NEXUS_AudioDecoder_GetDefaultOpenSettings( |
|---|
| 321 | NEXUS_AudioDecoderOpenSettings *pSettings /* [out] default settings */ |
|---|
| 322 | ) |
|---|
| 323 | { |
|---|
| 324 | BDBG_ASSERT(NULL != pSettings); |
|---|
| 325 | BKNI_Memset(pSettings, 0, sizeof(*pSettings)); |
|---|
| 326 | pSettings->independentDelay = g_NEXUS_audioModuleData.settings.independentDelay; |
|---|
| 327 | } |
|---|
| 328 | |
|---|
| 329 | static void NEXUS_AudioDecoder_P_GetDefaultSettings( |
|---|
| 330 | NEXUS_AudioDecoderSettings *pSettings /* [out] default settings */ |
|---|
| 331 | ) |
|---|
| 332 | { |
|---|
| 333 | int i; |
|---|
| 334 | BDBG_ASSERT(NULL != pSettings); |
|---|
| 335 | BKNI_Memset(pSettings, 0, sizeof(NEXUS_AudioDecoderSettings)); |
|---|
| 336 | pSettings->loudnessEquivalenceEnabled = true; |
|---|
| 337 | for ( i = 0; i < NEXUS_AudioChannel_eMax; i++ ) |
|---|
| 338 | { |
|---|
| 339 | pSettings->volumeMatrix[i][i] = NEXUS_AUDIO_VOLUME_LINEAR_NORMAL; |
|---|
| 340 | } |
|---|
| 341 | } |
|---|
| 342 | |
|---|
| 343 | /*************************************************************************** |
|---|
| 344 | Summary: |
|---|
| 345 | Open an audio decoder of the specified type |
|---|
| 346 | ***************************************************************************/ |
|---|
| 347 | NEXUS_AudioDecoderHandle NEXUS_AudioDecoder_Open( /* attr{destructor=NEXUS_AudioDecoder_Close} */ |
|---|
| 348 | unsigned index, |
|---|
| 349 | const NEXUS_AudioDecoderOpenSettings *pSettings /* settings */ |
|---|
| 350 | ) |
|---|
| 351 | { |
|---|
| 352 | NEXUS_AudioDecoderHandle handle; |
|---|
| 353 | NEXUS_AudioDecoderOpenSettings openSettings; |
|---|
| 354 | NEXUS_RaveOpenSettings raveSettings; |
|---|
| 355 | BAPE_DecoderOpenSettings decoderOpenSettings; |
|---|
| 356 | BAPE_DecoderInterruptHandlers interrupts; |
|---|
| 357 | BAPE_Connector mixerInput; |
|---|
| 358 | BERR_Code errCode; |
|---|
| 359 | unsigned j; |
|---|
| 360 | |
|---|
| 361 | if ( index >= NEXUS_NUM_AUDIO_DECODERS ) |
|---|
| 362 | { |
|---|
| 363 | errCode=BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 364 | return NULL; |
|---|
| 365 | } |
|---|
| 366 | |
|---|
| 367 | handle = &g_decoders[index]; |
|---|
| 368 | |
|---|
| 369 | /* Check if handle is already open */ |
|---|
| 370 | if ( handle->opened ) |
|---|
| 371 | { |
|---|
| 372 | BDBG_ERR(("Decoder %d already opened", index)); |
|---|
| 373 | errCode=BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 374 | return NULL; |
|---|
| 375 | } |
|---|
| 376 | |
|---|
| 377 | if ( NULL == pSettings ) |
|---|
| 378 | { |
|---|
| 379 | NEXUS_AudioDecoder_GetDefaultOpenSettings(&openSettings); |
|---|
| 380 | pSettings = &openSettings; |
|---|
| 381 | } |
|---|
| 382 | |
|---|
| 383 | /* Reset to default state */ |
|---|
| 384 | BKNI_Memset(handle, 0, sizeof(NEXUS_AudioDecoder)); |
|---|
| 385 | BDBG_OBJECT_SET(handle, NEXUS_AudioDecoder); |
|---|
| 386 | handle->index = index; |
|---|
| 387 | handle->stcDecoderType = NEXUS_StcChannelDecoderType_eMax; /* Invalid */ |
|---|
| 388 | handle->trickMute = false; |
|---|
| 389 | handle->trickForceStopped = false; |
|---|
| 390 | |
|---|
| 391 | #if NEXUS_HAS_ASTM |
|---|
| 392 | BKNI_Memset(&handle->astm.settings, 0, sizeof(NEXUS_AudioDecoderAstmSettings)); |
|---|
| 393 | BKNI_Memset(&handle->astm.status, 0, sizeof(NEXUS_AudioDecoderAstmStatus)); |
|---|
| 394 | #endif |
|---|
| 395 | |
|---|
| 396 | for ( j = 0; j < NEXUS_AudioDecoderConnectorType_eMax; j++ ) |
|---|
| 397 | { |
|---|
| 398 | /* Setup handle linkage */ |
|---|
| 399 | NEXUS_AUDIO_INPUT_INIT(&handle->connectors[j], NEXUS_AudioInputType_eDecoder, handle); |
|---|
| 400 | |
|---|
| 401 | /* Set format per-connector */ |
|---|
| 402 | if ( j == NEXUS_AudioDecoderConnectorType_eStereo ) |
|---|
| 403 | { |
|---|
| 404 | handle->connectors[j].format = NEXUS_AudioInputFormat_ePcmStereo; |
|---|
| 405 | } |
|---|
| 406 | else if ( j == NEXUS_AudioDecoderConnectorType_eMultichannel ) |
|---|
| 407 | { |
|---|
| 408 | /* The correct value for this is set later if multichannel is enabled */ |
|---|
| 409 | handle->connectors[j].format = NEXUS_AudioInputFormat_eNone; |
|---|
| 410 | } |
|---|
| 411 | else |
|---|
| 412 | { |
|---|
| 413 | handle->connectors[j].format = NEXUS_AudioInputFormat_eCompressed; |
|---|
| 414 | } |
|---|
| 415 | |
|---|
| 416 | /* Invalidate outputs */ |
|---|
| 417 | BKNI_Memset(&(handle->outputLists[j]), 0, sizeof(NEXUS_AudioOutputList)); |
|---|
| 418 | } |
|---|
| 419 | |
|---|
| 420 | NEXUS_AudioDecoder_P_TrickReset(handle); |
|---|
| 421 | |
|---|
| 422 | /* Create Events */ |
|---|
| 423 | errCode = BKNI_CreateEvent(&handle->sampleRateEvent); |
|---|
| 424 | if ( errCode ) |
|---|
| 425 | { |
|---|
| 426 | errCode=BERR_TRACE(errCode); |
|---|
| 427 | goto err_sample_rate_event; |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | handle->sampleRateCallback = NEXUS_RegisterEvent(handle->sampleRateEvent, NEXUS_AudioDecoder_P_SampleRate, handle); |
|---|
| 431 | if ( NULL == handle->sampleRateCallback ) |
|---|
| 432 | { |
|---|
| 433 | errCode=BERR_TRACE(BERR_OS_ERROR); |
|---|
| 434 | goto err_sample_rate_callback; |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | errCode = BKNI_CreateEvent(&handle->channelChangeReportEvent); |
|---|
| 438 | if ( errCode ) |
|---|
| 439 | { |
|---|
| 440 | errCode=BERR_TRACE(errCode); |
|---|
| 441 | goto err_channel_change_report_event; |
|---|
| 442 | } |
|---|
| 443 | |
|---|
| 444 | handle->channelChangeReportEventHandler = NEXUS_RegisterEvent(handle->channelChangeReportEvent, NEXUS_AudioDecoder_P_ChannelChangeReport, handle); |
|---|
| 445 | if ( NULL == handle->channelChangeReportEventHandler ) |
|---|
| 446 | { |
|---|
| 447 | errCode=BERR_TRACE(BERR_OS_ERROR); |
|---|
| 448 | goto err_channel_change_report_event_handler; |
|---|
| 449 | } |
|---|
| 450 | |
|---|
| 451 | errCode = BKNI_CreateEvent(&handle->inputFormatChangeEvent); |
|---|
| 452 | if ( errCode ) |
|---|
| 453 | { |
|---|
| 454 | errCode=BERR_TRACE(errCode); |
|---|
| 455 | goto err_input_format_change_event; |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | handle->inputFormatChangeEventHandler = NEXUS_RegisterEvent(handle->inputFormatChangeEvent, NEXUS_AudioDecoder_P_InputFormatChange, handle); |
|---|
| 459 | if ( NULL == handle->inputFormatChangeEventHandler ) |
|---|
| 460 | { |
|---|
| 461 | errCode=BERR_TRACE(BERR_OS_ERROR); |
|---|
| 462 | goto err_input_format_change_event_handler; |
|---|
| 463 | } |
|---|
| 464 | |
|---|
| 465 | if ( NEXUS_GetEnv("multichannel_disabled") || NEXUS_GetEnv("audio_processing_disabled") ) |
|---|
| 466 | { |
|---|
| 467 | handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].format = NEXUS_AudioInputFormat_ePcmStereo; |
|---|
| 468 | } |
|---|
| 469 | else |
|---|
| 470 | { |
|---|
| 471 | switch ( pSettings->multichannelFormat ) |
|---|
| 472 | { |
|---|
| 473 | case NEXUS_AudioMultichannelFormat_eNone: |
|---|
| 474 | /* Multichannel output disabled */ |
|---|
| 475 | handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].format = NEXUS_AudioInputFormat_ePcmStereo; |
|---|
| 476 | break; |
|---|
| 477 | case NEXUS_AudioMultichannelFormat_e5_1: |
|---|
| 478 | handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].format = NEXUS_AudioInputFormat_ePcm5_1; |
|---|
| 479 | #if NEXUS_NUM_HDMI_OUTPUTS && 0 |
|---|
| 480 | /* TODO: Notify PI of 5.1 vs. 7.1 */ |
|---|
| 481 | pChannelSettings->sChnRBufPool.uiMaxNumOutChPairs[0] += 3; |
|---|
| 482 | #endif |
|---|
| 483 | break; |
|---|
| 484 | #if 0 /* Not supported on any current chipsets */ |
|---|
| 485 | case NEXUS_AudioMultichannelFormat_e7_1: |
|---|
| 486 | handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].format = NEXUS_AudioInputFormat_ePcm7_1; |
|---|
| 487 | #if NEXUS_NUM_HDMI_OUTPUTS && 0 |
|---|
| 488 | /* TODO: Notify PI of 5.1 vs. 7.1 */ |
|---|
| 489 | pChannelSettings->sChnRBufPool.uiMaxNumOutChPairs[0] += 4; |
|---|
| 490 | #endif |
|---|
| 491 | break; |
|---|
| 492 | #endif |
|---|
| 493 | default: |
|---|
| 494 | BDBG_ERR(("Unsupported multichannel audio format")); |
|---|
| 495 | errCode = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 496 | goto err_channel; |
|---|
| 497 | } |
|---|
| 498 | } |
|---|
| 499 | if ( pSettings->independentDelay && !g_NEXUS_audioModuleData.settings.independentDelay ) |
|---|
| 500 | { |
|---|
| 501 | BDBG_ERR(("Independent delay must be enabled at the audio module level. Please check NEXUS_AudioModuleSettings.independentDelay.")); |
|---|
| 502 | errCode = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 503 | goto err_channel; |
|---|
| 504 | } |
|---|
| 505 | |
|---|
| 506 | /* Open APE decoder */ |
|---|
| 507 | BAPE_Decoder_GetDefaultOpenSettings(&decoderOpenSettings); |
|---|
| 508 | errCode = BAPE_Decoder_Open(NEXUS_AUDIO_DEVICE_HANDLE, index, &decoderOpenSettings, &handle->channel); |
|---|
| 509 | if ( errCode ) |
|---|
| 510 | { |
|---|
| 511 | errCode = BERR_TRACE(errCode); |
|---|
| 512 | goto err_channel; |
|---|
| 513 | } |
|---|
| 514 | |
|---|
| 515 | /* Init connectors */ |
|---|
| 516 | BAPE_Decoder_GetConnector(handle->channel, BAPE_ConnectorFormat_eStereo, &mixerInput); |
|---|
| 517 | handle->connectors[NEXUS_AudioDecoderConnectorType_eStereo].port = (uint32_t)mixerInput; |
|---|
| 518 | BAPE_Decoder_GetConnector(handle->channel, BAPE_ConnectorFormat_eMultichannel, &mixerInput); |
|---|
| 519 | handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].port = (uint32_t)mixerInput; |
|---|
| 520 | BAPE_Decoder_GetConnector(handle->channel, BAPE_ConnectorFormat_eCompressed, &mixerInput); |
|---|
| 521 | handle->connectors[NEXUS_AudioDecoderConnectorType_eCompressed].port = (uint32_t)mixerInput; |
|---|
| 522 | |
|---|
| 523 | /* Hook up decoder interrupts */ |
|---|
| 524 | BAPE_Decoder_GetInterruptHandlers(handle->channel, &interrupts); |
|---|
| 525 | interrupts.firstPts.pCallback_isr = NEXUS_AudioDecoder_P_FirstPts_isr; |
|---|
| 526 | interrupts.firstPts.pParam1 = handle; |
|---|
| 527 | interrupts.tsmFail.pCallback_isr = NEXUS_AudioDecoder_P_AudioTsmFail_isr; |
|---|
| 528 | interrupts.tsmFail.pParam1 = handle; |
|---|
| 529 | interrupts.tsmPass.pCallback_isr = NEXUS_AudioDecoder_P_AudioTsmPass_isr; |
|---|
| 530 | interrupts.tsmPass.pParam1 = handle; |
|---|
| 531 | interrupts.sampleRateChange.pCallback_isr = NEXUS_AudioDecoder_P_SampleRateChange_isr; |
|---|
| 532 | interrupts.sampleRateChange.pParam1 = handle; |
|---|
| 533 | interrupts.lock.pCallback_isr = NEXUS_AudioDecoder_P_Lock_isr; |
|---|
| 534 | interrupts.lock.pParam1 = handle; |
|---|
| 535 | interrupts.lock.param2 = true; |
|---|
| 536 | interrupts.unlock.pCallback_isr = NEXUS_AudioDecoder_P_Lock_isr; |
|---|
| 537 | interrupts.unlock.pParam1 = handle; |
|---|
| 538 | interrupts.unlock.param2 = false; |
|---|
| 539 | interrupts.statusReady.pCallback_isr = NEXUS_AudioDecoder_P_StreamStatusAvailable_isr; |
|---|
| 540 | interrupts.statusReady.pParam1 = handle; |
|---|
| 541 | interrupts.modeChange.pCallback_isr = NEXUS_AudioDecoder_P_StreamParameterChanged_isr; |
|---|
| 542 | interrupts.modeChange.pParam1 = handle; |
|---|
| 543 | #if 0 /* JDG: This causes far too many source changed callbacks to fire. Some codecs will trigger |
|---|
| 544 | this interrupt on every frame. It was not functional on older RAP platforms likely |
|---|
| 545 | for the same reason. */ |
|---|
| 546 | interrupts.bitrateChange.pCallback_isr = NEXUS_AudioDecoder_P_StreamParameterChanged_isr; |
|---|
| 547 | interrupts.bitrateChange.pParam1 = handle; |
|---|
| 548 | #endif |
|---|
| 549 | BAPE_Decoder_SetInterruptHandlers(handle->channel, &interrupts); |
|---|
| 550 | |
|---|
| 551 | LOCK_TRANSPORT(); |
|---|
| 552 | NEXUS_Rave_GetDefaultOpenSettings_priv(&raveSettings); |
|---|
| 553 | UNLOCK_TRANSPORT(); |
|---|
| 554 | |
|---|
| 555 | BAPE_Decoder_GetDefaultCdbItbConfig(handle->channel, &raveSettings.config); |
|---|
| 556 | |
|---|
| 557 | if ( pSettings->fifoSize == 0 ) |
|---|
| 558 | { |
|---|
| 559 | /* NOTE: Don't automatically increase CDB/ITB for IP Settop internally. */ |
|---|
| 560 | } |
|---|
| 561 | else |
|---|
| 562 | { |
|---|
| 563 | /* Make ITB proportional to CDB */ |
|---|
| 564 | raveSettings.config.Itb.Length = 1024*((raveSettings.config.Itb.Length/1024) * (pSettings->fifoSize/1024))/(raveSettings.config.Cdb.Length/1024); |
|---|
| 565 | BDBG_ASSERT(0 != raveSettings.config.Itb.Length); |
|---|
| 566 | raveSettings.config.Cdb.Length = pSettings->fifoSize; |
|---|
| 567 | } |
|---|
| 568 | |
|---|
| 569 | LOCK_TRANSPORT(); |
|---|
| 570 | handle->raveContext = NEXUS_Rave_Open_priv(&raveSettings); |
|---|
| 571 | UNLOCK_TRANSPORT(); |
|---|
| 572 | if ( NULL == handle->raveContext ) |
|---|
| 573 | { |
|---|
| 574 | BDBG_ERR(("Unable to allocate RAVE context")); |
|---|
| 575 | goto err_rave; |
|---|
| 576 | } |
|---|
| 577 | |
|---|
| 578 | handle->sourceChangeAppCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 579 | if ( NULL == handle->sourceChangeAppCallback ) |
|---|
| 580 | { |
|---|
| 581 | goto err_app_callback; |
|---|
| 582 | } |
|---|
| 583 | |
|---|
| 584 | handle->lockCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 585 | if ( NULL == handle->lockCallback ) |
|---|
| 586 | { |
|---|
| 587 | goto err_lock_callback; |
|---|
| 588 | } |
|---|
| 589 | |
|---|
| 590 | handle->ptsErrorCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 591 | if ( NULL == handle->ptsErrorCallback ) |
|---|
| 592 | { |
|---|
| 593 | goto err_pts_error_callback; |
|---|
| 594 | } |
|---|
| 595 | |
|---|
| 596 | handle->firstPtsCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 597 | if ( NULL == handle->firstPtsCallback ) |
|---|
| 598 | { |
|---|
| 599 | goto err_first_pts_callback; |
|---|
| 600 | } |
|---|
| 601 | |
|---|
| 602 | handle->fifoOverflowCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 603 | if ( NULL == handle->fifoOverflowCallback ) |
|---|
| 604 | { |
|---|
| 605 | goto err_overflow_callback; |
|---|
| 606 | } |
|---|
| 607 | |
|---|
| 608 | handle->streamStatusCallback = NEXUS_IsrCallback_Create(handle, NULL); |
|---|
| 609 | if ( NULL == handle->streamStatusCallback ) |
|---|
| 610 | { |
|---|
| 611 | goto err_status_callback; |
|---|
| 612 | } |
|---|
| 613 | |
|---|
| 614 | /* Success */ |
|---|
| 615 | NEXUS_AudioDecoder_P_GetDefaultSettings(&handle->settings); |
|---|
| 616 | (void)NEXUS_AudioDecoder_SetSettings(handle, &handle->settings); |
|---|
| 617 | handle->opened = true; |
|---|
| 618 | |
|---|
| 619 | return handle; |
|---|
| 620 | |
|---|
| 621 | err_status_callback: |
|---|
| 622 | NEXUS_IsrCallback_Destroy(handle->fifoOverflowCallback); |
|---|
| 623 | err_overflow_callback: |
|---|
| 624 | NEXUS_IsrCallback_Destroy(handle->firstPtsCallback); |
|---|
| 625 | err_first_pts_callback: |
|---|
| 626 | NEXUS_IsrCallback_Destroy(handle->ptsErrorCallback); |
|---|
| 627 | err_pts_error_callback: |
|---|
| 628 | NEXUS_IsrCallback_Destroy(handle->lockCallback); |
|---|
| 629 | err_lock_callback: |
|---|
| 630 | NEXUS_IsrCallback_Destroy(handle->sourceChangeAppCallback); |
|---|
| 631 | err_app_callback: |
|---|
| 632 | LOCK_TRANSPORT(); |
|---|
| 633 | NEXUS_Rave_Close_priv(handle->raveContext); |
|---|
| 634 | UNLOCK_TRANSPORT(); |
|---|
| 635 | err_rave: |
|---|
| 636 | BAPE_Decoder_Close(handle->channel); |
|---|
| 637 | err_channel: |
|---|
| 638 | NEXUS_UnregisterEvent(handle->inputFormatChangeEventHandler); |
|---|
| 639 | err_input_format_change_event_handler: |
|---|
| 640 | BKNI_DestroyEvent(handle->inputFormatChangeEvent); |
|---|
| 641 | err_input_format_change_event: |
|---|
| 642 | NEXUS_UnregisterEvent(handle->channelChangeReportEventHandler); |
|---|
| 643 | err_channel_change_report_event_handler: |
|---|
| 644 | BKNI_DestroyEvent(handle->channelChangeReportEvent); |
|---|
| 645 | err_channel_change_report_event: |
|---|
| 646 | NEXUS_UnregisterEvent(handle->sampleRateCallback); |
|---|
| 647 | err_sample_rate_callback: |
|---|
| 648 | BKNI_DestroyEvent(handle->sampleRateEvent); |
|---|
| 649 | err_sample_rate_event: |
|---|
| 650 | BDBG_OBJECT_UNSET(handle, NEXUS_AudioDecoder); |
|---|
| 651 | BKNI_Memset(handle, 0, sizeof(NEXUS_AudioDecoder)); |
|---|
| 652 | return NULL; |
|---|
| 653 | } |
|---|
| 654 | |
|---|
| 655 | /*************************************************************************** |
|---|
| 656 | Summary: |
|---|
| 657 | Close an audio decoder of the specified type |
|---|
| 658 | ***************************************************************************/ |
|---|
| 659 | void NEXUS_AudioDecoder_Close( |
|---|
| 660 | NEXUS_AudioDecoderHandle handle |
|---|
| 661 | ) |
|---|
| 662 | { |
|---|
| 663 | int i; |
|---|
| 664 | |
|---|
| 665 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 666 | BDBG_ASSERT(true == handle->opened); |
|---|
| 667 | |
|---|
| 668 | if ( handle->started ) |
|---|
| 669 | { |
|---|
| 670 | NEXUS_AudioDecoder_Stop(handle); |
|---|
| 671 | } |
|---|
| 672 | |
|---|
| 673 | for ( i = 0; i < NEXUS_AudioDecoderConnectorType_eMax; i++ ) |
|---|
| 674 | { |
|---|
| 675 | if ( handle->connectors[i].pMixerData ) |
|---|
| 676 | { |
|---|
| 677 | const char *pType; |
|---|
| 678 | switch ( i ) |
|---|
| 679 | { |
|---|
| 680 | case NEXUS_AudioDecoderConnectorType_eStereo: |
|---|
| 681 | pType = "stereo"; |
|---|
| 682 | break; |
|---|
| 683 | case NEXUS_AudioDecoderConnectorType_eCompressed: |
|---|
| 684 | pType = "compressed"; |
|---|
| 685 | break; |
|---|
| 686 | case NEXUS_AudioDecoderConnectorType_eMultichannel: |
|---|
| 687 | pType = "multichannel"; |
|---|
| 688 | break; |
|---|
| 689 | default: |
|---|
| 690 | pType = "unknown"; |
|---|
| 691 | break; |
|---|
| 692 | } |
|---|
| 693 | BDBG_WRN(("Decoder Connector %p (type=%s) is still active. Calling NEXUS_AudioInput_Shutdown.", &handle->connectors[i], pType)); |
|---|
| 694 | NEXUS_AudioInput_Shutdown(&handle->connectors[i]); |
|---|
| 695 | } |
|---|
| 696 | } |
|---|
| 697 | |
|---|
| 698 | BAPE_Decoder_Close(handle->channel); |
|---|
| 699 | |
|---|
| 700 | NEXUS_IsrCallback_Destroy(handle->ptsErrorCallback); |
|---|
| 701 | NEXUS_IsrCallback_Destroy(handle->lockCallback); |
|---|
| 702 | NEXUS_IsrCallback_Destroy(handle->sourceChangeAppCallback); |
|---|
| 703 | NEXUS_IsrCallback_Destroy(handle->firstPtsCallback); |
|---|
| 704 | NEXUS_IsrCallback_Destroy(handle->fifoOverflowCallback); |
|---|
| 705 | NEXUS_IsrCallback_Destroy(handle->streamStatusCallback); |
|---|
| 706 | LOCK_TRANSPORT(); |
|---|
| 707 | NEXUS_Rave_Close_priv(handle->raveContext); |
|---|
| 708 | UNLOCK_TRANSPORT(); |
|---|
| 709 | NEXUS_UnregisterEvent(handle->inputFormatChangeEventHandler); |
|---|
| 710 | BKNI_DestroyEvent(handle->inputFormatChangeEvent); |
|---|
| 711 | NEXUS_UnregisterEvent(handle->channelChangeReportEventHandler); |
|---|
| 712 | BKNI_DestroyEvent(handle->channelChangeReportEvent); |
|---|
| 713 | NEXUS_UnregisterEvent(handle->sampleRateCallback); |
|---|
| 714 | BKNI_DestroyEvent(handle->sampleRateEvent); |
|---|
| 715 | BKNI_Memset(handle, 0, sizeof(NEXUS_AudioDecoder)); |
|---|
| 716 | } |
|---|
| 717 | |
|---|
| 718 | /*************************************************************************** |
|---|
| 719 | Summary: |
|---|
| 720 | Get Settings for an audio decoder |
|---|
| 721 | ***************************************************************************/ |
|---|
| 722 | void NEXUS_AudioDecoder_GetSettings( |
|---|
| 723 | NEXUS_AudioDecoderHandle handle, |
|---|
| 724 | NEXUS_AudioDecoderSettings *pSettings /* [out] Settings */ |
|---|
| 725 | ) |
|---|
| 726 | { |
|---|
| 727 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 728 | BDBG_ASSERT(NULL != pSettings); |
|---|
| 729 | |
|---|
| 730 | *pSettings = handle->settings; |
|---|
| 731 | } |
|---|
| 732 | |
|---|
| 733 | /*************************************************************************** |
|---|
| 734 | Summary: |
|---|
| 735 | Set Settings for an audio decoder |
|---|
| 736 | ***************************************************************************/ |
|---|
| 737 | NEXUS_Error NEXUS_AudioDecoder_SetSettings( |
|---|
| 738 | NEXUS_AudioDecoderHandle handle, |
|---|
| 739 | const NEXUS_AudioDecoderSettings *pSettings /* Settings */ |
|---|
| 740 | ) |
|---|
| 741 | { |
|---|
| 742 | if ( NULL == pSettings ) |
|---|
| 743 | { |
|---|
| 744 | NEXUS_AudioDecoder_P_GetDefaultSettings(&handle->settings); |
|---|
| 745 | } |
|---|
| 746 | else |
|---|
| 747 | { |
|---|
| 748 | if ( pSettings->fifoThreshold != handle->settings.fifoThreshold ) |
|---|
| 749 | { |
|---|
| 750 | BERR_Code rc; |
|---|
| 751 | |
|---|
| 752 | LOCK_TRANSPORT(); |
|---|
| 753 | |
|---|
| 754 | rc = NEXUS_Rave_SetCdbThreshold_priv(handle->raveContext, pSettings->fifoThreshold); |
|---|
| 755 | |
|---|
| 756 | UNLOCK_TRANSPORT(); |
|---|
| 757 | |
|---|
| 758 | if (rc) return BERR_TRACE(rc); |
|---|
| 759 | } |
|---|
| 760 | |
|---|
| 761 | handle->settings = *pSettings; |
|---|
| 762 | } |
|---|
| 763 | NEXUS_IsrCallback_Set(handle->sourceChangeAppCallback, &(handle->settings.sourceChanged)); |
|---|
| 764 | NEXUS_IsrCallback_Set(handle->lockCallback, &(handle->settings.lockChanged)); |
|---|
| 765 | NEXUS_IsrCallback_Set(handle->ptsErrorCallback, &(handle->settings.ptsError)); |
|---|
| 766 | NEXUS_IsrCallback_Set(handle->firstPtsCallback, &(handle->settings.firstPts)); |
|---|
| 767 | NEXUS_IsrCallback_Set(handle->fifoOverflowCallback, &(handle->settings.fifoOverflow)); |
|---|
| 768 | NEXUS_IsrCallback_Set(handle->streamStatusCallback, &(handle->settings.streamStatusAvailable)); |
|---|
| 769 | return NEXUS_AudioDecoder_ApplySettings_priv(handle); |
|---|
| 770 | } |
|---|
| 771 | |
|---|
| 772 | /*************************************************************************** |
|---|
| 773 | Summary: |
|---|
| 774 | Initialize an audio decoder program structure |
|---|
| 775 | ***************************************************************************/ |
|---|
| 776 | void NEXUS_AudioDecoder_GetDefaultStartSettings( |
|---|
| 777 | NEXUS_AudioDecoderStartSettings *pSettings /* [out] Program Defaults */ |
|---|
| 778 | ) |
|---|
| 779 | { |
|---|
| 780 | BKNI_Memset(pSettings, 0, sizeof(NEXUS_AudioDecoderStartSettings)); |
|---|
| 781 | pSettings->codec = NEXUS_AudioCodec_eAc3; |
|---|
| 782 | pSettings->targetSyncEnabled = true; |
|---|
| 783 | } |
|---|
| 784 | |
|---|
| 785 | /*************************************************************************** |
|---|
| 786 | Summary: |
|---|
| 787 | Start deocding the specified program |
|---|
| 788 | ***************************************************************************/ |
|---|
| 789 | NEXUS_Error NEXUS_AudioDecoder_Start( |
|---|
| 790 | NEXUS_AudioDecoderHandle handle, |
|---|
| 791 | const NEXUS_AudioDecoderStartSettings *pProgram /* What to start decoding */ |
|---|
| 792 | ) |
|---|
| 793 | { |
|---|
| 794 | NEXUS_Error errCode; |
|---|
| 795 | bool useTsm, playback=false; |
|---|
| 796 | NEXUS_PidChannelStatus pidChannelStatus; |
|---|
| 797 | NEXUS_RaveSettings raveSettings; |
|---|
| 798 | BAVC_StreamType streamType=BAVC_StreamType_eTsMpeg; |
|---|
| 799 | BAPE_DecoderStartSettings *pStartSettings; |
|---|
| 800 | BAPE_DecoderTsmSettings tsmSettings; |
|---|
| 801 | |
|---|
| 802 | |
|---|
| 803 | BDBG_ENTER(NEXUS_AudioDecoder_Start); |
|---|
| 804 | |
|---|
| 805 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 806 | BDBG_ASSERT(NULL != pProgram); |
|---|
| 807 | |
|---|
| 808 | if ( handle->started ) |
|---|
| 809 | { |
|---|
| 810 | BDBG_ERR(("This decoder is already started. Please call stop first.")); |
|---|
| 811 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 812 | } |
|---|
| 813 | |
|---|
| 814 | pStartSettings = &handle->apeStartSettings; |
|---|
| 815 | BAPE_Decoder_GetDefaultStartSettings(pStartSettings); |
|---|
| 816 | pStartSettings->targetSyncEnabled = pProgram->targetSyncEnabled; |
|---|
| 817 | pStartSettings->nonRealTime = pProgram->nonRealTime; |
|---|
| 818 | switch ( pProgram->mixingMode ) |
|---|
| 819 | { |
|---|
| 820 | default: |
|---|
| 821 | BDBG_ERR(("Invalid mixing mode")); |
|---|
| 822 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 823 | case NEXUS_AudioDecoderMixingMode_eDescription: |
|---|
| 824 | pStartSettings->mixingMode = BAPE_DecoderMixingMode_eDescription; |
|---|
| 825 | break; |
|---|
| 826 | case NEXUS_AudioDecoderMixingMode_eSoundEffects: |
|---|
| 827 | pStartSettings->mixingMode = BAPE_DecoderMixingMode_eSoundEffects; |
|---|
| 828 | break; |
|---|
| 829 | } |
|---|
| 830 | NEXUS_AudioDecoder_P_TrickReset(handle); /* reset trick state on start */ |
|---|
| 831 | |
|---|
| 832 | /* Save Program */ |
|---|
| 833 | handle->programSettings = *pProgram; |
|---|
| 834 | |
|---|
| 835 | /* Sanity check program */ |
|---|
| 836 | if ( pProgram->pidChannel ) |
|---|
| 837 | { |
|---|
| 838 | /* Transport source */ |
|---|
| 839 | errCode = NEXUS_PidChannel_GetStatus(pProgram->pidChannel, &pidChannelStatus); |
|---|
| 840 | if ( errCode ) |
|---|
| 841 | { |
|---|
| 842 | errCode = BERR_TRACE(errCode); |
|---|
| 843 | } |
|---|
| 844 | |
|---|
| 845 | handle->isPlayback = pidChannelStatus.playback; |
|---|
| 846 | playback = handle->isPlayback; |
|---|
| 847 | |
|---|
| 848 | /* There are 4 types of DSS A/V streams: |
|---|
| 849 | DSS SD video - this is DSS ES |
|---|
| 850 | DSS HD video - this is DSS PES |
|---|
| 851 | DSS MPEG audio - this actually uses MPEG1 system headers, but it's very similar to PES, therefore DSS PES |
|---|
| 852 | Therefore we convert DSS ES to DSS PES here. |
|---|
| 853 | DSS AC3 audio - uses MPEG2 System PES, therefore DSS PES |
|---|
| 854 | */ |
|---|
| 855 | if (pidChannelStatus.transportType == NEXUS_TransportType_eDssEs) |
|---|
| 856 | { |
|---|
| 857 | pidChannelStatus.transportType = NEXUS_TransportType_eDssPes; |
|---|
| 858 | } |
|---|
| 859 | /* All DSS is converted to PES above */ |
|---|
| 860 | handle->isDss = (pidChannelStatus.transportType == NEXUS_TransportType_eDssPes)?true:false; |
|---|
| 861 | |
|---|
| 862 | /* Convert to AVC transport type */ |
|---|
| 863 | errCode = NEXUS_P_TransportType_ToMagnum(pidChannelStatus.transportType, &streamType); |
|---|
| 864 | if (errCode) return BERR_TRACE(errCode); |
|---|
| 865 | |
|---|
| 866 | switch( pidChannelStatus.transportType ) |
|---|
| 867 | { |
|---|
| 868 | case NEXUS_TransportType_eEs: |
|---|
| 869 | streamType = BAVC_StreamType_eEs; |
|---|
| 870 | break; |
|---|
| 871 | case NEXUS_TransportType_eTs: |
|---|
| 872 | streamType = BAVC_StreamType_eTsMpeg; |
|---|
| 873 | break; |
|---|
| 874 | case NEXUS_TransportType_eDssEs: |
|---|
| 875 | streamType = BAVC_StreamType_eDssEs; |
|---|
| 876 | break; |
|---|
| 877 | case NEXUS_TransportType_eDssPes: |
|---|
| 878 | streamType = BAVC_StreamType_eDssPes; |
|---|
| 879 | break; |
|---|
| 880 | case NEXUS_TransportType_eMpeg2Pes: |
|---|
| 881 | streamType = BAVC_StreamType_ePes; |
|---|
| 882 | break; |
|---|
| 883 | case NEXUS_TransportType_eMpeg1Ps: |
|---|
| 884 | streamType = BAVC_StreamType_eMpeg1System; |
|---|
| 885 | break; |
|---|
| 886 | default: |
|---|
| 887 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 888 | } |
|---|
| 889 | } |
|---|
| 890 | else if ( pProgram->input ) |
|---|
| 891 | { |
|---|
| 892 | streamType = BAVC_StreamType_ePes; |
|---|
| 893 | handle->isPlayback = false; |
|---|
| 894 | handle->isDss = false; |
|---|
| 895 | pStartSettings->inputPort = NEXUS_AudioInput_P_GetInputPort(pProgram->input); |
|---|
| 896 | /* TODO: Make this a start-time parameter from nexus */ |
|---|
| 897 | pStartSettings->delayMode = BAPE_DspDelayMode_eLow; |
|---|
| 898 | if ( NULL == pStartSettings->inputPort ) |
|---|
| 899 | { |
|---|
| 900 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 901 | } |
|---|
| 902 | playback = false; |
|---|
| 903 | BKNI_Memset(&pidChannelStatus, 0, sizeof(NEXUS_PidChannelStatus)); |
|---|
| 904 | } |
|---|
| 905 | else |
|---|
| 906 | { |
|---|
| 907 | BDBG_ERR(("No PID Channel or Input provided")); |
|---|
| 908 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 909 | } |
|---|
| 910 | |
|---|
| 911 | pStartSettings->streamType = streamType; |
|---|
| 912 | pStartSettings->codec = NEXUS_Audio_P_CodecToMagnum(pProgram->codec); |
|---|
| 913 | |
|---|
| 914 | if (pProgram->stcChannel) |
|---|
| 915 | { |
|---|
| 916 | NEXUS_StcChannelSettings stcSettings; |
|---|
| 917 | LOCK_TRANSPORT(); |
|---|
| 918 | NEXUS_StcChannel_GetIndex_priv(pProgram->stcChannel, &pStartSettings->stcIndex); |
|---|
| 919 | UNLOCK_TRANSPORT(); |
|---|
| 920 | NEXUS_StcChannel_GetSettings(pProgram->stcChannel, &stcSettings); |
|---|
| 921 | playback = (stcSettings.mode != NEXUS_StcChannelMode_ePcr && NULL == pProgram->input); |
|---|
| 922 | } |
|---|
| 923 | |
|---|
| 924 | /* Compute TSM details */ |
|---|
| 925 | BAPE_Decoder_GetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 926 | tsmSettings.playback = handle->isPlayback && playback; |
|---|
| 927 | tsmSettings.ptsOffset = handle->settings.ptsOffset + handle->syncSettings.delay; |
|---|
| 928 | tsmSettings.thresholds.discard = (tsmSettings.playback)?30000:3000; /* ms */ |
|---|
| 929 | tsmSettings.thresholds.grossAdjustment = (pidChannelStatus.originalTransportType == NEXUS_TransportType_eAvi) ? 0x30 : 0x8; |
|---|
| 930 | BAPE_Decoder_SetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 931 | |
|---|
| 932 | /* Determine TSM mode */ |
|---|
| 933 | if ( NULL == pProgram->stcChannel || |
|---|
| 934 | NULL != NEXUS_GetEnv("force_vsync") || |
|---|
| 935 | (pProgram->pidChannel && (pidChannelStatus.transportType == NEXUS_TransportType_eEs || |
|---|
| 936 | pidChannelStatus.originalTransportType == NEXUS_TransportType_eWav || |
|---|
| 937 | #if 1 /* SW7425-2000: OGG PTS values are invalid from bmedia currently */ |
|---|
| 938 | pidChannelStatus.originalTransportType == NEXUS_TransportType_eOgg || |
|---|
| 939 | #endif |
|---|
| 940 | pidChannelStatus.originalTransportType == NEXUS_TransportType_eEs)) ) |
|---|
| 941 | { |
|---|
| 942 | useTsm = false; |
|---|
| 943 | } |
|---|
| 944 | else |
|---|
| 945 | { |
|---|
| 946 | useTsm = true; |
|---|
| 947 | } |
|---|
| 948 | handle->tsmPermitted = useTsm; |
|---|
| 949 | NEXUS_AudioDecoder_P_SetTsm(handle); |
|---|
| 950 | |
|---|
| 951 | if ( pProgram->pidChannel ) |
|---|
| 952 | { |
|---|
| 953 | LOCK_TRANSPORT(); |
|---|
| 954 | NEXUS_Rave_GetDefaultSettings_priv(&raveSettings); |
|---|
| 955 | raveSettings.pidChannel = pProgram->pidChannel; |
|---|
| 956 | raveSettings.bandHold = handle->isPlayback; |
|---|
| 957 | raveSettings.continuityCountEnabled = !handle->isPlayback; |
|---|
| 958 | raveSettings.numOutputBytesEnabled = true; |
|---|
| 959 | raveSettings.audioDescriptor = pProgram->secondaryDecoder; /* We need descriptor values for any secondary decoder */ |
|---|
| 960 | errCode = NEXUS_Rave_ConfigureAudio_priv(handle->raveContext, pProgram->codec, &raveSettings); |
|---|
| 961 | if (errCode) |
|---|
| 962 | { |
|---|
| 963 | UNLOCK_TRANSPORT(); |
|---|
| 964 | return BERR_TRACE(errCode); |
|---|
| 965 | } |
|---|
| 966 | errCode = NEXUS_Rave_GetStatus_priv(handle->raveContext, &handle->raveStatus); |
|---|
| 967 | UNLOCK_TRANSPORT(); |
|---|
| 968 | if (errCode) |
|---|
| 969 | { |
|---|
| 970 | errCode = BERR_TRACE(errCode); |
|---|
| 971 | goto err_rave_status; |
|---|
| 972 | } |
|---|
| 973 | pStartSettings->pContextMap = &handle->raveStatus.xptContextMap; |
|---|
| 974 | } |
|---|
| 975 | |
|---|
| 976 | if ( pProgram->input ) |
|---|
| 977 | { |
|---|
| 978 | if ( NEXUS_AudioInput_P_SupportsFormatChanges(pProgram->input) ) |
|---|
| 979 | { |
|---|
| 980 | /* If this input supports dynamic format changes, enable the dynamic format change interrupt and kick off the format state machine. */ |
|---|
| 981 | errCode = NEXUS_AudioInput_P_SetFormatChangeInterrupt(pProgram->input, NEXUS_AudioDecoder_P_InputFormatChange_isr, handle, 0); |
|---|
| 982 | if ( errCode ) |
|---|
| 983 | { |
|---|
| 984 | errCode = BERR_TRACE(errCode); |
|---|
| 985 | goto err_start; |
|---|
| 986 | } |
|---|
| 987 | handle->started = true; |
|---|
| 988 | NEXUS_AudioDecoder_P_InputFormatChange(handle); |
|---|
| 989 | return BERR_SUCCESS; |
|---|
| 990 | } |
|---|
| 991 | } |
|---|
| 992 | |
|---|
| 993 | /* We're ready to start. Build up lists of outputs to check for configuration changes. */ |
|---|
| 994 | errCode = NEXUS_AudioDecoder_P_Start(handle); |
|---|
| 995 | if ( errCode ) |
|---|
| 996 | { |
|---|
| 997 | errCode=BERR_TRACE(errCode); |
|---|
| 998 | goto err_start; |
|---|
| 999 | } |
|---|
| 1000 | |
|---|
| 1001 | handle->started = true; |
|---|
| 1002 | |
|---|
| 1003 | BDBG_LEAVE(NEXUS_AudioDecoder_Start); |
|---|
| 1004 | |
|---|
| 1005 | /* Success */ |
|---|
| 1006 | return BERR_SUCCESS; |
|---|
| 1007 | |
|---|
| 1008 | err_start: |
|---|
| 1009 | err_rave_status: |
|---|
| 1010 | if ( pProgram->pidChannel ) |
|---|
| 1011 | { |
|---|
| 1012 | LOCK_TRANSPORT(); |
|---|
| 1013 | NEXUS_Rave_RemovePidChannel_priv(handle->raveContext); |
|---|
| 1014 | UNLOCK_TRANSPORT(); |
|---|
| 1015 | } |
|---|
| 1016 | return errCode; |
|---|
| 1017 | } |
|---|
| 1018 | |
|---|
| 1019 | /*************************************************************************** |
|---|
| 1020 | Summary: |
|---|
| 1021 | Stop deocding the current program |
|---|
| 1022 | ***************************************************************************/ |
|---|
| 1023 | void NEXUS_AudioDecoder_Stop( |
|---|
| 1024 | NEXUS_AudioDecoderHandle handle |
|---|
| 1025 | ) |
|---|
| 1026 | { |
|---|
| 1027 | NEXUS_Error errCode; |
|---|
| 1028 | |
|---|
| 1029 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1030 | |
|---|
| 1031 | BDBG_ENTER(NEXUS_AudioDecoder_Stop); |
|---|
| 1032 | |
|---|
| 1033 | if ( !handle->started ) |
|---|
| 1034 | { |
|---|
| 1035 | BDBG_ERR(("Decoder not started")); |
|---|
| 1036 | return; |
|---|
| 1037 | } |
|---|
| 1038 | |
|---|
| 1039 | if ( handle->programSettings.input ) |
|---|
| 1040 | { |
|---|
| 1041 | if ( NEXUS_AudioInput_P_SupportsFormatChanges(handle->programSettings.input) ) |
|---|
| 1042 | { |
|---|
| 1043 | /* If this input supports dynamic format changes, disable the dynamic format change interrupt. */ |
|---|
| 1044 | (void)NEXUS_AudioInput_P_SetFormatChangeInterrupt(handle->programSettings.input, NULL, NULL, 0); |
|---|
| 1045 | } |
|---|
| 1046 | } |
|---|
| 1047 | |
|---|
| 1048 | errCode = NEXUS_AudioDecoder_P_Stop(handle, true); |
|---|
| 1049 | if ( errCode ) |
|---|
| 1050 | { |
|---|
| 1051 | errCode = BERR_TRACE(errCode); |
|---|
| 1052 | } |
|---|
| 1053 | |
|---|
| 1054 | handle->running = false; |
|---|
| 1055 | handle->started = false; |
|---|
| 1056 | handle->trickForceStopped = false; /* do we need to forcedly unmute on Stop, in a way it helps if in a PIP change mode decoder is moved from trickmode on one channel to normal mode on another channel, however it hurts if one stops decoder just in order to change a PID/ audio program */ |
|---|
| 1057 | |
|---|
| 1058 | if ( handle->programSettings.pidChannel ) |
|---|
| 1059 | { |
|---|
| 1060 | LOCK_TRANSPORT(); |
|---|
| 1061 | NEXUS_Rave_RemovePidChannel_priv(handle->raveContext); |
|---|
| 1062 | UNLOCK_TRANSPORT(); |
|---|
| 1063 | } |
|---|
| 1064 | |
|---|
| 1065 | BKNI_Memset(&handle->programSettings, 0, sizeof(handle->programSettings)); |
|---|
| 1066 | |
|---|
| 1067 | BDBG_LEAVE(NEXUS_AudioDecoder_Stop); |
|---|
| 1068 | } |
|---|
| 1069 | |
|---|
| 1070 | /*************************************************************************** |
|---|
| 1071 | Summary: |
|---|
| 1072 | Discards all data accumulated in the decoder buffer |
|---|
| 1073 | ***************************************************************************/ |
|---|
| 1074 | NEXUS_Error NEXUS_AudioDecoder_Flush( |
|---|
| 1075 | NEXUS_AudioDecoderHandle handle |
|---|
| 1076 | ) |
|---|
| 1077 | { |
|---|
| 1078 | BERR_Code rc = BERR_SUCCESS; |
|---|
| 1079 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1080 | |
|---|
| 1081 | if ( !handle->started || !handle->running ) |
|---|
| 1082 | { |
|---|
| 1083 | return BERR_SUCCESS; |
|---|
| 1084 | } |
|---|
| 1085 | |
|---|
| 1086 | BAPE_Decoder_DisableForFlush(handle->channel); |
|---|
| 1087 | |
|---|
| 1088 | BDBG_ASSERT(handle->raveContext); |
|---|
| 1089 | |
|---|
| 1090 | if ( handle->programSettings.pidChannel ) |
|---|
| 1091 | { |
|---|
| 1092 | LOCK_TRANSPORT(); |
|---|
| 1093 | NEXUS_Rave_Disable_priv(handle->raveContext); |
|---|
| 1094 | NEXUS_Rave_Flush_priv(handle->raveContext); |
|---|
| 1095 | UNLOCK_TRANSPORT(); |
|---|
| 1096 | } |
|---|
| 1097 | |
|---|
| 1098 | rc = BAPE_Decoder_Flush(handle->channel); |
|---|
| 1099 | if ( rc ) |
|---|
| 1100 | { |
|---|
| 1101 | (void)BERR_TRACE(rc); |
|---|
| 1102 | } |
|---|
| 1103 | |
|---|
| 1104 | if ( handle->programSettings.pidChannel ) |
|---|
| 1105 | { |
|---|
| 1106 | LOCK_TRANSPORT(); |
|---|
| 1107 | NEXUS_Rave_Enable_priv(handle->raveContext); |
|---|
| 1108 | UNLOCK_TRANSPORT(); |
|---|
| 1109 | } |
|---|
| 1110 | |
|---|
| 1111 | return rc; |
|---|
| 1112 | } |
|---|
| 1113 | |
|---|
| 1114 | /*************************************************************************** |
|---|
| 1115 | Summary: |
|---|
| 1116 | Get codec-specific decoder settings |
|---|
| 1117 | ***************************************************************************/ |
|---|
| 1118 | void NEXUS_AudioDecoder_GetCodecSettings( |
|---|
| 1119 | NEXUS_AudioDecoderHandle handle, |
|---|
| 1120 | NEXUS_AudioCodec codec, |
|---|
| 1121 | NEXUS_AudioDecoderCodecSettings *pSettings /* [out] settings for specified codec */ |
|---|
| 1122 | ) |
|---|
| 1123 | { |
|---|
| 1124 | BAPE_DecoderCodecSettings codecSettings; |
|---|
| 1125 | BAVC_AudioCompressionStd avcCodec; |
|---|
| 1126 | |
|---|
| 1127 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1128 | BDBG_ASSERT(NULL != pSettings); |
|---|
| 1129 | |
|---|
| 1130 | avcCodec = NEXUS_Audio_P_CodecToMagnum(codec); |
|---|
| 1131 | |
|---|
| 1132 | BKNI_Memset(pSettings, 0, sizeof(*pSettings)); |
|---|
| 1133 | pSettings->codec = codec; |
|---|
| 1134 | |
|---|
| 1135 | BAPE_Decoder_GetCodecSettings(handle->channel, avcCodec, &codecSettings); |
|---|
| 1136 | switch ( codec ) |
|---|
| 1137 | { |
|---|
| 1138 | case NEXUS_AudioCodec_eAc3: |
|---|
| 1139 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyDrcMode_eLine == (NEXUS_AudioDecoderDolbyDrcMode)BAPE_Ac3DrcMode_eLine); |
|---|
| 1140 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyDrcMode_eRf == (NEXUS_AudioDecoderDolbyDrcMode)BAPE_Ac3DrcMode_eRf); |
|---|
| 1141 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyDrcMode_eCustomA == (NEXUS_AudioDecoderDolbyDrcMode)BAPE_Ac3DrcMode_eCustomA); |
|---|
| 1142 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyDrcMode_eCustomD == (NEXUS_AudioDecoderDolbyDrcMode)BAPE_Ac3DrcMode_eCustomD); |
|---|
| 1143 | pSettings->codecSettings.ac3.drcMode = codecSettings.codecSettings.ac3.drcMode; |
|---|
| 1144 | pSettings->codecSettings.ac3.drcModeDownmix = codecSettings.codecSettings.ac3.drcModeDownmix; |
|---|
| 1145 | pSettings->codecSettings.ac3.cut = codecSettings.codecSettings.ac3.drcScaleHi; |
|---|
| 1146 | pSettings->codecSettings.ac3.boost = codecSettings.codecSettings.ac3.drcScaleLow; |
|---|
| 1147 | pSettings->codecSettings.ac3.cutDownmix = codecSettings.codecSettings.ac3.drcScaleHiDownmix; |
|---|
| 1148 | pSettings->codecSettings.ac3.boostDownmix = codecSettings.codecSettings.ac3.drcScaleLowDownmix; |
|---|
| 1149 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyStereoDownmixMode_eAutomatic == (NEXUS_AudioDecoderDolbyStereoDownmixMode)BAPE_Ac3StereoMode_eAuto); |
|---|
| 1150 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyStereoDownmixMode_eDolbySurroundCompatible == (NEXUS_AudioDecoderDolbyStereoDownmixMode)BAPE_Ac3StereoMode_eLtRt); |
|---|
| 1151 | BDBG_CASSERT(NEXUS_AudioDecoderDolbyStereoDownmixMode_eStandard == (NEXUS_AudioDecoderDolbyStereoDownmixMode)BAPE_Ac3StereoMode_eLoRo); |
|---|
| 1152 | pSettings->codecSettings.ac3.stereoDownmixMode = codecSettings.codecSettings.ac3.stereoMode; |
|---|
| 1153 | pSettings->codecSettings.ac3.scale = codecSettings.codecSettings.ac3.scale; |
|---|
| 1154 | pSettings->codecSettings.ac3.scaleDownmix = codecSettings.codecSettings.ac3.scaleDownmix; |
|---|
| 1155 | pSettings->codecSettings.ac3.dialogNormalization = codecSettings.codecSettings.ac3.dialogNormalization; |
|---|
| 1156 | pSettings->codecSettings.ac3.dialogNormalizationValue = codecSettings.codecSettings.ac3.dialogNormalizationValue; |
|---|
| 1157 | pSettings->codecSettings.ac3.substreamId = codecSettings.codecSettings.ac3.substreamId; |
|---|
| 1158 | break; |
|---|
| 1159 | case NEXUS_AudioCodec_eAc3Plus: |
|---|
| 1160 | pSettings->codecSettings.ac3Plus.drcMode = codecSettings.codecSettings.ac3Plus.drcMode; |
|---|
| 1161 | pSettings->codecSettings.ac3Plus.drcModeDownmix = codecSettings.codecSettings.ac3Plus.drcModeDownmix; |
|---|
| 1162 | pSettings->codecSettings.ac3Plus.cut = codecSettings.codecSettings.ac3Plus.drcScaleHi; |
|---|
| 1163 | pSettings->codecSettings.ac3Plus.boost = codecSettings.codecSettings.ac3Plus.drcScaleLow; |
|---|
| 1164 | pSettings->codecSettings.ac3Plus.cutDownmix = codecSettings.codecSettings.ac3Plus.drcScaleHiDownmix; |
|---|
| 1165 | pSettings->codecSettings.ac3Plus.boostDownmix = codecSettings.codecSettings.ac3Plus.drcScaleLowDownmix; |
|---|
| 1166 | pSettings->codecSettings.ac3Plus.stereoDownmixMode = codecSettings.codecSettings.ac3Plus.stereoMode; |
|---|
| 1167 | pSettings->codecSettings.ac3Plus.scale = codecSettings.codecSettings.ac3Plus.scale; |
|---|
| 1168 | pSettings->codecSettings.ac3Plus.scaleDownmix = codecSettings.codecSettings.ac3Plus.scaleDownmix; |
|---|
| 1169 | pSettings->codecSettings.ac3Plus.dialogNormalization = codecSettings.codecSettings.ac3Plus.dialogNormalization; |
|---|
| 1170 | pSettings->codecSettings.ac3Plus.dialogNormalizationValue = codecSettings.codecSettings.ac3Plus.dialogNormalizationValue; |
|---|
| 1171 | pSettings->codecSettings.ac3Plus.substreamId = codecSettings.codecSettings.ac3Plus.substreamId; |
|---|
| 1172 | break; |
|---|
| 1173 | case NEXUS_AudioCodec_eAacAdts: |
|---|
| 1174 | case NEXUS_AudioCodec_eAacLoas: |
|---|
| 1175 | pSettings->codecSettings.aac.cut = codecSettings.codecSettings.aac.drcScaleHi; |
|---|
| 1176 | pSettings->codecSettings.aac.boost = codecSettings.codecSettings.aac.drcScaleLow; |
|---|
| 1177 | pSettings->codecSettings.aac.drcTargetLevel = codecSettings.codecSettings.aac.drcTargetLevel; |
|---|
| 1178 | BDBG_CASSERT((int)BAPE_AacStereoMode_eMatrix == (int)NEXUS_AudioDecoderAacDownmixMode_eMatrix); |
|---|
| 1179 | BDBG_CASSERT((int)BAPE_AacStereoMode_eArib == (int)NEXUS_AudioDecoderAacDownmixMode_eArib); |
|---|
| 1180 | BDBG_CASSERT((int)BAPE_AacStereoMode_eLtRt == (int)NEXUS_AudioDecoderAacDownmixMode_eLtRt); |
|---|
| 1181 | BDBG_CASSERT((int)BAPE_AacStereoMode_eLoRo == (int)NEXUS_AudioDecoderAacDownmixMode_eLoRo); |
|---|
| 1182 | pSettings->codecSettings.aac.downmixMode = codecSettings.codecSettings.aac.downmixMode; |
|---|
| 1183 | BDBG_CASSERT((int)NEXUS_AudioDecoderDolbyPulseDrcMode_eLine == (int)BAPE_DolbyPulseDrcMode_eLine); |
|---|
| 1184 | BDBG_CASSERT((int)NEXUS_AudioDecoderDolbyPulseDrcMode_eRf == (int)BAPE_DolbyPulseDrcMode_eRf); |
|---|
| 1185 | pSettings->codecSettings.aac.drcMode = codecSettings.codecSettings.aac.drcMode; |
|---|
| 1186 | pSettings->codecSettings.aac.drcTargetLevel = codecSettings.codecSettings.aac.drcDefaultLevel; |
|---|
| 1187 | pSettings->codecSettings.aac.mpegConformanceMode = codecSettings.codecSettings.aac.mpegConformanceMode; |
|---|
| 1188 | break; |
|---|
| 1189 | case NEXUS_AudioCodec_eAacPlusAdts: |
|---|
| 1190 | case NEXUS_AudioCodec_eAacPlusLoas: |
|---|
| 1191 | pSettings->codecSettings.aacPlus.cut = codecSettings.codecSettings.aacPlus.drcScaleHi; |
|---|
| 1192 | pSettings->codecSettings.aacPlus.boost = codecSettings.codecSettings.aacPlus.drcScaleLow; |
|---|
| 1193 | pSettings->codecSettings.aacPlus.drcTargetLevel = codecSettings.codecSettings.aacPlus.drcTargetLevel; |
|---|
| 1194 | BDBG_CASSERT((int)BAPE_AacStereoMode_eMatrix == (int)NEXUS_AudioDecoderAacDownmixMode_eMatrix); |
|---|
| 1195 | BDBG_CASSERT((int)BAPE_AacStereoMode_eArib == (int)NEXUS_AudioDecoderAacDownmixMode_eArib); |
|---|
| 1196 | BDBG_CASSERT((int)BAPE_AacStereoMode_eLtRt == (int)NEXUS_AudioDecoderAacDownmixMode_eLtRt); |
|---|
| 1197 | BDBG_CASSERT((int)BAPE_AacStereoMode_eLoRo == (int)NEXUS_AudioDecoderAacDownmixMode_eLoRo); |
|---|
| 1198 | pSettings->codecSettings.aacPlus.downmixMode = codecSettings.codecSettings.aacPlus.downmixMode; |
|---|
| 1199 | BDBG_CASSERT((int)NEXUS_AudioDecoderDolbyPulseDrcMode_eLine == (int)BAPE_DolbyPulseDrcMode_eLine); |
|---|
| 1200 | BDBG_CASSERT((int)NEXUS_AudioDecoderDolbyPulseDrcMode_eRf == (int)BAPE_DolbyPulseDrcMode_eRf); |
|---|
| 1201 | pSettings->codecSettings.aacPlus.drcMode = codecSettings.codecSettings.aacPlus.drcMode; |
|---|
| 1202 | pSettings->codecSettings.aacPlus.drcTargetLevel = codecSettings.codecSettings.aacPlus.drcDefaultLevel; |
|---|
| 1203 | pSettings->codecSettings.aacPlus.mpegConformanceMode = codecSettings.codecSettings.aacPlus.mpegConformanceMode; |
|---|
| 1204 | break; |
|---|
| 1205 | case NEXUS_AudioCodec_eWmaPro: |
|---|
| 1206 | /* TODO: Nexus is exposing the older WMA Pro DRC mode. This should switch from bool .. enum to match APE */ |
|---|
| 1207 | switch ( codecSettings.codecSettings.wmaPro.drcMode ) |
|---|
| 1208 | { |
|---|
| 1209 | case BAPE_WmaProDrcMode_eDisabled: |
|---|
| 1210 | pSettings->codecSettings.wmaPro.dynamicRangeControlValid = false; |
|---|
| 1211 | break; |
|---|
| 1212 | default: |
|---|
| 1213 | pSettings->codecSettings.wmaPro.dynamicRangeControlValid = true; |
|---|
| 1214 | break; |
|---|
| 1215 | } |
|---|
| 1216 | /* TODO: Expose stereo mode */ |
|---|
| 1217 | pSettings->codecSettings.wmaPro.dynamicRangeControl.peakReference = codecSettings.codecSettings.wmaPro.peakAmplitudeReference; |
|---|
| 1218 | pSettings->codecSettings.wmaPro.dynamicRangeControl.peakTarget = codecSettings.codecSettings.wmaPro.desiredPeak; |
|---|
| 1219 | pSettings->codecSettings.wmaPro.dynamicRangeControl.averageReference = codecSettings.codecSettings.wmaPro.rmsAmplitudeReference; |
|---|
| 1220 | pSettings->codecSettings.wmaPro.dynamicRangeControl.averageTarget = codecSettings.codecSettings.wmaPro.desiredRms; |
|---|
| 1221 | break; |
|---|
| 1222 | case NEXUS_AudioCodec_eDts: |
|---|
| 1223 | case NEXUS_AudioCodec_eDtsHd: |
|---|
| 1224 | case NEXUS_AudioCodec_eDtsLegacy: /* For DTS streams with legacy frame-sync. These streams are something called as 14bits stream */ |
|---|
| 1225 | pSettings->codecSettings.dts.mixLfeToPrimary = codecSettings.codecSettings.dts.mixLfeToPrimary; |
|---|
| 1226 | BDBG_CASSERT((int)NEXUS_AudioDecoderDtsDownmixMode_eAuto == (int)BAPE_DtsStereoMode_eAuto); |
|---|
| 1227 | BDBG_CASSERT((int)NEXUS_AudioDecoderDtsDownmixMode_eLtRt == (int)BAPE_DtsStereoMode_eLtRt); |
|---|
| 1228 | BDBG_CASSERT((int)NEXUS_AudioDecoderDtsDownmixMode_eLoRo == (int)BAPE_DtsStereoMode_eLoRo); |
|---|
| 1229 | pSettings->codecSettings.dts.stereoDownmixMode = (NEXUS_AudioDecoderDtsStereoDownmixMode)codecSettings.codecSettings.dts.stereoMode; |
|---|
| 1230 | pSettings->codecSettings.dts.enableDrc = codecSettings.codecSettings.dts.drcMode == BAPE_DtsDrcMode_eEnabled ? true : false; |
|---|
| 1231 | pSettings->codecSettings.dts.boost = codecSettings.codecSettings.dts.drcScaleLow; |
|---|
| 1232 | pSettings->codecSettings.dts.cut = codecSettings.codecSettings.dts.drcScaleHi; |
|---|
| 1233 | break; |
|---|
| 1234 | case NEXUS_AudioCodec_eAdpcm: |
|---|
| 1235 | pSettings->codecSettings.adpcm.enableGain = codecSettings.codecSettings.adpcm.gain.enabled; |
|---|
| 1236 | pSettings->codecSettings.adpcm.gainFactor = codecSettings.codecSettings.adpcm.gain.factor; |
|---|
| 1237 | break; |
|---|
| 1238 | default: |
|---|
| 1239 | return; |
|---|
| 1240 | } |
|---|
| 1241 | } |
|---|
| 1242 | |
|---|
| 1243 | /*************************************************************************** |
|---|
| 1244 | Summary: |
|---|
| 1245 | Set codec-specific decoder settings |
|---|
| 1246 | ***************************************************************************/ |
|---|
| 1247 | NEXUS_Error NEXUS_AudioDecoder_SetCodecSettings( |
|---|
| 1248 | NEXUS_AudioDecoderHandle handle, |
|---|
| 1249 | const NEXUS_AudioDecoderCodecSettings *pSettings |
|---|
| 1250 | ) |
|---|
| 1251 | { |
|---|
| 1252 | BAPE_DecoderCodecSettings codecSettings; |
|---|
| 1253 | BAVC_AudioCompressionStd avcCodec; |
|---|
| 1254 | BERR_Code errCode; |
|---|
| 1255 | |
|---|
| 1256 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1257 | BDBG_ASSERT(NULL != pSettings); |
|---|
| 1258 | |
|---|
| 1259 | avcCodec = NEXUS_Audio_P_CodecToMagnum(pSettings->codec); |
|---|
| 1260 | |
|---|
| 1261 | BAPE_Decoder_GetCodecSettings(handle->channel, avcCodec, &codecSettings); |
|---|
| 1262 | switch ( pSettings->codec ) |
|---|
| 1263 | { |
|---|
| 1264 | case NEXUS_AudioCodec_eAc3: |
|---|
| 1265 | codecSettings.codecSettings.ac3.drcMode = pSettings->codecSettings.ac3.drcMode; |
|---|
| 1266 | codecSettings.codecSettings.ac3.drcModeDownmix = pSettings->codecSettings.ac3.drcModeDownmix; |
|---|
| 1267 | codecSettings.codecSettings.ac3.drcScaleHi = pSettings->codecSettings.ac3.cut; |
|---|
| 1268 | codecSettings.codecSettings.ac3.drcScaleLow = pSettings->codecSettings.ac3.boost; |
|---|
| 1269 | codecSettings.codecSettings.ac3.drcScaleHiDownmix = pSettings->codecSettings.ac3.cutDownmix; |
|---|
| 1270 | codecSettings.codecSettings.ac3.drcScaleLowDownmix = pSettings->codecSettings.ac3.boostDownmix; |
|---|
| 1271 | codecSettings.codecSettings.ac3.stereoMode = pSettings->codecSettings.ac3.stereoDownmixMode; |
|---|
| 1272 | codecSettings.codecSettings.ac3.scale = pSettings->codecSettings.ac3.scale; |
|---|
| 1273 | codecSettings.codecSettings.ac3.scaleDownmix = pSettings->codecSettings.ac3.scaleDownmix; |
|---|
| 1274 | codecSettings.codecSettings.ac3.dialogNormalization = pSettings->codecSettings.ac3.dialogNormalization; |
|---|
| 1275 | codecSettings.codecSettings.ac3.dialogNormalizationValue = pSettings->codecSettings.ac3.dialogNormalizationValue; |
|---|
| 1276 | codecSettings.codecSettings.ac3.substreamId = pSettings->codecSettings.ac3.substreamId; |
|---|
| 1277 | break; |
|---|
| 1278 | case NEXUS_AudioCodec_eAc3Plus: |
|---|
| 1279 | codecSettings.codecSettings.ac3Plus.drcMode = pSettings->codecSettings.ac3Plus.drcMode; |
|---|
| 1280 | codecSettings.codecSettings.ac3Plus.drcModeDownmix = pSettings->codecSettings.ac3Plus.drcModeDownmix; |
|---|
| 1281 | codecSettings.codecSettings.ac3Plus.drcScaleHi = pSettings->codecSettings.ac3Plus.cut; |
|---|
| 1282 | codecSettings.codecSettings.ac3Plus.drcScaleLow = pSettings->codecSettings.ac3Plus.boost; |
|---|
| 1283 | codecSettings.codecSettings.ac3Plus.drcScaleHiDownmix = pSettings->codecSettings.ac3Plus.cutDownmix; |
|---|
| 1284 | codecSettings.codecSettings.ac3Plus.drcScaleLowDownmix = pSettings->codecSettings.ac3Plus.boostDownmix; |
|---|
| 1285 | codecSettings.codecSettings.ac3Plus.stereoMode = pSettings->codecSettings.ac3Plus.stereoDownmixMode; |
|---|
| 1286 | codecSettings.codecSettings.ac3Plus.scale = pSettings->codecSettings.ac3Plus.scale; |
|---|
| 1287 | codecSettings.codecSettings.ac3Plus.scaleDownmix = pSettings->codecSettings.ac3Plus.scaleDownmix; |
|---|
| 1288 | codecSettings.codecSettings.ac3Plus.dialogNormalization = pSettings->codecSettings.ac3Plus.dialogNormalization; |
|---|
| 1289 | codecSettings.codecSettings.ac3Plus.dialogNormalizationValue = pSettings->codecSettings.ac3Plus.dialogNormalizationValue; |
|---|
| 1290 | codecSettings.codecSettings.ac3Plus.substreamId = pSettings->codecSettings.ac3Plus.substreamId; |
|---|
| 1291 | break; |
|---|
| 1292 | case NEXUS_AudioCodec_eAacAdts: |
|---|
| 1293 | case NEXUS_AudioCodec_eAacLoas: |
|---|
| 1294 | codecSettings.codecSettings.aac.drcScaleHi = pSettings->codecSettings.aac.cut; |
|---|
| 1295 | codecSettings.codecSettings.aac.drcScaleLow = pSettings->codecSettings.aac.boost; |
|---|
| 1296 | codecSettings.codecSettings.aac.drcTargetLevel = pSettings->codecSettings.aac.drcTargetLevel; |
|---|
| 1297 | codecSettings.codecSettings.aac.downmixMode = pSettings->codecSettings.aac.downmixMode; |
|---|
| 1298 | codecSettings.codecSettings.aac.drcMode = pSettings->codecSettings.aac.drcMode; |
|---|
| 1299 | codecSettings.codecSettings.aac.drcDefaultLevel = pSettings->codecSettings.aac.drcTargetLevel; |
|---|
| 1300 | codecSettings.codecSettings.aac.mpegConformanceMode = pSettings->codecSettings.aac.mpegConformanceMode; |
|---|
| 1301 | break; |
|---|
| 1302 | case NEXUS_AudioCodec_eAacPlusAdts: |
|---|
| 1303 | case NEXUS_AudioCodec_eAacPlusLoas: |
|---|
| 1304 | codecSettings.codecSettings.aacPlus.drcScaleHi = pSettings->codecSettings.aacPlus.cut; |
|---|
| 1305 | codecSettings.codecSettings.aacPlus.drcScaleLow = pSettings->codecSettings.aacPlus.boost; |
|---|
| 1306 | codecSettings.codecSettings.aacPlus.drcTargetLevel = pSettings->codecSettings.aacPlus.drcTargetLevel; |
|---|
| 1307 | codecSettings.codecSettings.aacPlus.downmixMode = pSettings->codecSettings.aacPlus.downmixMode; |
|---|
| 1308 | codecSettings.codecSettings.aacPlus.drcMode = pSettings->codecSettings.aacPlus.drcMode; |
|---|
| 1309 | codecSettings.codecSettings.aacPlus.drcDefaultLevel = pSettings->codecSettings.aacPlus.drcTargetLevel; |
|---|
| 1310 | codecSettings.codecSettings.aacPlus.mpegConformanceMode = pSettings->codecSettings.aacPlus.mpegConformanceMode; |
|---|
| 1311 | break; |
|---|
| 1312 | case NEXUS_AudioCodec_eWmaPro: |
|---|
| 1313 | /* TODO: Nexus is exposing the older WMA Pro DRC mode. This should switch from bool .. enum to match APE */ |
|---|
| 1314 | if ( pSettings->codecSettings.wmaPro.dynamicRangeControlValid ) |
|---|
| 1315 | { |
|---|
| 1316 | codecSettings.codecSettings.wmaPro.drcMode = BAPE_WmaProDrcMode_eHigh; |
|---|
| 1317 | } |
|---|
| 1318 | else |
|---|
| 1319 | { |
|---|
| 1320 | codecSettings.codecSettings.wmaPro.drcMode = BAPE_WmaProDrcMode_eDisabled; |
|---|
| 1321 | } |
|---|
| 1322 | /* TODO: Expose stereo mode */ |
|---|
| 1323 | codecSettings.codecSettings.wmaPro.peakAmplitudeReference = pSettings->codecSettings.wmaPro.dynamicRangeControl.peakReference; |
|---|
| 1324 | codecSettings.codecSettings.wmaPro.desiredPeak = pSettings->codecSettings.wmaPro.dynamicRangeControl.peakTarget; |
|---|
| 1325 | codecSettings.codecSettings.wmaPro.rmsAmplitudeReference = pSettings->codecSettings.wmaPro.dynamicRangeControl.averageReference; |
|---|
| 1326 | codecSettings.codecSettings.wmaPro.desiredRms = pSettings->codecSettings.wmaPro.dynamicRangeControl.averageTarget; |
|---|
| 1327 | break; |
|---|
| 1328 | case NEXUS_AudioCodec_eDts: |
|---|
| 1329 | case NEXUS_AudioCodec_eDtsHd: |
|---|
| 1330 | case NEXUS_AudioCodec_eDtsLegacy: /* For DTS streams with legacy frame-sync. These streams are something called as 14bits stream */ |
|---|
| 1331 | codecSettings.codecSettings.dts.mixLfeToPrimary = pSettings->codecSettings.dts.mixLfeToPrimary; |
|---|
| 1332 | codecSettings.codecSettings.dts.stereoMode = (BAPE_DtsStereoMode)pSettings->codecSettings.dts.stereoDownmixMode; |
|---|
| 1333 | codecSettings.codecSettings.dts.drcMode = pSettings->codecSettings.dts.enableDrc ? BAPE_DtsDrcMode_eEnabled : BAPE_DtsDrcMode_eDisabled; |
|---|
| 1334 | codecSettings.codecSettings.dts.drcScaleLow = pSettings->codecSettings.dts.boost; |
|---|
| 1335 | codecSettings.codecSettings.dts.drcScaleHi = pSettings->codecSettings.dts.cut; |
|---|
| 1336 | break; |
|---|
| 1337 | case NEXUS_AudioCodec_eAdpcm: |
|---|
| 1338 | codecSettings.codecSettings.adpcm.gain.enabled = pSettings->codecSettings.adpcm.enableGain; |
|---|
| 1339 | codecSettings.codecSettings.adpcm.gain.factor = pSettings->codecSettings.adpcm.gainFactor; |
|---|
| 1340 | break; |
|---|
| 1341 | default: |
|---|
| 1342 | return BERR_SUCCESS; |
|---|
| 1343 | } |
|---|
| 1344 | |
|---|
| 1345 | errCode = BAPE_Decoder_SetCodecSettings(handle->channel, &codecSettings); |
|---|
| 1346 | if ( errCode ) |
|---|
| 1347 | { |
|---|
| 1348 | return BERR_TRACE(errCode); |
|---|
| 1349 | } |
|---|
| 1350 | return BERR_SUCCESS; |
|---|
| 1351 | } |
|---|
| 1352 | |
|---|
| 1353 | static unsigned NEXUS_AudioDecoder_P_GetAc3Bitrate(unsigned frameSizeCode) |
|---|
| 1354 | { |
|---|
| 1355 | const unsigned bitrateTable[] = { |
|---|
| 1356 | |
|---|
| 1357 | 32000, /* '000000' 32 kbps */ |
|---|
| 1358 | 32000, /* '000001' 32 kbps */ |
|---|
| 1359 | 40000, /* '000010' 40 kbps */ |
|---|
| 1360 | 40000, /* '000011' 40 kbps */ |
|---|
| 1361 | 48000, /* '000100' 48 kbps */ |
|---|
| 1362 | 48000, /* '000101' 48 kbps */ |
|---|
| 1363 | 56000, /* '000110' 56 kbps */ |
|---|
| 1364 | 56000, /* '000111' 56 kbps */ |
|---|
| 1365 | 64000, /* '001000' 64 kbps */ |
|---|
| 1366 | 64000, /* '001001' 64 kbps */ |
|---|
| 1367 | 80000, /* '001010' 80 kbps */ |
|---|
| 1368 | 80000, /* '001011' 80 kbps */ |
|---|
| 1369 | 96000, /* '001100' 96 kbps */ |
|---|
| 1370 | 96000, /* '001101' 96 kbps */ |
|---|
| 1371 | 112000, /* '001110' 112 kbps */ |
|---|
| 1372 | 112000, /* '001111' 112 kbps */ |
|---|
| 1373 | |
|---|
| 1374 | 128000, /* '010000' 128 kbps */ |
|---|
| 1375 | 128000, /* '010001' 128 kbps */ |
|---|
| 1376 | 160000, /* '010010' 160 kbps */ |
|---|
| 1377 | 160000, /* '010011' 160 kbps */ |
|---|
| 1378 | 192000, /* '010100' 192 kbps */ |
|---|
| 1379 | 192000, /* '010101' 192 kbps */ |
|---|
| 1380 | 224000, /* '010110' 224 kbps */ |
|---|
| 1381 | 224000, /* '010111' 224 kbps */ |
|---|
| 1382 | 256000, /* '011000' 256 kbps */ |
|---|
| 1383 | 256000, /* '011001' 256 kbps */ |
|---|
| 1384 | 320000, /* '011010' 320 kbps */ |
|---|
| 1385 | 320000, /* '011011' 320 kbps */ |
|---|
| 1386 | 384000, /* '011100' 384 kbps */ |
|---|
| 1387 | 384000, /* '011101' 384 kbps */ |
|---|
| 1388 | 448000, /* '011110' 448 kbps */ |
|---|
| 1389 | 448000, /* '011111' 448 kbps */ |
|---|
| 1390 | |
|---|
| 1391 | 512000, /* '100000' 512 kbps */ |
|---|
| 1392 | 512000, /* '100001' 512 kbps */ |
|---|
| 1393 | 576000, /* '100010' 576 kbps */ |
|---|
| 1394 | 576000, /* '100011' 576 kbps */ |
|---|
| 1395 | 640000, /* '100100' 640 kbps */ |
|---|
| 1396 | 640000 /* '100101' 640 kbps */ |
|---|
| 1397 | }; |
|---|
| 1398 | |
|---|
| 1399 | if ( frameSizeCode < 38 ) |
|---|
| 1400 | { |
|---|
| 1401 | return bitrateTable[frameSizeCode]; |
|---|
| 1402 | } |
|---|
| 1403 | else |
|---|
| 1404 | { |
|---|
| 1405 | return 0; |
|---|
| 1406 | } |
|---|
| 1407 | } |
|---|
| 1408 | |
|---|
| 1409 | /*************************************************************************** |
|---|
| 1410 | Summary: |
|---|
| 1411 | Get the current audio decoder status |
|---|
| 1412 | ***************************************************************************/ |
|---|
| 1413 | NEXUS_Error NEXUS_AudioDecoder_GetStatus( |
|---|
| 1414 | NEXUS_AudioDecoderHandle handle, |
|---|
| 1415 | NEXUS_AudioDecoderStatus *pStatus /* [out] current status */ |
|---|
| 1416 | ) |
|---|
| 1417 | { |
|---|
| 1418 | unsigned depth=0, size=0; |
|---|
| 1419 | BAPE_DecoderStatus decoderStatus; |
|---|
| 1420 | |
|---|
| 1421 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1422 | BDBG_ASSERT(NULL != pStatus); |
|---|
| 1423 | |
|---|
| 1424 | BKNI_Memset(pStatus, 0, sizeof(NEXUS_AudioDecoderStatus)); |
|---|
| 1425 | pStatus->started = handle->started; |
|---|
| 1426 | pStatus->locked = handle->locked; |
|---|
| 1427 | pStatus->codec = handle->programSettings.codec; |
|---|
| 1428 | pStatus->ptsType = NEXUS_PtsType_eInterpolatedFromInvalidPTS; |
|---|
| 1429 | pStatus->numFifoOverflows = handle->numFifoOverflows; |
|---|
| 1430 | pStatus->numFifoUnderflows = handle->numFifoUnderflows; |
|---|
| 1431 | |
|---|
| 1432 | if(!handle->running) |
|---|
| 1433 | { |
|---|
| 1434 | return BERR_SUCCESS; |
|---|
| 1435 | } |
|---|
| 1436 | |
|---|
| 1437 | BKNI_EnterCriticalSection(); |
|---|
| 1438 | if ( handle->programSettings.pidChannel ) |
|---|
| 1439 | { |
|---|
| 1440 | NEXUS_Rave_GetCdbBufferInfo_isr(handle->raveContext, &depth, &size); |
|---|
| 1441 | } |
|---|
| 1442 | BKNI_LeaveCriticalSection(); |
|---|
| 1443 | |
|---|
| 1444 | pStatus->fifoDepth = depth; |
|---|
| 1445 | pStatus->fifoSize = size; |
|---|
| 1446 | |
|---|
| 1447 | pStatus->tsm = handle->tsmEnabled; |
|---|
| 1448 | pStatus->timebase = handle->apeStartSettings.stcIndex; |
|---|
| 1449 | pStatus->ptsErrorCount = handle->ptsErrorCount; |
|---|
| 1450 | pStatus->codec = handle->programSettings.codec; |
|---|
| 1451 | pStatus->numWatchdogs = g_numWatchdogs; |
|---|
| 1452 | |
|---|
| 1453 | if ( handle->programSettings.pidChannel ) |
|---|
| 1454 | { |
|---|
| 1455 | NEXUS_RaveStatus raveStatus; |
|---|
| 1456 | NEXUS_Error errCode; |
|---|
| 1457 | LOCK_TRANSPORT(); |
|---|
| 1458 | NEXUS_Rave_GetAudioFrameCount_priv(handle->raveContext, &pStatus->queuedFrames); |
|---|
| 1459 | errCode = NEXUS_Rave_GetStatus_priv(handle->raveContext, &raveStatus); |
|---|
| 1460 | UNLOCK_TRANSPORT(); |
|---|
| 1461 | if ( NEXUS_SUCCESS == errCode ) |
|---|
| 1462 | { |
|---|
| 1463 | pStatus->numBytesDecoded = raveStatus.numOutputBytes; |
|---|
| 1464 | } |
|---|
| 1465 | } |
|---|
| 1466 | |
|---|
| 1467 | /* Get decoder info */ |
|---|
| 1468 | BAPE_Decoder_GetStatus(handle->channel, &decoderStatus); |
|---|
| 1469 | { |
|---|
| 1470 | unsigned frameLength, bitrate; |
|---|
| 1471 | |
|---|
| 1472 | pStatus->sampleRate = decoderStatus.sampleRate; |
|---|
| 1473 | pStatus->pts = decoderStatus.tsmStatus.ptsInfo.ui32CurrentPTS; |
|---|
| 1474 | pStatus->ptsType = decoderStatus.tsmStatus.ptsInfo.ePTSType == BAVC_PTSType_eCoded ? NEXUS_PtsType_eCoded : |
|---|
| 1475 | decoderStatus.tsmStatus.ptsInfo.ePTSType == BAVC_PTSType_eInterpolatedFromValidPTS ? NEXUS_PtsType_eInterpolatedFromValidPTS : NEXUS_PtsType_eInterpolatedFromInvalidPTS; |
|---|
| 1476 | pStatus->ptsStcDifference = decoderStatus.tsmStatus.ptsStcDifference; |
|---|
| 1477 | |
|---|
| 1478 | pStatus->framesDecoded = decoderStatus.framesDecoded; |
|---|
| 1479 | pStatus->frameErrors = decoderStatus.frameErrors; |
|---|
| 1480 | pStatus->dummyFrames = decoderStatus.dummyFrames; |
|---|
| 1481 | |
|---|
| 1482 | /* Convert codec to nexus type */ |
|---|
| 1483 | pStatus->codec = NEXUS_Audio_P_MagnumToCodec(decoderStatus.codec); |
|---|
| 1484 | |
|---|
| 1485 | /* Handle specifics per-codec */ |
|---|
| 1486 | switch ( decoderStatus.codec ) |
|---|
| 1487 | { |
|---|
| 1488 | case BAVC_AudioCompressionStd_eMpegL1: |
|---|
| 1489 | case BAVC_AudioCompressionStd_eMpegL2: |
|---|
| 1490 | case BAVC_AudioCompressionStd_eMpegL3: |
|---|
| 1491 | pStatus->codec = (decoderStatus.codecStatus.mpeg.layer == 3)?NEXUS_AudioCodec_eMp3:NEXUS_AudioCodec_eMpeg; |
|---|
| 1492 | pStatus->codecStatus.mpeg.channelMode = decoderStatus.codecStatus.mpeg.mpegChannelMode; |
|---|
| 1493 | switch ( decoderStatus.codecStatus.mpeg.layer ) |
|---|
| 1494 | { |
|---|
| 1495 | default: |
|---|
| 1496 | case 1: |
|---|
| 1497 | pStatus->codecStatus.mpeg.layer = NEXUS_AudioMpegLayer_e1; |
|---|
| 1498 | pStatus->codec = NEXUS_AudioCodec_eMpeg; |
|---|
| 1499 | break; |
|---|
| 1500 | case 2: |
|---|
| 1501 | pStatus->codecStatus.mpeg.layer = NEXUS_AudioMpegLayer_e2; |
|---|
| 1502 | pStatus->codec = NEXUS_AudioCodec_eMpeg; |
|---|
| 1503 | break; |
|---|
| 1504 | case 3: |
|---|
| 1505 | pStatus->codecStatus.mpeg.layer = NEXUS_AudioMpegLayer_e3; |
|---|
| 1506 | pStatus->codec = NEXUS_AudioCodec_eMp3; |
|---|
| 1507 | break; |
|---|
| 1508 | } |
|---|
| 1509 | pStatus->codecStatus.mpeg.emphasis = decoderStatus.codecStatus.mpeg.emphasisMode; |
|---|
| 1510 | pStatus->codecStatus.mpeg.original = decoderStatus.codecStatus.mpeg.original; |
|---|
| 1511 | pStatus->codecStatus.mpeg.copyright = decoderStatus.codecStatus.mpeg.copyright; |
|---|
| 1512 | pStatus->codecStatus.mpeg.bitrate = decoderStatus.codecStatus.mpeg.bitRate; |
|---|
| 1513 | if ( pStatus->sampleRate > 0 ) |
|---|
| 1514 | { |
|---|
| 1515 | /* MPEG audio uses a CDB sync, so the frame count is bogus. Calculate based on frame size and CDB depth */ |
|---|
| 1516 | bitrate = (decoderStatus.codecStatus.mpeg.bitRate>0)?1000*decoderStatus.codecStatus.mpeg.bitRate:128000; |
|---|
| 1517 | if ( decoderStatus.codecStatus.mpeg.layer == 1 ) |
|---|
| 1518 | { |
|---|
| 1519 | frameLength = (48*bitrate)/pStatus->sampleRate; |
|---|
| 1520 | } |
|---|
| 1521 | else |
|---|
| 1522 | { |
|---|
| 1523 | frameLength = (144*bitrate)/pStatus->sampleRate; |
|---|
| 1524 | } |
|---|
| 1525 | if ( frameLength == 0 ) |
|---|
| 1526 | { |
|---|
| 1527 | pStatus->queuedFrames = 0; |
|---|
| 1528 | } |
|---|
| 1529 | else |
|---|
| 1530 | { |
|---|
| 1531 | pStatus->queuedFrames = pStatus->fifoDepth/frameLength; |
|---|
| 1532 | } |
|---|
| 1533 | BDBG_MSG(("Queued Frames %d bitrate %d framelength %d samplerate %d", pStatus->queuedFrames, bitrate, frameLength, pStatus->sampleRate)); |
|---|
| 1534 | } |
|---|
| 1535 | break; |
|---|
| 1536 | case BAVC_AudioCompressionStd_eAacLoas: |
|---|
| 1537 | case BAVC_AudioCompressionStd_eAacAdts: |
|---|
| 1538 | case BAVC_AudioCompressionStd_eAacPlusLoas: |
|---|
| 1539 | case BAVC_AudioCompressionStd_eAacPlusAdts: |
|---|
| 1540 | /* Convert channel mode to aac acmod */ |
|---|
| 1541 | switch ( decoderStatus.codecStatus.aac.channelMode ) |
|---|
| 1542 | { |
|---|
| 1543 | case BAPE_ChannelMode_e1_0: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eOneCenter_1_0_C; break; |
|---|
| 1544 | case BAPE_ChannelMode_e1_1: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eTwoMono_1_ch1_ch2; break; |
|---|
| 1545 | case BAPE_ChannelMode_e2_0: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eTwoChannel_2_0_L_R; break; |
|---|
| 1546 | case BAPE_ChannelMode_e3_0: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eThreeChannel_3_0_L_C_R; break; |
|---|
| 1547 | case BAPE_ChannelMode_e2_1: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eThreeChannel_2_1_L_R_S; break; |
|---|
| 1548 | case BAPE_ChannelMode_e3_1: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eFourChannel_3_1_L_C_R_S; break; |
|---|
| 1549 | case BAPE_ChannelMode_e2_2: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eFourChannel_2_2_L_R_SL_SR; break; |
|---|
| 1550 | case BAPE_ChannelMode_e3_2: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eFiveChannel_3_2_L_C_R_SL_SR; break; |
|---|
| 1551 | default: pStatus->codecStatus.aac.acmod = NEXUS_AudioAacAcmod_eMax; break; |
|---|
| 1552 | } |
|---|
| 1553 | pStatus->codecStatus.aac.profile = decoderStatus.codecStatus.aac.profile; |
|---|
| 1554 | pStatus->codecStatus.aac.bitrate = decoderStatus.codecStatus.aac.bitRate; |
|---|
| 1555 | pStatus->codecStatus.aac.lfe = decoderStatus.codecStatus.aac.lfe; |
|---|
| 1556 | pStatus->codecStatus.aac.pseudoSurround = decoderStatus.codecStatus.aac.pseudoSurround; |
|---|
| 1557 | pStatus->codecStatus.aac.stereoMatrix = decoderStatus.codecStatus.aac.stereoMatrix; |
|---|
| 1558 | pStatus->codecStatus.aac.matrixIndex = decoderStatus.codecStatus.aac.matrixIndex; |
|---|
| 1559 | pStatus->codecStatus.aac.numLfeChannels = decoderStatus.codecStatus.aac.numLfeChannels; |
|---|
| 1560 | pStatus->codecStatus.aac.numBackChannels = decoderStatus.codecStatus.aac.numBackChannels; |
|---|
| 1561 | pStatus->codecStatus.aac.numSideChannels = decoderStatus.codecStatus.aac.numSideChannels; |
|---|
| 1562 | pStatus->codecStatus.aac.numFrontChannels = decoderStatus.codecStatus.aac.numFrontChannels; |
|---|
| 1563 | break; |
|---|
| 1564 | case BAVC_AudioCompressionStd_eAc3: |
|---|
| 1565 | case BAVC_AudioCompressionStd_eAc3Plus: |
|---|
| 1566 | pStatus->codec = (decoderStatus.codec == BAVC_AudioCompressionStd_eAc3)?NEXUS_AudioCodec_eAc3:NEXUS_AudioCodec_eAc3Plus; |
|---|
| 1567 | pStatus->codecStatus.ac3.bitStreamId = decoderStatus.codecStatus.ac3.bitstreamId; |
|---|
| 1568 | pStatus->codecStatus.ac3.acmod = decoderStatus.codecStatus.ac3.acmod; |
|---|
| 1569 | pStatus->codecStatus.ac3.frameSizeCode = decoderStatus.codecStatus.ac3.frameSizeCode; |
|---|
| 1570 | pStatus->codecStatus.ac3.bitrate = NEXUS_AudioDecoder_P_GetAc3Bitrate(decoderStatus.codecStatus.ac3.frameSizeCode); |
|---|
| 1571 | pStatus->codecStatus.ac3.lfe = decoderStatus.codecStatus.ac3.lfe; |
|---|
| 1572 | pStatus->codecStatus.ac3.copyright = decoderStatus.codecStatus.ac3.copyright; |
|---|
| 1573 | break; |
|---|
| 1574 | case BAVC_AudioCompressionStd_eDts: |
|---|
| 1575 | case BAVC_AudioCompressionStd_eDtshd: |
|---|
| 1576 | case BAVC_AudioCompressionStd_eDtsLegacy: |
|---|
| 1577 | pStatus->codecStatus.dts.amode = decoderStatus.codecStatus.dts.amode; |
|---|
| 1578 | pStatus->codecStatus.dts.pcmResolution = decoderStatus.codecStatus.dts.pcmResolution; |
|---|
| 1579 | pStatus->codecStatus.dts.copyHistory = decoderStatus.codecStatus.dts.copyHistory; |
|---|
| 1580 | pStatus->codecStatus.dts.extensionDescriptor = decoderStatus.codecStatus.dts.extensionDescriptor; |
|---|
| 1581 | pStatus->codecStatus.dts.bitRate = decoderStatus.codecStatus.dts.bitRate; |
|---|
| 1582 | pStatus->codecStatus.dts.version = decoderStatus.codecStatus.dts.version; |
|---|
| 1583 | pStatus->codecStatus.dts.esFormat = decoderStatus.codecStatus.dts.esFormat; |
|---|
| 1584 | pStatus->codecStatus.dts.lfe = decoderStatus.codecStatus.dts.lfe; |
|---|
| 1585 | pStatus->codecStatus.dts.extensionPresent = decoderStatus.codecStatus.dts.extensionPresent; |
|---|
| 1586 | pStatus->codecStatus.dts.crc = decoderStatus.codecStatus.dts.crc; |
|---|
| 1587 | pStatus->codecStatus.dts.hdcdFormat = decoderStatus.codecStatus.dts.hdcdFormat; |
|---|
| 1588 | pStatus->codecStatus.dts.drc = decoderStatus.codecStatus.dts.drc; |
|---|
| 1589 | pStatus->codecStatus.dts.downmixCoefficients = decoderStatus.codecStatus.dts.downmixCoefficients; |
|---|
| 1590 | pStatus->codecStatus.dts.neo = decoderStatus.codecStatus.dts.neo; |
|---|
| 1591 | pStatus->codecStatus.dts.frameSize = decoderStatus.codecStatus.dts.frameSize; |
|---|
| 1592 | pStatus->codecStatus.dts.numChannels = decoderStatus.codecStatus.dts.numChannels; |
|---|
| 1593 | pStatus->codecStatus.dts.pcmFrameSize = decoderStatus.codecStatus.dts.pcmFrameSize; |
|---|
| 1594 | pStatus->codecStatus.dts.numPcmBlocks = decoderStatus.codecStatus.dts.numPcmBlocks; |
|---|
| 1595 | break; |
|---|
| 1596 | case BAVC_AudioCompressionStd_eWmaStd: |
|---|
| 1597 | case BAVC_AudioCompressionStd_eWmaStdTs: |
|---|
| 1598 | pStatus->codecStatus.wma.bitRate = decoderStatus.codecStatus.wma.bitRate; |
|---|
| 1599 | pStatus->codecStatus.wma.original = decoderStatus.codecStatus.wma.original; |
|---|
| 1600 | pStatus->codecStatus.wma.copyright = decoderStatus.codecStatus.wma.copyright; |
|---|
| 1601 | pStatus->codecStatus.wma.crc = decoderStatus.codecStatus.wma.crc; |
|---|
| 1602 | pStatus->codecStatus.wma.stereo = decoderStatus.codecStatus.wma.channelMode == (BAPE_ChannelMode_e2_0)?true:false; |
|---|
| 1603 | pStatus->codecStatus.wma.version = decoderStatus.codecStatus.wma.version; |
|---|
| 1604 | break; |
|---|
| 1605 | case BAVC_AudioCompressionStd_eWmaPro: |
|---|
| 1606 | pStatus->codecStatus.wmaPro.bitRate = decoderStatus.codecStatus.wmaPro.bitRate; |
|---|
| 1607 | pStatus->codecStatus.wmaPro.original = decoderStatus.codecStatus.wmaPro.original; |
|---|
| 1608 | pStatus->codecStatus.wmaPro.copyright = decoderStatus.codecStatus.wmaPro.copyright; |
|---|
| 1609 | pStatus->codecStatus.wmaPro.crc = decoderStatus.codecStatus.wmaPro.crc; |
|---|
| 1610 | pStatus->codecStatus.wmaPro.lfe = decoderStatus.codecStatus.wmaPro.lfe; |
|---|
| 1611 | pStatus->codecStatus.wmaPro.version = decoderStatus.codecStatus.wmaPro.version; |
|---|
| 1612 | pStatus->codecStatus.wmaPro.stereoMode = decoderStatus.codecStatus.wmaPro.stereoMode; |
|---|
| 1613 | switch ( decoderStatus.codecStatus.wmaPro.channelMode ) |
|---|
| 1614 | { |
|---|
| 1615 | case BAPE_ChannelMode_e1_0: |
|---|
| 1616 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e1_0_C; |
|---|
| 1617 | break; |
|---|
| 1618 | case BAPE_ChannelMode_e2_0: |
|---|
| 1619 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e2_0_LR; |
|---|
| 1620 | break; |
|---|
| 1621 | case BAPE_ChannelMode_e3_0: |
|---|
| 1622 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e3_0_LCR; |
|---|
| 1623 | break; |
|---|
| 1624 | case BAPE_ChannelMode_e2_1: |
|---|
| 1625 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e2_1_LRS; |
|---|
| 1626 | break; |
|---|
| 1627 | case BAPE_ChannelMode_e3_1: |
|---|
| 1628 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e3_1_LCRS; |
|---|
| 1629 | break; |
|---|
| 1630 | case BAPE_ChannelMode_e2_2: |
|---|
| 1631 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e2_2_LRLsRs; |
|---|
| 1632 | break; |
|---|
| 1633 | case BAPE_ChannelMode_e3_2: |
|---|
| 1634 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_e3_2_LCRLsRs; |
|---|
| 1635 | break; |
|---|
| 1636 | default: |
|---|
| 1637 | pStatus->codecStatus.wmaPro.acmod = NEXUS_AudioWmaProAcmod_eUndefined; |
|---|
| 1638 | break; |
|---|
| 1639 | } |
|---|
| 1640 | break; |
|---|
| 1641 | case BAVC_AudioCompressionStd_ePcmWav: |
|---|
| 1642 | pStatus->codecStatus.pcmWav.numChannels = decoderStatus.codecStatus.pcmWav.numChannels; |
|---|
| 1643 | break; |
|---|
| 1644 | case BAVC_AudioCompressionStd_eAmr: |
|---|
| 1645 | pStatus->codecStatus.amr.bitRate = decoderStatus.codecStatus.amr.bitRate; |
|---|
| 1646 | break; |
|---|
| 1647 | case BAVC_AudioCompressionStd_eDra: |
|---|
| 1648 | pStatus->codecStatus.dra.frameSize = decoderStatus.codecStatus.dra.frameSize; |
|---|
| 1649 | pStatus->codecStatus.dra.numBlocks = decoderStatus.codecStatus.dra.numBlocks; |
|---|
| 1650 | pStatus->codecStatus.dra.acmod = decoderStatus.codecStatus.dra.acmod; |
|---|
| 1651 | pStatus->codecStatus.dra.lfe = decoderStatus.codecStatus.dra.lfe; |
|---|
| 1652 | pStatus->codecStatus.dra.stereoMode = decoderStatus.codecStatus.dra.stereoMode; |
|---|
| 1653 | break; |
|---|
| 1654 | case BAVC_AudioCompressionStd_eCook: |
|---|
| 1655 | pStatus->codecStatus.cook.stereo = decoderStatus.codecStatus.cook.stereo; |
|---|
| 1656 | pStatus->codecStatus.cook.frameSize = decoderStatus.codecStatus.cook.frameSize; |
|---|
| 1657 | break; |
|---|
| 1658 | default: |
|---|
| 1659 | /* No specifics for this codec */ |
|---|
| 1660 | break; |
|---|
| 1661 | } |
|---|
| 1662 | } |
|---|
| 1663 | |
|---|
| 1664 | return NEXUS_SUCCESS; |
|---|
| 1665 | } |
|---|
| 1666 | |
|---|
| 1667 | /*************************************************************************** |
|---|
| 1668 | Summary: |
|---|
| 1669 | Get raw channel status information from the decoder |
|---|
| 1670 | |
|---|
| 1671 | Description: |
|---|
| 1672 | When the decoder is connected to a digital input, this routine can |
|---|
| 1673 | return the raw channel status bit information from the input device. |
|---|
| 1674 | Currently, this applies to HDMI or SPDIF inputs only. This routine |
|---|
| 1675 | will return an error if not connected to a digital input. |
|---|
| 1676 | |
|---|
| 1677 | See Also: |
|---|
| 1678 | NEXUS_SpdifOutput_SetRawChannelStatus |
|---|
| 1679 | ***************************************************************************/ |
|---|
| 1680 | NEXUS_Error NEXUS_AudioDecoder_GetRawChannelStatus( |
|---|
| 1681 | NEXUS_AudioDecoderHandle handle, |
|---|
| 1682 | NEXUS_AudioRawChannelStatus *pStatus /* [out] current status */ |
|---|
| 1683 | ) |
|---|
| 1684 | { |
|---|
| 1685 | BSTD_UNUSED(handle); |
|---|
| 1686 | BSTD_UNUSED(pStatus); |
|---|
| 1687 | return BERR_TRACE(BERR_NOT_SUPPORTED); |
|---|
| 1688 | } |
|---|
| 1689 | |
|---|
| 1690 | /*************************************************************************** |
|---|
| 1691 | Summary: |
|---|
| 1692 | Get an audio connector for use in the audio mixer |
|---|
| 1693 | ***************************************************************************/ |
|---|
| 1694 | NEXUS_AudioInput NEXUS_AudioDecoder_GetConnector( /* attr{shutdown=NEXUS_AudioInput_Shutdown} */ |
|---|
| 1695 | NEXUS_AudioDecoderHandle handle, |
|---|
| 1696 | NEXUS_AudioDecoderConnectorType type |
|---|
| 1697 | ) |
|---|
| 1698 | { |
|---|
| 1699 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1700 | BDBG_ASSERT(type < NEXUS_AudioDecoderConnectorType_eMax); |
|---|
| 1701 | return &handle->connectors[type]; |
|---|
| 1702 | } |
|---|
| 1703 | |
|---|
| 1704 | NEXUS_Error NEXUS_AudioDecoder_ApplySettings_priv( |
|---|
| 1705 | NEXUS_AudioDecoderHandle handle |
|---|
| 1706 | ) |
|---|
| 1707 | { |
|---|
| 1708 | BAPE_DecoderTsmSettings tsmSettings; |
|---|
| 1709 | BAPE_DecoderSettings decoderSettings; |
|---|
| 1710 | BAPE_MixerInputVolume volume; |
|---|
| 1711 | unsigned i,j; |
|---|
| 1712 | BERR_Code errCode; |
|---|
| 1713 | bool forceMute=false; |
|---|
| 1714 | |
|---|
| 1715 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1716 | |
|---|
| 1717 | BAPE_Decoder_GetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 1718 | tsmSettings.ptsOffset = handle->settings.ptsOffset + handle->syncSettings.delay; |
|---|
| 1719 | |
|---|
| 1720 | #if NEXUS_HAS_ASTM |
|---|
| 1721 | if (handle->astm.settings.enableAstm) |
|---|
| 1722 | { |
|---|
| 1723 | BDBG_MSG(("ASTM is setting the sync limit for audio channel %p to %d", handle, handle->astm.settings.syncLimit)); |
|---|
| 1724 | tsmSettings.thresholds.syncLimit = handle->astm.settings.syncLimit; |
|---|
| 1725 | /* PR49489 20081201 bandrews - added for audio master mode */ |
|---|
| 1726 | BDBG_MSG(("ASTM is %s playback mode for audio channel %p", handle->astm.settings.enablePlayback ? "enabling" : "disabling", handle)); |
|---|
| 1727 | tsmSettings.playback = handle->astm.settings.enablePlayback; |
|---|
| 1728 | tsmSettings.ptsOffset += handle->astm.settings.ptsOffset; |
|---|
| 1729 | } |
|---|
| 1730 | else |
|---|
| 1731 | { |
|---|
| 1732 | tsmSettings.thresholds.syncLimit = 0; |
|---|
| 1733 | } |
|---|
| 1734 | #endif |
|---|
| 1735 | |
|---|
| 1736 | if ( 0 == handle->settings.discardThreshold ) |
|---|
| 1737 | { |
|---|
| 1738 | tsmSettings.thresholds.discard = (handle->isPlayback)?30000:3000; /* ms */ |
|---|
| 1739 | } |
|---|
| 1740 | else |
|---|
| 1741 | { |
|---|
| 1742 | tsmSettings.thresholds.discard = handle->settings.discardThreshold; |
|---|
| 1743 | } |
|---|
| 1744 | |
|---|
| 1745 | if ( 0 == handle->settings.gaThreshold ) |
|---|
| 1746 | { |
|---|
| 1747 | NEXUS_PidChannelStatus pidChannelStatus; |
|---|
| 1748 | |
|---|
| 1749 | BKNI_Memset(&pidChannelStatus, 0, sizeof(pidChannelStatus)); |
|---|
| 1750 | if ( handle->started && NULL != handle->programSettings.pidChannel ) |
|---|
| 1751 | { |
|---|
| 1752 | (void)NEXUS_PidChannel_GetStatus(handle->programSettings.pidChannel, &pidChannelStatus); |
|---|
| 1753 | } |
|---|
| 1754 | |
|---|
| 1755 | tsmSettings.thresholds.grossAdjustment = (pidChannelStatus.originalTransportType == NEXUS_TransportType_eAvi) ? 0x30 : 0x8; |
|---|
| 1756 | } |
|---|
| 1757 | else |
|---|
| 1758 | { |
|---|
| 1759 | tsmSettings.thresholds.grossAdjustment = handle->settings.gaThreshold; |
|---|
| 1760 | } |
|---|
| 1761 | BAPE_Decoder_SetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 1762 | |
|---|
| 1763 | NEXUS_AudioDecoder_P_SetTsm(handle); |
|---|
| 1764 | |
|---|
| 1765 | BAPE_Decoder_GetSettings(handle->channel, &decoderSettings); |
|---|
| 1766 | switch ( handle->settings.outputLfeMode ) |
|---|
| 1767 | { |
|---|
| 1768 | default: |
|---|
| 1769 | decoderSettings.outputLfe = true; |
|---|
| 1770 | break; |
|---|
| 1771 | case NEXUS_AudioDecoderOutputLfeMode_eOff: |
|---|
| 1772 | decoderSettings.outputLfe = false; |
|---|
| 1773 | break; |
|---|
| 1774 | } |
|---|
| 1775 | switch ( handle->settings.outputMode ) |
|---|
| 1776 | { |
|---|
| 1777 | default: |
|---|
| 1778 | case NEXUS_AudioDecoderOutputMode_eAuto: |
|---|
| 1779 | decoderSettings.outputMode = BAPE_ChannelMode_e3_2; |
|---|
| 1780 | break; |
|---|
| 1781 | case NEXUS_AudioDecoderOutputMode_e1_0: |
|---|
| 1782 | decoderSettings.outputMode = BAPE_ChannelMode_e1_0; |
|---|
| 1783 | break; |
|---|
| 1784 | case NEXUS_AudioDecoderOutputMode_e1_1: |
|---|
| 1785 | decoderSettings.outputMode = BAPE_ChannelMode_e1_1; |
|---|
| 1786 | break; |
|---|
| 1787 | case NEXUS_AudioDecoderOutputMode_e2_0: |
|---|
| 1788 | decoderSettings.outputMode = BAPE_ChannelMode_e2_0; |
|---|
| 1789 | break; |
|---|
| 1790 | case NEXUS_AudioDecoderOutputMode_e3_0: |
|---|
| 1791 | decoderSettings.outputMode = BAPE_ChannelMode_e3_0; |
|---|
| 1792 | break; |
|---|
| 1793 | case NEXUS_AudioDecoderOutputMode_e2_1: |
|---|
| 1794 | decoderSettings.outputMode = BAPE_ChannelMode_e2_1; |
|---|
| 1795 | break; |
|---|
| 1796 | case NEXUS_AudioDecoderOutputMode_e3_1: |
|---|
| 1797 | decoderSettings.outputMode = BAPE_ChannelMode_e3_1; |
|---|
| 1798 | break; |
|---|
| 1799 | case NEXUS_AudioDecoderOutputMode_e2_2: |
|---|
| 1800 | decoderSettings.outputMode = BAPE_ChannelMode_e2_2; |
|---|
| 1801 | break; |
|---|
| 1802 | case NEXUS_AudioDecoderOutputMode_e3_2: |
|---|
| 1803 | decoderSettings.outputMode = BAPE_ChannelMode_e3_2; |
|---|
| 1804 | break; |
|---|
| 1805 | case NEXUS_AudioDecoderOutputMode_e3_4: |
|---|
| 1806 | decoderSettings.outputMode = BAPE_ChannelMode_e3_4; |
|---|
| 1807 | break; |
|---|
| 1808 | } |
|---|
| 1809 | switch ( handle->settings.dualMonoMode ) |
|---|
| 1810 | { |
|---|
| 1811 | default: |
|---|
| 1812 | case NEXUS_AudioDecoderDualMonoMode_eStereo: |
|---|
| 1813 | decoderSettings.dualMonoMode = BAPE_DualMonoMode_eStereo; |
|---|
| 1814 | break; |
|---|
| 1815 | case NEXUS_AudioDecoderDualMonoMode_eLeft: |
|---|
| 1816 | decoderSettings.dualMonoMode = BAPE_DualMonoMode_eLeft; |
|---|
| 1817 | break; |
|---|
| 1818 | case NEXUS_AudioDecoderDualMonoMode_eRight: |
|---|
| 1819 | decoderSettings.dualMonoMode = BAPE_DualMonoMode_eRight; |
|---|
| 1820 | break; |
|---|
| 1821 | case NEXUS_AudioDecoderDualMonoMode_eMix: |
|---|
| 1822 | decoderSettings.dualMonoMode = BAPE_DualMonoMode_eMix; |
|---|
| 1823 | break; |
|---|
| 1824 | } |
|---|
| 1825 | |
|---|
| 1826 | if ( handle->trickState.rate == 0 ) |
|---|
| 1827 | { |
|---|
| 1828 | decoderSettings.decodeRate = BAPE_NORMAL_DECODE_RATE; |
|---|
| 1829 | } |
|---|
| 1830 | else if ( handle->trickState.rate > (2*NEXUS_NORMAL_DECODE_RATE) || handle->trickState.rate < (NEXUS_NORMAL_DECODE_RATE/2) ) |
|---|
| 1831 | { |
|---|
| 1832 | BDBG_MSG(("Audio trick modes are only supported between 0.5x and 2x normal rate. Muting audio decoder.")); |
|---|
| 1833 | forceMute = true; |
|---|
| 1834 | decoderSettings.decodeRate = BAPE_NORMAL_DECODE_RATE; |
|---|
| 1835 | } |
|---|
| 1836 | else |
|---|
| 1837 | { |
|---|
| 1838 | decoderSettings.decodeRate = (handle->trickState.rate * BAPE_NORMAL_DECODE_RATE)/ NEXUS_NORMAL_DECODE_RATE; |
|---|
| 1839 | } |
|---|
| 1840 | // JPF decoderSettings.loudnessEquivalenceEnabled = handle->settings.loudnessEquivalenceEnabled; |
|---|
| 1841 | errCode = BAPE_Decoder_SetSettings(handle->channel, &decoderSettings); |
|---|
| 1842 | if ( errCode ) |
|---|
| 1843 | { |
|---|
| 1844 | return BERR_TRACE(errCode); |
|---|
| 1845 | } |
|---|
| 1846 | |
|---|
| 1847 | /* Apply volume settings - but only if an output has ever been connected by the user. |
|---|
| 1848 | Otherwise this forces a Shutdown() call in the application. */ |
|---|
| 1849 | if ( handle->connectors[NEXUS_AudioDecoderConnectorType_eStereo].pMixerData ) |
|---|
| 1850 | { |
|---|
| 1851 | NEXUS_AudioInput_P_GetVolume(&handle->connectors[NEXUS_AudioDecoderConnectorType_eStereo], &volume); |
|---|
| 1852 | } |
|---|
| 1853 | else if ( handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].pMixerData ) |
|---|
| 1854 | { |
|---|
| 1855 | NEXUS_AudioInput_P_GetVolume(&handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel], &volume); |
|---|
| 1856 | } |
|---|
| 1857 | else |
|---|
| 1858 | { |
|---|
| 1859 | goto skip_volume; |
|---|
| 1860 | } |
|---|
| 1861 | for ( i = 0; i < NEXUS_AudioChannel_eMax; i++ ) |
|---|
| 1862 | { |
|---|
| 1863 | for ( j = 0; j < NEXUS_AudioChannel_eMax; j++ ) |
|---|
| 1864 | { |
|---|
| 1865 | volume.coefficients[i][j] = handle->settings.volumeMatrix[j][i]; |
|---|
| 1866 | } |
|---|
| 1867 | } |
|---|
| 1868 | volume.muted = handle->settings.muted || handle->trickState.muted || handle->syncSettings.mute || forceMute; |
|---|
| 1869 | if ( handle->connectors[NEXUS_AudioDecoderConnectorType_eStereo].pMixerData ) |
|---|
| 1870 | { |
|---|
| 1871 | errCode = NEXUS_AudioInput_P_SetVolume(&handle->connectors[NEXUS_AudioDecoderConnectorType_eStereo], &volume); |
|---|
| 1872 | if ( errCode ) |
|---|
| 1873 | { |
|---|
| 1874 | return BERR_TRACE(errCode); |
|---|
| 1875 | } |
|---|
| 1876 | } |
|---|
| 1877 | if ( handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel].pMixerData ) |
|---|
| 1878 | { |
|---|
| 1879 | errCode = NEXUS_AudioInput_P_SetVolume(&handle->connectors[NEXUS_AudioDecoderConnectorType_eMultichannel], &volume); |
|---|
| 1880 | if ( errCode ) |
|---|
| 1881 | { |
|---|
| 1882 | return BERR_TRACE(errCode); |
|---|
| 1883 | } |
|---|
| 1884 | } |
|---|
| 1885 | skip_volume: |
|---|
| 1886 | return BERR_SUCCESS; |
|---|
| 1887 | } |
|---|
| 1888 | |
|---|
| 1889 | #if NEXUS_HAS_ASTM |
|---|
| 1890 | void NEXUS_AudioDecoder_GetAstmSettings_priv( |
|---|
| 1891 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1892 | NEXUS_AudioDecoderAstmSettings * pAstmSettings /* [out] */ |
|---|
| 1893 | ) |
|---|
| 1894 | { |
|---|
| 1895 | NEXUS_ASSERT_MODULE(); |
|---|
| 1896 | |
|---|
| 1897 | *pAstmSettings = audioDecoder->astm.settings; |
|---|
| 1898 | } |
|---|
| 1899 | |
|---|
| 1900 | NEXUS_Error NEXUS_AudioDecoder_SetAstmSettings_priv( |
|---|
| 1901 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1902 | const NEXUS_AudioDecoderAstmSettings * pAstmSettings |
|---|
| 1903 | ) |
|---|
| 1904 | { |
|---|
| 1905 | NEXUS_Error rc = NEXUS_SUCCESS; |
|---|
| 1906 | |
|---|
| 1907 | NEXUS_ASSERT_MODULE(); |
|---|
| 1908 | |
|---|
| 1909 | /* copy settings as-is, this way ASTM will always get what it set */ |
|---|
| 1910 | audioDecoder->astm.settings = *pAstmSettings; |
|---|
| 1911 | |
|---|
| 1912 | /* if ASTM is internally permitted, apply settings */ |
|---|
| 1913 | rc = NEXUS_AudioDecoder_ApplySettings_priv(audioDecoder); |
|---|
| 1914 | |
|---|
| 1915 | return rc; |
|---|
| 1916 | } |
|---|
| 1917 | |
|---|
| 1918 | NEXUS_Error NEXUS_AudioDecoder_GetAstmStatus_isr( |
|---|
| 1919 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1920 | NEXUS_AudioDecoderAstmStatus * pAstmStatus /* [out] */ |
|---|
| 1921 | ) |
|---|
| 1922 | { |
|---|
| 1923 | BAPE_DecoderTsmStatus tsmStatus; |
|---|
| 1924 | BERR_Code rc; |
|---|
| 1925 | |
|---|
| 1926 | BKNI_ASSERT_ISR_CONTEXT(); |
|---|
| 1927 | |
|---|
| 1928 | rc = BAPE_Decoder_GetTsmStatus_isr(audioDecoder->channel, &tsmStatus); |
|---|
| 1929 | audioDecoder->astm.status.ptsStcDiff = tsmStatus.ptsStcDifference; |
|---|
| 1930 | |
|---|
| 1931 | *pAstmStatus = audioDecoder->astm.status; |
|---|
| 1932 | |
|---|
| 1933 | return 0; |
|---|
| 1934 | } |
|---|
| 1935 | #endif |
|---|
| 1936 | |
|---|
| 1937 | void NEXUS_AudioDecoder_GetSyncSettings_priv( |
|---|
| 1938 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1939 | NEXUS_AudioInputSyncSettings *pSyncSettings /* [out] */ |
|---|
| 1940 | ) |
|---|
| 1941 | { |
|---|
| 1942 | BDBG_OBJECT_ASSERT(audioDecoder, NEXUS_AudioDecoder); |
|---|
| 1943 | BDBG_ASSERT(NULL != pSyncSettings); |
|---|
| 1944 | *pSyncSettings = audioDecoder->syncSettings; |
|---|
| 1945 | } |
|---|
| 1946 | |
|---|
| 1947 | NEXUS_Error NEXUS_AudioDecoder_SetSyncSettings_priv( |
|---|
| 1948 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1949 | const NEXUS_AudioInputSyncSettings *pSyncSettings |
|---|
| 1950 | ) |
|---|
| 1951 | { |
|---|
| 1952 | BDBG_OBJECT_ASSERT(audioDecoder, NEXUS_AudioDecoder); |
|---|
| 1953 | BDBG_ASSERT(NULL != pSyncSettings); |
|---|
| 1954 | audioDecoder->syncSettings = *pSyncSettings; |
|---|
| 1955 | return NEXUS_AudioDecoder_ApplySettings_priv(audioDecoder); |
|---|
| 1956 | } |
|---|
| 1957 | |
|---|
| 1958 | NEXUS_Error NEXUS_AudioDecoder_GetSyncStatus_isr( |
|---|
| 1959 | NEXUS_AudioDecoderHandle audioDecoder, |
|---|
| 1960 | NEXUS_AudioInputSyncStatus *pSyncStatus /* [out] */ |
|---|
| 1961 | ) |
|---|
| 1962 | { |
|---|
| 1963 | BDBG_OBJECT_ASSERT(audioDecoder, NEXUS_AudioDecoder); |
|---|
| 1964 | BDBG_ASSERT(NULL != pSyncStatus); |
|---|
| 1965 | BKNI_Memset(pSyncStatus, 0, sizeof(*pSyncStatus)); |
|---|
| 1966 | pSyncStatus->started = audioDecoder->running; |
|---|
| 1967 | pSyncStatus->digital = true; |
|---|
| 1968 | pSyncStatus->dsolaEnabled = false; |
|---|
| 1969 | BAPE_GetDecoderPathDelay(NEXUS_AUDIO_DEVICE_HANDLE, &pSyncStatus->delay); |
|---|
| 1970 | return BERR_SUCCESS; |
|---|
| 1971 | } |
|---|
| 1972 | |
|---|
| 1973 | bool NEXUS_AudioDecoder_P_IsRunning(NEXUS_AudioDecoderHandle handle) |
|---|
| 1974 | { |
|---|
| 1975 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 1976 | /* This is slightly dangerous with trick modes, because a trick mute may cause this to return false. |
|---|
| 1977 | But, it's required for HDMI/SPDIF inputs where the decoder actually "starts stopped". */ |
|---|
| 1978 | return handle->running; |
|---|
| 1979 | } |
|---|
| 1980 | |
|---|
| 1981 | void NEXUS_AudioDecoder_P_Reset(void) |
|---|
| 1982 | { |
|---|
| 1983 | unsigned i; |
|---|
| 1984 | |
|---|
| 1985 | LOCK_TRANSPORT(); |
|---|
| 1986 | for ( i = 0; i < NEXUS_NUM_AUDIO_DECODERS; i++ ) |
|---|
| 1987 | { |
|---|
| 1988 | if ( g_decoders[i].opened && g_decoders[i].running && NULL == g_decoders[i].programSettings.input ) |
|---|
| 1989 | { |
|---|
| 1990 | NEXUS_Rave_Disable_priv(g_decoders[i].raveContext); |
|---|
| 1991 | NEXUS_Rave_Flush_priv(g_decoders[i].raveContext); |
|---|
| 1992 | } |
|---|
| 1993 | } |
|---|
| 1994 | UNLOCK_TRANSPORT(); |
|---|
| 1995 | |
|---|
| 1996 | /* Process watchdog event */ |
|---|
| 1997 | BAPE_ProcessWatchdogInterrupt(NEXUS_AUDIO_DEVICE_HANDLE); |
|---|
| 1998 | |
|---|
| 1999 | /* Restart RAVE contexts */ |
|---|
| 2000 | LOCK_TRANSPORT(); |
|---|
| 2001 | for ( i = 0; i < NEXUS_NUM_AUDIO_DECODERS; i++ ) |
|---|
| 2002 | { |
|---|
| 2003 | if ( g_decoders[i].opened && g_decoders[i].running && NULL == g_decoders[i].programSettings.input ) |
|---|
| 2004 | { |
|---|
| 2005 | NEXUS_Rave_Enable_priv(g_decoders[i].raveContext); |
|---|
| 2006 | } |
|---|
| 2007 | } |
|---|
| 2008 | UNLOCK_TRANSPORT(); |
|---|
| 2009 | |
|---|
| 2010 | #if NEXUS_HAS_ASTM |
|---|
| 2011 | for ( i = 0; i < NEXUS_NUM_AUDIO_DECODERS; i++ ) |
|---|
| 2012 | { |
|---|
| 2013 | if ( g_decoders[i].opened && g_decoders[i].running && g_decoders[i].astm.settings.enableAstm ) |
|---|
| 2014 | { |
|---|
| 2015 | NEXUS_Callback astm_watchdog_isr = g_decoders[i].astm.settings.watchdog_isr; |
|---|
| 2016 | BDBG_MSG(("Audio channel %p is notifying ASTM of its watchdog recovery", &g_decoders[i])); |
|---|
| 2017 | if (astm_watchdog_isr) |
|---|
| 2018 | { |
|---|
| 2019 | BKNI_EnterCriticalSection(); |
|---|
| 2020 | astm_watchdog_isr(g_decoders[i].astm.settings.callbackContext, 0); |
|---|
| 2021 | BKNI_LeaveCriticalSection(); |
|---|
| 2022 | } |
|---|
| 2023 | } |
|---|
| 2024 | } |
|---|
| 2025 | #endif |
|---|
| 2026 | } |
|---|
| 2027 | |
|---|
| 2028 | static void NEXUS_AudioDecoder_P_Watchdog(void *pParam) |
|---|
| 2029 | { |
|---|
| 2030 | bool corePending=false; |
|---|
| 2031 | |
|---|
| 2032 | BSTD_UNUSED(pParam); |
|---|
| 2033 | |
|---|
| 2034 | g_numWatchdogs++; |
|---|
| 2035 | |
|---|
| 2036 | /* Check if core dump support is enabled. If so, spin and wait for it to complete. */ |
|---|
| 2037 | if ( g_NEXUS_audioModuleData.settings.dspDebugSettings.typeSettings[NEXUS_AudioDspDebugType_eCoreDump].enabled ) |
|---|
| 2038 | { |
|---|
| 2039 | /* Poll for core dump to finish and inform application */ |
|---|
| 2040 | unsigned retries = 100; |
|---|
| 2041 | |
|---|
| 2042 | while ( BDSP_Raaga_GetCoreDumpStatus(g_NEXUS_audioModuleData.dspHandle, 0) == BDSP_Raaga_FwStatus_eCoreDumpInProgress ) |
|---|
| 2043 | { |
|---|
| 2044 | BKNI_Sleep(1); |
|---|
| 2045 | if ( 0 == --retries ) |
|---|
| 2046 | { |
|---|
| 2047 | break; |
|---|
| 2048 | } |
|---|
| 2049 | } |
|---|
| 2050 | |
|---|
| 2051 | if ( BDSP_Raaga_GetCoreDumpStatus(g_NEXUS_audioModuleData.dspHandle, 0) == BDSP_Raaga_FwStatus_eCoreDumpComplete ) |
|---|
| 2052 | { |
|---|
| 2053 | corePending = true; |
|---|
| 2054 | } |
|---|
| 2055 | } |
|---|
| 2056 | |
|---|
| 2057 | if ( corePending ) |
|---|
| 2058 | { |
|---|
| 2059 | BDBG_WRN(("Audio watchdog reset postponed for core dump retrieval")); |
|---|
| 2060 | g_NEXUS_audioModuleData.watchdogDeferred = true; |
|---|
| 2061 | } |
|---|
| 2062 | else |
|---|
| 2063 | { |
|---|
| 2064 | /* Just restart now */ |
|---|
| 2065 | NEXUS_AudioDecoder_P_Reset(); |
|---|
| 2066 | } |
|---|
| 2067 | } |
|---|
| 2068 | |
|---|
| 2069 | static void NEXUS_AudioDecoder_P_SampleRate(void *pParam) |
|---|
| 2070 | { |
|---|
| 2071 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam; |
|---|
| 2072 | |
|---|
| 2073 | #if 0 /* TODO */ |
|---|
| 2074 | if(pDecoder->settings.wideGaThreshold) { |
|---|
| 2075 | BRAP_DSPCHN_TsmDebugInfo info; |
|---|
| 2076 | uint32_t new_threshold; |
|---|
| 2077 | |
|---|
| 2078 | BRAP_GetTsmDebugInfo(pDecoder->rapChannel, &info); |
|---|
| 2079 | |
|---|
| 2080 | new_threshold = (info.sPtsInfo.i32TSMUpperThreshold*3)/2; |
|---|
| 2081 | |
|---|
| 2082 | BDBG_WRN(("Adjusting GA threshold to: %d (was %d)", new_threshold, info.sPtsInfo.i32TSMUpperThreshold)); |
|---|
| 2083 | |
|---|
| 2084 | BRAP_SetTsmGAThreshold(pDecoder->rapChannel, new_threshold/45); |
|---|
| 2085 | } |
|---|
| 2086 | #else |
|---|
| 2087 | BSTD_UNUSED(pDecoder); |
|---|
| 2088 | #endif |
|---|
| 2089 | |
|---|
| 2090 | BDBG_MSG(("Sample Rate decoder[%d]", pDecoder->index)); |
|---|
| 2091 | } |
|---|
| 2092 | |
|---|
| 2093 | static void NEXUS_AudioDecoder_P_ChannelChangeReport(void * context) |
|---|
| 2094 | { |
|---|
| 2095 | BSTD_UNUSED(context); |
|---|
| 2096 | } |
|---|
| 2097 | |
|---|
| 2098 | static void NEXUS_AudioDecoder_P_FirstPts_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus) |
|---|
| 2099 | { |
|---|
| 2100 | NEXUS_Error errCode; |
|---|
| 2101 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2102 | |
|---|
| 2103 | BSTD_UNUSED(param2); |
|---|
| 2104 | |
|---|
| 2105 | BDBG_MSG(("audio[%d] First PTS %08x", pDecoder->index, pTsmStatus->ptsInfo.ui32CurrentPTS)); |
|---|
| 2106 | if ( pDecoder->programSettings.stcChannel ) |
|---|
| 2107 | { |
|---|
| 2108 | NEXUS_IsrCallback_Fire_isr(pDecoder->firstPtsCallback); |
|---|
| 2109 | errCode = NEXUS_StcChannel_RequestStc_isr(pDecoder->programSettings.stcChannel, pDecoder->stcDecoderType, &pTsmStatus->ptsInfo); |
|---|
| 2110 | if ( errCode ) |
|---|
| 2111 | { |
|---|
| 2112 | errCode=BERR_TRACE(errCode); |
|---|
| 2113 | } |
|---|
| 2114 | } |
|---|
| 2115 | #if NEXUS_HAS_ASTM |
|---|
| 2116 | if (pDecoder->astm.settings.enableAstm) |
|---|
| 2117 | { |
|---|
| 2118 | pDecoder->astm.status.pts = pTsmStatus->ptsInfo.ui32CurrentPTS; |
|---|
| 2119 | |
|---|
| 2120 | if (pDecoder->astm.settings.firstPts_isr) |
|---|
| 2121 | { |
|---|
| 2122 | pDecoder->astm.settings.firstPts_isr(pDecoder->astm.settings.callbackContext, 0); |
|---|
| 2123 | } |
|---|
| 2124 | } |
|---|
| 2125 | #endif /* NEXUS_HAS_ASTM */ |
|---|
| 2126 | } |
|---|
| 2127 | |
|---|
| 2128 | static void NEXUS_AudioDecoder_P_AudioTsmFail_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus) |
|---|
| 2129 | { |
|---|
| 2130 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2131 | BAPE_DecoderTsmStatus tsmStatus; |
|---|
| 2132 | NEXUS_Error errCode; |
|---|
| 2133 | |
|---|
| 2134 | uint32_t stc; |
|---|
| 2135 | |
|---|
| 2136 | BSTD_UNUSED(param2); |
|---|
| 2137 | BDBG_ASSERT(NULL != pTsmStatus); |
|---|
| 2138 | |
|---|
| 2139 | BDBG_MSG(("audio[%d] Tsm fail: PTS 0x%08x, type %d", |
|---|
| 2140 | pDecoder->index, pTsmStatus->ptsInfo.ui32CurrentPTS, pTsmStatus->ptsInfo.ePTSType)); |
|---|
| 2141 | |
|---|
| 2142 | NEXUS_StcChannel_GetStc_isr(pDecoder->programSettings.stcChannel, &stc); |
|---|
| 2143 | |
|---|
| 2144 | /* If we're in a non-standard STC trick mode */ |
|---|
| 2145 | if ( pDecoder->trickState.stcTrickEnabled && (pDecoder->trickState.rate < 500 || pDecoder->trickState.rate > 2000) ) |
|---|
| 2146 | { |
|---|
| 2147 | /* in STC trick mode, PTS might lag the STC because of decoder drop algorithm. don't reset STC in this case. */ |
|---|
| 2148 | if ( stc > pTsmStatus->ptsInfo.ui32CurrentPTS && stc - pTsmStatus->ptsInfo.ui32CurrentPTS < 45000 * 8 ) |
|---|
| 2149 | { |
|---|
| 2150 | return; |
|---|
| 2151 | } |
|---|
| 2152 | } |
|---|
| 2153 | |
|---|
| 2154 | BDBG_MSG(("pts2stcphase: %d", pTsmStatus->ptsStcDifference)); |
|---|
| 2155 | |
|---|
| 2156 | #if NEXUS_HAS_ASTM |
|---|
| 2157 | if (pDecoder->astm.settings.enableAstm && pDecoder->astm.settings.syncLimit > 0) |
|---|
| 2158 | { |
|---|
| 2159 | tsmStatus = *pTsmStatus; |
|---|
| 2160 | tsmStatus.ptsInfo.ui32CurrentPTS = (uint32_t)((int32_t)stc - tsmStatus.ptsStcDifference); |
|---|
| 2161 | pTsmStatus = &tsmStatus; |
|---|
| 2162 | } |
|---|
| 2163 | #endif /* NEXUS_HAS_ASTM */ |
|---|
| 2164 | |
|---|
| 2165 | /* PR:52308 ignore PTS errors for non-XPT inputs - we can't do anything about them from stcchannel/pcrlib anyway */ |
|---|
| 2166 | if (!pDecoder->programSettings.input) |
|---|
| 2167 | { |
|---|
| 2168 | NEXUS_IsrCallback_Fire_isr(pDecoder->ptsErrorCallback); |
|---|
| 2169 | errCode = NEXUS_StcChannel_PtsError_isr(pDecoder->programSettings.stcChannel, pDecoder->stcDecoderType, &pTsmStatus->ptsInfo); |
|---|
| 2170 | if (errCode) |
|---|
| 2171 | { |
|---|
| 2172 | errCode=BERR_TRACE(errCode); |
|---|
| 2173 | /* keep going */ |
|---|
| 2174 | } |
|---|
| 2175 | } |
|---|
| 2176 | |
|---|
| 2177 | #if NEXUS_HAS_ASTM |
|---|
| 2178 | if (pDecoder->astm.settings.enableAstm) |
|---|
| 2179 | { |
|---|
| 2180 | pDecoder->astm.status.pts = pTsmStatus->ptsInfo.ui32CurrentPTS; |
|---|
| 2181 | |
|---|
| 2182 | if (pDecoder->astm.settings.tsmFail_isr) |
|---|
| 2183 | { |
|---|
| 2184 | pDecoder->astm.settings.tsmFail_isr(pDecoder->astm.settings.callbackContext, 0); |
|---|
| 2185 | } |
|---|
| 2186 | } |
|---|
| 2187 | #endif /* NEXUS_HAS_ASTM */ |
|---|
| 2188 | |
|---|
| 2189 | pDecoder->ptsErrorCount++; |
|---|
| 2190 | } |
|---|
| 2191 | |
|---|
| 2192 | static void NEXUS_AudioDecoder_P_AudioTsmPass_isr(void *pParam1, int param2, const BAPE_DecoderTsmStatus *pTsmStatus) |
|---|
| 2193 | { |
|---|
| 2194 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2195 | |
|---|
| 2196 | BSTD_UNUSED(param2); |
|---|
| 2197 | BDBG_ASSERT(NULL != pTsmStatus); |
|---|
| 2198 | |
|---|
| 2199 | BDBG_MSG(("audio[%d] TSM pass: PTS 0x%08x, type %d", |
|---|
| 2200 | pDecoder->index, pTsmStatus->ptsInfo.ui32CurrentPTS, pTsmStatus->ptsInfo.ePTSType)); |
|---|
| 2201 | |
|---|
| 2202 | if (pDecoder->astm.settings.enableAstm) |
|---|
| 2203 | { |
|---|
| 2204 | pDecoder->astm.status.pts = pTsmStatus->ptsInfo.ui32CurrentPTS; |
|---|
| 2205 | |
|---|
| 2206 | if (pDecoder->astm.settings.tsmPass_isr) |
|---|
| 2207 | { |
|---|
| 2208 | pDecoder->astm.settings.tsmPass_isr(pDecoder->astm.settings.callbackContext, 0); |
|---|
| 2209 | } |
|---|
| 2210 | } |
|---|
| 2211 | } |
|---|
| 2212 | |
|---|
| 2213 | static void NEXUS_AudioDecoder_P_SampleRateChange_isr(void *pParam1, int param2, BAVC_AudioSamplingRate sampleRate) |
|---|
| 2214 | { |
|---|
| 2215 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2216 | |
|---|
| 2217 | BSTD_UNUSED(param2); |
|---|
| 2218 | |
|---|
| 2219 | BDBG_MSG(("audio[%d] Sampling Rate Info, samplingRate=%x", pDecoder->index, sampleRate)); |
|---|
| 2220 | |
|---|
| 2221 | BKNI_SetEvent_isr(pDecoder->sampleRateEvent); |
|---|
| 2222 | NEXUS_IsrCallback_Fire_isr(pDecoder->sourceChangeAppCallback); |
|---|
| 2223 | |
|---|
| 2224 | if (pDecoder->syncSettings.sampleRateCallback_isr) { |
|---|
| 2225 | (*pDecoder->syncSettings.sampleRateCallback_isr)(pDecoder->syncSettings.callbackContext, 0); |
|---|
| 2226 | } |
|---|
| 2227 | |
|---|
| 2228 | } |
|---|
| 2229 | |
|---|
| 2230 | static void NEXUS_AudioDecoder_P_Lock_isr(void *pParam1, int param2) |
|---|
| 2231 | { |
|---|
| 2232 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2233 | |
|---|
| 2234 | pDecoder->locked = param2; |
|---|
| 2235 | BDBG_MSG(("Decoder %u %s", pDecoder->index, param2?"lock":"unlock")); |
|---|
| 2236 | NEXUS_IsrCallback_Fire_isr(pDecoder->lockCallback); |
|---|
| 2237 | } |
|---|
| 2238 | |
|---|
| 2239 | static void NEXUS_AudioDecoder_P_StreamStatusAvailable_isr(void *pParam1, int param2) |
|---|
| 2240 | { |
|---|
| 2241 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2242 | |
|---|
| 2243 | pDecoder->locked = param2; |
|---|
| 2244 | BDBG_MSG(("Decoder %u Stream Status Ready", pDecoder->index)); |
|---|
| 2245 | NEXUS_IsrCallback_Fire_isr(pDecoder->streamStatusCallback); |
|---|
| 2246 | NEXUS_IsrCallback_Fire_isr(pDecoder->sourceChangeAppCallback); |
|---|
| 2247 | } |
|---|
| 2248 | |
|---|
| 2249 | static void NEXUS_AudioDecoder_P_StreamParameterChanged_isr(void *pParam1, int param2) |
|---|
| 2250 | { |
|---|
| 2251 | NEXUS_AudioDecoder *pDecoder = (NEXUS_AudioDecoder *)pParam1; |
|---|
| 2252 | |
|---|
| 2253 | pDecoder->locked = param2; |
|---|
| 2254 | BDBG_MSG(("Decoder %u Stream Parameter Changed", pDecoder->index)); |
|---|
| 2255 | NEXUS_IsrCallback_Fire_isr(pDecoder->sourceChangeAppCallback); |
|---|
| 2256 | } |
|---|
| 2257 | |
|---|
| 2258 | void NEXUS_AudioDecoder_P_SetTsm(NEXUS_AudioDecoderHandle handle) |
|---|
| 2259 | { |
|---|
| 2260 | BAPE_DecoderTsmSettings tsmSettings; |
|---|
| 2261 | |
|---|
| 2262 | BAPE_Decoder_GetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 2263 | tsmSettings.tsmEnabled = false; |
|---|
| 2264 | |
|---|
| 2265 | if ( handle->tsmPermitted ) |
|---|
| 2266 | { |
|---|
| 2267 | if ( handle->trickState.tsmEnabled ) |
|---|
| 2268 | { |
|---|
| 2269 | #if NEXUS_HAS_ASTM |
|---|
| 2270 | if ( handle->astm.settings.enableAstm ) |
|---|
| 2271 | { |
|---|
| 2272 | BDBG_MSG(("ASTM is %s TSM for audio channel %p", handle->astm.settings.enableTsm ? "enabling" : "disabling", handle)); |
|---|
| 2273 | if ( handle->astm.settings.enableTsm ) |
|---|
| 2274 | { |
|---|
| 2275 | tsmSettings.tsmEnabled = true; |
|---|
| 2276 | } |
|---|
| 2277 | } |
|---|
| 2278 | else |
|---|
| 2279 | #endif |
|---|
| 2280 | { |
|---|
| 2281 | tsmSettings.tsmEnabled = true; |
|---|
| 2282 | } |
|---|
| 2283 | } |
|---|
| 2284 | } |
|---|
| 2285 | |
|---|
| 2286 | BDBG_MSG(("%s TSM",tsmSettings.tsmEnabled?"Enabling":"Disabling")); |
|---|
| 2287 | |
|---|
| 2288 | #if NEXUS_HAS_ASTM |
|---|
| 2289 | /* Only allow ASTM if we have TSM enabled for all non-ASTM controls and we have a TS source */ |
|---|
| 2290 | if ( handle->tsmPermitted && handle->trickState.tsmEnabled && |
|---|
| 2291 | handle->apeStartSettings.streamType == BAVC_StreamType_eTsMpeg ) |
|---|
| 2292 | { |
|---|
| 2293 | BDBG_MSG(("%s ASTM mode for audio channel %p",handle->astm.settings.enableAstm?"Enabling":"Disabling", handle)); |
|---|
| 2294 | tsmSettings.astmEnabled = handle->astm.settings.enableAstm; |
|---|
| 2295 | } |
|---|
| 2296 | else |
|---|
| 2297 | { |
|---|
| 2298 | BDBG_MSG(("Disabling ASTM mode for audio channel %p", handle)); |
|---|
| 2299 | tsmSettings.astmEnabled = false; |
|---|
| 2300 | } |
|---|
| 2301 | #endif |
|---|
| 2302 | |
|---|
| 2303 | BAPE_Decoder_SetTsmSettings(handle->channel, &tsmSettings); |
|---|
| 2304 | |
|---|
| 2305 | handle->tsmEnabled = tsmSettings.tsmEnabled; |
|---|
| 2306 | } |
|---|
| 2307 | |
|---|
| 2308 | NEXUS_Error NEXUS_AudioDecoder_P_Start(NEXUS_AudioDecoderHandle handle) |
|---|
| 2309 | { |
|---|
| 2310 | NEXUS_Error errCode; |
|---|
| 2311 | const NEXUS_AudioDecoderStartSettings *pProgram; |
|---|
| 2312 | |
|---|
| 2313 | BDBG_ASSERT(NULL != handle); |
|---|
| 2314 | |
|---|
| 2315 | BDBG_ENTER(NEXUS_AudioDecoder_P_Start); |
|---|
| 2316 | |
|---|
| 2317 | pProgram = &handle->programSettings; |
|---|
| 2318 | |
|---|
| 2319 | if ( handle->programSettings.input || !handle->started || handle->outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[0] != NULL ) |
|---|
| 2320 | { |
|---|
| 2321 | int i; |
|---|
| 2322 | bool changed=false; |
|---|
| 2323 | NEXUS_AudioOutputList outputLists[NEXUS_AudioDecoderConnectorType_eMax]; |
|---|
| 2324 | |
|---|
| 2325 | /* Get output lists */ |
|---|
| 2326 | for ( i = 0; i < NEXUS_AudioDecoderConnectorType_eMax; i++ ) |
|---|
| 2327 | { |
|---|
| 2328 | NEXUS_AudioInput_P_GetOutputs(&handle->connectors[i], &outputLists[i], false); |
|---|
| 2329 | /* Check for changes */ |
|---|
| 2330 | if ( BKNI_Memcmp(&outputLists[i], &handle->outputLists[i], sizeof(NEXUS_AudioOutputList)) ) |
|---|
| 2331 | { |
|---|
| 2332 | BDBG_MSG(("Output change detected for connector type %d", i)); |
|---|
| 2333 | changed = true; |
|---|
| 2334 | } |
|---|
| 2335 | else |
|---|
| 2336 | { |
|---|
| 2337 | BDBG_MSG(("NO Output change detected for connector type %d (firstOld=%p, firstNew=%p)", i, outputLists[i].outputs[0], handle->outputLists[i].outputs[0])); |
|---|
| 2338 | } |
|---|
| 2339 | } |
|---|
| 2340 | |
|---|
| 2341 | /* 20111212 bandrews - the following code is concerned with stc programming priority. |
|---|
| 2342 | As such, the variable in use has been renamed to stcPriority. DecoderType is now simply |
|---|
| 2343 | a mapping combining type and index */ |
|---|
| 2344 | |
|---|
| 2345 | /* type now matches index directly */ |
|---|
| 2346 | handle->stcDecoderType = NEXUS_StcChannelDecoderType_eAudio0 + handle->index; |
|---|
| 2347 | |
|---|
| 2348 | /* Determine mode to add new outputs */ |
|---|
| 2349 | if ( outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[0] != NULL && |
|---|
| 2350 | outputLists[NEXUS_AudioDecoderConnectorType_eStereo].outputs[0] == NULL && |
|---|
| 2351 | outputLists[NEXUS_AudioDecoderConnectorType_eMultichannel].outputs[0] == NULL ) |
|---|
| 2352 | { |
|---|
| 2353 | /* Compressed output, but no stereo or multichannel. This is a passthrough channel. */ |
|---|
| 2354 | if ( handle->connectors[NEXUS_AudioDecoderConnectorType_eCompressed].format == NEXUS_AudioInputFormat_eCompressed ) |
|---|
| 2355 | { |
|---|
| 2356 | BDBG_MSG(("Decoder %d is a passthrough channel", handle->index)); |
|---|
| 2357 | } |
|---|
| 2358 | else |
|---|
| 2359 | { |
|---|
| 2360 | BDBG_MSG(("Decoder %d is a decode channel (PCM data for passthrough)", handle->index)); |
|---|
| 2361 | } |
|---|
| 2362 | |
|---|
| 2363 | handle->stcPriority = 1; |
|---|
| 2364 | } |
|---|
| 2365 | else |
|---|
| 2366 | { |
|---|
| 2367 | if ( handle->descriptorParent || handle->programSettings.secondaryDecoder ) |
|---|
| 2368 | { |
|---|
| 2369 | /* AD child or secondary decoder (MS10/MS11). This is decoder type audio2 */ |
|---|
| 2370 | handle->stcPriority = 2; |
|---|
| 2371 | } |
|---|
| 2372 | else |
|---|
| 2373 | { |
|---|
| 2374 | /* Standard decode channel. Compressed will be simul */ |
|---|
| 2375 | handle->stcPriority = 0; |
|---|
| 2376 | } |
|---|
| 2377 | /* Determine decoder mode as decode or simul based on presence of compressed outputs */ |
|---|
| 2378 | if ( outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[0] != NULL ) |
|---|
| 2379 | { |
|---|
| 2380 | /* Simul Mode */ |
|---|
| 2381 | BDBG_MSG(("Decoder %d is a simul channel", handle->index)); |
|---|
| 2382 | } |
|---|
| 2383 | else |
|---|
| 2384 | { |
|---|
| 2385 | /* Decode Mode */ |
|---|
| 2386 | BDBG_MSG(("Decoder %d is a decode channel", handle->index)); |
|---|
| 2387 | } |
|---|
| 2388 | } |
|---|
| 2389 | |
|---|
| 2390 | /* This process is slow and involves memory allocation/free. Only do it if something changed */ |
|---|
| 2391 | if ( changed ) |
|---|
| 2392 | { |
|---|
| 2393 | /* Remove all outputs */ |
|---|
| 2394 | for ( i = 0; i < NEXUS_AudioDecoderConnectorType_eMax; i++ ) |
|---|
| 2395 | { |
|---|
| 2396 | int j; |
|---|
| 2397 | |
|---|
| 2398 | handle->hdmiOutput = NULL; /* Invalidate this, it will be re-discovered when ports are added */ |
|---|
| 2399 | for ( j = 0; j < NEXUS_AUDIO_MAX_OUTPUTS; j++ ) |
|---|
| 2400 | { |
|---|
| 2401 | NEXUS_AudioOutput output = handle->outputLists[i].outputs[j]; |
|---|
| 2402 | if ( output ) |
|---|
| 2403 | { |
|---|
| 2404 | BDBG_MSG(("Removing output port %d from decoder %d", output->port, handle->index)); |
|---|
| 2405 | /* Clear this output port */ |
|---|
| 2406 | handle->outputLists[i].outputs[j] = NULL; |
|---|
| 2407 | } |
|---|
| 2408 | } |
|---|
| 2409 | } |
|---|
| 2410 | |
|---|
| 2411 | /* Now, actually attach outputs */ |
|---|
| 2412 | for ( i = 0; i < NEXUS_AUDIO_MAX_OUTPUTS; i++ ) |
|---|
| 2413 | { |
|---|
| 2414 | NEXUS_AudioOutput output = outputLists[NEXUS_AudioDecoderConnectorType_eStereo].outputs[i]; |
|---|
| 2415 | if ( NULL == output ) |
|---|
| 2416 | { |
|---|
| 2417 | break; |
|---|
| 2418 | } |
|---|
| 2419 | else |
|---|
| 2420 | { |
|---|
| 2421 | BDBG_MSG(("Adding output port %d to decoder %d (pcm) %p", output->port, handle->index, output)); |
|---|
| 2422 | handle->outputLists[NEXUS_AudioDecoderConnectorType_eStereo].outputs[i] = output; |
|---|
| 2423 | if ( output->objectType == NEXUS_AudioOutputType_eHdmi ) |
|---|
| 2424 | { |
|---|
| 2425 | handle->hdmiOutput = output; |
|---|
| 2426 | } |
|---|
| 2427 | } |
|---|
| 2428 | } |
|---|
| 2429 | |
|---|
| 2430 | for ( i = 0; i < NEXUS_AUDIO_MAX_OUTPUTS; i++ ) |
|---|
| 2431 | { |
|---|
| 2432 | NEXUS_AudioOutput output = outputLists[NEXUS_AudioDecoderConnectorType_eMultichannel].outputs[i]; |
|---|
| 2433 | if ( NULL == output ) |
|---|
| 2434 | { |
|---|
| 2435 | break; |
|---|
| 2436 | } |
|---|
| 2437 | else |
|---|
| 2438 | { |
|---|
| 2439 | BDBG_MSG(("Adding output port %d to decoder %d (multichannel)", output->port, handle->index)); |
|---|
| 2440 | handle->outputLists[NEXUS_AudioDecoderConnectorType_eMultichannel].outputs[i] = output; |
|---|
| 2441 | if ( output->objectType == NEXUS_AudioOutputType_eHdmi ) |
|---|
| 2442 | { |
|---|
| 2443 | handle->hdmiOutput = output; |
|---|
| 2444 | } |
|---|
| 2445 | } |
|---|
| 2446 | } |
|---|
| 2447 | |
|---|
| 2448 | /* Add compressed ports */ |
|---|
| 2449 | for ( i = 0; i < NEXUS_AUDIO_MAX_OUTPUTS; i++ ) |
|---|
| 2450 | { |
|---|
| 2451 | NEXUS_AudioOutput output = outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[i]; |
|---|
| 2452 | if ( NULL == output ) |
|---|
| 2453 | { |
|---|
| 2454 | break; |
|---|
| 2455 | } |
|---|
| 2456 | else |
|---|
| 2457 | { |
|---|
| 2458 | BDBG_MSG(("Adding output port %d to decoder %d (compressed) %p", output->port, handle->index, output)); |
|---|
| 2459 | handle->outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[i] = output; |
|---|
| 2460 | if ( output->objectType == NEXUS_AudioOutputType_eHdmi ) |
|---|
| 2461 | { |
|---|
| 2462 | handle->hdmiOutput = output; |
|---|
| 2463 | } |
|---|
| 2464 | } |
|---|
| 2465 | } |
|---|
| 2466 | } |
|---|
| 2467 | |
|---|
| 2468 | if ( NULL == outputLists[NEXUS_AudioDecoderConnectorType_eStereo].outputs[0] && |
|---|
| 2469 | NULL == outputLists[NEXUS_AudioDecoderConnectorType_eMultichannel].outputs[0] && |
|---|
| 2470 | NULL == outputLists[NEXUS_AudioDecoderConnectorType_eCompressed].outputs[0] ) |
|---|
| 2471 | { |
|---|
| 2472 | BDBG_ERR(("No outputs have been connected to this decoder.")); |
|---|
| 2473 | return BERR_TRACE(BERR_NOT_SUPPORTED); |
|---|
| 2474 | } |
|---|
| 2475 | |
|---|
| 2476 | /* Notify downstream objects we're about to start - should be done after outputs are connected on 7400/7401 */ |
|---|
| 2477 | /* This will trigger connections on the 7405/3563/... */ |
|---|
| 2478 | for ( i = 0; i < NEXUS_AudioDecoderConnectorType_eMax; i++ ) |
|---|
| 2479 | { |
|---|
| 2480 | /* Only call this for inputs about to actually start */ |
|---|
| 2481 | BDBG_MSG(("Preparing to start path %d", i)); |
|---|
| 2482 | |
|---|
| 2483 | errCode = NEXUS_AudioInput_P_PrepareToStart(&handle->connectors[i]); |
|---|
| 2484 | if ( errCode ) |
|---|
| 2485 | { |
|---|
| 2486 | return BERR_TRACE(errCode); |
|---|
| 2487 | } |
|---|
| 2488 | } |
|---|
| 2489 | } |
|---|
| 2490 | |
|---|
| 2491 | /* Setup StcChannel */ |
|---|
| 2492 | if ( pProgram->stcChannel ) |
|---|
| 2493 | { |
|---|
| 2494 | NEXUS_StcChannelCallbacks callbacks; |
|---|
| 2495 | |
|---|
| 2496 | LOCK_TRANSPORT(); |
|---|
| 2497 | |
|---|
| 2498 | NEXUS_StcChannel_GetDefaultCallbacks_priv(&callbacks); |
|---|
| 2499 | callbacks.getPts_isr = NEXUS_AudioDecoder_P_GetPtsCallback_isr; |
|---|
| 2500 | callbacks.getCdbLevel_isr = NEXUS_AudioDecoder_P_GetCdbLevelCallback_isr; |
|---|
| 2501 | callbacks.stcValid_isr = NEXUS_AudioDecoder_P_StcValidCallback_isr; |
|---|
| 2502 | callbacks.pDevContext = handle; |
|---|
| 2503 | if ( pProgram->nonRealTime ) |
|---|
| 2504 | { |
|---|
| 2505 | callbacks.getPcrOffset_isr = NEXUS_AudioDecoder_P_GetPcrOffset_isr; |
|---|
| 2506 | callbacks.setPcrOffset_isr = NEXUS_AudioDecoder_P_SetPcrOffset_isr; |
|---|
| 2507 | } |
|---|
| 2508 | NEXUS_StcChannel_SetCallbacks_priv(pProgram->stcChannel, handle->stcDecoderType, handle->stcPriority, &callbacks); |
|---|
| 2509 | if ( pProgram->pidChannel ) |
|---|
| 2510 | { |
|---|
| 2511 | NEXUS_StcChannel_EnablePidChannel_priv(pProgram->stcChannel, pProgram->pidChannel); |
|---|
| 2512 | handle->fifoWatchdogTimer = NEXUS_ScheduleTimer(250, NEXUS_AudioDecoder_P_FifoWatchdog, handle); |
|---|
| 2513 | } |
|---|
| 2514 | |
|---|
| 2515 | UNLOCK_TRANSPORT(); |
|---|
| 2516 | } |
|---|
| 2517 | |
|---|
| 2518 | /* After all that, we're ready to go. Start. */ |
|---|
| 2519 | handle->ptsErrorCount = 0; |
|---|
| 2520 | BDBG_MSG(("Starting Decoder %d", handle->index)); |
|---|
| 2521 | |
|---|
| 2522 | /* Re-apply settings */ |
|---|
| 2523 | NEXUS_AudioDecoder_ApplySettings_priv(handle); |
|---|
| 2524 | BDBG_MSG(("Starting with codec %u", handle->apeStartSettings.codec)); |
|---|
| 2525 | |
|---|
| 2526 | handle->locked = false; |
|---|
| 2527 | handle->numFifoOverflows = handle->numFifoUnderflows = 0; |
|---|
| 2528 | errCode = BAPE_Decoder_Start(handle->channel, &handle->apeStartSettings); |
|---|
| 2529 | if ( errCode && !handle->started ) |
|---|
| 2530 | { |
|---|
| 2531 | if ( handle->programSettings.stcChannel ) |
|---|
| 2532 | { |
|---|
| 2533 | LOCK_TRANSPORT(); |
|---|
| 2534 | if ( handle->programSettings.pidChannel ) |
|---|
| 2535 | { |
|---|
| 2536 | NEXUS_StcChannel_DisablePidChannel_priv(handle->programSettings.stcChannel, handle->programSettings.pidChannel); |
|---|
| 2537 | if ( handle->fifoWatchdogTimer ) |
|---|
| 2538 | { |
|---|
| 2539 | NEXUS_CancelTimer(handle->fifoWatchdogTimer); |
|---|
| 2540 | handle->fifoWatchdogTimer = NULL; |
|---|
| 2541 | } |
|---|
| 2542 | } |
|---|
| 2543 | NEXUS_StcChannel_ClearCallbacks_priv(handle->programSettings.stcChannel, handle->stcDecoderType); |
|---|
| 2544 | UNLOCK_TRANSPORT(); |
|---|
| 2545 | } |
|---|
| 2546 | return BERR_TRACE(errCode); |
|---|
| 2547 | } |
|---|
| 2548 | |
|---|
| 2549 | if ( handle->programSettings.pidChannel ) |
|---|
| 2550 | { |
|---|
| 2551 | LOCK_TRANSPORT(); |
|---|
| 2552 | NEXUS_Rave_Enable_priv(handle->raveContext); |
|---|
| 2553 | UNLOCK_TRANSPORT(); |
|---|
| 2554 | } |
|---|
| 2555 | handle->running = true; |
|---|
| 2556 | |
|---|
| 2557 | if ( handle->programSettings.pidChannel ) |
|---|
| 2558 | { |
|---|
| 2559 | (void)NEXUS_PidChannel_ConsumerStarted(handle->programSettings.pidChannel); |
|---|
| 2560 | } |
|---|
| 2561 | |
|---|
| 2562 | /* PR:49294 sync/astm must know that audio has been started *every* time it is started */ |
|---|
| 2563 | if (handle->syncSettings.startCallback_isr) { |
|---|
| 2564 | BKNI_EnterCriticalSection(); |
|---|
| 2565 | (*handle->syncSettings.startCallback_isr)(handle->syncSettings.callbackContext, 0); |
|---|
| 2566 | BKNI_LeaveCriticalSection(); |
|---|
| 2567 | } |
|---|
| 2568 | |
|---|
| 2569 | #if NEXUS_HAS_ASTM |
|---|
| 2570 | handle->astm.status.started = true; |
|---|
| 2571 | |
|---|
| 2572 | if (handle->astm.settings.enableAstm) |
|---|
| 2573 | { |
|---|
| 2574 | BDBG_MSG(("Audio channel %p is notifying ASTM of its start action", handle)); |
|---|
| 2575 | if (handle->astm.settings.lifecycle_isr) |
|---|
| 2576 | { |
|---|
| 2577 | BKNI_EnterCriticalSection(); |
|---|
| 2578 | (*handle->astm.settings.lifecycle_isr)(handle->astm.settings.callbackContext, 0); |
|---|
| 2579 | BKNI_LeaveCriticalSection(); |
|---|
| 2580 | } |
|---|
| 2581 | } |
|---|
| 2582 | |
|---|
| 2583 | #endif |
|---|
| 2584 | |
|---|
| 2585 | BDBG_LEAVE(NEXUS_AudioDecoder_P_Start); |
|---|
| 2586 | |
|---|
| 2587 | return BERR_SUCCESS; |
|---|
| 2588 | } |
|---|
| 2589 | |
|---|
| 2590 | NEXUS_Error NEXUS_AudioDecoder_P_Stop(NEXUS_AudioDecoderHandle handle, bool flush) |
|---|
| 2591 | { |
|---|
| 2592 | BDBG_ENTER(NEXUS_AudioDecoder_P_Stop); |
|---|
| 2593 | |
|---|
| 2594 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 2595 | |
|---|
| 2596 | if ( handle->running ) |
|---|
| 2597 | { |
|---|
| 2598 | if ( handle->fifoWatchdogTimer ) |
|---|
| 2599 | { |
|---|
| 2600 | NEXUS_CancelTimer(handle->fifoWatchdogTimer); |
|---|
| 2601 | handle->fifoWatchdogTimer = NULL; |
|---|
| 2602 | } |
|---|
| 2603 | |
|---|
| 2604 | handle->locked = false; |
|---|
| 2605 | BAPE_Decoder_Stop(handle->channel); |
|---|
| 2606 | |
|---|
| 2607 | if ( handle->programSettings.pidChannel && flush ) |
|---|
| 2608 | { |
|---|
| 2609 | LOCK_TRANSPORT(); |
|---|
| 2610 | NEXUS_Rave_Disable_priv(handle->raveContext); |
|---|
| 2611 | NEXUS_Rave_Flush_priv(handle->raveContext); |
|---|
| 2612 | UNLOCK_TRANSPORT(); |
|---|
| 2613 | } |
|---|
| 2614 | |
|---|
| 2615 | handle->running = false; |
|---|
| 2616 | |
|---|
| 2617 | if ( handle->programSettings.stcChannel && handle->stcDecoderType != NEXUS_StcChannelDecoderType_eMax ) |
|---|
| 2618 | { |
|---|
| 2619 | LOCK_TRANSPORT(); |
|---|
| 2620 | if ( handle->programSettings.pidChannel && handle->programSettings.stcChannel ) |
|---|
| 2621 | { |
|---|
| 2622 | NEXUS_StcChannel_DisablePidChannel_priv(handle->programSettings.stcChannel, handle->programSettings.pidChannel); |
|---|
| 2623 | } |
|---|
| 2624 | NEXUS_StcChannel_ClearCallbacks_priv(handle->programSettings.stcChannel, handle->stcDecoderType); |
|---|
| 2625 | UNLOCK_TRANSPORT(); |
|---|
| 2626 | } |
|---|
| 2627 | |
|---|
| 2628 | /* PR:49294 sync/astm must know that audio has been started *every* time it is started */ |
|---|
| 2629 | if (handle->syncSettings.startCallback_isr) { |
|---|
| 2630 | BKNI_EnterCriticalSection(); |
|---|
| 2631 | (*handle->syncSettings.startCallback_isr)(handle->syncSettings.callbackContext, 0); |
|---|
| 2632 | BKNI_LeaveCriticalSection(); |
|---|
| 2633 | } |
|---|
| 2634 | |
|---|
| 2635 | #if NEXUS_HAS_ASTM |
|---|
| 2636 | handle->astm.status.started = false; |
|---|
| 2637 | |
|---|
| 2638 | if (handle->astm.settings.enableAstm) |
|---|
| 2639 | { |
|---|
| 2640 | BDBG_MSG(("Audio channel %p is notifying ASTM of its stop action", handle)); |
|---|
| 2641 | if (handle->astm.settings.lifecycle_isr) |
|---|
| 2642 | { |
|---|
| 2643 | BKNI_EnterCriticalSection(); |
|---|
| 2644 | (*handle->astm.settings.lifecycle_isr)(handle->astm.settings.callbackContext, 0); |
|---|
| 2645 | BKNI_LeaveCriticalSection(); |
|---|
| 2646 | } |
|---|
| 2647 | } |
|---|
| 2648 | |
|---|
| 2649 | #endif |
|---|
| 2650 | } |
|---|
| 2651 | |
|---|
| 2652 | BDBG_LEAVE(NEXUS_AudioDecoder_P_Stop); |
|---|
| 2653 | |
|---|
| 2654 | return BERR_SUCCESS; |
|---|
| 2655 | } |
|---|
| 2656 | |
|---|
| 2657 | static BERR_Code NEXUS_AudioDecoder_P_GetPtsCallback_isr(void *pContext, BAVC_PTSInfo *pPTSInfo) |
|---|
| 2658 | { |
|---|
| 2659 | BERR_Code errCode; |
|---|
| 2660 | NEXUS_AudioDecoderHandle handle = pContext; |
|---|
| 2661 | BAPE_DecoderTsmStatus tsmStatus; |
|---|
| 2662 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 2663 | BDBG_ASSERT(NULL != pPTSInfo); |
|---|
| 2664 | errCode = BAPE_Decoder_GetTsmStatus_isr(handle->channel, &tsmStatus); |
|---|
| 2665 | if ( errCode ) |
|---|
| 2666 | { |
|---|
| 2667 | return errCode; /* BERR_TRACE intentionally omitted */ |
|---|
| 2668 | } |
|---|
| 2669 | *pPTSInfo = tsmStatus.ptsInfo; |
|---|
| 2670 | return BERR_SUCCESS; |
|---|
| 2671 | } |
|---|
| 2672 | |
|---|
| 2673 | static BERR_Code NEXUS_AudioDecoder_P_GetCdbLevelCallback_isr(void *pContext, unsigned *pCdbLevel) |
|---|
| 2674 | { |
|---|
| 2675 | unsigned depth=0, size=0; |
|---|
| 2676 | NEXUS_AudioDecoderHandle audioDecoder = (NEXUS_AudioDecoderHandle)pContext; |
|---|
| 2677 | BDBG_OBJECT_ASSERT(audioDecoder, NEXUS_AudioDecoder); |
|---|
| 2678 | if ( audioDecoder->programSettings.pidChannel ) |
|---|
| 2679 | { |
|---|
| 2680 | NEXUS_Rave_GetCdbBufferInfo_isr(audioDecoder->raveContext, &depth, &size); |
|---|
| 2681 | } |
|---|
| 2682 | BDBG_MSG(("GetCdbLevel - returned %d", depth)); |
|---|
| 2683 | *pCdbLevel = depth; |
|---|
| 2684 | return 0; |
|---|
| 2685 | } |
|---|
| 2686 | |
|---|
| 2687 | static BERR_Code NEXUS_AudioDecoder_P_StcValidCallback_isr(void *pContext) |
|---|
| 2688 | { |
|---|
| 2689 | NEXUS_AudioDecoderHandle audioDecoder = (NEXUS_AudioDecoderHandle)pContext; |
|---|
| 2690 | BDBG_OBJECT_ASSERT(audioDecoder, NEXUS_AudioDecoder); |
|---|
| 2691 | return BAPE_Decoder_SetStcValid_isr(audioDecoder->channel); |
|---|
| 2692 | } |
|---|
| 2693 | |
|---|
| 2694 | static void NEXUS_AudioDecoder_P_FifoWatchdog(void *context) |
|---|
| 2695 | { |
|---|
| 2696 | NEXUS_AudioDecoderHandle audioDecoder = context; |
|---|
| 2697 | unsigned timeout=150; |
|---|
| 2698 | |
|---|
| 2699 | audioDecoder->fifoWatchdogTimer = NULL; |
|---|
| 2700 | |
|---|
| 2701 | if (audioDecoder->programSettings.stcChannel) { |
|---|
| 2702 | uint32_t cdbValidPointer, cdbReadPointer; |
|---|
| 2703 | bool shouldFlush, isLocked; |
|---|
| 2704 | unsigned depth, size; |
|---|
| 2705 | |
|---|
| 2706 | BKNI_EnterCriticalSection(); |
|---|
| 2707 | NEXUS_Rave_GetCdbPointers_isr(audioDecoder->raveContext, &cdbValidPointer, &cdbReadPointer); |
|---|
| 2708 | NEXUS_Rave_GetCdbBufferInfo_isr(audioDecoder->raveContext, &depth, &size); |
|---|
| 2709 | BKNI_LeaveCriticalSection(); |
|---|
| 2710 | if (audioDecoder->lastCdbValidPointer == cdbValidPointer && audioDecoder->lastCdbReadPointer == cdbReadPointer) { |
|---|
| 2711 | if (audioDecoder->staticFifoCount < 20) { |
|---|
| 2712 | audioDecoder->staticFifoCount++; |
|---|
| 2713 | } |
|---|
| 2714 | } |
|---|
| 2715 | else { |
|---|
| 2716 | audioDecoder->staticFifoCount = 0; |
|---|
| 2717 | audioDecoder->lastCdbValidPointer = cdbValidPointer; |
|---|
| 2718 | audioDecoder->lastCdbReadPointer = cdbReadPointer; |
|---|
| 2719 | } |
|---|
| 2720 | |
|---|
| 2721 | isLocked = (audioDecoder->staticFifoCount > 4) && (audioDecoder->trickState.rate >= NEXUS_NORMAL_DECODE_RATE); |
|---|
| 2722 | |
|---|
| 2723 | LOCK_TRANSPORT(); |
|---|
| 2724 | NEXUS_StcChannel_ReportDecoderHang_priv(audioDecoder->programSettings.stcChannel, |
|---|
| 2725 | audioDecoder->stcDecoderType, isLocked, size?depth*100/size:0, &shouldFlush); |
|---|
| 2726 | UNLOCK_TRANSPORT(); |
|---|
| 2727 | |
|---|
| 2728 | if (shouldFlush) { |
|---|
| 2729 | NEXUS_AudioDecoder_Flush(audioDecoder); |
|---|
| 2730 | LOCK_TRANSPORT(); |
|---|
| 2731 | NEXUS_StcChannel_ReportFlush_priv(audioDecoder->programSettings.stcChannel, |
|---|
| 2732 | audioDecoder->stcDecoderType); |
|---|
| 2733 | UNLOCK_TRANSPORT(); |
|---|
| 2734 | } |
|---|
| 2735 | } |
|---|
| 2736 | |
|---|
| 2737 | audioDecoder->fifoWatchdogTimer = NEXUS_ScheduleTimer(timeout, NEXUS_AudioDecoder_P_FifoWatchdog, audioDecoder); |
|---|
| 2738 | } |
|---|
| 2739 | |
|---|
| 2740 | static void NEXUS_AudioDecoder_P_InputFormatChange_isr(void *pParam1, int param2) |
|---|
| 2741 | { |
|---|
| 2742 | NEXUS_AudioDecoderHandle handle = (NEXUS_AudioDecoderHandle)pParam1; |
|---|
| 2743 | BSTD_UNUSED(param2); |
|---|
| 2744 | /* convert to task time */ |
|---|
| 2745 | BKNI_SetEvent_isr(handle->inputFormatChangeEvent); |
|---|
| 2746 | } |
|---|
| 2747 | |
|---|
| 2748 | static void NEXUS_AudioDecoder_P_InputFormatChange(void *pParam) |
|---|
| 2749 | { |
|---|
| 2750 | NEXUS_AudioDecoderHandle handle = (NEXUS_AudioDecoderHandle)pParam; |
|---|
| 2751 | NEXUS_AudioInputPortStatus inputPortStatus; |
|---|
| 2752 | NEXUS_Error errCode; |
|---|
| 2753 | BAVC_AudioCompressionStd avcCodec; |
|---|
| 2754 | bool stop=false, start=false; |
|---|
| 2755 | |
|---|
| 2756 | errCode = NEXUS_AudioInput_P_GetInputPortStatus(handle->programSettings.input, &inputPortStatus); |
|---|
| 2757 | if ( errCode ) |
|---|
| 2758 | { |
|---|
| 2759 | (void)BERR_TRACE(errCode); |
|---|
| 2760 | return; |
|---|
| 2761 | } |
|---|
| 2762 | |
|---|
| 2763 | avcCodec = NEXUS_Audio_P_CodecToMagnum(inputPortStatus.codec); |
|---|
| 2764 | if ( handle->running ) |
|---|
| 2765 | { |
|---|
| 2766 | BDBG_MSG(("Input Format Change - Decoder is running")); |
|---|
| 2767 | if ( avcCodec == handle->apeStartSettings.codec ) |
|---|
| 2768 | { |
|---|
| 2769 | /* Nothing to do, return. */ |
|---|
| 2770 | BDBG_MSG(("Signal codec has not changed. Not restarting decoder.")); |
|---|
| 2771 | return; |
|---|
| 2772 | } |
|---|
| 2773 | else |
|---|
| 2774 | { |
|---|
| 2775 | /* Must stop if codec has changed */ |
|---|
| 2776 | stop = true; |
|---|
| 2777 | if ( inputPortStatus.signalPresent ) |
|---|
| 2778 | { |
|---|
| 2779 | /* Restart with new codec if signal is present */ |
|---|
| 2780 | start = true; |
|---|
| 2781 | BDBG_MSG(("Valid input signal with different codec, restarting decoder.")); |
|---|
| 2782 | } |
|---|
| 2783 | else |
|---|
| 2784 | { |
|---|
| 2785 | BDBG_MSG(("No valid input signal, stopping decoder.")); |
|---|
| 2786 | } |
|---|
| 2787 | } |
|---|
| 2788 | } |
|---|
| 2789 | else |
|---|
| 2790 | { |
|---|
| 2791 | BDBG_MSG(("Input Format Change - Decoder is not running")); |
|---|
| 2792 | if ( inputPortStatus.signalPresent ) |
|---|
| 2793 | { |
|---|
| 2794 | /* Start with new codec if signal is present */ |
|---|
| 2795 | BDBG_MSG(("Valid input signal, starting decoder.")); |
|---|
| 2796 | start = true; |
|---|
| 2797 | } |
|---|
| 2798 | else |
|---|
| 2799 | { |
|---|
| 2800 | BDBG_MSG(("No valid input signal, not starting decoder.")); |
|---|
| 2801 | } |
|---|
| 2802 | } |
|---|
| 2803 | |
|---|
| 2804 | if ( stop ) |
|---|
| 2805 | { |
|---|
| 2806 | BDBG_MSG(("Stop decoder on input format change")); |
|---|
| 2807 | NEXUS_AudioDecoder_P_Stop(handle, true); |
|---|
| 2808 | } |
|---|
| 2809 | handle->apeStartSettings.codec = avcCodec; |
|---|
| 2810 | if ( start ) |
|---|
| 2811 | { |
|---|
| 2812 | NEXUS_Error errCode; |
|---|
| 2813 | BDBG_MSG(("Start decoder on input format change")); |
|---|
| 2814 | errCode = NEXUS_AudioDecoder_P_Start(handle); |
|---|
| 2815 | if ( errCode ) |
|---|
| 2816 | { |
|---|
| 2817 | (void)BERR_TRACE(errCode); |
|---|
| 2818 | } |
|---|
| 2819 | } |
|---|
| 2820 | } |
|---|
| 2821 | |
|---|
| 2822 | static BERR_Code NEXUS_AudioDecoder_P_SetPcrOffset_isr(void *pContext, uint32_t pcrOffset) |
|---|
| 2823 | { |
|---|
| 2824 | NEXUS_AudioDecoderHandle handle = (NEXUS_AudioDecoderHandle)pContext; |
|---|
| 2825 | BAPE_DecoderTsmSettings tsmSettings; |
|---|
| 2826 | BERR_Code errCode; |
|---|
| 2827 | |
|---|
| 2828 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 2829 | |
|---|
| 2830 | BAPE_Decoder_GetTsmSettings_isr(handle->channel, &tsmSettings); |
|---|
| 2831 | tsmSettings.stcOffset = pcrOffset; |
|---|
| 2832 | errCode = BAPE_Decoder_SetTsmSettings_isr(handle->channel, &tsmSettings); |
|---|
| 2833 | if ( errCode ) |
|---|
| 2834 | { |
|---|
| 2835 | return BERR_TRACE(errCode); |
|---|
| 2836 | } |
|---|
| 2837 | return BERR_SUCCESS; |
|---|
| 2838 | } |
|---|
| 2839 | |
|---|
| 2840 | static BERR_Code NEXUS_AudioDecoder_P_GetPcrOffset_isr(void *pContext, uint32_t *pPcrOffset) |
|---|
| 2841 | { |
|---|
| 2842 | NEXUS_AudioDecoderHandle handle = (NEXUS_AudioDecoderHandle)pContext; |
|---|
| 2843 | BAPE_DecoderTsmSettings tsmSettings; |
|---|
| 2844 | |
|---|
| 2845 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 2846 | BDBG_ASSERT(NULL != pPcrOffset); |
|---|
| 2847 | |
|---|
| 2848 | BAPE_Decoder_GetTsmSettings_isr(handle->channel, &tsmSettings); |
|---|
| 2849 | *pPcrOffset = tsmSettings.stcOffset; |
|---|
| 2850 | return BERR_SUCCESS; |
|---|
| 2851 | } |
|---|
| 2852 | |
|---|
| 2853 | NEXUS_Error NEXUS_AudioDecoder_GetExtendedStatus( |
|---|
| 2854 | NEXUS_AudioDecoderHandle handle, |
|---|
| 2855 | NEXUS_AudioDecoderExtendedStatus *pStatus /* [out] */ |
|---|
| 2856 | ) |
|---|
| 2857 | { |
|---|
| 2858 | BERR_Code errCode = BERR_SUCCESS; |
|---|
| 2859 | |
|---|
| 2860 | BDBG_OBJECT_ASSERT(handle, NEXUS_AudioDecoder); |
|---|
| 2861 | BDBG_ASSERT(NULL != pStatus); |
|---|
| 2862 | LOCK_TRANSPORT(); |
|---|
| 2863 | if ( handle->raveContext ) |
|---|
| 2864 | { |
|---|
| 2865 | NEXUS_RaveStatus raveStatus; |
|---|
| 2866 | |
|---|
| 2867 | errCode = NEXUS_Rave_GetStatus_priv(handle->raveContext, &raveStatus); |
|---|
| 2868 | if ( errCode == BERR_SUCCESS ) |
|---|
| 2869 | { |
|---|
| 2870 | pStatus->raveIndex = raveStatus.index; |
|---|
| 2871 | } |
|---|
| 2872 | } |
|---|
| 2873 | UNLOCK_TRANSPORT(); |
|---|
| 2874 | |
|---|
| 2875 | return errCode; |
|---|
| 2876 | } |
|---|
| 2877 | |
|---|