[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