MPEG-TS Packet Sizing and Stuffing in FFmpeg
This article provides a practical guide on how to configure and control packet sizing and packet stuffing in MPEG Transport Streams (MPEG-TS) using FFmpeg. You will learn how to adjust network payload sizes to prevent IP fragmentation and how to use null packet stuffing to maintain a strict Constant Bitrate (CBR) for broadcast-grade streaming.
Managing Packet Sizing in FFmpeg
In MPEG-TS, the standard packet size at the transport layer is fixed at 188 bytes. However, when streaming MPEG-TS over network protocols like UDP or RTP, multiple 188-byte packets are grouped together into a single network packet (the payload) to maximize transmission efficiency.
To prevent IP fragmentation, the total network packet size must not exceed the Maximum Transmission Unit (MTU) of your network, which is typically 1500 bytes.
To configure packet sizing in FFmpeg, use the pkt_size
parameter in your output URL:
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f mpegts "udp://12.34.56.78:1234?pkt_size=1316"Why 1316 Bytes?
A packet size of 1316 is the broadcast standard for UDP
streaming because: * \(7 \times 188\text{
bytes} = 1316\text{ bytes}\) of payload. * Adding the IP header
(20 bytes) and UDP header (8 bytes) brings the total packet size to 1344
bytes. * This safely fits under the standard 1500-byte MTU limit,
preventing packet fragmentation and reducing packet loss over the
network.
Managing Packet Stuffing (Constant Bitrate)
Packet stuffing is the process of injecting null packets (PID
0x1FFF) into the stream to fill gaps when the actual video
and audio bitrate is lower than the allocated bandwidth. This is
required to maintain a strict Constant Bitrate (CBR), which hardware
decoders, satellite uplinks, and multiplexers require to prevent buffer
underflow.
To force FFmpeg to perform packet stuffing and output a strict CBR
stream, you must define the -muxrate option.
ffmpeg -i input.mp4 \
-c:v libx264 -b:v 4000k -maxrate 4000k -bufsize 8000k \
-c:a aac -b:a 128k \
-f mpegts -muxrate 5000k \
"udp://12.34.56.78:1234?pkt_size=1316"How Muxrate Stuffing Works:
- Target Bitrate Allocation: In the example above, the video is capped at 4000 kbps and the audio at 128 kbps.
- The Muxrate Cap: The
-muxrate 5000kflag forces the overall MPEG-TS container to stream at exactly 5000 kbps. - Stuffing Injection: FFmpeg calculates the difference between the actual media bitrate (approx. 4128 kbps plus container overhead) and the 5000 kbps target. It automatically stuffs the remaining bandwidth (roughly 700-800 kbps) with null packets to maintain an exact 5.0 Mbps output.
Essential FFmpeg MPEG-TS Parameters
When fine-tuning packet sizing and stuffing, use these additional
flags inside the -mpegts_flags option:
resend_headers: Forces FFmpeg to frequently resend PAT (Program Association Table) and PMT (Program Map Table) packets. This ensures that receivers joining a live stream mid-way can decode the packets instantly.pat_pmt_at_frames: Writes PAT and PMT multiplexing information with every frame rather than at set time intervals.
Example implementation:
ffmpeg -i input.mp4 -c:v libx264 -b:v 3000k \
-f mpegts -mpegts_flags +resend_headers -muxrate 4500k \
"udp://12.34.56.78:1234?pkt_size=1316"