-
Notifications
You must be signed in to change notification settings - Fork 140
[RFC]: Add support for drain operation on compress streams #3808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -898,6 +898,35 @@ static void ipc3_xrun(struct snd_sof_dev *sdev, u32 msg_id) | |
| #endif | ||
| } | ||
|
|
||
| static void ipc3_drain(struct snd_sof_dev *sdev, u32 msg_id) | ||
| { | ||
| struct snd_soc_component *scomp = sdev->component; | ||
| struct snd_sof_pcm *spcm; | ||
| struct snd_sof_pcm_stream *stream; | ||
| struct sof_ipc_stream_drain drain; | ||
| int direction; | ||
|
|
||
| spcm = snd_sof_find_spcm_comp(scomp, msg_id, &direction); | ||
| if (!spcm) { | ||
| dev_err(sdev->dev, | ||
| "error: drain for unknown stream, msg_id %d\n", | ||
| msg_id); | ||
| return; | ||
| } | ||
|
|
||
| stream = &spcm->stream[direction]; | ||
| snd_sof_ipc_msg_data(sdev, stream->substream, &drain, sizeof(drain)); | ||
|
|
||
| /* since struct sof_ipc_stream drain only contains the reply | ||
| * header there's no need for additional checks. | ||
| * | ||
| * we're assuming that since we're receiving the drain-related | ||
| * reply then the drain operation finished successfully. | ||
| */ | ||
| if (spcm->pcm.compress) | ||
| snd_compr_drain_notify(stream->cstream); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And what happens when the drain is finished? Don't we need a TRIGGER_STOP or something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drain can be possible without stop if there are somehow two consecutive streams being fed, you do a partial drain for the first stream before starting the next one (useful for gapless playback I guess? Not 100% sure). I'd guess stop should wait until a drain finishes though. |
||
| } | ||
|
|
||
| /* stream notifications from firmware */ | ||
| static void ipc3_stream_message(struct snd_sof_dev *sdev, void *msg_buf) | ||
| { | ||
|
|
@@ -912,6 +941,9 @@ static void ipc3_stream_message(struct snd_sof_dev *sdev, void *msg_buf) | |
| case SOF_IPC_STREAM_TRIG_XRUN: | ||
| ipc3_xrun(sdev, msg_id); | ||
| break; | ||
| case SOF_IPC_STREAM_TRIG_DRAIN: | ||
| ipc3_drain(sdev, msg_id); | ||
| break; | ||
| default: | ||
| dev_err(sdev->dev, "unhandled stream message %#x\n", | ||
| msg_id); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you probably need a different behavior for capture and playback.
From the alsa-lib PCM documentation https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#ga49afc5b8527f30c33fafa476533c9f86
"
For playback wait for all pending frames to be played and then stop the PCM. For capture stop PCM permitting to retrieve residual frames.
"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, most likely so