How ST 2110-20 bandwidth is actually calculated
First published: 2026-08-22 · 8 min read
Written against Calculator v1.5.1
Some background
When I first started working with ST 2110 I did what many people probably do. I Googled ST 2110 bandwidth calculator. I came across vibe-coded calculators and some methods that essentially added a multiplier on top of the data rate of a frame. Both options work as quick rule-of-thumb but I wanted the confidence that I was getting as close to a real number as possible - this is where the rabbit hole of reading, researching and measuring began.
A lot of the arithmetic that has been implemented into 2110.tools can be in-part attributed to the SMPTE Course taught by Wes Simpson “SMPTE ST 2110 Standards Overview” and the SMPTE ST 2110 Suite of Standards
Creating a packet
2110 uses the Real-time Transport Protocol (RTP) to move media over a network. RTP typically transmits its data in UDP Packets or UDP Datagrams if you’re fancy. Without going into too much detail here; UDP has lower overhead than other methods like TCP - this becomes important when we’re handling hundreds-of-thousands of packets per second in such situations as UHD -20 video.
We’ll go through the steps of how Calculator generates the mathematical UDP datagram.
How much space is available in the payload to pack pixels into?
The ST 2110 spec defines that the typical MTU maximum transmission unit is 1500 bytes. We have to subtract the IP header from this MTU value to work out the size of our UDP packet. ST 2110 states that 40 bytes (the size of an IPv6 header) should always be subtracted from the MTU. You might think “I’m not using an IPv6 network” - neither am I. However, diverging and instead subtracting the size of an IPv4 header would be a violation of the standard - and we don’t want to be doing that. So subtracting 40 bytes it is - giving us a UDP Datagram size of 1460 bytes.
In the 1460-bytes UDP datagram we need to contain the following:
- UDP Header = 8 bytes
- RTP Header = 12 bytes
- RTP Payload Header = 14 bytes*
- The RTP Payload itself - this is the bit that contains our video pixels
*The smallest size the payload header could be is 8 bytes. If the particular payload spans two or three lines of video we have to extend the payload header by 6 bytes per extra line. This has a dynamic effect on how many pixels can be packed into our RTP payload. Calculator does not currently account for this and instead picks the middle ground option of 14 bytes. Which means that calculator’s results right now are a slight over-estimate - around 0.17% for UHD-50 4:2:2 10-bit. This is on the roadmap to account for by adding a toggle to enable or disable this sample row data wrapping.
Calculating our available payload space goes something like this:
How many bytes are in a pgroup?
I should first start off by explaining what a pgroup is. It’s short hand for Pixel Group and it’s the smallest group of pixels whose samples pack into a whole number of octets (or bytes). The sampling method like YCbCr-4:2:2 or RGB and bit-depth change how big pgroups are and how many pixels they cover. The ST 2110 specification outlines how these pgroups should be constructed based on bit-depth and sampling method.
For the rest of the example in this article we’ll work with the common SDI Sampling of 10-bit YCbCr-4:2:2 which has a pgroup size of 5 octets and coverage of 2 pixels which means that 5 bytes can represent two pixels horizontally.
Not all sampling methods have horizontal coverage. For example YCbCr-4:2:0 covers a 2x2 grid spanning two consecutive lines of pixels.
Calculator in 2110.tools uses the following lookup table for its pgroup coverage and size:
| Sampling | Bit Depth | Pgroup size | Pgroup coverage |
|---|---|---|---|
| RGB / YCbCr-4:4:4 | 8 | 3 | 1 |
| RGB / YCbCr-4:4:4 | 10 | 15 | 4 |
| RGB / YCbCr-4:4:4 | 12 | 9 | 2 |
| RGB / YCbCr-4:4:4 | 16 | 6 | 1 |
| YCbCr-4:2:2 | 8 | 4 | 2 |
| YCbCr-4:2:2 | 10 | 5 | 2 |
| YCbCr-4:2:2 | 12 | 6 | 2 |
| YCbCr-4:2:2 | 16 | 8 | 2 |
| YCbCr-4:2:0 | 8 | 6 | 4 |
| YCbCr-4:2:0 | 10 | 15 | 8 |
| YCbCr-4:2:0 | 12 | 9 | 4 |
Pgroups & pixels per packet
Now we know how much space we have to fill in our RTP Payload 1426 bytes , how big our pgroup is 5 bytes and what coverage it has 2 pixels we can calculate how many pgroups we can fit in a packet.
There is one main rule that we have to follow here - a packet can only contain full pgroups. We can’t completely fill the 1426 byte space if that results in it containing 0.3 of a pgroup at the end, for example.
We simply do floor division of the available payload space and the size of our given pgroup:
This leaves one byte of unused space in the available payload space. So we just won’t utilise it. Now we know that there’s 285 pgroups per packet we can calculate how many pixels that translates to.
Packets per second
Now we know:
- Our video format - in the case of this example:
UHD-50 YCbCr-4:2:2 - How many pgroups we can fit into a packet
- How many subsequent pixels can fit into that packet
We can work out how many of these packets per second we are working with. You can see this breakdown in every stream you make in Calculator
As I mentioned before; currently Calculator treats all packets the same in terms of their size. When sample row data wrapping is implemented Calculator will treat all non-wrapping packets (ones that only contain pixels from a single line) the same, but will correctly account for those packets that land on the end of a line and therefore roll over onto the start of the next. This is coming soon.
To start with let’s work out how many packets it will take to assemble a frame. In this case we need to round our result up because we can only work with whole packets.
To turn that into packets per second we simply multiply by the frame rate:
Assembly
Now we’re ready to build our UDP payload that contains an RTP Packet. A reminder of the values we’re using for our UHD-50 YCbCr-4:2:2 signal:
- RTP Header = 12
- RTP Payload Header = 14
- Pgroups per packet = 285
- Pgroup size = 5
With this we can add on our 8 byte UDP header to assemble our full UDP datagram. Getting our datagram size to 1459 bytes .
At this point Calculator does some additional arithmetic to calculate bytes on the wire which is the total number of bytes that are actually transmitted. This includes the IPv4 header, Ethernet frame header and transmission overheads.
*Calculator includes the ethernet header, checksum and a single VLAN tag in its calculations. I figured this would be a fairly common scenario particularly across links between switches. On the roadmap is a VLAN tag toggle to include or omit this data from the calculation.
Finally we can get our final bandwidth value in bits per second:
We have to convert our calculations, which so far have been in bytes, into bits to align with how we typically measure data transmission. There are 8 bits in a byte so we just multiply the result of our bytes on the wire per second calculation by 8.
That’s it!
Some technical notes
Traffic shaping
There are a few types of senders (devices that transmit -20 video) outlined in the ST 2110 specification - N, NL, & W. N, or narrow senders have their traffic shaped across the active picture period. Meaning that packet egress is spread (as best as possible) throughout the duration of that particular period and pauses during what would be the blanking interval - mimicking SDI signal timing. NL or narrow linear senders are similar except they spread their packets evenly across whole frame period including what would be the blanking interval. Whereas W, or Wide senders are permitted more deviation and are more ‘bursty’ - producing the majority of their packets in a very short time window. This bursty behaviour can cause problems with switch egress buffers when multiple W senders align with each other - possibly overwhelming those switch egress buffers. Even at link utilisations well below what the link should comfortably carry. The number that Calculator produces is an average across a whole frame, roughly similar to what NL senders would look like in practise. So although the bandwidth is correct at a frame-by-frame or second-by-second interval, it doesn’t know what sender type your video is being transmitted from. If you’re working with wide senders, real-world behaviour can differ in ways that matter.
Interlaced
For interlaced signals we do the same mathematics per field of an interlaced signal and sum those fields appropriately. There is some nuance to what is contained in the payload header for interlaced fields but it doesn’t affect the size of the payload or overall bandwidth. It’s just a signal to say “Hey I contain pixels from field2”, for example.
As you can imagine there is more nuance under the hood of how Calculator works and its a project I am continuously improving. If any of this article, or 2110.tools is helpful then please consider supporting the project by buying me a coffee.