Skip to content

Commit fc87f70

Browse files
laklimovtiwai
authored andcommitted
ASoC: qcom: qdsp6/audioreach: add support for offloading raw opus playback
Add support for OPUS module, OPUS format ID, media format payload struct and make it all recognizable by audioreach compress playback path. At this moment this only supports raw or plain OPUS packets not encapsulated in container (for instance OGG container). For this usecase each OPUS packet needs to be prepended with 4-bytes long length field which is expected to be done by userspace applications. This is Qualcomm DSP specific requirement. Cc: Annemarie Porter <annemari@quicinc.com> Cc: Vinod Koul <vkoul@kernel.org> Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org> Acked-by: Mark Brown <broonie@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent b07d251 commit fc87f70

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

sound/soc/qcom/qdsp6/audioreach.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
859859
struct payload_media_fmt_aac_t *aac_cfg;
860860
struct payload_media_fmt_pcm *mp3_cfg;
861861
struct payload_media_fmt_flac_t *flac_cfg;
862+
struct payload_media_fmt_opus_t *opus_cfg;
862863

863864
switch (mcfg->fmt) {
864865
case SND_AUDIOCODEC_MP3:
@@ -901,6 +902,32 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
901902
flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;
902903
flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;
903904
break;
905+
case SND_AUDIOCODEC_OPUS_RAW:
906+
media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
907+
media_fmt_hdr->fmt_id = MEDIA_FMT_ID_OPUS;
908+
media_fmt_hdr->payload_size = sizeof(*opus_cfg);
909+
p = p + sizeof(*media_fmt_hdr);
910+
opus_cfg = p;
911+
/* raw opus packets prepended with 4 bytes of length */
912+
opus_cfg->bitstream_format = 1;
913+
/*
914+
* payload_type:
915+
* 0 -- read metadata from opus stream;
916+
* 1 -- metadata is provided by filling in the struct here.
917+
*/
918+
opus_cfg->payload_type = 1;
919+
opus_cfg->version = mcfg->codec.options.opus_d.version;
920+
opus_cfg->num_channels = mcfg->codec.options.opus_d.num_channels;
921+
opus_cfg->pre_skip = mcfg->codec.options.opus_d.pre_skip;
922+
opus_cfg->sample_rate = mcfg->codec.options.opus_d.sample_rate;
923+
opus_cfg->output_gain = mcfg->codec.options.opus_d.output_gain;
924+
opus_cfg->mapping_family = mcfg->codec.options.opus_d.mapping_family;
925+
opus_cfg->stream_count = mcfg->codec.options.opus_d.chan_map.stream_count;
926+
opus_cfg->coupled_count = mcfg->codec.options.opus_d.chan_map.coupled_count;
927+
memcpy(opus_cfg->channel_mapping, mcfg->codec.options.opus_d.chan_map.channel_map,
928+
sizeof(opus_cfg->channel_mapping));
929+
opus_cfg->reserved[0] = opus_cfg->reserved[1] = opus_cfg->reserved[2] = 0;
930+
break;
904931
default:
905932
return -EINVAL;
906933
}

sound/soc/qcom/qdsp6/audioreach.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct q6apm_graph;
2929
#define MODULE_ID_MP3_DECODE 0x0700103B
3030
#define MODULE_ID_GAPLESS 0x0700104D
3131
#define MODULE_ID_DISPLAY_PORT_SINK 0x07001069
32+
#define MODULE_ID_OPUS_DEC 0x07001174
3233

3334
#define APM_CMD_GET_SPF_STATE 0x01001021
3435
#define APM_CMD_RSP_GET_SPF_STATE 0x02001007
@@ -255,6 +256,22 @@ struct payload_media_fmt_aac_t {
255256
uint32_t sample_rate;
256257
} __packed;
257258

259+
#define MEDIA_FMT_ID_OPUS 0x09001039
260+
struct payload_media_fmt_opus_t {
261+
uint16_t bitstream_format;
262+
uint16_t payload_type;
263+
uint8_t version;
264+
uint8_t num_channels;
265+
uint16_t pre_skip;
266+
uint32_t sample_rate;
267+
uint16_t output_gain;
268+
uint8_t mapping_family;
269+
uint8_t stream_count;
270+
uint8_t coupled_count;
271+
uint8_t channel_mapping[8];
272+
uint8_t reserved[3];
273+
} __packed;
274+
258275
#define DATA_CMD_WR_SH_MEM_EP_EOS 0x04001002
259276
#define WR_SH_MEM_EP_EOS_POLICY_LAST 1
260277
#define WR_SH_MEM_EP_EOS_POLICY_EACH 2

sound/soc/qcom/qdsp6/q6apm-dai.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,11 @@ static int q6apm_dai_compr_get_caps(struct snd_soc_component *component,
551551
caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
552552
caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
553553
caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
554-
caps->num_codecs = 3;
554+
caps->num_codecs = 4;
555555
caps->codecs[0] = SND_AUDIOCODEC_MP3;
556556
caps->codecs[1] = SND_AUDIOCODEC_AAC;
557557
caps->codecs[2] = SND_AUDIOCODEC_FLAC;
558+
caps->codecs[3] = SND_AUDIOCODEC_OPUS_RAW;
558559

559560
return 0;
560561
}

sound/soc/qcom/qdsp6/q6apm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph,
354354
case SND_AUDIOCODEC_FLAC:
355355
module_id = MODULE_ID_FLAC_DEC;
356356
break;
357+
case SND_AUDIOCODEC_OPUS_RAW:
358+
module_id = MODULE_ID_OPUS_DEC;
359+
break;
357360
default:
358361
return -EINVAL;
359362
}

0 commit comments

Comments
 (0)