QCC5125/QCC5144----LDAC 44.1K 48K 96K 192K 输出
而且还不需要license限制
/*******************************************************************************
Copyright 2019-2021 Sony Corporation
$Id: ldac_decode.c 490 2021-01-18 07:13:17Z $
*******************************************************************************/
#include "capabilities.h"
#include "ldac_decode.h"
#include "ldac_dec_priv_lib.h"
#include "ldac_buffer_control.h"
#include "platform/pl_assert.h"
#include "a2dp_decode/a2dp_common_decode.h"
#include "op_msg_helpers.h"
#include "patch/patch.h"
#include "ldac_decode_struct.h"
/****************************************************************************
Private Constant Definitions
*/
/****************************************************************************
Private Type Definitions
*/
typedef struct
{
/** A2DP_DECODER_PARAMS must be the first parameters always */
A2DP_DECODER_PARAMS decoder_data;
/** The ldac_codec specific data */
LDAC_DEC_PARAMS codec_data;
/** Timer ID used to kick operator to ensure data keeps flowing */
tTimerId self_kick_timer;
} LDAC_DEC_OP_DATA;
/****************************************************************************
Private Constant Declarations
*/
#define LDAC_DECODE_PRIVATE_ID 0xC002 /* CHANGE THIS VALUE TO THAT SELECTED */
/** The stub capability function handler table */
const handler_lookup_struct ldac_decode_handler_table =
{
ldac_decode_create, /* OPCMD_CREATE */
ldac_decode_destroy, /* OPCMD_DESTROY */
ldac_decode_start, /* OPCMD_START */
base_op_stop, /* OPCMD_STOP */
ldac_decode_reset, /* OPCMD_RESET */
ldac_decode_connect, /* OPCMD_CONNECT */
a2dp_decode_disconnect, /* OPCMD_DISCONNECT */
ldac_decode_buffer_details, /* OPCMD_BUFFER_DETAILS */
a2dp_decode_get_data_format, /* OPCMD_DATA_FORMAT */
a2dp_decode_get_sched_info /* OPCMD_GET_SCHED_INFO */
};
/** ldac decode capability data */
const opmsg_handler_lookup_table_entry ldac_decode_opmsg_obpm_handler_table[] =
{
{OPMSG_COMMON_ID_GET_CAPABILITY_VERSION, base_op_opmsg_get_capability_version},
{OPMSG_COMMON_ID_FADEOUT_ENABLE, a2dp_dec_opmsg_enable_fadeout},
{OPMSG_COMMON_ID_FADEOUT_DISABLE, a2dp_dec_opmsg_disable_fadeout},
{OPMSG_SET_CTRL, a2dp_dec_assign_buffering},
{OPMSG_COMMON_ID_SET_CONTROL, ldac_dec_opmsg_obpm_set_control},
{OPMSG_COMMON_ID_GET_PARAMS, ldac_dec_opmsg_obpm_get_params},
{OPMSG_COMMON_ID_GET_DEFAULTS, ldac_dec_opmsg_obpm_get_defaults},
{OPMSG_COMMON_ID_SET_PARAMS, ldac_dec_opmsg_obpm_set_params},
{OPMSG_COMMON_ID_GET_STATUS, ldac_dec_opmsg_obpm_get_status},
{0, NULL}
};
const CAPABILITY_DATA ldac_decode_cap_data =
{
LDAC_DECODE_PRIVATE_ID,
LDAC_DECODE_VERSION_MAJOR, 1, /* Version information - hi and lo parts */
1, 2, /* Max 1 sink and 2 sources */
&ldac_decode_handler_table,
ldac_decode_opmsg_obpm_handler_table,
ldac_decode_process_data, /* Data processing function */
0, /* TODO: this would hold processing time information */
sizeof(LDAC_DEC_OP_DATA)
};
/***************************************************************************
Private Function Declarations
*/
/**
* \brief timer handler to allow internal self-kick
* This prevents a stall when buffers fill up
*
* \param timer_data Pointer to the operator instance data.
*/
void ldac_decode_timer_task(void *timer_data)
{
OPERATOR_DATA *op_data = (OPERATOR_DATA*) timer_data;
LDAC_DEC_OP_DATA *ldac_dec_op_data = (LDAC_DEC_OP_DATA *)(op_data->extra_op_data);
ldac_dec_op_data->self_kick_timer = TIMER_ID_INVALID;
/* Raise a bg int to process */
opmgr_kick_operator(op_data);
}
/**
* \brief Frees up any data that has been allocated by the instance of the
* ldac_decode capability.
*
* \param op_data Pointer to the operator instance data.
*/
static void free_data(OPERATOR_DATA *op_data)
{
LDAC_DEC_OP_DATA *ldac_data = (LDAC_DEC_OP_DATA *)op_data->extra_op_data;
/* This can be called when create fails or on destroy so it checks that
* every allocation has happened before calling free. */
/* The variables aren't reset to NULL as this is either a failed create or
* a destroy which means the operator data is about to be freed.
*/
/* free the shared codec data */
mem_table_free((void *)(ldac_data->codec_data.hData),ldac_malloc_table3, LDAC_TABLE_LENGTH);
/* free non-shared memory */
mem_table_free((void *)(&(ldac_data->codec_data)), ldac_dec_malloc_table,
LDAC_DEC_MALLOC_TABLE_LENGTH);
}
/**
* \brief Frees up any data that has been allocated by the instnace of the
* ldac_decode capability and sets the response field to failed.
*
* \param op_data Pointer to the operator instance data.
* \param response Pointer to the response message to give a failed status
*/
static void free_data_and_fail(OPERATOR_DATA *op_data, void **response)
{
/* Free the data and then override the response message status to fail */
LDAC_DEC_OP_DATA *ldac_dec_op_data = (LDAC_DEC_OP_DATA *)(op_data->extra_op_data);
if( ldac_dec_op_data->codec_data.cb_stream != NULL )
cbuffer_destroy(ldac_dec_op_data->codec_data.cb_stream);
if( ldac_dec_op_data->codec_data.RxBuf.carried != NULL )
cbuffer_destroy(ldac_dec_op_data->codec_data.RxBuf.carried);
if( ldac_dec_op_data->codec_data.RxBuf.main != NULL )
cbuffer_destroy(ldac_dec_op_data->codec_data.RxBuf.main);
if( ldac_dec_op_data->codec_data.RxBuf.clone != NULL )
cbuffer_destroy_struct(ldac_dec_op_data->codec_data.RxBuf.clone);
#ifdef ENABLE_BUFFER_CONTROL
bc_mem_destroy(&ldac_dec_op_data->codec_data.hBufCtrl);
#endif
free_data(op_data);
base_op_change_response_status(response, STATUS_CMD_FAILED);
}
/**
* \brief Allocates the ldac_decode specific capability memory and initialises
* the decoder.
*
* \param op_data Pointer to the operator instance data.
* \param message_data Pointer to the create request message
* \param response_id Location to write the response message id
* \param response_data Location to write a pointer to the response message
*
* \return Whether the response_data field has been populated with a valid
* response
*/
bool ldac_decode_create(OPERATOR_DATA *op_data, void *message_data,
unsigned *response_id, void **response_data)
{
LDAC_DEC_OP_DATA *ldac_data = (LDAC_DEC_OP_DA