author | Shuai Li <shuai.li@amlogic.com> | 2017-03-14 10:42:34 (GMT) |
---|---|---|
committer | Shuai Li <shuai.li@amlogic.com> | 2017-03-14 10:49:16 (GMT) |
commit | b3b173265b359f533335e8b63d6f1da6c97bc418 (patch) | |
tree | c15330d5ee07e59c292cfb696b42159429936245 | |
parent | e38bd3eb862bc738a82183fb5195512a05e2cbe6 (diff) | |
download | audio-b3b173265b359f533335e8b63d6f1da6c97bc418.zip audio-b3b173265b359f533335e8b63d6f1da6c97bc418.tar.gz audio-b3b173265b359f533335e8b63d6f1da6c97bc418.tar.bz2 |
PD#139537: audio: add pcm pause state check
- Fix AudioTrack blocked by pcm_write.
Reason is pcm in pause state and pcm_write is blocked.
Change-Id: Ib8eee84e013fd96198111a8293419b96a07e6836
Signed-off-by: Shuai Li <shuai.li@amlogic.com>
-rw-r--r-- | audio_hw.c | 18 | ||||
-rw-r--r-- | audio_hw.h | 1 |
2 files changed, 18 insertions, 1 deletions
@@ -306,7 +306,7 @@ static int start_output_stream(struct aml_stream_out *out) struct aml_audio_device *adev = out->dev; unsigned int card = CARD_AMLOGIC_BOARD; unsigned int port = PORT_I2S; - int ret; + int ret = 0; int i = 0; struct aml_stream_out *out_removed = NULL; bool hwsync_lpcm = (out->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC && out->config.rate <= 48000 && audio_is_linear_pcm(out->hal_format)); @@ -387,6 +387,13 @@ static int start_output_stream(struct aml_stream_out *out) } else { ALOGI("stream %p share the pcm %p\n", out, adev->pcm); out->pcm = adev->pcm; + // add to fix start output when pcm in pause state + if (adev->pcm_paused && pcm_is_ready(out->pcm)) { + ret = pcm_ioctl(out->pcm, SNDRV_PCM_IOCTL_PAUSE, 0); + if (ret < 0) { + ALOGE("cannot resume channel\n"); + } + } } LOGFUNC("channels=%d---format=%d---period_count%d---period_size%d---rate=%d---", out->config.channels, out->config.format, out->config.period_count, @@ -819,6 +826,7 @@ static int do_output_standby(struct aml_stream_out *out) adev->pcm = NULL; } out->pause_status = false; + adev->pcm_paused = false; } } return 0; @@ -1238,6 +1246,11 @@ static int out_pause(struct audio_stream_out *stream) ALOGE("cannot pause channel\n"); } else { r = 0; + // set the pcm pause state + if (out->pcm == adev->pcm) + adev->pcm_paused = true; + else + ALOGE("out->pcm and adev->pcm are assumed same handle"); } } exit1: @@ -1268,6 +1281,9 @@ static int out_resume(struct audio_stream_out *stream) ALOGE("cannot resume channel\n"); } else { r = 0; + // clear the pcm pause state + if (out->pcm == adev->pcm) + adev->pcm_paused = false; } } if (out->hw_sync_mode) { @@ -77,6 +77,7 @@ struct aml_audio_device { struct aml_stream_out *hwsync_output; struct aml_hal_mixer hal_mixer; struct pcm *pcm; + bool pcm_paused; unsigned hdmi_arc_ad[HDMI_ARC_MAX_FORMAT]; }; |