Live data from Hacker News

We replaced H.264 streaming with JPEG screenshots (and it worked better)

blog.helix.ml

121–130 of 332 posts

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#121
I have some experience with pushing video frames over TCP.

It appears that the writer has jumped to conclusions at every turn and it's usually the wrong one.

The reason that the simple "poll for jpeg" method works is that polling is actually a very crude congestion control mechanism. The sender only sends the next frame when the receiver has received the last frame and asks for more. The downside of this is that network latency affects the frame rate.

The frame rate issue with the polling method can be solved by sending multiple frame requests at a time, but only as many as will fit within one RTT, so the client needs to know the minimum RTT and the sender's maximum frame rate.

The RFB (VNC) protocol does this, by the way. Well, the thing about rtt_min and frame rate isn't in the spec though.

Now, I will not go though every wrong assumption, but as for this nonsense about P-frames and I-frames: With TCP, you only need one I-frame. The rest can be all P-frames. I don't understand how they came to the conclusion that sending only I-frames over TCP might help with their latency problem. Just turn off B-frames and you should be OK.

The actual problem with the latency was that they had frames piling up in buffers between the sender and the receiver. If you're pushing video frames over TCP, you need feedback. The server needs to know how fast it can send. Otherwise, you get pile-up and a bunch of latency. That's all there is to it.

The simplest, absolutely foolproof way to do this is to use TCP's own congestion control. Spin up a thread that does two things: encodes video frames and sends them out on the socket using a blocking send/write call. Set SO_SNDBUF on that socket to a value that's proportional to your maximum latency tolerance and the rough size of your video frames.

One final bit of advice: use ffmpeg (libavcodec, libavformat, etc). It's much simpler to actually understand what you're doing with that than some convoluted gstreamer pipeline.

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#123

> When the network is bad, you get... fewer JPEGs. That’s it. The ones that arrive are perfect. This would make sense... if they were using UDP, but they are using TCP. All the JPEGs they send will get there eventually (unless the connection drops). JPEG does not fix your buffering and congestion control problems. What presumably happened here is the way they implemented their JPEG screenshots, they have some mechani…

Probably either (1) they don't request another jpeg until they have the previous one on-screen (so everything is completely serialized and there are no frames "in-flight" ever) (2) they're doing a fresh GET for each and getting a new connection anyway (unless that kind of thing is pipelined these days? in which case it still falls back to (1) above.)

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#124
Many moons ago I was using this software which would screenshot every five seconds and give you a little time lapse and the end of the day. So you could see how you were spending your computer time.

My hard disk ended up filling up with tens of gigabytes of screenshots.

I lowered the quality. I lowered the resolution, but this only delayed the inevitable.

One day I was looking through the folder and I noticed well almost all the image data on almost all of these screenshots is identical.

What if I created some sort of algorithm which would allow me to preserve only the changes?

I spent embarrassingly long thinking about this before realizing that I had begun to reinvent video compression!

So I just wrote a ffmpeg one-liner and got like 98% disk usage reduction :)

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#126
post #123

> When the network is bad, you get... fewer JPEGs. That’s it. The ones that arrive are perfect. This would make sense... if they were using UDP, but they are using TCP. All the JPEGs they send will get there eventually (unless the connection drops). JPEG does not fix your buffering and congestion control problems. What presumably happened here is the way they implemented their JPEG screenshots, they have some mechani…

Probably either (1) they don't request another jpeg until they have the previous one on-screen (so everything is completely serialized and there are no frames "in-flight" ever) (2) they're doing a fresh GET for each and getting a new connection anyway (unless that kind of thing is pipelined these days? in which case it still falls back to (1) above.)

You can still get this backpressure properly even if you're doing it push-style. The TCP socket will eventually fill up its buffer and start blocking your writes. When that happens, you stop encoding new frames until the socket is able to send again.

The trick is to not buffer frames on the sender.

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#127
post #106
post #63

They might want to check out what VNC has been doing since 1998– keep the client-pull model, break the framebuffer up into tiles and, when client requests an update, perform a diff against last frame sent, composite the updated tiles client-side. (This is what VNC falls back to when it doesn’t have damage-tracking from the OS compositor) This would really cut down on the bandwidth of static coding terminals where 90%…

The blog post did smell of inexperience. Glad to hear there is other approaches - is something like that open source?

Yup. Go look into tigervnc if you want to see the source. But also you can just search for "tigervnc h.264" and you'll see extensive discussions between the devs on h.264 and integrating it into tiger. This is something that people spent a LOT of brainpower on.

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#129
post #109

Earlier quoted context omitted.

What's the term for the ideology that "laws are silly because people sometimes break them"?

Posting stuff into Deepseek is banned. The corporate firewall is like putting a camera in your home because you may break the law. But, yeah, arguing against cameras in homes because people find dead angles where they can hide may not be the strongest argument.

Disclaimer: I work in corporate cybersecurity.

I know that some guardrails and restrictions in a corporate setting can backfire. I know that onerous processes to get approval for needed software access can drive people to break the rules or engage in shadow IT. As a member of a firewall team, I did it myself! We couldn't get access to Python packages or PHP for a local webserver we had available to us from a grandfather clause. My team hated our "approved" Sharepoint service request system. So a few of us built a small web app with Bottle (single file web server microframework, no dependencies) and Bootstrap CSS and SQLite backend. Everyone who interacted with our team loved it. Had we more support from corporate it might have been a lot easier.

Good cybersecurity needs to work with IT to facilitate peoples' legitimate use cases, not stand in the way all the time just because it's easier that way.

But saying "corporate IT controls are all useless" is just as foolish to me. It is reasonable and moral for a business to put controls and visibility on what data is moving between endpoints, and to block unsanctioned behavior.

Re: We replaced H.264 streaming with JPEG screenshots (and it worked better)

#130
post #84

There are so many things that I would have done differently. > We added a keyframes_only flag. We modified the video decoder to check FrameType::Idr. We set GOP to 60 (one keyframe per second at 60fps). We tested. Why muck around with P-frames and keyframes? Just make your video 1fps. > Now it’s 10Mbps of blocky garbage that’s still 30 seconds behind. 10 Mbps is way too much. I occasionally watch YouTube videos where…

Setting to 1 FPS might not be enough. GOP or P frame setting needs to be adjusted to make every frame keyframe.

[deleted]
Post reply on HN