diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-05-29 05:46:10 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-05-29 05:46:10 -0400 |
commit | e93721a70263afefbac781f575bfe851c6f95d84 (patch) | |
tree | ab359f12a0688802aa99339bae82c51763dae9f6 /sound/core | |
parent | ae1ec5e1e97f67d41e641a73380129e5905e41cc (diff) | |
parent | c87d9732004b3f8fd82d729f12ccfb96c0df279e (diff) |
Merge branch 'fix/pcm-jiffies-check' into topic/pcm-jiffies-check
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/pcm_lib.c | 17 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 6 |
2 files changed, 21 insertions, 2 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 63d088f2265f..d659995ac3ac 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -249,6 +249,17 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) | |||
249 | new_hw_ptr = hw_base + pos; | 249 | new_hw_ptr = hw_base + pos; |
250 | } | 250 | } |
251 | } | 251 | } |
252 | |||
253 | /* Do jiffies check only in xrun_debug mode */ | ||
254 | if (!xrun_debug(substream)) | ||
255 | goto no_jiffies_check; | ||
256 | |||
257 | /* Skip the jiffies check for hardwares with BATCH flag. | ||
258 | * Such hardware usually just increases the position at each IRQ, | ||
259 | * thus it can't give any strange position. | ||
260 | */ | ||
261 | if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) | ||
262 | goto no_jiffies_check; | ||
252 | hdelta = new_hw_ptr - old_hw_ptr; | 263 | hdelta = new_hw_ptr - old_hw_ptr; |
253 | jdelta = jiffies - runtime->hw_ptr_jiffies; | 264 | jdelta = jiffies - runtime->hw_ptr_jiffies; |
254 | if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) { | 265 | if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) { |
@@ -272,6 +283,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) | |||
272 | hw_base -= hw_base % runtime->buffer_size; | 283 | hw_base -= hw_base % runtime->buffer_size; |
273 | delta = 0; | 284 | delta = 0; |
274 | } | 285 | } |
286 | no_jiffies_check: | ||
275 | if (delta > runtime->period_size + runtime->period_size / 2) { | 287 | if (delta > runtime->period_size + runtime->period_size / 2) { |
276 | hw_ptr_error(substream, | 288 | hw_ptr_error(substream, |
277 | "Lost interrupts? " | 289 | "Lost interrupts? " |
@@ -329,7 +341,9 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) | |||
329 | hw_base = 0; | 341 | hw_base = 0; |
330 | new_hw_ptr = hw_base + pos; | 342 | new_hw_ptr = hw_base + pos; |
331 | } | 343 | } |
332 | if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) { | 344 | /* Do jiffies check only in xrun_debug mode */ |
345 | if (xrun_debug(substream) && | ||
346 | ((delta * HZ) / runtime->rate) > jdelta + HZ/100) { | ||
333 | hw_ptr_error(substream, | 347 | hw_ptr_error(substream, |
334 | "hw_ptr skipping! " | 348 | "hw_ptr skipping! " |
335 | "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", | 349 | "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", |
@@ -1471,7 +1485,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, | |||
1471 | runtime->status->hw_ptr %= runtime->buffer_size; | 1485 | runtime->status->hw_ptr %= runtime->buffer_size; |
1472 | else | 1486 | else |
1473 | runtime->status->hw_ptr = 0; | 1487 | runtime->status->hw_ptr = 0; |
1474 | runtime->hw_ptr_jiffies = jiffies; | ||
1475 | snd_pcm_stream_unlock_irqrestore(substream, flags); | 1488 | snd_pcm_stream_unlock_irqrestore(substream, flags); |
1476 | return 0; | 1489 | return 0; |
1477 | } | 1490 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index cb769d415db7..45dc53fcfa2f 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -849,6 +849,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) | |||
849 | { | 849 | { |
850 | struct snd_pcm_runtime *runtime = substream->runtime; | 850 | struct snd_pcm_runtime *runtime = substream->runtime; |
851 | snd_pcm_trigger_tstamp(substream); | 851 | snd_pcm_trigger_tstamp(substream); |
852 | runtime->hw_ptr_jiffies = jiffies; | ||
852 | runtime->status->state = state; | 853 | runtime->status->state = state; |
853 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && | 854 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
854 | runtime->silence_size > 0) | 855 | runtime->silence_size > 0) |
@@ -962,6 +963,11 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) | |||
962 | { | 963 | { |
963 | if (substream->runtime->trigger_master != substream) | 964 | if (substream->runtime->trigger_master != substream) |
964 | return 0; | 965 | return 0; |
966 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by | ||
967 | * a delta betwen the current jiffies, this gives a large enough | ||
968 | * delta, effectively to skip the check once. | ||
969 | */ | ||
970 | substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; | ||
965 | return substream->ops->trigger(substream, | 971 | return substream->ops->trigger(substream, |
966 | push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH : | 972 | push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH : |
967 | SNDRV_PCM_TRIGGER_PAUSE_RELEASE); | 973 | SNDRV_PCM_TRIGGER_PAUSE_RELEASE); |