This deals with the transfer of the video frames from the server which generates them to the server which streams the videos.
Transferring the videos currently takes 80% of the "post-generation" time, meaning the time from when the message "a video is being forged - wait." appears, to the time when the video is completed and ready to watch.
The generic question which appeared on linuxquestions.org:
I'm looking for an efficient solution to stream a big volume of images over a small bandwidth line. The goal is to transmit all the images transferring the smallest amount of data.
The images are ordered sequential frames of a video and between two consecutive frames most of the pixels (~ 95%) are exactly the same.
Each image is about 1MB of compressed png format (compression level 3), with 24 bits per pixel. Let's define this format to be the canonical one.
A list of the ideas / attempts I went along:
- Note: all rsync transfers are performed between ordered frames; the source frame is always the n-th, and the destination is the n-1-th, so that their visual difference is minimal. All the frames preceding the n-th are available on the source computer.
- Transfers performed by rsync with delta algorithm, on the canonical png images:
For each 1MB image, rsync transfers about 900KB and saves 100KB. This results to be unsuitable; Probably the delta algorithm isn't able to spot similarities in the images if these are compressed.
- Transfers performed by rsync with delta algorithm, on uncompressed ppm images:
I converted a pool of canonical images into ppm*, each one resulting about 8MB; for each image, rsynch was able to detect ~7MB of similarity and transfer "only" 1MB. This proved to be unsuitable as the canonical images are 1MB themselves.
- Extract a difference image to be transmitted (idea, not tested):
Instead of using rsync's delta algorithm, I can create an image on the local computer composed of only the pixels which differ from the two frames; given that two consecutive frames are identical for about 95% of pixels, this method could generate very light compressed images to be transfered.
Contrarily, I think this would be very cpu-intensive on both source and destination.
- Assemble a video and transmit frame chunks (idea, not tested):
It is possible to assemble the frames into a video file. Video encoders are extremely able to recognize similarities between frames and present the differences in a vectorial form, which uses very little space on the video file. If it could be possible to cut and extract from the video file the portions representing each image, they would be very light to be transferred over the network.
However, standing by the ffmpeg's manual, it doesn't seem possible to extract frames from an encoded video with this program.
If more details about the systems are required, I'll describe them in an appendix here.
* The ppm format is uncompressed and stores each pixel color "linearly" with its position on the picture