4

I 'm running an ffserver process on a Linux machine, in order to achieve video streaming via ffmpeg. However, there is a delay on video streaming. On ffserver configuration file I define Port 8090.

Command netstat -tulnap gives me this:

root@beagleboard:/etc# netstat -tulnap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             Stat                                                                             e       PID/Program name
tcp        0      0 0.0.0.0:68                  0.0.0.0:*                   LIST                                                                             EN      654/pump
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LIST                                                                             EN      662/portmap
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LIST                                                                             EN      698/dropbear
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LIST                                                                             EN      744/ffserver
tcp        0     52 192.168.1.104:22            192.168.1.111:10838         ESTA                                                                             BLISHED 724/dropbear
udp        0      0 0.0.0.0:514                 0.0.0.0:*                                                                                                            703/syslog-ng
udp        0      0 0.0.0.0:111                 0.0.0.0:*                                                                                                            662/portmap
udp        0      0 0.0.0.0:60628               0.0.0.0:*                                                                                                            709/avahi-daemon: r
udp        0      0 0.0.0.0:5353                0.0.0.0:*                                                                                                            709/avahi-daemon: r

As you can see, ffserver process uses tcp protocol to transmit and I suspect that this is the reason of video streaming delay. How can I force process to make use or udp protocol? Should I change port?

6
  • 9
    tcp vs udp is a very different usage and not interchangeable Mar 7, 2014 at 16:45
  • You 're telling me there is no way acheiving transmission over UDP?
    – dempap
    Mar 7, 2014 at 16:57
  • 4
    That is a change that needs to happen at the application level, you can't do it externally.
    – heavyd
    Mar 7, 2014 at 17:06
  • 3
    What you want is to tell FFMpeg to stream via Simple RTP, see also the "Point to point streaming" section. RTP can use UDP.
    – Josh
    Mar 7, 2014 at 20:53
  • 4
    The question should have been titled "how to make ffmpeg stream over UDP" Mar 8, 2014 at 10:33

3 Answers 3

22

You cannot just force a program to use UDP instead of TCP, without rewriting parts of the program itself. These protocols are just too different to be interchangeable.

  • TCP is stream-oriented (the receiver sees everything as a continuous stream in the exact order that the sender output it); UDP is datagram-oriented (each datagram is sent in a separate packet, and they can even get reordered).

  • TCP has flow control, so the sender (or the sender's OS) knows exactly how fast it should send data without overflowing the link or significantly affecting other connections. UDP doesn't do any of this – a poorly-"forced" program might start sending gigabytes of data per second over UDP, regardless of link speed.

  • TCP has retransmission, so if a packet is dropped in the middle (e.g. because the network is overloaded or has other problems) it will be resent. If the protocol depends on a reliable transport and you force it to go over UDP, the connection might die completely as soon as at least a single packet gets lost. (And packets will get lost; see points #1 and #2 above.)

4
  • 1
    Is the connection dropped if the sender doesn't abide by the flow control? Mar 8, 2014 at 11:29
  • 1
    @JordanDoyle No. That will just make the connection slower because the receiver will have to drop the extra packets, which will then require retransmission.
    – Bakuriu
    Mar 8, 2014 at 13:07
  • @Bakuriu ah thanks. Does anything happen if the sender doesn't abide? Mar 8, 2014 at 13:46
  • @JordanDoyle As I said, nothing special will happen except that more packets will be dropped and the connection will get slower and slower, because the sender will be filling all the link capacity. You are just increasing the traffic in the network uselessly and you might cause a congestion of the network.
    – Bakuriu
    Mar 8, 2014 at 13:57
6

As others have mentioned, UDP and TCP are fundamentally different protocols.

However, if you must transport data over UDP instead of TCP, you can use a relay tool such as socat. You can configure socat to listen for a TCP connection, and forward the contents of the TCP stream as a UDP stream to another host. If the other host is expecting TCP traffic, you can use another instance of the relay there to convert back to TCP. This will remove retry and ack behavior from the host-to-host link. Retries and acks will still be present between the local relay tool and the local application, but you're unlikely to see retries on a local loopback link.

However, this is unlikely to solve your delay problem. If your application is built to use TCP instead of UDP, it may not be tolerant of dropped packets, in which case this hack may cause unstable behavior.

3

Unless you're using really slow connections, your delay problem is most likely due to your video codec.

To efficiently compress video, you'll have to use predictive encodings (see this article on Wikipedia).

Predictive codings basically calculate images from earlier or later images. This has the following implications:

  1. If you use many P-frames (calculated from earlier frames), you'll get a delay before the display of the video starts, because the client has to wait for the next full video frame (I-frame). However, once the stream is established, you can watch the video relatively lag-free.

  2. If you use B-frames (calculated from earlier AND later images), you'll have some really big delay: Additionally to the inital delay from above, the client has to wait for the next I-frame to start playback from the last I-frame. This will introduce lag (client plays video noticeably later than server records/sends it, often many seconds). If you're encoding the video on the fly, you'll also have a delay from the server – it will need to wait for the next I-frame to send everything starting from the previous I-frame.

For most codecs, you can tweak the usage of B- and P-frames according to your needs, however, there is a trade-off delay vs. compression efficiency

If you have enough bandwidth, you could also use a codec without B-/P-frames, like MJPEG

Another reason for a delay would be buffering on the player side, so you don't have any distortions if there's a jittery network transmission. Many video players allow you to tweak the buffer sizes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .