mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
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: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org> Signed-off-by: Alexy Joseph <alexyj@codeaurora.org> Signed-off-by: Banajit Goswami <bgoswami@codeaurora.org> Signed-off-by: Meng Wang <mengw@codeaurora.org>
This commit is contained in:
parent
a70116e190
commit
7913e574a9
4 changed files with 68 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue