Fixes https://bugzilla.libav.org/show_bug.cgi?id=312
---
 libavdevice/jack_audio.c | 55 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index c261514..ef6e0fb 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -21,7 +21,7 @@
  */
 
 #include "config.h"
-#include <semaphore.h>
+#include <pthread.h>
 #include <jack/jack.h>
 
 #include "libavutil/log.h"
@@ -42,7 +42,8 @@ typedef struct {
     AVClass        *class;
     jack_client_t * client;
     int             activated;
-    sem_t           packet_count;
+    pthread_mutex_t pkt_mutex;
+    pthread_cond_t  pkt_cond;
     jack_nframes_t  sample_rate;
     jack_nframes_t  buffer_size;
     jack_port_t **  ports;
@@ -107,9 +108,9 @@ static int process_callback(jack_nframes_t nframes, void 
*arg)
     /* Timestamp the packet with the cycle start time minus the average 
latency */
     pkt.pts = (cycle_time - (double) latency / (self->nports * 
self->sample_rate)) * 1000000.0;
 
-    /* Send the now filled packet back, and increase packet counter */
+    /* Send the now filled packet back, and signal that it's ready */
     av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL);
-    sem_post(&self->packet_count);
+    pthread_cond_signal(&self->pkt_cond);
 
     return 0;
 }
@@ -160,7 +161,8 @@ static int start_jack(AVFormatContext *context)
         return AVERROR(EIO);
     }
 
-    sem_init(&self->packet_count, 0, 0);
+    pthread_mutex_init(&self->pkt_mutex, NULL);
+    pthread_cond_init(&self->pkt_cond, NULL);
 
     self->sample_rate = jack_get_sample_rate(self->client);
     self->ports       = av_malloc(self->nports * sizeof(*self->ports));
@@ -225,7 +227,8 @@ static void stop_jack(JackData *self)
             jack_deactivate(self->client);
         jack_client_close(self->client);
     }
-    sem_destroy(&self->packet_count);
+    pthread_cond_destroy(&self->pkt_cond);
+    pthread_mutex_destroy(&self->pkt_mutex);
     free_pkt_fifo(self->new_pkts);
     free_pkt_fifo(self->filled_pkts);
     av_freep(&self->ports);
@@ -284,18 +287,40 @@ static int audio_read_packet(AVFormatContext *context, 
AVPacket *pkt)
 
     /* Wait for a packet coming back from process_callback(), if one isn't 
available yet */
     timeout.tv_sec = av_gettime() / 1000000 + 2;
-    if (sem_timedwait(&self->packet_count, &timeout)) {
-        if (errno == ETIMEDOUT) {
-            av_log(context, AV_LOG_ERROR,
-                   "Input error: timed out when waiting for JACK process 
callback output\n");
-        } else {
-            av_log(context, AV_LOG_ERROR, "Error while waiting for audio 
packet: %s\n",
+
+    /* Only wait if there's nothing to read yet */
+    if (!av_fifo_size(self->filled_pkts)) {
+
+        if (pthread_mutex_lock(&self->pkt_mutex)) {
+            av_log(context, AV_LOG_ERROR, "Error while trying to lock mutex: 
%s\n",
                    strerror(errno));
+            return AVERROR(EIO);
         }
-        if (!self->client)
-            av_log(context, AV_LOG_ERROR, "Input error: JACK server is 
gone\n");
 
-        return AVERROR(EIO);
+        if (pthread_cond_timedwait(&self->pkt_cond, &self->pkt_mutex, 
&timeout)) {
+            if (errno == ETIMEDOUT) {
+                av_log(context, AV_LOG_ERROR,
+                       "Input error: timed out when waiting for JACK process 
callback output\n");
+            } else {
+                av_log(context, AV_LOG_ERROR, "Error while waiting for audio 
packet: %s\n",
+                       strerror(errno));
+            }
+            if (!self->client)
+                av_log(context, AV_LOG_ERROR, "Input error: JACK server is 
gone\n");
+
+            if (pthread_mutex_unlock(&self->pkt_mutex)) {
+                av_log(context, AV_LOG_ERROR, "Error while trying to unlock 
mutex: %s\n",
+                       strerror(errno));
+            }
+
+            return AVERROR(EIO);
+        }
+
+        if (pthread_mutex_unlock(&self->pkt_mutex)) {
+            av_log(context, AV_LOG_ERROR, "Error while trying to unlock mutex: 
%s\n",
+                   strerror(errno));
+            return AVERROR(EIO);
+        }
     }
 
     if (self->pkt_xrun) {
-- 
1.8.1.2

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to