Skip to content

Commit 99c0b6b

Browse files
singalsulgirdwood
authored andcommitted
Audio: Copier: Add error handling for audio_stream_fmt_conversion()
This patch re-arranges function audio_stream_fmt_conversion() to use switch-case for IPC4 sample types handling. Errors are returned for non-enabled formats and for illegal depth and valid values. The U8 format must be unsigned type. The normal s16/s24/s32 SOF types are allowed to be MSB integer, LSB integer, or signed integer as relaxed check. Currently topology uses LSB integer as default. The handling of MSB integer that is used in some parts of topologies is done elsewhere. The SOF_IPC_FRAME_INVALID is added as second error indicator. It avoids e.g. in IPC helper function use of uninitialized frame_fmt. The function audio_stream_fmt_conversion() is called from a large number of other functions without check for return code. But the components usually check their format and without a handler for it, will block processing with unsupported format. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent c445bbd commit 99c0b6b

3 files changed

Lines changed: 82 additions & 48 deletions

File tree

src/audio/copier/copier_host.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,28 @@ __cold int copier_host_create(struct comp_dev *dev, struct copier_data *cd,
149149
config->type = SOF_COMP_HOST;
150150
cd->gtw_type = ipc4_gtw_host;
151151

152-
audio_stream_fmt_conversion(copier_cfg->base.audio_fmt.depth,
153-
copier_cfg->base.audio_fmt.valid_bit_depth,
154-
&in_frame_fmt, &in_valid_fmt,
155-
copier_cfg->base.audio_fmt.s_type);
156-
157-
audio_stream_fmt_conversion(copier_cfg->out_fmt.depth,
158-
copier_cfg->out_fmt.valid_bit_depth,
159-
&out_frame_fmt, &out_valid_fmt,
160-
copier_cfg->out_fmt.s_type);
152+
ret = audio_stream_fmt_conversion(copier_cfg->base.audio_fmt.depth,
153+
copier_cfg->base.audio_fmt.valid_bit_depth,
154+
&in_frame_fmt, &in_valid_fmt,
155+
copier_cfg->base.audio_fmt.s_type);
156+
if (ret) {
157+
comp_err(dev, "failed with input format: depth %d, valid %d, type %d",
158+
copier_cfg->base.audio_fmt.depth,
159+
copier_cfg->base.audio_fmt.valid_bit_depth,
160+
copier_cfg->base.audio_fmt.s_type);
161+
return ret;
162+
}
163+
164+
ret = audio_stream_fmt_conversion(copier_cfg->out_fmt.depth,
165+
copier_cfg->out_fmt.valid_bit_depth,
166+
&out_frame_fmt, &out_valid_fmt,
167+
copier_cfg->out_fmt.s_type);
168+
if (ret) {
169+
comp_err(dev, "failed with output format: depth %d, valid %d, type %d",
170+
copier_cfg->out_fmt.depth, copier_cfg->out_fmt.valid_bit_depth,
171+
copier_cfg->out_fmt.s_type);
172+
return ret;
173+
}
161174

162175
memset(&ipc_host, 0, sizeof(ipc_host));
163176
ipc_host.direction = dir;

src/include/module/ipc/stream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ enum sof_ipc_frame {
2525
SOF_IPC_FRAME_S16_4LE, /* 16-bit in 32-bit container */
2626
SOF_IPC_FRAME_A_LAW,
2727
SOF_IPC_FRAME_MU_LAW,
28+
SOF_IPC_FRAME_INVALID, /* keep last */
2829
};
2930

3031
#endif /* __MODULE_IPC_STREAM_H__ */

src/include/sof/audio/audio_stream.h

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,54 +1007,74 @@ static inline void cir_buf_set_zero(void *ptr, void *buf_addr, void *buf_end, ui
10071007
memset(buf_addr, 0, tail_size);
10081008
}
10091009

1010-
static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth,
1011-
enum ipc4_bit_depth valid,
1012-
enum sof_ipc_frame *frame_fmt,
1013-
enum sof_ipc_frame *valid_fmt,
1014-
enum ipc4_sample_type type)
1010+
static inline int audio_stream_fmt_conversion(enum ipc4_bit_depth depth,
1011+
enum ipc4_bit_depth valid,
1012+
enum sof_ipc_frame *frame_fmt,
1013+
enum sof_ipc_frame *valid_fmt,
1014+
enum ipc4_sample_type type)
10151015
{
1016-
/* IPC4_DEPTH_16BIT (16) <---> SOF_IPC_FRAME_S16_LE (0)
1017-
* IPC4_DEPTH_24BIT (24) <---> SOF_IPC_FRAME_S24_4LE (1)
1018-
* IPC4_DEPTH_32BIT (32) <---> SOF_IPC_FRAME_S32_LE (2)
1019-
*/
1020-
*frame_fmt = (enum sof_ipc_frame)((depth >> 3) - 2);
1021-
*valid_fmt = (enum sof_ipc_frame)((valid >> 3) - 2);
1022-
1016+
int ret = -EINVAL;
1017+
*frame_fmt = SOF_IPC_FRAME_INVALID;
1018+
*valid_fmt = SOF_IPC_FRAME_INVALID;
1019+
1020+
switch (type) {
1021+
case IPC4_TYPE_FLOAT:
1022+
#ifdef CONFIG_FORMAT_FLOAT
1023+
if (depth == 32 && valid == 32) {
1024+
*frame_fmt = SOF_IPC_FRAME_FLOAT;
1025+
*valid_fmt = SOF_IPC_FRAME_FLOAT;
1026+
ret = 0;
1027+
}
1028+
#endif
1029+
break;
1030+
case IPC4_TYPE_MSB_INTEGER:
1031+
case IPC4_TYPE_LSB_INTEGER:
1032+
case IPC4_TYPE_SIGNED_INTEGER:
1033+
if (depth == 24 && valid == 24) {
1034+
#ifdef CONFIG_FORMAT_S24_3LE
1035+
*frame_fmt = SOF_IPC_FRAME_S24_3LE;
1036+
*valid_fmt = SOF_IPC_FRAME_S24_3LE;
1037+
ret = 0;
1038+
#endif
1039+
} else {
1040+
/* IPC4_DEPTH_16BIT (16) <---> SOF_IPC_FRAME_S16_LE (0)
1041+
* IPC4_DEPTH_24BIT (24) <---> SOF_IPC_FRAME_S24_4LE (1)
1042+
* IPC4_DEPTH_32BIT (32) <---> SOF_IPC_FRAME_S32_LE (2)
1043+
*/
1044+
*frame_fmt = (enum sof_ipc_frame)((depth >> 3) - 2);
1045+
*valid_fmt = (enum sof_ipc_frame)((valid >> 3) - 2);
1046+
ret = 0;
1047+
}
1048+
break;
1049+
case IPC4_TYPE_UNSIGNED_INTEGER:
10231050
#ifdef CONFIG_FORMAT_U8
1024-
if (depth == 8)
1025-
*frame_fmt = SOF_IPC_FRAME_U8;
1026-
1027-
if (valid == 8)
1028-
*valid_fmt = SOF_IPC_FRAME_U8;
1051+
if (depth == 8 && valid == 8) {
1052+
*frame_fmt = SOF_IPC_FRAME_U8;
1053+
*valid_fmt = SOF_IPC_FRAME_U8;
1054+
ret = 0;
1055+
}
10291056
#endif /* CONFIG_FORMAT_U8 */
1030-
1057+
break;
1058+
case IPC4_TYPE_A_LAW:
10311059
#ifdef CONFIG_FORMAT_A_LAW
1032-
if (type == IPC4_TYPE_A_LAW && depth == 8) {
1033-
*frame_fmt = SOF_IPC_FRAME_A_LAW;
1034-
*valid_fmt = SOF_IPC_FRAME_A_LAW;
1035-
}
1060+
if (depth == 8 && valid == 8) {
1061+
*frame_fmt = SOF_IPC_FRAME_A_LAW;
1062+
*valid_fmt = SOF_IPC_FRAME_A_LAW;
1063+
ret = 0;
1064+
}
10361065
#endif
1037-
1066+
break;
1067+
case IPC4_TYPE_MU_LAW:
10381068
#ifdef CONFIG_FORMAT_MU_LAW
1039-
if (type == IPC4_TYPE_MU_LAW && depth == 8) {
1040-
*frame_fmt = SOF_IPC_FRAME_MU_LAW;
1041-
*valid_fmt = SOF_IPC_FRAME_MU_LAW;
1042-
}
1043-
#endif
1044-
1045-
if (valid == 24) {
1046-
#ifdef CONFIG_FORMAT_S24_3LE
1047-
if (depth == 24) {
1048-
*frame_fmt = SOF_IPC_FRAME_S24_3LE;
1049-
*valid_fmt = SOF_IPC_FRAME_S24_3LE;
1069+
if (depth == 8 && valid == 8) {
1070+
*frame_fmt = SOF_IPC_FRAME_MU_LAW;
1071+
*valid_fmt = SOF_IPC_FRAME_MU_LAW;
1072+
ret = 0;
10501073
}
10511074
#endif
1075+
break;
10521076
}
1053-
1054-
if (type == IPC4_TYPE_FLOAT && depth == 32) {
1055-
*frame_fmt = SOF_IPC_FRAME_FLOAT;
1056-
*valid_fmt = SOF_IPC_FRAME_FLOAT;
1057-
}
1077+
return ret;
10581078
}
10591079
/** @}*/
10601080

0 commit comments

Comments
 (0)