For the Google Lunar Xprize I’m looking into video compression in order to estimate the bandwidth that is needed to stream video from the moon to earth. PlanIn order to make an estimate, uncompressed footage from the moon would be best to use as a base. In stead of that footage we have panoramic shot from the moon available in tiff format with a resolution of 17531 x 2333 pixels. Cutting this panoramic shot in seperate pictures and animating those pictures in a video pan shot should give some information on what compression is acceptable and the required bandwith it needs. [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() All processing will be done on the following system:
If possible the whole process will be executed using open source software. The first test will be done in 720p HD format (1280x720). Converting to picturesUsing ImageMagick it is quite easy to convert an image to different formats and different resolutions. The first step consists of scaling the original image to a vertical resultion that is the same as the target video steam, 720 pixels. I stored the image in the lossless png format using:
This results in a pano.png image with a resultion of 5410 x 720 pixels. Using this as the base image, the idea is to cut seperate 1280 x 720 pixel images. The first image will start at x coordinate 0 and the following will increment 1 pixel further on the x axis. This should result in 5410 - 1280 = 4130 frames that can be used to create movies. To automate this process the following script can be used to convert the pano.png to seperate frames.
When the script is finished 4130 files are created in bmp (losless) format. Compiling softwareTo convert the frames into movies the ffmpeg software is used. Below is the procedure used to compile ffmpeg and the x264 library. Compiling x264Using git the repository for x264 can be checked out, compiled and installed.
Compiling ffmpegUsing git the repository for ffmpeg can be checked out, compiled and installed.
H264To get an initial idea of compression and picture quality, the h264 codec is choosen. ConfigurationThis codec has a number of parameters that can be configured. For this test 2 are defined:
Video PresetThe h264 codec has a number of video presets to choose from:
Rate control methodAssuming passing twice over the input isn’t an option in the real application, there are two rate control methods which are interesting to try:
The constant rate factor is aimed at picture quality. Bit rate and output size can vary in this situation. The constant rate factor method is choosen by passing the -crf option followed by a float value (lower value is higher picture quality and higher bitrate). The one pass average bitrate is aimed at keeping a constant bitrate. Picture quality can vary depeding on the type of movement etc. in the input. The one pass averate bitrate method is choosen by passing the -b option followed by the desired bitrate. Commandline settingsThe following commandline options used are:
Output processingThe ffmpeg command outputs information on the screen at intervals. It displays lines with the following information:
One of the interesting variables in the output is the bitrate. Depending on the encoding used the bitrate can vary through the processing of the frames. It can be quite useful to have a bitrate vs. time graph based on the output of ffmpeg. After capturing the output of ffmpeg some simple scripting can process the bitrate vs. time graph.
Encoding at 25 frames per secondFor the initial test the frame rate is kept at the basic 25 frames per second. All commands used limit the target video duration to 30 seconds to limit rendering time. Constant rate factorThe constant rate factor was tested with 3 values:
CRF 26
Average bitrate: 201.41kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: CRF 35
Average bitrate: 119.53kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: CRF 40
Average bitrate: 91.87kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: one pass average bitrateThe one pass average bitrate was tested with 2 values:
150kbit/second
Average bitrate: 134.08kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: 120kbit/second
Average bitrate: 108.52kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: ConclusionsIn all cases it is clear the bitrate variation over the whole video peaks at the start. This seems logical, as the initial picture needs to be established. As soon as this information is available, only differences have to be encoded which takes a lot less bandwidth. When using the average bitrate method, the initial amount of bandwidth required is much less then when using the constant rate factor. However, the lower bandwidth requirement results in a much worse initial picture. Due to the bandwidth constraint it takes longer for a high quality initial picture to form. The quality of the picture improves while the actual movement is taking place. With the constant rate factor the initial frame is formed to high quality after which movement starts. The spikes in bitrate that can be seen in bitrate graphs indicate the use of i-frames every 10 seconds. The i-frame uses more bandwidth because it doesn’t require references to other frames to allow for decoding (like with p or b frames). For more information see a relevant article on <a href=“http://en.wikipedia.org/wiki/B-frame#Bi-directional_predicted_frames_.28or_slices.2C.29_a.k.a._B_pictures" data-wikipedia<=”" data-a="">. For this specific pan shot is seems like the big difference is in the startup bandwidth required. The difference in bitrate during the remainder of the video is very low. Encoding at 10 frames per secondTo see what the effect of the framerate is on the resulting videostream, a test was done with the framerate lowered to 10. To keep an acceptable motion effect, framerates lower then 10 shouldn’t be selected. The resulting video will become very choppy. The same test were re-run as before with the 25 frames per second encoding. Constant rate factorThe constant rate factor was tested with 3 values:
CRF 26
Average bitrate: 161.07kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: CRF 35
Average bitrate: 91.53kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: CRF 40
Average bitrate: 64.80kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: one pass average bitrateThe one pass average bitrate was tested with 2 values:
150kbit/second
Average bitrate: 165.41kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: 120kbit/second
Average bitrate: 137.10kbit/second Bitrate variation over the whole video: [h264-br120-10.png h264-br120.png h264-br150-10.png h264-br150.png h264-crf26-10.png h264-crf26.png h264-crf30.png h264-crf35-10.png h264-crf35.png h264-crf40-10.png h264-crf40.png pano.png h264-br120-10.mp4 h264-br120.mp4 h264-br150-10.mp4 h264-br150.mp4 h264-crf26-10.mp4 h264-crf26.mp4 h264-crf35-10.mp4 h264-crf35-r5.mp4 h264-crf35.mp4 h264-crf40-10.mp4 h264-crf40.mp4]![]() Result video: ConclusionsAs might be expected, a lower framerate yields a lower bitrate. This seems to be true for the constant rate factor encoding, but not for the average bitrate encoding. While the constant rate factor bitrate graphs display the same initial peak bandwidth usage, the constant bitrate graphs display a big increase in initial bitrate. Both types of encoding also don’t display the characteristic i-frame spikes in the bitrate graph. It seems that lowering the frames per second has some interesting side effects that need to be reviewed more closely if this technique is chosen to lower the bandwidth. Results summary
|