Fix FFmpeg RTSP Packet Drops with Buffer Size

When streaming live video over RTSP using FFmpeg, high-resolution streams or network congestion can lead to packet loss, causing video corruption and “packet loss” or “frame dropped” errors. This article explains how to prevent these issues by configuring the socket buffer size, adjusting the internal FIFO queue, and selecting the appropriate network protocol within your FFmpeg commands.

1. Switch from UDP to TCP

By default, RTSP often uses UDP to transmit media packets. UDP does not guarantee delivery, leading to packet drops under heavy network load. Switching the transport protocol to TCP forces packet retransmission and eliminates packet drops caused by network congestion.

To force TCP, place the -rtsp_transport tcp parameter before your input:

ffmpeg -rtsp_transport tcp -i rtsp://your_stream_address -c copy output.mp4

2. Increase the UDP Receive Buffer Size

If your project requires UDP due to latency constraints, you must increase the socket buffer size. If the buffer is too small, the operating system will drop incoming packets before FFmpeg can process them.

You can increase the buffer size using the -buffer_size option. This value is defined in bytes (e.g., 10485760 for 10 MB):

ffmpeg -rtsp_transport udp -buffer_size 10485760 -i rtsp://your_stream_address -c copy output.mp4

3. Adjust the FFmpeg FIFO Queue Size

FFmpeg uses an internal FIFO (First In, First Out) queue to hold packets while they wait to be decoded. If the decoder falls behind, this queue overflows, resulting in dropped packets.

You can increase the queue capacity by adjusting the -fifo_size parameter, which determines the maximum number of packets the queue can hold:

ffmpeg -rtsp_transport udp -fifo_size 50000 -buffer_size 10485760 -i rtsp://your_stream_address -c copy output.mp4

4. Optimize Operating System Socket Buffers (Linux)

If you configure a large buffer size in FFmpeg but still experience drops, your operating system may be limiting the maximum allowed socket buffer size. On Linux, you can increase the system-wide maximum receive buffer limits by running the following commands:

sudo sysctl -w net.core.rmem_max=26214400
sudo sysctl -w net.core.rmem_default=26214400

To make these changes permanent, add these lines to your /etc/sysctl.conf file:

net.core.rmem_max=26214400
net.core.rmem_default=26214400