]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/writer_improvements'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 7 Nov 2021 16:07:24 +0000 (17:07 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 7 Nov 2021 16:09:00 +0000 (17:09 +0100)
A small set of patches which fix some minor issues, notably a problem
related to the handling of early EOF which affects all paraslash
writers.

* refs/heads/t/writer_improvements:
  alsa_write: Avoid spurious underrun warnings.
  Teach writers to abort gracefully on early EOF.
  alsa_write: Simplify alsa_post_select().

NEWS.md
alsa_write.c
ao_write.c
oss_write.c
write.h
write_common.c

diff --git a/NEWS.md b/NEWS.md
index 7554cd6b9fac8ae061d8be75afa0f4f706007ef8..76e00d3d166f71a4f98432464b87f937bc28ceaf 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,13 @@
 NEWS
 ====
 
+---------------------------------------
+0.7.0 (to be announced) "seismic orbit"
+---------------------------------------
+
+- Paraslash writers handle early end-of-file more gracefully.
+- The alsa writer no longer warns about spurious underruns.
+
 --------------------------------------
 0.6.4 (2021-11-04) "fuzzy calibration"
 --------------------------------------
index bc06fc315bc51fb3fc1fa9729ae429b47a70d4b4..bbbf8b650ac86c4952ac46f22c166583018bfb88 100644 (file)
@@ -240,6 +240,8 @@ static void alsa_close(struct writer_node *wn)
 
        if (!pad)
                return;
+       if (!pad->handle)
+               goto free_pad;
        /*
         * It's OK to have a blocking operation here because we already made
         * sure that the PCM output buffer is (nearly) empty.
@@ -248,6 +250,7 @@ static void alsa_close(struct writer_node *wn)
        snd_pcm_drain(pad->handle);
        snd_pcm_close(pad->handle);
        snd_config_update_free_global();
+free_pad:
        free(pad);
 }
 
@@ -294,21 +297,23 @@ again:
                if (bytes == 0) /* no data available */
                        return 0;
                pad = wn->private_data = para_calloc(sizeof(*pad));
-               get_btr_sample_rate(btrn, &val);
+               ret = get_btr_sample_rate(btrn, &val);
+               if (ret < 0)
+                       goto err;
                pad->sample_rate = val;
-               get_btr_channels(btrn, &val);
+               ret = get_btr_channels(btrn, &val);
+               if (ret < 0)
+                       goto err;
                pad->channels = val;
-               get_btr_sample_format(btrn, &val);
+               ret = get_btr_sample_format(btrn, &val);
+               if (ret < 0)
+                       goto err;
                pad->sample_format = get_alsa_pcm_format(val);
-
                PARA_INFO_LOG("%u channel(s), %uHz\n", pad->channels,
                        pad->sample_rate);
                ret = alsa_init(wn);
-               if (ret < 0) {
-                       free(wn->private_data);
-                       wn->private_data = NULL;
+               if (ret < 0)
                        goto err;
-               }
                wn->min_iqs = pad->bytes_per_frame;
                goto again;
        }
@@ -326,7 +331,11 @@ again:
                goto again;
        }
        if (frames == -EPIPE) {
-               PARA_WARNING_LOG("underrun (tried to write %zu bytes)\n", bytes);
+               snd_pcm_status_t *status;
+               snd_pcm_status_malloc(&status);
+               if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN)
+                       PARA_WARNING_LOG("underrun\n");
+               snd_pcm_status_free(status);
                snd_pcm_prepare(pad->handle);
                return 0;
        }
index 447dea84c00a468330fe8229bfd70b74292264bd..037b92993325539552ddd625b881a843aa57c5a9 100644 (file)
@@ -357,9 +357,15 @@ static int aow_post_select(__a_unused struct sched *s, void *context)
                        goto remove_btrn;
                if (ret == 0)
                        return 0;
-               get_btr_sample_rate(wn->btrn, &rate);
-               get_btr_channels(wn->btrn, &ch);
-               get_btr_sample_format(wn->btrn, &format);
+               ret = get_btr_sample_rate(wn->btrn, &rate);
+               if (ret < 0)
+                       goto remove_btrn;
+               ret = get_btr_channels(wn->btrn, &ch);
+               if (ret < 0)
+                       goto remove_btrn;
+               ret = get_btr_sample_format(wn->btrn, &format);
+               if (ret < 0)
+                       goto remove_btrn;
                ret = aow_init(wn, rate, ch, format);
                if (ret < 0)
                        goto remove_btrn;
