History

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.

Alexey Klimov committed 1 year ago

Commit fc87f701 parent b07d2514 files · +49 −1Browse files

Unified · Split

4 files
  1. sound/soc/qcom/qdsp6/audioreach.c +27 −0
  2. sound/soc/qcom/qdsp6/audioreach.h +17 −0
  3. sound/soc/qcom/qdsp6/q6apm-dai.c +2 −1
  4. sound/soc/qcom/qdsp6/q6apm.c +3 −0
sound/soc/qcom/qdsp6/audioreach.c+27−0
@@ -859,6 +859,7 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr, · 858 unmodified lines
859 struct payload_media_fmt_aac_t *aac_cfg;859 struct payload_media_fmt_aac_t *aac_cfg;
860 struct payload_media_fmt_pcm *mp3_cfg;860 struct payload_media_fmt_pcm *mp3_cfg;
861 struct payload_media_fmt_flac_t *flac_cfg;861 struct payload_media_fmt_flac_t *flac_cfg;
862 struct payload_media_fmt_opus_t *opus_cfg;
862 863
863 switch (mcfg->fmt) {864 switch (mcfg->fmt) {
864 case SND_AUDIOCODEC_MP3:865 case SND_AUDIOCODEC_MP3:
@@ -901,6 +902,32 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr, · 36 unmodified lines
901 flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;902 flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;
902 flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;903 flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;
903 break;904 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;
904 default:931 default:
905 return -EINVAL;932 return -EINVAL;
906 }933 }
sound/soc/qcom/qdsp6/audioreach.h+17−0
@@ -29,6 +29,7 @@ struct q6apm_graph; · 28 unmodified lines
29#define MODULE_ID_MP3_DECODE 0x0700103B29#define MODULE_ID_MP3_DECODE 0x0700103B
30#define MODULE_ID_GAPLESS 0x0700104D30#define MODULE_ID_GAPLESS 0x0700104D
31#define MODULE_ID_DISPLAY_PORT_SINK 0x0700106931#define MODULE_ID_DISPLAY_PORT_SINK 0x07001069
32#define MODULE_ID_OPUS_DEC 0x07001174
32 33
33#define APM_CMD_GET_SPF_STATE 0x0100102134#define APM_CMD_GET_SPF_STATE 0x01001021
34#define APM_CMD_RSP_GET_SPF_STATE 0x0200100735#define APM_CMD_RSP_GET_SPF_STATE 0x02001007
@@ -255,6 +256,22 @@ struct payload_media_fmt_aac_t { · 220 unmodified lines
255 uint32_t sample_rate;256 uint32_t sample_rate;
256} __packed;257} __packed;
257 258
259#define MEDIA_FMT_ID_OPUS 0x09001039
260struct 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
258#define DATA_CMD_WR_SH_MEM_EP_EOS 0x04001002275#define DATA_CMD_WR_SH_MEM_EP_EOS 0x04001002
259#define WR_SH_MEM_EP_EOS_POLICY_LAST 1276#define WR_SH_MEM_EP_EOS_POLICY_LAST 1
260#define WR_SH_MEM_EP_EOS_POLICY_EACH 2277#define WR_SH_MEM_EP_EOS_POLICY_EACH 2
sound/soc/qcom/qdsp6/q6apm-dai.c+2−1
@@ -551,10 +551,11 @@ static int q6apm_dai_compr_get_caps(struct snd_soc_component *component, · 550 unmodified lines
551 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;551 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
552 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;552 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
553 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;553 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
554 caps->num_codecs = 3;554 caps->num_codecs = 4;
555 caps->codecs[0] = SND_AUDIOCODEC_MP3;555 caps->codecs[0] = SND_AUDIOCODEC_MP3;
556 caps->codecs[1] = SND_AUDIOCODEC_AAC;556 caps->codecs[1] = SND_AUDIOCODEC_AAC;
557 caps->codecs[2] = SND_AUDIOCODEC_FLAC;557 caps->codecs[2] = SND_AUDIOCODEC_FLAC;
558 caps->codecs[3] = SND_AUDIOCODEC_OPUS_RAW;
558 559
559 return 0;560 return 0;
560}561}
sound/soc/qcom/qdsp6/q6apm.c+3−0
@@ -354,6 +354,9 @@ int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, · 353 unmodified lines
354 case SND_AUDIOCODEC_FLAC:354 case SND_AUDIOCODEC_FLAC:
355 module_id = MODULE_ID_FLAC_DEC;355 module_id = MODULE_ID_FLAC_DEC;
356 break;356 break;
357 case SND_AUDIOCODEC_OPUS_RAW:
358 module_id = MODULE_ID_OPUS_DEC;
359 break;
357 default:360 default:
358 return -EINVAL;361 return -EINVAL;
359 }362 }