UDP multicast output
Addressing
Section titled “Addressing”For distribution inside a building, use the administratively scoped range, 239.0.0.0/8. It is the multicast equivalent of 10.0.0.0/8: reserved for local use, never routed onto the public internet, and safe to allocate without checking a registry. Assign a group per channel and keep a written record of the allocation, because a collision between two channels is the same fault as a duplicate sender and presents the same way.
Do not use 224.0.0.0/24. That block is reserved for link-local control protocols — routing adjacencies, IGMP itself, and neighbour discovery on some equipment. Video sent into it is delivered to every device on the segment and is processed by control-plane code that was not expecting 38 Mbps. Castmux warns when a destination falls in that range rather than refusing outright, on the assumption that you might be testing something deliberately, but the warning should be treated as an error in production.
Unicast destinations are accepted and are the right choice for a point-to-point link: feeding another headend across a routed path, handing a channel to a recorder or compliance logger, or testing from a laptop that is not on the television VLAN. A unicast channel has no IGMP membership behind it, so on-demand streaming cannot detect viewers for it and the channel must be left always-on.
| Range | Use |
|---|---|
| 239.0.0.0/8 | recommended Administratively scoped. The correct choice for in-building distribution. |
| 224.0.0.0/24 | avoid Reserved for link-local control protocols. Castmux warns if a channel is pointed here. |
| Unicast address | point-to-point Accepted. Suitable for another headend or a recorder. No viewer detection, so keep the channel always-on. |
Datagram size
Section titled “Datagram size”The payload of each datagram is 1316 bytes, which is exactly seven 188-byte transport packets. That number is not arbitrary and it is worth understanding why it is the only sane choice.
A transport packet is 188 bytes and cannot be split across datagrams without a receiver having to reassemble it. Seven of them is 1316 bytes, which with 8 bytes of UDP header and 20 bytes of IPv4 header comes to 1344 — comfortably inside a 1500-byte Ethernet MTU with room for a VLAN tag. Eight packets would be 1504 bytes of payload and would fragment.
Sending fewer than seven packets per datagram is legal but wasteful in two distinct ways. Every datagram carries the same 28 bytes of header regardless of how full it is, so a stream of half-filled datagrams spends roughly twice the header overhead and twice the per-packet processing on the receiving device for the same video. More importantly, some set-top boxes handle ragged datagrams badly: a decoder that assumes seven packets per datagram, or that buffers by datagram count rather than by byte count, produces intermittent artefacts that appear only on some models and are almost impossible to reproduce on a PC player.
The two engines differ here. The pass-through engine emits full 1316-byte datagrams 100% of the time. The remux engine fills them about 85% of the time, flushing a short datagram whenever its internal muxer reaches a frame boundary. This is why Castmux forces the packet size explicitly on HLS channels rather than accepting the engine default — see Streaming engines for the full comparison.
The default is 16. TTL on a multicast datagram is decremented by every router that forwards it, so it bounds how far the traffic can travel.
TTL 1
The datagram never leaves the local segment. In a single building with the appliance and the televisions on the same VLAN this is usually the correct value, and it is a useful safety net: a misconfiguration cannot leak video onto the rest of the network.
TTL 16 (default)
Allows forwarding across a handful of router hops. Chosen as the default because it works in both the flat case and the routed case, and because a stream that does not arrive is a harder fault to diagnose than one that travels slightly further than it needed to.
Higher values
Only needed where a router is deliberately forwarding multicast between VLANs, which requires PIM or an equivalent to have been configured by whoever runs the network. Raising the TTL does not by itself make multicast cross a router.
Egress interface
Section titled “Egress interface”A channel can be given a source address, and the engine will bind its socket to it. This is useful for making the source address of the traffic predictable, for firewall rules and for identifying which appliance a stream came from on a segment with more than one.
Two further points that follow from the same fact. Fix the range, 224.0.0.0/4, not individual groups: a host route per group patches the channels you happen to have today and leaves every channel added later silently unroutable. And route changes made with ip route do not survive a reboot, so they must be installed as a unit that runs at boot.
Constant bitrate
Section titled “Constant bitrate”Some downstream equipment, and some older set-top boxes, behave better with a constant-bitrate transport stream than with one that follows the source. Padding to CBR means inserting null packets so the wire rate is flat regardless of what the video is doing.
The remux engine can do this, because it builds its own transport stream and can decide how much of it is padding. The pass-through engine cannot: it forwards the source’s packets unaltered and has no mechanism to insert nulls, which is the same property that makes it preserve original PIDs and report source-side loss faithfully. You cannot have both.
On the DVB-C path the question does not arise. A DVB-C carrier is constant-bitrate by construction and the multiplexer pads to fill it, so a channel destined for a multiplex does not need CBR applied to its UDP output.
Per-channel constant bitrate on plain UDP output, configurable independently of the engine, is roadmap.
Service naming
Section titled “Service naming”A television or set-top box that scans a multicast group shows whatever name the transport stream declares in its Service Description Table. On the pass-through engine, Castmux writes the channel name into the SDT, so the name you type in the web interface is the name that appears on screen.
The remux engine does not write an SDT. Channels on that engine will appear under whatever name the receiving device invents, typically the group address or a generic placeholder. If the on-screen name matters and the source permits it, use the pass-through engine.
Duplicate senders
Section titled “Duplicate senders”Two processes sending to the same group and port produce a stream that is the interleaving of both. Continuity counters conflict, PIDs collide, and the result on screen is pixelation and audio breakup that comes and goes.
This fault is unusually expensive to diagnose because both senders look completely healthy. Each one is producing a valid stream at the correct bitrate; each one’s metrics are green. The bitrate measured on the wire is roughly double what it should be, which is the only clue, and it is easy to attribute to something else.
Castmux therefore sweeps for other senders on the destination address and port before starting a channel, and reports the condition rather than starting on top of them. The classic cause is not two Castmux channels — the user interface prevents that — but an older service left running alongside a new deployment: a previous streamer that was disabled but not stopped, or a systemd unit that a cron entry restarts every night.
Dummy listeners
Section titled “Dummy listeners”When nothing on the network has joined a multicast group, there is no receiver applying back-pressure and, on some kernel and driver combinations, the socket send buffer can overrun rather than simply discarding. The symptom is intermittent send errors on a channel that nobody is even watching.
Castmux can maintain a local consumer for each group, which joins it and reads and discards the traffic. This keeps the group membership and the buffer behaviour consistent whether or not real viewers are present. It is on by default and costs very little; there is no reason to turn it off unless you are measuring something and want the group genuinely unjoined.
Note the interaction with on-demand streaming: the dummy listener is deliberately not counted as a viewer. If it were, no on-demand channel would ever stop.
Verifying output
Section titled “Verifying output”Three checks, in increasing order of how much they prove.
First, play the group from a machine on the same segment:
# ffplay, on a host in the same VLAN as the applianceffplay udp://@239.10.0.1:1234
# The @ is required. Without it ffplay listens on a unicast socket# and never joins the group, so you will see nothing and blame the encoder.In VLC, use Media → Open Network Stream and enter the same URL:
udp://@239.10.0.1:1234Second, use the browser preview in the web interface. It confirms that the source is arriving and being prepared correctly, but it does not prove anything about the multicast path, because the preview does not travel over it.
Third, and most usefully, read the UDP bitrate tile on the channel card. That figure is measured with packet capture on the interface, off the wire, not reported by the engine. It is therefore the only signal that does not depend on the engine telling the truth about itself, and it is the same measurement for both engines. A channel whose engine claims to be running but whose UDP bitrate is zero is not on air.