index 311a514dc86ff6bfb01abf53d16a75672827af12..0565167c256a43bfe86a6442f195a320e1458db8 100644 (file)
@@ -199,9 +199,15 @@ static int oss_post_select(__a_unused struct sched *s, void *context)
 
                if (sound_device_is_busy())
                        return 0;
-               get_btr_sample_rate(btrn, &rate);
-               get_btr_channels(btrn, &ch);
-               get_btr_sample_format(btrn, &format);
+               ret = get_btr_sample_rate(btrn, &rate);
+               if (ret < 0)
+                       goto out;
+               ret = get_btr_channels(btrn, &ch);
+               if (ret < 0)
+                       goto out;
+               ret = get_btr_sample_format(btrn, &format);
+               if (ret < 0)
+                       goto out;
                ret = oss_init(wn, rate, ch, format);
                if (ret < 0)
                        goto out;
diff --git a/write.h b/write.h
index cb0beff812121b338e3749e80f63ad2cb99999db..833cb69a5cb6373bae819d5b7c323e1d567c6104 100644 (file)
--- a/write.h
+++ b/write.h
@@ -66,7 +66,7 @@ const struct writer *writer_get(int wid);
 const char *writer_name(int wid);
 void register_writer_node(struct writer_node *wn, struct btr_node *parent,
                struct sched *s);
-void get_btr_sample_rate(struct btr_node *btrn, int32_t *result);
-void get_btr_channels(struct btr_node *btrn, int32_t *result);
-void get_btr_sample_format(struct btr_node *btrn, int32_t *result);
+int get_btr_sample_rate(struct btr_node *btrn, int32_t *result);
+int get_btr_channels(struct btr_node *btrn, int32_t *result);
+int get_btr_sample_format(struct btr_node *btrn, int32_t *result);
 void print_writer_helps(bool detailed);
index 14cc98a4189a5f74907f8bfcf416f62bcc2515c5..41c3eb23728ab11cde71f837d4c58a1ef6908d24 100644 (file)
@@ -174,24 +174,24 @@ void print_writer_helps(bool detailed)
        }
 }
 
-static void get_btr_value(struct btr_node *btrn, const char *cmd,
+static int get_btr_value(struct btr_node *btrn, const char *cmd,
                int32_t *result)
 {
        char *buf = NULL;
        int ret = btr_exec_up(btrn, cmd, &buf);
 
-       if (ret < 0) {
-               /*
-                * This really should not happen. It means one of our parent
-                * nodes died unexpectedly. Proceed with fingers crossed.
-                */
-               PARA_CRIT_LOG("cmd %s: %s\n", cmd, para_strerror(-ret));
-               *result = 0;
-               return;
-       }
+       *result = 0;
+       /*
+        * Errors may happen when the decoder returns EOF before the writer had
+        * a chance to query the buffer tree for the channel count, sample rate
+        * etc.
+        */
+       if (ret < 0)
+               return ret;
        ret = para_atoi32(buf, result);
        assert(ret >= 0);
        free(buf);
+       return ret;
 }
 
 /**
@@ -200,11 +200,11 @@ static void get_btr_value(struct btr_node *btrn, const char *cmd,
  * \param btrn Where to start the search.
  * \param result Filled in by this function.
  *
- * This function is assumed to succeed and terminates on errors.
+ * \return Standard.
  */
-void get_btr_sample_rate(struct btr_node *btrn, int32_t *result)
+int get_btr_sample_rate(struct btr_node *btrn, int32_t *result)
 {
-       get_btr_value(btrn, "sample_rate", result);
+       return get_btr_value(btrn, "sample_rate", result);
 }
 
 /**
@@ -212,10 +212,12 @@ void get_btr_sample_rate(struct btr_node *btrn, int32_t *result)
  *
  * \param btrn See \ref get_btr_sample_rate.
  * \param result See \ref get_btr_sample_rate.
+ *
+ * \return Standard.
  */
-void get_btr_channels(struct btr_node *btrn, int32_t *result)
+int get_btr_channels(struct btr_node *btrn, int32_t *result)
 {
-       get_btr_value(btrn, "channels", result);
+       return get_btr_value(btrn, "channels", result);
 }
 
 /**
@@ -223,8 +225,10 @@ void get_btr_channels(struct btr_node *btrn, int32_t *result)
  *
  * \param btrn See \ref get_btr_sample_rate.
  * \param result Contains the sample format as an enum sample_format type.
+ *
+ * \return Standard.
  */
-void get_btr_sample_format(struct btr_node *btrn, int32_t *result)
+int get_btr_sample_format(struct btr_node *btrn, int32_t *result)
 {
-       get_btr_value(btrn, "sample_format", result);
+       return get_btr_value(btrn, "sample_format", result);
 }