Mercurial > mplayer.hg
comparison libmpdemux/ai_alsa1x.c @ 7586:d12421dd1265
this patch adds an ability to recover from audio buffer cross-run by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
author | alex |
---|---|
date | Wed, 02 Oct 2002 16:56:54 +0000 |
parents | 13fcab6fde41 |
children | 31f12f99118b |
comparison
equal
deleted
inserted
replaced
7585:cfd6a99021ac | 7586:d12421dd1265 |
---|---|
1 #include <stdio.h> | 1 #include <stdio.h> |
2 #include <stdlib.h> | 2 #include <stdlib.h> |
3 #include <sys/time.h> | |
3 | 4 |
4 #include "config.h" | 5 #include "config.h" |
5 | 6 |
6 #if defined(USE_TV) && defined(HAVE_TV_V4L) && defined(HAVE_ALSA9) | 7 #if defined(USE_TV) && defined(HAVE_TV_V4L) && defined(HAVE_ALSA9) |
7 | 8 |
11 | 12 |
12 int ai_alsa_setup(audio_in_t *ai) | 13 int ai_alsa_setup(audio_in_t *ai) |
13 { | 14 { |
14 snd_pcm_hw_params_t *params; | 15 snd_pcm_hw_params_t *params; |
15 snd_pcm_sw_params_t *swparams; | 16 snd_pcm_sw_params_t *swparams; |
16 size_t buffer_size; | 17 int buffer_size; |
17 int err; | 18 int err; |
18 size_t n; | |
19 unsigned int rate; | 19 unsigned int rate; |
20 snd_pcm_uframes_t start_threshold, stop_threshold; | |
21 | 20 |
22 snd_pcm_hw_params_alloca(¶ms); | 21 snd_pcm_hw_params_alloca(¶ms); |
23 snd_pcm_sw_params_alloca(&swparams); | 22 snd_pcm_sw_params_alloca(&swparams); |
24 | 23 |
25 err = snd_pcm_hw_params_any(ai->alsa.handle, params); | 24 err = snd_pcm_hw_params_any(ai->alsa.handle, params); |
122 err = ai_alsa_setup(ai); | 121 err = ai_alsa_setup(ai); |
123 | 122 |
124 return err; | 123 return err; |
125 } | 124 } |
126 | 125 |
126 #ifndef timersub | |
127 #define timersub(a, b, result) \ | |
128 do { \ | |
129 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ | |
130 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ | |
131 if ((result)->tv_usec < 0) { \ | |
132 --(result)->tv_sec; \ | |
133 (result)->tv_usec += 1000000; \ | |
134 } \ | |
135 } while (0) | |
136 #endif | |
137 | |
138 int ai_alsa_xrun(audio_in_t *ai) | |
139 { | |
140 snd_pcm_status_t *status; | |
141 int res; | |
142 | |
143 snd_pcm_status_alloca(&status); | |
144 if ((res = snd_pcm_status(ai->alsa.handle, status))<0) { | |
145 mp_msg(MSGT_TV, MSGL_ERR, "ALSA status error: %s", snd_strerror(res)); | |
146 return -1; | |
147 } | |
148 if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) { | |
149 struct timeval now, diff, tstamp; | |
150 gettimeofday(&now, 0); | |
151 snd_pcm_status_get_trigger_tstamp(status, &tstamp); | |
152 timersub(&now, &tstamp, &diff); | |
153 mp_msg(MSGT_TV, MSGL_ERR, "ALSA xrun!!! (at least %.3f ms long)\n", | |
154 diff.tv_sec * 1000 + diff.tv_usec / 1000.0); | |
155 if (mp_msg_test(MSGT_TV, MSGL_V)) { | |
156 mp_msg(MSGT_TV, MSGL_ERR, "ALSA Status:\n"); | |
157 snd_pcm_status_dump(status, ai->alsa.log); | |
158 } | |
159 if ((res = snd_pcm_prepare(ai->alsa.handle))<0) { | |
160 mp_msg(MSGT_TV, MSGL_ERR, "ALSA xrun: prepare error: %s", snd_strerror(res)); | |
161 return -1; | |
162 } | |
163 return 0; /* ok, data should be accepted again */ | |
164 } | |
165 mp_msg(MSGT_TV, MSGL_ERR, "ALSA read/write error"); | |
166 return -1; | |
167 } | |
168 | |
127 #endif /* HAVE_ALSA9 */ | 169 #endif /* HAVE_ALSA9 */ |