aacdec: detect buffer overrun and return an errror.
[paraslash.git] / alsa_writer.c
index 617173a..7c6e8ca 100644 (file)
@@ -47,6 +47,8 @@ struct private_alsa_data {
        size_t bytes_per_frame;
        /** don't write anything until this time */
        struct timeval next_chunk;
+       /** the return value of snd_pcm_hw_params_get_buffer_time_max() */
+       unsigned buffer_time;
 };
 
 /*
@@ -60,7 +62,6 @@ static int alsa_open(struct writer_node *w)
        snd_pcm_sw_params_t *swparams;
        snd_pcm_uframes_t buffer_size, xfer_align, start_threshold,
                stop_threshold;
-       unsigned buffer_time = 0;
        int err;
        snd_pcm_info_t *info;
        snd_pcm_uframes_t period_size;
@@ -91,18 +92,18 @@ static int alsa_open(struct writer_node *w)
        if (snd_pcm_hw_params_set_rate_near(pad->handle, hwparams,
                        (unsigned int*) &conf->sample_rate_arg, 0) < 0)
                return -E_SET_RATE;
-       err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0);
-       if (err < 0 || !buffer_time)
+       err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &pad->buffer_time, 0);
+       if (err < 0 || !pad->buffer_time)
                return -E_GET_BUFFER_TIME;
-       PARA_DEBUG_LOG("buffer time: %d\n", buffer_time);
+       PARA_INFO_LOG("buffer time: %d\n", pad->buffer_time);
        if (snd_pcm_hw_params_set_buffer_time_near(pad->handle, hwparams,
-                       &buffer_time, 0) < 0)
+                       &pad->buffer_time, 0) < 0)
                return -E_SET_BUFFER_TIME;
        if (snd_pcm_hw_params(pad->handle, hwparams) < 0)
                return -E_HW_PARAMS;
        snd_pcm_hw_params_get_period_size(hwparams, &period_size, 0);
        snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
-       PARA_DEBUG_LOG("buffer size: %lu, period_size: %lu\n", buffer_size,
+       PARA_INFO_LOG("buffer size: %lu, period_size: %lu\n", buffer_size,
                period_size);
        if (period_size == buffer_size)
                return -E_BAD_PERIOD;
@@ -129,8 +130,8 @@ static int alsa_open(struct writer_node *w)
                return -E_SW_PARAMS;
        pad->bytes_per_frame = snd_pcm_format_physical_width(FORMAT)
                * conf->channels_arg / 8;
-//     if (snd_pcm_nonblock(pad->handle, 1))
-//             PARA_ERROR_LOG("%s\n", "failed to set nonblock mode");
+       if (snd_pcm_nonblock(pad->handle, 1))
+               PARA_ERROR_LOG("%s\n", "failed to set nonblock mode");
        return period_size * pad->bytes_per_frame;
 }
 static void alsa_write_pre_select(struct sched *s, struct task *t)
@@ -176,15 +177,14 @@ static void alsa_write_post_select(struct sched *s, struct task *t)
 //     while (frames > 0) {
                ret = snd_pcm_writei(pad->handle, data, frames);
                if (ret == -EAGAIN || (ret >= 0 && ret < frames)) {
-                       struct timeval tv = {0, 1000 * 10};
-                       PARA_INFO_LOG("EAGAIN. frames: %d, ret: %lu\n", frames, ret);
+                       struct timeval tv;
+                       ms2tv(pad->buffer_time / 2000, &tv);
+                       PARA_DEBUG_LOG("EAGAIN. frames: %d, ret: %lu\n", frames, ret);
                        tv_add(&s->now, &tv, &pad->next_chunk);
-//                     snd_pcm_wait(pad->handle, 1);
                } else if (ret == -EPIPE) {
-                       PARA_INFO_LOG("%s", "EPIPE\n");
+                       PARA_WARNING_LOG("%s", "EPIPE\n");
                        snd_pcm_prepare(pad->handle);
                } else if (ret < 0) {
-                       PARA_INFO_LOG("ALSA ERR %d\n", frames);
                        t->ret = -E_ALSA_WRITE;
                        return;
                }