aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2013-10-25 10:58:14 +0200
committerNicolas George <george@nsup.org>2014-02-20 11:22:55 +0100
commit299a56879d2d790ac0c40d09af18e7f03471de9e (patch)
treed272a3952d09c79b85b24f0fc11de99ffd50a1a6
parent3edc3b159503d512c919b3d5902f7026e961823a (diff)
downloadffmpeg-299a56879d2d790ac0c40d09af18e7f03471de9e.tar.gz
ffmpeg: make reading packets from thread blocking.
If a packet is not ready on the input selected by ffmpeg, it will read from another input instead. If that happens repeatedly, frames will accumulate somewhere later in the processing to ensure streams synchronization. It can happen in particular when reading from a slow medium or an expensive lavfi filter graph. Make reading from normal demuxers on non-streamed data and from the lavfi pseudo-device blocking to avoid that. Should fix trac ticket #3079.
-rw-r--r--ffmpeg.c20
-rw-r--r--ffmpeg.h1
2 files changed, 19 insertions, 2 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index 1369fdaf64..28bebe532a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2960,11 +2960,15 @@ static void *input_thread(void *arg)
av_dup_packet(&pkt);
av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
+ pthread_cond_signal(&f->fifo_cond);
pthread_mutex_unlock(&f->fifo_lock);
}
+ pthread_mutex_lock(&f->fifo_lock);
f->finished = 1;
+ pthread_cond_signal(&f->fifo_cond);
+ pthread_mutex_unlock(&f->fifo_lock);
return NULL;
}
@@ -3016,6 +3020,10 @@ static int init_input_threads(void)
if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
return AVERROR(ENOMEM);
+ if (f->ctx->pb ? !f->ctx->pb->seekable :
+ strcmp(f->ctx->iformat->name, "lavfi"))
+ f->non_blocking = 1;
+
pthread_mutex_init(&f->fifo_lock, NULL);
pthread_cond_init (&f->fifo_cond, NULL);
@@ -3031,14 +3039,22 @@ static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
pthread_mutex_lock(&f->fifo_lock);
+ while (1) {
if (av_fifo_size(f->fifo)) {
av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
pthread_cond_signal(&f->fifo_cond);
+ break;
} else {
- if (f->finished)
+ if (f->finished) {
ret = AVERROR_EOF;
- else
+ break;
+ }
+ if (f->non_blocking) {
ret = AVERROR(EAGAIN);
+ break;
+ }
+ pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
+ }
}
pthread_mutex_unlock(&f->fifo_lock);
diff --git a/ffmpeg.h b/ffmpeg.h
index 04e5b7274b..151667d74a 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -327,6 +327,7 @@ typedef struct InputFile {
#if HAVE_PTHREADS
pthread_t thread; /* thread reading from this file */
+ int non_blocking; /* reading packets from the thread should not block */
int finished; /* the thread has exited */
int joined; /* the thread has been joined */
pthread_mutex_t fifo_lock; /* lock for access to fifo */