comparison libmpdemux/ai_alsa.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(&params); 21 snd_pcm_hw_params_alloca(&params);
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 */