Working with network streams

For the developers that use FFmpeg in their software.
Post Reply
malcolmb
Posts: 8
Joined: Fri Dec 16, 2011 5:54 pm

Working with network streams

Post by malcolmb » Thu Jan 12, 2012 11:07 pm

Hey, does anyone have any insight with what ffmpeg does and doesn't do when reading from a network stream. I'm not using ffmpeg.exe, but rather in my own application using libavcodec/format etc.

For example say I open a http stream using av_open_input_file and then read packets with av_read_frame(). Is there any pre-buffering of the stream that ffmpeg will do for me? If so, is there a way to control the buffer size?
If I call av_read_frame() repeatedly until I've exhausted the buffer (I get negative results eventually), will I eventually get packets again if I wait a bit before calling again, or does the stream go into an error state?

Thanks

Vladimir
Posts: 29
Joined: Tue Sep 27, 2011 1:15 pm

Re: Working with network streams

Post by Vladimir » Mon Jan 16, 2012 8:37 am

Default low-level buffer seems to be 32kb long.

Libav first loads about 5Mb of data and uses them to determine format.
You can change this amount by changing AVFormatContext::max_analyze_duration.
In my code I have

Code: Select all

input->max_analyze_duration = 2 * AV_TIME_BASE; // read 2 seconds of data 
These data are stored in the AVFormatContext::AVPacketList field, and libav gives these data in response to calls to av_read_frame(), simultaneously removing them from the packet list.

Then it reads data from a stream, using that low-level buffer.

You can define your own AVIOContext and have finer control of this reading.
See manuals of avio_alloc_context(), AVFormatContext::pb, AVFMT_FLAG_CUSTOM_IO.

You can wait some time before reading, but this is limited to the system TCP buffer size, in case of TCP. In case of UDP, you'll lose all unread UDP packets.

Libav doesn't reconnect after timeouts, so, you should implement this error restoration by yourself.

If you use custom AVIOContext, and your reading function returns error code, you can see this code in the AVIOContext::error field.
If you restore after errors, you should zero this field, and also AVIOContext::eof_reached field.

To detect connection failures and conditions for reconnection, you should check both the result of av_read_frame() and AVIOContext::error.

If av_read_frame()'s result == 0, and AVIOContext::error == some_error_code, then current frame, returned by av_read_frame() is OK, but there are errors, and you should reconnect, and rerequest data right after the current frame.
If you don't reconnect, the next call to av_read_frame() will return the same some_error_code.

Post Reply