[FFmpeg-devel] [PATCH] libavformat: Add FIFO pseudo-muxer
sebechlebskyjan at gmail.com
Sat Jul 9 03:20:13 EEST 2016
On 07/08/2016 10:39 PM, Marton Balint wrote:
> On Fri, 8 Jul 2016, Nicolas George wrote:
>> Le primidi 21 messidor, an CCXXIV, Jan Sebechlebsky a écrit :
>>> I actually thought about this and maybe I am still missing
>>> something, but
>>> how is this different from the situation without FIFO muxer?
>> It is not, which is exactly the answer you do not want when people
>> ask what
>> your program is good for.
That question was related to usage of interrupt_callback, not the
functionality of FIFO muxer :)
>>> When the FIFO is not used, let's say an I/O operation somewhere inside
>>> write_packet call blocks for a long time - actually it means it is
>>> in a cycle "wait for io with short timeout"<->"check return value of
>>> interrupt callback". When the application decides to interrupt the
>>> operation, it sets some interrupt condition (ffmpeg increments
>>> received_nb_signals when receives SIGINT). The next call to interrupt
>>> callback will cause the IO function to return AVERROR_EXIT causing
>>> write_packet to fail with same error.
>>> When the FIFO is used the write_packet call will return immediately.
>>> The I/O
>>> blocking will happen in consumer thread, in some of the
>>> fifo_thread_write_packet calls. Let's say that during that time all
>>> are send to queue and write_trailer is called. The main thread
>>> is blocked by pthread_join(). However when the interrupt condition
>>> is set
>>> (for example by receiving SIGINT as in ffmpeg), this is still
>>> handled by the
>>> blocking IO function which will return AVERROR_EXIT causing
>>> fifo_thread_write_packet to fail with the same error, causing the
>>> thread to
>>> terminate which unblocks write_trailer.
>>> My point is that the same asynchronous mechanism which is supposed
>>> to work
>>> in case of blocking I/O operation should work also in case
>>> pthread_join is
>>> blocking, so the I/O operation should be terminated the same way
>>> AVERROR_EXIT which will cause consumer thread to terminate and unblock
>>> pthread_join call...
>>> Am I missing something?
>> I think you are missing (not in the sense of your question) a clear
>> statement for the FIFO muxer. Or, to put another way, a detailed
>> of what it is useful for and more importantly, how to benefit from it.
> The basic goals are the ones which are set in the GSOC trac page under
> the tee muxer improvement project:
> Description: FFmpeg contains a tee muxer, which is capable of writing
> the same coded packets to multiple outputs. However, if one of the
> outputs blocks or fails for any reason, the other outputs will block
> or fail too. Also there is no built-in support for gracefully
> restarting an output in case of a failure. Lacking these two features
> makes the tee muxer unsuitable for redundancy or high availability
> purposes especially on networked outputs.
> Expected results:
> •Add a non-blocking mode with a configurable maximum packet queue size
> where one output does not block the others
> •Add a graceful restart mode where a failed output can transparently
> automatically restart its operation
> We decided to implement these features in a separate muxer, instead of
> hard coding it to tee, but the goals are the same. In order to reach
> them, one will have to specify fifo muxers in the output of the tee
> muxer, or Jan can work on some syntactic sugar which makes this more
> convenient for the user, but the result is the same.
>> If I understand things correctly, it is meant to be used by
>> applications (or
>> libraries, including the tee muxer), not directly by users. But how
>> are the
>> applications supposed to do exactly, and what can they expect.
> It also can be used by users. For example in blocking mode the fifo
> muxer can work as a pipeline between the encoder and the output,
> hiding disk latencies. In this scenario the user don't need to use the
> tee muxer to grab the benefits of the fifo muxer. In this case, it
> works similarly as the async protocol for input, only for output.
>> One of the features seems to be to turn a blocking muxer into a
>> muxer, which is indeed useful. But if the muxer falls back to
>> blocking on
>> close and the application needs to set up a thread-synchronized
>> callback to handle it, then I feel we are missing a serious opportunity.
> The reason why neither me (and I guess nor Jan) sees this as an issue,
> is that this is not needed for the goals set in the project. We simply
> don't care if closeing a stream blocks, that is not what we are aiming
> for here.
>> The way I see it, in non-blocking mode, the most logical approach
>> would be
>> something like this: the first call to write_header() causes the closing
>> process to start an returns EAGAIN immediately, subsequent calls return
>> EAGAIN until the closing process is done, then 0 for success, or an
>> code after a configurable timeout.
> Sure, this can be implemented (although an API change, so dificcult to
> pull through), but in GSOC this was simply not a goal of ours.
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
Marton, thanks for summing that up :)
I also think advantage of having blocking write_trailer call is
that you can use the fifo muxer transparently as any other muxer, but
you have the advantage of asynchronous output processing and transparent
restarts of output in case of failure.
More information about the ffmpeg-devel