[FFmpeg-devel] Blocking vs non-blocking modes in protocols
Andriy Gelman
andriy.gelman at gmail.com
Tue Sep 3 06:00:52 EEST 2019
Nicolas, thank you for clarifying
On Mon, 02. Sep 17:21, Nicolas George wrote:
> Andriy Gelman (12019-09-01):
> > Below are my notes on blocking and non-blocking modes in protocols. Proposed
> > changes that I'd like to make are at the end.
> >
> > Thanks,
> > Andriy
> >
> >
> > ---General notes--
> > -blocking mode-
> > - transfer_function deals with polling and timeout
> > - block inside transfer_function for max rw_timeout.
> > - if rw_timeout expires the protocol designers have two options:
> > (1) transfer_funciton returns AVERROR(ETIMEDOUT). This will cause the
> > encoding/decoding to exit with timeout error.
> > (2) transfer_function returns AVERROR(EINTR). Immediately retry the
> > transfer_function after checking interrupt callback.
> >
> > -non-blocking mode-
> > - retry_transfer_wrapper deals with retries
> > - if read/writes are not available transfer_function should immediately
> > return with AVERROR(EAGAIN)
>
> > - retry transfer_function with 5 x fast_retry (no sleep). Then, retry with
> > 1ms sleep.
> > - If rw_timeout expires, exit encoding/decoding with AVERROR(EIO) (Probably
> > should be changed to AVERROR(ETIMEDOUT) to be consistent with blocking
> > mdoe.
>
> This looks like one of the reasons the non-blocking mode does not work.
>
> > But overall, the two modes seem similar to me:
> > - "Blocking" - blocks at the transfer_function
> > - "Non-blocking" - blocks in retry_transfer_function
>
> The expected behaviour is: non-blocking does not block.
>
> > ----Potential advantage of non-blocking over blocking mode----
> > I'm trying to figure what would be the advantage of non-blocking over blocking
> > modes. The only reason I can think of: non-blocking mode gives more control to
> > the user rather than protocol designer. In non-blocking mode the user can force
> > an exit after rw_timeout expires. On the other hand, in blocking mode, the
> > protocol designer can force a retry by returing AVERROR(EINTR) after rw_timeout
> > expires instead of exiting the code (i.e. after AVERROR(ETIMEDOUT) is returned).
> >
> > Any other reason someone would prefer non-blocking over blocking modes?
>
> I am not sure I read you correctly, I think you are saying that
> blocking/non-blocking mode is a design decision for protocol
> implementors. The difference between blocking and non-blocking mode is
> not meant for the internal design of FFmpeg but for applications.
>
> An application that has several live inputs (network, device, GUI (a GUI
> is one big live input)) cannot be blocked reading on one of them,
> because it needs to react to the others immediately. The application
> design is then to have all live inputs in non-blocking mode, and walk
> over them, like this:
>
> while (1) {
> wait_for_any_input();
> for (input)
> process_input_non_blocking(input);
> }
>
> (If the application is CPU-bound rather than input-bound,
> wait_for_any_input() will need to be rather
> perform_a_slice_of_computation().)
>
> (Some applications, including FFmpeg, will have wait_a_small_time()
> instead of wait_for_any_input(), but that is terrible design and a waste
> of energy that contributes to global warming.)
>
> > ----Proposed changes----
> > (1) At the moment, non-blocking mode immediately exits after AVERROR(EAGAIN)
> > is returned without doing any retries. I'm quite sure there is a bug on
> > avio.c:379. It should be changed to: if (!(h->flags & AVIO_FLAG_NONBLOCK))
>
> In non-blocking mode, if no data is available, the flow must return to
> the application immediately with AVERROR(EAGAIN).
I assumed that the set of retries in retry_transfer_wrapper were aimed at the
non-blocking mode. But these retries are not called at the moment when the
AVIO_FLAG_NONBLOCK flag is set.
As I understand from your reply this is the correct behaviour.
>
> > (3) Update avio.h/url.h to clarify difference between AVERROR(ETIMEDOUT) and
> > AVERROR(EINTR) in blocking mode.
>
> The semantic of EINTR is "Unix sucks, signals are terribly badly
> designed". It should never be used in our code except to deal with that
> bad design.
>
> > (4) Add non-blocking option to the cli. Something like -avioflags
> > nonblocking. But add a note that this may not be supported by a specific
> > protocol
>
> Working in blocking or non-blocking mode means a completely different
> design of the program, making it an option does not make sense.
>
> > (5) If rw_timeout expires in non-blocking mode, return AVERROR(ETIMEDOUT)
> > instead of AVERROR(EIO) to be consistent with blocking mode.
>
> In non-blocking mode, there can be no timeout because there can be no
> time. If there is, it is a bug.
>
> Note: Currently, non-blocking mode works for a few cases but is
> completely broken in most of FFmpeg's code base. In a subsequent mail I
> will try to summarise the state of affairs and how it could be enhanced.
Thanks,
Andriy
More information about the ffmpeg-devel
mailing list