I have a couple of project in mind, involving video streaming. For those projects, the bandwidth usage is important and I was wondering how well the Rpi Camera hardware H264 encoder performs. These is what I have found.
For the test I have used a Rpi 3 with a camera module and gstreamer for the SW side. Check this post Quick and Dirty Raspberry Pi Spy Cam for details on how to stream video using gstreamer.
For these tests, I was mainly interested on checking how well the HW encoder can keep the bitrate as well as, how much the stream exceeds the maximum value. I started every test running raspivid without a bandwidth constraint to measure the natural bitrate from the camera. Then I progressively decrease the bandwidth to verify how it performs.
With Regards to quality, I haven't carried out objective measurements. I'm just providing some subjective quality estimation as reference.
As we can see, the first 20 seconds, that corresponds to a static image, used around 8Mbps to stream the video feed. When the image starts to constantly change, the bandwidth gets increased considerably. Roughly it looks like the average for the last 20 secs is around 16 Mbps and we reach a peak of almost 20Mbps
The video quality was excellent and the frame rate was a steady 30 fps.
Now, let's reduce the bandwidth to a half of the peak for the native streaming mode: 10Mbps
Again we can see how the bandwidth required cannot be maintained for the last 20 seconds of the test. In this case we see a higher variance. Average seems to be around 10, but there the bandwidth required is far from being steady.
Image quality and frame rate was all OK with this bandwidth. Let's reduce the bandwidth now to 5 Mbps:
As expected from the statistics, this one is a lot flatter than the previous plots. We can see he big peaks happening when just after the 20 seconds, but this time, the average seems to stay around the requested value for the second period.
The image quality was also good and the framerate still 30 fps steady.
Now, let's move to 2 Mbps
The situation is very similar to what we have seen with the initial full HD test. The static image video requires something around 3Mbps, but the moving video goes as high as 14 Mbps (a bit less). After the still 20 seconds we see how the bandwidth goes to a roughly average of 8 to 10 Mbps. Again, quality and framerate are perfect.
So, let's try 8 Mbps.
Let's halve the bandwidth. 4 Mbps give us those results:
Finally let's go down to 2 Mbps....
As we've also seen in the previous test, there is no longer a huge difference between the steady image and the moving image, however, the moving image produces a more unstable bandwidth pattern.
At this bandwidth visual artefacts are already noticeable. Frame rate is stable.
Once again we can see a big peak when we start changing the image (what makes sense) and then a average value roughly in the spot but peaks goes over 1 Mbps extra.
Finally we will test 1Mbps.
The quality is clearly degraded
For the Full HD case, we can see that for 5Mbps the streaming behaves more stable, exposing a very low peak ratio. For the HD case (720p), all values below 5Mbps shows similar rations but quite close to 50%.
Yes, I measure again the 5Mbps... similar results as you can see
So... you better check your network characteristics (size and duration of a allowed traffic burst) when selecting your bandwidth for streaming from your Rpi Cam.
Maybe I should also measure the impact of the framerate... but let's leave this for other post.
■
Measurements
I used a slightly modified version of the bandwidth measurement script I described in Real-time Bandwidth Monitoring#!/bin/bash rm $2.bw $2.cpu (while true; do (ifstat -b -i $1 1 1 | awk 'NR>2{print $1, $2}' >> $2.bw ; cat /proc/loadavg | awk '{print $1}' >> $2.cpu); done)As you can see I was also monitoring the CPU usage. However, the values were always very low so I will not report any data on that. Let's say that, in a sense, we can be sure that the H264 encoding was performed using the hardware accelerations capabilities. I also wrote a very simplistic script to extract minimal statistics from the captured data. In case you are curious, this is how it does look like.
#!/usr/bin/perl use List::Util qw(sum max min); use POSIX; @F=<>; printf "%-7s : %f\n" x 3, "Min", min(@F), "Max", max(@F), "Average", sum(@F)/@F;I use this script for other tasks and it just process files with all the data in one single column. Our bandwidth script produces two columns, one for the incoming traffic and another one for the outgoing traffic. This means that we need to filter the bw data before feeding it into the statistics module. I use awk for this:
$ cat data.bw | awk '{print $1}' | ./stats.plDepending on the machine you launch the bw script, you may need to change $1 to $2. Finally, each dataset is composed of 20 seconds of a static image followed by 20 seconds of a constantly changing image.
Full HD Streaming
First test was at Full HD (1920x1080). Without imposing any bandwidth or framerate condition, the statistics we get are:Min : 7330.530000 Max : 19897.850000 Average : 11711.743171So the average bandwidth required is around 12 Mbps. However we can see that, at some point the bandwidth get doubled. Let's take a look to the graph to know more.

Min : 6744.500000 Max : 14242.150000 Average : 8817.024222Again, the average is in general below the requested bandwidth, however we have 14Mbps peaks that way above the average. Let's take a look again to the run-time bandwidth usage

Min : 3172.670000 Max : 6007.200000 Average : 5062.105500This is a lot better. The average is pretty close to the required bandwidth and the peak bandwidth is only 1Mbps above the average (20%). Let's take a look to the graph

Min : 1409.230000 Max : 2827.400000 Average : 2035.182000The average bandwidth is pretty much the one required. The peak is close to 50% more than the requested bandwidth. The plot is very similar to the one we got with 5Mbps. In this case, the video quality is poor, specially when something changes in the image. No variations on the frame rate.

Going 720p
So, it looks like we cannot go below 2Mbps without a massive degradations of the image, and 5Mbps seems to be the minimum for a decent quality. Now we are going to reduce the resolution and check the minimum bandwidth for a decent quality video. First, let's check bandwidth without any parameter to get our reference statistics.Min : 2831.870000 Max : 13382.100000 Average : 7227.804750And this is the graph:

Min : 3009.310000 Max : 10255.040000 Average : 5543.662326The average is below the requested 8 Mbps. However the bandwidth peaks actually doubles the required bandwidth. The bandwidth plot shows that again a similar shape.

Min : 3153.340000 Max : 5762.350000 Average : 3902.724762And this is the plot.

Min : 1405.580000 Max : 2939.410000 Average : 2010.246829Around 50% extra peaks. Let's look at the graph

Min : 525.790000 Max : 1520.210000 Average : 1021.731739We can see the usual 50% extra bandwidth peak. However the plot in this case is curious:

CONCLUSIONS
Overall, the Rpi Camera hardware acceleration bandwidth setting is rough estimation. In general, we will get peaks of around 50% extra with respect to the request bandwidth. These values are summarized in the tables below:MAX | 10Mbps | 5Mbps | 2Mbps | 5Mbps-2 | |
Min | 7330.53 | 6744.5 | 3172.67 | 1409.23 | 4013.41 |
Max | 19897.85 | 14242.15 | 6007.2 | 2827.4 | 6485.22 |
Average | 11711.74 | 8817.02 | 5062.10 | 2035.18 | 5061.81 |
Peak ratio | 0.699 | 0.615 | 0.187 | 0.389 | 0.281 |
MAX | 8Mbps | 4Mbps | 2Mbps | 1Mbps | 5 Mbps | |
Min | 2831.87 | 3009.31 | 3153.34 | 1405.58 | 525.79 | 2691.64 |
Max | 13382.1 | 10255.04 | 5762.35 | 2939.41 | 1520.21 | 6792.55 |
Average | 7227.80 | 5543.66 | 3902.72 | 2010.25 | 1021.73 | 4403.91 |
Peak Ration | 0.851 | 0.849 | 0.476 | 0.462 | 0.488 | 0.542 |
■
CLICKS: 2101