source: svn/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_custom_processing.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 18.9 KB
Line 
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: bape_custom_processing.c $
39* $brcm_Revision: Hydra_Software_Devel/3 $
40* $brcm_Date: 5/13/11 12:50p $
41*
42* API Description:
43*   API name: CustomProcessing
44*    Specific APIs related to custom audio post-processing
45*
46* Revision History:
47*
48* $brcm_Log: /magnum/portinginterface/ape/7422/bape_custom_processing.c $
49*
50* Hydra_Software_Devel/3   5/13/11 12:50p jgarrett
51* SW7422-410: Fixing coverity defect
52*
53* Hydra_Software_Devel/2   5/12/11 9:51a jgarrett
54* SW7422-410: Fixing initial setting state
55*
56* Hydra_Software_Devel/1   5/11/11 7:04p jgarrett
57* SW7422-410: Adding CustomProcessing
58*
59***************************************************************************/
60
61#include "bape.h"
62#include "bape_priv.h"
63#include "bdsp_raaga.h"
64
65BDBG_MODULE(bape_custom_processing);
66
67BDBG_OBJECT_ID(BAPE_CustomProcessing);
68
69typedef struct BAPE_CustomProcessing
70{
71    BDBG_OBJECT(BAPE_CustomProcessing)
72    BAPE_PathNode node;
73    BAPE_CustomProcessingSettings settings;
74    void *pSettings;
75    BAPE_Connector input;
76} BAPE_CustomProcessing;
77
78static BERR_Code BAPE_CustomProcessing_P_ConnectorSupported(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector);
79static BERR_Code BAPE_CustomProcessing_P_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
80static BERR_Code BAPE_CustomProcessing_P_ConfigPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
81static BERR_Code BAPE_CustomProcessing_P_ApplyDspSettings(BAPE_CustomProcessingHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId);
82static void BAPE_CustomProcessing_P_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection);
83static void BAPE_CustomProcessing_P_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector);
84
85void BAPE_CustomProcessing_GetDefaultSettings(
86    BAPE_CustomProcessingSettings *pSettings   /* [out] default settings */
87    )
88{
89    BDBG_ASSERT(NULL != pSettings);
90    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
91    pSettings->algorithm = BDSP_AudioProcessing_eMax;
92    pSettings->outputFormat = BAPE_MultichannelFormat_e2_0;
93}
94
95BERR_Code BAPE_CustomProcessing_Create(
96    BAPE_Handle deviceHandle,
97    const BAPE_CustomProcessingSettings *pSettings,
98    BAPE_CustomProcessingHandle *pHandle
99    )
100{
101    BAPE_CustomProcessingHandle handle;
102    BERR_Code errCode;
103
104    BDBG_OBJECT_ASSERT(deviceHandle, BAPE_Device);
105    BDBG_ASSERT(NULL != pSettings);
106    BDBG_ASSERT(NULL != pHandle);
107
108    handle = BKNI_Malloc(sizeof(BAPE_CustomProcessing));
109    if ( NULL == handle )
110    {
111        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
112    }
113    BKNI_Memset(handle, 0, sizeof(BAPE_CustomProcessing));
114    BDBG_OBJECT_SET(handle, BAPE_CustomProcessing);   
115    BAPE_P_InitPathNode(&handle->node, BAPE_PathNodeType_ePostProcessor, BAPE_PostProcessorType_eCustom, 1, deviceHandle, handle);
116    handle->node.pName = "CustomProcessing";
117    handle->node.paths[0].connector.numChannelPairs = 1; /* Only output stereo */
118    handle->node.paths[0].connector.useBufferPool = true;   
119    handle->node.paths[0].connector.dataSource = BAPE_DataSource_eDspBuffer;   
120
121    /* Generic Routines */
122    handle->node.allocatePathToOutput = BAPE_DSP_P_AllocatePathToOutput;
123    handle->node.configPathToOutput = BAPE_DSP_P_ConfigPathToOutput;
124    handle->node.stopPathToOutput = BAPE_DSP_P_StopPathToOutput;
125    handle->node.startPathToOutput = BAPE_DSP_P_StartPathToOutput;
126    handle->node.stopPathToOutput = BAPE_DSP_P_StopPathToOutput;
127
128    /* CustomProcessing Specifics */
129    handle->node.connectorSupported = BAPE_CustomProcessing_P_ConnectorSupported;
130    handle->node.allocatePathFromInput = BAPE_CustomProcessing_P_AllocatePathFromInput;
131    handle->node.configPathFromInput = BAPE_CustomProcessing_P_ConfigPathFromInput;
132    handle->node.stopPathFromInput = BAPE_CustomProcessing_P_StopPathFromInput;
133    handle->node.removeInput = BAPE_CustomProcessing_P_RemoveInputCallback;
134
135    /* Apply Settings */
136    errCode = BAPE_CustomProcessing_SetSettings(handle, pSettings);
137    if ( errCode )
138    {
139        BDBG_OBJECT_DESTROY(handle, BAPE_CustomProcessing);
140        BKNI_Free(handle);
141        return BERR_TRACE(errCode);
142    }
143
144    *pHandle = handle;
145    return BERR_SUCCESS;
146}
147
148
149void BAPE_CustomProcessing_Destroy(
150    BAPE_CustomProcessingHandle handle
151    )
152{
153    bool running;
154    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
155    running = (handle->node.paths[0].connector.task != NULL)?true:false;
156    BDBG_ASSERT(false == running);
157    BDBG_ASSERT(NULL == handle->input);
158    if ( handle->pSettings )
159    {
160        BKNI_Free(handle->pSettings);
161        handle->pSettings = NULL;
162    }
163    BDBG_OBJECT_DESTROY(handle, BAPE_CustomProcessing);
164    BKNI_Free(handle);
165}
166
167void BAPE_CustomProcessing_GetSettings(
168    BAPE_CustomProcessingHandle handle,
169    BAPE_CustomProcessingSettings *pSettings    /* [out] Settings */
170    )
171{
172    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
173    BDBG_ASSERT(NULL != pSettings);
174    *pSettings = handle->settings;
175}
176
177
178BERR_Code BAPE_CustomProcessing_SetSettings(
179    BAPE_CustomProcessingHandle handle,
180    const BAPE_CustomProcessingSettings *pSettings
181    )
182{
183    BERR_Code errCode;
184    bool running;
185    bool algoChanged;
186    bool formatChanged;
187    unsigned channelPairs;
188    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
189    BDBG_ASSERT(NULL != pSettings);
190
191    /* Check if we are running */
192    running = (handle->node.paths[0].connector.task == NULL) ? false : true;
193    /* Check if the algorithm is changing */
194    algoChanged = (pSettings->algorithm == handle->settings.algorithm) ? false : true;
195
196    switch ( pSettings->outputFormat )
197    {
198    case BAPE_MultichannelFormat_e2_0:
199        channelPairs = 1;
200        break;
201    case BAPE_MultichannelFormat_e5_1:
202        channelPairs = 3;
203        break;
204    case BAPE_MultichannelFormat_e7_1:
205        channelPairs = 4;
206        break;
207    default:
208        BDBG_ERR(("Invalid multichannel format"));
209        return BERR_TRACE(BERR_INVALID_PARAMETER);
210    }
211
212    /* Check if format changed */
213    formatChanged = (handle->node.paths[0].connector.numChannelPairs == channelPairs) ? false : true;
214
215    /* Only allow some changes if we are stopped */
216    if ( running )
217    {
218        if ( algoChanged )
219        {
220            BDBG_ERR(("Can not change custom processing algorithm while running."));
221            return BERR_TRACE(BERR_NOT_SUPPORTED);
222        }
223        if ( formatChanged )
224        {
225            BDBG_ERR(("Can not change output format while running."));
226            return BERR_TRACE(BERR_NOT_SUPPORTED);
227        }
228    }
229 
230    if ( formatChanged )
231    {
232        /* Propagate format change first */
233        handle->node.paths[0].connector.numChannelPairs = channelPairs;
234        errCode = BAPE_Connector_P_FormatChange(&handle->node.paths[0].connector);
235        if ( errCode )
236        {
237            return BERR_TRACE(errCode);
238        }
239    }
240
241    /* Check if algorithm changed */
242    if ( algoChanged )
243    {
244        /* Check if this algorithm is supported */
245        if ( !BDSP_Raaga_IsAudioProcessingSupported(pSettings->algorithm) )
246        {
247            BDBG_ERR(("Audio processing algorithm %u is not supported", pSettings->algorithm));
248            return BERR_TRACE(BERR_NOT_SUPPORTED);
249        }
250
251        /* Release old settings buffer if needed */
252        if ( handle->pSettings )
253        {
254            BKNI_Free(handle->pSettings);
255            handle->pSettings = NULL;
256        }
257
258        /* Alloc new settings buffer */
259        if ( pSettings->algorithmSettingsSize > 0 )
260        {
261            handle->pSettings = BKNI_Malloc(pSettings->algorithmSettingsSize);
262            if ( NULL == handle->pSettings )
263            {
264                return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
265            }
266
267            /* Retrieve defaults for this algorithm into our buffer */
268            errCode = BDSP_Raaga_GetDefaultAudioProcessingSettings(pSettings->algorithm, handle->pSettings, pSettings->algorithmSettingsSize);
269            if ( errCode )
270            {
271                return BERR_TRACE(BERR_INVALID_PARAMETER);
272            }
273        }
274    }
275
276    /* Save settings */
277    BKNI_Memcpy(&handle->settings, pSettings, sizeof(BAPE_CustomProcessingSettings));
278
279    return BERR_SUCCESS;
280}
281
282void BAPE_CustomProcessing_GetAlgorithmSettings(
283    BAPE_CustomProcessingHandle handle,
284    void *pSettings,        /* [out] Should be defined as the correct data type for this custom algorithm */
285    size_t settingsSize     /* Size of the settings structure in bytes */
286    )
287{
288    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
289    BDBG_ASSERT(NULL != pSettings);
290    BDBG_ASSERT(settingsSize > 0);
291    BDBG_ASSERT(settingsSize <= handle->settings.algorithmSettingsSize);
292    if ( NULL != handle->pSettings )
293    {
294        BKNI_Memcpy(pSettings, handle->pSettings, settingsSize);
295    }
296    else
297    {
298        BKNI_Memset(pSettings, 0, settingsSize);
299    }
300}
301
302BERR_Code BAPE_CustomProcessing_SetAlgorithmSettings(
303    BAPE_CustomProcessingHandle handle,
304    const void *pSettings,  /* Should be defined as the correct data type for this custom algorithm */
305    size_t settingsSize     /* Size of the settings structure in bytes */
306    )
307{
308    BERR_Code errCode;
309    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
310    BDBG_ASSERT(NULL != pSettings);
311    BDBG_ASSERT(settingsSize > 0);
312    if ( settingsSize > handle->settings.algorithmSettingsSize )
313    {
314        BDBG_ERR(("Custom algorithm size is greater than specified in BAPE_CustomProcessingSettings.algorithmSettingsSize"));
315        return BERR_TRACE(BERR_INVALID_PARAMETER);
316    }
317    if ( NULL != handle->pSettings )
318    {
319        BKNI_Memcpy(handle->pSettings, pSettings, settingsSize);
320    }
321    if ( handle->node.paths[0].connector.task != NULL )
322    {
323        errCode = BAPE_CustomProcessing_P_ApplyDspSettings(handle, 
324                                                           handle->node.paths[0].connector.task, 
325                                                           handle->node.paths[0].connector.branchId, 
326                                                           handle->node.paths[0].connector.stageId);
327        if ( errCode )
328        {
329            return BERR_TRACE(errCode);
330        }
331    }
332
333    return BERR_SUCCESS;
334}
335
336void BAPE_CustomProcessing_GetConnector(
337    BAPE_CustomProcessingHandle handle,
338    BAPE_Connector *pConnector
339    )
340{
341    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
342    BDBG_ASSERT(NULL != pConnector);
343    *pConnector = &handle->node.paths[0].connector;
344}
345
346
347BERR_Code BAPE_CustomProcessing_AddInput(
348    BAPE_CustomProcessingHandle handle,
349    BAPE_Connector input
350    )
351{
352    BERR_Code errCode;
353    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
354    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
355    if ( NULL != handle->input )
356    {
357        BDBG_ERR(("Can not have more than one input"));
358        return BERR_TRACE(BERR_NOT_SUPPORTED);
359    }
360    errCode = BAPE_PathNode_P_AddInput(&handle->node, input);
361    if ( errCode )
362    {
363        return BERR_TRACE(errCode);
364    }
365    handle->input = input;
366    return BERR_SUCCESS;
367}
368
369BERR_Code BAPE_CustomProcessing_RemoveInput(
370    BAPE_CustomProcessingHandle handle,
371    BAPE_Connector input
372    )
373{
374    BERR_Code errCode;
375    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
376    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
377    if ( input != handle->input )
378    {
379        BDBG_ERR(("Input %s %s (%#x) is not connected", input->pParent->pName, input->pName, input));
380        return BERR_TRACE(BERR_INVALID_PARAMETER);
381    }
382    errCode = BAPE_PathNode_P_RemoveInput(&handle->node, input);
383    if ( errCode )
384    {
385        return BERR_TRACE(errCode);
386    }
387    handle->input = NULL;
388    return BERR_SUCCESS;
389}
390
391BERR_Code BAPE_CustomProcessing_RemoveAllInputs(
392    BAPE_CustomProcessingHandle handle
393    )
394{
395    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
396    if ( handle->input )
397    {
398        return BAPE_CustomProcessing_RemoveInput(handle, handle->input);
399    }
400    return BERR_SUCCESS;
401}
402
403BERR_Code BAPE_CustomProcessing_GetAlgorithmStatus(
404    BAPE_CustomProcessingHandle handle,
405    void *pStatus,      /* [out] Should be defined as the correct data type for this custom algorithm */
406    size_t statusSize   /* Size of the status structure in bytes */
407    )
408{
409    BERR_Code errCode;
410    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
411    BDBG_ASSERT(NULL != pStatus);
412    BDBG_ASSERT(statusSize > 0);
413    if ( NULL != handle->node.paths[0].connector.task )
414    {
415        errCode = BDSP_Task_GetStageStatus(handle->node.paths[0].connector.task, 
416                                           handle->node.paths[0].connector.branchId,
417                                           handle->node.paths[0].connector.stageId,
418                                           pStatus,
419                                           statusSize);
420        if ( errCode )
421        {
422            return BERR_TRACE(errCode);
423        }
424    }
425    else
426    {
427        BDBG_ERR(("Processing Status not available while stopped."));
428        return BERR_TRACE(BERR_NOT_SUPPORTED);
429    }
430
431    return BERR_SUCCESS;
432}
433
434
435static BERR_Code BAPE_CustomProcessing_P_ConnectorSupported(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector)
436{
437    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
438    BDBG_OBJECT_ASSERT(pConnector, BAPE_PathConnector);
439    if ( pConnector->dataSource == BAPE_DataSource_eDspBuffer &&
440         !pConnector->compressed )
441    {
442        return BERR_SUCCESS;
443    }
444    else
445    {
446        BDBG_ERR(("Only PCM DSP input is supported"));
447        return BERR_TRACE(BERR_INVALID_PARAMETER);
448    }
449}
450
451static BERR_Code BAPE_CustomProcessing_P_AllocatePathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
452{
453    BERR_Code errCode;
454    BAPE_CustomProcessingHandle handle;
455    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
456    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
457    BDBG_ASSERT(NULL != pConnection->pSource->pTaskCreateSettings);
458    handle = pNode->pHandle;
459    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
460    /* Add stage to CIT and propagate task settings */
461    errCode = BAPE_DSP_P_AddProcessingStage(pConnection->pSource->pTaskCreateSettings, pConnection->pSource->branchId, pConnection->pSource->stageId, 
462                                            BAPE_DSP_P_GetDataTypeFromConnector(handle->input), 
463                                            handle->settings.algorithm,
464                                            false,
465                                            &pNode->paths[0].connector.branchId, &pNode->paths[0].connector.stageId);
466    if ( errCode )
467    {
468        return BERR_TRACE(errCode);
469    }
470    pNode->paths[0].connector.pTaskCreateSettings = pConnection->pSource->pTaskCreateSettings;
471    return BERR_SUCCESS;
472}
473
474static BERR_Code BAPE_CustomProcessing_P_ConfigPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
475{
476    BERR_Code errCode;
477    BAPE_CustomProcessingHandle handle;
478    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
479    BDBG_OBJECT_ASSERT(pConnection, BAPE_PathConnection);
480    BDBG_ASSERT(NULL != pConnection->pSource->task);
481
482    handle = pNode->pHandle;
483    BDBG_OBJECT_ASSERT(handle, BAPE_CustomProcessing);
484    pNode->paths[0].connector.task = pConnection->pSource->task;
485    errCode = BAPE_CustomProcessing_P_ApplyDspSettings(handle, 
486                                                       handle->node.paths[0].connector.task, 
487                                                       handle->node.paths[0].connector.branchId, 
488                                                       handle->node.paths[0].connector.stageId);
489    if ( errCode )
490    {
491        return BERR_TRACE(errCode);
492    }
493
494    return BERR_SUCCESS;   
495}
496
497static BERR_Code BAPE_CustomProcessing_P_ApplyDspSettings(BAPE_CustomProcessingHandle handle, BDSP_TaskHandle task, unsigned branchId, unsigned stageId)
498{
499    BERR_Code errCode;
500
501    if ( NULL == handle->pSettings )
502    {
503        /* NULL means just use the defaults */
504        return BERR_SUCCESS;
505    }
506
507    errCode = BDSP_Task_SetStageSettings(task, branchId, stageId, handle->pSettings, handle->settings.algorithmSettingsSize);
508    if ( errCode )
509    {
510        return BERR_TRACE(errCode);
511    }
512
513    return BERR_SUCCESS;
514}
515
516static void BAPE_CustomProcessing_P_StopPathFromInput(struct BAPE_PathNode *pNode, struct BAPE_PathConnection *pConnection)
517{
518    /* Invalidate task handle */
519    BDBG_OBJECT_ASSERT(pNode, BAPE_PathNode);
520    BSTD_UNUSED(pConnection);
521    pNode->paths[0].connector.task = NULL;
522}
523
524static void BAPE_CustomProcessing_P_RemoveInputCallback(struct BAPE_PathNode *pNode, BAPE_PathConnector *pConnector)
525{
526    (void)BAPE_CustomProcessing_RemoveInput(pNode->pHandle, pConnector);
527}
528
Note: See TracBrowser for help on using the repository browser.