[FFmpeg-devel] [PATCH] ffmpeg: make reading packets from thread blocking.
Paul B Mahol
onemda at gmail.com
Tue Oct 29 14:43:48 CET 2013
On 10/25/13, Nicolas George <george at nsup.org> wrote:
> 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.
>
> Signed-off-by: Nicolas George <george at nsup.org>
> ---
> ffmpeg.c | 17 +++++++++++++++--
> ffmpeg.h | 1 +
> 2 files changed, 16 insertions(+), 2 deletions(-)
>
>
> Note: the non_blocking flag can be later made an option. But I am in fact
> rather convinced that the blocking mode should be made the default even for
> devices, possibly enlarging the size of the FIFO at the same time.
>
>
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 001e5c1..ff717d5 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -2795,6 +2795,7 @@ 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);
> }
> @@ -2851,6 +2852,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);
>
> @@ -2866,14 +2871,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 054e718..4dc10ff 100644
> --- a/ffmpeg.h
> +++ b/ffmpeg.h
> @@ -293,6 +293,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 */
> --
> 1.8.4.rc3
>
lgtm
More information about the ffmpeg-devel
mailing list