[FFmpeg-devel] Blocking vs non-blocking modes in protocols

Andriy Gelman andriy.gelman at gmail.com
Sun Sep 1 19:54:08 EEST 2019


Marton, 

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.

But overall, the two modes seem similar to me: 
    - "Blocking" - blocks at the transfer_function
    - "Non-blocking" - blocks in retry_transfer_function

----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? 

----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))

    (2) The default value for rw_timeout = 0. This value implies an infinite
    wait in both blocking/non-blocking mode. The documentation in
    docs/protocols.texi should say this. 

    (3) Update avio.h/url.h to clarify difference between AVERROR(ETIMEDOUT) and
    AVERROR(EINTR) in blocking mode. Clarify what is the potential advantage of
    non-blocking mode over blocking mode.

    (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 

    (5) If rw_timeout expires in non-blocking mode, return AVERROR(ETIMEDOUT)
    instead of AVERROR(EIO) to be consistent with blocking mode.


More information about the ffmpeg-devel mailing list