Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7913e574 authored by Meng Wang's avatar Meng Wang
Browse files

ALSA: compress: Add support to send codec specific data



Codec specific  metadata is sent only for first stream in gapless
playback. This causes incorrect configuration to be set for second
stream and distortions are observed due to framedrops in adsp.
Add support to send codec specific format during start of
next stream in gapless using set_next_track_param.

Change-Id: Ic0a9286c4fd8d17df63d676d6ce14cd394dea791
Signed-off-by: default avatarChaithanya Krishna Bacharaju <chaithan@codeaurora.org>
Signed-off-by: default avatarAlexy Joseph <alexyj@codeaurora.org>
Signed-off-by: default avatarBanajit Goswami <bgoswami@codeaurora.org>
Signed-off-by: default avatarMeng Wang <mengw@codeaurora.org>
parent a70116e1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -183,6 +183,10 @@ partial drain
  EOF is reached and now DSP can start skipping padding delay. Also next write
  data would belong to next track

- set_next_track_param
This routine is called to send to DSP codec specific data of subsequent track
in gapless before first write.

Sequence flow for gapless would be:
- Open
- Get caps / codec caps
+6 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ struct snd_compr_stream {
 * @get_params: retrieve the codec parameters, mandatory
 * @set_metadata: Set the metadata values for a stream
 * @get_metadata: retrieves the requested metadata values from stream
 * @set_next_track_param: send codec specific data of subsequent track
 * in gapless
 * @trigger: Trigger operations like start, pause, resume, drain, stop.
 * This callback is mandatory
 * @pointer: Retrieve current h/w pointer information. Mandatory
@@ -107,6 +109,10 @@ struct snd_compr_ops {
			struct snd_compr_metadata *metadata);
	int (*get_metadata)(struct snd_compr_stream *stream,
			struct snd_compr_metadata *metadata);
#ifdef CONFIG_AUDIO_QGKI
	int (*set_next_track_param)(struct snd_compr_stream *stream,
			union snd_codec_options *codec_options);
#endif
	int (*trigger)(struct snd_compr_stream *stream, int cmd);
	int (*pointer)(struct snd_compr_stream *stream,
			struct snd_compr_tstamp *tstamp);
+26 −0
Original line number Diff line number Diff line
@@ -901,6 +901,27 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
	return snd_compress_wait_for_drain(stream);
}

#ifdef CONFIG_AUDIO_QGKI
static int snd_compr_set_next_track_param(struct snd_compr_stream *stream,
		unsigned long arg)
{
	union snd_codec_options codec_options;
	int retval;

	/* set next track params when stream is running or has been setup */
	if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&
			stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
		return -EPERM;

	if (copy_from_user(&codec_options, (void __user *)arg,
				sizeof(codec_options)))
		return -EFAULT;

	retval = stream->ops->set_next_track_param(stream, &codec_options);
	return retval;
}
#endif

static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
	struct snd_compr_file *data = f->private_data;
@@ -965,6 +986,11 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
	case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
		retval = snd_compr_next_track(stream);
		break;
#ifdef CONFIG_AUDIO_QGKI
	case _IOC_NR(SNDRV_COMPRESS_SET_NEXT_TRACK_PARAM):
		retval = snd_compr_set_next_track_param(stream, arg);
		break;
#endif

	}
	mutex_unlock(&stream->device->lock);
+32 −0
Original line number Diff line number Diff line
@@ -755,6 +755,32 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
	return ret;
}

#ifdef CONFIG_AUDIO_QGKI
static int soc_compr_set_next_track_param(struct snd_compr_stream *cstream,
				union snd_codec_options *codec_options)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_platform *component;
	struct snd_soc_rtdcom_list *rtdcom;
	int ret = 0;

	for_each_rtdcom(rtd, rtdcom) {
		component = rtdcom->component;

		if (!component->driver->compr_ops ||
			component->driver->compr_ops->set_next_track_param)
			continue;

		ret = component->driver->compr_ops->set_next_track_param(
					cstream, codec_options);
		if (ret < 0)
			return ret;
	}

	return 0;
}
#endif

static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
				  struct snd_compr_metadata *metadata)
{
@@ -822,6 +848,9 @@ static struct snd_compr_ops soc_compr_ops = {
	.set_params	= soc_compr_set_params,
	.set_metadata   = soc_compr_set_metadata,
	.get_metadata	= soc_compr_get_metadata,
#ifdef CONFIG_AUDIO_QGKI
	.set_next_track_param	= soc_compr_set_next_track_param,
#endif
	.get_params	= soc_compr_get_params,
	.trigger	= soc_compr_trigger,
	.pointer	= soc_compr_pointer,
@@ -838,6 +867,9 @@ static struct snd_compr_ops soc_compr_dyn_ops = {
	.get_params	= soc_compr_get_params,
	.set_metadata   = soc_compr_set_metadata,
	.get_metadata	= soc_compr_get_metadata,
#ifdef CONFIG_AUDIO_QGKI
	.set_next_track_param	= soc_compr_set_next_track_param,
#endif
	.trigger	= soc_compr_trigger_fe,
	.pointer	= soc_compr_pointer,
	.ack		= soc_compr_ack,