[FFmpeg-devel] [PATCH 2/3] avformat: remove more unneeded avio_flush() calls

Marton Balint cus at passwd.hu
Fri Jan 3 22:31:17 EET 2020


On Fri, 3 Jan 2020, Martin Storsjö wrote:

> On Fri, 3 Jan 2020, Marton Balint wrote:
>
>> Throughout libavformat there are lots of avio_flush() calls which are 
> unneeded:
>> - Instances found at the end of write_header, write_packet and 
> write_trailer
>>  callbacks. These are handled by the generic code in libavformat/mux.c.
>
> They are only handled by the generic code, if the flush_packets flag is 
> set. If it isn't, and the flush was there for a reason (I'm sure not all 
> of them are, but I'm also quite sure a few of them are there for very 
> specific reasons), things will now break.

For write_packet, you are right, it removes the explicit flush and fall 
backs to the default behaviour of the flush_packets flag, which is to 
flush if the output is streamed, and not flush otherwise. Can you a think 
of a case which breaks when the output is not streamed?

For write_header there is an explicit flush in avio_write_marker if the 
marker type is AVIO_DATA_MARKER_HEADER and if the type is different to the 
existing marker, so it should not make a difference.

>
> One such case that you're removing comes from 
> 8ad5124b7ecf7f727724e270a7b4bb8c7bcbf6a4 which was added for a specific 
> reason.

I guess this predates your avio_write_marker addition.

>
>> - Instances in the middle of write_header and write_trailer which are
>>  redundant or are present becuase avio_flush() used to be required before
>>  doing a seekback. That is no longer the case, aviobuf code does the flush
>>  automatically on seek.
>
> It's not necessarily about flushing before doing seekback, it's also about 
> ensuring that seekback can be done within the current buffer.
>
> For streaming output (where we can't seek back once data has been 
> flushed), it's cruicial to flush _before_ a point you want to seek to. 
> Consider if we have a 32k avio buffer, and it's filled up to 30k at the 
> moment. We're going to write a 8k structure which requires seeks back and 
> forth. If we remove the pre-write-flush, we'll write 2k of data, flush it 
> out, and later seeks to the beginning of this block will fail.
>
> If we explicitly flush before starting to write one block where we know 
> we'll need to seek to, we maximize the chances of it working. (If we need 
> to seek across a larger area than the avio buffer, then it still won't 
> work of course.)
>
> I didn't check yet all of the ones you are removing, but I'd say at least 
> that movenc.c has cases of intentional flushing in this style.

Ok, this can be a problem indeed. A proper solution would be to use a 
dynbuf in these cases if streaming is of importance because it is wrong to 
assume any particular output buffer size in a muxer and rely on this 
behaviour.

>> So this patch removes those cases. Removing explicit avio_flush() calls 
> helps
>> us to buffer more data and avoid flushing the IO context too often which 
> causes
>> reduced IO throughput for non-streamed file output.
>
> So if you're arguing that some can be removed because the generic code in 
> mux.c does the same (although it only does so if a nondefault flag is 
> set?), this benefit can only be attributed to the other ones, that are 
> removed from the middle of functions.

Yes. I will rework the patchset, sepearte the cases better and maybe keep 
the ones in the middle write_header/write_trailer for now.

Thanks,
Marton


More information about the ffmpeg-devel mailing list