I bet it has to do with buffering you're doing on streams. man popen has this line
Note that output popen() streams are block buffered by default.
You'll have to increase the buffer size to something more respectable than the default block size (which can be as small as 256 bytes) using setvbuf. AFAIK nc increases the buffer size to 8K.
I have tried to do this a few times but never gotten the results I wanted. Just recently I revisited it and found this works to multicast directly from raspivid.
raspivid -a 12 -a "ras2" -t 0 -b 3000000 -fps 20 -w 1920 -h 1080 -o udp://188.8.131.52:1234 -ih -fl -stm -if adaptive -pf main -v -n
Then use this on a linux PC to view: