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 spinning
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 packets
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 returning
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 mission statement for the FIFO muxer. Or, to put another way, a detailed explanation
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 non-blocking 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 interrupt
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 error
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.

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
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.

Regards,
Jan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to