diff options
author | Nicolas George <george@nsup.org> | 2013-10-25 12:58:14 +0400 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2014-02-20 14:22:55 +0400 |
commit | 299a56879d2d790ac0c40d09af18e7f03471de9e (patch) | |
tree | d272a3952d09c79b85b24f0fc11de99ffd50a1a6 /ffmpeg.c | |
parent | 3edc3b159503d512c919b3d5902f7026e961823a (diff) |
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.
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 20 |
1 files changed, 18 insertions, 2 deletions
@@ -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); |