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
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, · 36 unmodified lines
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+17−0
@@ -29,6 +29,7 @@ struct q6apm_graph; · 28 unmodified lines
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 { · 220 unmodified lines
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+2−1
@@ -551,10 +551,11 @@ static int q6apm_dai_compr_get_caps(struct snd_soc_component *component, · 550 unmodified lines
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+3−0
@@ -354,6 +354,9 @@ int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, · 353 unmodified lines
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 }