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:

  1. Target Bitrate Allocation: In the example above, the video is capped at 4000 kbps and the audio at 128 kbps.
  2. The Muxrate Cap: The -muxrate 5000k flag forces the overall MPEG-TS container to stream at exactly 5000 kbps.
  3. 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:

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"